"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
);
}