0.0.1
This commit is contained in:
75
src/hooks/useSettingsGroups.ts
Normal file
75
src/hooks/useSettingsGroups.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { doc, getDoc } from "firebase/firestore";
|
||||
|
||||
import { db } from "@/lib/firebase";
|
||||
|
||||
export type GroupRow = {
|
||||
groupId: string;
|
||||
displayName: string;
|
||||
};
|
||||
|
||||
type FirestoreStatus = "idle" | "loading" | "error";
|
||||
|
||||
function parseGroupsDoc(data: { groups?: unknown } | undefined): GroupRow[] {
|
||||
const raw = data?.groups;
|
||||
if (!Array.isArray(raw)) return [];
|
||||
|
||||
return raw
|
||||
.map((g) => g as Partial<GroupRow>)
|
||||
.filter((g) => typeof g.groupId === "string" && g.groupId.length > 0)
|
||||
.map((g) => ({
|
||||
groupId: g.groupId as string,
|
||||
displayName:
|
||||
typeof g.displayName === "string" && g.displayName.length > 0
|
||||
? g.displayName
|
||||
: (g.groupId as string),
|
||||
}));
|
||||
}
|
||||
|
||||
export function useSettingsGroups(enabled = true) {
|
||||
const [groups, setGroups] = useState<GroupRow[]>([]);
|
||||
const [status, setStatus] = useState<FirestoreStatus>("idle");
|
||||
const [error, setError] = useState<string>("");
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
if (!enabled) {
|
||||
setGroups([]);
|
||||
setStatus("idle");
|
||||
setError("");
|
||||
return;
|
||||
}
|
||||
|
||||
setStatus("loading");
|
||||
setError("");
|
||||
|
||||
try {
|
||||
const snap = await getDoc(doc(db, "settings", "groups"));
|
||||
|
||||
if (!snap.exists()) {
|
||||
setGroups([]);
|
||||
setStatus("idle");
|
||||
return;
|
||||
}
|
||||
|
||||
setGroups(parseGroupsDoc(snap.data() as { groups?: unknown }));
|
||||
setStatus("idle");
|
||||
} catch (e) {
|
||||
setStatus("error");
|
||||
setError(e instanceof Error ? e.message : "Failed to load groups");
|
||||
}
|
||||
}, [enabled]);
|
||||
|
||||
useEffect(() => {
|
||||
void refresh();
|
||||
}, [refresh]);
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
groups,
|
||||
status,
|
||||
error,
|
||||
refresh,
|
||||
}),
|
||||
[error, groups, refresh, status],
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user