From f532f1fb5249b5ebed633b492072769420b6576d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B6=8C=ED=98=81=EC=84=B1?= Date: Tue, 27 Jan 2026 22:38:55 +0900 Subject: [PATCH] =?UTF-8?q?fix(WEB):=20=EC=98=A4=EB=8A=98=EC=9D=98=20?= =?UTF-8?q?=EC=9D=B4=EC=8A=88=20=EB=B1=83=EC=A7=80=20=ED=83=80=EC=9E=85=20?= =?UTF-8?q?API=20=EB=AA=A8=EB=8D=B8=EA=B3=BC=20=EB=8F=99=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TodayIssueListBadgeType 업데이트 (수주등록, 추심이슈, 안전재고 등) - BADGE_COLORS 및 FILTER_KEYS 새 타입으로 변경 - transformers.ts의 VALID_BADGE_TYPES 배열 동기화 - 입금/출금 뱃지 타입 추가 --- package-lock.json | 11 ---- .../sections/TodayIssueSection.tsx | 63 +++++++++++-------- src/components/business/CEODashboard/types.ts | 18 +++--- src/lib/api/dashboard/transformers.ts | 18 +++--- 4 files changed, 57 insertions(+), 53 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8285e15f..293a7d7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8312,17 +8312,6 @@ } } }, - "node_modules/next-intl/node_modules/@swc/helpers": { - "version": "0.5.18", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.18.tgz", - "integrity": "sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "tslib": "^2.8.0" - } - }, "node_modules/next/node_modules/postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", diff --git a/src/components/business/CEODashboard/sections/TodayIssueSection.tsx b/src/components/business/CEODashboard/sections/TodayIssueSection.tsx index 57ce3afe..df171c4d 100644 --- a/src/components/business/CEODashboard/sections/TodayIssueSection.tsx +++ b/src/components/business/CEODashboard/sections/TodayIssueSection.tsx @@ -15,15 +15,17 @@ import { import { toast } from 'sonner'; import type { TodayIssueListItem, TodayIssueListBadgeType } from '../types'; -// 뱃지 색상 매핑 +// 뱃지 색상 매핑 (API TodayIssue 모델과 동기화) const BADGE_COLORS: Record = { - '수주 성공': 'bg-blue-100 text-blue-700 hover:bg-blue-100', - '추심 이슈': 'bg-purple-100 text-purple-700 hover:bg-purple-100', - '적정 재고': 'bg-orange-100 text-orange-700 hover:bg-orange-100', - '지출예상내역서': 'bg-green-100 text-green-700 hover:bg-green-100', - '세금 신고': 'bg-red-100 text-red-700 hover:bg-red-100', - '결재 요청': 'bg-yellow-100 text-yellow-700 hover:bg-yellow-100', - '신규거래처': 'bg-emerald-100 text-emerald-700 hover:bg-emerald-100', + '수주등록': 'bg-blue-100 text-blue-700 hover:bg-blue-100', + '추심이슈': 'bg-purple-100 text-purple-700 hover:bg-purple-100', + '안전재고': 'bg-orange-100 text-orange-700 hover:bg-orange-100', + '지출승인': 'bg-green-100 text-green-700 hover:bg-green-100', + '세금신고': 'bg-red-100 text-red-700 hover:bg-red-100', + '결재요청': 'bg-yellow-100 text-yellow-700 hover:bg-yellow-100', + '신규업체': 'bg-emerald-100 text-emerald-700 hover:bg-emerald-100', + '입금': 'bg-cyan-100 text-cyan-700 hover:bg-cyan-100', + '출금': 'bg-pink-100 text-pink-700 hover:bg-pink-100', '기타': 'bg-gray-100 text-gray-700 hover:bg-gray-100', }; @@ -42,18 +44,27 @@ const getRandomCreditRating = (): CreditRating => { return ratings[Math.floor(Math.random() * ratings.length)]; }; -// 필터 옵션 키 +// 필터 옵션 키 (API TodayIssue 모델과 동기화) const FILTER_KEYS = [ 'all', - '수주 성공', - '추심 이슈', - '적정 재고', - '지출예상내역서', - '세금 신고', - '결재 요청', - '신규거래처', + '수주등록', + '추심이슈', + '안전재고', + '지출승인', + '세금신고', + '결재요청', + '신규업체', + '입금', + '출금', + '기타', ] as const; +// badge를 필터 키로 변환 (정의되지 않은 타입은 기타로) +const getFilterKey = (badge: string): string => { + const knownBadges = ['수주등록', '추심이슈', '안전재고', '지출승인', '세금신고', '결재요청', '신규업체', '입금', '출금']; + return knownBadges.includes(badge) ? badge : '기타'; +}; + interface TodayIssueSectionProps { items: TodayIssueListItem[]; } @@ -66,23 +77,23 @@ export function TodayIssueSection({ items }: TodayIssueSectionProps) { // 확인되지 않은 아이템만 필터링 const activeItems = items.filter((item) => !dismissedIds.has(item.id)); - // 신규거래처 아이템별 랜덤 신용등급 생성 (세션 동안 유지) + // 신규업체 아이템별 랜덤 신용등급 생성 (세션 동안 유지) const creditRatings = useMemo(() => { const ratings: Record = {}; items.forEach((item) => { - if (item.badge === '신규거래처') { + if (item.badge === '신규업체') { ratings[item.id] = getRandomCreditRating(); } }); return ratings; }, [items]); - // 항목별 수량 계산 + // 항목별 수량 계산 (입금/출금 등은 기타로 카운트) const itemCounts = useMemo(() => { const counts: Record = { all: activeItems.length }; FILTER_KEYS.forEach((key) => { if (key !== 'all') { - counts[key] = activeItems.filter((item) => item.badge === key).length; + counts[key] = activeItems.filter((item) => getFilterKey(item.badge) === key).length; } }); return counts; @@ -97,10 +108,10 @@ export function TodayIssueSection({ items }: TodayIssueSectionProps) { })); }, [itemCounts]); - // 필터링된 아이템 + // 필터링된 아이템 (입금/출금 등은 기타로 분류) const filteredItems = filter === 'all' ? activeItems - : activeItems.filter((item) => item.badge === filter); + : activeItems.filter((item) => getFilterKey(item.badge) === filter); // 아이템 클릭 const handleItemClick = (item: TodayIssueListItem) => { @@ -165,10 +176,10 @@ export function TodayIssueSection({ items }: TodayIssueSectionProps) { className="flex items-center gap-2 p-3 bg-white border border-gray-200 rounded-lg hover:bg-gray-50 transition-colors cursor-pointer" onClick={() => handleItemClick(item)} > - {/* 뱃지 */} + {/* 뱃지 (입금/출금 등은 기타 색상 사용) */} {item.badge} @@ -178,8 +189,8 @@ export function TodayIssueSection({ items }: TodayIssueSectionProps) { {item.content} - {/* 신용등급 배지 (신규거래처인 경우) */} - {item.badge === '신규거래처' && creditRatings[item.id] && ( + {/* 신용등급 배지 (신규업체인 경우) */} + {item.badge === '신규업체' && creditRatings[item.id] && (