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 GreenOpsDashboardScreen() { const [energy, setEnergy] = useState(null) const [carbon, setCarbon] = useState(null) const [loading, setLoading] = useState(false) const load = useCallback(async () => { setLoading(true) try { const [e, c] = await Promise.all([ client.get('/api/greenops/energy'), client.get('/api/greenops/carbon'), ]) setEnergy(e.data); setCarbon(c.data) } catch {} finally { setLoading(false) } }, []) useFocusEffect(useCallback(() => { load() }, [load])) const servers = energy?.servers ?? energy?.items ?? [] const trend = carbon?.monthly ?? carbon?.trend ?? [] return ( } contentContainerStyle={{ padding: 12 }}> {/* 헤더 요약 */} {/* 서버별 전력 */} {servers.length > 0 && ( <> 서버별 전력 사용량 {servers.slice(0, 10).map((s2: any, i: number) => { const kwh = s2.kwh ?? s2.power_kwh ?? 0 const max = Math.max(...servers.map((x: any) => x.kwh ?? x.power_kwh ?? 0), 1) return ( {s2.name ?? s2.server_name ?? 'N/A'} {kwh}kWh ) })} )} {/* 월별 탄소 추이 */} {trend.length > 0 && ( <> 월별 탄소 배출 추이 {trend.slice(-6).map((t: any, i: number) => { const val = t.co2_kg ?? t.value ?? 0 const max2 = Math.max(...trend.map((x: any) => x.co2_kg ?? x.value ?? 0), 1) const h = Math.max(20, Math.round((val/max2)*80)) return ( {t.month?.slice(5) ?? `M${i+1}`} ) })} )} ) } function SummaryCard({ label, value, color, icon }: any) { return ( {icon} {value} {label} ) } const c = StyleSheet.create({ card: { flex: 1, backgroundColor: '#fff', borderRadius: 10, padding: 12, alignItems: 'center', borderTopWidth: 3, elevation: 1 }, icon: { fontSize: 24, marginBottom: 4 }, val: { fontSize: 16, fontWeight: '800', marginBottom: 2 }, label: { fontSize: 11, color: COLORS.muted }, }) const s = StyleSheet.create({ container: { flex: 1, backgroundColor: COLORS.bg }, summary: { flexDirection: 'row', gap: 8, marginBottom: 12 }, section: { fontSize: 14, fontWeight: '700', color: COLORS.text, marginTop: 8, marginBottom: 8 }, row: { flexDirection: 'row', alignItems: 'center', gap: 8, marginBottom: 8 }, sName: { fontSize: 12, color: COLORS.text, width: 90 }, barBg: { flex: 1, height: 8, backgroundColor: COLORS.border, borderRadius: 4 }, barFill: { height: 8, backgroundColor: COLORS.success, borderRadius: 4 }, kwhText: { fontSize: 11, color: COLORS.muted, width: 55, textAlign: 'right' }, trendRow: { flexDirection: 'row', alignItems: 'flex-end', gap: 8, height: 100 }, bar: { flex: 1, alignItems: 'center' }, barV: { width: '80%', backgroundColor: COLORS.accent, borderRadius: 4 }, barLabel: { fontSize: 10, color: COLORS.muted, marginTop: 4 }, })