From e9a76553095378f52e5ca0e282884f1bad52b241 Mon Sep 17 00:00:00 2001 From: ComputelessComputer Date: Tue, 25 Nov 2025 01:29:52 +0900 Subject: [PATCH] feat: add search state management for about page details --- apps/web/src/routes/_view/about.tsx | 55 +++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/apps/web/src/routes/_view/about.tsx b/apps/web/src/routes/_view/about.tsx index b93a17c84a..387ead3d7d 100644 --- a/apps/web/src/routes/_view/about.tsx +++ b/apps/web/src/routes/_view/about.tsx @@ -1,7 +1,7 @@ import { Icon } from "@iconify-icon/react"; -import { createFileRoute } from "@tanstack/react-router"; +import { createFileRoute, useNavigate } from "@tanstack/react-router"; import { Mail, XIcon } from "lucide-react"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { ResizableHandle, @@ -13,8 +13,24 @@ import { cn } from "@hypr/utils"; import { Image } from "@/components/image"; import { MockWindow } from "@/components/mock-window"; +type AboutSearch = { + type?: "story" | "founder" | "photo"; + id?: string; +}; + export const Route = createFileRoute("/_view/about")({ component: Component, + validateSearch: (search: Record): AboutSearch => { + return { + type: + search.type === "story" || + search.type === "founder" || + search.type === "photo" + ? search.type + : undefined, + id: typeof search.id === "string" ? search.id : undefined, + }; + }, head: () => ({ meta: [ { title: "Team - Hyprnote Press Kit" }, @@ -136,8 +152,41 @@ type SelectedItem = | { type: "photo"; data: (typeof teamPhotos)[0] }; function Component() { + const navigate = useNavigate({ from: Route.fullPath }); + const search = Route.useSearch(); const [selectedItem, setSelectedItem] = useState(null); + useEffect(() => { + if (search.type === "story") { + setSelectedItem({ type: "story" }); + } else if (search.type === "founder" && search.id) { + const founder = founders.find((f) => f.id === search.id); + if (founder) { + setSelectedItem({ type: "founder", data: founder }); + } + } else if (search.type === "photo" && search.id) { + const photo = teamPhotos.find((p) => p.id === search.id); + if (photo) { + setSelectedItem({ type: "photo", data: photo }); + } + } else { + setSelectedItem(null); + } + }, [search.type, search.id]); + + const handleSetSelectedItem = (item: SelectedItem | null) => { + setSelectedItem(item); + if (item === null) { + navigate({ search: {} }); + } else if (item.type === "story") { + navigate({ search: { type: "story" } }); + } else if (item.type === "founder") { + navigate({ search: { type: "founder", id: item.data.id } }); + } else if (item.type === "photo") { + navigate({ search: { type: "photo", id: item.data.id } }); + } + }; + return (