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 dating app allows users to upload photos of their bedside table and phone case.
* It uses Val Town's SQLite for data persistence and blob storage for image uploads.
* The app includes a simple matching algorithm based on common items in bedside tables.
*/
/** @jsxImportSource https://esm.sh/react */
import React, { useState, useEffect } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
function App() {
const [user, setUser] = useState(null);
const [matches, setMatches] = useState([]);
const [bedsideImage, setBedsideImage] = useState(null);
const [phoneCaseImage, setPhoneCaseImage] = useState(null);
useEffect(() => {
fetchUser();
fetchMatches();
}, []);
const fetchUser = async () => {
const response = await fetch('/user');
if (response.ok) {
const userData = await response.json();
setUser(userData);
setBedsideImage(userData.bedsideImage);
setPhoneCaseImage(userData.phoneCaseImage);
}
};
const fetchMatches = async () => {
const response = await fetch('/matches');
if (response.ok) {
const matchesData = await response.json();
setMatches(matchesData);
}
};
const handleImageUpload = async (event, type) => {
const file = event.target.files[0];
const formData = new FormData();
formData.append('image', file);
formData.append('type', type);
const response = await fetch('/upload', {
method: 'POST',
body: formData,
});
if (response.ok) {
const result = await response.json();
if (type === 'bedside') {
setBedsideImage(result.imageUrl);
} else {
setPhoneCaseImage(result.imageUrl);
}
}
};
return (
<div className="app">
<h1>Bedside & Case Dating App</h1>
{user ? (
<div>
<h2>Welcome, {user.name}!</h2>
<div className="image-upload">
<h3>Your Bedside Table</h3>
{bedsideImage ? (
<img src={bedsideImage} alt="Bedside Table" className="uploaded-image" />
) : (
<input type="file" onChange={(e) => handleImageUpload(e, 'bedside')} />
)}
</div>
<div className="image-upload">
<h3>Your Phone Case</h3>
{phoneCaseImage ? (
<img src={phoneCaseImage} alt="Phone Case" className="uploaded-image" />
) : (
<input type="file" onChange={(e) => handleImageUpload(e, 'phonecase')} />
)}
</div>
<h3>Your Matches</h3>
<div className="matches">
{matches.map((match) => (
<div key={match.id} className="match">
<h4>{match.name}</h4>
<img src={match.bedsideImage} alt="Bedside Table" className="match-image" />
<img src={match.phoneCaseImage} alt="Phone Case" className="match-image" />
</div>
))}
</div>
</div>
) : (
<p>Loading...</p>
)}
<footer>
<a href={import.meta.url.replace("esm.town", "val.town")}>View Source</a>
</footer>
</div>
ejfox-eldestbronzeptarmigan.web.val.run
August 20, 2024