analytica-frontend-lib
Version:
Repositório público dos componentes utilizados nas plataformas da Analytica Ensino
1 lines • 12 kB
Source Map (JSON)
{"version":3,"sources":["../src/components/PerformanceQuestionsData/PerformanceQuestionsData.tsx"],"sourcesContent":["import { type HTMLAttributes, type ReactNode } from 'react';\nimport Text from '../Text/Text';\nimport Select, {\n SelectTrigger,\n SelectValue,\n SelectContent,\n SelectItem,\n} from '../Select/Select';\nimport { cn } from '../../utils/utils';\nimport { PROFILE_ROLES } from '../../types/chat';\nimport type { StudentsHighlightPeriod } from '../../hooks/useStudentsHighlight';\nimport {\n calculateYAxisTicks,\n LegendItem,\n DataBar,\n GridLines,\n YAxis,\n type BarItemConfig,\n} from '../shared/ChartComponents';\n\n/**\n * Re-export period type for API consumers\n */\nexport type { StudentsHighlightPeriod as PerformanceQuestionsPeriod } from '../../hooks/useStudentsHighlight';\n\n// --- Variant data shapes ---\n\n/**\n * Data for STUDENT variant: question statistics\n */\nexport interface QuestionsVariantData {\n total: number;\n correct: number;\n incorrect: number;\n blank: number;\n}\n\n/**\n * Data for non-STUDENT variant: produced content\n */\nexport interface ContentVariantData {\n total: number;\n totalActivities: number;\n totalRecommendedLessons: number;\n}\n\n// --- Filter types ---\n\nexport interface PerformanceFilterOption {\n value: string;\n label: string;\n}\n\nexport interface PerformanceFilterConfig {\n options: PerformanceFilterOption[];\n value: string;\n onChange: (value: string) => void;\n placeholder?: string;\n /** Icon rendered before the select value */\n icon?: ReactNode;\n}\n\n// --- API types ---\n\nexport interface PerformanceQuestionsRequest {\n period: StudentsHighlightPeriod;\n targetProfile: PROFILE_ROLES;\n schoolIds?: string[];\n schoolGroupIds?: string[];\n allSchoolGroupsSelected?: boolean;\n subjectIds?: string[];\n allSubjectsSelected?: boolean;\n activityTypes?: string[];\n}\n\nexport interface PerformanceQuestionsStudentResponse {\n message: string;\n data: QuestionsVariantData;\n}\n\nexport interface PerformanceQuestionsDefaultResponse {\n message: string;\n data: ContentVariantData;\n}\n\n// --- Component types ---\n\nexport enum PerformanceQuestionsVariant {\n QUESTIONS = 'questions',\n CONTENT = 'content',\n}\n\nexport interface PerformanceQuestionsDataProps extends HTMLAttributes<HTMLDivElement> {\n /** Variant determines title, bars, and colors */\n variant: PerformanceQuestionsVariant;\n /** Chart data (shape depends on variant) */\n data: QuestionsVariantData | ContentVariantData;\n /** Subject/discipline filter configuration */\n subjectFilter?: PerformanceFilterConfig;\n /** Activity type filter configuration */\n activityTypeFilter?: PerformanceFilterConfig;\n /** Maximum value for the chart scale (defaults to total) */\n maxValue?: number;\n /** Height of the chart area in pixels */\n chartHeight?: number;\n}\n\n// --- Bar color constants ---\n\nconst QUESTIONS_COLORS = {\n total: 'bg-info-600',\n correct: 'bg-success-200',\n incorrect: 'bg-warning-400',\n blank: 'bg-background-300',\n} as const;\n\nconst CONTENT_COLORS = {\n total: 'bg-info-600',\n totalActivities: 'bg-success-700',\n totalRecommendedLessons: 'bg-warning-300',\n} as const;\n\n// --- Variant titles ---\n\nconst VARIANT_TITLES: Record<PerformanceQuestionsVariant, string> = {\n questions: 'Dados de questões',\n content: 'Dados de material produzido',\n};\n\n// --- Bar builders ---\n\n/**\n * Build bar items for the \"questions\" variant (STUDENT)\n */\nconst buildQuestionsBarItems = (\n data: QuestionsVariantData\n): BarItemConfig[] => [\n {\n key: 'total',\n label: 'Total',\n legendLabel: 'Total de questões respondidas',\n value: data.total,\n colorClass: QUESTIONS_COLORS.total,\n },\n {\n key: 'correct',\n label: 'Corretas',\n legendLabel: 'Questões corretas',\n value: data.correct,\n colorClass: QUESTIONS_COLORS.correct,\n },\n {\n key: 'incorrect',\n label: 'Incorretas',\n legendLabel: 'Questões incorretas',\n value: data.incorrect,\n colorClass: QUESTIONS_COLORS.incorrect,\n },\n {\n key: 'blank',\n label: 'Em branco',\n legendLabel: 'Questões em branco',\n value: data.blank,\n colorClass: QUESTIONS_COLORS.blank,\n },\n];\n\n/**\n * Build bar items for the \"content\" variant (non-STUDENT)\n */\nconst buildContentBarItems = (data: ContentVariantData): BarItemConfig[] => [\n {\n key: 'total',\n label: 'Total',\n legendLabel: 'Total',\n value: data.total,\n colorClass: CONTENT_COLORS.total,\n },\n {\n key: 'totalActivities',\n label: 'Atividades',\n legendLabel: 'Atividades',\n value: data.totalActivities,\n colorClass: CONTENT_COLORS.totalActivities,\n },\n {\n key: 'totalRecommendedLessons',\n label: 'Aulas recomendadas',\n legendLabel: 'Aulas recomendadas',\n value: data.totalRecommendedLessons,\n colorClass: CONTENT_COLORS.totalRecommendedLessons,\n },\n];\n\n// --- Sub-components ---\n\nconst FilterSelect = ({ filter }: { filter: PerformanceFilterConfig }) => (\n <Select\n value={filter.value}\n onValueChange={filter.onChange}\n size=\"small\"\n className=\"w-auto\"\n >\n <SelectTrigger\n variant=\"outlined\"\n className=\"whitespace-nowrap overflow-hidden\"\n >\n {filter.icon && (\n <span className=\"text-text-700 [&>svg]:w-4 [&>svg]:h-4 mr-2 flex-shrink-0\">\n {filter.icon}\n </span>\n )}\n <span className=\"truncate\">\n <SelectValue placeholder={filter.placeholder} />\n </span>\n </SelectTrigger>\n <SelectContent>\n {filter.options.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n);\n\n// --- Main component ---\n\n/**\n * PerformanceQuestionsData component - displays a vertical bar chart\n * with variant-specific data for performance reports.\n *\n * - `variant=\"questions\"` (STUDENT): Total, Correct, Incorrect, Blank\n * - `variant=\"content\"` (non-STUDENT): Total, Activities, Recommended Lessons\n *\n * Includes optional integrated Select filters for subjects and activity types.\n *\n * @example\n * ```tsx\n * <PerformanceQuestionsData\n * variant=\"questions\"\n * data={{ total: 100, correct: 60, incorrect: 30, blank: 10 }}\n * subjectFilter={{\n * options: [{ value: 'all', label: 'Todos componentes' }],\n * value: 'all',\n * onChange: (v) => setSubject(v),\n * placeholder: 'Todos componentes',\n * }}\n * />\n * ```\n */\nexport const PerformanceQuestionsData = ({\n variant,\n data,\n subjectFilter,\n activityTypeFilter,\n maxValue,\n chartHeight = 180,\n className,\n ...props\n}: PerformanceQuestionsDataProps) => {\n const title = VARIANT_TITLES[variant];\n\n const barItems =\n variant === PerformanceQuestionsVariant.QUESTIONS\n ? buildQuestionsBarItems(data as QuestionsVariantData)\n : buildContentBarItems(data as ContentVariantData);\n\n const chartMaxValue = maxValue ?? data.total;\n const yAxisTicks = calculateYAxisTicks(chartMaxValue);\n const adjustedMaxValue = yAxisTicks[0];\n\n return (\n <div\n className={cn(\n 'flex flex-col p-5 gap-4 bg-background border border-border-50 rounded-xl',\n className\n )}\n {...props}\n >\n {/* Header: title + filters */}\n <div className=\"flex flex-row items-center justify-between gap-4\">\n <Text\n as=\"h3\"\n size=\"lg\"\n weight=\"bold\"\n className=\"text-text-950 tracking-[0.2px]\"\n >\n {title}\n </Text>\n\n {(subjectFilter || activityTypeFilter) && (\n <div className=\"flex flex-row gap-3\">\n {subjectFilter && <FilterSelect filter={subjectFilter} />}\n {activityTypeFilter && <FilterSelect filter={activityTypeFilter} />}\n </div>\n )}\n </div>\n\n {/* Legend */}\n <div className=\"flex flex-row flex-wrap gap-x-6 gap-y-2 mb-4\">\n {barItems.map((item) => (\n <LegendItem\n key={item.key}\n color={item.colorClass}\n label={item.legendLabel}\n />\n ))}\n </div>\n\n {/* Chart */}\n <div className=\"flex flex-row\">\n <YAxis ticks={yAxisTicks} chartHeight={chartHeight} />\n <div className=\"w-4\" />\n <div className=\"flex-1 relative\">\n <GridLines ticks={yAxisTicks} chartHeight={chartHeight} />\n <div className=\"flex flex-row flex-1 gap-4 relative z-10\">\n {barItems.map((item) => (\n <DataBar\n key={item.key}\n label={item.label}\n value={item.value}\n maxValue={adjustedMaxValue}\n colorClass={item.colorClass}\n chartHeight={chartHeight}\n />\n ))}\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nexport default PerformanceQuestionsData;\n"],"mappings":"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","names":["PerformanceQuestionsVariant"]}