import { useState } from 'react'; import { Button } from '#/components/atoms/button.jsx'; /** * One group of repository settings: what the group is called, what it means, * the fields, and the button that writes them. Each group saves on its own, * because one request covers one setting and leaves the rest alone. * * The panel holds the write. `value` is what the fields would send, so the * panel can tell what it last wrote from an edit since: it says the write * landed until the fields move again, and the button is dead while there is * nothing new to send. * @param {{title: string, note?: import('react').ReactNode, action?: string, value: unknown, onSave: () => Promise, children: import('react').ReactNode}} props */ export function SettingsPanel({ title, note, action = 'Save', value, onSave, children, }) { const [busy, setBusy] = useState(false); const [error, setError] = useState(''); const [written, setWritten] = useState(''); const pending = JSON.stringify(value); const saved = written !== '' && written === pending; const submit = async (/** @type {{preventDefault: () => void}} */ event) => { event.preventDefault(); setBusy(true); setError(''); try { await onSave(); setWritten(pending); } catch (err) { setError(err instanceof Error ? err.message : String(err)); } setBusy(false); }; return (

{title}

{note && (

{note}

)}
{children}
{saved && ( Saved. )} {error && ( {error} )}
); }