+ {/if}
+
+
+
+
diff --git a/ui/src/stores/selection.svelte.ts b/ui/src/stores/selection.svelte.ts
index de18a09..c6be297 100644
--- a/ui/src/stores/selection.svelte.ts
+++ b/ui/src/stores/selection.svelte.ts
@@ -1,13 +1,49 @@
-// Cross-component selection state. Currently just tracks the user
-// whose detail modal is open; App renders the modal off this store
-// so any component in the tree can open it by setting `user`.
+// Simple hash-based routing for user pages. The URL hash is the
+// source of truth:
+// #/ -> dashboard
+// #/user/ -> per-user page
+//
+// selectUser / clearSelection just mutate the hash; a hashchange
+// listener reads it back into reactive state so any component in the
+// tree re-renders when the route changes.
-export const selection = $state<{ user: string | null }>({ user: null });
+const USER_PREFIX = "#/user/";
+
+export const selection = $state<{ user: string | null }>({
+ user: readHash(),
+});
+
+function readHash(): string | null {
+ if (typeof window === "undefined") return null;
+ const h = window.location.hash;
+ if (h.startsWith(USER_PREFIX)) {
+ const addr = decodeURIComponent(h.slice(USER_PREFIX.length));
+ return addr || null;
+ }
+ return null;
+}
+
+function syncFromHash(): void {
+ selection.user = readHash();
+}
+
+if (typeof window !== "undefined") {
+ window.addEventListener("hashchange", syncFromHash);
+}
export function selectUser(address: string): void {
- selection.user = address;
+ // Set the hash; the hashchange listener updates selection.user so
+ // routing-style state stays in one place.
+ window.location.hash = USER_PREFIX + encodeURIComponent(address);
}
export function clearSelection(): void {
- selection.user = null;
+ // Prefer history.back when we arrived here via selectUser so the
+ // browser back arrow does the obvious thing; otherwise just drop
+ // the hash so a fresh page load starts on the dashboard.
+ if (window.history.length > 1 && window.location.hash.startsWith(USER_PREFIX)) {
+ window.history.back();
+ } else {
+ window.location.hash = "";
+ }
}