analytica-frontend-lib
Version:
Repositório público dos componentes utilizados nas plataformas da Analytica Ensino
428 lines (426 loc) • 14.6 kB
JavaScript
import {
loadCategoriesData,
useDynamicStudentFetching
} from "./chunk-5WLR5TLU.mjs";
// src/hooks/useRecommendedLessonsPage.ts
import { useCallback, useRef, useMemo, useState } from "react";
var buildQueryParams = (filters) => {
if (!filters) return {};
const params = {};
for (const key in filters) {
const value = filters[key];
if (value !== void 0 && value !== null) {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
params[key] = value;
}
}
}
return params;
};
var getSchoolOptions = (userData) => {
if (!userData?.userInstitutions) return [];
const schoolMap = /* @__PURE__ */ new Map();
userData.userInstitutions.forEach((inst) => {
if (inst.school?.id && inst.school?.name) {
schoolMap.set(inst.school.id, inst.school.name);
}
});
return Array.from(schoolMap.entries()).map(([id, name]) => ({ id, name }));
};
var getClassOptions = (userData) => {
if (!userData?.userInstitutions) return [];
const classMap = /* @__PURE__ */ new Map();
userData.userInstitutions.forEach((inst) => {
if (inst.class?.id && inst.class?.name) {
classMap.set(inst.class.id, inst.class.name);
}
});
return Array.from(classMap.entries()).map(([id, name]) => ({ id, name }));
};
var getSubjectOptions = (userData) => {
if (!userData?.subTeacherTopicClasses) return [];
const subjectMap = /* @__PURE__ */ new Map();
userData.subTeacherTopicClasses.forEach((stc) => {
if (stc.subject?.id && stc.subject?.name) {
subjectMap.set(stc.subject.id, stc.subject.name);
}
});
return Array.from(subjectMap.entries()).map(([id, name]) => ({ id, name }));
};
var getSchoolYearOptions = (userData) => {
if (!userData?.userInstitutions) return [];
const yearMap = /* @__PURE__ */ new Map();
userData.userInstitutions.forEach((inst) => {
if (inst.schoolYear?.id && inst.schoolYear?.name) {
yearMap.set(inst.schoolYear.id, inst.schoolYear.name);
}
});
return Array.from(yearMap.entries()).map(([id, name]) => ({ id, name }));
};
var toFilterArray = (m) => Array.from(m.entries()).map(([id, name]) => ({ id, name }));
var collectBreakdownData = (b, schoolMap, classMap, schoolYearMap) => {
if (b.schoolId && b.schoolName) {
schoolMap.set(b.schoolId, b.schoolName);
}
if (b.classId && b.className) {
classMap.set(b.classId, b.className);
}
if (b.schoolYearId && b.schoolYearName) {
schoolYearMap.set(b.schoolYearId, b.schoolYearName);
}
};
var extractMapsFromItems = (items) => {
const schoolMap = /* @__PURE__ */ new Map();
const classMap = /* @__PURE__ */ new Map();
const subjectMap = /* @__PURE__ */ new Map();
const schoolYearMap = /* @__PURE__ */ new Map();
for (const item of items) {
if (item.subject?.id && item.subject?.name) {
subjectMap.set(item.subject.id, item.subject.name);
}
for (const b of item.breakdown) {
collectBreakdownData(b, schoolMap, classMap, schoolYearMap);
}
}
return { schoolMap, classMap, subjectMap, schoolYearMap };
};
var extractSubjectsFromDraftItems = (drafts) => {
const subjectMap = /* @__PURE__ */ new Map();
for (const draft of drafts) {
if (draft.subject?.id && draft.subject?.name) {
subjectMap.set(draft.subject.id, draft.subject.name);
}
}
return Array.from(subjectMap.entries()).map(([id, name]) => ({ id, name }));
};
var hasMapChanged = (merged, prev) => {
if (merged.size !== prev.length) return true;
return prev.some((item) => merged.get(item.id) !== item.name);
};
var mergeFilterData = (prev, maps) => {
const mergedSchools = new Map([
...prev.schools.map((s) => [s.id, s.name]),
...maps.schoolMap
]);
const mergedClasses = new Map([
...prev.classes.map((c) => [c.id, c.name]),
...maps.classMap
]);
const mergedSubjects = new Map([
...prev.subjects.map((s) => [s.id, s.name]),
...maps.subjectMap
]);
const mergedSchoolYears = new Map([
...prev.schoolYears.map((y) => [y.id, y.name]),
...maps.schoolYearMap
]);
if (!hasMapChanged(mergedSchools, prev.schools) && !hasMapChanged(mergedClasses, prev.classes) && !hasMapChanged(mergedSubjects, prev.subjects) && !hasMapChanged(mergedSchoolYears, prev.schoolYears)) {
return prev;
}
return {
schools: toFilterArray(mergedSchools),
classes: toFilterArray(mergedClasses),
subjects: toFilterArray(mergedSubjects),
schoolYears: toFilterArray(mergedSchoolYears)
};
};
var mergeFilterOptions = (base, extra) => {
if (extra.length === 0) return base;
const baseIds = new Set(base.map((item) => item.id));
const hasNew = extra.some((item) => !baseIds.has(item.id));
if (!hasNew) return base;
const map = new Map(base.map((item) => [item.id, item.name]));
extra.forEach((item) => {
if (!map.has(item.id)) {
map.set(item.id, item.name);
}
});
return Array.from(map.entries()).map(([id, name]) => ({ id, name }));
};
var createUseRecommendedLessonsPage = (config) => {
const {
api,
navigate,
userData,
paths,
endpoints,
texts,
emptyStateImage,
noSearchImage,
mapSubjectNameToEnum,
extraFilterCategories
} = config;
return () => {
const recommendedClassMapRef = useRef(/* @__PURE__ */ new Map());
const [historyFilterData, setHistoryFilterData] = useState(
{
schools: [],
classes: [],
subjects: [],
schoolYears: []
}
);
const [sendModalOpen, setSendModalOpen] = useState(false);
const [selectedModel, setSelectedModel] = useState(null);
const [sendModalLoading, setSendModalLoading] = useState(false);
const [sendModalCategories, setSendModalCategories] = useState([]);
const userFilterData = useMemo(() => {
const baseSchools = getSchoolOptions(userData);
const baseClasses = getClassOptions(userData);
const baseSubjects = getSubjectOptions(userData);
const baseSchoolYears = getSchoolYearOptions(userData);
return {
schools: mergeFilterOptions(baseSchools, historyFilterData.schools),
classes: mergeFilterOptions(baseClasses, historyFilterData.classes),
subjects: mergeFilterOptions(baseSubjects, historyFilterData.subjects),
schoolYears: mergeFilterOptions(
baseSchoolYears,
historyFilterData.schoolYears
)
};
}, [userData, historyFilterData]);
const subjectsMap = useMemo(() => {
const map = /* @__PURE__ */ new Map();
userFilterData.subjects.forEach((s) => {
map.set(s.id, s.name);
});
return map;
}, [userFilterData.subjects]);
const extractFilterDataFromHistory = useCallback(
(items) => {
const maps = extractMapsFromItems(items);
setHistoryFilterData((prev) => mergeFilterData(prev, maps));
},
[]
);
const fetchRecommendedClassHistory = useCallback(
async (filters) => {
const params = buildQueryParams(filters);
const response = await api.get(
endpoints.recommendedClassHistory,
{ params }
);
const items = response.data.data.recommendedClass;
items.forEach((item) => {
recommendedClassMapRef.current.set(item.recommendedClass.id, item);
});
extractFilterDataFromHistory(items);
return response.data;
},
[api, endpoints.recommendedClassHistory, extractFilterDataFromHistory]
);
const fetchRecommendedClassModels = useCallback(
async (filters) => {
const params = buildQueryParams({
...filters,
type: "MODELO" /* MODELO */
});
const response = await api.get(
endpoints.recommendedClassDrafts,
{ params }
);
const subjects = extractSubjectsFromDraftItems(
response.data.data.drafts
);
if (subjects.length > 0) {
setHistoryFilterData((prev) => ({
...prev,
subjects: mergeFilterOptions(prev.subjects, subjects)
}));
}
return response.data;
},
[api, endpoints.recommendedClassDrafts]
);
const deleteRecommendedClassModel = useCallback(
async (id) => {
await api.delete(`${endpoints.recommendedClassDrafts}/${id}`);
},
[api, endpoints.recommendedClassDrafts]
);
const fetchRecommendedClassDrafts = useCallback(
async (filters) => {
const params = buildQueryParams({
...filters,
type: "RASCUNHO" /* RASCUNHO */
});
const response = await api.get(
endpoints.recommendedClassDrafts,
{ params }
);
const subjects = extractSubjectsFromDraftItems(
response.data.data.drafts
);
if (subjects.length > 0) {
setHistoryFilterData((prev) => ({
...prev,
subjects: mergeFilterOptions(prev.subjects, subjects)
}));
}
return response.data;
},
[api, endpoints.recommendedClassDrafts]
);
const deleteRecommendedClassDraft = useCallback(
async (id) => {
await api.delete(`${endpoints.recommendedClassDrafts}/${id}`);
},
[api, endpoints.recommendedClassDrafts]
);
const handleCreateLesson = useCallback(() => {
navigate(paths.createLesson);
}, []);
const handleCreateModel = useCallback(() => {
navigate(paths.createModel);
}, []);
const handleRowClick = useCallback((row) => {
const originalData = recommendedClassMapRef.current.get(row.id);
navigate(`${paths.lessonDetails}/${row.id}`, {
state: { recommendedClassData: originalData }
});
}, []);
const deleteRecommendedClass = useCallback(
async (id) => {
await api.delete(`${endpoints.submitRecommendedClass}/${id}`);
},
[api, endpoints.submitRecommendedClass]
);
const updateRecommendedClass = useCallback(
async (id, data) => {
await api.patch(`${endpoints.submitRecommendedClass}/${id}`, data);
},
[api, endpoints.submitRecommendedClass]
);
const fetchRecommendedClassById = useCallback(
async (id) => {
const response = await api.get(
`${endpoints.submitRecommendedClass}/${id}`
);
return response.data.data;
},
[api, endpoints.submitRecommendedClass]
);
const handleEditModel = useCallback(
(model) => {
navigate(`${paths.editModel}${model.id}`);
},
[]
);
const handleSendLesson = useCallback(
async (model) => {
setSelectedModel(model);
try {
const categories = await loadCategoriesData(api, []);
setSendModalCategories(categories);
} catch (error) {
console.error("Erro ao carregar destinat\xE1rios:", error);
setSendModalCategories([]);
}
setSendModalOpen(true);
},
[api]
);
const handleSendLessonSubmit = useCallback(
async (formData) => {
if (!selectedModel) return;
setSendModalLoading(true);
try {
const draftResponse = await api.get(`${endpoints.recommendedClassDrafts}/${selectedModel.id}`);
const draft = draftResponse.data.data;
const lessonIds = (draft.lessons ?? []).map((lesson, index) => ({
lessonId: lesson.lessonId,
sequence: index + 1
}));
const activityDraftIds = (draft.activityDrafts ?? []).map(
(activity, index) => ({
activityDraftId: activity.activityDraftId,
sequence: index + 1
})
);
const hasAttachedActivities = activityDraftIds.length > 0;
await api.post(endpoints.submitRecommendedClass, {
title: formData.title || selectedModel.title,
startDate: (/* @__PURE__ */ new Date(
`${formData.startDate}T${formData.startTime}`
)).toISOString(),
finalDate: (/* @__PURE__ */ new Date(
`${formData.finalDate}T${formData.finalTime}`
)).toISOString(),
lessonIds,
...hasAttachedActivities && { activityDraftIds },
targetStudentIds: formData.students.map((s) => s.userInstitutionId),
...formData.notification && {
notification: formData.notification
},
...hasAttachedActivities && {
canRetry: formData.canRetry ?? false
}
});
setSendModalOpen(false);
setSelectedModel(null);
} finally {
setSendModalLoading(false);
}
},
[
api,
endpoints.recommendedClassDrafts,
endpoints.submitRecommendedClass,
selectedModel
]
);
const handleSendModalClose = useCallback(() => {
setSendModalOpen(false);
setSelectedModel(null);
}, []);
const { handleCategoriesChange } = useDynamicStudentFetching(
setSendModalCategories,
{ apiClient: api }
);
return {
historyProps: {
fetchRecommendedClassHistory,
fetchRecommendedClassModels,
deleteRecommendedClassModel,
onCreateLesson: handleCreateLesson,
onCreateModel: handleCreateModel,
onRowClick: handleRowClick,
deleteRecommendedClass,
updateRecommendedClass,
fetchRecommendedClassById,
onEditModel: handleEditModel,
onSendLesson: handleSendLesson,
fetchRecommendedClassDrafts,
deleteRecommendedClassDraft,
onSendDraft: handleSendLesson,
onEditDraft: handleEditModel,
emptyStateImage,
noSearchImage,
mapSubjectNameToEnum,
userFilterData,
subjectsMap,
title: texts.title,
createButtonText: texts.createButtonText,
searchPlaceholder: texts.searchPlaceholder,
extraFilterCategories
},
modalProps: {
isOpen: sendModalOpen,
onClose: handleSendModalClose,
onSubmit: handleSendLessonSubmit,
categories: sendModalCategories,
onCategoriesChange: handleCategoriesChange,
isLoading: sendModalLoading,
modalTitle: selectedModel?.title,
hasAttachedActivities: (selectedModel?.activityDraftsCount ?? 0) > 0
},
navigate
};
};
};
var createRecommendedLessonsPageHook = createUseRecommendedLessonsPage;
export {
createUseRecommendedLessonsPage,
createRecommendedLessonsPageHook
};
//# sourceMappingURL=chunk-HFY4S3JV.mjs.map