diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-01-01 23:44:50 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-01-01 23:47:21 +0900 |
| commit | 2fb6471a685bec1433be3335f377a1a2313e4820 (patch) | |
| tree | 328ddaeec0c591b06bf005d48b0242345c1336be /src/client/components/ImportNotesModal.tsx | |
| parent | f30566e1c7126db4c6242ab38d07a9478f79d3db (diff) | |
| download | kioku-2fb6471a685bec1433be3335f377a1a2313e4820.tar.gz kioku-2fb6471a685bec1433be3335f377a1a2313e4820.tar.zst kioku-2fb6471a685bec1433be3335f377a1a2313e4820.zip | |
refactor(client): migrate API calls to typed RPC client
Replace raw fetch() calls with apiClient.rpc typed client across all
modal and page components. This provides better type safety and
eliminates manual auth header handling.
- Make handleResponse public for component usage
- Update all component tests to mock RPC methods instead of fetch
- Change POSTGRES_HOST default to kioku-db for Docker compatibility
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'src/client/components/ImportNotesModal.tsx')
| -rw-r--r-- | src/client/components/ImportNotesModal.tsx | 60 |
1 files changed, 14 insertions, 46 deletions
diff --git a/src/client/components/ImportNotesModal.tsx b/src/client/components/ImportNotesModal.tsx index b49b276..a7a88c5 100644 --- a/src/client/components/ImportNotesModal.tsx +++ b/src/client/components/ImportNotesModal.tsx @@ -73,34 +73,21 @@ export function ImportNotesModal({ const fetchNoteTypes = useCallback(async () => { try { - const authHeader = apiClient.getAuthHeader(); - if (!authHeader) { - throw new ApiClientError("Not authenticated", 401); - } - - const res = await fetch("/api/note-types", { - headers: authHeader, - }); - - if (!res.ok) { - const errorBody = await res.json().catch(() => ({})); - throw new ApiClientError( - (errorBody as { error?: string }).error || - `Request failed with status ${res.status}`, - res.status, - ); - } - - const data = await res.json(); + const res = await apiClient.rpc.api["note-types"].$get(); + const data = await apiClient.handleResponse<{ + noteTypes: { id: string; name: string }[]; + }>(res); // Fetch details for each note type to get fields const noteTypesWithFields: NoteType[] = []; for (const nt of data.noteTypes) { - const detailRes = await fetch(`/api/note-types/${nt.id}`, { - headers: authHeader, + const detailRes = await apiClient.rpc.api["note-types"][":id"].$get({ + param: { id: nt.id }, }); if (detailRes.ok) { - const detailData = await detailRes.json(); + const detailData = await apiClient.handleResponse<{ + noteType: NoteType; + }>(detailRes); noteTypesWithFields.push(detailData.noteType); } } @@ -247,35 +234,16 @@ export function ImportNotesModal({ setError(null); try { - const authHeader = apiClient.getAuthHeader(); - if (!authHeader) { - throw new ApiClientError("Not authenticated", 401); - } - - const res = await fetch(`/api/decks/${deckId}/notes/import`, { - method: "POST", - headers: { - "Content-Type": "application/json", - ...authHeader, - }, - body: JSON.stringify({ + const res = await apiClient.rpc.api.decks[":deckId"].notes.import.$post({ + param: { deckId }, + json: { notes: validatedRows.map((row) => ({ noteTypeId: row.noteTypeId, fields: row.fields, })), - }), + }, }); - - if (!res.ok) { - const errorBody = await res.json().catch(() => ({})); - throw new ApiClientError( - (errorBody as { error?: string }).error || - `Request failed with status ${res.status}`, - res.status, - ); - } - - const result = await res.json(); + const result = await apiClient.handleResponse<ImportResult>(res); setImportResult(result); setPhase("complete"); onImportComplete(); |
