import { useSignal, useSignalEffect } from '@preact/signals'; import { useEffect } from 'preact/hooks'; import { RequestBody, ResponseBody } from '/routes/api/dashboard/save-notes.tsx'; interface NotesProps { initialNotes: string; } export default function Notes({ initialNotes }: NotesProps) { const saveTimeout = useSignal>(0); const hasSavedTimeout = useSignal>(0); const isSaving = useSignal(false); const hasSaved = useSignal(false); function saveNotes(newNotes: string) { if (saveTimeout.value) { clearTimeout(saveTimeout.value); } saveTimeout.value = setTimeout(async () => { hasSaved.value = false; isSaving.value = true; try { const requestBody: RequestBody = { notes: newNotes }; const response = await fetch(`/api/dashboard/save-notes`, { method: 'POST', body: JSON.stringify(requestBody), }); if (!response.ok) { throw new Error(`Failed to save notes. ${response.statusText} ${await response.text()}`); } const result = await response.json() as ResponseBody; if (!result.success) { throw new Error('Failed to save notes!'); } } catch (error) { console.error(error); } isSaving.value = false; hasSaved.value = true; }, 1000); } useSignalEffect(() => { if (hasSaved.value && !hasSavedTimeout.value) { hasSavedTimeout.value = setTimeout(() => { hasSaved.value = false; }, 3000); } }); useEffect(() => { return () => { if (saveTimeout.value) { clearTimeout(saveTimeout.value); } if (hasSavedTimeout.value) { clearTimeout(hasSavedTimeout.value); } }; }, []); return (
{isSaving.value ? ( <> Saving... ) : null} {hasSaved.value ? ( <> Saved! ) : null} {!isSaving.value && !hasSaved.value ? <>  : null}
); }