101 lines
2.9 KiB
TypeScript
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 };
|
|
}
|