"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) setRoomDeviceStatus(prev => ({ ...prev, "room_1": { ...prev["room_1"], "Lampu 1": backendData.lampu1 === "on", "Lampu 2": backendData.lampu2 === "on", "AC": backendData.ac === "on", "Proyektor": backendData.projector === "on", } })); } } catch (err) { console.error("Gagal sinkronisasi status perangkat:", err); } }; // ========================================================================= // 3. INISIALISASI & POLLING (AUTO-REFRESH) // ========================================================================= useEffect(() => { // Simulasi Data Ruangan 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); // 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": false, "Proyektor": false, }; }); setRoomDeviceStatus(initialStatus); // Tarik data pertama kali & set Interval 2 detik fetchPowerStatus(); fetchDeviceStatus(); const interval = setInterval(() => { fetchPowerStatus(); fetchDeviceStatus(); }, 2000); 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; // Logika Pintar: Jika sedang ON, maka klik selanjutnya adalah OFF. Sebaliknya. const actionType = currentStatus ? "off" : "on"; // Konfirmasi mematikan (Biar admin gak salah pencet) if (currentStatus) { const confirmMsg = `Apakah Anda yakin ingin mematikan ${deviceName} di ${roomName}?`; if (!window.confirm(confirmMsg)) return; // Jika di-cancel, berhenti di sini } // Mapping nama device untuk backend let backendDevice = ""; if (deviceName === 'AC') backendDevice = "ac"; else if (deviceName === 'Proyektor') backendDevice = "projector"; else if (deviceName === 'Lampu 1') backendDevice = "lampu1"; else if (deviceName === 'Lampu 2') backendDevice = "lampu2"; // 1. UBAH UI SEKETIKA (Optimistic UI) agar layar merespons tanpa delay setRoomDeviceStatus(prev => ({ ...prev, [roomIdKey]: { ...prev[roomIdKey], [deviceName]: !currentStatus, }, })); // 2. KIRIM KE GOLANG 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 }), }); // 3. JIKA GAGAL, KEMBALIKAN UI KE POSISI SEMULA if (!response.ok) { setRoomDeviceStatus(prev => ({ ...prev, [roomIdKey]: { ...prev[roomIdKey], [deviceName]: currentStatus, }, })); const errorData = await response.json(); alert(`GAGAL: ${errorData.error || "Server menolak perintah"}`); } } catch (error) { console.error("Error API:", error); // Rollback UI jika koneksi mati setRoomDeviceStatus(prev => ({ ...prev, [roomIdKey]: { ...prev[roomIdKey], [deviceName]: currentStatus, }, })); alert("GAGAL: Tidak dapat terhubung ke Server Golang."); } }; const handleCutOff = (roomName: string) => { if (window.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 (

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 (
{room.isRelayOn ? 'Sirkuit Aktif' : 'Sirkuit Terputus'}

{room.name}

1000 ? 'text-orange-500' : 'text-gray-800'}`}> {room.power} Watts
{room.power > 1000 && (
Beban Tinggi Terdeteksi!
)}

IoT Device Control

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