"use client"; import { useEffect, useState } from "react"; import { collection, doc, onSnapshot, query, orderBy, limit, where, FirestoreError } from "firebase/firestore"; import { onAuthStateChanged } from "firebase/auth"; import { db, auth } from "@/lib/firebase"; import type { IncidentRecord } from "@/lib/types"; const toISO = (v: unknown): string => (v as { toDate?: () => Date })?.toDate?.()?.toISOString?.() ?? (typeof v === "string" ? v : new Date().toISOString()); export function useIncidents(limitCount = 100) { const [incidents, setIncidents] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { let unsubFirestore: (() => void) | undefined; const unsubAuth = onAuthStateChanged(auth, (user) => { if (unsubFirestore) { unsubFirestore(); unsubFirestore = undefined; } if (!user) { setIncidents([]); setLoading(false); return; } const q = query( collection(db, "incidents"), orderBy("started_at", "desc"), limit(limitCount) ); unsubFirestore = onSnapshot(q, (snap) => { setIncidents(snap.docs.map((d) => { const data = d.data(); return { ...data, started_at: toISO(data.started_at), updated_at: toISO(data.updated_at), } as IncidentRecord; })); setLoading(false); }, (err: FirestoreError) => { console.error("useIncidents:", err); setError(err.message); setLoading(false); }); }); return () => { unsubAuth(); if (unsubFirestore) unsubFirestore(); }; }, [limitCount]); return { incidents, loading, error }; } export function useIncident(incidentId: string | null) { const [incident, setIncident] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { if (!incidentId) { setLoading(false); return; } let unsubFirestore: (() => void) | undefined; const unsubAuth = onAuthStateChanged(auth, (user) => { if (unsubFirestore) { unsubFirestore(); unsubFirestore = undefined; } if (!user) { setLoading(false); return; } const ref = doc(db, "incidents", incidentId); unsubFirestore = onSnapshot(ref, (snap) => { if (snap.exists()) { const data = snap.data(); setIncident({ ...data, started_at: toISO(data.started_at), updated_at: toISO(data.updated_at), } as IncidentRecord); } else { setIncident(null); } setLoading(false); }, (err: FirestoreError) => { console.error("useIncident:", err); setLoading(false); }); }); return () => { unsubAuth(); if (unsubFirestore) unsubFirestore(); }; }, [incidentId]); return { incident, loading }; } export function useActiveIncidents() { const [incidents, setIncidents] = useState([]); useEffect(() => { let unsubFirestore: (() => void) | undefined; const unsubAuth = onAuthStateChanged(auth, (user) => { if (unsubFirestore) { unsubFirestore(); unsubFirestore = undefined; } if (!user) { setIncidents([]); return; } const q = query(collection(db, "incidents"), where("status", "==", "active")); unsubFirestore = onSnapshot(q, (snap) => { setIncidents(snap.docs.map((d) => { const data = d.data(); return { ...data, started_at: toISO(data.started_at), updated_at: toISO(data.updated_at), } as IncidentRecord; })); }, (err: FirestoreError) => { console.error("useActiveIncidents:", err); }); }); return () => { unsubAuth(); if (unsubFirestore) unsubFirestore(); }; }, []); return incidents; }