import React, { useState, useEffect } from 'react'; import { View, Text, ScrollView, TouchableOpacity, StyleSheet, Switch } from 'react-native'; import NetInfo from '@react-native-community/netinfo'; interface CacheItem { key: string; size: string; updated: string; category: string } const CACHE_ITEMS: CacheItem[] = [ { key: 'kb-docs', size: '12.4MB', updated: '10분 전', category: 'KB 문서' }, { key: 'runbooks', size: '3.2MB', updated: '1시간 전', category: '런북' }, { key: 'sr-templates', size: '0.8MB', updated: '30분 전', category: 'SR 템플릿' }, { key: 'ollama-model', size: '4.7GB', updated: '어제', category: 'AI 모델' }, ]; export default function OfflineAIScreen() { const [isOnline, setIsOnline] = useState(true); const [offlineEnabled, setOfflineEnabled] = useState(false); const [syncProgress, setSyncProgress] = useState(0); const [syncing, setSyncing] = useState(false); useEffect(() => { const unsubscribe = NetInfo.addEventListener(state => { setIsOnline(!!state.isConnected); }); return unsubscribe; }, []); const startSync = async () => { setSyncing(true); setSyncProgress(0); for (let i = 1; i <= 10; i++) { await new Promise(r => setTimeout(r, 300)); setSyncProgress(i * 10); } setSyncing(false); }; return ( 오프라인 AI 엣지 캐시 & 온디바이스 AI 추론 {isOnline ? '온라인 — ITSM 서버 연결됨' : '오프라인 — 캐시 모드 동작 중'} 오프라인 모드 활성화 활성화 시 AI 추론이 온디바이스(Ollama 로컬)로만 처리됩니다 캐시 현황 총 캐시4.72GB 마지막 동기화10분 전 {syncing && ( )} {syncing ? `동기화 중 ${syncProgress}%` : '🔄 지금 동기화'} 캐시 항목 {CACHE_ITEMS.map((item, i) => ( {item.category} {item.size} · {item.updated} 업데이트 ))} ); } const s = StyleSheet.create({ container: { flex: 1, backgroundColor: '#0A0E1A', padding: 16 }, title: { color: '#fff', fontSize: 20, fontWeight: '700', marginBottom: 4 }, sub: { color: '#888', fontSize: 13, marginBottom: 16 }, statusCard: { flexDirection: 'row', alignItems: 'center', backgroundColor: '#1A1F2E', borderRadius: 12, padding: 14, marginBottom: 12, borderWidth: 1 }, statusDot: { width: 10, height: 10, borderRadius: 5, marginRight: 10 }, statusText: { color: '#fff', fontSize: 14, fontWeight: '600' }, card: { backgroundColor: '#1A1F2E', borderRadius: 12, padding: 16, marginBottom: 16, borderWidth: 1, borderColor: '#333' }, row: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }, label: { color: '#fff', fontSize: 15, fontWeight: '600' }, desc: { color: '#888', fontSize: 12, marginTop: 8 }, sectionTitle: { color: '#fff', fontSize: 15, fontWeight: '700', marginBottom: 10 }, cacheRow: { flexDirection: 'row', justifyContent: 'space-between', paddingVertical: 8, borderBottomWidth: 1, borderBottomColor: '#222' }, cacheLabel: { color: '#888' }, cacheVal: { color: '#fff', fontWeight: '600' }, progressBar: { height: 6, backgroundColor: '#333', borderRadius: 3, marginVertical: 12 }, progressFill: { height: 6, backgroundColor: '#00A0C8', borderRadius: 3 }, syncBtn: { backgroundColor: '#00A0C8', padding: 12, borderRadius: 10, alignItems: 'center', marginTop: 12 }, syncBtnText: { color: '#fff', fontWeight: '700' }, cacheItem: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', backgroundColor: '#1A1F2E', borderRadius: 10, padding: 14, marginBottom: 8, borderWidth: 1, borderColor: '#333' }, cacheItemLeft: {}, cacheItemRight: {}, cacheItemName: { color: '#fff', fontWeight: '600', marginBottom: 2 }, cacheItemMeta: { color: '#888', fontSize: 12 }, cacheItemStatus: { fontSize: 18 }, });