"use client"; import { useState, useEffect } from "react"; import { Activity, Power, ZapOff, AlertTriangle, Lightbulb, Wind, Projector } from "lucide-react"; export default function PowerMonitoringPage() { // ========================================================================= // 1. DEKLARASI STATE // ========================================================================= const [rooms, setRooms] = useState([]); const [roomDeviceStatus, setRoomDeviceStatus] = useState<{ [roomId: string]: { [deviceName: string]: boolean } }>({}); // ========================================================================= // 2. FUNGSI FETCH DATA DARI BACKEND // ========================================================================= // A. Tarik Data Daya (Power / Watt) const fetchPowerStatus = async () => { try { const response = await fetch("http://172.17.172.17:8080/api/hardware/power-status"); const data = await response.json(); setRooms(prev => prev.map(room => room.name === "Kelas D101" ? { ...room, power: parseFloat(data.power) || 0 } : room )); } catch (err) { console.error("Gagal mengambil data daya:", err); } }; // B. Tarik Data Status Perangkat (Sinkronisasi Real-time Antar Admin) const fetchDeviceStatus = async () => { try { const response = await fetch("http://172.17.172.17:8080/api/hardware/status"); const result = await response.json(); if (result.status === "success") { const backendData = result.data; // Kita terjemahkan data Golang ("on"/"off") menjadi boolean (true/false) // dan masukkan khusus untuk Kelas D101 (id: 1) setRoomDeviceStatus(prev => ({ ...prev, "room_1": { ...prev["room_1"], "Lampu 1": backendData.lampu1 === "on", "Lampu 2": backendData.lampu2 === "on", "AC 1": backendData.ac === "on", "Proyektor": backendData.projector === "on", } })); } } catch (err) { console.error("Gagal sinkronisasi status perangkat:", err); } }; // ========================================================================= // 3. INISIALISASI & POLLING (AUTO-REFRESH) // ========================================================================= useEffect(() => { // A. Simulasi Data Ruangan dari DB/IoT const dummyRooms = [ { id: 1, name: "Kelas D101", power: 0, isRelayOn: true, lastUpdate: "Real-time" }, { id: 2, name: "Kelas D102", power: 0, isRelayOn: false, lastUpdate: "2 mnt lalu" }, { id: 3, name: "Kelas D103", power: 45, isRelayOn: true, lastUpdate: "Baru saja" }, { id: 4, name: "Kelas D104", power: 0, isRelayOn: false, lastUpdate: "10 mnt lalu" }, ]; setRooms(dummyRooms); // B. Inisialisasi status default semua device OFF const initialStatus: { [roomId: string]: { [deviceName: string]: boolean } } = {}; dummyRooms.forEach(room => { initialStatus[`room_${room.id}`] = { "Lampu 1": false, "Lampu 2": false, "AC 1": false, "Proyektor": false, }; }); setRoomDeviceStatus(initialStatus); // C. Tarik data pertama kali saat halaman dibuka fetchPowerStatus(); fetchDeviceStatus(); // D. Jalankan Polling setiap 2 detik (2000 ms) const interval = setInterval(() => { fetchPowerStatus(); fetchDeviceStatus(); }, 2000); // E. Bersihkan interval jika admin pindah halaman return () => clearInterval(interval); }, []); // ========================================================================= // 4. FUNGSI KONTROL DEVICE (TOGGLE ON/OFF) // ========================================================================= const handleDeviceToggle = async (roomId: number, roomName: string, deviceName: string) => { const roomIdKey = `room_${roomId}`; const currentStatus = roomDeviceStatus[roomIdKey]?.[deviceName] || false; const actionType = currentStatus ? "off" : "on"; const confirmMsg = `Apakah Anda yakin ingin mematikan ${deviceName} di ${roomName}?`; if (currentStatus && !confirm(confirmMsg)) return; let backendDevice = ""; if (deviceName === 'AC 1') backendDevice = "ac"; else if (deviceName === 'Proyektor') backendDevice = "projector"; else if (deviceName === 'Lampu 1') backendDevice = "lampu1"; else if (deviceName === 'Lampu 2') backendDevice = "lampu2"; // Update UI seketika agar terasa responsif bagi admin yang menekan tombol setRoomDeviceStatus(prev => ({ ...prev, [roomIdKey]: { ...prev[roomIdKey], [deviceName]: !currentStatus, }, })); try { const response = await fetch("http://172.17.172.17:8080/api/hardware/control", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ device: backendDevice, action: actionType }), }); if (!response.ok) { // Jika gagal, kembalikan posisi tombol ke keadaan semula setRoomDeviceStatus(prev => ({ ...prev, [roomIdKey]: { ...prev[roomIdKey], [deviceName]: currentStatus, }, })); const errorData = await response.json(); alert(`GAGAL: ${errorData.error || response.statusText}`); } } catch (error) { console.error("Error API:", error); // Jika server mati, kembalikan posisi tombol setRoomDeviceStatus(prev => ({ ...prev, [roomIdKey]: { ...prev[roomIdKey], [deviceName]: currentStatus, }, })); alert("GAGAL: Tidak dapat terhubung ke Server Golang."); } }; const handleCutOff = (roomName: string) => { if (confirm(`PERINGATAN: Anda yakin ingin mematikan daya secara paksa di ${roomName}?`)) { alert(`Sinyal pemutusan daya dikirim ke Relay Master ${roomName}.`); } }; // ========================================================================= // 5. TAMPILAN UI (RENDER) // ========================================================================= return (
{/* Header section */}

Power Monitoring & Control

Pantau konsumsi daya kWh meter dan kendalikan relay sirkuit ruangan.

{[...rooms].sort((a, b) => a.name.localeCompare(b.name)).map((room) => { const roomIdKey = `room_${room.id}`; const currentRoomStatus = roomDeviceStatus[roomIdKey] || {}; return (
{/* Status Badge */}
{room.isRelayOn ? 'Sirkuit Aktif' : 'Sirkuit Terputus'}

{room.name}

{/* Power display */}
1000 ? 'text-orange-500' : 'text-gray-800'}`}> {room.power} Watts
{room.power > 1000 && (
Beban Tinggi Terdeteksi!
)} {/* PANEL KONTROL IoT */}

IoT Device Control

{/* LAMPU 1 */} {/* LAMPU 2 */} {/* AC 1 */} {/* PROYEKTOR */}
{/* Footer */}
Update: {room.lastUpdate}
); })}
); }