diff --git a/visions/ui/src/App.tsx b/visions/ui/src/App.tsx index 98626e8..635f326 100644 --- a/visions/ui/src/App.tsx +++ b/visions/ui/src/App.tsx @@ -8,6 +8,7 @@ import { WebsocketProvider } from './components/WebsocketProvider'; import { PlayerView } from './views/PlayerView/PlayerView'; import { Admin } from './views/Admin/Admin'; import Candela from './plugins/Candela'; +import { Authentication } from './views/Authentication/Authentication'; const TEST_CHARSHEET_UUID = "12df9c09-1f2f-4147-8eda-a97bd2a7a803"; @@ -35,6 +36,10 @@ const App = ({ client }: AppProps) => { let router = createBrowserRouter([ + { + path: "/", + element: websocketUrl ? :
+ }, { path: "/gm", element: websocketUrl ? :
@@ -43,10 +48,6 @@ const App = ({ client }: AppProps) => { path: "/admin", element: }, - { - path: "/", - element: websocketUrl ? :
- }, { path: "/candela", element: diff --git a/visions/ui/src/design.css b/visions/ui/src/design.css new file mode 100644 index 0000000..7e227a4 --- /dev/null +++ b/visions/ui/src/design.css @@ -0,0 +1,15 @@ +:root { + --border-standard: 2px solid black; + --border-radius-standard: 4px; + --border-shadow-shallow: 1px 1px 2px black; + --padding-m: 8px; + --margin-s: 4px; +} + +.card { + border: var(--border-standard); + border-radius: var(--border-radius-standard); + box-shadow: var(--border-shadow-shallow); + padding: var(--padding-m); +} + diff --git a/visions/ui/src/views/Authentication/Authentication.css b/visions/ui/src/views/Authentication/Authentication.css new file mode 100644 index 0000000..ca86baf --- /dev/null +++ b/visions/ui/src/views/Authentication/Authentication.css @@ -0,0 +1,24 @@ +@import '../../design.css'; + +.auth { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100vh; +} + +.auth > div { + border: var(--border-standard); + border-radius: var(--border-radius-standard); + padding: var(--padding-m); +} + +.auth__input-line { + display: flex; + justify-content: space-between; +} + +.auth__input-line > * { + margin: var(--margin-s); +} diff --git a/visions/ui/src/views/Authentication/Authentication.tsx b/visions/ui/src/views/Authentication/Authentication.tsx new file mode 100644 index 0000000..6997fe2 --- /dev/null +++ b/visions/ui/src/views/Authentication/Authentication.tsx @@ -0,0 +1,50 @@ +import React, { PropsWithChildren, ReactNode, useContext, useEffect, useState } from 'react'; +import { Client } from '../../client'; +import { assertNever } from '../../plugins/Candela'; +import './Authentication.css'; + +interface AuthenticationProps { + client: Client; +} + +type AuthState = "NoAdmin" | "Unauthed" | "Authed"; + +export const Authentication = ({ client, children }: PropsWithChildren) => { + // No admin password set: prompt for the admin password + // Password set, nobody logged in: prompt for login + // User logged in: show the children + + let [state, setState] = useState("Unauthed"); + + switch (state) { + case "NoAdmin": { + return
+
+

Welcome to your new Visions VTT Instance

+

Set your admin password:

+ + +
+
; + } + case "Unauthed": { + return
+
+

Welcome to Visions VTT

+
+ + + +
+
+
; + } + case "Authed": { + return
{children}
; + } + default: { + assertNever(state); + return
; + } + } +}