import React, { useState, useCallback } from 'react' import { View, Text, ScrollView, StyleSheet, RefreshControl, TouchableOpacity } from 'react-native' import { useFocusEffect } from 'expo-router' import { COLORS } from '../../constants/Config' import client from '../../services/api' type Period = '30d' | '60d' | '90d' export default function CapacityPlanScreen() { const [data, setData] = useState(null) const [period, setPeriod] = useState('30d') const [loading, setLoading] = useState(false) const load = useCallback(async () => { setLoading(true) try { const r = await client.get(`/api/capacity/predictions?days=${period.replace('d', '')}`); setData(r.data) } catch { setData(null) } finally { setLoading(false) } }, [period]) useFocusEffect(useCallback(() => { load() }, [load])) const predictions = data?.predictions ?? data?.items ?? [] return ( }> {(['30d','60d','90d'] as Period[]).map(p => ( setPeriod(p)}> {p} ))} {predictions.map((item: any, i: number) => { const util = item.predicted_utilization ?? item.cpu_avg ?? 0 const color = util >= 90 ? COLORS.danger : util >= 70 ? COLORS.warning : COLORS.success return ( {item.server_name ?? item.name ?? 'N/A'} {item.inst_name ?? ''} · {item.resource_type ?? 'CPU'} {util}% {item.recommendation && ( AI 권고: {item.recommendation} )} ) })} {predictions.length === 0 && !loading && ( 예측 데이터가 없습니다. )} ) } const s = StyleSheet.create({ container: { flex: 1, backgroundColor: COLORS.bg }, tabs: { flexDirection: 'row', backgroundColor: '#fff', borderBottomWidth: 1, borderBottomColor: COLORS.border }, tab: { flex: 1, paddingVertical: 12, alignItems: 'center' }, tabActive: { borderBottomWidth: 2, borderBottomColor: COLORS.accent }, tabText: { fontSize: 13, color: COLORS.muted }, tabTextActive:{ color: COLORS.accent, fontWeight: '700' }, card: { backgroundColor: '#fff', margin: 8, marginBottom: 0, borderRadius: 10, padding: 14, elevation: 1 }, row: { flexDirection: 'row', alignItems: 'center', marginBottom: 8 }, serverName: { fontSize: 14, fontWeight: '700', color: COLORS.text }, meta: { fontSize: 12, color: COLORS.muted, marginTop: 2 }, pct: { fontSize: 22, fontWeight: '800' }, barBg: { height: 6, backgroundColor: COLORS.border, borderRadius: 3, marginBottom: 6 }, barFill: { height: 6, borderRadius: 3 }, rec: { fontSize: 12, color: COLORS.blue, fontStyle: 'italic' }, empty: { textAlign: 'center', color: COLORS.muted, marginTop: 40 }, })