import React, { useState, useCallback } from 'react' import { View, Text, ScrollView, StyleSheet, RefreshControl } from 'react-native' import { useFocusEffect } from 'expo-router' import { COLORS } from '../../constants/Config' import client from '../../services/api' export default function SecurityScoreScreen() { const [data, setData] = useState(null) const [loading, setLoading] = useState(false) const load = useCallback(async () => { setLoading(true) try { const r = await client.get('/api/ai-soc/security-score'); setData(r.data) } catch { setData(null) } finally { setLoading(false) } }, []) useFocusEffect(useCallback(() => { load() }, [load])) if (!data) return 보안 점수를 불러올 수 없습니다. const score = data.total_score ?? data.score ?? 0 const color = score >= 80 ? COLORS.success : score >= 60 ? COLORS.warning : COLORS.danger const domains = data.domains ?? [ { name: 'Zero Trust 정책', score: data.zt_score ?? 0 }, { name: '취약점 관리', score: data.vuln_score ?? 0 }, { name: '감사 로그 완전성', score: data.audit_score ?? 0 }, { name: '패치 적용률', score: data.patch_score ?? 0 }, { name: 'CSAP 준수', score: data.csap_score ?? 0 }, ] return ( } contentContainerStyle={{ padding: 16 }}> 보안 점수 {score} {score >= 80 ? 'A등급' : score >= 60 ? 'B등급' : 'C등급'} {domains.map((d: any) => { const c = d.score >= 80 ? COLORS.success : d.score >= 60 ? COLORS.warning : COLORS.danger return ( {d.name} {d.score} ) })} {data.findings?.length > 0 && ( 주요 발견 사항 {data.findings.map((f: string, i: number) => • {f})} )} ) } const s = StyleSheet.create({ container: { flex: 1, backgroundColor: COLORS.bg }, empty: { textAlign: 'center', color: COLORS.muted, marginTop: 40 }, hero: { alignItems: 'center', borderWidth: 2, borderRadius: 16, padding: 24, marginBottom: 16, backgroundColor: '#fff', elevation: 2 }, heroLabel: { fontSize: 13, color: COLORS.muted }, heroScore: { fontSize: 64, fontWeight: '900', lineHeight: 72 }, heroGrade: { fontSize: 16, fontWeight: '700', marginTop: 4 }, row: { flexDirection: 'row', alignItems: 'center', gap: 10, backgroundColor: '#fff', borderRadius: 10, padding: 12, marginBottom: 6, elevation: 1 }, dname: { fontSize: 12, color: COLORS.text, width: 100 }, bar: { flex: 1, height: 6, backgroundColor: COLORS.border, borderRadius: 3, overflow: 'hidden' }, fill: { height: '100%', borderRadius: 3 }, dscore: { fontSize: 13, fontWeight: '700', width: 28 }, findingsCard: { backgroundColor: '#fff', borderRadius: 12, padding: 14, marginTop: 8, elevation: 1 }, findingsTitle:{ fontSize: 14, fontWeight: '700', color: COLORS.danger, marginBottom: 8 }, finding: { fontSize: 12, color: COLORS.text, marginBottom: 4 }, })