{"version":3,"sources":["../src/hooks/useActivitiesHistory.ts"],"sourcesContent":["import { useState, useCallback } from 'react';\nimport dayjs from 'dayjs';\nimport type { BaseApiClient } from '../types/api';\nimport { mapApiStatusToDisplay } from '../types/common';\nimport type {\n  ActivityHistoryResponse,\n  ActivityTableItem,\n  ActivitiesHistoryApiResponse,\n  ActivityHistoryFilters,\n  ActivityPagination,\n  ActivityFilterOption,\n} from '../types/activitiesHistory';\nimport {\n  mergeFilterOptions,\n  extractBreakdownFilterOptions,\n} from '../utils/filterHelpers';\n\n/**\n * Options for configuring the useActivitiesHistory hook\n */\nexport interface UseActivitiesHistoryOptions {\n  /** Filter by activity category (PROVA, ATIVIDADE, etc.) */\n  activityCategory?: 'PROVA' | 'ATIVIDADE';\n}\n\n/**\n * API filter options extracted from response\n */\nexport interface ActivityApiFilterOptions {\n  schools: ActivityFilterOption[];\n  classes: ActivityFilterOption[];\n  subjects: ActivityFilterOption[];\n  schoolYears: ActivityFilterOption[];\n}\n\n/**\n * Hook state interface\n */\nexport interface UseActivitiesHistoryState {\n  activities: ActivityTableItem[];\n  loading: boolean;\n  error: string | null;\n  pagination: ActivityPagination;\n  apiFilterOptions: ActivityApiFilterOptions;\n}\n\n/**\n * Hook return type\n */\nexport interface UseActivitiesHistoryReturn extends UseActivitiesHistoryState {\n  fetchActivities: (filters?: ActivityHistoryFilters) => Promise<void>;\n}\n\n/**\n * Default pagination values\n */\nexport const DEFAULT_ACTIVITIES_PAGINATION: ActivityPagination = {\n  total: 0,\n  page: 1,\n  limit: 10,\n  totalPages: 0,\n};\n\n/**\n * Default API filter options\n */\nexport const DEFAULT_ACTIVITY_FILTER_OPTIONS: ActivityApiFilterOptions = {\n  schools: [],\n  classes: [],\n  subjects: [],\n  schoolYears: [],\n};\n\n/**\n * Transform API response to table item format\n * @param activity - Activity from API response\n * @returns Formatted activity for table display\n */\nexport const transformActivityToTableItem = (\n  activity: ActivityHistoryResponse\n): ActivityTableItem => {\n  const firstBreakdown = activity.breakdown?.[0];\n  return {\n    id: activity.id,\n    startDate: activity.startDate\n      ? dayjs(activity.startDate).format('DD/MM')\n      : '-',\n    deadline: activity.finalDate\n      ? dayjs(activity.finalDate).format('DD/MM')\n      : '-',\n    creator: activity.creator?.name?.trim() ? activity.creator.name : '-',\n    creatorId: activity.creator?.id ?? null,\n    title: activity.title,\n    school: firstBreakdown?.school?.name ?? '-',\n    year: firstBreakdown?.schoolYear?.name ?? '-',\n    subject: activity.subject?.name ?? '-',\n    class: firstBreakdown?.class?.name ?? '-',\n    status: mapApiStatusToDisplay(activity.status),\n    completionPercentage: activity.completionPercentage,\n  };\n};\n\n/**\n * Extract unique filter options from activities API response.\n * Delegates to the shared extractBreakdownFilterOptions helper.\n */\nexport const extractActivityFilterOptions = (\n  activities: ActivityHistoryResponse[]\n): ActivityApiFilterOptions => extractBreakdownFilterOptions(activities);\n\n/**\n * Join an array of selected ids into the backend's comma-separated convention\n * (e.g. `schoolIds=a,b,c`). Returns undefined for empty / non-array input so the\n * query param is omitted entirely.\n */\nconst toCsv = (value: unknown): string | undefined => {\n  if (Array.isArray(value) && value.length > 0) {\n    return value.map(String).join(',');\n  }\n  return undefined;\n};\n\n/**\n * Collapse a single-select filter (emitted as an array by TableProvider) to its\n * first value. Also tolerates a bare string. Returns undefined when empty.\n */\nconst toSingle = (value: unknown): string | undefined => {\n  if (Array.isArray(value)) {\n    return value.length > 0 ? String(value[0]) : undefined;\n  }\n  if (typeof value === 'string' && value.length > 0) {\n    return value;\n  }\n  return undefined;\n};\n\n/**\n * Assign a resolved string value onto the params object only when it is present.\n * Keeps the builder free of repetitive `if (value) params[key] = value` blocks.\n */\nconst assignIf = (\n  params: Record<string, unknown>,\n  key: string,\n  value: string | undefined\n): void => {\n  if (value) {\n    params[key] = value;\n  }\n};\n\n/**\n * Raw scalar keys forwarded to the backend untouched (pagination, text search,\n * date range and sorting). Copied verbatim when present and non-empty.\n */\nconst PASSTHROUGH_KEYS = [\n  'page',\n  'limit',\n  'search',\n  'startDate',\n  'finalDate',\n  'sortBy',\n  'sortOrder',\n] as const;\n\n/**\n * Build the `/activities/history` query params from the raw TableProvider filter\n * keys. TableProvider emits UI-category keys (`subject`, `school`, `class`,\n * `schoolYear`, `status`, `creatorType`) as arrays; the backend expects a\n * different, mostly single-value contract. This adapter renames each key and\n * collapses/serializes to what the backend actually reads. Mirrors\n * `buildFiltersFromParams` in RecommendedLessonsHistory.\n *\n * @param filters - Raw table params (arrays under UI keys) plus page/limit/search/sort\n * @param activityCategory - Optional value forwarded as the `type` param\n */\nexport const buildActivityHistoryQueryParams = (\n  filters?: Record<string, unknown>,\n  activityCategory?: string\n): Record<string, unknown> => {\n  const params: Record<string, unknown> = {};\n  assignIf(params, 'type', activityCategory);\n\n  if (!filters) {\n    return params;\n  }\n\n  for (const key of PASSTHROUGH_KEYS) {\n    const value = filters[key];\n    if (value !== undefined && value !== null && value !== '') {\n      params[key] = value;\n    }\n  }\n\n  // Multi-select filters serialized as comma-separated ids. School and class each\n  // fall back to their legacy singular key when the raw multi-select key is absent.\n  assignIf(params, 'schoolIds', toCsv(filters.school));\n  assignIf(params, 'classIds', toCsv(filters.class));\n  assignIf(params, 'schoolYearIds', toCsv(filters.schoolYear));\n  if (!params.schoolIds) {\n    assignIf(params, 'schoolId', toSingle(filters.schoolId));\n  }\n  if (!params.classIds) {\n    assignIf(params, 'classId', toSingle(filters.classId));\n  }\n\n  // Single-select filters (subject also honors the legacy singular key).\n  assignIf(params, 'status', toSingle(filters.status));\n  assignIf(\n    params,\n    'subjectId',\n    toSingle(filters.subject) ?? toSingle(filters.subjectId)\n  );\n  assignIf(params, 'creatorType', toSingle(filters.creatorType));\n\n  return params;\n};\n\n/**\n * Hook implementation\n */\nconst useActivitiesHistoryImpl = (\n  apiClient: BaseApiClient,\n  options?: UseActivitiesHistoryOptions\n): UseActivitiesHistoryReturn => {\n  const [state, setState] = useState<UseActivitiesHistoryState>({\n    activities: [],\n    loading: false,\n    error: null,\n    pagination: DEFAULT_ACTIVITIES_PAGINATION,\n    apiFilterOptions: DEFAULT_ACTIVITY_FILTER_OPTIONS,\n  });\n\n  const fetchActivities = useCallback(\n    async (filters?: ActivityHistoryFilters) => {\n      setState((prev) => ({ ...prev, loading: true, error: null }));\n\n      try {\n        const params = buildActivityHistoryQueryParams(\n          filters as Record<string, unknown>,\n          options?.activityCategory\n        );\n        const response = await apiClient.get<ActivitiesHistoryApiResponse>(\n          '/activities/history',\n          { params }\n        );\n\n        const { data } = response.data;\n\n        const tableItems = data.activities.map(transformActivityToTableItem);\n        const extracted = extractActivityFilterOptions(data.activities);\n\n        setState((prev) => ({\n          activities: tableItems,\n          loading: false,\n          error: null,\n          pagination: data.pagination,\n          apiFilterOptions: {\n            schools: mergeFilterOptions(\n              prev.apiFilterOptions.schools,\n              extracted.schools\n            ),\n            classes: mergeFilterOptions(\n              prev.apiFilterOptions.classes,\n              extracted.classes\n            ),\n            subjects: mergeFilterOptions(\n              prev.apiFilterOptions.subjects,\n              extracted.subjects\n            ),\n            schoolYears: mergeFilterOptions(\n              prev.apiFilterOptions.schoolYears,\n              extracted.schoolYears\n            ),\n          },\n        }));\n      } catch (error) {\n        console.error('Erro ao carregar histórico:', error);\n        setState((prev) => ({\n          ...prev,\n          loading: false,\n          error: 'Erro ao carregar histórico de atividades',\n        }));\n      }\n    },\n    [apiClient, options?.activityCategory]\n  );\n\n  return { ...state, fetchActivities };\n};\n\n/**\n * Factory function to create useActivitiesHistory hook\n *\n * @param apiClient - API client instance (axios, fetch wrapper, etc.)\n * @param options - Hook configuration options\n * @returns Hook for managing activities history\n *\n * @example\n * ```tsx\n * import { createUseActivitiesHistory } from 'analytica-frontend-lib';\n * import api from '@/services/apiService';\n *\n * const useActivitiesHistory = createUseActivitiesHistory(api, { activityCategory: 'ATIVIDADE' });\n *\n * // In your component\n * const { activities, loading, fetchActivities, apiFilterOptions } = useActivitiesHistory();\n * ```\n */\nexport const createUseActivitiesHistory = (\n  apiClient: BaseApiClient,\n  options?: UseActivitiesHistoryOptions\n) => {\n  return (): UseActivitiesHistoryReturn =>\n    useActivitiesHistoryImpl(apiClient, options);\n};\n\n/**\n * Alias for createUseActivitiesHistory\n */\nexport const createActivitiesHistoryHook = createUseActivitiesHistory;\n"],"mappings":"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","names":[]}