UNPKG

analytica-frontend-lib

Version:

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

1 lines 8.65 kB
{"version":3,"sources":["../src/hooks/useSendActivity.ts"],"sourcesContent":["/**\n * useSendActivity Hook\n *\n * Hook for managing the SendActivityModal state and actions.\n * Uses BaseApiClient for type-safe API calls to backend-monolito endpoints.\n */\n\nimport { useState, useCallback, useMemo, useRef } from 'react';\nimport dayjs from 'dayjs';\nimport type { CategoryConfig } from '../components/CheckBoxGroup/CheckBoxGroup';\nimport {\n ActivityMode,\n ActivitySubtype,\n type SendActivityFormData,\n type SendActivityModalInitialData,\n} from '../components/SendActivityModal/types';\nimport type {\n UseSendActivityConfig,\n UseSendActivityReturn,\n ActivityModelItem,\n} from '../types/sendActivity';\nimport { loadCategoriesData } from '../utils/categoryDataUtils';\nimport { useDynamicStudentFetching } from '../utils/useDynamicStudentFetching';\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 * Pass a BaseApiClient instance and the hook will handle all API calls internally\n * using the backend-monolito endpoints.\n *\n * @param config - Configuration with BaseApiClient instance and optional callbacks\n * @returns Object with modal state, categories, and handlers\n *\n * @example\n * ```tsx\n * import { useSendActivity } from 'analytica-frontend-lib';\n * import api from '@/services/apiService';\n *\n * const sendActivity = useSendActivity({\n * api,\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 { api, onSuccess, onError } = 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 categoryConfig = await loadCategoriesData(api, []);\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 }, [api, 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 * Fetches students dynamically via POST /students/filters when the\n * school/série/turma selections change, mirroring the activity creation flow.\n */\n const { handleCategoriesChange: onCategoriesChange } =\n useDynamicStudentFetching(setCategories, { apiClient: api });\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 let questionIds: string[] | null = null;\n try {\n const response = await api.get<{\n data: { selectedQuestions?: { id: string }[] };\n }>(`/activity-drafts/${selectedModel.id}`);\n questionIds =\n response.data.data.selectedQuestions?.map((q) => q.id) || null;\n } catch {\n questionIds = null;\n }\n\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 api.post<{ data: { id: string } }>(\n '/activities',\n {\n title: data.title,\n subjectId: selectedModel.subjectId,\n questionIds,\n subtype: data.subtype,\n isDigital:\n data.subtype === ActivitySubtype.PROVA\n ? data.mode !== ActivityMode.PRESENCIAL\n : true,\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\n // 3. Send to students\n await api.post('/activities/send-to-students', {\n activityId: createResponse.data.data.id,\n students: data.students,\n });\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 [selectedModel, api, onSuccess, onError, closeModal]\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":[]}