From 3bddb0012da9cdde6f54ff2e1361870c77003641 Mon Sep 17 00:00:00 2001 From: Mikhail Kilin Date: Wed, 18 Mar 2026 14:28:15 +0300 Subject: [PATCH] Add URL hash routing for direct project links Opening #/project/123 navigates directly to the project page. Back button and project selection update the hash accordingly. Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/src/App.tsx | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 0aee570..2b4cb10 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -180,23 +180,43 @@ function ProjectPage({ ); } +function parseHash(): { view: "list" | "project"; projectId: number | null } { + const hash = window.location.hash; + const match = hash.match(/^#\/project\/(\d+)$/); + if (match) return { view: "project", projectId: Number(match[1]) }; + return { view: "list", projectId: null }; +} + function App() { - const [view, setView] = useState<"list" | "project">("list"); - const [projectId, setProjectId] = useState(null); + const [view, setView] = useState<"list" | "project">(parseHash().view); + const [projectId, setProjectId] = useState(parseHash().projectId); + + useEffect(() => { + const onHashChange = () => { + const state = parseHash(); + setView(state.view); + setProjectId(state.projectId); + }; + window.addEventListener("hashchange", onHashChange); + return () => window.removeEventListener("hashchange", onHashChange); + }, []); + + const navigate = (id: number | null) => { + if (id !== null) { + window.location.hash = `#/project/${id}`; + } else { + window.location.hash = ""; + } + }; return (
{view === "list" ? ( - { - setProjectId(id); - setView("project"); - }} - /> + navigate(id)} /> ) : ( setView("list")} + onBack={() => navigate(null)} /> )}