Files
frontend/apps/st/src/shared/lib/use-statistics-tab-url-sync.ts
T

101 lines
2.9 KiB
TypeScript

"use client";
import { useEffect, useRef } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import type { MenuItem } from "@/entities/menu";
import { isBbsNoticeMenu } from "@/shared/lib/bbs-notice-menu";
import { findMenuItemByUrlPath } from "@/shared/lib/stats-cd-input-navigation";
import { getTabStoreState } from "@/store/tab-store";
import {
STATISTICS_ROUTE,
STATISTICS_TAB_QUERY_KEY,
buildStatisticsTabUrl,
isStatisticsPathname,
} from "./statistics-tab-url";
type UseStatisticsTabUrlSyncParams = {
pathname: string | null;
menuList: MenuItem[] | null;
activeTabId: string | null;
addTab: (menuItem: MenuItem) => boolean;
addTabForGrid: (menuItem: MenuItem) => void;
setCurrentMenuInfo: (item: MenuItem) => void;
};
/** `/statistics?tab=` ↔ Zustand 활성 탭 동기화 */
export function useStatisticsTabUrlSync({
pathname,
menuList,
activeTabId,
addTab,
addTabForGrid,
setCurrentMenuInfo,
}: UseStatisticsTabUrlSyncParams): {
syncTabToUrl: (tabId: string) => void;
} {
const router = useRouter();
const searchParams = useSearchParams();
const tabParam = searchParams?.get(STATISTICS_TAB_QUERY_KEY) ?? null;
const skipUrlToStoreRef = useRef(false);
const syncTabToUrl = (tabId: string) => {
if (!isStatisticsPathname(pathname)) {
router.push(buildStatisticsTabUrl(tabId));
return;
}
if (tabParam === tabId) return;
skipUrlToStoreRef.current = true;
router.replace(buildStatisticsTabUrl(tabId), { scroll: false });
};
// URL ?tab → 탭 스토어
useEffect(() => {
if (!isStatisticsPathname(pathname) || !menuList) return;
if (skipUrlToStoreRef.current) {
skipUrlToStoreRef.current = false;
return;
}
if (!tabParam) return;
if (getTabStoreState().activeTabId === tabParam) return;
const menu = findMenuItemByUrlPath(menuList, tabParam);
if (!menu || isBbsNoticeMenu(menu)) return;
setCurrentMenuInfo(menu);
const ok = addTab(menu);
if (ok) {
addTabForGrid(menu);
}
}, [
pathname,
menuList,
tabParam,
addTab,
addTabForGrid,
setCurrentMenuInfo,
]);
// 활성 탭 → URL (탭 바 전환·persist 복원 포함)
useEffect(() => {
if (!isStatisticsPathname(pathname)) return;
if (!activeTabId) {
if (tabParam) {
skipUrlToStoreRef.current = true;
router.replace(STATISTICS_ROUTE, { scroll: false });
}
return;
}
if (tabParam === activeTabId) return;
skipUrlToStoreRef.current = true;
router.replace(buildStatisticsTabUrl(activeTabId), { scroll: false });
}, [pathname, activeTabId, tabParam, router]);
return { syncTabToUrl };
}