Skip to content

Commit bf75c75

Browse files
committed
consolidate domain types in schemas, add baseSlice for loading/error, refactor uiSlice to use baseSlice
1 parent 3c3bf4c commit bf75c75

File tree

4 files changed

+59
-48
lines changed

4 files changed

+59
-48
lines changed

app/store/baseSlice.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import type { StateCreator } from 'zustand';
2+
import type { Draft } from 'immer';
3+
4+
export interface BaseSlice {
5+
loading: boolean;
6+
error: string | null;
7+
setLoading: (loading: boolean) => void;
8+
setError: (error: string | null) => void;
9+
}
10+
11+
export const createBaseSlice = <T extends { loading: boolean; error: string | null }>(
12+
set: Parameters<StateCreator<T, [['zustand/immer', never]], [], T>>[0]
13+
): BaseSlice => ({
14+
loading: false,
15+
error: null,
16+
setLoading: (loading) => {
17+
set((state: Draft<T>) => {
18+
state.loading = loading;
19+
});
20+
},
21+
setError: (error) => {
22+
set((state: Draft<T>) => {
23+
state.error = error;
24+
});
25+
},
26+
});

app/store/uiSlice.ts

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import type { StateCreator } from 'zustand';
22
import type { TextGeneratorState } from './textGeneratorStore';
3+
import type { BaseSlice } from './baseSlice';
4+
import { createBaseSlice } from './baseSlice';
35

4-
export interface UISlice {
5-
loading: boolean;
6-
error: string | null;
6+
export interface UISlice extends BaseSlice {
77
showLoginPrompt: boolean;
88
showContent: boolean;
99
showQuestionSection: boolean;
1010
showExplanation: boolean;
11-
setError: (error: string | null) => void;
12-
setLoading: (loading: boolean) => void;
1311
setShowLoginPrompt: (show: boolean) => void;
1412
setShowContent: (show: boolean) => void;
1513
setShowQuestionSection: (show: boolean) => void;
@@ -22,23 +20,12 @@ export const createUISlice: StateCreator<
2220
[],
2321
UISlice
2422
> = (set, _get) => ({
25-
loading: false,
26-
error: null,
23+
...createBaseSlice(set),
2724
showLoginPrompt: true,
2825
showContent: false,
2926
showQuestionSection: false,
3027
showExplanation: false,
3128

32-
setError: (error) => {
33-
set((state) => {
34-
state.error = error;
35-
});
36-
},
37-
setLoading: (loading) => {
38-
set((state) => {
39-
state.loading = loading;
40-
});
41-
},
4229
setShowLoginPrompt: (show) => {
4330
set((state) => {
4431
state.showLoginPrompt = show;

lib/domain/exercise.types.ts

Lines changed: 0 additions & 31 deletions
This file was deleted.

lib/domain/schemas.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,32 @@ export const CEFRTopicsSchema = z.record(z.string(), z.array(TopicCategorySchema
117117

118118
export type TopicCategory = z.infer<typeof TopicCategorySchema>;
119119
export type CEFRTopics = z.infer<typeof CEFRTopicsSchema>;
120+
121+
// Exercise-related schemas (moved from exercise.types.ts)
122+
123+
export const ExerciseOptionsSchema = z.object({
124+
A: z.string(),
125+
B: z.string(),
126+
C: z.string(),
127+
D: z.string(),
128+
});
129+
export type ExerciseOptions = z.infer<typeof ExerciseOptionsSchema>;
130+
131+
export const ExerciseExplanationSchema = z.object({
132+
A: z.string(),
133+
B: z.string(),
134+
C: z.string(),
135+
D: z.string(),
136+
});
137+
export type ExerciseExplanation = z.infer<typeof ExerciseExplanationSchema>;
138+
139+
export const GeneratedExerciseSchema = z.object({
140+
paragraph: z.string(),
141+
topic: z.string(),
142+
question: z.string(),
143+
options: ExerciseOptionsSchema,
144+
correctAnswer: z.enum(['A', 'B', 'C', 'D']),
145+
allExplanations: ExerciseExplanationSchema,
146+
relevantText: z.string(),
147+
});
148+
export type GeneratedExercise = z.infer<typeof GeneratedExerciseSchema>;

0 commit comments

Comments
 (0)