"use client"; import { useCallback, useEffect, useState } from "react"; import { Database, HardDrive, Trash2, Activity } from "lucide-react"; import { AdminSettingRow, AdminStatCard, AdminSwitch } from "@/components/admin"; import ConfirmDialog from "@/components/ConfirmDialog"; import { apiStatsPurge, apiStatsSaveSettings, apiStatsSettings, type VisitSettingsPayload } from "@/lib/api"; import { StatsState, formatBytes, formatInt } from "../ui"; /** 保留天数输入边界(与后端 service 一致) */ const RETENTION_MIN = 7; const RETENTION_MAX = 365; export default function SettingsPage() { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); const [enabled, setEnabled] = useState(true); const [retention, setRetention] = useState(90); const [saving, setSaving] = useState(false); const [savedMsg, setSavedMsg] = useState(""); // 立即清理:天数输入 + 确认弹窗 + 受理提示 const [purgeDays, setPurgeDays] = useState(90); const [purgeOpen, setPurgeOpen] = useState(false); const [purging, setPurging] = useState(false); const [purgeMsg, setPurgeMsg] = useState(""); const load = useCallback(() => { apiStatsSettings() .then((d) => { setData(d); setEnabled(d.enabled); setRetention(d.retention_days); setPurgeDays(d.retention_days); setError(""); }) .catch(() => setError("加载失败,请稍后重试")) .finally(() => setLoading(false)); }, []); useEffect(() => { load(); }, [load]); const save = (nextEnabled: boolean, nextRetention: number) => { setSaving(true); setSavedMsg(""); apiStatsSaveSettings(nextEnabled, nextRetention) .then((d) => { setData(d); setEnabled(d.enabled); setRetention(d.retention_days); setSavedMsg("已保存"); setTimeout(() => setSavedMsg(""), 2000); }) .catch(() => setError("保存失败,请稍后重试")) .finally(() => setSaving(false)); }; const toggleEnabled = () => { if (saving) return; save(!enabled, retention); }; const submitRetention = () => { if (saving) return; const v = Math.min(RETENTION_MAX, Math.max(RETENTION_MIN, Math.round(Number(retention) || 90))); setRetention(v); save(enabled, v); }; const doPurge = () => { setPurging(true); apiStatsPurge(purgeDays) .then(() => { setPurgeMsg(`清理任务已受理(删除 ${purgeDays} 天前的明细),稍后刷新本页查看容量变化。`); setTimeout(load, 3000); }) .catch(() => setPurgeMsg("清理请求失败,请稍后重试。")) .finally(() => { setPurging(false); setPurgeOpen(false); }); }; if (!data) return ; const clampPurge = (v: number) => Math.min(RETENTION_MAX, Math.max(1, Math.round(Number(v) || 1))); return (
{error ? : null} {purgeMsg ? (
{purgeMsg}
) : null}
} /> } color="var(--ok)" soft="var(--ok-soft, var(--panel-2))" /> } color="var(--gold)" soft="var(--gold-soft)" /> } color="var(--ink-2)" soft="var(--panel-2)" />
} />
setRetention(Number(e.target.value))} onBlur={submitRetention} onKeyDown={(e) => e.key === "Enter" && submitRetention()} className="admin-field-input" style={{ width: 120 }} aria-label="明细保留天数" /> 天 {saving ? 保存中… : null} {savedMsg ? ( {savedMsg} ) : null}
setPurgeDays(clampPurge(Number(e.target.value)))} className="admin-field-input" style={{ width: 120 }} aria-label="清理多少天前的明细" /> 天前的明细
setPurgeOpen(false)} />
); }