{"version":3,"sources":["../src/components/TimeReport/TimeReport.tsx"],"sourcesContent":["import { type HTMLAttributes, type ReactNode } from 'react';\nimport { TrendUpIcon } from '@phosphor-icons/react/dist/csr/TrendUp';\nimport { TrendDownIcon } from '@phosphor-icons/react/dist/csr/TrendDown';\nimport dayjs from 'dayjs';\nimport duration from 'dayjs/plugin/duration';\nimport Text from '../Text/Text';\nimport { cn } from '../../utils/utils';\nimport { PROFILE_ROLES } from '../../types/chat';\nimport type { StudentsHighlightPeriod } from '../../hooks/useStudentsHighlight';\nimport { ReportLayout } from '../shared/ReportLayout';\n\ndayjs.extend(duration);\n\n/**\n * API types - reusing existing enums/types from the project\n */\nexport { PROFILE_ROLES } from '../../types/chat';\nexport type { StudentsHighlightPeriod as TimeReportPeriod } from '../../hooks/useStudentsHighlight';\n\nexport interface TimeReportRequest {\n  period: StudentsHighlightPeriod;\n  profile?: PROFILE_ROLES;\n  school_group_ids?: string[];\n  school_ids?: string[];\n  all_school_groups?: boolean;\n}\n\nexport interface TimeMetric {\n  hours: number;\n  variation_percent: number | null;\n}\n\nexport interface CountMetric {\n  count: number;\n  variation_percent: number | null;\n}\n\nexport interface TimeReportData {\n  total_platform_time: TimeMetric;\n  activity_time: TimeMetric;\n  exam_simulation_time?: TimeMetric;\n  content_time?: TimeMetric;\n  questionnaire_time?: TimeMetric;\n  recommended_classes_time: TimeMetric;\n  total_access_count?: CountMetric;\n}\n\nexport interface TimeReportResponse {\n  message: string;\n  data: TimeReportData;\n}\n\n/**\n * Format decimal hours to \"Xh Ymin\" display string\n */\nexport const formatHoursToTime = (hours: number): string => {\n  const d = dayjs.duration(hours, 'hours');\n  const h = Math.floor(d.asHours());\n  const min = d.minutes();\n  return `${h}h ${min}min`;\n};\n\n/**\n * Get trend direction from variation percentage\n */\nexport const getTrendDirection = (\n  variationPercent: number | null\n): TimeCardTrend | undefined => {\n  if (variationPercent === null) return undefined;\n  return variationPercent >= 0 ? 'up' : 'down';\n};\n\n/**\n * Format variation percentage to display string (e.g., \"+12.3%\", \"-5.2%\")\n */\nexport const formatVariation = (\n  variationPercent: number | null\n): string | undefined => {\n  if (variationPercent === null) return undefined;\n  const sign = variationPercent >= 0 ? '+' : '';\n  return `${sign}${variationPercent}%`;\n};\n\n/**\n * Trend direction for time card indicators\n */\nexport type TimeCardTrend = 'up' | 'down';\n\n/**\n * Data for a single time card\n */\nexport interface TimeCardData {\n  /** Unique identifier */\n  id: string;\n  /** Uppercase label (e.g., \"TEMPO NA PLATAFORMA\") */\n  label: string;\n  /** Formatted time value (e.g., \"12h 20min\") */\n  value: string;\n  /** Icon element for the card */\n  icon: ReactNode;\n  /** Trend percentage string (e.g., \"+10%\", \"-5%\") */\n  trendValue?: string;\n  /** Trend direction - determines color */\n  trendDirection?: TimeCardTrend;\n  /** Optional footer text shown below the value (e.g., \"de 16.778 escolas\") */\n  footer?: ReactNode;\n  /**\n   * Plain gray line under the value (e.g., \"1 município • 134 escolas\"), for\n   * cards whose context is a breakdown rather than a trend. Rendered alongside\n   * the trend when both are present.\n   */\n  subtitle?: string;\n}\n\n/**\n * Tab configuration for the TimeReport component\n */\nexport interface TimeReportTab {\n  /** Unique value identifying this tab */\n  value: string;\n  /** Display label */\n  label: string;\n  /** Icon element for the tab header */\n  icon?: ReactNode;\n  /** Cards to display when this tab is active */\n  cards: TimeCardData[];\n}\n\n/**\n * Props for the TimeCard component\n */\nexport interface TimeCardProps extends HTMLAttributes<HTMLDivElement> {\n  /** Card data */\n  data: TimeCardData;\n}\n\n/**\n * Props for the TimeReport component\n */\nexport interface TimeReportProps extends HTMLAttributes<HTMLDivElement> {\n  /** Tab configurations with associated card data */\n  tabs: TimeReportTab[];\n  /** Default active tab value */\n  defaultTab?: string;\n  /** Controlled active tab value */\n  activeTab?: string;\n  /** Callback when active tab changes */\n  onTabChange?: (value: string) => void;\n}\n\n/**\n * Trend styling configuration\n */\nconst TREND_CONFIG = {\n  up: {\n    colorClass: 'text-success-500',\n    Icon: TrendUpIcon,\n  },\n  down: {\n    colorClass: 'text-error-500',\n    Icon: TrendDownIcon,\n  },\n} as const;\n\n/**\n * TimeCard component - displays a single time statistic\n */\nexport const TimeCard = ({ data, className, ...props }: TimeCardProps) => {\n  const { label, value, icon, trendValue, trendDirection, footer, subtitle } =\n    data;\n\n  return (\n    <div\n      className={cn(\n        'flex flex-col gap-3 p-5 bg-background border border-border-50 rounded-xl',\n        className\n      )}\n      data-testid={`time-card-${data.id}`}\n      {...props}\n    >\n      {/* Icon + Label */}\n      <div className=\"flex flex-row items-center gap-2\">\n        <span className=\"text-text-600 [&>svg]:w-4 [&>svg]:h-4\">{icon}</span>\n        <Text\n          weight=\"bold\"\n          className=\"text-text-600 uppercase text-[8px] leading-[100%]\"\n        >\n          {label}\n        </Text>\n      </div>\n\n      {/* Time value */}\n      <Text\n        size=\"2xl\"\n        weight=\"bold\"\n        className=\"text-primary-800 leading-[100%] tracking-[0.2px]\"\n      >\n        {value}\n      </Text>\n\n      {/* Context line (e.g., \"1 município • 134 escolas\") */}\n      {subtitle && (\n        <Text\n          size=\"sm\"\n          className=\"text-text-600 leading-[100%]\"\n          data-testid={`subtitle-${data.id}`}\n        >\n          {subtitle}\n        </Text>\n      )}\n\n      {/* Trend indicator */}\n      {trendValue && trendDirection && (\n        <div\n          className={cn(\n            'flex flex-row items-center gap-1',\n            TREND_CONFIG[trendDirection].colorClass\n          )}\n          data-testid={`trend-${data.id}`}\n        >\n          {(() => {\n            const TrendIcon = TREND_CONFIG[trendDirection].Icon;\n            return <TrendIcon size={16} weight=\"bold\" />;\n          })()}\n          <Text\n            size=\"xs\"\n            weight=\"bold\"\n            color=\"inherit\"\n            className=\"leading-[100%] uppercase\"\n          >\n            {trendValue}\n          </Text>\n        </div>\n      )}\n\n      {footer !== undefined && footer !== null && footer !== false && (\n        <Text as=\"div\" size=\"xs\" className=\"text-text-500 leading-[130%]\">\n          {footer}\n        </Text>\n      )}\n    </div>\n  );\n};\n\n/**\n * TimeReport component\n *\n * Displays time statistics organized in tabs, each with configurable cards.\n * Used in the manager report page to show platform access time metrics.\n *\n * @example\n * ```tsx\n * <TimeReport\n *   tabs={[\n *     {\n *       value: 'student',\n *       label: 'Estudante',\n *       icon: <Student size={17} />,\n *       cards: [\n *         { id: 'platform', label: 'TEMPO NA PLATAFORMA', value: '12h 20min', icon: <Monitor />, trendValue: '+10%', trendDirection: 'up' },\n *       ],\n *     },\n *   ]}\n *   onTabChange={(tab) => console.log(tab)}\n * />\n * ```\n */\nexport const TimeReport = ({\n  tabs,\n  defaultTab,\n  activeTab,\n  onTabChange,\n  className,\n  ...props\n}: TimeReportProps) => (\n  <ReportLayout\n    tabs={tabs}\n    defaultTab={defaultTab}\n    activeTab={activeTab}\n    onTabChange={onTabChange}\n    renderCard={(card) => <TimeCard key={card.id} data={card} />}\n    gridTestId=\"time-report-cards\"\n    className={className}\n    {...props}\n  />\n);\n\nexport default TimeReport;\n"],"mappings":"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","names":[]}