feat(frontend): zustand stores for settings, lessons, session
This commit is contained in:
66
packages/frontend/src/stores/sessionStore.ts
Normal file
66
packages/frontend/src/stores/sessionStore.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { create } from 'zustand';
|
||||
import type { SessionRow, QueueItem } from '@flashcard/shared';
|
||||
import { sessionsApi } from '../api/sessions.js';
|
||||
|
||||
interface SessionState {
|
||||
session: SessionRow | null;
|
||||
current: QueueItem | null;
|
||||
done: boolean;
|
||||
showAnswer: boolean;
|
||||
shownAt: number | null;
|
||||
start: (input: { lessonId: number; maxCards: number | null; shuffle: boolean; direction: 'forward' | 'backward' | 'both' }) => Promise<void>;
|
||||
reveal: () => void;
|
||||
answer: (result: 'correct' | 'incorrect') => Promise<void>;
|
||||
end: () => Promise<void>;
|
||||
abandon: () => Promise<void>;
|
||||
reset: () => void;
|
||||
}
|
||||
|
||||
export const useSession = create<SessionState>((set, get) => ({
|
||||
session: null, current: null, done: false, showAnswer: false, shownAt: null,
|
||||
|
||||
start: async (input) => {
|
||||
const { session } = await sessionsApi.start(input);
|
||||
const nx = await sessionsApi.next(session.id);
|
||||
set({
|
||||
session,
|
||||
done: nx.done,
|
||||
current: nx.done ? null : nx.item,
|
||||
showAnswer: false,
|
||||
shownAt: Date.now(),
|
||||
});
|
||||
},
|
||||
|
||||
reveal: () => set({ showAnswer: true }),
|
||||
|
||||
answer: async (result) => {
|
||||
const s = get();
|
||||
if (!s.session || !s.current) return;
|
||||
const ttm = s.shownAt ? Date.now() - s.shownAt : null;
|
||||
await sessionsApi.attempt(s.session.id, {
|
||||
cardId: s.current.cardId, direction: s.current.direction, result, timeToAnswerMs: ttm,
|
||||
});
|
||||
const nx = await sessionsApi.next(s.session.id);
|
||||
if (nx.done) {
|
||||
set({ done: true, current: null, showAnswer: false });
|
||||
} else {
|
||||
set({ current: nx.item, showAnswer: false, shownAt: Date.now() });
|
||||
}
|
||||
},
|
||||
|
||||
end: async () => {
|
||||
const s = get();
|
||||
if (!s.session) return;
|
||||
const finished = await sessionsApi.end(s.session.id);
|
||||
set({ session: finished });
|
||||
},
|
||||
|
||||
abandon: async () => {
|
||||
const s = get();
|
||||
if (!s.session) return;
|
||||
await sessionsApi.abandon(s.session.id);
|
||||
set({ session: null, current: null, done: false, showAnswer: false });
|
||||
},
|
||||
|
||||
reset: () => set({ session: null, current: null, done: false, showAnswer: false, shownAt: null }),
|
||||
}));
|
||||
Reference in New Issue
Block a user