aboutsummaryrefslogtreecommitdiff
path: root/frontend/ts/src/pages/maps.ts
blob: ef5b7854a1adb2310f286ca7412a19a9083aeedd (plain)
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
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
    })
}