chore(WEB): CEO 대시보드 및 레이아웃 수정

- CEODashboard 컴포넌트 수정
- ShipmentList 컴포넌트 수정
- AuthenticatedLayout 업데이트

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
byeongcheolryu
2026-01-08 17:50:30 +09:00
parent 29e7b41615
commit 9885085259
3 changed files with 29 additions and 26 deletions

View File

@@ -1,6 +1,6 @@
'use client';
import { useState, useCallback } from 'react';
import { useState, useCallback, useEffect } from 'react';
import { Loader2, LayoutDashboard, Settings } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { PageLayout } from '@/components/organisms/PageLayout';
@@ -377,20 +377,19 @@ export function CEODashboard() {
// 항목 설정 모달 상태
const [isSettingsModalOpen, setIsSettingsModalOpen] = useState(false);
const [dashboardSettings, setDashboardSettings] = useState<DashboardSettings>(() => {
// localStorage에서 설정 불러오기
if (typeof window !== 'undefined') {
const saved = localStorage.getItem('ceo-dashboard-settings');
if (saved) {
try {
return JSON.parse(saved);
} catch {
return DEFAULT_DASHBOARD_SETTINGS;
}
const [dashboardSettings, setDashboardSettings] = useState<DashboardSettings>(DEFAULT_DASHBOARD_SETTINGS);
// 클라이언트에서만 localStorage에서 설정 불러오기 (hydration 에러 방지)
useEffect(() => {
const saved = localStorage.getItem('ceo-dashboard-settings');
if (saved) {
try {
setDashboardSettings(JSON.parse(saved));
} catch {
// 파싱 실패 시 기본값 유지
}
}
return DEFAULT_DASHBOARD_SETTINGS;
});
}, []);
// 항목 설정 클릭
const handleSettingClick = useCallback(() => {

View File

@@ -311,11 +311,16 @@ export function ShipmentList() {
count: shipmentStats?.totalCount || 0,
};
const statusTabs: TabOption[] = Object.entries(statusStats).map(([key, stat]) => ({
value: key,
label: stat.label,
count: stat.count,
}));
const statusTabs: TabOption[] = Object.entries(statusStats).map(([key, stat]) => {
// stat이 객체가 아니거나 label이 없는 경우 방어
const label = typeof stat?.label === 'string' ? stat.label : key;
const count = typeof stat?.count === 'number' ? stat.count : 0;
return {
value: key,
label,
count,
};
});
return [allTab, ...statusTabs];
}, [statusStats, shipmentStats?.totalCount]);