analytica-frontend-lib 1.2.81 → 1.2.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ActivitiesHistory/index.js +34 -43
- package/dist/ActivitiesHistory/index.js.map +1 -1
- package/dist/ActivitiesHistory/index.mjs +34 -43
- package/dist/ActivitiesHistory/index.mjs.map +1 -1
- package/dist/ActivityDetails/index.js +30 -38
- package/dist/ActivityDetails/index.js.map +1 -1
- package/dist/ActivityDetails/index.mjs +30 -38
- package/dist/ActivityDetails/index.mjs.map +1 -1
- package/dist/ActivityFilters/index.js +30 -38
- package/dist/ActivityFilters/index.js.map +1 -1
- package/dist/ActivityFilters/index.mjs +30 -38
- package/dist/ActivityFilters/index.mjs.map +1 -1
- package/dist/AlertManager/index.js +30 -38
- package/dist/AlertManager/index.js.map +1 -1
- package/dist/AlertManager/index.mjs +30 -38
- package/dist/AlertManager/index.mjs.map +1 -1
- package/dist/RecommendedLessonsHistory/index.js +34 -43
- package/dist/RecommendedLessonsHistory/index.js.map +1 -1
- package/dist/RecommendedLessonsHistory/index.mjs +34 -43
- package/dist/RecommendedLessonsHistory/index.mjs.map +1 -1
- package/dist/SendActivityModal/SendActivityModal.js +30 -38
- package/dist/SendActivityModal/SendActivityModal.js.map +1 -1
- package/dist/SendActivityModal/SendActivityModal.mjs +30 -38
- package/dist/SendActivityModal/SendActivityModal.mjs.map +1 -1
- package/dist/SendActivityModal/index.js +30 -38
- package/dist/SendActivityModal/index.js.map +1 -1
- package/dist/SendActivityModal/index.mjs +30 -38
- package/dist/SendActivityModal/index.mjs.map +1 -1
- package/dist/TableProvider/index.js +30 -38
- package/dist/TableProvider/index.js.map +1 -1
- package/dist/TableProvider/index.mjs +30 -38
- package/dist/TableProvider/index.mjs.map +1 -1
- package/dist/hooks/useRecommendedLessonsPage/index.d.ts +218 -0
- package/dist/hooks/useRecommendedLessonsPage/index.d.ts.map +1 -0
- package/dist/hooks/useRecommendedLessonsPage/index.js +247 -0
- package/dist/hooks/useRecommendedLessonsPage/index.js.map +1 -0
- package/dist/hooks/useRecommendedLessonsPage/index.mjs +221 -0
- package/dist/hooks/useRecommendedLessonsPage/index.mjs.map +1 -0
- package/dist/hooks/useRecommendedLessonsPage.d.ts +218 -0
- package/dist/hooks/useRecommendedLessonsPage.d.ts.map +1 -0
- package/dist/hooks/useSendActivity/index.js +1 -1
- package/dist/hooks/useSendActivity/index.js.map +1 -1
- package/dist/hooks/useSendActivity/index.mjs +1 -1
- package/dist/hooks/useSendActivity/index.mjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +344 -133
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +333 -124
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
// src/hooks/useRecommendedLessonsPage.ts
|
|
2
|
+
import { useCallback, useRef, useMemo, useState } from "react";
|
|
3
|
+
var buildQueryParams = (filters) => {
|
|
4
|
+
if (!filters) return {};
|
|
5
|
+
const params = {};
|
|
6
|
+
for (const key in filters) {
|
|
7
|
+
const value = filters[key];
|
|
8
|
+
if (value !== void 0 && value !== null) {
|
|
9
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
10
|
+
params[key] = value;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return params;
|
|
15
|
+
};
|
|
16
|
+
var getSchoolOptions = (userData) => {
|
|
17
|
+
if (!userData?.userInstitutions) return [];
|
|
18
|
+
const schoolMap = /* @__PURE__ */ new Map();
|
|
19
|
+
userData.userInstitutions.forEach((inst) => {
|
|
20
|
+
if (inst.school?.id && inst.school?.name) {
|
|
21
|
+
schoolMap.set(inst.school.id, inst.school.name);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
return Array.from(schoolMap.entries()).map(([id, name]) => ({ id, name }));
|
|
25
|
+
};
|
|
26
|
+
var getClassOptions = (userData) => {
|
|
27
|
+
if (!userData?.userInstitutions) return [];
|
|
28
|
+
const classMap = /* @__PURE__ */ new Map();
|
|
29
|
+
userData.userInstitutions.forEach((inst) => {
|
|
30
|
+
if (inst.class?.id && inst.class?.name) {
|
|
31
|
+
classMap.set(inst.class.id, inst.class.name);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return Array.from(classMap.entries()).map(([id, name]) => ({ id, name }));
|
|
35
|
+
};
|
|
36
|
+
var getSubjectOptions = (userData) => {
|
|
37
|
+
if (!userData?.subTeacherTopicClasses) return [];
|
|
38
|
+
const subjectMap = /* @__PURE__ */ new Map();
|
|
39
|
+
userData.subTeacherTopicClasses.forEach((stc) => {
|
|
40
|
+
if (stc.subject?.id && stc.subject?.name) {
|
|
41
|
+
subjectMap.set(stc.subject.id, stc.subject.name);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
return Array.from(subjectMap.entries()).map(([id, name]) => ({ id, name }));
|
|
45
|
+
};
|
|
46
|
+
var createUseRecommendedLessonsPage = (config) => {
|
|
47
|
+
const {
|
|
48
|
+
api,
|
|
49
|
+
navigate,
|
|
50
|
+
userData,
|
|
51
|
+
paths,
|
|
52
|
+
endpoints,
|
|
53
|
+
texts,
|
|
54
|
+
emptyStateImage,
|
|
55
|
+
noSearchImage,
|
|
56
|
+
mapSubjectNameToEnum
|
|
57
|
+
} = config;
|
|
58
|
+
return () => {
|
|
59
|
+
const goalsMapRef = useRef(/* @__PURE__ */ new Map());
|
|
60
|
+
const [sendModalOpen, setSendModalOpen] = useState(false);
|
|
61
|
+
const [selectedModel, setSelectedModel] = useState(null);
|
|
62
|
+
const [sendModalLoading, setSendModalLoading] = useState(false);
|
|
63
|
+
const [sendModalCategories, setSendModalCategories] = useState([]);
|
|
64
|
+
const userFilterData = useMemo(
|
|
65
|
+
() => ({
|
|
66
|
+
schools: getSchoolOptions(userData),
|
|
67
|
+
classes: getClassOptions(userData),
|
|
68
|
+
subjects: getSubjectOptions(userData)
|
|
69
|
+
}),
|
|
70
|
+
[userData]
|
|
71
|
+
);
|
|
72
|
+
const subjectsMap = useMemo(() => {
|
|
73
|
+
const map = /* @__PURE__ */ new Map();
|
|
74
|
+
const subjects = getSubjectOptions(userData);
|
|
75
|
+
subjects.forEach((s) => map.set(s.id, s.name));
|
|
76
|
+
return map;
|
|
77
|
+
}, [userData]);
|
|
78
|
+
const fetchGoalsHistory = useCallback(
|
|
79
|
+
async (filters) => {
|
|
80
|
+
const params = buildQueryParams(filters);
|
|
81
|
+
const response = await api.get(
|
|
82
|
+
endpoints.goalsHistory,
|
|
83
|
+
{ params }
|
|
84
|
+
);
|
|
85
|
+
const goals = response.data.data.goals;
|
|
86
|
+
goals.forEach((goal) => {
|
|
87
|
+
goalsMapRef.current.set(goal.goal.id, goal);
|
|
88
|
+
});
|
|
89
|
+
return response.data;
|
|
90
|
+
},
|
|
91
|
+
[api, endpoints.goalsHistory]
|
|
92
|
+
);
|
|
93
|
+
const fetchGoalModels = useCallback(
|
|
94
|
+
async (filters) => {
|
|
95
|
+
const params = buildQueryParams({
|
|
96
|
+
...filters,
|
|
97
|
+
type: "MODELO" /* MODELO */
|
|
98
|
+
});
|
|
99
|
+
const response = await api.get(
|
|
100
|
+
endpoints.goalDrafts,
|
|
101
|
+
{ params }
|
|
102
|
+
);
|
|
103
|
+
return response.data;
|
|
104
|
+
},
|
|
105
|
+
[api, endpoints.goalDrafts]
|
|
106
|
+
);
|
|
107
|
+
const deleteGoalModel = useCallback(
|
|
108
|
+
async (id) => {
|
|
109
|
+
await api.delete(`${endpoints.goalDrafts}/${id}`);
|
|
110
|
+
},
|
|
111
|
+
[api, endpoints.goalDrafts]
|
|
112
|
+
);
|
|
113
|
+
const handleCreateLesson = useCallback(() => {
|
|
114
|
+
navigate(paths.createLesson);
|
|
115
|
+
}, []);
|
|
116
|
+
const handleCreateModel = useCallback(() => {
|
|
117
|
+
navigate(paths.createModel);
|
|
118
|
+
}, []);
|
|
119
|
+
const handleRowClick = useCallback((row) => {
|
|
120
|
+
const originalData = goalsMapRef.current.get(row.id);
|
|
121
|
+
navigate(`${paths.lessonDetails}/${row.id}`, {
|
|
122
|
+
state: { goalData: originalData }
|
|
123
|
+
});
|
|
124
|
+
}, []);
|
|
125
|
+
const handleEditGoal = useCallback((id) => {
|
|
126
|
+
navigate(`${paths.editLesson}/${id}/editar`);
|
|
127
|
+
}, []);
|
|
128
|
+
const handleEditModel = useCallback((model) => {
|
|
129
|
+
navigate(`${paths.editModel}${model.id}`);
|
|
130
|
+
}, []);
|
|
131
|
+
const handleSendLesson = useCallback(
|
|
132
|
+
(model) => {
|
|
133
|
+
setSelectedModel(model);
|
|
134
|
+
const classes = getClassOptions(userData);
|
|
135
|
+
const categories = [];
|
|
136
|
+
if (classes.length > 0) {
|
|
137
|
+
categories.push({
|
|
138
|
+
key: "students",
|
|
139
|
+
label: "Turmas",
|
|
140
|
+
selectedIds: [],
|
|
141
|
+
itens: classes.map((cls) => ({
|
|
142
|
+
id: cls.id,
|
|
143
|
+
name: cls.name,
|
|
144
|
+
studentId: cls.id,
|
|
145
|
+
userInstitutionId: cls.id
|
|
146
|
+
}))
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
setSendModalCategories(categories);
|
|
150
|
+
setSendModalOpen(true);
|
|
151
|
+
},
|
|
152
|
+
[userData]
|
|
153
|
+
);
|
|
154
|
+
const handleSendLessonSubmit = useCallback(
|
|
155
|
+
async (formData) => {
|
|
156
|
+
if (!selectedModel) return;
|
|
157
|
+
setSendModalLoading(true);
|
|
158
|
+
try {
|
|
159
|
+
await api.post(endpoints.submitGoal, {
|
|
160
|
+
draftId: selectedModel.id,
|
|
161
|
+
students: formData.students,
|
|
162
|
+
startDate: `${formData.startDate}T${formData.startTime}:00`,
|
|
163
|
+
finalDate: `${formData.finalDate}T${formData.finalTime}:00`
|
|
164
|
+
});
|
|
165
|
+
setSendModalOpen(false);
|
|
166
|
+
setSelectedModel(null);
|
|
167
|
+
} finally {
|
|
168
|
+
setSendModalLoading(false);
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
[api, endpoints.submitGoal, selectedModel]
|
|
172
|
+
);
|
|
173
|
+
const handleSendModalClose = useCallback(() => {
|
|
174
|
+
setSendModalOpen(false);
|
|
175
|
+
setSelectedModel(null);
|
|
176
|
+
}, []);
|
|
177
|
+
const handleCategoriesChange = useCallback(
|
|
178
|
+
(categories) => {
|
|
179
|
+
setSendModalCategories(categories);
|
|
180
|
+
},
|
|
181
|
+
[]
|
|
182
|
+
);
|
|
183
|
+
return {
|
|
184
|
+
historyProps: {
|
|
185
|
+
fetchGoalsHistory,
|
|
186
|
+
fetchGoalModels,
|
|
187
|
+
deleteGoalModel,
|
|
188
|
+
onCreateLesson: handleCreateLesson,
|
|
189
|
+
onCreateModel: handleCreateModel,
|
|
190
|
+
onRowClick: handleRowClick,
|
|
191
|
+
onEditGoal: handleEditGoal,
|
|
192
|
+
onEditModel: handleEditModel,
|
|
193
|
+
onSendLesson: handleSendLesson,
|
|
194
|
+
emptyStateImage,
|
|
195
|
+
noSearchImage,
|
|
196
|
+
mapSubjectNameToEnum,
|
|
197
|
+
userFilterData,
|
|
198
|
+
subjectsMap,
|
|
199
|
+
title: texts.title,
|
|
200
|
+
createButtonText: texts.createButtonText,
|
|
201
|
+
searchPlaceholder: texts.searchPlaceholder
|
|
202
|
+
},
|
|
203
|
+
modalProps: {
|
|
204
|
+
isOpen: sendModalOpen,
|
|
205
|
+
onClose: handleSendModalClose,
|
|
206
|
+
onSubmit: handleSendLessonSubmit,
|
|
207
|
+
categories: sendModalCategories,
|
|
208
|
+
onCategoriesChange: handleCategoriesChange,
|
|
209
|
+
isLoading: sendModalLoading,
|
|
210
|
+
modalTitle: selectedModel?.title
|
|
211
|
+
},
|
|
212
|
+
navigate
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
var createRecommendedLessonsPageHook = createUseRecommendedLessonsPage;
|
|
217
|
+
export {
|
|
218
|
+
createRecommendedLessonsPageHook,
|
|
219
|
+
createUseRecommendedLessonsPage
|
|
220
|
+
};
|
|
221
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/hooks/useRecommendedLessonsPage.ts"],"sourcesContent":["/**\n * useRecommendedLessonsPage Hook Factory\n *\n * Factory function to create a hook for RecommendedLessons, LessonDrafts, and LessonModels pages.\n * Contains all common state, memos, and callbacks.\n */\n\nimport { useCallback, useRef, useMemo, useState } from 'react';\nimport {\n GoalDraftType,\n type GoalHistoryFilters,\n type GoalsHistoryApiResponse,\n type GoalTableItem,\n type GoalHistoryItem,\n type GoalModelFilters,\n type GoalModelsApiResponse,\n type GoalModelTableItem,\n} from '../types/recommendedLessons';\nimport type {\n SendLessonFormData,\n CategoryConfig,\n} from '../components/SendLessonModal/types';\nimport { SubjectEnum } from '../enums/SubjectEnum';\n\n/**\n * API client interface\n */\nexport interface RecommendedLessonsApiClient {\n get: <T>(\n url: string,\n config?: { params?: Record<string, unknown> }\n ) => Promise<{ data: T }>;\n post: <T>(url: string, data?: unknown) => Promise<{ data: T }>;\n delete: <T>(url: string) => Promise<{ data: T }>;\n}\n\n/**\n * User institution data structure\n */\nexport interface UserInstitution {\n school: { id: string; name: string };\n schoolYear: { id: string; name: string };\n class: { id: string; name: string };\n}\n\n/**\n * Subject teacher class data structure\n */\nexport interface SubTeacherTopicClass {\n subject: { id: string; name: string };\n class: { id: string; name: string };\n}\n\n/**\n * User data structure\n */\nexport interface RecommendedLessonsUserData {\n userInstitutions?: UserInstitution[];\n subTeacherTopicClasses?: SubTeacherTopicClass[];\n}\n\n/**\n * Navigation paths configuration\n */\nexport interface RecommendedLessonsPagePaths {\n /** Path for creating a new lesson */\n createLesson: string;\n /** Path for creating a new model */\n createModel: string;\n /** Base path for lesson details */\n lessonDetails: string;\n /** Base path for editing a lesson */\n editLesson: string;\n /** Path for editing a model (with id parameter) */\n editModel: string;\n}\n\n/**\n * API endpoints configuration\n */\nexport interface RecommendedLessonsPageEndpoints {\n /** Endpoint for fetching goals history */\n goalsHistory: string;\n /** Endpoint for fetching goal models/drafts */\n goalDrafts: string;\n /** Endpoint for submitting a goal */\n submitGoal: string;\n}\n\n/**\n * UI text configuration\n */\nexport interface RecommendedLessonsPageTexts {\n title: string;\n createButtonText: string;\n searchPlaceholder: string;\n}\n\n/**\n * Configuration for createUseRecommendedLessonsPage factory\n */\nexport interface UseRecommendedLessonsPageConfig {\n /** API client for making requests */\n api: RecommendedLessonsApiClient;\n /** Navigation function */\n navigate: (path: string, options?: { state?: unknown }) => void;\n /** User data for filter options */\n userData: RecommendedLessonsUserData | null;\n /** Navigation paths */\n paths: RecommendedLessonsPagePaths;\n /** API endpoints */\n endpoints: RecommendedLessonsPageEndpoints;\n /** UI text */\n texts: RecommendedLessonsPageTexts;\n /** Image for empty state */\n emptyStateImage: string;\n /** Image for no search results */\n noSearchImage: string;\n /** Function to map subject name to SubjectEnum */\n mapSubjectNameToEnum: (subjectName: string) => SubjectEnum | null;\n}\n\n/**\n * Return type for the useRecommendedLessonsPage hook\n */\nexport interface UseRecommendedLessonsPageReturn {\n /** Props for RecommendedLessonsHistory component */\n historyProps: {\n fetchGoalsHistory: (\n filters?: GoalHistoryFilters\n ) => Promise<GoalsHistoryApiResponse>;\n fetchGoalModels: (\n filters?: GoalModelFilters\n ) => Promise<GoalModelsApiResponse>;\n deleteGoalModel: (id: string) => Promise<void>;\n onCreateLesson: () => void;\n onCreateModel: () => void;\n onRowClick: (row: GoalTableItem) => void;\n onEditGoal: (id: string) => void;\n onEditModel: (model: GoalModelTableItem) => void;\n onSendLesson: (model: GoalModelTableItem) => void;\n emptyStateImage: string;\n noSearchImage: string;\n mapSubjectNameToEnum: (subjectName: string) => SubjectEnum | null;\n userFilterData: {\n schools: Array<{ id: string; name: string }>;\n classes: Array<{ id: string; name: string }>;\n subjects: Array<{ id: string; name: string }>;\n };\n subjectsMap: Map<string, string>;\n title: string;\n createButtonText: string;\n searchPlaceholder: string;\n };\n /** Props for SendLessonModal component */\n modalProps: {\n isOpen: boolean;\n onClose: () => void;\n onSubmit: (formData: SendLessonFormData) => Promise<void>;\n categories: CategoryConfig[];\n onCategoriesChange: (categories: CategoryConfig[]) => void;\n isLoading: boolean;\n modalTitle: string | undefined;\n };\n /** Navigate function for custom tab handlers */\n navigate: (path: string, options?: { state?: unknown }) => void;\n}\n\n/**\n * Build query parameters from filter object\n */\nconst buildQueryParams = (\n filters?: Record<string, unknown>\n): Record<string, unknown> => {\n if (!filters) return {};\n\n const params: Record<string, unknown> = {};\n for (const key in filters) {\n const value = filters[key];\n if (value !== undefined && value !== null) {\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n params[key] = value;\n }\n }\n }\n return params;\n};\n\n/**\n * Get school options from user data\n */\nconst getSchoolOptions = (\n userData: RecommendedLessonsUserData | null\n): Array<{ id: string; name: string }> => {\n if (!userData?.userInstitutions) return [];\n\n const schoolMap = new Map<string, string>();\n userData.userInstitutions.forEach((inst) => {\n if (inst.school?.id && inst.school?.name) {\n schoolMap.set(inst.school.id, inst.school.name);\n }\n });\n\n return Array.from(schoolMap.entries()).map(([id, name]) => ({ id, name }));\n};\n\n/**\n * Get class options from user data\n */\nconst getClassOptions = (\n userData: RecommendedLessonsUserData | null\n): Array<{ id: string; name: string }> => {\n if (!userData?.userInstitutions) return [];\n\n const classMap = new Map<string, string>();\n userData.userInstitutions.forEach((inst) => {\n if (inst.class?.id && inst.class?.name) {\n classMap.set(inst.class.id, inst.class.name);\n }\n });\n\n return Array.from(classMap.entries()).map(([id, name]) => ({ id, name }));\n};\n\n/**\n * Get subject options from user data\n */\nconst getSubjectOptions = (\n userData: RecommendedLessonsUserData | null\n): Array<{ id: string; name: string }> => {\n if (!userData?.subTeacherTopicClasses) return [];\n\n const subjectMap = new Map<string, string>();\n userData.subTeacherTopicClasses.forEach((stc) => {\n if (stc.subject?.id && stc.subject?.name) {\n subjectMap.set(stc.subject.id, stc.subject.name);\n }\n });\n\n return Array.from(subjectMap.entries()).map(([id, name]) => ({ id, name }));\n};\n\n/**\n * Factory function to create useRecommendedLessonsPage hook\n *\n * @param config - Configuration object with API client, navigation, user data, paths, etc.\n * @returns Hook function that returns historyProps, modalProps, and navigate\n *\n * @example\n * ```tsx\n * // In your app setup\n * const useRecommendedLessonsPage = createUseRecommendedLessonsPage({\n * api,\n * navigate,\n * userData,\n * paths: {\n * createLesson: '/criar-aula',\n * createModel: '/criar-aula?mode=model',\n * lessonDetails: '/aulas-recomendadas',\n * editLesson: '/aulas-recomendadas',\n * editModel: '/criar-aula?mode=model&id=',\n * },\n * endpoints: {\n * goalsHistory: '/recommended-class/history',\n * goalDrafts: '/recommended-class/drafts',\n * submitGoal: '/goals',\n * },\n * texts: {\n * title: 'Histórico de aulas recomendadas',\n * createButtonText: 'Criar aula',\n * searchPlaceholder: 'Buscar aula',\n * },\n * emptyStateImage,\n * noSearchImage,\n * mapSubjectNameToEnum,\n * });\n *\n * // In your component\n * const { historyProps, modalProps, navigate } = useRecommendedLessonsPage();\n * ```\n */\nexport const createUseRecommendedLessonsPage = (\n config: UseRecommendedLessonsPageConfig\n): (() => UseRecommendedLessonsPageReturn) => {\n const {\n api,\n navigate,\n userData,\n paths,\n endpoints,\n texts,\n emptyStateImage,\n noSearchImage,\n mapSubjectNameToEnum,\n } = config;\n\n return (): UseRecommendedLessonsPageReturn => {\n // Store original goal data for navigation\n const goalsMapRef = useRef<Map<string, GoalHistoryItem>>(new Map());\n\n // SendLessonModal state\n const [sendModalOpen, setSendModalOpen] = useState(false);\n const [selectedModel, setSelectedModel] =\n useState<GoalModelTableItem | null>(null);\n const [sendModalLoading, setSendModalLoading] = useState(false);\n const [sendModalCategories, setSendModalCategories] = useState<\n CategoryConfig[]\n >([]);\n\n // Build user filter data from user data\n const userFilterData = useMemo(\n () => ({\n schools: getSchoolOptions(userData),\n classes: getClassOptions(userData),\n subjects: getSubjectOptions(userData),\n }),\n [userData]\n );\n\n // Memoized subjects map for models display\n const subjectsMap = useMemo(() => {\n const map = new Map<string, string>();\n const subjects = getSubjectOptions(userData);\n subjects.forEach((s) => map.set(s.id, s.name));\n return map;\n }, [userData]);\n\n /**\n * Fetch goals history from API\n */\n const fetchGoalsHistory = useCallback(\n async (\n filters?: GoalHistoryFilters\n ): Promise<GoalsHistoryApiResponse> => {\n const params = buildQueryParams(filters as Record<string, unknown>);\n const response = await api.get<GoalsHistoryApiResponse>(\n endpoints.goalsHistory,\n { params }\n );\n\n // Store original goal data for later use in navigation\n const goals = response.data.data.goals;\n goals.forEach((goal) => {\n goalsMapRef.current.set(goal.goal.id, goal);\n });\n\n return response.data;\n },\n [api, endpoints.goalsHistory]\n );\n\n /**\n * Fetch goal models from API\n */\n const fetchGoalModels = useCallback(\n async (filters?: GoalModelFilters): Promise<GoalModelsApiResponse> => {\n const params = buildQueryParams({\n ...filters,\n type: GoalDraftType.MODELO,\n } as Record<string, unknown>);\n const response = await api.get<GoalModelsApiResponse>(\n endpoints.goalDrafts,\n { params }\n );\n return response.data;\n },\n [api, endpoints.goalDrafts]\n );\n\n /**\n * Delete a goal model\n */\n const deleteGoalModel = useCallback(\n async (id: string): Promise<void> => {\n await api.delete(`${endpoints.goalDrafts}/${id}`);\n },\n [api, endpoints.goalDrafts]\n );\n\n /**\n * Handle create lesson button click\n */\n const handleCreateLesson = useCallback(() => {\n navigate(paths.createLesson);\n }, []);\n\n /**\n * Handle create model button click\n */\n const handleCreateModel = useCallback(() => {\n navigate(paths.createModel);\n }, []);\n\n /**\n * Handle row click - navigate to goal details\n */\n const handleRowClick = useCallback((row: GoalTableItem) => {\n const originalData = goalsMapRef.current.get(row.id);\n navigate(`${paths.lessonDetails}/${row.id}`, {\n state: { goalData: originalData },\n });\n }, []);\n\n /**\n * Handle edit goal action\n */\n const handleEditGoal = useCallback((id: string) => {\n navigate(`${paths.editLesson}/${id}/editar`);\n }, []);\n\n /**\n * Handle edit model action\n */\n const handleEditModel = useCallback((model: GoalModelTableItem) => {\n navigate(`${paths.editModel}${model.id}`);\n }, []);\n\n /**\n * Handle send lesson button click - opens modal\n */\n const handleSendLesson = useCallback(\n (model: GoalModelTableItem) => {\n setSelectedModel(model);\n\n // Build categories from user data for CheckboxGroup\n const classes = getClassOptions(userData);\n const categories: CategoryConfig[] = [];\n\n if (classes.length > 0) {\n categories.push({\n key: 'students',\n label: 'Turmas',\n selectedIds: [],\n itens: classes.map((cls) => ({\n id: cls.id,\n name: cls.name,\n studentId: cls.id,\n userInstitutionId: cls.id,\n })),\n });\n }\n\n setSendModalCategories(categories);\n setSendModalOpen(true);\n },\n [userData]\n );\n\n /**\n * Handle send lesson modal submit\n */\n const handleSendLessonSubmit = useCallback(\n async (formData: SendLessonFormData) => {\n if (!selectedModel) return;\n\n setSendModalLoading(true);\n try {\n await api.post(endpoints.submitGoal, {\n draftId: selectedModel.id,\n students: formData.students,\n startDate: `${formData.startDate}T${formData.startTime}:00`,\n finalDate: `${formData.finalDate}T${formData.finalTime}:00`,\n });\n\n setSendModalOpen(false);\n setSelectedModel(null);\n } finally {\n setSendModalLoading(false);\n }\n },\n [api, endpoints.submitGoal, selectedModel]\n );\n\n /**\n * Handle send lesson modal close\n */\n const handleSendModalClose = useCallback(() => {\n setSendModalOpen(false);\n setSelectedModel(null);\n }, []);\n\n /**\n * Handle categories change in send modal\n */\n const handleCategoriesChange = useCallback(\n (categories: CategoryConfig[]) => {\n setSendModalCategories(categories);\n },\n []\n );\n\n return {\n historyProps: {\n fetchGoalsHistory,\n fetchGoalModels,\n deleteGoalModel,\n onCreateLesson: handleCreateLesson,\n onCreateModel: handleCreateModel,\n onRowClick: handleRowClick,\n onEditGoal: handleEditGoal,\n onEditModel: handleEditModel,\n onSendLesson: handleSendLesson,\n emptyStateImage,\n noSearchImage,\n mapSubjectNameToEnum,\n userFilterData,\n subjectsMap,\n title: texts.title,\n createButtonText: texts.createButtonText,\n searchPlaceholder: texts.searchPlaceholder,\n },\n modalProps: {\n isOpen: sendModalOpen,\n onClose: handleSendModalClose,\n onSubmit: handleSendLessonSubmit,\n categories: sendModalCategories,\n onCategoriesChange: handleCategoriesChange,\n isLoading: sendModalLoading,\n modalTitle: selectedModel?.title,\n },\n navigate,\n };\n };\n};\n\n/**\n * Alias for createUseRecommendedLessonsPage\n */\nexport const createRecommendedLessonsPageHook = createUseRecommendedLessonsPage;\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useRecommendedLessonsPage Hook Factory
|
|
3
|
+
*
|
|
4
|
+
* Factory function to create a hook for RecommendedLessons, LessonDrafts, and LessonModels pages.
|
|
5
|
+
* Contains all common state, memos, and callbacks.
|
|
6
|
+
*/
|
|
7
|
+
import { type GoalHistoryFilters, type GoalsHistoryApiResponse, type GoalTableItem, type GoalModelFilters, type GoalModelsApiResponse, type GoalModelTableItem } from '../types/recommendedLessons';
|
|
8
|
+
import type { SendLessonFormData, CategoryConfig } from '../components/SendLessonModal/types';
|
|
9
|
+
import { SubjectEnum } from '../enums/SubjectEnum';
|
|
10
|
+
/**
|
|
11
|
+
* API client interface
|
|
12
|
+
*/
|
|
13
|
+
export interface RecommendedLessonsApiClient {
|
|
14
|
+
get: <T>(url: string, config?: {
|
|
15
|
+
params?: Record<string, unknown>;
|
|
16
|
+
}) => Promise<{
|
|
17
|
+
data: T;
|
|
18
|
+
}>;
|
|
19
|
+
post: <T>(url: string, data?: unknown) => Promise<{
|
|
20
|
+
data: T;
|
|
21
|
+
}>;
|
|
22
|
+
delete: <T>(url: string) => Promise<{
|
|
23
|
+
data: T;
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* User institution data structure
|
|
28
|
+
*/
|
|
29
|
+
export interface UserInstitution {
|
|
30
|
+
school: {
|
|
31
|
+
id: string;
|
|
32
|
+
name: string;
|
|
33
|
+
};
|
|
34
|
+
schoolYear: {
|
|
35
|
+
id: string;
|
|
36
|
+
name: string;
|
|
37
|
+
};
|
|
38
|
+
class: {
|
|
39
|
+
id: string;
|
|
40
|
+
name: string;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Subject teacher class data structure
|
|
45
|
+
*/
|
|
46
|
+
export interface SubTeacherTopicClass {
|
|
47
|
+
subject: {
|
|
48
|
+
id: string;
|
|
49
|
+
name: string;
|
|
50
|
+
};
|
|
51
|
+
class: {
|
|
52
|
+
id: string;
|
|
53
|
+
name: string;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* User data structure
|
|
58
|
+
*/
|
|
59
|
+
export interface RecommendedLessonsUserData {
|
|
60
|
+
userInstitutions?: UserInstitution[];
|
|
61
|
+
subTeacherTopicClasses?: SubTeacherTopicClass[];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Navigation paths configuration
|
|
65
|
+
*/
|
|
66
|
+
export interface RecommendedLessonsPagePaths {
|
|
67
|
+
/** Path for creating a new lesson */
|
|
68
|
+
createLesson: string;
|
|
69
|
+
/** Path for creating a new model */
|
|
70
|
+
createModel: string;
|
|
71
|
+
/** Base path for lesson details */
|
|
72
|
+
lessonDetails: string;
|
|
73
|
+
/** Base path for editing a lesson */
|
|
74
|
+
editLesson: string;
|
|
75
|
+
/** Path for editing a model (with id parameter) */
|
|
76
|
+
editModel: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* API endpoints configuration
|
|
80
|
+
*/
|
|
81
|
+
export interface RecommendedLessonsPageEndpoints {
|
|
82
|
+
/** Endpoint for fetching goals history */
|
|
83
|
+
goalsHistory: string;
|
|
84
|
+
/** Endpoint for fetching goal models/drafts */
|
|
85
|
+
goalDrafts: string;
|
|
86
|
+
/** Endpoint for submitting a goal */
|
|
87
|
+
submitGoal: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* UI text configuration
|
|
91
|
+
*/
|
|
92
|
+
export interface RecommendedLessonsPageTexts {
|
|
93
|
+
title: string;
|
|
94
|
+
createButtonText: string;
|
|
95
|
+
searchPlaceholder: string;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Configuration for createUseRecommendedLessonsPage factory
|
|
99
|
+
*/
|
|
100
|
+
export interface UseRecommendedLessonsPageConfig {
|
|
101
|
+
/** API client for making requests */
|
|
102
|
+
api: RecommendedLessonsApiClient;
|
|
103
|
+
/** Navigation function */
|
|
104
|
+
navigate: (path: string, options?: {
|
|
105
|
+
state?: unknown;
|
|
106
|
+
}) => void;
|
|
107
|
+
/** User data for filter options */
|
|
108
|
+
userData: RecommendedLessonsUserData | null;
|
|
109
|
+
/** Navigation paths */
|
|
110
|
+
paths: RecommendedLessonsPagePaths;
|
|
111
|
+
/** API endpoints */
|
|
112
|
+
endpoints: RecommendedLessonsPageEndpoints;
|
|
113
|
+
/** UI text */
|
|
114
|
+
texts: RecommendedLessonsPageTexts;
|
|
115
|
+
/** Image for empty state */
|
|
116
|
+
emptyStateImage: string;
|
|
117
|
+
/** Image for no search results */
|
|
118
|
+
noSearchImage: string;
|
|
119
|
+
/** Function to map subject name to SubjectEnum */
|
|
120
|
+
mapSubjectNameToEnum: (subjectName: string) => SubjectEnum | null;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Return type for the useRecommendedLessonsPage hook
|
|
124
|
+
*/
|
|
125
|
+
export interface UseRecommendedLessonsPageReturn {
|
|
126
|
+
/** Props for RecommendedLessonsHistory component */
|
|
127
|
+
historyProps: {
|
|
128
|
+
fetchGoalsHistory: (filters?: GoalHistoryFilters) => Promise<GoalsHistoryApiResponse>;
|
|
129
|
+
fetchGoalModels: (filters?: GoalModelFilters) => Promise<GoalModelsApiResponse>;
|
|
130
|
+
deleteGoalModel: (id: string) => Promise<void>;
|
|
131
|
+
onCreateLesson: () => void;
|
|
132
|
+
onCreateModel: () => void;
|
|
133
|
+
onRowClick: (row: GoalTableItem) => void;
|
|
134
|
+
onEditGoal: (id: string) => void;
|
|
135
|
+
onEditModel: (model: GoalModelTableItem) => void;
|
|
136
|
+
onSendLesson: (model: GoalModelTableItem) => void;
|
|
137
|
+
emptyStateImage: string;
|
|
138
|
+
noSearchImage: string;
|
|
139
|
+
mapSubjectNameToEnum: (subjectName: string) => SubjectEnum | null;
|
|
140
|
+
userFilterData: {
|
|
141
|
+
schools: Array<{
|
|
142
|
+
id: string;
|
|
143
|
+
name: string;
|
|
144
|
+
}>;
|
|
145
|
+
classes: Array<{
|
|
146
|
+
id: string;
|
|
147
|
+
name: string;
|
|
148
|
+
}>;
|
|
149
|
+
subjects: Array<{
|
|
150
|
+
id: string;
|
|
151
|
+
name: string;
|
|
152
|
+
}>;
|
|
153
|
+
};
|
|
154
|
+
subjectsMap: Map<string, string>;
|
|
155
|
+
title: string;
|
|
156
|
+
createButtonText: string;
|
|
157
|
+
searchPlaceholder: string;
|
|
158
|
+
};
|
|
159
|
+
/** Props for SendLessonModal component */
|
|
160
|
+
modalProps: {
|
|
161
|
+
isOpen: boolean;
|
|
162
|
+
onClose: () => void;
|
|
163
|
+
onSubmit: (formData: SendLessonFormData) => Promise<void>;
|
|
164
|
+
categories: CategoryConfig[];
|
|
165
|
+
onCategoriesChange: (categories: CategoryConfig[]) => void;
|
|
166
|
+
isLoading: boolean;
|
|
167
|
+
modalTitle: string | undefined;
|
|
168
|
+
};
|
|
169
|
+
/** Navigate function for custom tab handlers */
|
|
170
|
+
navigate: (path: string, options?: {
|
|
171
|
+
state?: unknown;
|
|
172
|
+
}) => void;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Factory function to create useRecommendedLessonsPage hook
|
|
176
|
+
*
|
|
177
|
+
* @param config - Configuration object with API client, navigation, user data, paths, etc.
|
|
178
|
+
* @returns Hook function that returns historyProps, modalProps, and navigate
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```tsx
|
|
182
|
+
* // In your app setup
|
|
183
|
+
* const useRecommendedLessonsPage = createUseRecommendedLessonsPage({
|
|
184
|
+
* api,
|
|
185
|
+
* navigate,
|
|
186
|
+
* userData,
|
|
187
|
+
* paths: {
|
|
188
|
+
* createLesson: '/criar-aula',
|
|
189
|
+
* createModel: '/criar-aula?mode=model',
|
|
190
|
+
* lessonDetails: '/aulas-recomendadas',
|
|
191
|
+
* editLesson: '/aulas-recomendadas',
|
|
192
|
+
* editModel: '/criar-aula?mode=model&id=',
|
|
193
|
+
* },
|
|
194
|
+
* endpoints: {
|
|
195
|
+
* goalsHistory: '/recommended-class/history',
|
|
196
|
+
* goalDrafts: '/recommended-class/drafts',
|
|
197
|
+
* submitGoal: '/goals',
|
|
198
|
+
* },
|
|
199
|
+
* texts: {
|
|
200
|
+
* title: 'Histórico de aulas recomendadas',
|
|
201
|
+
* createButtonText: 'Criar aula',
|
|
202
|
+
* searchPlaceholder: 'Buscar aula',
|
|
203
|
+
* },
|
|
204
|
+
* emptyStateImage,
|
|
205
|
+
* noSearchImage,
|
|
206
|
+
* mapSubjectNameToEnum,
|
|
207
|
+
* });
|
|
208
|
+
*
|
|
209
|
+
* // In your component
|
|
210
|
+
* const { historyProps, modalProps, navigate } = useRecommendedLessonsPage();
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
export declare const createUseRecommendedLessonsPage: (config: UseRecommendedLessonsPageConfig) => (() => UseRecommendedLessonsPageReturn);
|
|
214
|
+
/**
|
|
215
|
+
* Alias for createUseRecommendedLessonsPage
|
|
216
|
+
*/
|
|
217
|
+
export declare const createRecommendedLessonsPageHook: (config: UseRecommendedLessonsPageConfig) => (() => UseRecommendedLessonsPageReturn);
|
|
218
|
+
//# sourceMappingURL=useRecommendedLessonsPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRecommendedLessonsPage.d.ts","sourceRoot":"","sources":["../../src/hooks/useRecommendedLessonsPage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAElB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACxB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EACV,kBAAkB,EAClB,cAAc,EACf,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,GAAG,EAAE,CAAC,CAAC,EACL,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,KAC1C,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IAC/D,MAAM,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;CAClD;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,UAAU,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC,sBAAsB,CAAC,EAAE,oBAAoB,EAAE,CAAC;CACjD;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,qCAAqC;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,mCAAmC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,+BAA+B;IAC9C,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,+BAA+B;IAC9C,qCAAqC;IACrC,GAAG,EAAE,2BAA2B,CAAC;IACjC,0BAA0B;IAC1B,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAChE,mCAAmC;IACnC,QAAQ,EAAE,0BAA0B,GAAG,IAAI,CAAC;IAC5C,uBAAuB;IACvB,KAAK,EAAE,2BAA2B,CAAC;IACnC,oBAAoB;IACpB,SAAS,EAAE,+BAA+B,CAAC;IAC3C,cAAc;IACd,KAAK,EAAE,2BAA2B,CAAC;IACnC,4BAA4B;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,kCAAkC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,kDAAkD;IAClD,oBAAoB,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,WAAW,GAAG,IAAI,CAAC;CACnE;AAED;;GAEG;AACH,MAAM,WAAW,+BAA+B;IAC9C,oDAAoD;IACpD,YAAY,EAAE;QACZ,iBAAiB,EAAE,CACjB,OAAO,CAAC,EAAE,kBAAkB,KACzB,OAAO,CAAC,uBAAuB,CAAC,CAAC;QACtC,eAAe,EAAE,CACf,OAAO,CAAC,EAAE,gBAAgB,KACvB,OAAO,CAAC,qBAAqB,CAAC,CAAC;QACpC,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/C,cAAc,EAAE,MAAM,IAAI,CAAC;QAC3B,aAAa,EAAE,MAAM,IAAI,CAAC;QAC1B,UAAU,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,CAAC;QACzC,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;QACjC,WAAW,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;QACjD,YAAY,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;QAClD,eAAe,EAAE,MAAM,CAAC;QACxB,aAAa,EAAE,MAAM,CAAC;QACtB,oBAAoB,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,WAAW,GAAG,IAAI,CAAC;QAClE,cAAc,EAAE;YACd,OAAO,EAAE,KAAK,CAAC;gBAAE,EAAE,EAAE,MAAM,CAAC;gBAAC,IAAI,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;YAC7C,OAAO,EAAE,KAAK,CAAC;gBAAE,EAAE,EAAE,MAAM,CAAC;gBAAC,IAAI,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;YAC7C,QAAQ,EAAE,KAAK,CAAC;gBAAE,EAAE,EAAE,MAAM,CAAC;gBAAC,IAAI,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;SAC/C,CAAC;QACF,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,KAAK,EAAE,MAAM,CAAC;QACd,gBAAgB,EAAE,MAAM,CAAC;QACzB,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,0CAA0C;IAC1C,UAAU,EAAE;QACV,MAAM,EAAE,OAAO,CAAC;QAChB,OAAO,EAAE,MAAM,IAAI,CAAC;QACpB,QAAQ,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1D,UAAU,EAAE,cAAc,EAAE,CAAC;QAC7B,kBAAkB,EAAE,CAAC,UAAU,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;QAC3D,SAAS,EAAE,OAAO,CAAC;QACnB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;KAChC,CAAC;IACF,gDAAgD;IAChD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CACjE;AAgFD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,eAAO,MAAM,+BAA+B,GAC1C,QAAQ,+BAA+B,KACtC,CAAC,MAAM,+BAA+B,CAgPxC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gCAAgC,WAtPnC,+BAA+B,KACtC,CAAC,MAAM,+BAA+B,CAqPsC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/hooks/useSendActivity.ts"],"sourcesContent":["/**\n * useSendActivity Hook\n *\n * Hook for managing the SendActivityModal state and actions.\n * Uses the API injection pattern (like ActivityDetails) for flexibility.\n */\n\nimport { useState, useCallback, useMemo, useRef } from 'react';\nimport dayjs from 'dayjs';\nimport type { CategoryConfig } from '../components/CheckBoxGroup/CheckBoxGroup';\nimport type {\n SendActivityFormData,\n SendActivityModalInitialData,\n} from '../components/SendActivityModal/types';\nimport type {\n UseSendActivityConfig,\n UseSendActivityReturn,\n SendActivityCategoriesData,\n ActivityModelItem,\n} from '../types/sendActivity';\n\n/**\n * Transform categories data to CategoryConfig format for CheckboxGroup\n * @param data - Categories data from API\n * @returns Array of CategoryConfig for CheckboxGroup\n */\nfunction transformToCategoryConfig(\n data: SendActivityCategoriesData\n): CategoryConfig[] {\n return [\n {\n key: 'escola',\n label: 'Escola',\n itens: data.schools,\n selectedIds: [],\n },\n {\n key: 'serie',\n label: 'Série',\n dependsOn: ['escola'],\n itens: data.schoolYears,\n filteredBy: [{ key: 'escola', internalField: 'escolaId' }],\n selectedIds: [],\n },\n {\n key: 'turma',\n label: 'Turma',\n dependsOn: ['escola', 'serie'],\n itens: data.classes,\n filteredBy: [\n { key: 'escola', internalField: 'escolaId' },\n { key: 'serie', internalField: 'serieId' },\n ],\n selectedIds: [],\n },\n {\n key: 'alunos',\n label: 'Aluno',\n dependsOn: ['escola', 'serie', 'turma'],\n itens: data.students,\n filteredBy: [\n { key: 'escola', internalField: 'escolaId' },\n { key: 'serie', internalField: 'serieId' },\n { key: 'turma', internalField: 'turmaId' },\n ],\n selectedIds: [],\n },\n ];\n}\n\n/**\n * Convert date and time to ISO datetime string\n * Uses dayjs for proper timezone conversion\n * @param date - Date string in YYYY-MM-DD format\n * @param time - Time string in HH:MM format\n * @returns ISO datetime string in UTC\n */\nfunction toISODateTime(date: string, time: string): string {\n return dayjs(`${date}T${time}`).toISOString();\n}\n\n/**\n * Hook for managing the SendActivityModal state and actions\n *\n * Uses the API injection pattern - receives functions for API calls\n * instead of making calls directly. This allows the hook to be used\n * in different projects with different API configurations.\n *\n * @param config - Configuration with API functions and callbacks\n * @returns Object with modal state, categories, and handlers\n *\n * @example\n * ```tsx\n * const sendActivity = useSendActivity({\n * fetchCategories: async () => {\n * const [schools, years, classes, students] = await Promise.all([\n * api.get('/schools'),\n * api.get('/school-years'),\n * api.get('/classes'),\n * api.get('/students'),\n * ]);\n * return { schools, schoolYears: years, classes, students };\n * },\n * createActivity: async (data) => {\n * const response = await api.post('/activities', data);\n * return { id: response.data.id };\n * },\n * sendToStudents: async (activityId, students) => {\n * await api.post('/activities/send-to-students', { activityId, students });\n * },\n * fetchQuestionIds: async (modelId) => {\n * const response = await api.get(`/activity-drafts/${modelId}`);\n * return response.data.selectedQuestions?.map(q => q.id) || null;\n * },\n * onSuccess: (msg) => toast.success(msg),\n * onError: (msg) => toast.error(msg),\n * });\n * ```\n */\nexport function useSendActivity(\n config: UseSendActivityConfig\n): UseSendActivityReturn {\n const {\n fetchCategories,\n createActivity,\n sendToStudents,\n fetchQuestionIds,\n onSuccess,\n onError,\n } = config;\n\n const [isOpen, setIsOpen] = useState(false);\n const [selectedModel, setSelectedModel] = useState<ActivityModelItem | null>(\n null\n );\n const [categories, setCategories] = useState<CategoryConfig[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [isCategoriesLoading, setIsCategoriesLoading] = useState(false);\n\n const categoriesLoadedRef = useRef(false);\n\n /**\n * Initial data for pre-filling the modal form\n */\n const initialData = useMemo<SendActivityModalInitialData | undefined>(() => {\n if (!selectedModel) return undefined;\n return {\n title: selectedModel.title,\n };\n }, [selectedModel]);\n\n /**\n * Load categories for recipient selection\n */\n const loadCategories = useCallback(async () => {\n if (categoriesLoadedRef.current) return;\n\n setIsCategoriesLoading(true);\n try {\n const data = await fetchCategories();\n const categoryConfig = transformToCategoryConfig(data);\n setCategories(categoryConfig);\n categoriesLoadedRef.current = true;\n } catch (error) {\n console.error('Error loading categories:', error);\n onError?.('Erro ao carregar destinatários');\n } finally {\n setIsCategoriesLoading(false);\n }\n }, [fetchCategories, onError]);\n\n /**\n * Open the modal with a selected model\n * @param model - Activity model to send\n */\n const openModal = useCallback(\n (model: ActivityModelItem) => {\n setSelectedModel(model);\n setIsOpen(true);\n void loadCategories();\n },\n [loadCategories]\n );\n\n /**\n * Close the modal and reset state\n */\n const closeModal = useCallback(() => {\n setIsOpen(false);\n setSelectedModel(null);\n }, []);\n\n /**\n * Handle categories change from CheckboxGroup\n * @param updatedCategories - Updated categories array\n */\n const onCategoriesChange = useCallback(\n (updatedCategories: CategoryConfig[]) => {\n setCategories(updatedCategories);\n },\n []\n );\n\n /**\n * Handle form submission\n * @param data - Form data from SendActivityModal\n */\n const handleSubmit = useCallback(\n async (data: SendActivityFormData) => {\n if (!selectedModel) return;\n\n setIsLoading(true);\n\n try {\n // 1. Fetch question IDs from draft/model\n const questionIds = await fetchQuestionIds(selectedModel.id);\n if (!questionIds || questionIds.length === 0) {\n throw new Error('Não foi possível obter questões do modelo');\n }\n\n // 2. Create activity\n const createResponse = await createActivity({\n title: data.title,\n subjectId: selectedModel.subjectId,\n questionIds,\n subtype: data.subtype,\n notification: data.notification,\n startDate: toISODateTime(data.startDate, data.startTime),\n finalDate: toISODateTime(data.finalDate, data.finalTime),\n canRetry: data.canRetry,\n });\n\n // 3. Send to students\n await sendToStudents(createResponse.id, data.students);\n\n onSuccess?.(`Atividade enviada para ${data.students.length} aluno(s)`);\n\n closeModal();\n } catch (error) {\n console.error('Error sending activity:', error);\n onError?.('Erro ao enviar atividade');\n } finally {\n setIsLoading(false);\n }\n },\n [\n selectedModel,\n fetchQuestionIds,\n createActivity,\n sendToStudents,\n onSuccess,\n onError,\n closeModal,\n ]\n );\n\n return {\n isOpen,\n openModal,\n closeModal,\n selectedModel,\n initialData,\n categories,\n onCategoriesChange,\n isLoading,\n isCategoriesLoading,\n handleSubmit,\n };\n}\n"],"mappings":"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","names":["dayjs"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/hooks/useSendActivity.ts"],"sourcesContent":["/**\n * useSendActivity Hook\n *\n * Hook for managing the SendActivityModal state and actions.\n * Uses the API injection pattern (like ActivityDetails) for flexibility.\n */\n\nimport { useState, useCallback, useMemo, useRef } from 'react';\nimport dayjs from 'dayjs';\nimport type { CategoryConfig } from '../components/CheckBoxGroup/CheckBoxGroup';\nimport type {\n SendActivityFormData,\n SendActivityModalInitialData,\n} from '../components/SendActivityModal/types';\nimport type {\n UseSendActivityConfig,\n UseSendActivityReturn,\n SendActivityCategoriesData,\n ActivityModelItem,\n} from '../types/sendActivity';\n\n/**\n * Transform categories data to CategoryConfig format for CheckboxGroup\n * @param data - Categories data from API\n * @returns Array of CategoryConfig for CheckboxGroup\n */\nfunction transformToCategoryConfig(\n data: SendActivityCategoriesData\n): CategoryConfig[] {\n return [\n {\n key: 'escola',\n label: 'Escola',\n itens: data.schools,\n selectedIds: [],\n },\n {\n key: 'serie',\n label: 'Série',\n dependsOn: ['escola'],\n itens: data.schoolYears,\n filteredBy: [{ key: 'escola', internalField: 'escolaId' }],\n selectedIds: [],\n },\n {\n key: 'turma',\n label: 'Turma',\n dependsOn: ['escola', 'serie'],\n itens: data.classes,\n filteredBy: [\n { key: 'escola', internalField: 'escolaId' },\n { key: 'serie', internalField: 'serieId' },\n ],\n selectedIds: [],\n },\n {\n key: 'students',\n label: 'Aluno',\n dependsOn: ['escola', 'serie', 'turma'],\n itens: data.students,\n filteredBy: [\n { key: 'escola', internalField: 'escolaId' },\n { key: 'serie', internalField: 'serieId' },\n { key: 'turma', internalField: 'turmaId' },\n ],\n selectedIds: [],\n },\n ];\n}\n\n/**\n * Convert date and time to ISO datetime string\n * Uses dayjs for proper timezone conversion\n * @param date - Date string in YYYY-MM-DD format\n * @param time - Time string in HH:MM format\n * @returns ISO datetime string in UTC\n */\nfunction toISODateTime(date: string, time: string): string {\n return dayjs(`${date}T${time}`).toISOString();\n}\n\n/**\n * Hook for managing the SendActivityModal state and actions\n *\n * Uses the API injection pattern - receives functions for API calls\n * instead of making calls directly. This allows the hook to be used\n * in different projects with different API configurations.\n *\n * @param config - Configuration with API functions and callbacks\n * @returns Object with modal state, categories, and handlers\n *\n * @example\n * ```tsx\n * const sendActivity = useSendActivity({\n * fetchCategories: async () => {\n * const [schools, years, classes, students] = await Promise.all([\n * api.get('/schools'),\n * api.get('/school-years'),\n * api.get('/classes'),\n * api.get('/students'),\n * ]);\n * return { schools, schoolYears: years, classes, students };\n * },\n * createActivity: async (data) => {\n * const response = await api.post('/activities', data);\n * return { id: response.data.id };\n * },\n * sendToStudents: async (activityId, students) => {\n * await api.post('/activities/send-to-students', { activityId, students });\n * },\n * fetchQuestionIds: async (modelId) => {\n * const response = await api.get(`/activity-drafts/${modelId}`);\n * return response.data.selectedQuestions?.map(q => q.id) || null;\n * },\n * onSuccess: (msg) => toast.success(msg),\n * onError: (msg) => toast.error(msg),\n * });\n * ```\n */\nexport function useSendActivity(\n config: UseSendActivityConfig\n): UseSendActivityReturn {\n const {\n fetchCategories,\n createActivity,\n sendToStudents,\n fetchQuestionIds,\n onSuccess,\n onError,\n } = config;\n\n const [isOpen, setIsOpen] = useState(false);\n const [selectedModel, setSelectedModel] = useState<ActivityModelItem | null>(\n null\n );\n const [categories, setCategories] = useState<CategoryConfig[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [isCategoriesLoading, setIsCategoriesLoading] = useState(false);\n\n const categoriesLoadedRef = useRef(false);\n\n /**\n * Initial data for pre-filling the modal form\n */\n const initialData = useMemo<SendActivityModalInitialData | undefined>(() => {\n if (!selectedModel) return undefined;\n return {\n title: selectedModel.title,\n };\n }, [selectedModel]);\n\n /**\n * Load categories for recipient selection\n */\n const loadCategories = useCallback(async () => {\n if (categoriesLoadedRef.current) return;\n\n setIsCategoriesLoading(true);\n try {\n const data = await fetchCategories();\n const categoryConfig = transformToCategoryConfig(data);\n setCategories(categoryConfig);\n categoriesLoadedRef.current = true;\n } catch (error) {\n console.error('Error loading categories:', error);\n onError?.('Erro ao carregar destinatários');\n } finally {\n setIsCategoriesLoading(false);\n }\n }, [fetchCategories, onError]);\n\n /**\n * Open the modal with a selected model\n * @param model - Activity model to send\n */\n const openModal = useCallback(\n (model: ActivityModelItem) => {\n setSelectedModel(model);\n setIsOpen(true);\n void loadCategories();\n },\n [loadCategories]\n );\n\n /**\n * Close the modal and reset state\n */\n const closeModal = useCallback(() => {\n setIsOpen(false);\n setSelectedModel(null);\n }, []);\n\n /**\n * Handle categories change from CheckboxGroup\n * @param updatedCategories - Updated categories array\n */\n const onCategoriesChange = useCallback(\n (updatedCategories: CategoryConfig[]) => {\n setCategories(updatedCategories);\n },\n []\n );\n\n /**\n * Handle form submission\n * @param data - Form data from SendActivityModal\n */\n const handleSubmit = useCallback(\n async (data: SendActivityFormData) => {\n if (!selectedModel) return;\n\n setIsLoading(true);\n\n try {\n // 1. Fetch question IDs from draft/model\n const questionIds = await fetchQuestionIds(selectedModel.id);\n if (!questionIds || questionIds.length === 0) {\n throw new Error('Não foi possível obter questões do modelo');\n }\n\n // 2. Create activity\n const createResponse = await createActivity({\n title: data.title,\n subjectId: selectedModel.subjectId,\n questionIds,\n subtype: data.subtype,\n notification: data.notification,\n startDate: toISODateTime(data.startDate, data.startTime),\n finalDate: toISODateTime(data.finalDate, data.finalTime),\n canRetry: data.canRetry,\n });\n\n // 3. Send to students\n await sendToStudents(createResponse.id, data.students);\n\n onSuccess?.(`Atividade enviada para ${data.students.length} aluno(s)`);\n\n closeModal();\n } catch (error) {\n console.error('Error sending activity:', error);\n onError?.('Erro ao enviar atividade');\n } finally {\n setIsLoading(false);\n }\n },\n [\n selectedModel,\n fetchQuestionIds,\n createActivity,\n sendToStudents,\n onSuccess,\n onError,\n closeModal,\n ]\n );\n\n return {\n isOpen,\n openModal,\n closeModal,\n selectedModel,\n initialData,\n categories,\n onCategoriesChange,\n isLoading,\n isCategoriesLoading,\n handleSubmit,\n };\n}\n"],"mappings":"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","names":["dayjs"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/hooks/useSendActivity.ts"],"sourcesContent":["/**\n * useSendActivity Hook\n *\n * Hook for managing the SendActivityModal state and actions.\n * Uses the API injection pattern (like ActivityDetails) for flexibility.\n */\n\nimport { useState, useCallback, useMemo, useRef } from 'react';\nimport dayjs from 'dayjs';\nimport type { CategoryConfig } from '../components/CheckBoxGroup/CheckBoxGroup';\nimport type {\n SendActivityFormData,\n SendActivityModalInitialData,\n} from '../components/SendActivityModal/types';\nimport type {\n UseSendActivityConfig,\n UseSendActivityReturn,\n SendActivityCategoriesData,\n ActivityModelItem,\n} from '../types/sendActivity';\n\n/**\n * Transform categories data to CategoryConfig format for CheckboxGroup\n * @param data - Categories data from API\n * @returns Array of CategoryConfig for CheckboxGroup\n */\nfunction transformToCategoryConfig(\n data: SendActivityCategoriesData\n): CategoryConfig[] {\n return [\n {\n key: 'escola',\n label: 'Escola',\n itens: data.schools,\n selectedIds: [],\n },\n {\n key: 'serie',\n label: 'Série',\n dependsOn: ['escola'],\n itens: data.schoolYears,\n filteredBy: [{ key: 'escola', internalField: 'escolaId' }],\n selectedIds: [],\n },\n {\n key: 'turma',\n label: 'Turma',\n dependsOn: ['escola', 'serie'],\n itens: data.classes,\n filteredBy: [\n { key: 'escola', internalField: 'escolaId' },\n { key: 'serie', internalField: 'serieId' },\n ],\n selectedIds: [],\n },\n {\n key: 'alunos',\n label: 'Aluno',\n dependsOn: ['escola', 'serie', 'turma'],\n itens: data.students,\n filteredBy: [\n { key: 'escola', internalField: 'escolaId' },\n { key: 'serie', internalField: 'serieId' },\n { key: 'turma', internalField: 'turmaId' },\n ],\n selectedIds: [],\n },\n ];\n}\n\n/**\n * Convert date and time to ISO datetime string\n * Uses dayjs for proper timezone conversion\n * @param date - Date string in YYYY-MM-DD format\n * @param time - Time string in HH:MM format\n * @returns ISO datetime string in UTC\n */\nfunction toISODateTime(date: string, time: string): string {\n return dayjs(`${date}T${time}`).toISOString();\n}\n\n/**\n * Hook for managing the SendActivityModal state and actions\n *\n * Uses the API injection pattern - receives functions for API calls\n * instead of making calls directly. This allows the hook to be used\n * in different projects with different API configurations.\n *\n * @param config - Configuration with API functions and callbacks\n * @returns Object with modal state, categories, and handlers\n *\n * @example\n * ```tsx\n * const sendActivity = useSendActivity({\n * fetchCategories: async () => {\n * const [schools, years, classes, students] = await Promise.all([\n * api.get('/schools'),\n * api.get('/school-years'),\n * api.get('/classes'),\n * api.get('/students'),\n * ]);\n * return { schools, schoolYears: years, classes, students };\n * },\n * createActivity: async (data) => {\n * const response = await api.post('/activities', data);\n * return { id: response.data.id };\n * },\n * sendToStudents: async (activityId, students) => {\n * await api.post('/activities/send-to-students', { activityId, students });\n * },\n * fetchQuestionIds: async (modelId) => {\n * const response = await api.get(`/activity-drafts/${modelId}`);\n * return response.data.selectedQuestions?.map(q => q.id) || null;\n * },\n * onSuccess: (msg) => toast.success(msg),\n * onError: (msg) => toast.error(msg),\n * });\n * ```\n */\nexport function useSendActivity(\n config: UseSendActivityConfig\n): UseSendActivityReturn {\n const {\n fetchCategories,\n createActivity,\n sendToStudents,\n fetchQuestionIds,\n onSuccess,\n onError,\n } = config;\n\n const [isOpen, setIsOpen] = useState(false);\n const [selectedModel, setSelectedModel] = useState<ActivityModelItem | null>(\n null\n );\n const [categories, setCategories] = useState<CategoryConfig[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [isCategoriesLoading, setIsCategoriesLoading] = useState(false);\n\n const categoriesLoadedRef = useRef(false);\n\n /**\n * Initial data for pre-filling the modal form\n */\n const initialData = useMemo<SendActivityModalInitialData | undefined>(() => {\n if (!selectedModel) return undefined;\n return {\n title: selectedModel.title,\n };\n }, [selectedModel]);\n\n /**\n * Load categories for recipient selection\n */\n const loadCategories = useCallback(async () => {\n if (categoriesLoadedRef.current) return;\n\n setIsCategoriesLoading(true);\n try {\n const data = await fetchCategories();\n const categoryConfig = transformToCategoryConfig(data);\n setCategories(categoryConfig);\n categoriesLoadedRef.current = true;\n } catch (error) {\n console.error('Error loading categories:', error);\n onError?.('Erro ao carregar destinatários');\n } finally {\n setIsCategoriesLoading(false);\n }\n }, [fetchCategories, onError]);\n\n /**\n * Open the modal with a selected model\n * @param model - Activity model to send\n */\n const openModal = useCallback(\n (model: ActivityModelItem) => {\n setSelectedModel(model);\n setIsOpen(true);\n void loadCategories();\n },\n [loadCategories]\n );\n\n /**\n * Close the modal and reset state\n */\n const closeModal = useCallback(() => {\n setIsOpen(false);\n setSelectedModel(null);\n }, []);\n\n /**\n * Handle categories change from CheckboxGroup\n * @param updatedCategories - Updated categories array\n */\n const onCategoriesChange = useCallback(\n (updatedCategories: CategoryConfig[]) => {\n setCategories(updatedCategories);\n },\n []\n );\n\n /**\n * Handle form submission\n * @param data - Form data from SendActivityModal\n */\n const handleSubmit = useCallback(\n async (data: SendActivityFormData) => {\n if (!selectedModel) return;\n\n setIsLoading(true);\n\n try {\n // 1. Fetch question IDs from draft/model\n const questionIds = await fetchQuestionIds(selectedModel.id);\n if (!questionIds || questionIds.length === 0) {\n throw new Error('Não foi possível obter questões do modelo');\n }\n\n // 2. Create activity\n const createResponse = await createActivity({\n title: data.title,\n subjectId: selectedModel.subjectId,\n questionIds,\n subtype: data.subtype,\n notification: data.notification,\n startDate: toISODateTime(data.startDate, data.startTime),\n finalDate: toISODateTime(data.finalDate, data.finalTime),\n canRetry: data.canRetry,\n });\n\n // 3. Send to students\n await sendToStudents(createResponse.id, data.students);\n\n onSuccess?.(`Atividade enviada para ${data.students.length} aluno(s)`);\n\n closeModal();\n } catch (error) {\n console.error('Error sending activity:', error);\n onError?.('Erro ao enviar atividade');\n } finally {\n setIsLoading(false);\n }\n },\n [\n selectedModel,\n fetchQuestionIds,\n createActivity,\n sendToStudents,\n onSuccess,\n onError,\n closeModal,\n ]\n );\n\n return {\n isOpen,\n openModal,\n closeModal,\n selectedModel,\n initialData,\n categories,\n onCategoriesChange,\n isLoading,\n isCategoriesLoading,\n handleSubmit,\n };\n}\n"],"mappings":";AAOA,SAAS,UAAU,aAAa,SAAS,cAAc;AACvD,OAAO,WAAW;AAkBlB,SAAS,0BACP,MACkB;AAClB,SAAO;AAAA,IACL;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,OAAO,KAAK;AAAA,MACZ,aAAa,CAAC;AAAA,IAChB;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,WAAW,CAAC,QAAQ;AAAA,MACpB,OAAO,KAAK;AAAA,MACZ,YAAY,CAAC,EAAE,KAAK,UAAU,eAAe,WAAW,CAAC;AAAA,MACzD,aAAa,CAAC;AAAA,IAChB;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,WAAW,CAAC,UAAU,OAAO;AAAA,MAC7B,OAAO,KAAK;AAAA,MACZ,YAAY;AAAA,QACV,EAAE,KAAK,UAAU,eAAe,WAAW;AAAA,QAC3C,EAAE,KAAK,SAAS,eAAe,UAAU;AAAA,MAC3C;AAAA,MACA,aAAa,CAAC;AAAA,IAChB;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,OAAO;AAAA,MACP,WAAW,CAAC,UAAU,SAAS,OAAO;AAAA,MACtC,OAAO,KAAK;AAAA,MACZ,YAAY;AAAA,QACV,EAAE,KAAK,UAAU,eAAe,WAAW;AAAA,QAC3C,EAAE,KAAK,SAAS,eAAe,UAAU;AAAA,QACzC,EAAE,KAAK,SAAS,eAAe,UAAU;AAAA,MAC3C;AAAA,MACA,aAAa,CAAC;AAAA,IAChB;AAAA,EACF;AACF;AASA,SAAS,cAAc,MAAc,MAAsB;AACzD,SAAO,MAAM,GAAG,IAAI,IAAI,IAAI,EAAE,EAAE,YAAY;AAC9C;AAwCO,SAAS,gBACd,QACuB;AACvB,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAC1C,QAAM,CAAC,eAAe,gBAAgB,IAAI;AAAA,IACxC;AAAA,EACF;AACA,QAAM,CAAC,YAAY,aAAa,IAAI,SAA2B,CAAC,CAAC;AACjE,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,qBAAqB,sBAAsB,IAAI,SAAS,KAAK;AAEpE,QAAM,sBAAsB,OAAO,KAAK;AAKxC,QAAM,cAAc,QAAkD,MAAM;AAC1E,QAAI,CAAC,cAAe,QAAO;AAC3B,WAAO;AAAA,MACL,OAAO,cAAc;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,aAAa,CAAC;AAKlB,QAAM,iBAAiB,YAAY,YAAY;AAC7C,QAAI,oBAAoB,QAAS;AAEjC,2BAAuB,IAAI;AAC3B,QAAI;AACF,YAAM,OAAO,MAAM,gBAAgB;AACnC,YAAM,iBAAiB,0BAA0B,IAAI;AACrD,oBAAc,cAAc;AAC5B,0BAAoB,UAAU;AAAA,IAChC,SAAS,OAAO;AACd,cAAQ,MAAM,6BAA6B,KAAK;AAChD,gBAAU,mCAAgC;AAAA,IAC5C,UAAE;AACA,6BAAuB,KAAK;AAAA,IAC9B;AAAA,EACF,GAAG,CAAC,iBAAiB,OAAO,CAAC;AAM7B,QAAM,YAAY;AAAA,IAChB,CAAC,UAA6B;AAC5B,uBAAiB,KAAK;AACtB,gBAAU,IAAI;AACd,WAAK,eAAe;AAAA,IACtB;AAAA,IACA,CAAC,cAAc;AAAA,EACjB;AAKA,QAAM,aAAa,YAAY,MAAM;AACnC,cAAU,KAAK;AACf,qBAAiB,IAAI;AAAA,EACvB,GAAG,CAAC,CAAC;AAML,QAAM,qBAAqB;AAAA,IACzB,CAAC,sBAAwC;AACvC,oBAAc,iBAAiB;AAAA,IACjC;AAAA,IACA,CAAC;AAAA,EACH;AAMA,QAAM,eAAe;AAAA,IACnB,OAAO,SAA+B;AACpC,UAAI,CAAC,cAAe;AAEpB,mBAAa,IAAI;AAEjB,UAAI;AAEF,cAAM,cAAc,MAAM,iBAAiB,cAAc,EAAE;AAC3D,YAAI,CAAC,eAAe,YAAY,WAAW,GAAG;AAC5C,gBAAM,IAAI,MAAM,oDAA2C;AAAA,QAC7D;AAGA,cAAM,iBAAiB,MAAM,eAAe;AAAA,UAC1C,OAAO,KAAK;AAAA,UACZ,WAAW,cAAc;AAAA,UACzB;AAAA,UACA,SAAS,KAAK;AAAA,UACd,cAAc,KAAK;AAAA,UACnB,WAAW,cAAc,KAAK,WAAW,KAAK,SAAS;AAAA,UACvD,WAAW,cAAc,KAAK,WAAW,KAAK,SAAS;AAAA,UACvD,UAAU,KAAK;AAAA,QACjB,CAAC;AAGD,cAAM,eAAe,eAAe,IAAI,KAAK,QAAQ;AAErD,oBAAY,0BAA0B,KAAK,SAAS,MAAM,WAAW;AAErE,mBAAW;AAAA,MACb,SAAS,OAAO;AACd,gBAAQ,MAAM,2BAA2B,KAAK;AAC9C,kBAAU,0BAA0B;AAAA,MACtC,UAAE;AACA,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/hooks/useSendActivity.ts"],"sourcesContent":["/**\n * useSendActivity Hook\n *\n * Hook for managing the SendActivityModal state and actions.\n * Uses the API injection pattern (like ActivityDetails) for flexibility.\n */\n\nimport { useState, useCallback, useMemo, useRef } from 'react';\nimport dayjs from 'dayjs';\nimport type { CategoryConfig } from '../components/CheckBoxGroup/CheckBoxGroup';\nimport type {\n SendActivityFormData,\n SendActivityModalInitialData,\n} from '../components/SendActivityModal/types';\nimport type {\n UseSendActivityConfig,\n UseSendActivityReturn,\n SendActivityCategoriesData,\n ActivityModelItem,\n} from '../types/sendActivity';\n\n/**\n * Transform categories data to CategoryConfig format for CheckboxGroup\n * @param data - Categories data from API\n * @returns Array of CategoryConfig for CheckboxGroup\n */\nfunction transformToCategoryConfig(\n data: SendActivityCategoriesData\n): CategoryConfig[] {\n return [\n {\n key: 'escola',\n label: 'Escola',\n itens: data.schools,\n selectedIds: [],\n },\n {\n key: 'serie',\n label: 'Série',\n dependsOn: ['escola'],\n itens: data.schoolYears,\n filteredBy: [{ key: 'escola', internalField: 'escolaId' }],\n selectedIds: [],\n },\n {\n key: 'turma',\n label: 'Turma',\n dependsOn: ['escola', 'serie'],\n itens: data.classes,\n filteredBy: [\n { key: 'escola', internalField: 'escolaId' },\n { key: 'serie', internalField: 'serieId' },\n ],\n selectedIds: [],\n },\n {\n key: 'students',\n label: 'Aluno',\n dependsOn: ['escola', 'serie', 'turma'],\n itens: data.students,\n filteredBy: [\n { key: 'escola', internalField: 'escolaId' },\n { key: 'serie', internalField: 'serieId' },\n { key: 'turma', internalField: 'turmaId' },\n ],\n selectedIds: [],\n },\n ];\n}\n\n/**\n * Convert date and time to ISO datetime string\n * Uses dayjs for proper timezone conversion\n * @param date - Date string in YYYY-MM-DD format\n * @param time - Time string in HH:MM format\n * @returns ISO datetime string in UTC\n */\nfunction toISODateTime(date: string, time: string): string {\n return dayjs(`${date}T${time}`).toISOString();\n}\n\n/**\n * Hook for managing the SendActivityModal state and actions\n *\n * Uses the API injection pattern - receives functions for API calls\n * instead of making calls directly. This allows the hook to be used\n * in different projects with different API configurations.\n *\n * @param config - Configuration with API functions and callbacks\n * @returns Object with modal state, categories, and handlers\n *\n * @example\n * ```tsx\n * const sendActivity = useSendActivity({\n * fetchCategories: async () => {\n * const [schools, years, classes, students] = await Promise.all([\n * api.get('/schools'),\n * api.get('/school-years'),\n * api.get('/classes'),\n * api.get('/students'),\n * ]);\n * return { schools, schoolYears: years, classes, students };\n * },\n * createActivity: async (data) => {\n * const response = await api.post('/activities', data);\n * return { id: response.data.id };\n * },\n * sendToStudents: async (activityId, students) => {\n * await api.post('/activities/send-to-students', { activityId, students });\n * },\n * fetchQuestionIds: async (modelId) => {\n * const response = await api.get(`/activity-drafts/${modelId}`);\n * return response.data.selectedQuestions?.map(q => q.id) || null;\n * },\n * onSuccess: (msg) => toast.success(msg),\n * onError: (msg) => toast.error(msg),\n * });\n * ```\n */\nexport function useSendActivity(\n config: UseSendActivityConfig\n): UseSendActivityReturn {\n const {\n fetchCategories,\n createActivity,\n sendToStudents,\n fetchQuestionIds,\n onSuccess,\n onError,\n } = config;\n\n const [isOpen, setIsOpen] = useState(false);\n const [selectedModel, setSelectedModel] = useState<ActivityModelItem | null>(\n null\n );\n const [categories, setCategories] = useState<CategoryConfig[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [isCategoriesLoading, setIsCategoriesLoading] = useState(false);\n\n const categoriesLoadedRef = useRef(false);\n\n /**\n * Initial data for pre-filling the modal form\n */\n const initialData = useMemo<SendActivityModalInitialData | undefined>(() => {\n if (!selectedModel) return undefined;\n return {\n title: selectedModel.title,\n };\n }, [selectedModel]);\n\n /**\n * Load categories for recipient selection\n */\n const loadCategories = useCallback(async () => {\n if (categoriesLoadedRef.current) return;\n\n setIsCategoriesLoading(true);\n try {\n const data = await fetchCategories();\n const categoryConfig = transformToCategoryConfig(data);\n setCategories(categoryConfig);\n categoriesLoadedRef.current = true;\n } catch (error) {\n console.error('Error loading categories:', error);\n onError?.('Erro ao carregar destinatários');\n } finally {\n setIsCategoriesLoading(false);\n }\n }, [fetchCategories, onError]);\n\n /**\n * Open the modal with a selected model\n * @param model - Activity model to send\n */\n const openModal = useCallback(\n (model: ActivityModelItem) => {\n setSelectedModel(model);\n setIsOpen(true);\n void loadCategories();\n },\n [loadCategories]\n );\n\n /**\n * Close the modal and reset state\n */\n const closeModal = useCallback(() => {\n setIsOpen(false);\n setSelectedModel(null);\n }, []);\n\n /**\n * Handle categories change from CheckboxGroup\n * @param updatedCategories - Updated categories array\n */\n const onCategoriesChange = useCallback(\n (updatedCategories: CategoryConfig[]) => {\n setCategories(updatedCategories);\n },\n []\n );\n\n /**\n * Handle form submission\n * @param data - Form data from SendActivityModal\n */\n const handleSubmit = useCallback(\n async (data: SendActivityFormData) => {\n if (!selectedModel) return;\n\n setIsLoading(true);\n\n try {\n // 1. Fetch question IDs from draft/model\n const questionIds = await fetchQuestionIds(selectedModel.id);\n if (!questionIds || questionIds.length === 0) {\n throw new Error('Não foi possível obter questões do modelo');\n }\n\n // 2. Create activity\n const createResponse = await createActivity({\n title: data.title,\n subjectId: selectedModel.subjectId,\n questionIds,\n subtype: data.subtype,\n notification: data.notification,\n startDate: toISODateTime(data.startDate, data.startTime),\n finalDate: toISODateTime(data.finalDate, data.finalTime),\n canRetry: data.canRetry,\n });\n\n // 3. Send to students\n await sendToStudents(createResponse.id, data.students);\n\n onSuccess?.(`Atividade enviada para ${data.students.length} aluno(s)`);\n\n closeModal();\n } catch (error) {\n console.error('Error sending activity:', error);\n onError?.('Erro ao enviar atividade');\n } finally {\n setIsLoading(false);\n }\n },\n [\n selectedModel,\n fetchQuestionIds,\n createActivity,\n sendToStudents,\n onSuccess,\n onError,\n closeModal,\n ]\n );\n\n return {\n isOpen,\n openModal,\n closeModal,\n selectedModel,\n initialData,\n categories,\n onCategoriesChange,\n isLoading,\n isCategoriesLoading,\n handleSubmit,\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -171,6 +171,8 @@ export { RecommendedLessonDetails, StudentPerformanceModal, } from './components
|
|
|
171
171
|
export type { RecommendedLessonDetailsProps, StudentPerformanceModalProps, StudentPerformanceData, StudentPerformanceLabels, LessonProgress, LessonQuestion, QuestionAlternative, LessonDetailsLabels, DisplayStudent, } from './components/RecommendedLessonDetails';
|
|
172
172
|
export { createUseRecommendedLessonsHistory, createRecommendedLessonsHistoryHook, determineGoalStatus, transformGoalToTableItem, handleGoalFetchError, goalsHistoryApiResponseSchema, } from './hooks/useRecommendedLessons';
|
|
173
173
|
export type { UseRecommendedLessonsHistoryState, UseRecommendedLessonsHistoryReturn, } from './hooks/useRecommendedLessons';
|
|
174
|
+
export { createUseRecommendedLessonsPage, createRecommendedLessonsPageHook, } from './hooks/useRecommendedLessonsPage';
|
|
175
|
+
export type { UseRecommendedLessonsPageConfig, UseRecommendedLessonsPageReturn, RecommendedLessonsApiClient, RecommendedLessonsUserData, RecommendedLessonsPagePaths, RecommendedLessonsPageEndpoints, RecommendedLessonsPageTexts, UserInstitution as RecommendedLessonsUserInstitution, SubTeacherTopicClass as RecommendedLessonsSubTeacherTopicClass, } from './hooks/useRecommendedLessonsPage';
|
|
174
176
|
export { createUseRecommendedLessonDetails, createRecommendedLessonDetailsHook, handleLessonDetailsFetchError, goalApiResponseSchema, goalDetailsApiResponseSchema, historyApiResponseSchema, } from './hooks/useRecommendedLessonDetails';
|
|
175
177
|
export type { UseRecommendedLessonDetailsState, UseRecommendedLessonDetailsReturn, LessonDetailsApiClient, } from './hooks/useRecommendedLessonDetails';
|
|
176
178
|
export { GoalApiStatus, GoalDisplayStatus, GoalBadgeActionType, getGoalStatusBadgeAction, GOAL_FILTER_STATUS_OPTIONS, GOAL_STATUS_OPTIONS, StudentLessonStatus, getStudentStatusBadgeAction, isDeadlinePassed, deriveStudentStatus, formatDaysToComplete, GoalDraftType, GOAL_ACTIVITY_STATUS, } from './types/recommendedLessons';
|