analytica-frontend-lib
Version:
Repositório público dos componentes utilizados nas plataformas da Analytica Ensino
1 lines • 10.7 kB
Source Map (JSON)
{"version":3,"sources":["../src/hooks/useStudentsHighlight.ts"],"sourcesContent":["import { useState, useCallback } from 'react';\nimport { z } from 'zod';\n\n/**\n * Period tabs configuration matching the Figma design\n */\nexport const PERIOD_TABS = [\n { value: '7_DAYS', label: '7 dias' },\n { value: '1_MONTH', label: '1 mês' },\n { value: '3_MONTHS', label: '3 meses' },\n { value: '6_MONTHS', label: '6 meses' },\n { value: '1_YEAR', label: '1 ano' },\n] as const;\n\n/**\n * Period filter options for students highlight (derived from PERIOD_TABS)\n */\nexport type StudentsHighlightPeriod = (typeof PERIOD_TABS)[number]['value'];\n\n/**\n * Type filter options for students highlight\n */\nexport type StudentsHighlightType = 'ACTIVITIES' | 'LESSON_CONTENT';\n\n/**\n * Trend direction for student performance\n */\nexport type TrendDirection = 'up' | 'down' | 'stable';\n\n/**\n * Filters for students highlight API request\n */\nexport interface StudentsHighlightFilters {\n type?: StudentsHighlightType;\n period?: StudentsHighlightPeriod;\n subjectId?: string;\n schoolYearId?: string;\n classId?: string;\n schoolId?: string;\n}\n\n/**\n * Student highlight item from API response\n */\nexport interface StudentHighlightApiItem {\n id: string;\n name: string;\n correctAnswers: number;\n incorrectAnswers: number;\n totalQuestions: number;\n trend: number | null;\n trendDirection: TrendDirection | null;\n}\n\n/**\n * API response structure for students highlight endpoint\n */\nexport interface StudentsHighlightApiResponse {\n message: string;\n data: {\n topStudents: StudentHighlightApiItem[];\n bottomStudents: StudentHighlightApiItem[];\n };\n}\n\n/**\n * Transformed student item for UI display\n */\nexport interface StudentHighlightItem {\n /** Student ID */\n id: string;\n /** Student position in the ranking */\n position: number;\n /** Student name */\n name: string;\n /** Performance percentage (0-100) */\n percentage: number;\n /** Correct answers count */\n correctAnswers: number;\n /** Incorrect answers count */\n incorrectAnswers: number;\n /** Total questions answered */\n totalQuestions: number;\n /** Trend value (percentage change) */\n trend: number | null;\n /** Trend direction */\n trendDirection: TrendDirection | null;\n}\n\n/**\n * Zod schema for trend direction\n */\nconst trendDirectionSchema = z.enum(['up', 'down', 'stable']).nullable();\n\n/**\n * Zod schema for student highlight item validation\n */\nconst studentHighlightItemSchema = z.object({\n id: z.string().uuid(),\n name: z.string(),\n correctAnswers: z.number().min(0),\n incorrectAnswers: z.number().min(0),\n totalQuestions: z.number().min(0),\n trend: z.number().nullable(),\n trendDirection: trendDirectionSchema,\n});\n\n/**\n * Zod schema for students highlight API response validation\n */\nexport const studentsHighlightApiResponseSchema = z.object({\n message: z.string(),\n data: z.object({\n topStudents: z.array(studentHighlightItemSchema),\n bottomStudents: z.array(studentHighlightItemSchema),\n }),\n});\n\n/**\n * Hook state interface\n */\nexport interface UseStudentsHighlightState {\n topStudents: StudentHighlightItem[];\n bottomStudents: StudentHighlightItem[];\n loading: boolean;\n error: string | null;\n}\n\n/**\n * Hook return type\n */\nexport interface UseStudentsHighlightReturn extends UseStudentsHighlightState {\n fetchStudentsHighlight: (filters?: StudentsHighlightFilters) => Promise<void>;\n reset: () => void;\n}\n\n/**\n * Calculate performance percentage based on correct answers and total questions\n * @param correctAnswers - Number of correct answers\n * @param totalQuestions - Total number of questions\n * @returns Performance percentage (0-100)\n */\nexport const calculatePerformancePercentage = (\n correctAnswers: number,\n totalQuestions: number\n): number => {\n if (totalQuestions === 0) {\n return 0;\n }\n return Math.round((correctAnswers / totalQuestions) * 100);\n};\n\n/**\n * Transform API student item to UI display format\n * @param item - Student item from API response\n * @param position - Position in the ranking (1-based)\n * @returns Transformed student item for UI\n */\nexport const transformStudentHighlightItem = (\n item: StudentHighlightApiItem,\n position: number\n): StudentHighlightItem => ({\n id: item.id,\n position,\n name: item.name,\n percentage: calculatePerformancePercentage(\n item.correctAnswers,\n item.totalQuestions\n ),\n correctAnswers: item.correctAnswers,\n incorrectAnswers: item.incorrectAnswers,\n totalQuestions: item.totalQuestions,\n trend: item.trend,\n trendDirection: item.trendDirection,\n});\n\n/**\n * Handle errors during students highlight fetch\n * @param error - Error object\n * @returns Error message for UI display\n */\nexport const handleStudentsHighlightFetchError = (error: unknown): string => {\n if (error instanceof z.ZodError) {\n console.error('Erro ao validar dados de destaque de estudantes:', error);\n return 'Erro ao validar dados de destaque de estudantes';\n }\n\n console.error('Erro ao carregar destaque de estudantes:', error);\n return 'Erro ao carregar destaque de estudantes';\n};\n\n/**\n * Initial state for the hook\n */\nconst initialState: UseStudentsHighlightState = {\n topStudents: [],\n bottomStudents: [],\n loading: false,\n error: null,\n};\n\n/**\n * Factory function to create useStudentsHighlight hook\n *\n * @param fetchStudentsHighlightApi - Function to fetch students highlight from API\n * @returns Hook for managing students highlight data\n *\n * @example\n * ```tsx\n * // In your app setup\n * const fetchStudentsHighlightApi = async (filters) => {\n * const response = await api.get('/performance/students-highlight', { params: filters });\n * return response.data;\n * };\n *\n * const useStudentsHighlight = createUseStudentsHighlight(fetchStudentsHighlightApi);\n *\n * // In your component\n * const { topStudents, bottomStudents, loading, error, fetchStudentsHighlight } = useStudentsHighlight();\n *\n * useEffect(() => {\n * fetchStudentsHighlight({ period: '1_MONTH' });\n * }, []);\n * ```\n */\nexport const createUseStudentsHighlight = (\n fetchStudentsHighlightApi: (\n filters?: StudentsHighlightFilters\n ) => Promise<StudentsHighlightApiResponse>\n) => {\n return (): UseStudentsHighlightReturn => {\n const [state, setState] = useState<UseStudentsHighlightState>(initialState);\n\n /**\n * Fetch students highlight from API\n * @param filters - Optional filters for period, subject, class, etc.\n */\n const fetchStudentsHighlight = useCallback(\n async (filters?: StudentsHighlightFilters) => {\n setState((prev) => ({ ...prev, loading: true, error: null }));\n\n try {\n // Fetch data from API\n const responseData = await fetchStudentsHighlightApi(filters);\n\n // Validate response with Zod\n const validatedData =\n studentsHighlightApiResponseSchema.parse(responseData);\n\n // Transform students to UI format with positions\n const topStudents = validatedData.data.topStudents.map(\n (student, index) =>\n transformStudentHighlightItem(student, index + 1)\n );\n\n const bottomStudents = validatedData.data.bottomStudents.map(\n (student, index) =>\n transformStudentHighlightItem(student, index + 1)\n );\n\n // Update state with validated and transformed data\n setState({\n topStudents,\n bottomStudents,\n loading: false,\n error: null,\n });\n } catch (error) {\n const errorMessage = handleStudentsHighlightFetchError(error);\n setState((prev) => ({\n ...prev,\n loading: false,\n error: errorMessage,\n }));\n }\n },\n [fetchStudentsHighlightApi]\n );\n\n /**\n * Reset state to initial values\n */\n const reset = useCallback(() => {\n setState(initialState);\n }, []);\n\n return {\n ...state,\n fetchStudentsHighlight,\n reset,\n };\n };\n};\n\n/**\n * Alias for createUseStudentsHighlight\n */\nexport const createStudentsHighlightHook = createUseStudentsHighlight;\n"],"mappings":"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","names":[]}