refactor(WEB): V2 파일 통합, store 구조 정리 및 대시보드 개선
- V2 컴포넌트를 원본에 통합 후 V2 파일 삭제 (InspectionModal, BillDetail, ContractDocumentModal, LaborDetailClient, PricingDetailClient, QuoteRegistration) - store → stores 디렉토리 이동 및 favoritesStore 추가 - dashboard_type3~5 추가 및 기존 대시보드 차트/훅 분리 - Sidebar 리팩토링 및 HeaderFavoritesBar 추가 - DashboardSwitcher 컴포넌트 추가 - 백업 파일(.v1-backup) 및 불필요 코드 정리 - InspectionPreviewModal 레이아웃 개선 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
66
src/stores/menuStore.ts
Normal file
66
src/stores/menuStore.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
import type { LucideIcon } from 'lucide-react';
|
||||
|
||||
// localStorage 저장용 (icon을 문자열로 저장)
|
||||
export interface SerializableMenuItem {
|
||||
id: string;
|
||||
label: string;
|
||||
iconName: string; // 문자열로 저장 (예: 'dashboard', 'folder')
|
||||
path: string;
|
||||
children?: SerializableMenuItem[];
|
||||
}
|
||||
|
||||
// 실제 사용용 (icon을 컴포넌트로 사용)
|
||||
export interface MenuItem {
|
||||
id: string;
|
||||
label: string;
|
||||
icon: LucideIcon;
|
||||
path: string;
|
||||
component?: React.ComponentType;
|
||||
children?: MenuItem[];
|
||||
}
|
||||
|
||||
interface MenuState {
|
||||
activeMenu: string;
|
||||
menuItems: MenuItem[];
|
||||
sidebarCollapsed: boolean;
|
||||
_hasHydrated: boolean;
|
||||
setActiveMenu: (menuId: string) => void;
|
||||
setMenuItems: (items: MenuItem[]) => void;
|
||||
toggleSidebar: () => void;
|
||||
setSidebarCollapsed: (collapsed: boolean) => void;
|
||||
setHasHydrated: (hydrated: boolean) => void;
|
||||
}
|
||||
|
||||
export const useMenuStore = create<MenuState>()(
|
||||
persist(
|
||||
(set) => ({
|
||||
activeMenu: 'dashboard',
|
||||
menuItems: [],
|
||||
sidebarCollapsed: false,
|
||||
_hasHydrated: false,
|
||||
|
||||
setActiveMenu: (menuId: string) => set({ activeMenu: menuId }),
|
||||
|
||||
setMenuItems: (items: MenuItem[]) => set({ menuItems: items }),
|
||||
|
||||
toggleSidebar: () => set((state) => ({ sidebarCollapsed: !state.sidebarCollapsed })),
|
||||
|
||||
setSidebarCollapsed: (collapsed: boolean) => set({ sidebarCollapsed: collapsed }),
|
||||
|
||||
setHasHydrated: (hydrated: boolean) => set({ _hasHydrated: hydrated }),
|
||||
}),
|
||||
{
|
||||
name: 'sam-menu',
|
||||
// menuItems는 함수(icon)를 포함하므로 localStorage에서 제외
|
||||
partialize: (state) => ({
|
||||
activeMenu: state.activeMenu,
|
||||
sidebarCollapsed: state.sidebarCollapsed,
|
||||
}),
|
||||
onRehydrateStorage: () => (state) => {
|
||||
state?.setHasHydrated(true);
|
||||
},
|
||||
}
|
||||
)
|
||||
);
|
||||
Reference in New Issue
Block a user