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
/** @jsxImportSource https://esm.sh/react */
import React, { useEffect } from "https://esm.sh/react";
import { createRoot, hydrateRoot } from "https://esm.sh/react-dom/client";
import { renderToString } from "https://esm.sh/react-dom/server";
import { collectionColors } from "https://esm.town/v/peterqliu/vtm_constants";
function handleKeyDown(e) {
alert(JSON.stringify(e));
}
function App() {
const [collections, setCollections] = React.useState([]);
const [links, setLinks] = React.useState([]);
const [vals, setVals] = React.useState([]);
const [selected, setSelected] = React.useState([]);
const [selectedCollection, setSelectedCollection] = React.useState();
const update = {
vals: async function() {
api.fetch("vals")
.then(setVals);
},
collections: async function() {
api.fetch("collections")
.then(d => setCollections(d.map(([id, name]) => ({ id, name }))));
},
links: async function() {
api.fetch("links")
.then(d => setLinks(d.map(([project, val]) => ({ project, val }))));
},
};
useEffect(() => {
update.vals();
update.collections();
update.links();
}, []);
// clear val selection whenever new collection viewed, or val list changes
useEffect(() => {
setSelected([]);
}, [selectedCollection, vals]);
function handleClick(v) {
const { id } = v;
if (selected.includes(id)) setSelected(selected.filter(s => s !== id));
else setSelected([...selected, id]);
}
async function createCollection() {
const confirmAdd = prompt("Create new collection", "Collection");
const newCollectionId = JSON.stringify(Date.now());
if (confirmAdd) {
const collectionResponse = await api.fetch("newCollection", {
method: "POST",
body: api.formData({ collection: confirmAdd, id: newCollectionId }),
});
const linkResponse = await api.fetch("newLinks", {
method: "POST",
body: api.formData({ links: JSON.stringify(selected.map(s => ({ val: s, project: newCollectionId }))) }),
});
console.log(selected);
setSelected([]);
api.fetch("collections")
.then(d => setCollections(d.map(([id, name]) => ({ id, name }))));
// if (response.ok) setUploadStatus("Image uploaded successfully!");
// else setUploadStatus("Upload failed. Please try again.");
}
}
function CollectionList({ collections }) {
return (
<aside>
<button onClick={createCollection}>Create collection</button>
{selectedCollection
? (
<button onClick={() => updateCollections("deleteCollection")}>
Delete collection
</button>
)
: null}
<nav>
<detail>
<summary onClick={() => setSelectedCollection(false)}>All vals</summary>
<summary>Collections</summary>
<ul>
{collections.map((c, cI) => {
return (
<li
style={{ color: collectionColors[cI] }}
className={c.id === selectedCollection ? "selected" : ""}
onClick={() => setSelectedCollection(c.id)}
>
{c.name}
</li>
);
})}
</ul>
peterqliu-mayor.web.val.run
September 18, 2024