80 lines
2.2 KiB
TypeScript
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,
|
|
});
|
|
},
|
|
}));
|