aboutsummaryrefslogtreecommitdiff
path: root/frontend/ts/src/pages/maps.ts
diff options
context:
space:
mode:
authorJoris2025-04-19 12:36:38 +0200
committerJoris2025-04-19 12:38:24 +0200
commit632eef6424d8dc8d40c2906177892697679e7b85 (patch)
tree48d9cd60e9e96eab810b5f7bb3c7b1fa79e0438f /frontend/ts/src/pages/maps.ts
parent063d8ef9eaf874a941f4459e831057dd0a1b7ddd (diff)
Add ZIG server
Diffstat (limited to 'frontend/ts/src/pages/maps.ts')
-rw-r--r--frontend/ts/src/pages/maps.ts94
1 files changed, 94 insertions, 0 deletions
diff --git a/frontend/ts/src/pages/maps.ts b/frontend/ts/src/pages/maps.ts
new file mode 100644
index 0000000..ef5b785
--- /dev/null
+++ b/frontend/ts/src/pages/maps.ts
@@ -0,0 +1,94 @@
+import { h, withState, withState2, Html } from 'lib/rx'
+import * as request from 'request'
+import * as modal from 'ui/modal'
+import * as route from 'route'
+import { Map } from 'models/map'
+import * as form from 'lib/form'
+import * as L from 'lib/loadable'
+import * as layout from 'ui/layout'
+
+export function view(): Html {
+ return withState<L.Loadable<Array<Map>>>(L.loading, mapsVar => {
+ request
+ .get<Array<Map>>('/api/maps')
+ .then(res => {
+ res.sort((a, b) => a.name.localeCompare(b.name))
+ mapsVar.update(_ => L.loaded(res))
+ })
+ .catch(({ message }) => L.failure(message))
+
+ return h('div',
+ { className: 'g-Maps' },
+ withState<boolean>(false, showVar => [
+ h('button',
+ { className: 'g-Button g-Button--Primary',
+ onclick: (event: Event) => showVar.update(_ => true)
+ },
+ 'Nouvelle carte'
+ ),
+ showVar.map(show => {
+ if (show) {
+ return createModal({
+ onClose: () => showVar.update(_ => false)
+ })
+ }
+ })
+ ]),
+ mapsVar.map(loadable => layout.loadable(loadable, maps => h('ul', maps.map(viewMap))))
+ )
+ })
+}
+
+function viewMap(m: Map): Html {
+ const url = route.toString(route.map({ id: m.id }))
+
+ return h('li',
+ h('a', { href: url }, m.name)
+ )
+}
+
+// Create map
+
+interface CreateParams {
+ onClose: () => void,
+}
+
+function createModal({ onClose }: CreateParams): Html {
+ return modal.view({
+ header: 'Nouvelle carte',
+ body: withState2<string, L.Loadable<void>>(['', L.init], (nameVar, requestVar) =>
+ h('form',
+ {
+ onsubmit: nameVar.map(name => (event: Event) => {
+ event.preventDefault()
+ requestVar.update(_ => L.loading)
+
+ request
+ .post<Map>('/api/maps', JSON.stringify({ name }))
+ .then(map => {
+ requestVar.update(_ => L.loaded(undefined))
+ route.push(route.map({ id: map.id }))
+ })
+ .catch(({ message }) => requestVar.update(_ => L.failure(message)))
+ })
+ },
+ form.input({
+ label: 'Nom',
+ select: true,
+ onUpdate: value => {
+ nameVar.update(_ => value)
+ requestVar.update(_ => L.init)
+ },
+ required: true
+ }),
+ form.error(requestVar),
+ form.submit({
+ label: 'Créer',
+ className: 'g-Button--FullWidth',
+ requestVar
+ })
+ )
+ ),
+ onClose: onClose
+ })
+}