Files
Brancheneinstufung2/k-pop-thumbnail-genie/components/ImageResult.tsx

104 lines
4.2 KiB
TypeScript

import React, { useState } from 'react';
import { GenerationResult } from '../types';
import { DownloadIcon } from './icons/DownloadIcon';
import { MagicIcon } from './icons/MagicIcon';
interface ImageResultProps {
result: GenerationResult | null;
onRefine: (refinementPrompt: string) => void;
masterPrompt: string;
isLoading: boolean;
loadingMessage: string;
onStartOver: () => void;
}
const ImageResult: React.FC<ImageResultProps> = ({ result, onRefine, masterPrompt, isLoading, loadingMessage, onStartOver }) => {
const [refinementPrompt, setRefinementPrompt] = useState('');
const handleRefineSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (refinementPrompt.trim()) {
onRefine(refinementPrompt);
setRefinementPrompt('');
}
};
if (!result) {
return (
<div className="text-center">
<p>Something went wrong. No image was generated.</p>
<button onClick={onStartOver} className="mt-4 bg-purple-600 hover:bg-purple-700 text-white font-bold py-2 px-4 rounded">Start Over</button>
</div>
);
}
return (
<div className="w-full flex flex-col lg:flex-row gap-8">
<div className="lg:w-2/3 relative">
<div className="aspect-w-16 aspect-h-9 bg-black rounded-lg overflow-hidden shadow-lg">
<img src={`data:image/png;base64,${result.currentImage}`} alt="Generated thumbnail" className="w-full h-full object-contain" />
</div>
{isLoading && (
<div className="absolute inset-0 bg-black/70 flex flex-col items-center justify-center text-center p-4 rounded-lg">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-purple-400 mb-4"></div>
<p className="text-lg text-purple-300">{loadingMessage}</p>
</div>
)}
</div>
<div className="lg:w-1/3 flex flex-col">
<h2 className="text-2xl font-bold text-gray-100 mb-4">Your Masterpiece</h2>
<div className="flex-grow space-y-6">
<form onSubmit={handleRefineSubmit}>
<label htmlFor="refinement-prompt" className="block text-lg font-semibold text-purple-300 mb-2">
Refine Your Image
</label>
<textarea
id="refinement-prompt"
value={refinementPrompt}
onChange={(e) => setRefinementPrompt(e.target.value)}
placeholder="e.g., 'Make the smile a little softer.' or 'Change the background to be more blurry.'"
className="w-full bg-gray-700 border border-gray-600 rounded-lg p-3 text-base h-24 focus:ring-2 focus:ring-purple-500 focus:border-purple-500 transition"
required
/>
<button
type="submit"
disabled={isLoading || !refinementPrompt}
className="w-full mt-3 bg-purple-600 hover:bg-purple-700 disabled:bg-gray-600 text-white font-bold py-2.5 px-4 rounded-lg transition-colors duration-300 flex items-center justify-center gap-2"
>
<MagicIcon className="w-5 h-5"/> Refine
</button>
</form>
<div>
<details className="bg-gray-700/50 rounded-lg">
<summary className="cursor-pointer text-purple-300 font-semibold p-3">View Master Prompt</summary>
<p className="p-3 pt-0 text-gray-400 text-sm">{masterPrompt}</p>
</details>
</div>
</div>
<div className="mt-8 space-y-3">
<a
href={`data:image/png;base64,${result.currentImage}`}
download="kpop-thumbnail.png"
className="w-full bg-green-600 hover:bg-green-700 text-white font-bold py-3 px-4 rounded-lg transition-colors duration-300 flex items-center justify-center gap-2 text-lg"
>
<DownloadIcon className="w-6 h-6" /> Download Image
</a>
<button
onClick={onStartOver}
className="w-full bg-gray-600 hover:bg-gray-500 text-white font-bold py-2 px-4 rounded-lg transition-colors duration-300"
>
Start Over
</button>
</div>
</div>
</div>
);
};
export default ImageResult;