diff --git a/packages/client/src/dungeon.client.ts b/packages/client/src/dungeon.client.ts
index b7ea3d3..70dcb68 100644
--- a/packages/client/src/dungeon.client.ts
+++ b/packages/client/src/dungeon.client.ts
@@ -37,6 +37,14 @@ export class DungeonClient {
return [...this.session.participants];
}
+ public setName(name: string): void {
+ this.socket.emit('setup/name', name);
+ }
+
+ public setReady(isReady: boolean): void {
+ this.socket.emit('setup/ready', isReady);
+ }
+
private subscribeToSocket(): void {
this.socket.on('participant/join', (participant: Participant) => {
this.addParticipant(participant);
diff --git a/packages/client/src/index.tsx b/packages/client/src/index.tsx
index 96df522..b50d03f 100644
--- a/packages/client/src/index.tsx
+++ b/packages/client/src/index.tsx
@@ -7,6 +7,7 @@ import globalStyle from './views/style.css';
import { ErrorBoundary } from 'react-error-boundary';
import { ErrorView } from './views/error/error.view';
import { ExternalStyle } from './components/external.style';
+import { ParticipantSetupView } from './views/participant.setup/participant.setup.view';
function getRootContainer(): Element {
const container = document.querySelector('#root');
@@ -23,6 +24,10 @@ createRoot(getRootContainer()).render(
} />
} />
+ }
+ />
diff --git a/packages/client/src/views/participant.setup/participant.setup.view.tsx b/packages/client/src/views/participant.setup/participant.setup.view.tsx
new file mode 100644
index 0000000..e1a6cf5
--- /dev/null
+++ b/packages/client/src/views/participant.setup/participant.setup.view.tsx
@@ -0,0 +1,56 @@
+import { useState, type ChangeEvent, type JSX } from 'react';
+import viewStyle from './style.css';
+import { app } from '#src/app';
+import { ExternalStyle } from '#src/components/external.style';
+
+function NameInput(props: { onChange: (name: string) => void }): JSX.Element {
+ const changeHandler = (event: ChangeEvent): void => {
+ props.onChange(event.target.value);
+ };
+
+ return ;
+}
+
+function ReadyButton(props: {
+ onChange: (isReady: boolean) => void;
+}): JSX.Element {
+ const [isReady, setReady] = useState();
+
+ const clickHandler = (): void => {
+ setReady(!isReady);
+ props.onChange(isReady ?? false);
+ };
+
+ return (
+
+ );
+}
+
+export function ParticipantSetupView(): JSX.Element {
+ const dungeonClient = app.items.dungeonClient;
+
+ return (
+ <>
+
+
+
Your name:
+
{
+ dungeonClient.setName(name);
+ }}
+ />
+ Ready?
+ {
+ dungeonClient.setReady(isReady);
+ }}
+ />
+
+ >
+ );
+}
diff --git a/packages/client/src/views/participant.setup/style.css b/packages/client/src/views/participant.setup/style.css
new file mode 100644
index 0000000..3196ed4
--- /dev/null
+++ b/packages/client/src/views/participant.setup/style.css
@@ -0,0 +1,49 @@
+.setup.main {
+ background-color: #262b44;
+ font-size: 2rem;
+ border: 4px solid #5a6988;
+ padding: 1rem;
+}
+
+input {
+ background-color: #181425;
+ border: 2px solid #5a6988;
+ font-size: 1em;
+ color: white;
+ text-align: center;
+}
+
+.setup.ready {
+ border: none;
+
+ font-size: 1.5em;
+ width: 1.5em;
+ height: 1.5em;
+ border-radius: 100%;
+ text-align: center;
+ vertical-align: center;
+
+ color: #ff0044;
+
+ background: rgb(139, 155, 180);
+ background: radial-gradient(
+ circle,
+ rgba(139, 155, 180, 1) 9%,
+ rgba(90, 105, 136, 1) 51%,
+ rgba(58, 68, 102, 1) 100%
+ );
+}
+
+.setup.ready:active {
+ background: rgb(58, 68, 102);
+ background: radial-gradient(
+ circle,
+ rgba(58, 68, 102, 1) 9%,
+ rgba(58, 68, 102, 1) 51%,
+ rgba(90, 105, 136, 1) 100%
+ );
+}
+
+.setup.ready.active {
+ color: #63c74d;
+}
diff --git a/packages/shared/src/api/frontend.routes.ts b/packages/shared/src/api/frontend.routes.ts
index f91bdab..8ef594a 100644
--- a/packages/shared/src/api/frontend.routes.ts
+++ b/packages/shared/src/api/frontend.routes.ts
@@ -1,5 +1,6 @@
export const frontendRoutes = {
index: '/',
- lobby: '/lobby/:id',
- join: '/join/:id',
+ lobby: '/watch/:id/lobby',
+ join: '/play/:id',
+ participantSetup: '/play/:id/setup',
};
diff --git a/packages/shared/src/api/socket.events.ts b/packages/shared/src/api/socket.events.ts
index 218a874..dc33d39 100644
--- a/packages/shared/src/api/socket.events.ts
+++ b/packages/shared/src/api/socket.events.ts
@@ -14,4 +14,9 @@ interface ParticipantEventMap extends EventMap {
'participant/update': (participant: Participant) => void;
}
-export type SocketEventMap = ParticipantEventMap;
+interface SetupEventMap extends EventMap {
+ 'setup/name': (name: string) => void;
+ 'setup/ready': (isReady: boolean) => void;
+}
+
+export interface SocketEventMap extends ParticipantEventMap, SetupEventMap {}