From 38b8fc0e9927c4146b4c8b309b2bcc644abd63d0 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Wed, 25 Feb 2026 23:02:35 +0900 Subject: feat(decks): add default note type setting per deck Allow each deck to specify a default note type that is auto-selected when creating new notes. Includes DB schema migration, server API updates, sync layer support, and UI for editing the default in the deck settings modal. Co-Authored-By: Claude Opus 4.6 --- src/client/components/EditDeckModal.tsx | 60 ++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) (limited to 'src/client/components/EditDeckModal.tsx') diff --git a/src/client/components/EditDeckModal.tsx b/src/client/components/EditDeckModal.tsx index 8e95295..9a79de8 100644 --- a/src/client/components/EditDeckModal.tsx +++ b/src/client/components/EditDeckModal.tsx @@ -1,10 +1,16 @@ -import { type FormEvent, useEffect, useState } from "react"; +import { type FormEvent, useCallback, useEffect, useState } from "react"; import { ApiClientError, apiClient } from "../api"; interface Deck { id: string; name: string; description: string | null; + defaultNoteTypeId: string | null; +} + +interface NoteTypeSummary { + id: string; + name: string; } interface EditDeckModalProps { @@ -22,18 +28,45 @@ export function EditDeckModal({ }: EditDeckModalProps) { const [name, setName] = useState(""); const [description, setDescription] = useState(""); + const [defaultNoteTypeId, setDefaultNoteTypeId] = useState( + null, + ); + const [noteTypes, setNoteTypes] = useState([]); + const [isLoadingNoteTypes, setIsLoadingNoteTypes] = useState(false); const [error, setError] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); + const fetchNoteTypes = useCallback(async () => { + setIsLoadingNoteTypes(true); + try { + const res = await apiClient.rpc.api["note-types"].$get(); + const data = await apiClient.handleResponse<{ + noteTypes: NoteTypeSummary[]; + }>(res); + setNoteTypes(data.noteTypes); + } catch { + // Non-critical: note type list is optional + } finally { + setIsLoadingNoteTypes(false); + } + }, []); + // Sync form state when deck changes useEffect(() => { if (deck) { setName(deck.name); setDescription(deck.description ?? ""); + setDefaultNoteTypeId(deck.defaultNoteTypeId); setError(null); } }, [deck]); + useEffect(() => { + if (isOpen) { + fetchNoteTypes(); + } + }, [isOpen, fetchNoteTypes]); + const handleClose = () => { setError(null); onClose(); @@ -52,6 +85,7 @@ export function EditDeckModal({ json: { name: name.trim(), description: description.trim() || null, + defaultNoteTypeId: defaultNoteTypeId || null, }, }); await apiClient.handleResponse(res); @@ -147,6 +181,30 @@ export function EditDeckModal({ /> +
+ + +
+