Public
HTTP
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// This program creates an image generation service using the maxm-imggenurl API.
// It provides a simple HTML interface for users to enter a prompt and generate an image.
// The generated images are displayed in a grid, and clicking on an image shows a popup with the image and prompt.
/** @jsxImportSource https://esm.sh/react */
import React, { useState } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
// Define a type for our generated images
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);
// After generating, fetch the updated list of images
fetchImages();
} catch (error) {
console.error("Error generating image:", error);
}
setPrompt(""); // Clear the prompt after generating
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();
}
motyar-genimage.web.val.run
August 29, 2024