96 lines
2.7 KiB
TypeScript
96 lines
2.7 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import { collection, 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<IncidentRecord[]>([]);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState<string | null>(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 useActiveIncidents() {
|
|
const [incidents, setIncidents] = useState<IncidentRecord[]>([]);
|
|
|
|
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;
|
|
}
|