UNPKG

analytica-frontend-lib

Version:

Repositório público dos componentes utilizados nas plataformas da Analytica Ensino

1,709 lines (1,690 loc) 708 kB
import { renderSubjectCell } from "./chunk-4CJLURKO.mjs"; import { mapSubjectNameToEnum } from "./chunk-GVGQ7EUU.mjs"; import { PERIOD_TABS } from "./chunk-NPDKLMTS.mjs"; import { TypeSelector_default } from "./chunk-Z7PV3KSQ.mjs"; import { createActivityCategoryConfig } from "./chunk-3SHJQQCA.mjs"; import { EXAM_STATUS_OPTIONS } from "./chunk-P7FCUXDE.mjs"; import { AreaKnowledgeSelector, ESSAY_AREA_ID, GeneralOverviewSection, PERFORMANCE_TAG_TO_BADGE_ACTION, SIMULATED_PERFORMANCE_TAG_CONFIG, SimulatedStudentDetailsModal, isClassesData, isMunicipalitiesData, isStudentsData } from "./chunk-XEYCESHY.mjs"; import { useModulesStore } from "./chunk-KSJOLTXH.mjs"; import { PeriodSelector } from "./chunk-I3TCUZIY.mjs"; import { AnswerSheetCard, CardContainer, PageContainer as PageContainer2, PrintStyles } from "./chunk-OWNZKDMR.mjs"; import { examsTableColumns } from "./chunk-5SP2WHVJ.mjs"; import { renderTextCell } from "./chunk-RL26IDPE.mjs"; import { areSelectedIdsEqual, calculateFormattedItemsForAutoSelection, getBadgeText, handleAccordionValueChange, isCategoryEnabled, useTableFilter } from "./chunk-45LJRS7N.mjs"; import { useAlertFormStore } from "./chunk-IQEDRSDD.mjs"; import { questionTypeLabels } from "./chunk-GRGWBD7V.mjs"; import { useAuthStore } from "./chunk-TNOKCEMB.mjs"; import { createUseActivitiesHistory } from "./chunk-BMJTQFRE.mjs"; import { getClassOptionsFromUserData, getSchoolOptionsFromUserData, getSchoolYearOptionsFromUserData, getSubjectOptionsFromUserData, mergeFilterOptions } from "./chunk-XRPLT7ML.mjs"; import { createUseActivityModels } from "./chunk-F44EAWVH.mjs"; import { ACTIVITY_FILTER_STATUS_OPTIONS, getActivityStatusBadgeAction } from "./chunk-DJG7DLCI.mjs"; import { createUseRecommendedLessonsHistory } from "./chunk-KP6KKVAB.mjs"; import { formatTime, loadCategoriesData, useDynamicStudentFetching } from "./chunk-5WLR5TLU.mjs"; import { createUseRecommendedClassDrafts, createUseRecommendedClassModels } from "./chunk-3DZ6JVFL.mjs"; import { RECOMMENDED_CLASS_FILTER_STATUS_OPTIONS, getRecommendedClassStatusBadgeAction } from "./chunk-FD4UD2X5.mjs"; import { createUseSimulations } from "./chunk-37WFJLC5.mjs"; import { extractStudentsFromCategories, useSendActivityModalStore } from "./chunk-MMCTPGXO.mjs"; import { validateActivityStep, validateDeadlineStep } from "./chunk-MSG5POSR.mjs"; import { ACTIVITY_MODE_OPTIONS, ACTIVITY_TYPE_OPTIONS, ActivitySubtype } from "./chunk-GMYYB6A2.mjs"; import { Toaster_default, useToast } from "./chunk-L2AMPFWU.mjs"; import { useUrlAuthentication } from "./chunk-S6C2Q522.mjs"; import { useApiConfig } from "./chunk-KMVBJFFX.mjs"; import { createUseQuestionsList } from "./chunk-EHORXGFK.mjs"; import { PageContainer } from "./chunk-GNLZTQRR.mjs"; import { VideoPlayer_default } from "./chunk-5XJWMPI4.mjs"; import { Whiteboard_default } from "./chunk-6TUOCZ7Y.mjs"; import { ImageUpload } from "./chunk-IPVIZIHN.mjs"; import { useAuth } from "./chunk-VQTRDBGR.mjs"; import { AlertDialog } from "./chunk-6E2SCKRJ.mjs"; import { Calendar_default } from "./chunk-YPQFSNET.mjs"; import { Stepper_default } from "./chunk-4QZWLI7Q.mjs"; import { useMobile } from "./chunk-GKY77WVA.mjs"; import { CorrectActivityModal_default, QUESTION_STATUS, convertApiResponseToCorrectionData, getQuestionStatusBadgeConfig, renderFromMap } from "./chunk-3UWJRI7S.mjs"; import { StatCard } from "./chunk-3ZYHNRVG.mjs"; import { AccordionGroup } from "./chunk-ILCBSWZF.mjs"; import { ToastStore_default } from "./chunk-OAP6DJKU.mjs"; import { CardAccordation } from "./chunk-2ACDTDO4.mjs"; import { highlightSearchTerm, normalizeText, stripHtmlTags } from "./chunk-C6FDFF3W.mjs"; import { prependLetterToHtml } from "./chunk-DDZDNGBU.mjs"; import { AlternativesList } from "./chunk-TUJ3CWS2.mjs"; import { MultipleChoiceList } from "./chunk-PZ2H7EXH.mjs"; import { HtmlMathRenderer_default, stripHtml } from "./chunk-FN4G43WK.mjs"; import { CardAudio } from "./chunk-R7FP73MH.mjs"; import { TextArea_default } from "./chunk-LI2FS7M2.mjs"; import { Toast_default } from "./chunk-YGF3KVWG.mjs"; import { TruncatedText } from "./chunk-2P7LJCTW.mjs"; import { Menu, MenuContent, MenuItem, MenuOverflow, Menu_default } from "./chunk-WI3GQX74.mjs"; import { RadioGroup, RadioGroupItem, Radio_default } from "./chunk-NLK3GG73.mjs"; import { SelectContent, SelectItem, SelectTrigger, SelectValue, Select_default } from "./chunk-UU7Q5S52.mjs"; import { TableBody, TableCell, TableHead, TableRow, Table_default, useTableSort } from "./chunk-66F2QDAX.mjs"; import { EmptyState_default } from "./chunk-6WVHF7N3.mjs"; import { Skeleton, SkeletonCard, SkeletonRounded, SkeletonTable, SkeletonText } from "./chunk-NKVUUWCA.mjs"; import { TablePagination_default } from "./chunk-JYLO3IQT.mjs"; import { SimplePieChart } from "./chunk-Y4MZ2KAU.mjs"; import { ProgressBar_default } from "./chunk-LDBWF6EA.mjs"; import { IconButton_default } from "./chunk-LGQNMQOT.mjs"; import { IconRender_default } from "./chunk-QEZJZHJG.mjs"; import { Input_default } from "./chunk-EXVVHZOO.mjs"; import { LatexRenderer_default } from "./chunk-NNUCT5IL.mjs"; import { getSubjectInfo } from "./chunk-3ERLYM6Y.mjs"; import { Search_default } from "./chunk-YMDK7D7Z.mjs"; import { Alert_default } from "./chunk-YQTOSHD5.mjs"; import { Badge_default } from "./chunk-OEW3ST4F.mjs"; import { CheckBox_default } from "./chunk-VDUO65VK.mjs"; import { Chips_default } from "./chunk-TVFP3HZX.mjs"; import { Divider_default } from "./chunk-VN4ORBHU.mjs"; import { DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, DropdownMenu_default } from "./chunk-DHHHYBOU.mjs"; import { useTheme } from "./chunk-HYVBZ5EV.mjs"; import { SelectionButton_default } from "./chunk-W46HZ2AP.mjs"; import { Modal_default } from "./chunk-TNLGS7SB.mjs"; import { Button_default } from "./chunk-LAYB7IKW.mjs"; import { Text_default } from "./chunk-IMCIR6TJ.mjs"; import { areFiltersEqual, arraysEqual, cn, deriveYearIdsFromBankIds, formatPercentageRounded, formatScore, getSelectedIdsFromCategories, getSubjectColorWithOpacity, mapQuestionTypeToEnum, mapQuestionTypeToEnumRequired, mergeYearIdsForSelectedBanks, toggleArrayItem, toggleSingleValue } from "./chunk-53ICLDGS.mjs"; import { formatActivityDateToBrazilian, formatDateToBrazilian, formatQuestionNumbers, formatTimeSpent, getStatusBadgeConfig } from "./chunk-YG7W6JE3.mjs"; import { STUDENT_ACTIVITY_STATUS } from "./chunk-AYI25BJ2.mjs"; import { GenericApiStatus, GenericDisplayStatus } from "./chunk-DG76FRXG.mjs"; import { QUESTION_TYPE } from "./chunk-G7IP4VLI.mjs"; // src/components/CheckBoxGroup/CheckBoxGroup.tsx import { useEffect as useEffect44, useMemo as useMemo43, useRef as useRef35, useState as useState46 } from "react"; // src/components/AlertManager/AlertsManager.tsx import { useState as useState3, useEffect as useEffect5, useMemo as useMemo4, useCallback as useCallback2, useSyncExternalStore, useRef as useRef3 } from "react"; import { CaretLeftIcon as CaretLeftIcon2 } from "@phosphor-icons/react/dist/csr/CaretLeft"; import { CaretRightIcon } from "@phosphor-icons/react/dist/csr/CaretRight"; import { PaperPlaneTiltIcon as PaperPlaneTiltIcon2 } from "@phosphor-icons/react/dist/csr/PaperPlaneTilt"; // src/components/AlertManager/AlertSteps/MessageStep.tsx import { useState } from "react"; import { useShallow } from "zustand/react/shallow"; import { jsx, jsxs } from "react/jsx-runtime"; var ACCEPTED_IMAGE_EXTENSIONS = ".jpg,.jpeg,.png,.gif,.webp,.svg"; var MAX_IMAGE_SIZE_BYTES = 5 * 1024 * 1024; var MAX_IMAGE_SIZE_LABEL = "5MB"; var MessageStep = ({ labels, allowImageAttachment = true }) => { const [imageError, setImageError] = useState(null); const { title, message, image, setTitle, setMessage, setImage } = useAlertFormStore( useShallow((state) => ({ title: state.title, message: state.message, image: state.image, setTitle: state.setTitle, setMessage: state.setMessage, setImage: state.setImage })) ); const handleFileSelect = (file) => { setImageError(null); setImage(file); }; const handleRemoveFile = () => { setImageError(null); setImage(null); }; const handleTypeError = () => { setImageError( "Formato de imagem n\xE3o suportado. Use jpg, jpeg, png, gif, webp ou svg." ); }; const handleSizeError = () => { setImageError( `Imagem muito grande. O tamanho m\xE1ximo permitido \xE9 ${MAX_IMAGE_SIZE_LABEL}.` ); }; const isImageFile = image instanceof File; return /* @__PURE__ */ jsxs("section", { className: "flex flex-col gap-4", children: [ /* @__PURE__ */ jsx( Input_default, { required: true, label: labels?.titleLabel || "T\xEDtulo", placeholder: labels?.titlePlaceholder || "Digite o t\xEDtulo do aviso", variant: "rounded", value: title, onChange: (e) => setTitle(e.target.value) } ), /* @__PURE__ */ jsx( TextArea_default, { required: true, label: labels?.messageLabel || "Mensagem", placeholder: labels?.messagePlaceholder || "Digite a mensagem do aviso", value: message, onChange: (e) => setMessage(e.target.value) } ), allowImageAttachment && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [ /* @__PURE__ */ jsx( ImageUpload, { selectedFile: isImageFile ? image : null, onFileSelect: handleFileSelect, onRemoveFile: handleRemoveFile, accept: ACCEPTED_IMAGE_EXTENSIONS, maxSize: MAX_IMAGE_SIZE_BYTES, onTypeError: handleTypeError, onSizeError: handleSizeError } ), imageError && /* @__PURE__ */ jsx(Text_default, { size: "sm", className: "text-error-600", role: "alert", children: imageError }) ] }) ] }); }; // src/components/AlertManager/AlertSteps/RecipientsStep.tsx import { useEffect, useMemo } from "react"; import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime"; var RecipientsStep = ({ categories, labels, onCategoriesChange }) => { const { recipientCategories, initializeCategory } = useAlertFormStore(); useEffect(() => { for (const category of categories) { const existingCategory = recipientCategories[category.key]; if (!existingCategory) { initializeCategory({ key: category.key, label: category.label, availableItems: category.itens || [], selectedIds: category.selectedIds || [], allSelected: false }); } } }, [categories, recipientCategories, initializeCategory]); const handleCategoriesChange = (updatedCategories) => { for (const category of updatedCategories) { const selectedIds = category.selectedIds || []; const allSelected = selectedIds.length === (category.itens?.length || 0); initializeCategory({ key: category.key, label: category.label, availableItems: category.itens || [], selectedIds, allSelected }); } if (onCategoriesChange) { onCategoriesChange(updatedCategories); } }; const syncedCategories = useMemo(() => { return categories.map((category) => { const storeCategory = recipientCategories[category.key]; if (storeCategory) { return { ...category, selectedIds: storeCategory.selectedIds }; } return category; }); }, [categories, recipientCategories]); return /* @__PURE__ */ jsxs2("section", { className: "flex flex-col gap-4", children: [ /* @__PURE__ */ jsx2(Text_default, { size: "lg", weight: "medium", className: "text-text-950", children: labels?.recipientsDescription || "Para quem voc\xEA vai enviar o aviso?" }), /* @__PURE__ */ jsx2( CheckboxGroup, { categories: syncedCategories, onCategoriesChange: handleCategoriesChange } ) ] }); }; // src/components/AlertManager/AlertSteps/DateStep.tsx import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime"; var DateStep = ({ labels, allowScheduling = true, allowEmailCopy = true }) => { const date = useAlertFormStore((state) => state.date); const time = useAlertFormStore((state) => state.time); const sendToday = useAlertFormStore((state) => state.sendToday); const sendCopyToEmail = useAlertFormStore((state) => state.sendCopyToEmail); const setDate = useAlertFormStore((state) => state.setDate); const setTime = useAlertFormStore((state) => state.setTime); const setSendToday = useAlertFormStore((state) => state.setSendToday); const setSendCopyToEmail = useAlertFormStore( (state) => state.setSendCopyToEmail ); return /* @__PURE__ */ jsxs3("section", { className: "flex flex-col gap-4", children: [ /* @__PURE__ */ jsxs3("span", { className: "flex flex-row items-center gap-6", children: [ /* @__PURE__ */ jsx3( Text_default, { weight: "normal", className: "cursor-pointer select-none leading-[150%] flex items-center font-roboto", children: labels?.sendTodayLabel || "Enviar Hoje?" } ), /* @__PURE__ */ jsx3( CheckBox_default, { label: "Sim", checked: sendToday, onChange: (e) => setSendToday(e.target.checked) } ) ] }), allowScheduling && /* @__PURE__ */ jsx3( DateTimeInput_default, { label: labels?.dateLabel || "Data de envio", date, time, onDateChange: setDate, onTimeChange: setTime, disabled: sendToday, timeLabel: labels?.timeLabel || "Hora de envio", testId: "alert-datetime" } ), allowEmailCopy && /* @__PURE__ */ jsx3( CheckBox_default, { label: labels?.sendCopyToEmailLabel || "Enviar c\xF3pia para e-mail", checked: sendCopyToEmail, onChange: (e) => setSendCopyToEmail(e.target.checked) } ) ] }); }; // src/components/AlertManager/AlertSteps/PreviewStep.tsx import { useMemo as useMemo2, useEffect as useEffect2 } from "react"; import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime"; var PreviewStep = ({ imageLink, defaultImage }) => { const title = useAlertFormStore((state) => state.title); const message = useAlertFormStore((state) => state.message); const image = useAlertFormStore((state) => state.image); const imageUrl = useMemo2(() => { if (globalThis.window === void 0) { return void 0; } if (image instanceof File) { return globalThis.window.URL.createObjectURL(image); } if (typeof image === "string") { return image; } return void 0; }, [image]); useEffect2(() => { return () => { if (globalThis.window !== void 0 && imageUrl && image instanceof File) { URL.revokeObjectURL(imageUrl); } }; }, [imageUrl, image]); const finalImageUrl = imageLink || imageUrl || defaultImage || void 0; return /* @__PURE__ */ jsx4("section", { className: "flex flex-col gap-4", children: /* @__PURE__ */ jsxs4("div", { className: "bg-background-50 px-5 py-6 flex flex-col items-center gap-4 rounded-xl", children: [ finalImageUrl && /* @__PURE__ */ jsx4("img", { src: finalImageUrl, alt: title || "Imagem do alerta" }), /* @__PURE__ */ jsxs4("div", { className: "flex flex-col items-center text-center gap-3", children: [ /* @__PURE__ */ jsx4(Text_default, { size: "lg", weight: "semibold", children: title || "Nenhum T\xEDtulo de Alerta" }), /* @__PURE__ */ jsx4(Text_default, { size: "sm", weight: "normal", className: "text-text-500", children: message || "Aqui aparecer\xE1 a mensagem do alerta definido pelo usu\xE1rio" }) ] }) ] }) }); }; // src/components/AlertManager/validation.ts var BASE_STEPS_COUNT = 4; var validateMessageStep = (formData) => { if (!formData.title?.trim()) return "T\xEDtulo \xE9 obrigat\xF3rio"; if (!formData.message?.trim()) return "Mensagem \xE9 obrigat\xF3ria"; return true; }; var validateRecipientsStep = (categories) => { if (categories.length === 0) return "Nenhuma categoria configurada"; const lastCategory = categories[categories.length - 1]; if (!lastCategory?.selectedIds?.length) return "Selecione destinat\xE1rios"; return true; }; var validateDateStep = (formData) => { if (formData.sendToday) return true; if (!formData.date) return "Data \xE9 obrigat\xF3ria"; if (!formData.time) return "Hora \xE9 obrigat\xF3ria"; return true; }; var canFinish = (formData, categories) => { return validateMessageStep(formData) === true && validateRecipientsStep(categories) === true && validateDateStep(formData) === true; }; var isCurrentStepValid = (currentStep, formData, categories, customSteps) => { return validateCurrentStep(currentStep, formData, categories, customSteps) === true; }; var validateCurrentStep = (currentStep, formData, categories, customSteps) => { switch (currentStep) { case 0: return validateMessageStep(formData); case 1: return validateRecipientsStep(categories); case 2: return validateDateStep(formData); case 3: return true; default: { const currentStepConfig = customSteps?.[currentStep - BASE_STEPS_COUNT]; return currentStepConfig?.validate ? currentStepConfig.validate(formData) : true; } } }; var advanceToNextStep = (currentStep, completedSteps, setCompletedSteps, setCurrentStep) => { if (setCompletedSteps && !completedSteps.includes(currentStep)) { setCompletedSteps([...completedSteps, currentStep]); } if (setCurrentStep) { setCurrentStep(currentStep + 1); } }; var handleNext = ({ currentStep, steps, formData, categories, customSteps, completedSteps = [], setCompletedSteps, setCurrentStep }) => { if (currentStep >= steps.length - 1) { return { success: false, error: "J\xE1 est\xE1 no \xFAltimo step" }; } const validation = validateCurrentStep( currentStep, formData, categories, customSteps ); if (validation !== true) { console.error("Valida\xE7\xE3o falhou:", validation); const errorMessage = typeof validation === "string" ? validation : "Preencha todos os campos obrigat\xF3rios"; return { success: false, error: errorMessage }; } advanceToNextStep( currentStep, completedSteps, setCompletedSteps, setCurrentStep ); return { success: true }; }; // src/components/shared/SendModalBase/utils/applyChainedAutoSelection.ts function applyChainedAutoSelection(categories) { let current = categories; let safety = 0; let changed = true; while (changed && safety < categories.length + 2) { safety += 1; changed = false; const next = current.map((category) => { const filteredItems = calculateFormattedItemsForAutoSelection( category, current ); const hasNoSelection = !category.selectedIds || category.selectedIds.length === 0; if (filteredItems.length === 1 && hasNoSelection) { changed = true; return { ...category, selectedIds: [filteredItems[0].id] }; } return category; }); current = next; } return current; } // src/components/shared/SendModalBase/hooks/useDateTimeHandlers.ts import { useCallback } from "react"; function useDateTimeHandlers({ setFormData }) { const handleStartDateChange = useCallback( (value) => { setFormData({ startDate: value }); }, [setFormData] ); const handleStartTimeChange = useCallback( (value) => { setFormData({ startTime: value }); }, [setFormData] ); const handleFinalDateChange = useCallback( (value) => { setFormData({ finalDate: value }); }, [setFormData] ); const handleFinalTimeChange = useCallback( (value) => { setFormData({ finalTime: value }); }, [setFormData] ); return { handleStartDateChange, handleStartTimeChange, handleFinalDateChange, handleFinalTimeChange }; } // src/components/shared/SendModalBase/hooks/useCategoryInitialization.ts import { useEffect as useEffect3, useRef } from "react"; function useCategoryInitialization({ isOpen, initialCategories, setCategories, onCategoriesChange }) { const categoriesInitialized = useRef(false); useEffect3(() => { if (isOpen && initialCategories.length > 0 && !categoriesInitialized.current) { const autoSelectedCategories = applyChainedAutoSelection(initialCategories); setCategories(autoSelectedCategories); if (onCategoriesChange) { onCategoriesChange(autoSelectedCategories); } categoriesInitialized.current = true; } }, [isOpen, initialCategories, setCategories, onCategoriesChange]); useEffect3(() => { if (!isOpen) { categoriesInitialized.current = false; } }, [isOpen]); return { categoriesInitializedRef: categoriesInitialized }; } // src/components/shared/SendModalBase/hooks/useCategorySync.ts import { useEffect as useEffect4 } from "react"; var DYNAMIC_KEYS = ["turma", "students"]; function dynamicItemsSignature(categories) { return DYNAMIC_KEYS.map((key) => { const category = categories.find((c) => c.key === key); const ids = (category?.itens ?? []).map((item) => item.id).join(","); return `${key}:${ids}`; }).join("|"); } function useCategorySync({ isOpen, initialCategories, storeCategories, setCategories, categoriesInitializedRef }) { useEffect4(() => { if (isOpen && initialCategories.length > 0 && categoriesInitializedRef.current) { if (dynamicItemsSignature(initialCategories) !== dynamicItemsSignature(storeCategories)) { setCategories(initialCategories); } } }, [ isOpen, initialCategories, storeCategories, setCategories, categoriesInitializedRef ]); } // src/components/shared/SendModalBase/components/SendModalError.tsx import { WarningCircleIcon } from "@phosphor-icons/react/dist/csr/WarningCircle"; import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime"; var SendModalError = ({ error, testId, className }) => { if (!error) return null; return /* @__PURE__ */ jsxs5( Text_default, { as: "p", size: "sm", color: "text-error-600", className: `flex items-center gap-1 mt-1 ${className || ""}`, "data-testid": testId, "aria-live": "polite", children: [ /* @__PURE__ */ jsx5(WarningCircleIcon, { size: 16 }), error ] } ); }; // src/components/shared/SendModalBase/components/RecipientStep.tsx import { useMemo as useMemo3 } from "react"; import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime"; var RecipientStep = ({ categories, onCategoriesChange, entityNameWithArticle, studentsError, testIdPrefix }) => { const categoriesWithSearch = useMemo3( () => categories.map( (category) => category.key === "students" ? { ...category, searchable: true } : category ), [categories] ); return /* @__PURE__ */ jsxs6( "div", { className: "flex flex-col gap-4 min-h-0 flex-1", "data-testid": testIdPrefix ? `${testIdPrefix}-recipient-step` : void 0, children: [ /* @__PURE__ */ jsxs6( Text_default, { size: "sm", weight: "medium", color: "text-text-700", className: "flex-shrink-0", children: [ "Para quem voc\xEA vai enviar ", entityNameWithArticle, "?" ] } ), /* @__PURE__ */ jsx6( "div", { className: cn( "flex-1 min-h-0 overflow-y-auto", "scrollbar-thin scrollbar-thumb-border-300 scrollbar-track-transparent" ), "data-testid": testIdPrefix ? `${testIdPrefix}-scroll-container` : "scroll-container", children: /* @__PURE__ */ jsx6( CheckboxGroup, { categories: categoriesWithSearch, onCategoriesChange, compactSingleItem: true, showDivider: true } ) } ), /* @__PURE__ */ jsx6( SendModalError, { error: studentsError, testId: testIdPrefix ? `${testIdPrefix}-students-error` : void 0, className: "flex-shrink-0" } ) ] } ); }; // src/components/DateTimeInput/DateTimeInput.tsx import { useRef as useRef2, useState as useState2 } from "react"; import { CalendarBlankIcon } from "@phosphor-icons/react/dist/csr/CalendarBlank"; import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime"; var formatDateToInput = (dateObj) => { const year = dateObj.getFullYear(); const month = String(dateObj.getMonth() + 1).padStart(2, "0"); const day = String(dateObj.getDate()).padStart(2, "0"); return `${year}-${month}-${day}`; }; var DateTimeInput = ({ label, date, time, onDateChange, onTimeChange, errorMessage, disabled = false, defaultTime = "00:00", testId, timeLabel = "Hora", className }) => { const [isCalendarOpen, setIsCalendarOpen] = useState2(false); const [selectedDate, setSelectedDate] = useState2( date ? /* @__PURE__ */ new Date(`${date}T12:00:00`) : void 0 ); const triggerRef = useRef2(null); const handleDateSelect = (dateObj) => { setSelectedDate(dateObj); onDateChange(formatDateToInput(dateObj)); if (!time) { onTimeChange(defaultTime); } }; const handleDateInputChange = (e) => { const value = e.target.value; if (value.includes("T")) { const [datePart, timePart] = value.split("T"); onDateChange(datePart); if (timePart) { onTimeChange(timePart); } } else { onDateChange(value); } if (value) { const dateValue = value.includes("T") ? value : `${value}T12:00:00`; const dateObj = new Date(dateValue); if (!Number.isNaN(dateObj.getTime())) { setSelectedDate(dateObj); } } }; const handleTimeChange = (e) => { onTimeChange(e.target.value); }; const inputValue = date ? `${date}T${time || defaultTime}` : ""; return /* @__PURE__ */ jsxs7( DropdownMenu_default, { open: !disabled && isCalendarOpen, onOpenChange: (open) => { if (!disabled) { setIsCalendarOpen(open); } }, children: [ /* @__PURE__ */ jsx7( DropdownMenuTrigger, { className, ref: triggerRef, disabled, children: /* @__PURE__ */ jsx7( Input_default, { label, type: "datetime-local", placeholder: "00/00/0000", value: inputValue, onChange: handleDateInputChange, variant: "rounded", errorMessage, disabled, "data-testid": testId ? `${testId}-input` : void 0, iconRight: /* @__PURE__ */ jsx7(CalendarBlankIcon, { size: 14 }), className: "[&::-webkit-calendar-picker-indicator]:hidden" } ) } ), /* @__PURE__ */ jsxs7( DropdownMenuContent, { align: "start", className: "p-0 z-[100]", portal: true, triggerRef, children: [ /* @__PURE__ */ jsx7( Calendar_default, { variant: "selection", selectedDate, onDateSelect: handleDateSelect, showActivities: false } ), /* @__PURE__ */ jsx7("div", { className: "p-3 border-t border-border-200", children: /* @__PURE__ */ jsx7( Input_default, { label: timeLabel, type: "time", value: time || defaultTime, onChange: handleTimeChange, variant: "rounded", "data-testid": testId ? `${testId}-time` : void 0 } ) }) ] } ) ] } ); }; var DateTimeInput_default = DateTimeInput; // src/components/shared/SendModalBase/components/DeadlineStep.tsx import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime"; var DeadlineStep = ({ startDate, startTime, finalDate, finalTime, onStartDateChange, onStartTimeChange, onFinalDateChange, onFinalTimeChange, errors, testIdPrefix, children }) => { return /* @__PURE__ */ jsxs8( "div", { className: "flex flex-col gap-4 sm:gap-6 pt-6", "data-testid": testIdPrefix ? `${testIdPrefix}-deadline-step` : void 0, children: [ /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-2 sm:grid sm:grid-cols-2", children: [ /* @__PURE__ */ jsx8( DateTimeInput_default, { label: "Iniciar em*", date: startDate, time: startTime, onDateChange: onStartDateChange, onTimeChange: onStartTimeChange, errorMessage: [errors.startDate, errors.startTime].filter(Boolean).join(" ") || void 0, defaultTime: "00:00", testId: testIdPrefix ? `${testIdPrefix}-start-datetime` : "start-datetime", className: "w-full" } ), /* @__PURE__ */ jsx8( DateTimeInput_default, { label: "Finalizar at\xE9*", date: finalDate, time: finalTime, onDateChange: onFinalDateChange, onTimeChange: onFinalTimeChange, errorMessage: [errors.finalDate, errors.finalTime].filter(Boolean).join(" ") || void 0, defaultTime: "23:59", testId: testIdPrefix ? `${testIdPrefix}-final-datetime` : "final-datetime", className: "w-full" } ) ] }), children ] } ); }; var DeadlineStep_default = DeadlineStep; // src/components/shared/SendModalBase/components/SendModalFooter.tsx import { CaretLeftIcon } from "@phosphor-icons/react/dist/csr/CaretLeft"; import { ArrowRightIcon } from "@phosphor-icons/react/dist/csr/ArrowRight"; import { PaperPlaneTiltIcon } from "@phosphor-icons/react/dist/csr/PaperPlaneTilt"; import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime"; var SendModalFooter = ({ currentStep, maxSteps, isLoading, onCancel, onPreviousStep, onNextStep, onSubmit, entityName, testIdPrefix }) => { const isLastStep = currentStep >= maxSteps; const showPreviousButton = currentStep > 1; return /* @__PURE__ */ jsxs9( "div", { className: "flex flex-col-reverse sm:flex-row items-center justify-between gap-3 w-full", "data-testid": testIdPrefix ? `${testIdPrefix}-footer` : void 0, children: [ /* @__PURE__ */ jsx9( Button_default, { variant: "link", action: "primary", onClick: onCancel, className: "w-full sm:w-auto", "data-testid": testIdPrefix ? `${testIdPrefix}-cancel-button` : void 0, children: "Cancelar" } ), /* @__PURE__ */ jsxs9("div", { className: "flex flex-col-reverse sm:flex-row items-center gap-2 sm:gap-3 w-full sm:w-auto", children: [ showPreviousButton && /* @__PURE__ */ jsx9( Button_default, { variant: "outline", action: "primary", onClick: onPreviousStep, iconLeft: /* @__PURE__ */ jsx9(CaretLeftIcon, { size: 16 }), className: "w-full sm:w-auto", "data-testid": testIdPrefix ? `${testIdPrefix}-previous-button` : void 0, children: "Anterior" } ), isLastStep ? /* @__PURE__ */ jsx9( Button_default, { variant: "solid", action: "primary", onClick: onSubmit, disabled: isLoading, iconLeft: /* @__PURE__ */ jsx9(PaperPlaneTiltIcon, { size: 16 }), className: "w-full sm:w-auto", "data-testid": testIdPrefix ? `${testIdPrefix}-submit-button` : void 0, children: isLoading ? "Enviando..." : `Enviar ${entityName}` } ) : /* @__PURE__ */ jsx9( Button_default, { variant: "solid", action: "primary", onClick: onNextStep, iconRight: /* @__PURE__ */ jsx9(ArrowRightIcon, { size: 16 }), className: "w-full sm:w-auto", "data-testid": testIdPrefix ? `${testIdPrefix}-next-button` : void 0, children: "Pr\xF3ximo" } ) ] }) ] } ); }; // src/components/AlertManager/AlertsManager.tsx import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime"; var StepWrapper = ({ children }) => /* @__PURE__ */ jsx10("div", { children }); var AlertsManager = ({ config, isOpen = false, onClose, imageLink, defaultImage }) => { const [isModalOpen, setIsModalOpen] = useState3(isOpen); const [currentStep, setCurrentStep] = useState3(0); const [completedSteps, setCompletedSteps] = useState3([]); const [categories, setCategories] = useState3(config.categories); const formData = useSyncExternalStore( useAlertFormStore.subscribe, useAlertFormStore.getState ); useEffect5(() => { setIsModalOpen(isOpen); }, [isOpen]); const categoriesInitializedRef = useRef3(false); const { labels, behavior, steps: customSteps } = config; const { handleCategoriesChange: baseHandleCategoriesChange } = useDynamicStudentFetching(setCategories, { fetchStudentsByFilters: behavior?.fetchStudentsByFilters }); const handleCategoriesChange = useCallback2( async (updatedCategories) => { await baseHandleCategoriesChange(updatedCategories); }, [baseHandleCategoriesChange] ); useEffect5(() => { if (isModalOpen && config.categories.length > 0 && !categoriesInitializedRef.current) { const autoSelectedCategories = applyChainedAutoSelection( config.categories ); setCategories(autoSelectedCategories); void handleCategoriesChange(autoSelectedCategories); categoriesInitializedRef.current = true; } }, [ isModalOpen, config.categories, applyChainedAutoSelection, handleCategoriesChange ]); useEffect5(() => { if (!isModalOpen) { categoriesInitializedRef.current = false; } }, [isModalOpen]); const defaultSteps = [ { id: "1", label: "Mensagem", state: "completed" }, { id: "2", label: labels?.recipientsTitle || "Destinat\xE1rios", state: "current" }, { id: "3", label: labels?.dateLabel || "Data de envio", state: "pending" }, { id: "4", label: labels?.previewTitle || "Pr\xE9via", state: "pending" } ]; const steps = customSteps || defaultSteps; const handleCloseModal = () => { setIsModalOpen(false); onClose?.(); }; const isCurrentStepValid2 = useCallback2(() => { return isCurrentStepValid( currentStep, formData, categories, customSteps ); }, [currentStep, categories, customSteps, formData]); const canFinish2 = useCallback2(() => { return canFinish(formData, categories); }, [categories, formData]); const handleNext2 = useCallback2(() => { const result = handleNext({ currentStep, steps, formData, categories, customSteps, completedSteps, setCompletedSteps, setCurrentStep }); if (!result.success && result.error) { alert(result.error); } }, [ currentStep, steps, categories, customSteps, completedSteps, setCompletedSteps, setCurrentStep, formData ]); const handlePrevious = useCallback2(() => { if (currentStep > 0) { setCurrentStep(currentStep - 1); } }, [currentStep, setCurrentStep]); const handleFinish = async () => { if (!completedSteps.includes(currentStep)) { setCompletedSteps([...completedSteps, currentStep]); } const alertData = { title: formData.title, message: formData.message, image: formData.image, date: formData.date, time: formData.time, sendToday: formData.sendToday, sendCopyToEmail: formData.sendCopyToEmail, recipientCategories: Object.fromEntries( Object.entries(formData.recipientCategories).map(([key, c]) => [ key, { selectedIds: c.selectedIds || [], allSelected: !!c.allSelected } ]) ) }; try { if (behavior?.onSendAlert) { await behavior.onSendAlert(alertData); } else { console.log("Dados do formul\xE1rio:", alertData); alert("Aviso enviado com sucesso!"); } handleCloseModal(); } catch (error) { console.error("Erro ao enviar aviso:", error); } }; const dynamicSteps = steps.map( (step, index) => { if (completedSteps.includes(index)) { return { ...step, state: "completed" }; } if (index === currentStep) { return { ...step, state: "current" }; } return { ...step, state: "pending" }; } ); const currentStepContent = useMemo4(() => { if (customSteps?.[currentStep]?.component) { const CustomComponent = customSteps[currentStep].component; return /* @__PURE__ */ jsx10(StepWrapper, { children: /* @__PURE__ */ jsx10(CustomComponent, { onNext: handleNext2, onPrevious: handlePrevious }) }); } switch (currentStep) { case 0: return /* @__PURE__ */ jsx10(StepWrapper, { children: /* @__PURE__ */ jsx10( MessageStep, { labels, allowImageAttachment: behavior?.allowImageAttachment } ) }); case 1: return /* @__PURE__ */ jsx10(StepWrapper, { children: /* @__PURE__ */ jsx10( RecipientsStep, { categories, labels, onCategoriesChange: handleCategoriesChange } ) }); case 2: return /* @__PURE__ */ jsx10(StepWrapper, { children: /* @__PURE__ */ jsx10( DateStep, { labels, allowScheduling: behavior?.allowScheduling, allowEmailCopy: behavior?.allowEmailCopy } ) }); case 3: return /* @__PURE__ */ jsx10(StepWrapper, { children: /* @__PURE__ */ jsx10(PreviewStep, { imageLink, defaultImage }) }); default: return null; } }, [ currentStep, customSteps, categories, labels, behavior, handleNext2, handlePrevious, imageLink, defaultImage ]); const isFirstStep = currentStep === 0; const isLastStep = currentStep === steps.length - 1; return /* @__PURE__ */ jsx10( Modal_default, { isOpen: isModalOpen, onClose: handleCloseModal, title: labels?.modalTitle || "Enviar aviso", size: "md", contentClassName: "p-0", footer: /* @__PURE__ */ jsx10("div", { className: "flex gap-3 justify-end w-full", children: /* @__PURE__ */ jsxs10("div", { className: "flex gap-3", children: [ /* @__PURE__ */ jsx10(Button_default, { variant: "link", size: "small", onClick: handleCloseModal, children: labels?.cancelButton || "Cancelar" }), !isFirstStep && /* @__PURE__ */ jsx10( Button_default, { variant: "outline", size: "small", iconLeft: /* @__PURE__ */ jsx10(CaretLeftIcon2, {}), onClick: handlePrevious, children: labels?.previousButton || "Anterior" } ), isLastStep ? /* @__PURE__ */ jsx10( Button_default, { variant: "solid", iconLeft: /* @__PURE__ */ jsx10(PaperPlaneTiltIcon2, {}), size: "small", onClick: handleFinish, disabled: !canFinish2(), children: labels?.finishButton || "Enviar Aviso" } ) : /* @__PURE__ */ jsx10( Button_default, { variant: "solid", iconRight: /* @__PURE__ */ jsx10(CaretRightIcon, {}), size: "small", onClick: handleNext2, disabled: !isCurrentStepValid2(), children: labels?.nextButton || "Pr\xF3ximo" } ) ] }) }), children: /* @__PURE__ */ jsxs10("div", { className: "flex flex-col h-[calc(100vh-14rem)] max-h-[600px]", children: [ /* @__PURE__ */ jsx10("div", { className: "shrink-0 px-6 pt-4", children: /* @__PURE__ */ jsx10( Stepper_default, { steps: dynamicSteps, size: "small", showProgress: true, responsive: true, progressText: `Etapa ${currentStep + 1} de ${steps.length}` } ) }), /* @__PURE__ */ jsx10("div", { className: "flex-1 overflow-y-auto px-6 pb-4", children: currentStepContent }) ] }) } ); }; // src/hooks/useActivityFiltersData.ts import { useState as useState4, useEffect as useEffect6, useCallback as useCallback3, useMemo as useMemo5, useRef as useRef4 } from "react"; var areCategoriesSame = (prev, current) => { if (prev.length !== current.length) return false; return current.every((category) => { const prevCategory = prev.find((c) => c.key === category.key); if (!prevCategory) return false; const prevIds = (prevCategory.itens || []).map( (item) => item.id ); const currentIds = (category.itens || []).map( (item) => item.id ); if (prevIds.length !== currentIds.length) return false; return currentIds.every((id) => prevIds.includes(id)); }); }; var mergeCategoriesWithSelection = (prev, current) => { return current.map((category) => { const prevCategory = prev.find((c) => c.key === category.key); if (!prevCategory) { return category; } const validSelectedIds = (prevCategory.selectedIds || []).filter( (id) => category.itens?.some((item) => item.id === id) ); return { ...category, selectedIds: validSelectedIds }; }); }; var mapSelectedNames = (ids, items) => { return ids.map((id) => { const item = items.find((t) => t.id === id); return item ? item.name : null; }).filter((name) => name !== null); }; var useActivityFiltersDataImpl = (apiClient, options) => { const { selectedSubjects, institutionId } = options; const [banksState, setBanksState] = useState4({ banks: [], bankYears: [], loading: false, error: null }); const loadBanks = useCallback3(async () => { setBanksState((prev) => ({ ...prev, loading: true, error: null })); try { const response = await apiClient.get( "/questions/exam-institutions" ); const banksMap = /* @__PURE__ */ new Map(); const bankYearsArray = []; for (const item of response.data.data) { if (!item.questionBankName) continue; const existingBank = banksMap.get(item.questionBankName); if (existingBank) { if (!existingBank.years.includes(item.year)) { existingBank.years.push(item.year); } existingBank.questionsCount += item.questionsCount; } else { banksMap.set(item.questionBankName, { id: item.questionBankName, name: item.questionBankName, examInstitution: item.questionBankName, years: [item.year], questionsCount: item.questionsCount }); } bankYearsArray.push({ id: `${item.questionBankYearId}-${item.questionBankName}`, name: item.year, bankId: item.questionBankName }); } const banks = Array.from(banksMap.values()).map((bank) => ({ id: bank.id, name: bank.name, examInstitution: bank.examInstitution })); setBanksState({ banks, bankYears: bankYearsArray, loading: false, error: null }); } catch (error) { console.error("Erro ao carregar bancas de vestibular:", error); setBanksState((prev) => ({ ...prev, loading: false, error: "Erro ao carregar bancas de vestibular" })); } }, [apiClient]); const [areasState, setAreasState] = useState4({ knowledgeAreas: [], loading: false, error: null }); const loadKnowledgeAreas = useCallback3(async () => { setAreasState((prev) => ({ ...prev, loading: true, error: null })); try { const response = await apiClient.get( "/knowledge/subjects" ); setAreasState({ knowledgeAreas: response.data.data, loading: false, error: null }); } catch (error) { console.error("Erro ao carregar \xE1reas de conhecimento:", error); setAreasState((prev) => ({ ...prev, loading: false, error: "Erro ao carregar \xE1reas de conhecimento" })); } }, [apiClient]); const [questionTypesState, setQuestionTypesState] = useState4({ questionTypes: [], loading: false, error: null }); const loadQuestionTypes = useCallback3(async () => { if (!institutionId) { setQuestionTypesState((prev) => ({ ...prev, questionTypes: [], loading: false, error: null })); return; } setQuestionTypesState((prev) => ({ ...prev, loading: true, error: null })); try { const response = await apiClient.get( `/institutions/${institutionId}/question-types` ); const mappedTypes = response.data.data.questionTypes.map((type) => mapQuestionTypeToEnum(type)).filter((type) => type !== null); setQuestionTypesState({ questionTypes: mappedTypes, loading: false, error: null }); } catch (error) { console.error("Erro ao carregar tipos de quest\xF5es:", error); setQuestionTypesState((prev) => ({ ...prev, loading: false, error: "Erro ao carregar tipos de quest\xF5es" })); } }, [apiClient, institutionId]); const [knowledgeStructure, setKnowledgeStructure] = useState4({ topics: [], subtopics: [], contents: [], loading: false, error: null }); const [knowledgeCategories, setKnowledgeCategories] = useState4([]); const previousSubjectsRef = useRef4(null); const loadTopics = useCallback3( async (subjectIds) => { if (subjectIds.length === 0) { setKnowledgeStructure({ topics: [], subtopics: [], contents: [], loading: false, error: null }); setKnowledgeCategories([]); return; } setKnowledgeStructure((prev) => ({ ...prev, loading: true, error: null })); try { const response = await apiClient.post( "/knowledge/topics", { subjectIds } ); const topics = response.data.data.map((topic) => ({ id: topic.id, name: topic.name })); setKnowledgeStructure((prev) => ({ ...prev, topics, subtopics: [], contents: [], loading: false, error: null })); } catch (error) { console.error("Erro ao carregar temas:", error); setKnowledgeStructure((prev) => ({ ...prev, topics: [], subtopics: [], contents: [], loading: false, error: "Erro ao carregar temas" })); } }, [apiClient] ); const loadSubtopics = useCallback3( async (topicIds) => { if (topicIds.length === 0) { setKnowledgeStructure((prev) => ({ ...prev, subtopics: [], contents: [], loading: false, error: null })); return; } setKnowledgeStructure((prev) => ({ ...prev, loading: topicIds.length > 0, error: null })); try { const response = await apiClient.post( "/knowledge/subtopics", { topicIds } ); const subtopics = response.data.data.map( (subtopic) => ({ id: subtopic.id, name: subtopic.name, topicId: subtopic.topicId || topicIds[0] }) ); setKnowledgeStructure((prev) => ({ ...prev, subtopics, contents: [], loading: false, error: null })); } catch (error) { console.error("Erro ao carregar subtemas:", error); setKnowledgeStructure((prev) => ({ ...prev, subtopics: [], contents: [], loading: false, error: "Erro ao carregar subtemas" })); } }, [apiClient] ); const loadContents = useCallback3( async (subtopicIds) => { if (subtopicIds.length === 0) { setKnowledgeStructure((prev) => ({ ...prev, contents: [], loading: false, error: null })); return; } setKnowledgeStructure((prev) => ({ ...prev, loading: true,