import { useState, useEffect } from 'react'; import { screeningGuideApi, type ComplianceCategoryResponse, type ComplianceIndicatorResponse, } from '../../api/screeningGuideApi'; interface ComplianceTabProps { lang: string; } type ViewMode = 'table' | 'card'; type IndicatorType = 'SHIP' | 'COMPANY'; const SHIP_CAT_COLORS: Record = { 'Sanctions – Ship (US OFAC)': '#1e3a5f', 'Sanctions – Ownership (US OFAC)': '#1d4ed8', 'Sanctions – Ship (Non-US)': '#065f46', 'Sanctions – Ownership (Non-US)': '#0f766e', 'Sanctions – FATF': '#6b21a8', 'Sanctions – Other': '#991b1b', 'Port Calls': '#065f46', 'STS Activity': '#0f766e', 'Dark Activity': '#374151', }; const COMPANY_CAT_COLORS: Record = { 'Company Sanctions (US OFAC)': '#1e3a5f', 'Company Sanctions (Non-US)': '#065f46', 'Company Compliance': '#6b21a8', 'Company Risk': '#92400e', }; function getCatHex(categoryName: string, type: IndicatorType): string { const map = type === 'SHIP' ? SHIP_CAT_COLORS : COMPANY_CAT_COLORS; return map[categoryName] ?? '#374151'; } interface FlatRow { category: string; indicatorType: string; indicator: ComplianceIndicatorResponse; } export default function ComplianceTab({ lang }: ComplianceTabProps) { const [categories, setCategories] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [selectedCategory, setSelectedCategory] = useState('전체'); const [viewMode, setViewMode] = useState('table'); const [indicatorType, setIndicatorType] = useState('SHIP'); useEffect(() => { setLoading(true); setError(null); setSelectedCategory('전체'); screeningGuideApi .getComplianceIndicators(lang, indicatorType) .then((res) => setCategories(res.data ?? [])) .catch((err: Error) => setError(err.message)) .finally(() => setLoading(false)); }, [lang, indicatorType]); const flatRows: FlatRow[] = categories.flatMap((cat) => cat.indicators.map((ind) => ({ category: cat.category, indicatorType: cat.indicatorType, indicator: ind, })), ); const filtered: FlatRow[] = selectedCategory === '전체' ? flatRows : flatRows.filter((r) => r.category === selectedCategory); const uniqueCategories = Array.from(new Set(flatRows.map((r) => r.category))); function downloadCSV() { const bom = '\uFEFF'; const headers = [ '카테고리', '타입', '필드키', '필드명', '설명', 'RED 조건', 'AMBER 조건', 'GREEN 조건', '데이터 타입', '이력 관리 참고사항', ]; const rows = flatRows.map((r) => [ r.category, r.indicatorType, r.indicator.fieldKey, r.indicator.fieldName, r.indicator.description, r.indicator.conditionRed, r.indicator.conditionAmber, r.indicator.conditionGreen, r.indicator.dataType, r.indicator.collectionNote, ] .map((v) => `"${(v ?? '').replace(/"/g, '""')}"`) .join(','), ); const csv = bom + [headers.join(','), ...rows].join('\n'); const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = `MIRS_Compliance_${indicatorType}.csv`; a.click(); } return (
{/* SHIP / COMPANY 토글 */}
{loading && (
데이터를 불러오는 중...
)} {error && (
데이터 로딩 실패: {error}
)} {!loading && !error && ( <> {/* 카테고리 요약 카드 */}
{uniqueCategories.map((catName) => { const count = flatRows.filter((r) => r.category === catName).length; const isActive = selectedCategory === catName; const hex = getCatHex(catName, indicatorType); return ( ); })}
{/* 컨트롤 바 */}
표시:{' '} {filtered.length}개 항목
{/* 테이블 뷰 */} {viewMode === 'table' && (
{[ '카테고리', '필드명', '설명', '🔴 RED', '🟡 AMBER', '🟢 GREEN', '데이터 타입', '이력 관리 참고', ].map((h) => ( ))} {filtered.map((row, i) => { const showCat = i === 0 || filtered[i - 1].category !== row.category; const hex = getCatHex(row.category, indicatorType); return ( ); })}
{h}
{showCat && ( {row.category} )}
{row.indicator.fieldName}
{row.indicator.fieldKey}
{row.indicator.description}
{row.indicator.conditionRed}
{row.indicator.conditionAmber}
{row.indicator.conditionGreen}
{row.indicator.dataType} {row.indicator.collectionNote && `💡 ${row.indicator.collectionNote}`}
)} {/* 카드 뷰 */} {viewMode === 'card' && (
{filtered.map((row, i) => { const hex = getCatHex(row.category, indicatorType); return (
{row.category} {row.indicator.dataType}
{row.indicator.fieldName}
{row.indicator.fieldKey}
{row.indicator.description}
🔴 RED
{row.indicator.conditionRed}
🟡 AMBER
{row.indicator.conditionAmber}
🟢 GREEN
{row.indicator.conditionGreen}
{row.indicator.collectionNote && (
💡 {row.indicator.collectionNote}
)}
); })}
)} )}
); }