diff --git a/frontend/react/src/ui/modals/components/modal.tsx b/frontend/react/src/ui/modals/components/modal.tsx
index 2e5eb931..2ad7fb53 100644
--- a/frontend/react/src/ui/modals/components/modal.tsx
+++ b/frontend/react/src/ui/modals/components/modal.tsx
@@ -1,10 +1,16 @@
import React, { useEffect, useState } from "react";
import { ModalEvent } from "../../../events";
import { FaXmark } from "react-icons/fa6";
-import { getApp, OlympusApp } from "../../../olympusapp";
+import { getApp } from "../../../olympusapp";
import { OlympusState } from "../../../constants/constants";
-export function Modal(props: { open: boolean; children?: JSX.Element | JSX.Element[]; className?: string; size?: "sm" | "md" | "lg" | "full" }) {
+export function Modal(props: {
+ open: boolean;
+ children?: JSX.Element | JSX.Element[];
+ className?: string;
+ size?: "sm" | "md" | "lg" | "full";
+ disableClose?: boolean;
+}) {
const [splash, setSplash] = useState(Math.ceil(Math.random() * 7));
useEffect(() => {
@@ -15,21 +21,47 @@ export function Modal(props: { open: boolean; children?: JSX.Element | JSX.Eleme
<>
{props.open && (
<>
-
+
-

+
{props.children}
-
- {
- getApp().setState(OlympusState.IDLE);
- }}
- />{" "}
-
+ {!props.disableClose && (
+
+ {
+ getApp().setState(OlympusState.IDLE);
+ }}
+ />{" "}
+
+ )}
diff --git a/frontend/react/src/ui/modals/loginmodal.tsx b/frontend/react/src/ui/modals/loginmodal.tsx
index df5afb0f..402d8607 100644
--- a/frontend/react/src/ui/modals/loginmodal.tsx
+++ b/frontend/react/src/ui/modals/loginmodal.tsx
@@ -3,12 +3,12 @@ import { Modal } from "./components/modal";
import { Card } from "./components/card";
import { ErrorCallout } from "../components/olcallout";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { faArrowRight, faCheckCircle, faExternalLink } from "@fortawesome/free-solid-svg-icons";
+import { faArrowLeft, faArrowRight, faCheckCircle, faExternalLink } from "@fortawesome/free-solid-svg-icons";
import { getApp, VERSION } from "../../olympusapp";
import { sha256 } from "js-sha256";
import { LoginSubState, NO_SUBSTATE, OlympusState } from "../../constants/constants";
import { OlDropdown, OlDropdownItem } from "../components/oldropdown";
-import { AppStateChangedEvent, EnabledCommandModesChangedEvent, MissionDataChangedEvent, WrongCredentialsEvent } from "../../events";
+import { AppStateChangedEvent, EnabledCommandModesChangedEvent, WrongCredentialsEvent } from "../../events";
export function LoginModal(props: { open: boolean }) {
const [subState, setSubState] = useState(NO_SUBSTATE);
@@ -18,6 +18,7 @@ export function LoginModal(props: { open: boolean }) {
const [loginError, setLoginError] = useState(false);
const [commandModes, setCommandModes] = useState(null as null | string[]);
const [activeCommandMode, setActiveCommandMode] = useState(null as null | string);
+ const [loginByRole, setLoginByRole] = useState(true);
useEffect(() => {
AppStateChangedEvent.on((state, subState) => {
@@ -29,6 +30,11 @@ export function LoginModal(props: { open: boolean }) {
});
}, []);
+ const updateUsername = useCallback(() => {
+ loginByRole ? setUsername("Game master") : setUsername("");
+ }, [loginByRole]);
+ useEffect(updateUsername, [loginByRole]);
+
const usernameCallback = useCallback(() => getApp()?.getServerManager().setUsername(username), [username]);
useEffect(usernameCallback, [username]);
@@ -80,7 +86,7 @@ export function LoginModal(props: { open: boolean }) {
useEffect(subStateCallback, [subState]);
return (
-
+
{!checkingPassword ? (
<>
-
-
- Connect to
-
-
- {window.location.toString()}
-
-
{subState === LoginSubState.CREDENTIALS && (
<>
-
-
+
+
+ {loginByRole ? (
+ <>
+
+
+ {setUsername("Game master")}}>Game master
+ {setUsername("Blue commander")}}>Blue commander
+ {setUsername("Red commander")}}>Red commander
+
+
+ >
+ ) : (
+ <>
+
+
setUsername(ev.currentTarget.value)}
+ className={`
+ block w-full rounded-lg border border-gray-300
+ bg-gray-50 p-2.5 text-sm text-gray-900
+ dark:border-gray-600 dark:bg-gray-700
+ dark:text-white dark:placeholder-gray-400
+ dark:focus:border-blue-500
+ dark:focus:ring-blue-500
+ focus:border-blue-500 focus:ring-blue-500
+ `}
+ placeholder="Enter username"
+ value={username}
+ required
+ />
+ >
+ )}
+
)}
+
-
+
YouTube Video Guide
@@ -348,9 +420,9 @@ export function LoginModal(props: { open: boolean }) {
object-cover
`}
>
-
+
Wiki Guide
diff --git a/frontend/react/src/ui/ui.tsx b/frontend/react/src/ui/ui.tsx
index 8a3cecf5..ff53ff02 100644
--- a/frontend/react/src/ui/ui.tsx
+++ b/frontend/react/src/ui/ui.tsx
@@ -73,7 +73,6 @@ export function UI() {
-