- cn() 유틸 신규 (clsx + tailwind-merge, 시맨틱 토큰 classGroup 등록) - theme.css @layer utilities로 직접 정의 (Tailwind v4 복합 이름 매핑 실패 대응): text-heading/label/hint/on-vivid/on-bright, bg-surface-raised/overlay - badgeVariants (CVA) 재구축: 8 intent x 4 size, rem 기반, !important 제거 - Badge 컴포넌트가 cn(badgeVariants, className)로 override 허용 - DataTable width 의미 변경: 고정 -> 선호 최소 너비 (minWidth), truncate + title 툴팁 - dateFormat.ts sv-SE 로케일로 YYYY-MM-DD HH:mm:ss 일관된 KST 출력 - ColorPicker 신규 (팔레트 + native color + hex 입력) - shared/constants/ 19개 카탈로그: violation/alert/event/enforcement/patrol/ engine/userRole/device/parentResolution/modelDeployment/gearGroup/darkVessel/ httpStatus/userAccount/loginResult/permission/vesselAnalysis/connection/trainingZone + kpiUiMap. 백엔드 enum/code_master 기반 SSOT - i18n ko/en common.json에 카테고리 섹션 추가 - adminApi.fetchRoles()가 updateRoleColorCache 자동 호출 - 공통 컴포넌트 (ExcelExport/NotificationBanner/Pagination/SaveButton) 시맨틱 토큰 적용
80 lines
2.2 KiB
TypeScript
80 lines
2.2 KiB
TypeScript
/**
|
|
* 단속 결과 코드 공통 카탈로그
|
|
*
|
|
* SSOT: backend `code_master` 그룹 ENFORCEMENT_RESULT (V008 시드).
|
|
* 백엔드 EnforcementRecord.result enum.
|
|
*
|
|
* 사용처: EnforcementHistory(결과 컬럼), 단속 통계
|
|
*/
|
|
|
|
export type EnforcementResult =
|
|
| 'PUNISHED'
|
|
| 'WARNED'
|
|
| 'RELEASED'
|
|
| 'REFERRED'
|
|
| 'FALSE_POSITIVE';
|
|
|
|
export interface EnforcementResultMeta {
|
|
code: EnforcementResult;
|
|
i18nKey: string;
|
|
fallback: { ko: string; en: string };
|
|
classes: string;
|
|
order: number;
|
|
}
|
|
|
|
export const ENFORCEMENT_RESULTS: Record<EnforcementResult, EnforcementResultMeta> = {
|
|
PUNISHED: {
|
|
code: 'PUNISHED',
|
|
i18nKey: 'enforcementResult.PUNISHED',
|
|
fallback: { ko: '처벌', en: 'Punished' },
|
|
classes: 'bg-red-500/20 text-red-400',
|
|
order: 1,
|
|
},
|
|
REFERRED: {
|
|
code: 'REFERRED',
|
|
i18nKey: 'enforcementResult.REFERRED',
|
|
fallback: { ko: '수사의뢰', en: 'Referred' },
|
|
classes: 'bg-purple-500/20 text-purple-400',
|
|
order: 2,
|
|
},
|
|
WARNED: {
|
|
code: 'WARNED',
|
|
i18nKey: 'enforcementResult.WARNED',
|
|
fallback: { ko: '경고', en: 'Warned' },
|
|
classes: 'bg-yellow-500/20 text-yellow-400',
|
|
order: 3,
|
|
},
|
|
RELEASED: {
|
|
code: 'RELEASED',
|
|
i18nKey: 'enforcementResult.RELEASED',
|
|
fallback: { ko: '훈방', en: 'Released' },
|
|
classes: 'bg-green-500/20 text-green-400',
|
|
order: 4,
|
|
},
|
|
FALSE_POSITIVE: {
|
|
code: 'FALSE_POSITIVE',
|
|
i18nKey: 'enforcementResult.FALSE_POSITIVE',
|
|
fallback: { ko: '오탐(정상)', en: 'False Positive' },
|
|
classes: 'bg-muted text-muted-foreground',
|
|
order: 5,
|
|
},
|
|
};
|
|
|
|
export function getEnforcementResultMeta(result: string): EnforcementResultMeta | undefined {
|
|
return ENFORCEMENT_RESULTS[result as EnforcementResult];
|
|
}
|
|
|
|
export function getEnforcementResultLabel(
|
|
result: string,
|
|
t: (key: string, opts?: { defaultValue?: string }) => string,
|
|
lang: 'ko' | 'en' = 'ko',
|
|
): string {
|
|
const meta = getEnforcementResultMeta(result);
|
|
if (!meta) return result;
|
|
return t(meta.i18nKey, { defaultValue: meta.fallback[lang] });
|
|
}
|
|
|
|
export function getEnforcementResultClasses(result: string): string {
|
|
return getEnforcementResultMeta(result)?.classes ?? 'bg-muted text-muted-foreground';
|
|
}
|