analytica-frontend-lib 1.0.43 → 1.0.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -94,7 +94,7 @@ var getDayStyles = (day, variant, showActivities) => {
94
94
  dayStyle = "bg-primary-800";
95
95
  textStyle = "text-white";
96
96
  } else if (day.isToday) {
97
- textStyle = "text-[#1c61b2]";
97
+ textStyle = "text-primary-800";
98
98
  } else if (variant === "navigation" && showActivities && day.activities?.length) {
99
99
  const primaryActivity = day.activities[0];
100
100
  if (primaryActivity.status === "near-deadline") {
@@ -330,7 +330,7 @@ var Calendar = ({
330
330
  );
331
331
  let spanClass = "";
332
332
  if (day.isSelected && day.isToday) {
333
- spanClass = "h-6 w-6 rounded-full bg-[#1c61b2] text-text";
333
+ spanClass = "h-6 w-6 rounded-full bg-primary-800 text-text";
334
334
  } else if (day.isSelected) {
335
335
  spanClass = "h-6 w-6 rounded-full bg-primary-950 text-text";
336
336
  }
@@ -342,12 +342,12 @@ var Calendar = ({
342
342
  "button",
343
343
  {
344
344
  className: `
345
- w-9 h-9
346
- flex items-center justify-center
347
- text-md font-normal
348
- cursor-pointer
345
+ w-9 h-9
346
+ flex items-center justify-center
347
+ text-md font-normal
348
+ cursor-pointer
349
349
  rounded-full
350
- ${dayStyle}
350
+ ${dayStyle}
351
351
  ${textStyle}
352
352
  `,
353
353
  onClick: () => handleDateSelect(day),
@@ -496,13 +496,13 @@ var Calendar = ({
496
496
  "button",
497
497
  {
498
498
  className: `
499
- w-10 h-10
500
- flex items-center justify-center
501
- text-xl font-normal
502
- cursor-pointer
499
+ w-10 h-10
500
+ flex items-center justify-center
501
+ text-xl font-normal
502
+ cursor-pointer
503
503
  rounded-full
504
504
  focus:outline-none focus:ring-2 focus:ring-primary-600 focus:ring-offset-1
505
- ${dayStyle}
505
+ ${dayStyle}
506
506
  ${textStyle}
507
507
  `,
508
508
  onClick: () => handleDateSelect(day),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/Calendar/Calendar.tsx"],"sourcesContent":["import React, { useState, useMemo, useEffect, useRef } from 'react';\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: React.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: React.FC<MonthYearPickerProps> = ({\n monthPickerRef,\n availableYears,\n currentDate,\n onYearChange,\n onMonthChange,\n}) => (\n <div\n ref={monthPickerRef}\n className=\"absolute top-full left-0 z-50 mt-1 bg-white 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-white';\n } else if (day.isToday) {\n textStyle = 'text-[#1c61b2]';\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: MouseEvent) => {\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: React.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={`bg-background rounded-xl p-3 ${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 gap-1 hover:bg-background-100 rounded px-2 py-1 transition-colors\"\n >\n <span className=\"text-sm font-medium text-text-600\">\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\">\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\">\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-[#1c61b2] 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={`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 gap-1 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 gap-1\">\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-10 h-10 \n flex items-center justify-center \n text-xl 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"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/Calendar/Calendar.tsx"],"sourcesContent":["import {\n useState,\n useMemo,\n useEffect,\n useRef,\n MouseEvent,\n RefObject,\n} from 'react';\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-white 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-white';\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={`bg-background rounded-xl p-3 ${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 gap-1 hover:bg-background-100 rounded px-2 py-1 transition-colors\"\n >\n <span className=\"text-sm font-medium text-text-600\">\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\">\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\">\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={`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 gap-1 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 gap-1\">\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-10 h-10\n flex items-center justify-center\n text-xl 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"],"mappings":"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","names":[]}
@@ -1,5 +1,10 @@
1
1
  // src/components/Calendar/Calendar.tsx
2
- import { useState, useMemo, useEffect, useRef } from "react";
2
+ import {
3
+ useState,
4
+ useMemo,
5
+ useEffect,
6
+ useRef
7
+ } from "react";
3
8
  import { jsx, jsxs } from "react/jsx-runtime";
4
9
  var WEEK_DAYS = ["SEG", "TER", "QUA", "QUI", "SEX", "S\xC1B", "DOM"];
5
10
  var WEEK_DAYS_SHORT = ["S", "T", "Q", "Q", "S", "S", "D"];
@@ -69,7 +74,7 @@ var getDayStyles = (day, variant, showActivities) => {
69
74
  dayStyle = "bg-primary-800";
70
75
  textStyle = "text-white";
71
76
  } else if (day.isToday) {
72
- textStyle = "text-[#1c61b2]";
77
+ textStyle = "text-primary-800";
73
78
  } else if (variant === "navigation" && showActivities && day.activities?.length) {
74
79
  const primaryActivity = day.activities[0];
75
80
  if (primaryActivity.status === "near-deadline") {
@@ -305,7 +310,7 @@ var Calendar = ({
305
310
  );
306
311
  let spanClass = "";
307
312
  if (day.isSelected && day.isToday) {
308
- spanClass = "h-6 w-6 rounded-full bg-[#1c61b2] text-text";
313
+ spanClass = "h-6 w-6 rounded-full bg-primary-800 text-text";
309
314
  } else if (day.isSelected) {
310
315
  spanClass = "h-6 w-6 rounded-full bg-primary-950 text-text";
311
316
  }
@@ -317,12 +322,12 @@ var Calendar = ({
317
322
  "button",
318
323
  {
319
324
  className: `
320
- w-9 h-9
321
- flex items-center justify-center
322
- text-md font-normal
323
- cursor-pointer
325
+ w-9 h-9
326
+ flex items-center justify-center
327
+ text-md font-normal
328
+ cursor-pointer
324
329
  rounded-full
325
- ${dayStyle}
330
+ ${dayStyle}
326
331
  ${textStyle}
327
332
  `,
328
333
  onClick: () => handleDateSelect(day),
@@ -471,13 +476,13 @@ var Calendar = ({
471
476
  "button",
472
477
  {
473
478
  className: `
474
- w-10 h-10
475
- flex items-center justify-center
476
- text-xl font-normal
477
- cursor-pointer
479
+ w-10 h-10
480
+ flex items-center justify-center
481
+ text-xl font-normal
482
+ cursor-pointer
478
483
  rounded-full
479
484
  focus:outline-none focus:ring-2 focus:ring-primary-600 focus:ring-offset-1
480
- ${dayStyle}
485
+ ${dayStyle}
481
486
  ${textStyle}
482
487
  `,
483
488
  onClick: () => handleDateSelect(day),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/Calendar/Calendar.tsx"],"sourcesContent":["import React, { useState, useMemo, useEffect, useRef } from 'react';\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: React.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: React.FC<MonthYearPickerProps> = ({\n monthPickerRef,\n availableYears,\n currentDate,\n onYearChange,\n onMonthChange,\n}) => (\n <div\n ref={monthPickerRef}\n className=\"absolute top-full left-0 z-50 mt-1 bg-white 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-white';\n } else if (day.isToday) {\n textStyle = 'text-[#1c61b2]';\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: MouseEvent) => {\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: React.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={`bg-background rounded-xl p-3 ${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 gap-1 hover:bg-background-100 rounded px-2 py-1 transition-colors\"\n >\n <span className=\"text-sm font-medium text-text-600\">\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\">\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\">\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-[#1c61b2] 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={`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 gap-1 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 gap-1\">\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-10 h-10 \n flex items-center justify-center \n text-xl 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"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/Calendar/Calendar.tsx"],"sourcesContent":["import {\n useState,\n useMemo,\n useEffect,\n useRef,\n MouseEvent,\n RefObject,\n} from 'react';\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-white 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-white';\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={`bg-background rounded-xl p-3 ${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 gap-1 hover:bg-background-100 rounded px-2 py-1 transition-colors\"\n >\n <span className=\"text-sm font-medium text-text-600\">\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\">\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\">\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={`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 gap-1 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 gap-1\">\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-10 h-10\n flex items-center justify-center\n text-xl 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"],"mappings":"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","names":[]}
@@ -15,7 +15,7 @@ interface DropdownMenuProps {
15
15
  open?: boolean;
16
16
  onOpenChange?: (open: boolean) => void;
17
17
  }
18
- declare const DropdownMenu: ({ children, open, onOpenChange }: DropdownMenuProps) => react_jsx_runtime.JSX.Element;
18
+ declare const DropdownMenu: ({ children, open: propOpen, onOpenChange, }: DropdownMenuProps) => react_jsx_runtime.JSX.Element;
19
19
  declare const DropdownMenuTrigger: {
20
20
  ({ className, children, onClick, store: externalStore, ...props }: HTMLAttributes<HTMLButtonElement> & {
21
21
  disabled?: boolean;
@@ -15,7 +15,7 @@ interface DropdownMenuProps {
15
15
  open?: boolean;
16
16
  onOpenChange?: (open: boolean) => void;
17
17
  }
18
- declare const DropdownMenu: ({ children, open, onOpenChange }: DropdownMenuProps) => react_jsx_runtime.JSX.Element;
18
+ declare const DropdownMenu: ({ children, open: propOpen, onOpenChange, }: DropdownMenuProps) => react_jsx_runtime.JSX.Element;
19
19
  declare const DropdownMenuTrigger: {
20
20
  ({ className, children, onClick, store: externalStore, ...props }: HTMLAttributes<HTMLButtonElement> & {
21
21
  disabled?: boolean;
@@ -127,16 +127,17 @@ var injectStore = (children, store) => {
127
127
  return child;
128
128
  });
129
129
  };
130
- var DropdownMenu = ({ children, open, onOpenChange }) => {
130
+ var DropdownMenu = ({
131
+ children,
132
+ open: propOpen,
133
+ onOpenChange
134
+ }) => {
131
135
  const storeRef = (0, import_react.useRef)(null);
132
136
  storeRef.current ??= createDropdownStore();
133
137
  const store = storeRef.current;
134
- const isControlled = open !== void 0;
135
- const uncontrolledOpen = (0, import_zustand.useStore)(store, (s) => s.open);
136
- const currentOpen = isControlled ? open : uncontrolledOpen;
138
+ const { open, setOpen: storeSetOpen } = (0, import_zustand.useStore)(store, (s) => s);
137
139
  const setOpen = (newOpen) => {
138
- onOpenChange?.(newOpen);
139
- if (!isControlled) store.setState({ open: newOpen });
140
+ storeSetOpen(newOpen);
140
141
  };
141
142
  const menuRef = (0, import_react.useRef)(null);
142
143
  const handleArrowDownOrArrowUp = (event) => {
@@ -173,8 +174,7 @@ var DropdownMenu = ({ children, open, onOpenChange }) => {
173
174
  }
174
175
  };
175
176
  (0, import_react.useEffect)(() => {
176
- onOpenChange?.(currentOpen);
177
- if (currentOpen) {
177
+ if (open) {
178
178
  document.addEventListener("mousedown", handleClickOutside);
179
179
  document.addEventListener("keydown", handleDownkey);
180
180
  }
@@ -182,12 +182,16 @@ var DropdownMenu = ({ children, open, onOpenChange }) => {
182
182
  document.removeEventListener("mousedown", handleClickOutside);
183
183
  document.removeEventListener("keydown", handleDownkey);
184
184
  };
185
- }, [currentOpen]);
185
+ }, [open]);
186
+ (0, import_react.useEffect)(() => {
187
+ setOpen(open);
188
+ onOpenChange?.(open);
189
+ }, [open, onOpenChange]);
186
190
  (0, import_react.useEffect)(() => {
187
- if (isControlled) {
188
- store.setState({ open });
191
+ if (propOpen) {
192
+ setOpen(propOpen);
189
193
  }
190
- }, []);
194
+ }, [propOpen]);
191
195
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "relative", ref: menuRef, children: injectStore(children, store) });
192
196
  };
193
197
  var DropdownMenuTrigger = ({