UNPKG

analytica-frontend-lib

Version:

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

1 lines 30.2 kB
{"version":3,"sources":["../../src/components/Calendar/Calendar.tsx","../../src/utils/utils.ts"],"sourcesContent":["import {\n useState,\n useMemo,\n useEffect,\n useRef,\n MouseEvent,\n RefObject,\n} from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Activity status types for calendar days\n */\nexport type ActivityStatus = 'near-deadline' | 'overdue' | 'in-deadline';\n\n/**\n * Activity data for a specific day\n */\nexport interface CalendarActivity {\n id: string;\n status: ActivityStatus;\n title?: string;\n}\n\n/**\n * Calendar day data\n */\nexport interface CalendarDay {\n date: Date;\n isCurrentMonth: boolean;\n isToday: boolean;\n isSelected: boolean;\n activities?: CalendarActivity[];\n}\n\n/**\n * Calendar variant types\n */\nexport type CalendarVariant = 'navigation' | 'selection';\n\n/**\n * Calendar component props\n */\nexport interface CalendarProps {\n /** Calendar variant - navigation (compact) or selection (full) */\n variant?: CalendarVariant;\n /** Currently selected date */\n selectedDate?: Date;\n /** Function called when a date is selected */\n onDateSelect?: (date: Date) => void;\n /** Function called when month changes */\n onMonthChange?: (date: Date) => void;\n /** Activities data for calendar days */\n activities?: Record<string, CalendarActivity[]>;\n /** Show activities indicators */\n showActivities?: boolean;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Day names abbreviations\n */\nexport const WEEK_DAYS = ['SEG', 'TER', 'QUA', 'QUI', 'SEX', 'SÁB', 'DOM'];\n\n/**\n * Day names single-letter abbreviations\n */\nconst WEEK_DAYS_SHORT = ['S', 'T', 'Q', 'Q', 'S', 'S', 'D'];\n\n/**\n * Month names in Portuguese\n */\nconst MONTH_NAMES = [\n 'Janeiro',\n 'Fevereiro',\n 'Março',\n 'Abril',\n 'Maio',\n 'Junho',\n 'Julho',\n 'Agosto',\n 'Setembro',\n 'Outubro',\n 'Novembro',\n 'Dezembro',\n];\n\n/**\n * Month/Year picker props\n */\ninterface MonthYearPickerProps {\n monthPickerRef: RefObject<HTMLDivElement | null>;\n availableYears: number[];\n currentDate: Date;\n onYearChange: (year: number) => void;\n onMonthChange: (month: number, year: number) => void;\n}\n\n/**\n * Month/Year picker component\n */\nconst MonthYearPicker = ({\n monthPickerRef,\n availableYears,\n currentDate,\n onYearChange,\n onMonthChange,\n}: MonthYearPickerProps) => (\n <div\n ref={monthPickerRef}\n className=\"absolute top-full left-0 z-50 mt-1 bg-background rounded-lg shadow-lg border border-border-200 p-4 min-w-[280px]\"\n >\n <div className=\"mb-4\">\n <h3 className=\"text-sm font-medium text-text-700 mb-2\">Selecionar Ano</h3>\n <div className=\"grid grid-cols-4 gap-1 max-h-32 overflow-y-auto\">\n {availableYears.map((year) => (\n <button\n key={year}\n onClick={() => onYearChange(year)}\n className={`\n px-2 py-1 text-xs rounded text-center hover:bg-background-100 transition-colors\n ${\n year === currentDate.getFullYear()\n ? 'bg-primary-800 text-text font-medium hover:text-text-950'\n : 'text-text-700'\n }\n `}\n >\n {year}\n </button>\n ))}\n </div>\n </div>\n\n <div>\n <h3 className=\"text-sm font-medium text-text-700 mb-2\">Selecionar Mês</h3>\n <div className=\"grid grid-cols-3 gap-1\">\n {MONTH_NAMES.map((month, index) => (\n <button\n key={month}\n onClick={() => onMonthChange(index, currentDate.getFullYear())}\n className={`\n px-2 py-2 text-xs rounded text-center hover:bg-background-100 transition-colors\n ${\n index === currentDate.getMonth()\n ? 'bg-primary-800 text-text font-medium hover:text-text-950'\n : 'text-text-700'\n }\n `}\n >\n {month.substring(0, 3)}\n </button>\n ))}\n </div>\n </div>\n </div>\n);\n\n/**\n * Helper function to get day styles based on variant and conditions\n */\nconst getDayStyles = (\n day: CalendarDay,\n variant: CalendarVariant,\n showActivities: boolean\n) => {\n let dayStyle = '';\n let textStyle = '';\n\n if (variant === 'selection' && day.isSelected) {\n dayStyle = 'bg-primary-800';\n textStyle = 'text-text';\n } else if (day.isToday) {\n textStyle = 'text-primary-800';\n } else if (\n variant === 'navigation' &&\n showActivities &&\n day.activities?.length\n ) {\n const primaryActivity = day.activities[0];\n if (primaryActivity.status === 'near-deadline') {\n dayStyle = 'bg-warning-background border-2 border-warning-400';\n textStyle = 'text-text-950';\n } else if (primaryActivity.status === 'in-deadline') {\n dayStyle = 'bg-success-background border-2 border-success-300';\n textStyle = 'text-text-950';\n } else if (primaryActivity.status === 'overdue') {\n dayStyle = 'bg-error-background border-2 border-error-300';\n textStyle = 'text-text-950';\n } else {\n dayStyle = 'border-2 border-blue-500';\n textStyle = 'text-blue-500';\n }\n } else {\n textStyle = 'text-text-950 hover:bg-background-100';\n }\n\n return { dayStyle, textStyle };\n};\n\n/**\n * Calendar component for Analytica Ensino platforms\n *\n * A comprehensive calendar component with activity indicators,\n * date selection, and navigation capabilities.\n */\nconst Calendar = ({\n variant = 'selection',\n selectedDate,\n onDateSelect,\n onMonthChange,\n activities = {},\n showActivities = true,\n className = '',\n}: CalendarProps) => {\n const [currentDate, setCurrentDate] = useState(selectedDate || new Date());\n const [isMonthPickerOpen, setIsMonthPickerOpen] = useState(false);\n const monthPickerRef = useRef<HTMLDivElement>(null);\n const monthPickerContainerRef = useRef<HTMLDivElement>(null);\n\n // Close month picker when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: Event) => {\n if (\n monthPickerContainerRef.current &&\n !monthPickerContainerRef.current.contains(event.target as Node)\n ) {\n setIsMonthPickerOpen(false);\n }\n };\n\n if (isMonthPickerOpen) {\n document.addEventListener('mousedown', handleClickOutside);\n }\n\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, [isMonthPickerOpen]);\n\n // Get today's date for comparison\n const today = new Date();\n\n // Generate available years (current year ± 10 years)\n const availableYears = useMemo(() => {\n const currentYear = new Date().getFullYear();\n const years = [];\n for (let year = currentYear - 10; year <= currentYear + 10; year++) {\n years.push(year);\n }\n return years;\n }, []);\n\n // Calculate calendar data\n const calendarData = useMemo(() => {\n const year = currentDate.getFullYear();\n const month = currentDate.getMonth();\n\n // First day of the month\n const firstDay = new Date(year, month, 1);\n\n // Get the first Monday of the calendar view\n const startDate = new Date(firstDay);\n const firstDayOfWeek = (firstDay.getDay() + 6) % 7; // Convert Sunday=0 to Monday=0\n startDate.setDate(startDate.getDate() - firstDayOfWeek);\n\n const days: CalendarDay[] = [];\n const currentCalendarDate = new Date(startDate);\n\n // Generate 42 days (6 weeks)\n for (let i = 0; i < 42; i++) {\n const dateKey = currentCalendarDate.toISOString().split('T')[0];\n const dayActivities = activities[dateKey] || [];\n\n days.push({\n date: new Date(currentCalendarDate),\n isCurrentMonth: currentCalendarDate.getMonth() === month,\n isToday:\n currentCalendarDate.getFullYear() === today.getFullYear() &&\n currentCalendarDate.getMonth() === today.getMonth() &&\n currentCalendarDate.getDate() === today.getDate(),\n isSelected: selectedDate\n ? currentCalendarDate.getFullYear() === selectedDate.getFullYear() &&\n currentCalendarDate.getMonth() === selectedDate.getMonth() &&\n currentCalendarDate.getDate() === selectedDate.getDate()\n : false,\n activities: dayActivities,\n });\n\n currentCalendarDate.setDate(currentCalendarDate.getDate() + 1);\n }\n\n return days;\n }, [currentDate, selectedDate, activities]);\n\n // Navigation functions\n const goToPreviousMonth = () => {\n const newDate = new Date(currentDate);\n newDate.setMonth(newDate.getMonth() - 1);\n setCurrentDate(newDate);\n onMonthChange?.(newDate);\n };\n\n const goToNextMonth = () => {\n const newDate = new Date(currentDate);\n newDate.setMonth(newDate.getMonth() + 1);\n setCurrentDate(newDate);\n onMonthChange?.(newDate);\n };\n\n // Month/Year selection functions\n const goToMonth = (month: number, year: number) => {\n const newDate = new Date(year, month, 1);\n setCurrentDate(newDate);\n setIsMonthPickerOpen(false);\n onMonthChange?.(newDate);\n };\n\n const handleYearChange = (year: number) => {\n const newDate = new Date(year, currentDate.getMonth(), 1);\n setCurrentDate(newDate);\n };\n\n const toggleMonthPicker = (event: MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n setIsMonthPickerOpen(!isMonthPickerOpen);\n };\n\n // Date selection handler\n const handleDateSelect = (day: CalendarDay) => {\n onDateSelect?.(day.date);\n };\n\n // Navigation variant (compact)\n if (variant === 'navigation') {\n return (\n <div className={cn('bg-background rounded-xl pt-6', className)}>\n {/* Compact header */}\n <div className=\"flex items-center justify-between mb-4 px-6\">\n <div className=\"relative\" ref={monthPickerContainerRef}>\n <button\n onClick={toggleMonthPicker}\n className=\"flex items-center group gap-1 rounded transition-colors cursor-pointer\"\n >\n <span className=\"text-sm font-medium text-text-600 group-hover:text-primary-950\">\n {MONTH_NAMES[currentDate.getMonth()]}{' '}\n {currentDate.getFullYear()}\n </span>\n <svg\n className={`w-4 h-4 text-primary-950 transition-transform ${\n isMonthPickerOpen ? 'rotate-180' : ''\n }`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 9l-7 7-7-7\"\n />\n </svg>\n </button>\n {isMonthPickerOpen && (\n <MonthYearPicker\n monthPickerRef={monthPickerRef}\n availableYears={availableYears}\n currentDate={currentDate}\n onYearChange={handleYearChange}\n onMonthChange={goToMonth}\n />\n )}\n </div>\n <div className=\"flex items-center gap-10\">\n <button\n onClick={goToPreviousMonth}\n className=\"p-1 rounded hover:bg-background-100 transition-colors\"\n aria-label=\"Mês anterior\"\n >\n <svg\n className=\"w-6 h-6 text-primary-950\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 19l-7-7 7-7\"\n />\n </svg>\n </button>\n <button\n onClick={goToNextMonth}\n className=\"p-1 rounded hover:bg-background-100 transition-colors\"\n aria-label=\"Próximo mês\"\n >\n <svg\n className=\"w-6 h-6 text-primary-950\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 5l7 7-7 7\"\n />\n </svg>\n </button>\n </div>\n </div>\n\n {/* Compact week days */}\n <div className=\"grid grid-cols-7 gap-1 mb-2 px-3\">\n {WEEK_DAYS_SHORT.map((day, index) => (\n <div\n key={`${day}-${index}`}\n className=\"h-9 flex items-center justify-center text-xs font-normal text-text-600\"\n >\n {day}\n </div>\n ))}\n </div>\n\n {/* Compact calendar grid */}\n <div className=\"grid grid-cols-7 gap-1 px-3\">\n {calendarData.map((day) => {\n // Não renderizar dias que não pertencem ao mês atual\n if (!day.isCurrentMonth) {\n return (\n <div\n key={day.date.getTime()}\n className=\"flex items-center justify-center\"\n >\n <div className=\"w-9 h-9\"></div>\n </div>\n );\n }\n\n const { dayStyle, textStyle } = getDayStyles(\n day,\n variant,\n showActivities\n );\n\n let spanClass = '';\n if (day.isSelected && day.isToday) {\n spanClass = 'h-6 w-6 rounded-full bg-primary-800 text-text';\n } else if (day.isSelected) {\n spanClass = 'h-6 w-6 rounded-full bg-primary-950 text-text';\n }\n\n return (\n <div\n key={day.date.getTime()}\n className=\"flex items-center justify-center\"\n >\n <button\n className={`\n w-9 h-9\n flex items-center justify-center\n text-md font-normal\n cursor-pointer\n rounded-full\n ${dayStyle}\n ${textStyle}\n `}\n onClick={() => handleDateSelect(day)}\n aria-label={`${day.date.getDate()} de ${MONTH_NAMES[day.date.getMonth()]}`}\n aria-current={day.isToday ? 'date' : undefined}\n tabIndex={0}\n >\n <span className={spanClass}>{day.date.getDate()}</span>\n </button>\n </div>\n );\n })}\n </div>\n </div>\n );\n }\n\n // Selection variant (full)\n return (\n <div className={cn('bg-background rounded-xl p-4', className)}>\n {/* Full header */}\n <div className=\"flex items-center justify-between mb-3.5\">\n <div className=\"relative\" ref={monthPickerContainerRef}>\n <button\n onClick={toggleMonthPicker}\n className=\"flex items-center gap-2 hover:bg-background-100 rounded px-2 py-1 transition-colors\"\n >\n <h2 className=\"text-lg font-semibold text-text-950\">\n {MONTH_NAMES[currentDate.getMonth()]} {currentDate.getFullYear()}\n </h2>\n <svg\n className={`w-4 h-4 text-text-400 transition-transform ${\n isMonthPickerOpen ? 'rotate-180' : ''\n }`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 9l-7 7-7-7\"\n />\n </svg>\n </button>\n {isMonthPickerOpen && (\n <MonthYearPicker\n monthPickerRef={monthPickerRef}\n availableYears={availableYears}\n currentDate={currentDate}\n onYearChange={handleYearChange}\n onMonthChange={goToMonth}\n />\n )}\n </div>\n <div className=\"flex items-center gap-1\">\n <button\n onClick={goToPreviousMonth}\n className=\"p-1 rounded-md hover:bg-background-100 transition-colors\"\n aria-label=\"Mês anterior\"\n >\n <svg\n className=\"w-6 h-6 text-primary-950\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15 19l-7-7 7-7\"\n />\n </svg>\n </button>\n <button\n onClick={goToNextMonth}\n className=\"p-1 rounded-md hover:bg-background-100 transition-colors\"\n aria-label=\"Próximo mês\"\n >\n <svg\n className=\"w-6 h-6 text-primary-950\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 5l7 7-7 7\"\n />\n </svg>\n </button>\n </div>\n </div>\n\n {/* Week days header */}\n <div className=\"grid grid-cols-7 mb-2\">\n {WEEK_DAYS.map((day) => (\n <div\n key={day}\n className=\"h-4 flex items-center justify-center text-xs font-semibold text-text-500\"\n >\n {day}\n </div>\n ))}\n </div>\n\n {/* Calendar grid */}\n <div className=\"grid grid-cols-7\">\n {calendarData.map((day) => {\n // Não renderizar dias que não pertencem ao mês atual\n if (!day.isCurrentMonth) {\n return (\n <div\n key={day.date.getTime()}\n className=\"flex items-center justify-center\"\n >\n <div className=\"w-10 h-10\"></div>\n </div>\n );\n }\n\n const { dayStyle, textStyle } = getDayStyles(\n day,\n variant,\n showActivities\n );\n\n return (\n <div\n key={day.date.getTime()}\n className=\"flex items-center justify-center\"\n >\n <button\n className={`\n w-9 h-9\n flex items-center justify-center\n text-lg font-normal\n cursor-pointer\n rounded-full\n focus:outline-none focus:ring-2 focus:ring-primary-600 focus:ring-offset-1\n ${dayStyle}\n ${textStyle}\n `}\n onClick={() => handleDateSelect(day)}\n aria-label={`${day.date.getDate()} de ${MONTH_NAMES[day.date.getMonth()]}`}\n aria-current={day.isToday ? 'date' : undefined}\n tabIndex={0}\n >\n {day.date.getDate()}\n </button>\n </div>\n );\n })}\n </div>\n </div>\n );\n};\n\nexport default Calendar;\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n\nexport { syncDropdownState } from './dropdown';\nexport {\n getSelectedIdsFromCategories,\n toggleArrayItem,\n toggleSingleValue,\n areFiltersEqual,\n} from './activityFilters';\nexport {\n mapQuestionTypeToEnum,\n mapQuestionTypeToEnumRequired,\n} from './questionTypeUtils';\nexport {\n getStatusBadgeConfig,\n formatTimeSpent,\n formatQuestionNumbers,\n formatDateToBrazilian,\n} from './activityDetailsUtils';\n\n/**\n * Retorna a cor hexadecimal com opacidade 0.3 (4d) se não estiver em dark mode.\n * Se estiver em dark mode, retorna a cor original.\n *\n * @param hexColor - Cor hexadecimal (ex: \"#0066b8\" ou \"0066b8\")\n * @param isDark - booleano indicando se está em dark mode\n * @returns string - cor hexadecimal com opacidade se necessário\n */\nexport function getSubjectColorWithOpacity(\n hexColor: string | undefined,\n isDark: boolean\n): string | undefined {\n if (!hexColor) return undefined;\n // Remove o '#' se existir\n let color = hexColor.replace(/^#/, '').toLowerCase();\n\n if (isDark) {\n // Se está em dark mode, sempre remove opacidade se existir\n if (color.length === 8) {\n color = color.slice(0, 6);\n }\n return `#${color}`;\n } else {\n // Se não está em dark mode (light mode)\n let resultColor: string;\n if (color.length === 6) {\n // Adiciona opacidade 0.3 (4D) para cores de 6 dígitos\n resultColor = `#${color}4d`;\n } else if (color.length === 8) {\n // Já tem opacidade, retorna como está\n resultColor = `#${color}`;\n } else {\n // Para outros tamanhos (3, 4, 5 dígitos), retorna como está\n resultColor = `#${color}`;\n }\n return resultColor;\n }\n}\n"],"mappings":"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","names":[]}