fix(WEB): 오늘의 이슈 뱃지 타입 API 모델과 동기화
- TodayIssueListBadgeType 업데이트 (수주등록, 추심이슈, 안전재고 등) - BADGE_COLORS 및 FILTER_KEYS 새 타입으로 변경 - transformers.ts의 VALID_BADGE_TYPES 배열 동기화 - 입금/출금 뱃지 타입 추가
This commit is contained in:
11
package-lock.json
generated
11
package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -15,15 +15,17 @@ import {
|
||||
import { toast } from 'sonner';
|
||||
import type { TodayIssueListItem, TodayIssueListBadgeType } from '../types';
|
||||
|
||||
// 뱃지 색상 매핑
|
||||
// 뱃지 색상 매핑 (API TodayIssue 모델과 동기화)
|
||||
const BADGE_COLORS: Record<TodayIssueListBadgeType, string> = {
|
||||
'수주 성공': '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<string, CreditRating> = {};
|
||||
items.forEach((item) => {
|
||||
if (item.badge === '신규거래처') {
|
||||
if (item.badge === '신규업체') {
|
||||
ratings[item.id] = getRandomCreditRating();
|
||||
}
|
||||
});
|
||||
return ratings;
|
||||
}, [items]);
|
||||
|
||||
// 항목별 수량 계산
|
||||
// 항목별 수량 계산 (입금/출금 등은 기타로 카운트)
|
||||
const itemCounts = useMemo(() => {
|
||||
const counts: Record<string, number> = { 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)}
|
||||
>
|
||||
{/* 뱃지 */}
|
||||
{/* 뱃지 (입금/출금 등은 기타 색상 사용) */}
|
||||
<Badge
|
||||
variant="secondary"
|
||||
className={`shrink-0 text-xs ${BADGE_COLORS[item.badge]}`}
|
||||
className={`shrink-0 text-xs ${BADGE_COLORS[item.badge as TodayIssueListBadgeType] || BADGE_COLORS['기타']}`}
|
||||
>
|
||||
{item.badge}
|
||||
</Badge>
|
||||
@@ -178,8 +189,8 @@ export function TodayIssueSection({ items }: TodayIssueSectionProps) {
|
||||
{item.content}
|
||||
</span>
|
||||
|
||||
{/* 신용등급 배지 (신규거래처인 경우) */}
|
||||
{item.badge === '신규거래처' && creditRatings[item.id] && (
|
||||
{/* 신용등급 배지 (신규업체인 경우) */}
|
||||
{item.badge === '신규업체' && creditRatings[item.id] && (
|
||||
<Button
|
||||
size="sm"
|
||||
className={`h-6 px-2 text-xs shrink-0 ${CREDIT_RATING_COLORS[creditRatings[item.id]]}`}
|
||||
|
||||
@@ -56,15 +56,17 @@ export interface TodayIssueItem {
|
||||
icon?: React.ComponentType<{ className?: string }>; // 카드 아이콘
|
||||
}
|
||||
|
||||
// 오늘의 이슈 뱃지 타입
|
||||
// 오늘의 이슈 뱃지 타입 (최대 4자, 띄어쓰기 없음 - API TodayIssue 모델과 동기화)
|
||||
export type TodayIssueListBadgeType =
|
||||
| '수주 성공'
|
||||
| '추심 이슈'
|
||||
| '적정 재고'
|
||||
| '지출예상내역서'
|
||||
| '세금 신고'
|
||||
| '결재 요청'
|
||||
| '신규거래처'
|
||||
| '수주등록'
|
||||
| '추심이슈'
|
||||
| '안전재고'
|
||||
| '지출승인'
|
||||
| '세금신고'
|
||||
| '결재요청'
|
||||
| '신규업체'
|
||||
| '입금'
|
||||
| '출금'
|
||||
| '기타';
|
||||
|
||||
// 오늘의 이슈 리스트 아이템 (리스트 형태 - 새로운 오늘의 이슈용)
|
||||
|
||||
@@ -602,15 +602,17 @@ export function transformStatusBoardResponse(api: StatusBoardApiResponse): Today
|
||||
// 7. TodayIssue 변환
|
||||
// ============================================
|
||||
|
||||
/** 유효한 뱃지 타입 목록 */
|
||||
/** 유효한 뱃지 타입 목록 (API TodayIssue 모델과 동기화) */
|
||||
const VALID_BADGE_TYPES: TodayIssueListBadgeType[] = [
|
||||
'수주 성공',
|
||||
'추심 이슈',
|
||||
'적정 재고',
|
||||
'지출예상내역서',
|
||||
'세금 신고',
|
||||
'결재 요청',
|
||||
'신규거래처',
|
||||
'수주등록',
|
||||
'추심이슈',
|
||||
'안전재고',
|
||||
'지출승인',
|
||||
'세금신고',
|
||||
'결재요청',
|
||||
'신규업체',
|
||||
'입금',
|
||||
'출금',
|
||||
'기타',
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user