/** * #37 Zero Trust 상태 뱃지 * GET /api/auth/network-status → { via: 'vpn'|'opennet'|'internal', level: 1|2|3 } * 🟢 Internal / 🟡 VPN / 🟠 OpenNet */ import { useEffect, useState } from 'react' import { View, Text, StyleSheet, ActivityIndicator } from 'react-native' import { getNetworkStatus } from '../services/api' type Via = 'vpn' | 'opennet' | 'internal' | string interface NetStatus { via: Via level: 1 | 2 | 3 | number } const META: Record = { internal: { dot: '🟢', label: 'Internal', color: '#15803d', bg: '#dcfce7' }, vpn: { dot: '🟡', label: 'VPN', color: '#a16207', bg: '#fef9c3' }, opennet: { dot: '🟠', label: 'OpenNet', color: '#c2410c', bg: '#ffedd5' }, } export default function ZeroTrustBadge() { const [status, setStatus] = useState(null) const [loading, setLoading] = useState(true) useEffect(() => { let active = true ;(async () => { try { const r = await getNetworkStatus() if (active) setStatus(r.data) } catch { // 서버 미응답 시 알 수 없음 처리 if (active) setStatus(null) } finally { if (active) setLoading(false) } })() return () => { active = false } }, []) if (loading) { return ( 네트워크 확인 중 ) } const meta = (status && META[status.via]) || { dot: '⚪', label: '알 수 없음', color: '#64748b', bg: '#f1f5f9', } return ( {meta.dot} Zero Trust · {meta.label} {status?.level != null && ( Lv.{status.level} )} ) } const s = StyleSheet.create({ badge: { flexDirection: 'row', alignItems: 'center', gap: 6, paddingHorizontal: 12, paddingVertical: 8, borderRadius: 12, marginHorizontal: 16, marginTop: 12, }, dot: { fontSize: 13 }, label: { fontSize: 13, fontWeight: '700', flex: 1 }, level: { fontSize: 11, fontWeight: '700', opacity: 0.8 }, })