aboutsummaryrefslogtreecommitdiff
path: root/frontend/ts/src/main.ts
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/ts/src/main.ts')
-rw-r--r--frontend/ts/src/main.ts79
1 files changed, 79 insertions, 0 deletions
diff --git a/frontend/ts/src/main.ts b/frontend/ts/src/main.ts
new file mode 100644
index 0000000..e94043b
--- /dev/null
+++ b/frontend/ts/src/main.ts
@@ -0,0 +1,79 @@
+import { h, Html } from 'lib/rx'
+import * as rx from 'lib/rx'
+import * as layout from 'ui/layout'
+import * as request from 'request'
+import * as login from 'pages/login'
+import * as maps from 'pages/maps'
+import * as notFound from 'pages/notFound'
+import * as route from 'route'
+import * as pagesLayout from 'pages/layout'
+import * as map from 'pages/map'
+import * as L from 'lib/loadable'
+import { User } from 'models/user'
+
+// Push internal route when clicking on link
+document.addEventListener('click', (event: Event) => {
+ if (event.target !== null) {
+ const element = event.target as HTMLElement
+ const href = element.getAttribute('href')
+ if (href !== null) {
+ const r = route.get(href)
+ if (r !== undefined) {
+ event.preventDefault()
+ route.push(r)
+ }
+ }
+ }
+})
+
+rx.mount(
+ document.body,
+ rx.withState<route.Route | undefined>(route.get(window.location.pathname), routeVar =>
+ rx.withState<L.Loadable<User>>(L.init, userLoadableVar => {
+ window.onpopstate = (event: Event) => {
+ routeVar.update(_ => route.get(window.location.pathname))
+ }
+
+ return rx.map2([routeVar, userLoadableVar], (route, userLoadable) =>
+ view({
+ route,
+ userLoadable,
+ updateUser: userLoadable => userLoadableVar.update(_ => userLoadable)
+ })
+ )
+ })
+ )
+)
+
+interface ViewParams {
+ route: route.Route | undefined
+ userLoadable: L.Loadable<User>
+ updateUser: (userLoadable: L.Loadable<User>) => void
+}
+
+function view({ route, userLoadable, updateUser }: ViewParams): Html {
+ if (route?.state == 'login') {
+ return login.view({ updateUser: (user: User) => updateUser(L.loaded(user)) })
+ } else {
+ if (userLoadable == L.init) {
+ request
+ .get<User>('/api/user')
+ .then(user => updateUser(L.loaded(user)))
+ .catch(({ message }) => updateUser(L.failure(message)))
+ }
+
+ return layout.loadable(userLoadable, user =>
+ pagesLayout.view(user, viewLoggedIn(route))
+ )
+ }
+}
+
+function viewLoggedIn(route?: route.Route): Html {
+ if (route?.state == 'maps') {
+ return maps.view()
+ } else if (route?.state == 'map') {
+ return map.view(route.id)
+ } else {
+ return notFound.view()
+ }
+}