diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-02 11:58:13 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-02 11:58:13 +0900 |
| commit | d47d1a014a71ae65cbbf1b384eed87c6fe078b07 (patch) | |
| tree | 76c3af22e10f963104f84f3d680c5dddfc8b2be6 /src/client/components/CreateNoteTypeModal.tsx | |
| parent | 023d0fcfce575030ee503c5f60df8c28dba7ab07 (diff) | |
| download | kioku-d47d1a014a71ae65cbbf1b384eed87c6fe078b07.tar.gz kioku-d47d1a014a71ae65cbbf1b384eed87c6fe078b07.tar.zst kioku-d47d1a014a71ae65cbbf1b384eed87c6fe078b07.zip | |
CreateNoteTypeModal, DeleteNoteTypeModal, and the NoteTypeEditor (which
covers field add/edit/delete/reorder) now write through the local
IndexedDB repositories and fire-and-forget syncActionAtom, mirroring the
deck-CRUD pattern. The dead EditNoteTypeModal — never imported — is
removed.
The local hasNotes / hasNoteFieldValues guards mirror the server's
delete-time checks so a note type with attached notes, or a field with
saved values, can't be silently soft-deleted offline.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'src/client/components/CreateNoteTypeModal.tsx')
| -rw-r--r-- | src/client/components/CreateNoteTypeModal.tsx | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/src/client/components/CreateNoteTypeModal.tsx b/src/client/components/CreateNoteTypeModal.tsx index bbd43a1..382935f 100644 --- a/src/client/components/CreateNoteTypeModal.tsx +++ b/src/client/components/CreateNoteTypeModal.tsx @@ -1,7 +1,7 @@ -import { useAtomValue } from "jotai"; +import { useAtomValue, useSetAtom } from "jotai"; import { type FormEvent, useState } from "react"; -import { ApiClientError, apiClient } from "../api"; -import { isOnlineAtom } from "../atoms"; +import { syncActionAtom, userAtom } from "../atoms"; +import { localNoteTypeRepository } from "../db/repositories"; interface CreateNoteTypeModalProps { isOpen: boolean; @@ -20,7 +20,8 @@ export function CreateNoteTypeModal({ const [isReversible, setIsReversible] = useState(false); const [error, setError] = useState<string | null>(null); const [isSubmitting, setIsSubmitting] = useState(false); - const isOnline = useAtomValue(isOnlineAtom); + const user = useAtomValue(userAtom); + const triggerSync = useSetAtom(syncActionAtom); const resetForm = () => { setName(""); @@ -37,29 +38,28 @@ export function CreateNoteTypeModal({ const handleSubmit = async (e: FormEvent) => { e.preventDefault(); + if (!user) { + setError("You must be signed in to create a note type."); + return; + } setError(null); setIsSubmitting(true); try { - const res = await apiClient.rpc.api["note-types"].$post({ - json: { - name: name.trim(), - frontTemplate: frontTemplate.trim(), - backTemplate: backTemplate.trim(), - isReversible, - }, + await localNoteTypeRepository.create({ + userId: user.id, + name: name.trim(), + frontTemplate: frontTemplate.trim(), + backTemplate: backTemplate.trim(), + isReversible, }); - await apiClient.handleResponse(res); resetForm(); onNoteTypeCreated(); onClose(); - } catch (err) { - if (err instanceof ApiClientError) { - setError(err.message); - } else { - setError("Failed to create note type. Please try again."); - } + void triggerSync().catch(() => {}); + } catch { + setError("Failed to create note type. Please try again."); } finally { setIsSubmitting(false); } @@ -200,8 +200,7 @@ export function CreateNoteTypeModal({ </button> <button type="submit" - disabled={isSubmitting || !name.trim() || !isOnline} - title={!isOnline ? "Reconnect to create" : undefined} + disabled={isSubmitting || !name.trim()} className="px-4 py-2 bg-primary hover:bg-primary-dark text-white font-medium rounded-lg transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed" > {isSubmitting ? "Creating..." : "Create"} |
