diff --git a/src/frontend/routes/dev.tsx b/src/frontend/routes/dev.tsx index f42e028..182c0d2 100644 --- a/src/frontend/routes/dev.tsx +++ b/src/frontend/routes/dev.tsx @@ -1482,7 +1482,7 @@ const CONFIG_DEFINITIONS: { key: string; label: string; description: string; pla function SettingsPanel() { const qc = useQueryClient() const [values, setValues] = useState>({}) - const [saved, setSaved] = useState>({}) + const [saved, setSaved] = useState(false) const { data, isLoading } = useQuery({ queryKey: ['admin', 'config'], @@ -1500,81 +1500,86 @@ function SettingsPanel() { setValues(initial) }, [configs]) - const saveMutation = useMutation({ - mutationFn: ({ key, value }: { key: string; value: string }) => - fetch('/api/admin/config', { - method: 'PUT', - credentials: 'include', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ key, value }), - }).then((r) => r.json()), - onSuccess: (_, { key }) => { + const saveAllMutation = useMutation({ + mutationFn: async (vals: Record) => { + await Promise.all( + CONFIG_DEFINITIONS.map((def) => + fetch('/api/admin/config', { + method: 'PUT', + credentials: 'include', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ key: def.key, value: vals[def.key] ?? '' }), + }) + ) + ) + }, + onSuccess: () => { qc.invalidateQueries({ queryKey: ['admin', 'config'] }) - setSaved((prev) => ({ ...prev, [key]: true })) - setTimeout(() => setSaved((prev) => ({ ...prev, [key]: false })), 2000) + setSaved(true) + setTimeout(() => setSaved(false), 2000) }, }) + const hasUnconfigured = CONFIG_DEFINITIONS.some((def) => !configs.find((c) => c.key === def.key)) + return ( Settings Konfigurasi runtime — perubahan langsung berlaku tanpa rebuild atau redeploy. {isLoading ?
: ( - - {CONFIG_DEFINITIONS.map((def) => { - const existing = configs.find((c) => c.key === def.key) - return ( - - - + + + {CONFIG_DEFINITIONS.map((def) => { + const existing = configs.find((c) => c.key === def.key) + return ( + +
{def.label} {def.key}
- {existing && ( - - Diupdate {new Date(existing.updatedAt).toLocaleString('id-ID')} - - )} + {existing + ? Diupdate {new Date(existing.updatedAt).toLocaleString('id-ID')} + : Belum dikonfigurasi + }
{def.description} - - - setValues((prev) => ({ ...prev, [def.key]: e.target.value }))} - placeholder={def.placeholder} - /> - - - - {!existing && ( - Belum dikonfigurasi — data tidak akan ter-load - )} + setValues((prev) => ({ ...prev, [def.key]: e.target.value }))} + placeholder={def.placeholder} + />
-
- ) - })} -
+ ) + })} + + {hasUnconfigured && ( + Beberapa konfigurasi belum diisi — data tidak akan ter-load sampai disimpan. + )} + + + + +
+ )}
)