Files
frontend/apps/st/app/(with-base-layout)/layout.tsx
T
rsone001 68c5548252 st: refactor:
- 컴포넌트 전체적으로 정리
- 그리드 컴포넌트 sort 기능 및 foooter 기능 수정
- menu active 기능 수정
2026-01-29 10:23:05 +09:00

140 lines
4.5 KiB
TypeScript

"use client";
import { useEffect, useCallback, useMemo } from "react";
import { usePathname } from "next/navigation";
import { useQueryClient, useQuery } from "@tanstack/react-query";
import type { MenuItem } from "@/entities/menu";
import { useMenuStore, useAlertStore } from "@/shared/lib";
import { useTabStore, getTabStoreState } from "@/store/tab-store";
import { useTabStore as gridTabStore } from "@rsone/components";
import { getConfig } from "@common/config";
import { getCookie } from "@/shared/lib";
import { getMenuList } from "../../../../packages/common/components/src/api";
import { ENDPOINT } from "@/shared/config";
import { BaseLayout } from "@common/components";
import { StatisticsPageLayout } from "@/shared/ui/statistics-page-layout";
const appConfig = getConfig();
const userId = getCookie(appConfig.AUTH_USER_ID ?? "");
const appSiteId = getCookie("site-id-key") ?? "";
const isLoggedIn = !!userId;
export default function WithBaseLayout({
children,
}: {
children: React.ReactNode;
}) {
const pathname = usePathname();
const queryClient = useQueryClient();
const setCurrentMenuInfo = useMenuStore((state) => state.setCurrentMenuInfo);
const currentMenuInfo = useMenuStore((state) => state.currentMenuInfo);
const addTab = useTabStore((state) => state.addTab);
const setActiveTab = useTabStore((state) => state.setActiveTab);
const setMenuList = useTabStore((state) => state.setMenuList);
const activeTabId = useTabStore((state) => state.activeTabId);
const menuList = useTabStore((state) => state.menuList);
const tabs = useTabStore((state) => state.tabs);
const addTabForGrid = gridTabStore((state) => state.addTab);
const setActiveTabForGrid = gridTabStore((state) => state.setActiveTab);
const setMenuListForGrid = gridTabStore((state) => state.setMenuList);
const alert = useAlertStore((state) => state.setMessage);
const { data: menuListData } = useQuery({
queryKey: [ENDPOINT.CMS_SERVICE.MENU_ROLES],
queryFn: () => getMenuList(appSiteId),
enabled: isLoggedIn,
});
useEffect(() => {
if (menuListData) {
setMenuList(menuListData);
setMenuListForGrid(menuListData);
}
}, [menuListData, setMenuList, setMenuListForGrid]);
useEffect(() => {
if (!pathname) return;
// pathname이 변경될 때만 실행되도록 tabs를 직접 가져옴
const currentTabs = getTabStoreState().tabs;
const tab = currentTabs.find((t) => t.path === pathname);
if (tab) {
setActiveTab(tab.id);
setActiveTabForGrid(tab.id);
}
}, [pathname, setActiveTab, setActiveTabForGrid]);
// 활성 탭의 메뉴를 찾아서 urlPath를 가져옴. 탭이 전부 닫히면 ''를 넘겨 LNB에서 메뉴 강조 제거
const currentPath = useMemo(() => {
if (tabs.length === 0) return "";
if (activeTabId && menuList) {
// menuList에서 활성 탭의 메뉴 찾기
const findMenuByEngNm = (items: MenuItem[]): MenuItem | null => {
for (const item of items) {
if (item.menuEngNm === activeTabId) {
return item;
}
if (item.children) {
const found = findMenuByEngNm(item.children);
if (found) return found;
}
}
return null;
};
const activeMenu = findMenuByEngNm(menuList);
if (activeMenu?.urlPath) {
return activeMenu.urlPath;
}
}
// 탭에서 직접 찾기
if (activeTabId) {
const currentTabs = getTabStoreState().tabs;
const activeTab = currentTabs.find((t) => t.id === activeTabId);
if (activeTab?.menuItem?.urlPath) {
return activeTab.menuItem.urlPath;
}
}
// currentMenuInfo에서 가져오기
if (currentMenuInfo?.urlPath) {
return currentMenuInfo.urlPath;
}
// 기본값으로 pathname 사용
return pathname ?? "";
}, [tabs.length, activeTabId, menuList, currentMenuInfo, pathname]);
const handleMenuClick = useCallback((item: MenuItem) => {
setCurrentMenuInfo(item);
const addTabResult: boolean = addTab(item);
// packages/rsone의 스토어에도 동기화
if (addTabResult) {
addTabForGrid(item);
}
if (!addTabResult) {
alert(`최대 추가 할 수 있는 화면 수를 초과 하였습니다.
기존 화면을 닫은 후 이용해주세요.`);
}
}, [setCurrentMenuInfo, addTab, addTabForGrid, alert]);
return (
<BaseLayout
queryClient={queryClient}
currentPath={currentPath}
handleMenuClick={handleMenuClick}
>
<StatisticsPageLayout>{children}</StatisticsPageLayout>
</BaseLayout>
);
}