diff --git a/web/src/App.tsx b/web/src/App.tsx index 35e33ea..6a876ee 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -47,6 +47,14 @@ const ShellTerminal = lazy(async () => { }); type Screen = "loading" | "setup" | "login" | "dashboard" | "fatal"; +type DashboardPage = "home" | "car" | "adb" | "network" | "settings"; + +const dashboardPages = new Set(["home", "car", "adb", "network", "settings"]); + +function pageFromLocation(): DashboardPage { + const page = window.location.hash.replace(/^#\/?/, ""); + return dashboardPages.has(page as DashboardPage) ? (page as DashboardPage) : "home"; +} export function App() { const [screen, setScreen] = useState("loading"); @@ -171,7 +179,7 @@ function AccountScreen({ } function Dashboard({ auth, onLoggedOut }: { auth: AuthState; onLoggedOut: () => Promise }) { - const [page, setPage] = useState<"home" | "car" | "adb" | "network" | "settings">("home"); + const [page, setPage] = useState(pageFromLocation); const [status, setStatus] = useState(null); const [error, setError] = useState(""); const [connection, setConnection] = useState<"connecting" | "live" | "offline">("connecting"); @@ -202,6 +210,17 @@ function Dashboard({ auth, onLoggedOut }: { auth: AuthState; onLoggedOut: () => return () => events.close(); }, [refresh]); + useEffect(() => { + const syncPageWithLocation = () => setPage(pageFromLocation()); + window.addEventListener("hashchange", syncPageWithLocation); + return () => window.removeEventListener("hashchange", syncPageWithLocation); + }, []); + + function navigate(nextPage: DashboardPage) { + setPage(nextPage); + window.location.hash = `/${nextPage}`; + } + async function logout() { await post("/api/auth/logout", {}, auth.csrfToken); await onLoggedOut(); @@ -212,11 +231,11 @@ function Dashboard({ auth, onLoggedOut }: { auth: AuthState; onLoggedOut: () =>