learning_ai_notes/mobile/src/store/notes-store.ts
2026-03-10 12:08:31 -07:00

80 lines
2.2 KiB
TypeScript

import { create } from 'zustand';
import { getNote, listNotes, updateNote as persistNote, type MobileNote } from '../api/notes';
export type NotesState = {
notes: MobileNote[];
selectedNote: MobileNote | null;
isLoading: boolean;
hydrate: () => Promise<void>;
openNote: (id: string) => Promise<void>;
saveDraft: (title: string, body: string) => void;
updateNote: (id: string, title: string, body: string) => Promise<void>;
};
export const useNotesStore = create<NotesState>((set, get) => ({
notes: [],
selectedNote: null,
isLoading: false,
async hydrate() {
set({ isLoading: true });
const notes = await listNotes();
set({ notes, isLoading: false });
},
async openNote(id: string) {
set({ isLoading: true });
const current = get().notes.find((note: MobileNote) => note.id === id);
if (!current) {
set({ selectedNote: null, isLoading: false });
return;
}
const note = await getNote(id, current.workspaceId);
set({ selectedNote: note, isLoading: false });
},
saveDraft(title: string, body: string) {
const draft: MobileNote = {
id: `draft-${Date.now()}`,
workspaceId: 'drafts',
title: title.trim() || 'Untitled draft',
body,
workspaceName: 'Drafts',
status: 'draft',
updatedAt: new Date().toISOString(),
};
set({ notes: [draft, ...get().notes], selectedNote: draft });
},
async updateNote(id: string, title: string, body: string) {
const nextTitle = title.trim() || 'Untitled draft';
const current = get().notes.find((note: MobileNote) => note.id === id);
if (!current) {
return;
}
if (current.workspaceId === 'drafts') {
const updated: MobileNote = {
...current,
title: nextTitle,
body,
updatedAt: new Date().toISOString(),
};
set({
notes: get().notes.map((note: MobileNote) => (note.id === id ? updated : note)),
selectedNote: updated,
});
return;
}
set({ isLoading: true });
const updated = await persistNote(id, current.workspaceId, nextTitle, body);
set({
notes: get().notes.map((note: MobileNote) => (note.id === id ? updated : note)),
selectedNote: updated,
isLoading: false,
});
},
}));