"use client"; import { useState, useEffect, useRef, useCallback } from "react"; import { Loader2, Check, AlertCircle } from "lucide-react"; interface SectionEditorProps { sectionKey: string; title: string; children: (data: T, update: (data: T) => void) => React.ReactNode; } const DEBOUNCE_MS = 800; export function SectionEditor({ sectionKey, title, children, }: SectionEditorProps) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [status, setStatus] = useState<"idle" | "saving" | "saved" | "error">("idle"); const [error, setError] = useState(""); const timerRef = useRef | null>(null); const initialLoadRef = useRef(true); useEffect(() => { fetch(`/api/admin/sections/${sectionKey}`) .then((r) => { if (!r.ok) throw new Error("Failed to load"); return r.json(); }) .then(setData) .catch(() => setError("Не удалось загрузить данные")) .finally(() => setLoading(false)); }, [sectionKey]); const save = useCallback(async (dataToSave: T) => { setStatus("saving"); setError(""); try { const res = await fetch(`/api/admin/sections/${sectionKey}`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(dataToSave), }); if (!res.ok) throw new Error("Failed to save"); setStatus("saved"); setTimeout(() => setStatus((s) => (s === "saved" ? "idle" : s)), 2000); } catch { setStatus("error"); setError("Ошибка сохранения"); } }, [sectionKey]); // Auto-save with debounce whenever data changes (skip initial load) useEffect(() => { if (!data) return; if (initialLoadRef.current) { initialLoadRef.current = false; return; } if (timerRef.current) clearTimeout(timerRef.current); timerRef.current = setTimeout(() => { save(data); }, DEBOUNCE_MS); return () => { if (timerRef.current) clearTimeout(timerRef.current); }; }, [data, save]); if (loading) { return (
Загрузка...
); } if (!data) { return

{error || "Данные не найдены"}

; } return (

{title}

{status === "saving" && ( <> Сохранение... )} {status === "saved" && ( <> Сохранено )} {status === "error" && ( <> {error} )}
{children(data, setData)}
); }