import React, { useState, useCallback } from ‘react’;
import { generateImagesService } from ‘./services/geminiService’;
import { STYLES, ASPECT_RATIOS } from ‘./constants’;
import type { ImageStyle, AspectRatio, GenerationOptions, HistoryItem } from ‘./types’;
import Loader from ‘./components/Loader’;
import { OptionSelector } from ‘./components/OptionSelector’;
const Header: React.FC = () => (
);
const ImageDisplay: React.FC<{ imageUrl: string | null; isLoading: boolean; error: string | null }> = ({ imageUrl, isLoading, error }) => (
{isLoading &&
}
{error && !isLoading && (
Generation Failed
{error}
)}
{!isLoading && !error && imageUrl && (
)}
{!isLoading && !error && !imageUrl && (
Your generated image will appear here.
Describe a vision, and let the AI paint it.
)}
);
const HistoryPanel: React.FC<{ history: HistoryItem[], onSelect: (item: HistoryItem) => void }> = ({ history, onSelect }) => (
History
{history.length === 0 ? (
No generations yet.
) : (
{history.map(item => (
onSelect(item)}
className=»group flex items-center gap-3 p-2 rounded-md bg-gray-700/50 hover:bg-cyan-900/50 cursor-pointer transition-colors duration-200″
>
{item.prompt}
))}
)}
);
function App() {
const [prompt, setPrompt] = useState(«A futuristic cityscape at night, with flying cars and neon signs, in a synthwave style.»);
const [options, setOptions] = useState({
style: ‘Cyberpunk’,
aspectRatio: ’16:9′,
});
const [generatedImageUrl, setGeneratedImageUrl] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const [history, setHistory] = useState([]);
const handleGenerate = useCallback(async () => {
if (!prompt || isLoading) return;
setIsLoading(true);
setError(null);
setGeneratedImageUrl(null);
try {
const images = await generateImagesService(prompt, options);
if (images && images.length > 0) {
const imageUrl = images[0];
setGeneratedImageUrl(imageUrl);
const newHistoryItem: HistoryItem = {
id: new Date().toISOString(),
prompt,
imageUrl,
options,
};
setHistory(prev => [newHistoryItem, …prev.slice(0, 19)]); // Keep history to 20 items
} else {
setError(«The model did not return an image. Try a different prompt.»);
}
} catch (e) {
setError(e instanceof Error ? e.message : «An unknown error occurred.»);
} finally {
setIsLoading(false);
}
}, [prompt, options, isLoading]);
const handleHistorySelect = (item: HistoryItem) => {
setPrompt(item.prompt);
setOptions(item.options);
setGeneratedImageUrl(item.imageUrl);
};
return (
);
}
export default App;