UNPKG

analytica-frontend-lib

Version:

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

1 lines 11.8 kB
{"version":3,"sources":["../../../src/hooks/useQuestionsList.ts"],"sourcesContent":["import { useState, useCallback } from 'react';\nimport type { BaseApiClient } from '../types/api';\nimport type {\n QuestionsFilterBody,\n QuestionsListResponseActivity,\n QuestionsByIdsBody,\n QuestionsByIdsResponse,\n Question,\n Pagination,\n PaginationActivity,\n} from '../types/questions';\n\n// ============================================================================\n// Hook State Types\n// ============================================================================\n\n/**\n * Hook state interface\n */\ninterface UseQuestionsListState {\n questions: Question[];\n pagination: Pagination | null;\n loading: boolean;\n loadingMore: boolean;\n error: string | null;\n currentFilters: Partial<QuestionsFilterBody> | null;\n}\n\n// ============================================================================\n// Hook Return Type\n// ============================================================================\n\n/**\n * Hook return type\n */\nexport interface UseQuestionsListReturn extends UseQuestionsListState {\n fetchQuestions: (\n filters?: Partial<QuestionsFilterBody>,\n append?: boolean\n ) => Promise<void>;\n fetchRandomQuestions: (\n count: number,\n filters?: Partial<QuestionsFilterBody>\n ) => Promise<Question[]>;\n fetchQuestionsByIds: (questionIds: string[]) => Promise<Question[]>;\n loadMore: () => Promise<void>;\n reset: () => void;\n}\n\n// ============================================================================\n// Main Hook Implementation\n// ============================================================================\n\nconst useQuestionsListImpl = (\n apiClient: BaseApiClient\n): UseQuestionsListReturn => {\n const [state, setState] = useState<UseQuestionsListState>({\n questions: [],\n pagination: null,\n loading: false,\n loadingMore: false,\n error: null,\n currentFilters: null,\n });\n\n const updateState = useCallback((updates: Partial<UseQuestionsListState>) => {\n setState((prev) => ({ ...prev, ...updates }));\n }, []);\n\n const handleError = useCallback(\n (error: unknown) => {\n console.error('Erro ao carregar questões:', error);\n let errorMessage = 'Erro ao carregar questões';\n\n if (error && typeof error === 'object' && 'response' in error) {\n const axiosError = error as {\n response?: { data?: { message?: string } };\n message?: string;\n };\n errorMessage =\n axiosError?.response?.data?.message ||\n axiosError?.message ||\n errorMessage;\n } else if (error instanceof Error) {\n errorMessage = error.message;\n }\n\n updateState({\n loading: false,\n loadingMore: false,\n error: errorMessage,\n });\n },\n [updateState]\n );\n\n /**\n * Convert PaginationActivity to Pagination format\n */\n const convertPagination = (\n pagination: PaginationActivity | undefined\n ): Pagination | null => {\n if (!pagination) return null;\n return {\n page: pagination.page,\n pageSize: pagination.limit,\n total: pagination.total,\n totalPages: pagination.totalPages,\n hasNext: pagination.hasNext,\n hasPrevious: pagination.hasPrev,\n };\n };\n\n /**\n * Fetch questions from API with filters\n * @param filters - Filters to apply\n * @param append - If true, appends results to existing questions; if false, replaces them\n */\n const fetchQuestions = useCallback(\n async (filters?: Partial<QuestionsFilterBody>, append: boolean = false) => {\n if (append) {\n setState((prev) => ({ ...prev, loadingMore: true, error: null }));\n } else {\n updateState({ loading: true, error: null, questions: [] });\n }\n\n try {\n const validatedFilters: QuestionsFilterBody = {\n ...filters,\n };\n\n const response = await apiClient.post<QuestionsListResponseActivity>(\n '/questions/list',\n validatedFilters\n );\n\n setState((prev) => ({\n loading: false,\n loadingMore: false,\n questions: append\n ? [...prev.questions, ...response.data.data.questions]\n : response.data.data.questions,\n pagination: convertPagination(response.data.data.pagination),\n error: null,\n currentFilters: validatedFilters,\n }));\n } catch (error) {\n setState((prev) => ({\n ...prev,\n loading: false,\n loadingMore: false,\n }));\n handleError(error);\n }\n },\n [apiClient, updateState, handleError]\n );\n\n /**\n * Fetch random questions from API\n * @param count - Number of random questions to fetch\n * @param filters - Optional filters to apply\n * @returns Promise with array of questions\n */\n const fetchRandomQuestions = useCallback(\n async (\n count: number,\n filters?: Partial<QuestionsFilterBody>\n ): Promise<Question[]> => {\n try {\n const validatedFilters: QuestionsFilterBody = {\n ...filters,\n randomQuestions: count,\n };\n\n const response = await apiClient.post<QuestionsListResponseActivity>(\n '/questions/list',\n validatedFilters\n );\n\n return response.data.data.questions;\n } catch (error) {\n handleError(error);\n return [];\n }\n },\n [apiClient, handleError]\n );\n\n /**\n * Fetch questions by their IDs\n * @param questionIds - Array of question IDs to fetch\n * @returns Promise with array of questions\n */\n const fetchQuestionsByIds = useCallback(\n async (questionIds: string[]): Promise<Question[]> => {\n try {\n const body: QuestionsByIdsBody & Record<string, unknown> = {\n questionsIds: questionIds,\n };\n\n const response = await apiClient.post<QuestionsByIdsResponse>(\n '/questions/by-ids',\n body\n );\n\n return response.data.data.questions;\n } catch (error) {\n handleError(error);\n return [];\n }\n },\n [apiClient, handleError]\n );\n\n const loadMore = useCallback(async () => {\n setState((prev) => {\n const { currentFilters, pagination, loadingMore: isLoadingMore } = prev;\n\n if (isLoadingMore || !currentFilters || !pagination?.hasNext) {\n return prev;\n }\n\n const nextPageFilters = {\n ...currentFilters,\n page: pagination.page + 1,\n };\n\n fetchQuestions(nextPageFilters, true).catch((error) => {\n console.error('Erro ao carregar mais questões:', error);\n });\n\n return {\n ...prev,\n loadingMore: true,\n };\n });\n }, [fetchQuestions]);\n\n /**\n * Reset questions list\n */\n const reset = useCallback(() => {\n setState({\n questions: [],\n pagination: null,\n loading: false,\n loadingMore: false,\n error: null,\n currentFilters: null,\n });\n }, []);\n\n return {\n ...state,\n fetchQuestions,\n fetchRandomQuestions,\n fetchQuestionsByIds,\n loadMore,\n reset,\n };\n};\n\n// ============================================================================\n// Hook Factory\n// ============================================================================\n\n/**\n * Create a questions list hook with API client injection.\n * @param apiClient - API client instance\n * @returns Pre-configured useQuestionsList hook\n *\n * @example\n * // In your app setup\n * import { createUseQuestionsList } from 'analytica-frontend-lib';\n * import api from './services/api';\n *\n * export const useQuestionsList = createUseQuestionsList(api);\n *\n * // Then use directly in components\n * const { questions, fetchQuestions, loadMore } = useQuestionsList();\n */\nexport const createUseQuestionsList = (apiClient: BaseApiClient) => {\n return (): UseQuestionsListReturn => useQuestionsListImpl(apiClient);\n};\n\n/**\n * Create a pre-configured questions list hook\n * This is a convenience function that returns a hook ready to use\n *\n * @param apiClient - API client instance\n * @returns Pre-configured useQuestionsList hook\n *\n * @example\n * // In your app setup\n * import { createQuestionsListHook } from 'analytica-frontend-lib';\n * import api from './services/api';\n *\n * export const useQuestionsList = createQuestionsListHook(api);\n *\n * // Then use directly in components\n * const { questions, fetchQuestions, loadMore } = useQuestionsList();\n */\nexport const createQuestionsListHook = (apiClient: BaseApiClient) => {\n return createUseQuestionsList(apiClient);\n};\n"],"mappings":"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","names":[]}