/** * 위험도/알림 등급 공통 카탈로그 * * SSOT: backend `code_master` 그룹 EVENT_LEVEL (V008 시드). * 향후 `GET /api/code-master?groupCode=EVENT_LEVEL`로 fetch 예정. * * **공통 Badge 컴포넌트와 연동**: 가능한 한 `` 사용. * 카드 컨테이너 등 분리된 클래스가 필요한 경우만 `ALERT_LEVELS.classes` 사용. * * 사용처: Dashboard, MonitoringDashboard, EventList, LiveMapView, VesselDetail, * MobileService, ChinaFishing 등 모든 위험도 배지 / 알림 / 마커 */ import type { BadgeIntent } from '@lib/theme/variants'; export type AlertLevel = 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW'; export interface AlertLevelMeta { code: AlertLevel; i18nKey: string; fallback: { ko: string; en: string }; /** 공통 Badge 컴포넌트 intent (badgeVariants 와 동기화) */ intent: BadgeIntent; /** Tailwind 클래스 묶음 — 카드/컨테이너 전용 (배지가 아님) * 배지에는 `` 사용 권장. * 여기서 bg/border는 약한 알파 — 카드 배경에 텍스트가 묻히지 않도록. */ classes: { bg: string; text: string; border: string; dot: string; /** 진한 배경 (액션 버튼 등) */ bgSolid: string; }; /** hex 색상 (지도 마커, 차트, 인라인 style 용) */ hex: string; order: number; } export const ALERT_LEVELS: Record = { CRITICAL: { code: 'CRITICAL', i18nKey: 'alert.critical', fallback: { ko: '심각', en: 'Critical' }, intent: 'critical', classes: { bg: 'bg-red-500/10', text: 'text-red-300', border: 'border-red-500/30', dot: 'bg-red-500', bgSolid: 'bg-red-500', }, hex: '#ef4444', order: 1, }, HIGH: { code: 'HIGH', i18nKey: 'alert.high', fallback: { ko: '높음', en: 'High' }, intent: 'high', classes: { bg: 'bg-orange-500/10', text: 'text-orange-300', border: 'border-orange-500/30', dot: 'bg-orange-500', bgSolid: 'bg-orange-500', }, hex: '#f97316', order: 2, }, MEDIUM: { code: 'MEDIUM', i18nKey: 'alert.medium', fallback: { ko: '보통', en: 'Medium' }, intent: 'warning', classes: { bg: 'bg-yellow-500/10', text: 'text-yellow-300', border: 'border-yellow-500/30', dot: 'bg-yellow-500', bgSolid: 'bg-yellow-500', }, hex: '#eab308', order: 3, }, LOW: { code: 'LOW', i18nKey: 'alert.low', fallback: { ko: '낮음', en: 'Low' }, intent: 'info', classes: { bg: 'bg-blue-500/10', text: 'text-blue-300', border: 'border-blue-500/30', dot: 'bg-blue-500', bgSolid: 'bg-blue-500', }, hex: '#3b82f6', order: 4, }, }; export function getAlertLevelMeta(level: string): AlertLevelMeta | undefined { return ALERT_LEVELS[level as AlertLevel]; } export function getAlertLevelLabel( level: string, t: (key: string, opts?: { defaultValue?: string }) => string, lang: 'ko' | 'en' = 'ko', ): string { const meta = getAlertLevelMeta(level); if (!meta) return level; return t(meta.i18nKey, { defaultValue: meta.fallback[lang] }); } export function getAlertLevelHex(level: string): string { return getAlertLevelMeta(level)?.hex ?? '#6b7280'; } /** 공통 Badge intent 매핑 */ export function getAlertLevelIntent(level: string): BadgeIntent { return getAlertLevelMeta(level)?.intent ?? 'muted'; }