feat: update landing

This commit is contained in:
Oleg Proskurin 2025-10-07 22:38:03 +07:00
parent 847145c385
commit f63c89a991
1 changed files with 39 additions and 66 deletions

View File

@ -38,8 +38,7 @@ interface GenerationResult {
geminiParams: object; geminiParams: object;
}; };
enhancementOptions?: { enhancementOptions?: {
imageStyle?: string; template?: string;
aspectRatio?: string;
} & AdvancedOptionsData; } & AdvancedOptionsData;
} }
@ -65,7 +64,7 @@ export default function DemoTTIPage() {
// Enhancement Options State // Enhancement Options State
const [aspectRatio, setAspectRatio] = useState('1:1'); const [aspectRatio, setAspectRatio] = useState('1:1');
const [imageStyle, setImageStyle] = useState(''); const [template, setTemplate] = useState('photorealistic');
const [advancedOptions, setAdvancedOptions] = useState<AdvancedOptionsData>({}); const [advancedOptions, setAdvancedOptions] = useState<AdvancedOptionsData>({});
const [showAdvancedModal, setShowAdvancedModal] = useState(false); const [showAdvancedModal, setShowAdvancedModal] = useState(false);
@ -205,32 +204,9 @@ export default function DemoTTIPage() {
const timestamp = new Date(); const timestamp = new Date();
try { try {
// Build enhancement options for right image (only non-empty values)
const rightEnhancementOptions: any = {};
if (imageStyle) {
rightEnhancementOptions.imageStyle = imageStyle;
}
if (aspectRatio) {
rightEnhancementOptions.aspectRatio = aspectRatio;
}
if (advancedOptions.mood) {
rightEnhancementOptions.mood = advancedOptions.mood;
}
if (advancedOptions.lighting) {
rightEnhancementOptions.lighting = advancedOptions.lighting;
}
if (advancedOptions.cameraAngle) {
rightEnhancementOptions.cameraAngle = advancedOptions.cameraAngle;
}
if (advancedOptions.negativePrompts && advancedOptions.negativePrompts.length > 0) {
rightEnhancementOptions.negativePrompts = advancedOptions.negativePrompts;
}
const hasEnhancementOptions = Object.keys(rightEnhancementOptions).length > 0;
// Call API twice in parallel // Call API twice in parallel
// Left: original prompt with no enhancement options // Left: original prompt WITHOUT enhancement (autoEnhance: false)
// Right: original prompt WITH enhancement options // Right: original prompt WITH enhancement (autoEnhance: true + template)
const [leftResult, rightResult] = await Promise.all([ const [leftResult, rightResult] = await Promise.all([
fetch(`${API_BASE_URL}/api/text-to-image`, { fetch(`${API_BASE_URL}/api/text-to-image`, {
method: 'POST', method: 'POST',
@ -242,6 +218,7 @@ export default function DemoTTIPage() {
prompt: prompt.trim(), prompt: prompt.trim(),
filename: `demo_${resultId}_left`, filename: `demo_${resultId}_left`,
aspectRatio, aspectRatio,
autoEnhance: false, // Explicitly disable enhancement for left image
}), }),
}), }),
fetch(`${API_BASE_URL}/api/text-to-image`, { fetch(`${API_BASE_URL}/api/text-to-image`, {
@ -254,10 +231,10 @@ export default function DemoTTIPage() {
prompt: prompt.trim(), prompt: prompt.trim(),
filename: `demo_${resultId}_right`, filename: `demo_${resultId}_right`,
aspectRatio, aspectRatio,
autoEnhance: true, autoEnhance: true, // Enable enhancement for right image
...(hasEnhancementOptions && { enhancementOptions: {
enhancementOptions: rightEnhancementOptions template: template || 'photorealistic', // Only template parameter
}), },
}), }),
}), }),
]); ]);
@ -294,6 +271,8 @@ export default function DemoTTIPage() {
request: { request: {
prompt: prompt.trim(), prompt: prompt.trim(),
filename: `demo_${resultId}_left`, filename: `demo_${resultId}_left`,
aspectRatio,
autoEnhance: false,
}, },
response: leftData, response: leftData,
geminiParams: leftData.data?.geminiParams || {}, geminiParams: leftData.data?.geminiParams || {},
@ -302,20 +281,19 @@ export default function DemoTTIPage() {
request: { request: {
prompt: prompt.trim(), prompt: prompt.trim(),
filename: `demo_${resultId}_right`, filename: `demo_${resultId}_right`,
aspectRatio,
autoEnhance: true, autoEnhance: true,
...(hasEnhancementOptions && { enhancementOptions: {
enhancementOptions: rightEnhancementOptions template: template || 'photorealistic',
}), },
}, },
response: rightData, response: rightData,
geminiParams: rightData.data?.geminiParams || {}, geminiParams: rightData.data?.geminiParams || {},
}, },
// Store enhancement options for display in inspect mode // Store enhancement options for display in inspect mode
enhancementOptions: hasEnhancementOptions ? { enhancementOptions: {
imageStyle, template,
aspectRatio, },
...advancedOptions,
} : undefined,
}; };
if (!leftData.success) { if (!leftData.success) {
@ -499,54 +477,49 @@ export default function DemoTTIPage() {
</select> </select>
</div> </div>
{/* Image Style */} {/* Template */}
<div className="flex-1 min-w-[150px]"> <div className="flex-1 min-w-[150px]">
<label htmlFor="image-style" className="block text-xs font-medium text-gray-400 mb-1.5"> <label htmlFor="template" className="block text-xs font-medium text-gray-400 mb-1.5">
Image Style Template
</label> </label>
<select <select
id="image-style" id="template"
value={imageStyle} value={template}
onChange={(e) => setImageStyle(e.target.value)} onChange={(e) => setTemplate(e.target.value)}
disabled={!apiKeyValidated || generating} disabled={!apiKeyValidated || generating}
className="w-full px-3 py-2 text-sm bg-slate-800 border border-slate-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-transparent disabled:opacity-50 disabled:cursor-not-allowed" className="w-full px-3 py-2 text-sm bg-slate-800 border border-slate-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-transparent disabled:opacity-50 disabled:cursor-not-allowed"
> >
<option value="">Auto</option>
<option value="photorealistic">Photorealistic</option> <option value="photorealistic">Photorealistic</option>
<option value="illustration">Illustration</option> <option value="illustration">Illustration</option>
<option value="minimalist">Minimalist</option> <option value="minimalist">Minimalist</option>
<option value="sticker">Sticker</option> <option value="sticker">Sticker</option>
<option value="product">Product</option> <option value="product">Product</option>
<option value="comic">Comic</option> <option value="comic">Comic</option>
<option value="general">General</option>
</select> </select>
</div> </div>
{/* Advanced Options Button */} {/* Advanced Options Button - Disabled (Coming Soon) */}
<div className="flex-1 min-w-[150px]"> <div className="flex-1 min-w-[150px]">
<label className="block text-xs font-medium text-gray-400 mb-1.5 md:invisible"> <label className="block text-xs font-medium text-gray-400 mb-1.5 md:invisible">
Advanced Advanced
</label> </label>
<div className="relative">
<button <button
onClick={() => setShowAdvancedModal(true)} disabled={true}
disabled={!apiKeyValidated || generating} className="w-full px-3 py-2 text-sm bg-slate-800 border border-slate-700 rounded-lg text-gray-500 opacity-50 cursor-not-allowed flex items-center justify-center gap-2"
className="w-full px-3 py-2 text-sm bg-slate-800 border border-slate-700 rounded-lg text-white hover:bg-slate-750 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-amber-500 flex items-center justify-center gap-2" aria-label="Advanced options (coming soon)"
aria-label="Open advanced options" title="Advanced options coming soon"
> >
<span></span> <span></span>
<span>Advanced</span> <span>Advanced</span>
{(advancedOptions.mood || advancedOptions.lighting || advancedOptions.cameraAngle || (advancedOptions.negativePrompts && advancedOptions.negativePrompts.length > 0)) && ( <span className="ml-1 px-1.5 py-0.5 text-xs bg-slate-700 text-gray-400 rounded-full">
<span className="ml-1 px-1.5 py-0.5 text-xs bg-amber-600/20 text-amber-400 rounded-full"> 🔒
{[
advancedOptions.mood,
advancedOptions.lighting,
advancedOptions.cameraAngle,
advancedOptions.negativePrompts && advancedOptions.negativePrompts.length > 0 ? 'prompts' : null
].filter(Boolean).length}
</span> </span>
)}
</button> </button>
</div> </div>
</div> </div>
</div>
{/* Generate Button & Timer */} {/* Generate Button & Timer */}
<div className="flex items-center justify-between gap-4 flex-wrap pt-2 border-t border-slate-700/50"> <div className="flex items-center justify-between gap-4 flex-wrap pt-2 border-t border-slate-700/50">