From bf41ba038e276ffcd7d03098a6e42d7c4e14c35b Mon Sep 17 00:00:00 2001 From: parsa aghaei Date: Sat, 22 Aug 2026 14:04:30 +0330 Subject: [PATCH] feat(dashboard): persist active tab in URL and keep active tab on reload --- frontend/application/app/dashboard/page.tsx | 8 +- .../application/components/UserDashboard.tsx | 27 +- graphify-out/.graphify_labels.json | 3 +- graphify-out/.graphify_labels.json.sig | 2 +- graphify-out/2026-08-22/.graphify_labels.json | 90 +- graphify-out/2026-08-22/GRAPH_REPORT.md | 492 +- graphify-out/2026-08-22/graph.json | 22750 +++++++++++----- graphify-out/2026-08-22/manifest.json | 1326 +- graphify-out/GRAPH_REPORT.md | 41 +- graphify-out/cache/stat-index.json | 2 +- graphify-out/graph.html | 6 +- graphify-out/graph.json | 790 +- graphify-out/manifest.json | 1134 +- 13 files changed, 17304 insertions(+), 9367 deletions(-) diff --git a/frontend/application/app/dashboard/page.tsx b/frontend/application/app/dashboard/page.tsx index a180ce4..f91a997 100644 --- a/frontend/application/app/dashboard/page.tsx +++ b/frontend/application/app/dashboard/page.tsx @@ -1,3 +1,4 @@ +import { Suspense } from 'react'; import type { Metadata } from 'next'; import UserDashboard from "../../components/UserDashboard"; import { getPageMetadata } from "../../lib/seo"; @@ -12,6 +13,11 @@ export async function generateMetadata(): Promise { } export default function DashboardPage() { - return ; + return ( + در حال بارگذاری داشبورد...}> + + + ); } + diff --git a/frontend/application/components/UserDashboard.tsx b/frontend/application/components/UserDashboard.tsx index f34cb7f..15c5bde 100644 --- a/frontend/application/components/UserDashboard.tsx +++ b/frontend/application/components/UserDashboard.tsx @@ -36,15 +36,30 @@ export default function UserDashboard() { }, [isLoggedIn, router]); const { orders } = useCartStore(); - const [activeTab, setActiveTab] = React.useState<"profile" | "orders" | "wallet" | "addresses" | "tickets" | "pets" | "prescriptions" | "overview">("profile"); + const validTabs = React.useMemo(() => ['profile', 'orders', 'wallet', 'addresses', 'tickets', 'pets', 'prescriptions'], []); - // Set tab from URL query param if present + // Initialize tab directly from URL or default to profile + const initialTab = (searchParams.get('tab') as "profile" | "orders" | "wallet" | "addresses" | "tickets" | "pets" | "prescriptions") || "profile"; + const [activeTab, setActiveTab] = React.useState<"profile" | "orders" | "wallet" | "addresses" | "tickets" | "pets" | "prescriptions" | "overview">( + validTabs.includes(initialTab) ? initialTab : "profile" + ); + + // Handle tab click and update browser URL without full reloads + const handleTabChange = React.useCallback((tabId: "profile" | "orders" | "wallet" | "addresses" | "tickets" | "pets" | "prescriptions") => { + setActiveTab(tabId); + const newUrl = tabId === 'profile' ? '/dashboard' : `/dashboard?tab=${tabId}`; + window.history.replaceState(null, '', newUrl); + }, []); + + // Sync tab if user navigates back/forward in browser history or searchParams change useEffect(() => { const tabParam = searchParams.get('tab'); - if (tabParam && ['profile', 'orders', 'wallet', 'addresses', 'tickets', 'pets', 'prescriptions'].includes(tabParam)) { + if (tabParam && validTabs.includes(tabParam)) { setActiveTab(tabParam as "profile" | "orders" | "wallet" | "addresses" | "tickets" | "pets" | "prescriptions"); + } else if (!tabParam) { + setActiveTab("profile"); } - }, [searchParams]); + }, [searchParams, validTabs]); const [isLoadingOrders, setIsLoadingOrders] = useState(false); const [prescriptions, setPrescriptions] = useState([]); @@ -402,7 +417,7 @@ export default function UserDashboard() { {tabs.map(tab => (