feat(WEB): 대시보드 네비게이션 경로 정규화 및 서버 설정 개선
- normalizePath 헬퍼 함수 추가 (/ko prefix, ?mode=view 자동 추가) - 대시보드 detailButtonPath에 /ko prefix 적용 - start 스크립트에 -H 0.0.0.0 추가 (외부 접근 허용) - start:local 스크립트 추가 (로컬 전용) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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: [
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user