"use client"; import React, { useState, useEffect } from "react"; import dynamic from "next/dynamic"; import KartuStatus from "@/components/KartuStatus"; import TabelAir from "@/components/TabelAir"; import TabelPrediksi from "@/components/TabelPrediksi"; import { rtdb } from "@/lib/firebase"; import { ref, query, limitToLast, onValue } from "firebase/database"; // Dynamic import for Leaflet (CSR only) const PetaLokasi = dynamic(() => import("@/components/PetaLokasi"), { ssr: false, loading: () =>
Memuat Peta...
}); export default function DashboardPage() { const [currentLevel, setCurrentLevel] = useState(0); const [riskInfo, setRiskInfo] = useState({ status: "LOADING", risk: "Memuat...", color: "#9ca3af" }); const [history, setHistory] = useState<{ time: string; level: number; status: string }[]>([]); const [location, setLocation] = useState<{ lat?: number; lng?: number }>({}); const [predictions, setPredictions] = useState<{ time: string; predictedLevel: number | null; currentLevel: number; status: string; currentStatus: string; risk: string; color: string; }[]>([]); const [isAlertDismissed, setIsAlertDismissed] = useState(false); const [firebaseError, setFirebaseError] = useState(null); const getStatus = (level: number) => { if (level < 56) return "NORMAL"; if (level <= 75) return "WASPADA"; return "BAHAYA"; }; const getRiskAnalysis = (current: number, predicted: number | null) => { if (predicted === null) return { status: "LOADING", risk: "Menunggu Prediksi...", color: "#9ca3af" }; const curS = getStatus(current); const predS = getStatus(predicted); // Kasus 1, 2, 3: Current Normal (<56) if (curS === "NORMAL") { if (predS === "NORMAL") return { status: "NORMAL", risk: "Rendah", color: "#22c55e" }; if (predS === "WASPADA") return { status: "WASPADA", risk: "Sedang", color: "#f59e0b" }; if (predS === "BAHAYA") return { status: "BAHAYA", risk: "Tinggi", color: "#ef4444" }; } // Kasus 4, 5, 6: Current Waspada (56-75) if (curS === "WASPADA") { if (predS === "NORMAL") return { status: "NORMAL", risk: "Waspada (Menurun)", color: "#f59e0b" }; if (predS === "WASPADA") return { status: "WASPADA", risk: "Waspada (Sedang)", color: "#f59e0b" }; if (predS === "BAHAYA") return { status: "BAHAYA", risk: "Bahaya (Tinggi)", color: "#ef4444" }; } // Kasus 7, 8, 9: Current Bahaya (>75) if (curS === "BAHAYA") { if (predS === "NORMAL") return { status: "NORMAL", risk: "Menurun Signifikan", color: "#22c55e" }; if (predS === "WASPADA") return { status: "WASPADA", risk: "Menurun Bertahap", color: "#f59e0b" }; if (predS === "BAHAYA") return { status: "BAHAYA", risk: "Bahaya (Kritis)", color: "#ef4444" }; } return { status: "NORMAL", risk: "Rendah", color: "#22c55e" }; }; useEffect(() => { // Mengambil data dari node 'iot/monitoring' di Realtime Database const refSensor = ref(rtdb, "iot/monitoring"); const unsubscribeSensor = onValue(refSensor, (snapshot) => { if (snapshot.exists()) { const data = snapshot.val(); console.log("Data diterima dari Firebase:", data); if (data) { // Menggunakan data elevasi_air sebagai elevasi air const level = parseFloat(data.elevasi_air?.toString() || "0"); // Format timestamp if it exists, otherwise use current time const timeStr = data.timestamp ? new Date(data.timestamp).toLocaleString("id-ID") : new Date().toLocaleString("id-ID"); if (data.latitude && data.longitude) { setLocation({ lat: parseFloat(data.latitude), lng: parseFloat(data.longitude) }); } setCurrentLevel(level); const status = getStatus(level); if (status !== "BAHAYA") { setIsAlertDismissed(false); } // Update history setHistory([{ time: timeStr, level: level, status: status }]); // Prediksi dari alat IoT const predLevel = data.prediksi !== undefined && data.prediksi !== null ? parseFloat(data.prediksi) : null; // Kita bisa tetap menggunakan getRiskAnalysis untuk menentukan status dan risk jika IoT tidak mengirimkannya, // atau menggunakan data langsung dari IoT jika ada. const analysis = getRiskAnalysis(level, predLevel); setRiskInfo({ status: data.predicted_status || analysis.status, risk: data.risk || analysis.risk, color: analysis.color // color bisa tetap dari frontend atau sesuaikan }); setPredictions([{ time: timeStr, predictedLevel: predLevel, currentLevel: level, status: data.predicted_status || analysis.status, currentStatus: status, risk: data.risk || analysis.risk, color: analysis.color }]); } } else { console.log("Node iot/monitoring tidak ditemukan di Firebase"); setFirebaseError("Data pada node iot/monitoring kosong atau tidak ditemukan. (Pastikan huruf kecil semua)"); } }, (error) => { console.error("Error mengambil data dari Firebase:", error); setFirebaseError(error.message || "Gagal menghubungi Firebase. Pastikan koneksi internet stabil dan aturan (Rules) Firebase mengizinkan read."); }); return () => unsubscribeSensor(); }, []); return (
{/* Error Message Display */} {firebaseError && (
Firebase Error: {firebaseError}

DB URL Terbaca: {process.env.NEXT_PUBLIC_FIREBASE_DATABASE_URL || "TIDAK TERBACA"}

)} {/* Floating Danger Alert */} {riskInfo.status === "BAHAYA" && !isAlertDismissed && (

PERINGATAN! Kondisi Sungai Bahaya

Segera lakukan pencegahan

)} {/* Navigasi / Header Refined */}
{/* Section 1: Status Cards (3 Grid) */} {/* Section 2: Current Water Data */} {/* Section 3: Prediction Data */} {/* Section 4: Maps Visualization */}

Peta Lokasi Alat Monitoring

); }