import React, { useState } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
type GeneratedImage = { imageUrl: string; prompt: string };
function App() {
const [prompt, setPrompt] = useState("");
const [imageUrl, setImageUrl] = useState("");
const [loading, setLoading] = useState(false);
const generateImage = async () => {
setLoading(true);
try {
const response = await fetch(`/generate?prompt=${encodeURIComponent(prompt)}`, { method: 'POST' });
const data = await response.json();
setImageUrl(data.imageUrl);
fetchImages();
} catch (error) {
console.error("Error generating image:", error);
}
setPrompt("");
setLoading(false);
};
const [images, setImages] = useState<GeneratedImage[]>([]);
const [selectedImage, setSelectedImage] = useState<GeneratedImage | null>(null);
const fetchImages = async () => {
try {
const response = await fetch('/images');
const data = await response.json();
setImages(data);
} catch (error) {
console.error("Error fetching images:", error);
}
};
React.useEffect(() => {
fetchImages();
}, []);
const openPopup = (image: GeneratedImage) => {
setSelectedImage(image);
};
const closePopup = () => {
setSelectedImage(null);
};
return (
<div className="container">
<h1>AI Image Generator</h1>
<div className="input-container">
<input
type="text"
value={prompt}
onChange={(e) => setPrompt(e.target.value)}
placeholder="Enter your image prompt"
/>
<button onClick={generateImage} disabled={loading || !prompt}>
{loading ? "Generating..." : "Generate Image"}
</button>
</div>
<div className="image-grid">
{images.map((image, index) => (
<div key={index} className="image-item" onClick={() => openPopup(image)}>
<img src={image.imageUrl} alt={image.prompt} />
</div>
))}
</div>
{selectedImage && (
<div className="popup-overlay" onClick={closePopup}>
<div className="popup-content" onClick={(e) => e.stopPropagation()}>
<img src={selectedImage.imageUrl} alt={selectedImage.prompt} />
<p>{selectedImage.prompt}</p>
<button onClick={closePopup}>Close</button>
</div>
</div>
)}
<p className="footer">
View source on <a href={import.meta.url.replace("esm.town", "val.town")}>Val Town</a>
</p>
</div>
);
}
function client() {
createRoot(document.getElementById("root")).render(<App />);
}
if (typeof document !== "undefined") {
client();
}