diff --git a/package.json b/package.json index f645fdc1..b5c62fef 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "dev": "next dev", "build": "next build", "build:restart": "lsof -ti:3000 | xargs kill 2>/dev/null; next build && next start &", - "start": "next start", + "start": "next start -H 0.0.0.0", + "start:local": "next start", "lint": "eslint", "test:e2e": "playwright test", "test:e2e:ui": "playwright test --ui", diff --git a/src/components/business/CEODashboard/mockData.ts b/src/components/business/CEODashboard/mockData.ts index decf1a2c..31924065 100644 --- a/src/components/business/CEODashboard/mockData.ts +++ b/src/components/business/CEODashboard/mockData.ts @@ -254,7 +254,7 @@ export const mockData: CEODashboardData = { ], }, ], - detailButtonPath: '/accounting/receivables-status', + detailButtonPath: '/ko/accounting/receivables-status', }, debtCollection: { cards: [ @@ -277,7 +277,7 @@ export const mockData: CEODashboardData = { highlights: [{ text: '(주)삼성테크 건 회수 불가 판정.', color: 'red' }], }, ], - detailButtonPath: '/accounting/bad-debt-collection', + detailButtonPath: '/ko/accounting/bad-debt-collection', }, vat: { cards: [ diff --git a/src/lib/api/dashboard/transformers.ts b/src/lib/api/dashboard/transformers.ts index dd7ea05a..9ba8fa46 100644 --- a/src/lib/api/dashboard/transformers.ts +++ b/src/lib/api/dashboard/transformers.ts @@ -47,6 +47,39 @@ import type { // 헬퍼 함수 // ============================================ +/** + * 네비게이션 경로 정규화 + * - /ko prefix 추가 (없는 경우) + * - 상세 페이지에 ?mode=view 추가 (필요시) + * @example normalizePath('/accounting/deposits/73') → '/ko/accounting/deposits/73?mode=view' + */ +function normalizePath(path: string | undefined, options?: { addViewMode?: boolean }): string { + if (!path) return ''; + + let normalizedPath = path; + + // /ko prefix 추가 (없는 경우) + if (!normalizedPath.startsWith('/ko')) { + normalizedPath = `/ko${normalizedPath}`; + } + + // 상세 페이지에 ?mode=view 추가 (숫자 ID가 있고 mode 파라미터가 없는 경우) + if (options?.addViewMode) { + const hasIdPattern = /\/\d+($|\?)/.test(normalizedPath); + const hasMode = /[?&]mode=/.test(normalizedPath); + const hasModal = /[?&]openModal=/.test(normalizedPath); + + // ID가 있고, mode 파라미터가 없고, openModal도 없는 경우에만 ?mode=view 추가 + if (hasIdPattern && !hasMode && !hasModal) { + normalizedPath = normalizedPath.includes('?') + ? `${normalizedPath}&mode=view` + : `${normalizedPath}?mode=view`; + } + } + + return normalizedPath; +} + /** * 금액 포맷팅 * @example formatAmount(3050000000) → "30.5억원" @@ -313,7 +346,7 @@ export function transformReceivableResponse(api: ReceivablesApiResponse): Receiv ], checkPoints: generateReceivableCheckPoints(api), detailButtonLabel: '미수금 상세', - detailButtonPath: '/accounting/receivables-status', + detailButtonPath: normalizePath('/accounting/receivables-status'), }; } @@ -383,7 +416,7 @@ export function transformDebtCollectionResponse(api: BadDebtApiResponse): DebtCo }, ], checkPoints: generateDebtCollectionCheckPoints(api), - detailButtonPath: '/accounting/bad-debt-collection', + detailButtonPath: normalizePath('/accounting/bad-debt-collection'), }; } @@ -560,7 +593,7 @@ export function transformStatusBoardResponse(api: StatusBoardApiResponse): Today id: item.id, label: item.label, count: item.count, - path: item.path, + path: normalizePath(item.path, { addViewMode: true }), isHighlighted: item.isHighlighted, })); } @@ -608,7 +641,7 @@ export function transformTodayIssueResponse(api: TodayIssueApiResponse): { time: item.time, date: item.date, needsApproval: item.needsApproval ?? false, - path: item.path, + path: normalizePath(item.path, { addViewMode: true }), })), totalCount: api.total_count, };