UNPKG

analytica-frontend-lib

Version:

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

1,450 lines (1,448 loc) 53.7 kB
import { ProgressBar_default } from "./chunk-LDBWF6EA.mjs"; import { IconRender_default } from "./chunk-QEZJZHJG.mjs"; import { Badge_default } from "./chunk-OEW3ST4F.mjs"; import { Button_default } from "./chunk-LAYB7IKW.mjs"; import { Text_default } from "./chunk-IMCIR6TJ.mjs"; import { cn } from "./chunk-53ICLDGS.mjs"; // src/components/Card/Card.tsx import { forwardRef, Fragment, useState, useRef, useEffect } from "react"; import { CaretRightIcon } from "@phosphor-icons/react/dist/csr/CaretRight"; import { ChatCircleTextIcon } from "@phosphor-icons/react/dist/csr/ChatCircleText"; import { CheckCircleIcon } from "@phosphor-icons/react/dist/csr/CheckCircle"; import { ClockIcon } from "@phosphor-icons/react/dist/csr/Clock"; import { DotsThreeVerticalIcon } from "@phosphor-icons/react/dist/csr/DotsThreeVertical"; import { PlayIcon } from "@phosphor-icons/react/dist/csr/Play"; import { SpeakerHighIcon } from "@phosphor-icons/react/dist/csr/SpeakerHigh"; import { SpeakerLowIcon } from "@phosphor-icons/react/dist/csr/SpeakerLow"; import { SpeakerSimpleXIcon } from "@phosphor-icons/react/dist/csr/SpeakerSimpleX"; import { XCircleIcon } from "@phosphor-icons/react/dist/csr/XCircle"; import { Fragment as Fragment2, jsx, jsxs } from "react/jsx-runtime"; var CARD_BASE_CLASSES = { default: "w-full bg-background border border-border-50 rounded-xl", compact: "w-full bg-background border border-border-50 rounded-lg", minimal: "w-full bg-background border border-border-100 rounded-md" }; var CARD_PADDING_CLASSES = { none: "", small: "p-2", medium: "p-4", large: "p-6" }; var CARD_MIN_HEIGHT_CLASSES = { none: "", small: "min-h-16", medium: "min-h-20", large: "min-h-24" }; var CARD_LAYOUT_CLASSES = { horizontal: "flex flex-row", vertical: "flex flex-col" }; var CARD_CURSOR_CLASSES = { default: "", pointer: "cursor-pointer" }; var CardBase = forwardRef( ({ children, variant = "default", layout = "horizontal", padding = "medium", minHeight = "medium", cursor = "default", className = "", onClick, onKeyDown, ...props }, ref) => { const baseClasses = CARD_BASE_CLASSES[variant]; const paddingClasses = CARD_PADDING_CLASSES[padding]; const minHeightClasses = CARD_MIN_HEIGHT_CLASSES[minHeight]; const layoutClasses = CARD_LAYOUT_CLASSES[layout]; const cursorClasses = CARD_CURSOR_CLASSES[cursor]; const isInteractive = !!onClick; const handleKeyDown = (e) => { if (isInteractive && ["Enter", " "].includes(e.key)) { e.preventDefault(); e.currentTarget.click(); } onKeyDown?.(e); }; return /* @__PURE__ */ jsx( "div", { ref, className: cn( baseClasses, paddingClasses, minHeightClasses, layoutClasses, cursorClasses, className ), onClick, onKeyDown: handleKeyDown, tabIndex: isInteractive ? 0 : void 0, role: isInteractive ? "button" : void 0, ...props, children } ); } ); var ACTION_CARD_CLASSES = { warning: "bg-warning-background", success: "bg-success-200", error: "bg-error-100", info: "bg-info-background" }; var ACTION_ICON_CLASSES = { warning: "bg-warning-300 text-text", success: "bg-indicator-positive text-text-950", error: "bg-indicator-negative text-text", info: "bg-info-500 text-text" }; var ACTION_SUBTITLE_CLASSES = { warning: "text-warning-600", success: "text-success-700", error: "text-error-700", info: "text-info-700" }; var ACTION_HEADER_CLASSES = { warning: "text-warning-300", success: "text-success-300", error: "text-error-300", info: "text-info-300" }; var CardActivitiesResults = forwardRef( ({ icon, title, subTitle, header, extended = false, action = "success", description, className, ...props }, ref) => { const actionCardClasses = ACTION_CARD_CLASSES[action]; const actionIconClasses = ACTION_ICON_CLASSES[action]; const actionSubTitleClasses = ACTION_SUBTITLE_CLASSES[action]; const actionHeaderClasses = ACTION_HEADER_CLASSES[action]; return /* @__PURE__ */ jsxs( "div", { ref, className: cn( "w-full flex flex-col rounded-xl", extended && "border border-border-50 bg-background", className ), ...props, children: [ /* @__PURE__ */ jsxs( "div", { className: cn( "flex flex-col gap-1 items-center justify-center p-4", actionCardClasses, extended ? "rounded-t-xl" : "rounded-xl" ), children: [ /* @__PURE__ */ jsx( "span", { className: cn( "size-7.5 rounded-full flex items-center justify-center", actionIconClasses ), children: icon } ), /* @__PURE__ */ jsx( Text_default, { size: "2xs", weight: "medium", className: "text-text-800 uppercase truncate", children: title } ), /* @__PURE__ */ jsx( "p", { className: cn("text-lg font-bold truncate", actionSubTitleClasses), children: subTitle } ) ] } ), extended && /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2.5 pb-9.5 pt-2.5", children: [ /* @__PURE__ */ jsx( "p", { className: cn( "text-2xs font-medium uppercase truncate", actionHeaderClasses ), children: header } ), /* @__PURE__ */ jsx(Badge_default, { size: "large", action: "info", children: description }) ] }) ] } ); } ); var CardQuestions = forwardRef( ({ header, state = "undone", className, onClickButton, valueButton, ...props }, ref) => { const getStateConfig = () => { switch (state) { case "done": return { label: "Realizado", buttonLabel: "Ver Resultado", badgeAction: "success" }; case "pending": return { label: "Aguardando corre\xE7\xE3o", buttonLabel: "Ver Resultado", badgeAction: "info" }; default: return { label: "N\xE3o Realizado", buttonLabel: "Responder", badgeAction: "error" }; } }; const { label, buttonLabel, badgeAction } = getStateConfig(); return /* @__PURE__ */ jsxs( CardBase, { ref, layout: "horizontal", padding: "medium", minHeight: "medium", className: cn("justify-between gap-4", className), ...props, children: [ /* @__PURE__ */ jsxs("section", { className: "flex flex-col gap-1 flex-1 min-w-0", children: [ /* @__PURE__ */ jsx("p", { className: "font-bold text-xs text-text-950 truncate", children: header }), /* @__PURE__ */ jsx("div", { className: "flex flex-row gap-6 items-center", children: /* @__PURE__ */ jsx(Badge_default, { size: "medium", variant: "solid", action: badgeAction, children: label }) }) ] }), /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx( Button_default, { size: "extra-small", onClick: () => onClickButton?.(valueButton), className: "min-w-fit", children: buttonLabel } ) }) ] } ); } ); var CardProgress = forwardRef( ({ header, subhead, initialDate, endDate, progress = 0, direction = "horizontal", icon, color = "#B7DFFF", progressVariant = "blue", showDates = true, className, ...props }, ref) => { const isHorizontal = direction === "horizontal"; const contentComponent = { horizontal: /* @__PURE__ */ jsxs(Fragment2, { children: [ showDates && /* @__PURE__ */ jsxs("div", { className: "flex flex-row gap-6 items-center", children: [ initialDate && /* @__PURE__ */ jsxs("span", { className: "flex flex-row gap-1 items-center text-2xs", children: [ /* @__PURE__ */ jsx("p", { className: "text-text-800 font-semibold", children: "In\xEDcio" }), /* @__PURE__ */ jsx("p", { className: "text-text-600", children: initialDate }) ] }), endDate && /* @__PURE__ */ jsxs("span", { className: "flex flex-row gap-1 items-center text-2xs", children: [ /* @__PURE__ */ jsx("p", { className: "text-text-800 font-semibold", children: "Fim" }), /* @__PURE__ */ jsx("p", { className: "text-text-600", children: endDate }) ] }) ] }), /* @__PURE__ */ jsxs("span", { className: "grid grid-cols-[1fr_auto] items-center gap-2", children: [ /* @__PURE__ */ jsx( ProgressBar_default, { size: "small", value: progress, variant: progressVariant, "data-testid": "progress-bar" } ), /* @__PURE__ */ jsxs( Text_default, { size: "xs", weight: "medium", className: cn( "text-text-950 leading-none tracking-normal text-center flex-none" ), children: [ Math.round(progress), "%" ] } ) ] }) ] }), vertical: /* @__PURE__ */ jsx("p", { className: "text-sm text-text-800", children: subhead }) }; return /* @__PURE__ */ jsxs( CardBase, { ref, layout: isHorizontal ? "horizontal" : "vertical", padding: "none", minHeight: "medium", cursor: "pointer", className: cn(isHorizontal ? "h-20" : "", className), ...props, children: [ /* @__PURE__ */ jsx( "div", { className: cn( "flex justify-center items-center [&>svg]:size-6 text-text-950", isHorizontal ? "min-w-[80px] min-h-[80px] rounded-l-xl" : "min-h-[50px] w-full rounded-t-xl", !color.startsWith("#") ? `${color}` : "" ), style: color.startsWith("#") ? { backgroundColor: color } : void 0, "data-testid": "icon-container", children: icon } ), /* @__PURE__ */ jsxs( "div", { className: cn( "p-4 flex flex-col justify-between w-full h-full", !isHorizontal && "gap-4" ), children: [ /* @__PURE__ */ jsx(Text_default, { size: "sm", weight: "bold", className: "text-text-950 truncate", children: header }), contentComponent[direction] ] } ) ] } ); } ); var CardTopic = forwardRef( ({ header, subHead, progress, showPercentage = false, progressVariant = "blue", className = "", ...props }, ref) => { return /* @__PURE__ */ jsxs( CardBase, { ref, layout: "vertical", padding: "small", minHeight: "medium", cursor: "pointer", className: cn("justify-center gap-2 py-2 px-4", className), ...props, children: [ subHead && /* @__PURE__ */ jsx("span", { className: "text-text-600 text-2xs flex flex-row gap-1", children: subHead.map((text, index) => /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx("p", { children: text }), index < subHead.length - 1 && /* @__PURE__ */ jsx("p", { children: "\u2022" }) ] }, `${text} - ${index}`)) }), /* @__PURE__ */ jsx("p", { className: "text-sm text-text-950 font-bold truncate", children: header }), /* @__PURE__ */ jsxs("span", { className: "grid grid-cols-[1fr_auto] items-center gap-2", children: [ /* @__PURE__ */ jsx( ProgressBar_default, { size: "small", value: progress, variant: progressVariant, "data-testid": "progress-bar" } ), showPercentage && /* @__PURE__ */ jsxs( Text_default, { size: "xs", weight: "medium", className: cn( "text-text-950 leading-none tracking-normal text-center flex-none" ), children: [ Math.round(progress), "%" ] } ) ] }) ] } ); } ); var CardPerformance = forwardRef( ({ header, progress, description = "Sem dados ainda! Voc\xEA ainda n\xE3o fez um question\xE1rio neste assunto.", actionVariant = "button", progressVariant = "blue", labelProgress = "", className = "", onClickButton, valueButton, ...props }, ref) => { const hasProgress = progress !== void 0; return /* @__PURE__ */ jsxs( CardBase, { ref, layout: "horizontal", padding: "medium", minHeight: "none", className: cn( actionVariant == "caret" ? "cursor-pointer" : "", className ), onClick: () => actionVariant == "caret" && onClickButton?.(valueButton), ...props, children: [ /* @__PURE__ */ jsxs("div", { className: "w-full flex flex-col justify-between gap-2", children: [ /* @__PURE__ */ jsxs("div", { className: "flex flex-row justify-between items-center gap-2", children: [ /* @__PURE__ */ jsx("p", { className: "text-lg font-bold text-text-950 truncate flex-1 min-w-0", children: header }), actionVariant === "button" && /* @__PURE__ */ jsx( Button_default, { variant: "outline", size: "extra-small", onClick: () => onClickButton?.(valueButton), className: "min-w-fit flex-shrink-0", children: "Ver Aula" } ) ] }), /* @__PURE__ */ jsx("div", { className: "w-full", children: hasProgress ? /* @__PURE__ */ jsx( ProgressBar_default, { value: progress, label: `${progress}% ${labelProgress}`, variant: progressVariant } ) : /* @__PURE__ */ jsx("p", { className: "text-xs text-text-600 truncate", children: description }) }) ] }), actionVariant == "caret" && /* @__PURE__ */ jsx( CaretRightIcon, { className: "size-4.5 text-text-800 cursor-pointer", "data-testid": "caret-icon" } ) ] } ); } ); var CardResults = forwardRef( ({ header, correct_answers, incorrect_answers, icon, direction = "col", color = "#B7DFFF", className, ...props }, ref) => { const isRow = direction == "row"; return /* @__PURE__ */ jsxs( CardBase, { ref, layout: "horizontal", padding: "none", minHeight: "medium", className: cn("items-stretch cursor-pointer pr-4", className), ...props, children: [ /* @__PURE__ */ jsx( "div", { className: cn( "flex justify-center items-center [&>svg]:size-8 text-text-950 min-w-20 max-w-20 min-h-full rounded-l-xl" ), style: { backgroundColor: color }, children: /* @__PURE__ */ jsx(IconRender_default, { iconName: icon, color: "currentColor", size: 20 }) } ), /* @__PURE__ */ jsxs("div", { className: "w-full flex flex-row justify-between items-center", children: [ /* @__PURE__ */ jsxs( "div", { className: cn( "p-4 flex flex-wrap justify-between w-full h-full", isRow ? "flex-row items-center gap-2" : "flex-col" ), children: [ /* @__PURE__ */ jsx("p", { className: "text-sm font-bold text-text-950 flex-1", children: header }), /* @__PURE__ */ jsxs("span", { className: "flex flex-wrap flex-row gap-1 items-center", children: [ /* @__PURE__ */ jsxs( Badge_default, { action: "success", variant: "solid", size: "large", iconLeft: /* @__PURE__ */ jsx(CheckCircleIcon, {}), children: [ correct_answers, " Corretas" ] } ), /* @__PURE__ */ jsxs( Badge_default, { action: "error", variant: "solid", size: "large", iconLeft: /* @__PURE__ */ jsx(XCircleIcon, {}), children: [ incorrect_answers, " Incorretas" ] } ) ] }) ] } ), /* @__PURE__ */ jsx(CaretRightIcon, { className: "min-w-6 min-h-6 text-text-800" }) ] }) ] } ); } ); var CardStatus = forwardRef( ({ header, className, status, label, ...props }, ref) => { const getLabelBadge = (status2) => { switch (status2) { case "correct": return "Correta"; case "incorrect": return "Incorreta"; case "unanswered": return "Em branco"; case "pending": return "Avalia\xE7\xE3o pendente"; default: return "Em branco"; } }; const getIconBadge = (status2) => { switch (status2) { case "correct": return /* @__PURE__ */ jsx(CheckCircleIcon, {}); case "incorrect": return /* @__PURE__ */ jsx(XCircleIcon, {}); case "pending": return /* @__PURE__ */ jsx(ClockIcon, {}); default: return /* @__PURE__ */ jsx(XCircleIcon, {}); } }; const getActionBadge = (status2) => { switch (status2) { case "correct": return "success"; case "incorrect": return "error"; case "pending": return "info"; default: return "info"; } }; return /* @__PURE__ */ jsx( CardBase, { ref, layout: "horizontal", padding: "medium", minHeight: "medium", className: cn("items-center cursor-pointer", className), ...props, children: /* @__PURE__ */ jsxs("div", { className: "flex justify-between w-full h-full flex-row items-center gap-2", children: [ /* @__PURE__ */ jsx("p", { className: "text-sm font-bold text-text-950 truncate flex-1 min-w-0", children: header }), /* @__PURE__ */ jsxs("span", { className: "flex flex-row gap-1 items-center flex-shrink-0", children: [ status && /* @__PURE__ */ jsx( Badge_default, { action: getActionBadge(status), variant: "solid", size: "medium", iconLeft: getIconBadge(status), children: getLabelBadge(status) } ), label && /* @__PURE__ */ jsx("p", { className: "text-sm text-text-800", children: label }) ] }), /* @__PURE__ */ jsx(CaretRightIcon, { className: "min-w-6 min-h-6 text-text-800 cursor-pointer flex-shrink-0 ml-2" }) ] }) } ); } ); var CardSettings = forwardRef( ({ header, className, icon, ...props }, ref) => { return /* @__PURE__ */ jsxs( CardBase, { ref, layout: "horizontal", padding: "small", minHeight: "none", className: cn( "border-none items-center gap-2 text-text-700", className ), ...props, children: [ /* @__PURE__ */ jsx("span", { className: "[&>svg]:size-6", children: icon }), /* @__PURE__ */ jsx("p", { className: "w-full text-sm truncate", children: header }), /* @__PURE__ */ jsx(CaretRightIcon, { size: 24, className: "cursor-pointer" }) ] } ); } ); var CardSupport = forwardRef( ({ header, className, direction = "col", children, ...props }, ref) => { return /* @__PURE__ */ jsxs( CardBase, { ref, layout: "horizontal", padding: "medium", minHeight: "none", className: cn( "border-none items-center gap-2 text-text-700", className ), ...props, children: [ /* @__PURE__ */ jsxs( "div", { className: cn( "w-full flex", direction == "col" ? "flex-col" : "flex-row items-center" ), children: [ /* @__PURE__ */ jsx("span", { className: "w-full min-w-0", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-text-950 font-bold truncate", children: header }) }), /* @__PURE__ */ jsx("span", { className: "flex flex-row gap-1", children }) ] } ), /* @__PURE__ */ jsx(CaretRightIcon, { className: "text-text-800 cursor-pointer", size: 24 }) ] } ); } ); var CardForum = forwardRef( ({ title, content, comments, onClickComments, valueComments, onClickProfile, valueProfile, className = "", date, hour, ...props }, ref) => { return /* @__PURE__ */ jsxs( CardBase, { ref, layout: "horizontal", padding: "medium", minHeight: "none", variant: "minimal", className: cn("w-auto h-auto gap-3", className), ...props, children: [ /* @__PURE__ */ jsx( "button", { type: "button", "aria-label": "Ver perfil", onClick: () => onClickProfile?.(valueProfile), className: "min-w-8 h-8 rounded-full bg-background-950" } ), /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 flex-1 min-w-0", children: [ /* @__PURE__ */ jsxs("div", { className: "flex flex-row gap-1 items-center flex-wrap", children: [ /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold text-primary-700 truncate", children: title }), /* @__PURE__ */ jsxs("p", { className: "text-xs text-text-600", children: [ "\u2022 ", date, " \u2022 ", hour ] }) ] }), /* @__PURE__ */ jsx("p", { className: "text-text-950 text-sm line-clamp-2 truncate", children: content }), /* @__PURE__ */ jsxs( "button", { type: "button", "aria-label": "Ver coment\xE1rios", onClick: () => onClickComments?.(valueComments), className: "text-text-600 flex flex-row gap-2 items-center", children: [ /* @__PURE__ */ jsx(ChatCircleTextIcon, { "aria-hidden": "true", size: 16 }), /* @__PURE__ */ jsxs("p", { className: "text-xs", children: [ comments, " respostas" ] }) ] } ) ] }) ] } ); } ); var CardAudio = forwardRef( ({ src, title, onPlay, onPause, onEnded, onAudioTimeUpdate, loop = false, preload = "metadata", tracks, className, ...props }, ref) => { const [isPlaying, setIsPlaying] = useState(false); const [currentTime, setCurrentTime] = useState(0); const [duration, setDuration] = useState(0); const [volume, setVolume] = useState(1); const [showVolumeControl, setShowVolumeControl] = useState(false); const [showSpeedMenu, setShowSpeedMenu] = useState(false); const [playbackRate, setPlaybackRate] = useState(1); const audioRef = useRef(null); const volumeControlRef = useRef(null); const speedMenuRef = useRef(null); const formatTime = (time) => { const minutes = Math.floor(time / 60); const seconds = Math.floor(time % 60); return `${minutes}:${seconds.toString().padStart(2, "0")}`; }; const handlePlayPause = () => { if (isPlaying) { audioRef.current?.pause(); setIsPlaying(false); onPause?.(); } else { audioRef.current?.play()?.catch(() => { }); setIsPlaying(true); onPlay?.(); } }; const handleTimeUpdate = () => { const current = audioRef.current?.currentTime ?? 0; const total = audioRef.current?.duration ?? 0; setCurrentTime(current); setDuration(total); onAudioTimeUpdate?.(current, total); }; const handleLoadedMetadata = () => { setDuration(audioRef.current?.duration ?? 0); }; const handleEnded = () => { setIsPlaying(false); setCurrentTime(0); onEnded?.(); }; const handleProgressClick = (e) => { const rect = e.currentTarget.getBoundingClientRect(); const clickX = e.clientX - rect.left; const width = rect.width; const percentage = clickX / width; const newTime = percentage * duration; if (audioRef.current && Number.isFinite(newTime)) { audioRef.current.currentTime = newTime; setCurrentTime(newTime); } }; const handleVolumeChange = (e) => { const newVolume = parseFloat(e.target.value); setVolume(newVolume); if (audioRef.current) { audioRef.current.volume = newVolume; } }; const toggleVolumeControl = () => { setShowVolumeControl(!showVolumeControl); setShowSpeedMenu(false); }; const toggleSpeedMenu = () => { setShowSpeedMenu(!showSpeedMenu); setShowVolumeControl(false); }; const handleSpeedChange = (speed) => { setPlaybackRate(speed); if (audioRef.current) { audioRef.current.playbackRate = speed; } setShowSpeedMenu(false); }; const getVolumeIcon = () => { if (volume === 0) { return /* @__PURE__ */ jsx(SpeakerSimpleXIcon, { size: 24 }); } if (volume < 0.5) { return /* @__PURE__ */ jsx(SpeakerLowIcon, { size: 24 }); } return /* @__PURE__ */ jsx(SpeakerHighIcon, { size: 24 }); }; useEffect(() => { const handleClickOutside = (event) => { if (volumeControlRef.current && !volumeControlRef.current.contains(event.target)) { setShowVolumeControl(false); } if (speedMenuRef.current && !speedMenuRef.current.contains(event.target)) { setShowSpeedMenu(false); } }; document.addEventListener("mousedown", handleClickOutside); return () => { document.removeEventListener("mousedown", handleClickOutside); }; }, []); return /* @__PURE__ */ jsxs( CardBase, { ref, layout: "horizontal", padding: "medium", minHeight: "none", className: cn( "flex flex-row w-auto h-14 items-center gap-2", className ), ...props, children: [ /* @__PURE__ */ jsx( "audio", { ref: audioRef, src, loop, preload, onTimeUpdate: handleTimeUpdate, onLoadedMetadata: handleLoadedMetadata, onEnded: handleEnded, "data-testid": "audio-element", "aria-label": title, children: tracks ? tracks.map((track) => /* @__PURE__ */ jsx( "track", { kind: track.kind, src: track.src, srcLang: track.srcLang, label: track.label, default: track.default }, track.src )) : /* @__PURE__ */ jsx( "track", { kind: "captions", src: "data:text/vtt;base64,", srcLang: "pt", label: "Sem legendas dispon\xEDveis" } ) } ), /* @__PURE__ */ jsx( "button", { type: "button", onClick: handlePlayPause, disabled: !src, className: "cursor-pointer text-text-950 hover:text-primary-600 disabled:text-text-400 disabled:cursor-not-allowed", "aria-label": isPlaying ? "Pausar" : "Reproduzir", children: isPlaying ? /* @__PURE__ */ jsx("div", { className: "w-6 h-6 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "flex gap-0.5", children: [ /* @__PURE__ */ jsx("div", { className: "w-1 h-4 bg-current rounded-sm" }), /* @__PURE__ */ jsx("div", { className: "w-1 h-4 bg-current rounded-sm" }) ] }) }) : /* @__PURE__ */ jsx(PlayIcon, { size: 24 }) } ), /* @__PURE__ */ jsx("p", { className: "text-text-800 text-md font-medium min-w-[2.5rem]", children: formatTime(currentTime) }), /* @__PURE__ */ jsx("div", { className: "flex-1 relative", "data-testid": "progress-bar", children: /* @__PURE__ */ jsx( "button", { type: "button", className: "w-full h-2 bg-border-100 rounded-full cursor-pointer", onClick: handleProgressClick, onKeyDown: (e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); e.currentTarget.click(); } }, "aria-label": "Barra de progresso do \xE1udio", children: /* @__PURE__ */ jsx( "div", { className: "h-full bg-primary-600 rounded-full transition-all duration-100", style: { width: duration > 0 ? `${currentTime / duration * 100}%` : "0%" } } ) } ) }), /* @__PURE__ */ jsx("p", { className: "text-text-800 text-md font-medium min-w-[2.5rem]", children: formatTime(duration) }), /* @__PURE__ */ jsxs("div", { className: "relative h-6", ref: volumeControlRef, children: [ /* @__PURE__ */ jsx( "button", { type: "button", onClick: toggleVolumeControl, className: "cursor-pointer text-text-950 hover:text-primary-600", "aria-label": "Controle de volume", children: /* @__PURE__ */ jsx("div", { className: "w-6 h-6 flex items-center justify-center", children: getVolumeIcon() }) } ), showVolumeControl && /* @__PURE__ */ jsx( "button", { type: "button", className: "absolute bottom-full right-0 mb-2 p-2 bg-background border border-border-100 rounded-lg shadow-lg focus:outline-none focus:ring-2 focus:ring-primary-500", onKeyDown: (e) => { if (e.key === "Escape") { setShowVolumeControl(false); } }, children: /* @__PURE__ */ jsx( "input", { type: "range", min: "0", max: "1", step: "0.1", value: volume, onChange: handleVolumeChange, onKeyDown: (e) => { if (e.key === "ArrowUp" || e.key === "ArrowRight") { e.preventDefault(); const newVolume = Math.min( 1, Math.round((volume + 0.1) * 10) / 10 ); setVolume(newVolume); if (audioRef.current) audioRef.current.volume = newVolume; } else if (e.key === "ArrowDown" || e.key === "ArrowLeft") { e.preventDefault(); const newVolume = Math.max( 0, Math.round((volume - 0.1) * 10) / 10 ); setVolume(newVolume); if (audioRef.current) audioRef.current.volume = newVolume; } }, className: "w-20 h-2 bg-border-100 rounded-lg appearance-none cursor-pointer", style: { background: `linear-gradient(to right, #3b82f6 0%, #3b82f6 ${volume * 100}%, #e5e7eb ${volume * 100}%, #e5e7eb 100%)` }, "aria-label": "Volume", "aria-valuenow": Math.round(volume * 100), "aria-valuemin": 0, "aria-valuemax": 100 } ) } ) ] }), /* @__PURE__ */ jsxs("div", { className: "relative h-6", ref: speedMenuRef, children: [ /* @__PURE__ */ jsx( "button", { type: "button", onClick: toggleSpeedMenu, className: "cursor-pointer text-text-950 hover:text-primary-600", "aria-label": "Op\xE7\xF5es de velocidade", children: /* @__PURE__ */ jsx(DotsThreeVerticalIcon, { size: 24 }) } ), showSpeedMenu && /* @__PURE__ */ jsx("div", { className: "absolute bottom-full right-0 mb-2 p-2 bg-background border border-border-100 rounded-lg shadow-lg min-w-24 z-10", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1", children: [ { speed: 1, label: "1x" }, { speed: 1.5, label: "1.5x" }, { speed: 2, label: "2x" } ].map(({ speed, label }) => /* @__PURE__ */ jsx( "button", { type: "button", onClick: () => handleSpeedChange(speed), className: cn( "px-3 py-1 text-sm text-left rounded hover:bg-border-50 transition-colors", playbackRate === speed ? "bg-primary-950 text-secondary-100 font-medium" : "text-text-950" ), children: label }, speed )) }) }) ] }) ] } ); } ); var SIMULADO_BACKGROUND_CLASSES = { enem: "bg-exam-1", prova: "bg-exam-2", simuladao: "bg-exam-3", vestibular: "bg-exam-4" }; var CardSimulado = forwardRef( ({ title, duration, info, backgroundColor, comingSoon = false, disabled = false, className, onClick, onKeyDown, ...props }, ref) => { const backgroundClass = SIMULADO_BACKGROUND_CLASSES[backgroundColor]; const isInteractive = !comingSoon && !disabled; return /* @__PURE__ */ jsx( CardBase, { ref, layout: "horizontal", padding: "medium", minHeight: "none", cursor: isInteractive ? "pointer" : "default", "aria-disabled": isInteractive ? void 0 : true, onClick: isInteractive ? onClick : void 0, onKeyDown: isInteractive ? onKeyDown : void 0, className: cn( backgroundClass, isInteractive ? "hover:shadow-soft-shadow-2 transition-shadow duration-200" : "opacity-60 pointer-events-none", className ), ...props, children: /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center w-full gap-4", children: [ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 flex-1 min-w-0", children: [ comingSoon ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [ /* @__PURE__ */ jsx( Text_default, { size: "lg", weight: "bold", className: "text-text-950 truncate", children: title } ), /* @__PURE__ */ jsx( Badge_default, { size: "small", variant: "solid", action: "info", className: "flex-shrink-0", "data-testid": "badge-em-breve", children: "Em breve" } ) ] }) : /* @__PURE__ */ jsx(Text_default, { size: "lg", weight: "bold", className: "text-text-950 truncate", children: title }), /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 text-text-700", children: [ duration && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [ /* @__PURE__ */ jsx(ClockIcon, { size: 16, className: "flex-shrink-0" }), /* @__PURE__ */ jsx(Text_default, { size: "sm", children: duration }) ] }), /* @__PURE__ */ jsx(Text_default, { size: "sm", className: "truncate", children: info }) ] }) ] }), isInteractive && /* @__PURE__ */ jsx( CaretRightIcon, { size: 24, className: "text-text-800 flex-shrink-0", "data-testid": "caret-icon" } ) ] }) } ); } ); var CardTest = forwardRef( ({ title, duration, questionsCount, additionalInfo, selected = false, onSelect, className = "", ...props }, ref) => { const handleClick = () => { if (onSelect) { onSelect(!selected); } }; const handleKeyDown = (event) => { if ((event.key === "Enter" || event.key === " ") && onSelect) { event.preventDefault(); onSelect(!selected); } }; const isSelectable = !!onSelect; const getQuestionsText = (count) => { const singular = count === 1 ? "quest\xE3o" : "quest\xF5es"; return `${count} ${singular}`; }; const displayInfo = questionsCount ? getQuestionsText(questionsCount) : additionalInfo || ""; const baseClasses = "flex flex-row items-center p-4 gap-2 w-full max-w-full bg-background shadow-soft-shadow-1 rounded-xl isolate border-0 text-left"; const interactiveClasses = isSelectable ? "cursor-pointer focus:outline-none focus:ring-2 focus:ring-primary-950 focus:ring-offset-2" : ""; const selectedClasses = selected ? "ring-2 ring-primary-950 ring-offset-2" : ""; if (isSelectable) { return /* @__PURE__ */ jsx( "button", { ref, type: "button", className: cn( `${baseClasses} ${interactiveClasses} ${selectedClasses} ${className}`.trim() ), onClick: handleClick, onKeyDown: handleKeyDown, "aria-pressed": selected, ...props, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col justify-between gap-[27px] flex-grow min-h-[67px] w-full min-w-0", children: [ /* @__PURE__ */ jsx( Text_default, { size: "md", weight: "bold", className: "text-text-950 tracking-[0.2px] leading-[19px] truncate", children: title } ), /* @__PURE__ */ jsxs("div", { className: "flex flex-row justify-start items-end gap-4 w-full", children: [ duration && /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center gap-1 flex-shrink-0", children: [ /* @__PURE__ */ jsx(ClockIcon, { size: 16, className: "text-text-700" }), /* @__PURE__ */ jsx( Text_default, { size: "sm", className: "text-text-700 leading-[21px] whitespace-nowrap", children: duration } ) ] }), /* @__PURE__ */ jsx( Text_default, { size: "sm", className: "text-text-700 leading-[21px] flex-grow truncate", children: displayInfo } ) ] }) ] }) } ); } return /* @__PURE__ */ jsx( "div", { ref, className: cn(`${baseClasses} ${className}`.trim()), ...props, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col justify-between gap-[27px] flex-grow min-h-[67px] w-full min-w-0", children: [ /* @__PURE__ */ jsx( Text_default, { size: "md", weight: "bold", className: "text-text-950 tracking-[0.2px] leading-[19px] truncate", children: title } ), /* @__PURE__ */ jsxs("div", { className: "flex flex-row justify-start items-end gap-4 w-full", children: [ duration && /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center gap-1 flex-shrink-0", children: [ /* @__PURE__ */ jsx(ClockIcon, { size: 16, className: "text-text-700" }), /* @__PURE__ */ jsx( Text_default, { size: "sm", className: "text-text-700 leading-[21px] whitespace-nowrap", children: duration } ) ] }), /* @__PURE__ */ jsx( Text_default, { size: "sm", className: "text-text-700 leading-[21px] flex-grow truncate min-w-0", children: displayInfo } ) ] }) ] }) } ); } ); var SIMULATION_TYPE_STYLES = { enem: { background: "bg-exam-1", badge: "exam1", text: "Enem" }, prova: { background: "bg-exam-2", badge: "exam2", text: "Prova" }, simulado: { background: "bg-exam-3", badge: "exam3", text: "Simulad\xE3o" }, vestibular: { background: "bg-exam-4", badge: "exam4", text: "Vestibular" } }; var CardSimulationHistory = forwardRef(({ data, onSimulationClick, className, ...props }, ref) => { return /* @__PURE__ */ jsx( "div", { ref, className: cn("w-full max-w-[992px] h-auto", className), ...props, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0", children: [ data.map((section, sectionIndex) => /* @__PURE__ */ jsx("div", { className: "flex flex-col", children: /* @__PURE__ */ jsxs( "div", { className: cn( "flex flex-row justify-center items-start px-4 py-6 gap-2 w-full bg-background", sectionIndex === 0 ? "rounded-t-3xl" : "" ), children: [ /* @__PURE__ */ jsx( Text_default, { size: "xs", weight: "bold", className: "text-text-800 w-11 flex-shrink-0", children: section.date } ), /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2 flex-1", children: section.simulations.map((simulation) => { const typeStyles = SIMULATION_TYPE_STYLES[simulation.type]; return /* @__PURE__ */ jsx( CardBase, { layout: "horizontal", padding: "medium", minHeight: "none", cursor: "pointer", className: cn( `${typeStyles.background} rounded-xl hover:shadow-soft-shadow-2 transition-shadow duration-200 h-auto min-h-[61px]` ), onClick: () => onSimulationClick?.(simulation), children: /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center w-full gap-2", children: [ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap flex-col justify-between sm:flex-row gap-2 flex-1 min-w-0", children: [ /* @__PURE__ */ jsx( Text_default, { size: "lg", weight: "bold", className: "text-text-950 truncate", children: simulation.title } ), /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [ /* @__PURE__ */ jsx( Badge_default, { variant: "examsOutlined", action: typeStyles.badge, size: "medium", children: typeStyles.text } ), simulation.statusBadge && /* @__PURE__ */ jsx( Badge_default, { variant: "outlined", action: simulation.statusBadge.action, size: "medium", children: simulation.statusBadge.label } ), /* @__PURE__ */ jsx(Text_default, { size: "sm", className: "text-text-800 truncate", children: simulation.info }) ] }) ] }), /* @__PURE__ */ jsx( CaretRightIcon, { size: 24, className: "text-text-800 flex-shrink-0", "data-testid": "caret-icon" } ) ] }) }, simulation.id ); }) }) ] } ) }, section.date)), data.length > 0 && /* @__PURE__ */ jsx("div", { className: "w-full h-6 bg-background rounded-b-3xl" }) ] }) } ); }); var EssayStatus = /* @__PURE__ */ ((EssayStatus2) => { EssayStatus2["DRAFT"] = "DRAFT"; EssayStatus2["SUBMITTED"] = "SUBMITTED"; EssayStatus2["CORRECTING"] = "CORRECTING"; EssayStatus2["CORRECTED"] = "CORRECTED"; EssayStatus2["ERROR"] = "ERROR"; return EssayStatus2; })(EssayStatus || {}); var EssayReviewStatus = /* @__PURE__ */ ((EssayReviewStatus2) => { EssayReviewStatus2["PENDING"] = "PENDING"; EssayReviewStatus2["APPROVED"] = "APPROVED"; EssayReviewStatus2["MODIFIED"] = "MODIFIED"; return EssayReviewStatus2; })(EssayReviewStatus || {}); var resolveEssayVisualState = (essay, maxScore) => { if (essay.totalScore != null) { return { background: "bg-subject-12", text: `${essay.totalScore} de ${maxScore}`, clickable: true }; } if (essay.status === "ERROR" /* ERROR */) { return { background: "bg-tertiary-100", text: "Erro na corre\xE7\xE3o", clickable: true }; } if (essay.status === "CORRECTING" /* CORRECTING */ || essay.status === "SUBMITTED" /* SUBMITTED */) { return { background: "bg-secondary-200", text: "Gerando resultado...", clickable: false }; } if (essay.status === "DRAFT" /* DRAFT */) { return { background: "bg-secondary-200", text: "Rascunho", clickable: false }; } return { background: "bg-secondary-200", text: "Sem nota ainda", clickable: false }; }; var resolveReviewBadge = (essay) => { if (essay.reviewStatus === "APPROVED" /* APPROVED */ || essay.reviewStatus === "MODIFIED" /* MODIFIED */) { return { label: "Revisado", action: "success" }; } if (essay.status === "CORRECTED" /* CORRECTED */ && essay.reviewStatus === "PENDING" /* PENDING */) { return { label: "Corrigido por IA", action: "info" }; } return null; }; var CardEssayHistory = forwardRef( ({ data, maxScore = 1e3, onEssayClick, className, ...props }, ref) => { return /* @__PURE__ */ jsx( "div", { ref, className: cn("w-full max-w-248 bg-background rounded-3xl", className),