UNPKG

analytica-frontend-lib

Version:

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

312 lines (310 loc) 11.1 kB
import { DEFAULT_PERFORMANCE_DETAILS_LABELS } from "./chunk-ILQ33JG4.mjs"; import { MetricBox } from "./chunk-G5AMZYLQ.mjs"; import { CardAccordation } from "./chunk-2ACDTDO4.mjs"; import { ProgressBar_default } from "./chunk-LDBWF6EA.mjs"; import { Badge_default } from "./chunk-OEW3ST4F.mjs"; import { Modal_default } from "./chunk-TNLGS7SB.mjs"; import { Text_default } from "./chunk-IMCIR6TJ.mjs"; // src/components/StudentPerformanceDetailsModal/StudentPerformanceDetailsModal.tsx import { useMemo } from "react"; import { UserIcon, TrophyIcon, XCircleIcon } from "@phosphor-icons/react"; import { jsx, jsxs } from "react/jsx-runtime"; var STAT_CARD_COLORS = { orange: { headerBg: "bg-warning-background", iconBg: "bg-warning-300", valueColor: "text-warning-600", secondaryLabelColor: "text-warning-500" }, green: { headerBg: "bg-success-200", iconBg: "bg-success-300", valueColor: "text-success-700", secondaryLabelColor: "text-success-600" }, red: { headerBg: "bg-error-100", iconBg: "bg-error-500", valueColor: "text-error-700", secondaryLabelColor: "text-error-300" }, default: { headerBg: "bg-warning-background", iconBg: "bg-warning-300", valueColor: "text-warning-600", secondaryLabelColor: "text-warning-500" } }; var PerformanceStatCard = ({ icon, label, value, secondaryLabel, badgeText, variant }) => { const colors = STAT_CARD_COLORS[variant] ?? STAT_CARD_COLORS.default; return /* @__PURE__ */ jsxs("div", { className: "flex flex-col rounded-xl border border-border-50 bg-background overflow-hidden flex-1", children: [ /* @__PURE__ */ jsxs( "div", { className: `flex flex-col items-center justify-center px-2 sm:px-3 py-2 gap-1 ${colors.headerBg}`, children: [ /* @__PURE__ */ jsx( Text_default, { as: "span", className: `size-8 rounded-full flex items-center justify-center ${colors.iconBg}`, children: icon } ), /* @__PURE__ */ jsx( Text_default, { size: "2xs", weight: "medium", className: "text-text-800 uppercase text-center leading-none", children: label } ), /* @__PURE__ */ jsx( Text_default, { size: "xl", weight: "bold", className: `${colors.valueColor} text-center`, children: value } ) ] } ), /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2 px-2 sm:px-3 py-2", children: [ /* @__PURE__ */ jsx( Text_default, { size: "2xs", weight: "medium", className: `${colors.secondaryLabelColor} uppercase text-center`, children: secondaryLabel } ), /* @__PURE__ */ jsx(Badge_default, { size: "large", action: "info", children: badgeText || "-" }) ] }) ] }); }; var formatProgressText = (template, correct, total) => { return template.replace("{correct}", String(correct)).replace("{total}", String(total)); }; var ActivityAccordionCard = ({ activity, noDataMessage, activityProgressText, activityDetailsUnavailable }) => { const hasData = !activity.hasNoData && activity.totalCount > 0; const progressPercentage = hasData ? Math.min( 100, Math.max(0, activity.correctCount / activity.totalCount * 100) ) : 0; return /* @__PURE__ */ jsx( CardAccordation, { value: activity.id, className: "bg-background rounded-xl border border-border-50", triggerClassName: "p-4", contentClassName: "px-4 pb-4", trigger: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 flex-1", children: [ /* @__PURE__ */ jsx(Text_default, { size: "lg", weight: "bold", className: "text-text-950", children: activity.name }), hasData ? /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center gap-2", children: [ /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx( ProgressBar_default, { value: progressPercentage, variant: "green", size: "medium" } ) }), /* @__PURE__ */ jsx( Text_default, { size: "xs", weight: "medium", className: "text-text-950 whitespace-nowrap", children: formatProgressText( activityProgressText, activity.correctCount, activity.totalCount ) } ) ] }) : /* @__PURE__ */ jsx(Text_default, { size: "xs", className: "text-text-500", children: noDataMessage }) ] }), children: /* @__PURE__ */ jsx(Text_default, { size: "sm", className: "text-text-700", children: activity.description || activityDetailsUnavailable }) } ); }; var LoadingSkeleton = () => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 animate-pulse", children: [ /* @__PURE__ */ jsx("div", { className: "h-6 bg-background-200 rounded w-48" }), /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-3 gap-2", children: [ /* @__PURE__ */ jsx("div", { className: "h-48 bg-background-200 rounded-xl" }), /* @__PURE__ */ jsx("div", { className: "h-48 bg-background-200 rounded-xl" }), /* @__PURE__ */ jsx("div", { className: "h-48 bg-background-200 rounded-xl" }) ] }), /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-2", children: [ /* @__PURE__ */ jsx("div", { className: "h-20 bg-background-200 rounded-xl" }), /* @__PURE__ */ jsx("div", { className: "h-20 bg-background-200 rounded-xl" }) ] }), /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-3 gap-2", children: [ /* @__PURE__ */ jsx("div", { className: "h-20 bg-background-200 rounded-xl" }), /* @__PURE__ */ jsx("div", { className: "h-20 bg-background-200 rounded-xl" }), /* @__PURE__ */ jsx("div", { className: "h-20 bg-background-200 rounded-xl" }) ] }) ] }); var ErrorContent = ({ message }) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center py-8 gap-3", children: [ /* @__PURE__ */ jsx( Text_default, { as: "span", className: "size-12 rounded-full bg-error-100 flex items-center justify-center", children: /* @__PURE__ */ jsx(XCircleIcon, { size: 24, className: "text-error-700", weight: "fill" }) } ), /* @__PURE__ */ jsx(Text_default, { size: "md", className: "text-error-700 text-center", children: message }) ] }); var PerformanceContent = ({ data, labels }) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 pt-2", children: [ /* @__PURE__ */ jsx( Text_default, { as: "span", className: "size-6 rounded-full bg-primary-100 flex items-center justify-center", children: /* @__PURE__ */ jsx(UserIcon, { size: 14, className: "text-primary-800", weight: "fill" }) } ), /* @__PURE__ */ jsx(Text_default, { size: "md", className: "text-text-950", children: data.studentName }) ] }), /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row gap-2 sm:gap-3", children: [ /* @__PURE__ */ jsx( PerformanceStatCard, { icon: /* @__PURE__ */ jsx(TrophyIcon, { size: 16, weight: "fill", className: "text-white" }), label: labels.gradeLabel, value: data.grade.value.toFixed(1), secondaryLabel: labels.performanceTagLabel, badgeText: data.grade.performanceLabel, variant: "orange" } ), /* @__PURE__ */ jsx( PerformanceStatCard, { icon: /* @__PURE__ */ jsx(TrophyIcon, { size: 16, weight: "fill", className: "text-text-950" }), label: labels.correctQuestionsLabel, value: data.correctQuestions.value, secondaryLabel: labels.bestResultLabel, badgeText: data.correctQuestions.bestResultTopic, variant: "green" } ), /* @__PURE__ */ jsx( PerformanceStatCard, { icon: /* @__PURE__ */ jsx(XCircleIcon, { size: 16, weight: "fill", className: "text-white" }), label: labels.incorrectQuestionsLabel, value: data.incorrectQuestions.value, secondaryLabel: labels.hardestTopicLabel, badgeText: data.incorrectQuestions.hardestTopic, variant: "red" } ) ] }), /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-2 sm:gap-3", children: [ /* @__PURE__ */ jsx( MetricBox, { label: labels.activitiesLabel, value: data.activitiesCompleted } ), /* @__PURE__ */ jsx(MetricBox, { label: labels.questionsLabel, value: data.questionsAnswered }) ] }), /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 sm:grid-cols-3 gap-2 sm:gap-3", children: [ /* @__PURE__ */ jsx(MetricBox, { label: labels.accessCountLabel, value: data.accessCount }), /* @__PURE__ */ jsx(MetricBox, { label: labels.timeOnlineLabel, value: data.timeOnline }), /* @__PURE__ */ jsx(MetricBox, { label: labels.lastLoginLabel, value: data.lastLogin }) ] }), data.activities.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 pt-4", children: [ /* @__PURE__ */ jsx(Text_default, { size: "lg", weight: "bold", className: "text-text-950", children: labels.activitiesProgressTitle }), /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: data.activities.map((activity) => /* @__PURE__ */ jsx( ActivityAccordionCard, { activity, noDataMessage: labels.noDataMessage, activityProgressText: labels.activityProgressText, activityDetailsUnavailable: labels.activityDetailsUnavailable }, activity.id )) }) ] }) ] }); var renderModalContent = (loading, error, data, labels) => { if (loading) { return /* @__PURE__ */ jsx(LoadingSkeleton, {}); } if (error) { return /* @__PURE__ */ jsx(ErrorContent, { message: error }); } if (data) { return /* @__PURE__ */ jsx(PerformanceContent, { data, labels }); } return null; }; var StudentPerformanceDetailsModal = ({ isOpen, onClose, data, loading = false, error = null, labels: customLabels }) => { const labels = useMemo( () => ({ ...DEFAULT_PERFORMANCE_DETAILS_LABELS, ...customLabels }), [customLabels] ); if (!data && !loading && !error) { return null; } return /* @__PURE__ */ jsx( Modal_default, { isOpen, onClose, title: labels.title, size: "lg", contentClassName: "max-h-[80vh] overflow-y-auto", children: renderModalContent(loading, error, data, labels) } ); }; export { StudentPerformanceDetailsModal }; //# sourceMappingURL=chunk-WPIILK4I.mjs.map