first commit
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
import { create } from "zustand";
|
||||
import { apiJson } from "@/utils/api";
|
||||
import type { AppConfig, Camera, Schedule } from "@/types/api";
|
||||
|
||||
type ConfigState = {
|
||||
config: AppConfig | null;
|
||||
isLoading: boolean;
|
||||
error: string | null;
|
||||
load: () => Promise<void>;
|
||||
addCamera: (camera: Camera) => Promise<void>;
|
||||
deleteCamera: (name: string) => Promise<void>;
|
||||
setSchedulerEnabled: (enabled: boolean) => Promise<void>;
|
||||
updateSchedule: (schedule: Omit<Schedule, "enabled">) => Promise<void>;
|
||||
};
|
||||
|
||||
function errToMessage(err: unknown) {
|
||||
if (!err) return "unknown_error";
|
||||
if (typeof err === "string") return err;
|
||||
if (typeof err === "object" && err && "status" in err) {
|
||||
const e = err as { status: number; bodyText?: string };
|
||||
return `http_${e.status}${e.bodyText ? `: ${e.bodyText}` : ""}`;
|
||||
}
|
||||
return "unknown_error";
|
||||
}
|
||||
|
||||
export const useConfigStore = create<ConfigState>((set, get) => ({
|
||||
config: null,
|
||||
isLoading: false,
|
||||
error: null,
|
||||
load: async () => {
|
||||
set({ isLoading: true, error: null });
|
||||
try {
|
||||
const cfg = await apiJson<AppConfig>("/config", { method: "GET" });
|
||||
set({ config: cfg, isLoading: false });
|
||||
} catch (e) {
|
||||
set({ isLoading: false, error: errToMessage(e) });
|
||||
}
|
||||
},
|
||||
addCamera: async (camera) => {
|
||||
set({ isLoading: true, error: null });
|
||||
try {
|
||||
const cfg = await apiJson<AppConfig>("/cameras", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(camera),
|
||||
});
|
||||
set({ config: cfg, isLoading: false });
|
||||
} catch (e) {
|
||||
set({ isLoading: false, error: errToMessage(e) });
|
||||
}
|
||||
},
|
||||
deleteCamera: async (name) => {
|
||||
set({ isLoading: true, error: null });
|
||||
try {
|
||||
const cfg = await apiJson<AppConfig>(`/cameras/${encodeURIComponent(name)}`, {
|
||||
method: "DELETE",
|
||||
});
|
||||
set({ config: cfg, isLoading: false });
|
||||
} catch (e) {
|
||||
set({ isLoading: false, error: errToMessage(e) });
|
||||
}
|
||||
},
|
||||
setSchedulerEnabled: async (enabled) => {
|
||||
set({ isLoading: true, error: null });
|
||||
try {
|
||||
const cfg = await apiJson<AppConfig>("/scheduler/enabled", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ enabled }),
|
||||
});
|
||||
set({ config: cfg, isLoading: false });
|
||||
} catch (e) {
|
||||
set({ isLoading: false, error: errToMessage(e) });
|
||||
}
|
||||
},
|
||||
updateSchedule: async (schedule) => {
|
||||
const cfg = get().config;
|
||||
const enabled = cfg?.schedule.enabled ?? true;
|
||||
set({ isLoading: true, error: null });
|
||||
try {
|
||||
const next = await apiJson<AppConfig>("/scheduler/schedule", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(schedule),
|
||||
});
|
||||
set({ config: { ...next, schedule: { ...next.schedule, enabled } }, isLoading: false });
|
||||
} catch (e) {
|
||||
set({ isLoading: false, error: errToMessage(e) });
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user