aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/client/atoms/noteTypes.ts
blob: 1fde8f5a337440e72da7b8ca0ac5ee6047297fc4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { atomWithSuspenseQuery } from "jotai-tanstack-query";
import type { LocalNoteType } from "../db";
import { localNoteTypeRepository } from "../db/repositories";
import { ensureBootstrap } from "./sync";

export interface NoteType {
	id: string;
	name: string;
	frontTemplate: string;
	backTemplate: string;
	isReversible: boolean;
	createdAt: string;
	updatedAt: string;
}

async function loadCurrentUserId(): Promise<string | null> {
	const stored = localStorage.getItem("kioku_user");
	if (!stored) return null;
	try {
		const user = JSON.parse(stored) as { id?: string } | null;
		return user?.id ?? null;
	} catch {
		return null;
	}
}

function localNoteTypeToView(noteType: LocalNoteType): NoteType {
	return {
		id: noteType.id,
		name: noteType.name,
		frontTemplate: noteType.frontTemplate,
		backTemplate: noteType.backTemplate,
		isReversible: noteType.isReversible,
		createdAt: noteType.createdAt.toISOString(),
		updatedAt: noteType.updatedAt.toISOString(),
	};
}

async function loadNoteTypes(): Promise<NoteType[]> {
	const userId = await loadCurrentUserId();
	if (!userId) return [];
	const noteTypes = await localNoteTypeRepository.findByUserId(userId);
	noteTypes.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
	return noteTypes.map(localNoteTypeToView);
}

// =====================
// NoteTypes List - Suspense-compatible, IndexedDB-first
// =====================

export const noteTypesAtom = atomWithSuspenseQuery(() => ({
	queryKey: ["noteTypes"],
	queryFn: async (): Promise<NoteType[]> => {
		const noteTypes = await loadNoteTypes();
		if (noteTypes.length > 0) {
			ensureBootstrap();
			return noteTypes;
		}
		await ensureBootstrap();
		return loadNoteTypes();
	},
}));