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 app implements a "Would You Rather" game with a ranking system for answers and a progress bar.
* It uses React for the frontend and SQLite for persistent storage on the backend.
* The ranking system updates based on user choices and displays in the Answers tab.
* A progress bar is added to show completion of 20 questions.
*/
/** @jsxImportSource https://esm.sh/react */
import React, { useCallback, useEffect, useState } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
import {
BrowserRouter as Router,
Link,
Route,
Routes,
useLocation,
useNavigate,
} from "https://esm.sh/react-router-dom";
// Types
type Question = { id: number; option1: string; option2: string };
type Answer = { questionId: number; answer: string };
type User = { id: number; username: string };
type EloRanking = { answer: string; score: number };
// Constants
const ANSWER_OPTIONS = [
"Have the ability to see through people's clothes",
"Have the ability to murder anyone without any consequences",
"Have a tight knit and loyal friend group",
"Have another set of eyes in the back of your head (they are fully functional)",
"Have a very physically attractive romantic partner",
"Be able to spawn pizzas by snapping your fingers (max 2 per 12 hours)",
"Be able to eat whatever you want and stay at your ideal weight",
"Have perfect health your whole life except for the illness that will eventually kill you",
"Have a job you like that pays 3x the usual salary",
];
function App() {
const [user, setUser] = useState<User | null>(null);
const [answers, setAnswers] = useState<Answer[]>([]);
const [rankings, setRankings] = useState<EloRanking[]>([]);
const [progress, setProgress] = useState(0);
const [showSplash, setShowSplash] = useState(true);
useEffect(() => {
fetchAnswersAndRankings();
}, [user]);
const fetchAnswersAndRankings = async () => {
if (user) {
const response = await fetch("/api/answers");
const data = await response.json();
setAnswers(data.answers);
setRankings(data.rankings);
setProgress(Math.min(data.answers.length / 20 * 100, 100));
}
};
const saveAnswer = useCallback(async (newAnswer: Answer, losingAnswer: string) => {
if (user) {
await fetch("/api/answer", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ ...newAnswer, losingAnswer }),
});
fetchAnswersAndRankings();
}
}, [user]);
const clearAnswers = useCallback(async () => {
if (user) {
await fetch("/api/clear-answers", { method: "POST" });
setAnswers([]);
setRankings([]);
setProgress(0);
}
}, [user]);
return (
<Router>
<div className="app">
{showSplash ? <SplashScreen onGetStarted={() => setShowSplash(false)} /> : (
<>
<header>
<h1>Woodu</h1>
<div className="progress-bar">
<div className="progress" style={{ width: `${progress}%` }}></div>
</div>
</header>
<main>
<Routes>
<Route path="/" element={<Game user={user} saveAnswer={saveAnswer} />} />
<Route
path="/answers"
element={<Answers user={user} answers={answers} rankings={rankings} clearAnswers={clearAnswers} />}
/>
<Route path="/profile" element={<Profile user={user} setUser={setUser} />} />
</Routes>
</main>
<TabBar />
kaz-reluctantcoffeegayal.web.val.run
August 22, 2024