Preserve dashboard page across refreshes
This commit is contained in:
+25
-6
@@ -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<DashboardPage>(["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<Screen>("loading");
|
||||
@@ -171,7 +179,7 @@ function AccountScreen({
|
||||
}
|
||||
|
||||
function Dashboard({ auth, onLoggedOut }: { auth: AuthState; onLoggedOut: () => Promise<void> }) {
|
||||
const [page, setPage] = useState<"home" | "car" | "adb" | "network" | "settings">("home");
|
||||
const [page, setPage] = useState<DashboardPage>(pageFromLocation);
|
||||
const [status, setStatus] = useState<SystemStatus | null>(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: () =>
|
||||
<aside className="sidebar">
|
||||
<div className="brand brand-compact"><Gauge size={30} weight="duotone" /><span>Pi Companion</span></div>
|
||||
<nav aria-label="Primary navigation">
|
||||
<button className={`nav-item ${page === "home" ? "active" : ""}`} onClick={() => setPage("home")}><House size={24} weight={page === "home" ? "fill" : "regular"} /><span>Home</span></button>
|
||||
<button className={`nav-item ${page === "car" ? "active" : ""}`} onClick={() => setPage("car")}><CarProfile size={24} weight={page === "car" ? "fill" : "regular"} /><span>Car</span></button>
|
||||
<button className={`nav-item ${page === "adb" ? "active" : ""}`} onClick={() => setPage("adb")}><AndroidLogo size={24} weight={page === "adb" ? "fill" : "regular"} /><span>ADB</span></button>
|
||||
<button className={`nav-item ${page === "network" ? "active" : ""}`} onClick={() => setPage("network")}><WifiHigh size={24} weight={page === "network" ? "fill" : "regular"} /><span>Network</span></button>
|
||||
<button className={`nav-item ${page === "settings" ? "active" : ""}`} onClick={() => setPage("settings")}><Gear size={24} weight={page === "settings" ? "fill" : "regular"} /><span>Settings</span></button>
|
||||
<button className={`nav-item ${page === "home" ? "active" : ""}`} onClick={() => navigate("home")}><House size={24} weight={page === "home" ? "fill" : "regular"} /><span>Home</span></button>
|
||||
<button className={`nav-item ${page === "car" ? "active" : ""}`} onClick={() => navigate("car")}><CarProfile size={24} weight={page === "car" ? "fill" : "regular"} /><span>Car</span></button>
|
||||
<button className={`nav-item ${page === "adb" ? "active" : ""}`} onClick={() => navigate("adb")}><AndroidLogo size={24} weight={page === "adb" ? "fill" : "regular"} /><span>ADB</span></button>
|
||||
<button className={`nav-item ${page === "network" ? "active" : ""}`} onClick={() => navigate("network")}><WifiHigh size={24} weight={page === "network" ? "fill" : "regular"} /><span>Network</span></button>
|
||||
<button className={`nav-item ${page === "settings" ? "active" : ""}`} onClick={() => navigate("settings")}><Gear size={24} weight={page === "settings" ? "fill" : "regular"} /><span>Settings</span></button>
|
||||
</nav>
|
||||
<button className="nav-item logout" onClick={() => void logout()}><SignOut size={24} /><span>Sign out</span></button>
|
||||
</aside>
|
||||
|
||||
Reference in New Issue
Block a user