import React, { useState } from 'react'; import { View, Text, ScrollView, TouchableOpacity, StyleSheet, Alert } from 'react-native'; import { ITSM_BASE } from '../../services/api'; interface AROverlay { label: string; value: string; color: string; x: number; y: number } const SAMPLE_OVERLAYS: AROverlay[] = [ { label: 'CPU', value: '42%', color: '#44bb44', x: 20, y: 80 }, { label: 'RAM', value: '67%', color: '#ffbb00', x: 60, y: 40 }, { label: 'DISK', value: '81%', color: '#ff8800', x: 70, y: 70 }, { label: 'NET', value: '1.2GB/s', color: '#44bb44', x: 30, y: 50 }, { label: 'TEMP', value: '52°C', color: '#44bb44', x: 50, y: 20 }, ]; export default function CameraARScreen() { const [scanning, setScanning] = useState(false); const [overlays, setOverlays] = useState([]); const [detectedServer, setDetectedServer] = useState(null); const [serverInfo, setServerInfo] = useState(null); const startScan = async () => { setScanning(true); setTimeout(() => { setOverlays(SAMPLE_OVERLAYS); setDetectedServer('app-svr-01'); setScanning(false); }, 1500); }; const fetchServerDetail = async (name: string) => { try { const r = await fetch(`${ITSM_BASE}/api/cmdb/servers?search=${name}`); if (r.ok) { const d = await r.json(); setServerInfo(d.servers?.[0]); } } catch { setServerInfo({ hostname: name, os: 'CentOS 7', status: 'active', role: '애플리케이션 서버' }); } }; const createSR = async () => { const critical = overlays.filter(o => o.color === '#ff4444' || o.color === '#ff8800'); if (critical.length === 0) { Alert.alert('정상', '감지된 이상 없음'); return; } try { await fetch(`${ITSM_BASE}/api/tasks`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ title: `[AR스캔] ${detectedServer} 리소스 이상`, description: critical.map(c => `${c.label}: ${c.value}`).join('\n'), priority: 'high' }), }); Alert.alert('SR 등록', 'AR 스캔 기반 SR이 등록되었습니다.'); } catch { Alert.alert('오류', 'SR 등록 실패'); } }; return ( 카메라 AR 오버레이 서버/장비를 카메라로 비추면 실시간 메트릭을 오버레이합니다 {!scanning && overlays.length === 0 && ( 📷 카메라 영역{'\n'}(실제 기기에서 카메라 활성화) )} {scanning && 🔍 서버 인식 중...} {overlays.map((o, i) => ( {o.label} {o.value} ))} {detectedServer && ✅ {detectedServer}} {scanning ? '스캔 중...' : '📡 AR 스캔 시작'} {overlays.length > 0 && ( 감지된 메트릭 {overlays.map((o, i) => ( {o.label} {o.value} ))} 📋 이상 항목 SR 등록 )} ); } 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 }, cameraView: { backgroundColor: '#1A1F2E', borderRadius: 12, overflow: 'hidden', marginBottom: 16, borderWidth: 1, borderColor: '#333' }, cameraFrame: { height: 260, position: 'relative', alignItems: 'center', justifyContent: 'center' }, cameraPlaceholder: { color: '#555', textAlign: 'center', fontSize: 14 }, scanningText: { color: '#00A0C8', fontSize: 16, fontWeight: '600' }, overlay: { position: 'absolute', backgroundColor: 'rgba(0,0,0,0.75)', borderWidth: 1, borderRadius: 6, padding: 6 }, overlayLabel: { color: '#fff', fontSize: 10, fontWeight: '600' }, overlayValue: { fontSize: 12, fontWeight: '700' }, detectedBadge: { position: 'absolute', bottom: 12, right: 12, backgroundColor: '#003366', paddingHorizontal: 10, paddingVertical: 4, borderRadius: 12, borderWidth: 1, borderColor: '#00A0C8' }, detectedText: { color: '#fff', fontSize: 12, fontWeight: '600' }, scanBtn: { backgroundColor: '#00A0C8', padding: 14, alignItems: 'center' }, scanBtnText: { color: '#fff', fontWeight: '700', fontSize: 15 }, metricsCard: { backgroundColor: '#1A1F2E', borderRadius: 12, padding: 16, borderWidth: 1, borderColor: '#333' }, metricsTitle: { color: '#fff', fontWeight: '700', fontSize: 16, marginBottom: 12 }, metricsGrid: { flexDirection: 'row', flexWrap: 'wrap', gap: 10, marginBottom: 14 }, metricItem: { backgroundColor: '#0A0E1A', borderWidth: 1, borderRadius: 10, padding: 10, minWidth: '28%', alignItems: 'center' }, metricLabel: { color: '#aaa', fontSize: 11, marginBottom: 4 }, metricValue: { fontSize: 16, fontWeight: '700' }, srBtn: { backgroundColor: '#003366', padding: 12, borderRadius: 10, alignItems: 'center', borderWidth: 1, borderColor: '#00A0C8' }, srBtnText: { color: '#fff', fontWeight: '700' }, });