Public
HTTP (deprecated)
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 web app creates a Side School Seminar location voting system.
* Users can vote for their preferred seminar location from four options.
* The app uses React for the frontend and SQLite for storing votes on the backend.
* The design is inspired by Side.school and includes an image in the first frame.
* It features a celebration animation when voting, a distinct style for the selected option,
* and allows users to cancel their vote by clicking on the selected option again.
*/
/** @jsxImportSource https://esm.sh/react */
import React, { useState, useEffect } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
const locations = [
{ id: 1, name: "Au camping", emoji: "⛺" },
{ id: 2, name: "Chez Ben", emoji: "🏢" },
{ id: 3, name: "Au Château", emoji: "🏰" },
{ id: 4, name: "Sur Saturne", emoji: "🪐" },
];
function App() {
const [votes, setVotes] = useState({});
const [selectedLocation, setSelectedLocation] = useState(null);
const [showCelebration, setShowCelebration] = useState(false);
useEffect(() => {
fetchVotes();
}, []);
const fetchVotes = async () => {
try {
const response = await fetch("/votes");
const data = await response.json();
console.log("Fetched votes:", data);
setVotes(data);
} catch (error) {
console.error("Error fetching votes:", error);
}
};
const handleVote = async (locationId) => {
console.log("Voting for location:", locationId);
try {
const response = await fetch("/vote", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ locationId }),
});
if (response.ok) {
const result = await response.json();
console.log("Vote result:", result);
setVotes(prevVotes => ({
...prevVotes,
[locationId]: result.newCount
}));
if (selectedLocation === locationId) {
// Annuler le vote
setSelectedLocation(null);
} else {
// Nouveau vote
setSelectedLocation(locationId);
setShowCelebration(true);
setTimeout(() => setShowCelebration(false), 2000);
}
} else {
console.error("Vote failed:", await response.text());
}
} catch (error) {
console.error("Error voting:", error);
}
};
return (
<div className="container">
<div className="image-frame"></div>
<div className="content">
<h1>Side School Seminar</h1>
<h2>Choose the location:</h2>
<div className="locations">
{locations.map((location) => (
<button
key={location.id}
onClick={() => handleVote(location.id)}
className={location.id === selectedLocation ? "selected" : ""}
>
<span className="emoji">{location.emoji}</span>
<span className="name">{location.name}</span>
<span className="votes">{votes[location.id] || 0} votes</span>
</button>
))}
</div>
{selectedLocation !== null && <p>Thank you for voting! Click your choice again to cancel.</p>}
</div>
{showCelebration && <div className="celebration">🎉🎊🥳</div>}
</div>
);
}
function client() {
olive-linkinbiotemplate.web.val.run
August 25, 2024