diff options
Diffstat (limited to 'frontend/ts/src/main.ts')
-rw-r--r-- | frontend/ts/src/main.ts | 79 |
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() + } +} |