UNPKG

analytica-frontend-lib

Version:

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

535 lines (532 loc) 20.7 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/components/Calendar/Calendar.tsx var Calendar_exports = {}; __export(Calendar_exports, { WEEK_DAYS: () => WEEK_DAYS, default: () => Calendar_default }); module.exports = __toCommonJS(Calendar_exports); var import_react = require("react"); // src/utils/utils.ts var import_clsx = require("clsx"); var import_tailwind_merge = require("tailwind-merge"); function cn(...inputs) { return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs)); } // src/components/Calendar/Calendar.tsx var import_jsx_runtime = require("react/jsx-runtime"); var WEEK_DAYS = ["SEG", "TER", "QUA", "QUI", "SEX", "S\xC1B", "DOM"]; var WEEK_DAYS_SHORT = ["S", "T", "Q", "Q", "S", "S", "D"]; var MONTH_NAMES = [ "Janeiro", "Fevereiro", "Mar\xE7o", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro" ]; var MonthYearPicker = ({ monthPickerRef, availableYears, currentDate, onYearChange, onMonthChange }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( "div", { ref: monthPickerRef, 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]", children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mb-4", children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "text-sm font-medium text-text-700 mb-2", children: "Selecionar Ano" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-4 gap-1 max-h-32 overflow-y-auto", children: availableYears.map((year) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "button", { onClick: () => onYearChange(year), className: ` px-2 py-1 text-xs rounded text-center hover:bg-background-100 transition-colors ${year === currentDate.getFullYear() ? "bg-primary-800 text-text font-medium hover:text-text-950" : "text-text-700"} `, children: year }, year )) }) ] }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "text-sm font-medium text-text-700 mb-2", children: "Selecionar M\xEAs" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-3 gap-1", children: MONTH_NAMES.map((month, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "button", { onClick: () => onMonthChange(index, currentDate.getFullYear()), className: ` px-2 py-2 text-xs rounded text-center hover:bg-background-100 transition-colors ${index === currentDate.getMonth() ? "bg-primary-800 text-text font-medium hover:text-text-950" : "text-text-700"} `, children: month.substring(0, 3) }, month )) }) ] }) ] } ); var getDayStyles = (day, variant, showActivities) => { let dayStyle = ""; let textStyle = ""; if (variant === "selection" && day.isSelected) { dayStyle = "bg-primary-800"; textStyle = "text-text"; } else if (day.isToday) { textStyle = "text-primary-800"; } else if (variant === "navigation" && showActivities && day.activities?.length) { const primaryActivity = day.activities[0]; if (primaryActivity.status === "near-deadline") { dayStyle = "bg-warning-background border-2 border-warning-400"; textStyle = "text-text-950"; } else if (primaryActivity.status === "in-deadline") { dayStyle = "bg-success-background border-2 border-success-300"; textStyle = "text-text-950"; } else if (primaryActivity.status === "overdue") { dayStyle = "bg-error-background border-2 border-error-300"; textStyle = "text-text-950"; } else { dayStyle = "border-2 border-blue-500"; textStyle = "text-blue-500"; } } else { textStyle = "text-text-950 hover:bg-background-100"; } return { dayStyle, textStyle }; }; var Calendar = ({ variant = "selection", selectedDate, onDateSelect, onMonthChange, activities = {}, showActivities = true, className = "" }) => { const [currentDate, setCurrentDate] = (0, import_react.useState)(selectedDate || /* @__PURE__ */ new Date()); const [isMonthPickerOpen, setIsMonthPickerOpen] = (0, import_react.useState)(false); const monthPickerRef = (0, import_react.useRef)(null); const monthPickerContainerRef = (0, import_react.useRef)(null); (0, import_react.useEffect)(() => { const handleClickOutside = (event) => { if (monthPickerContainerRef.current && !monthPickerContainerRef.current.contains(event.target)) { setIsMonthPickerOpen(false); } }; if (isMonthPickerOpen) { document.addEventListener("mousedown", handleClickOutside); } return () => { document.removeEventListener("mousedown", handleClickOutside); }; }, [isMonthPickerOpen]); const today = /* @__PURE__ */ new Date(); const availableYears = (0, import_react.useMemo)(() => { const currentYear = (/* @__PURE__ */ new Date()).getFullYear(); const years = []; for (let year = currentYear - 10; year <= currentYear + 10; year++) { years.push(year); } return years; }, []); const calendarData = (0, import_react.useMemo)(() => { const year = currentDate.getFullYear(); const month = currentDate.getMonth(); const firstDay = new Date(year, month, 1); const startDate = new Date(firstDay); const firstDayOfWeek = (firstDay.getDay() + 6) % 7; startDate.setDate(startDate.getDate() - firstDayOfWeek); const days = []; const currentCalendarDate = new Date(startDate); for (let i = 0; i < 42; i++) { const dateKey = currentCalendarDate.toISOString().split("T")[0]; const dayActivities = activities[dateKey] || []; days.push({ date: new Date(currentCalendarDate), isCurrentMonth: currentCalendarDate.getMonth() === month, isToday: currentCalendarDate.getFullYear() === today.getFullYear() && currentCalendarDate.getMonth() === today.getMonth() && currentCalendarDate.getDate() === today.getDate(), isSelected: selectedDate ? currentCalendarDate.getFullYear() === selectedDate.getFullYear() && currentCalendarDate.getMonth() === selectedDate.getMonth() && currentCalendarDate.getDate() === selectedDate.getDate() : false, activities: dayActivities }); currentCalendarDate.setDate(currentCalendarDate.getDate() + 1); } return days; }, [currentDate, selectedDate, activities]); const goToPreviousMonth = () => { const newDate = new Date(currentDate); newDate.setMonth(newDate.getMonth() - 1); setCurrentDate(newDate); onMonthChange?.(newDate); }; const goToNextMonth = () => { const newDate = new Date(currentDate); newDate.setMonth(newDate.getMonth() + 1); setCurrentDate(newDate); onMonthChange?.(newDate); }; const goToMonth = (month, year) => { const newDate = new Date(year, month, 1); setCurrentDate(newDate); setIsMonthPickerOpen(false); onMonthChange?.(newDate); }; const handleYearChange = (year) => { const newDate = new Date(year, currentDate.getMonth(), 1); setCurrentDate(newDate); }; const toggleMonthPicker = (event) => { event.stopPropagation(); setIsMonthPickerOpen(!isMonthPickerOpen); }; const handleDateSelect = (day) => { onDateSelect?.(day.date); }; if (variant === "navigation") { return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: cn("bg-background rounded-xl pt-6", className), children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between mb-4 px-6", children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative", ref: monthPickerContainerRef, children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( "button", { onClick: toggleMonthPicker, className: "flex items-center group gap-1 rounded transition-colors cursor-pointer", children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "text-sm font-medium text-text-600 group-hover:text-primary-950", children: [ MONTH_NAMES[currentDate.getMonth()], " ", currentDate.getFullYear() ] }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "svg", { className: `w-4 h-4 text-primary-950 transition-transform ${isMonthPickerOpen ? "rotate-180" : ""}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" } ) } ) ] } ), isMonthPickerOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsx)( MonthYearPicker, { monthPickerRef, availableYears, currentDate, onYearChange: handleYearChange, onMonthChange: goToMonth } ) ] }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-10", children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "button", { onClick: goToPreviousMonth, className: "p-1 rounded hover:bg-background-100 transition-colors", "aria-label": "M\xEAs anterior", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "svg", { className: "w-6 h-6 text-primary-950", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" } ) } ) } ), /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "button", { onClick: goToNextMonth, className: "p-1 rounded hover:bg-background-100 transition-colors", "aria-label": "Pr\xF3ximo m\xEAs", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "svg", { className: "w-6 h-6 text-primary-950", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" } ) } ) } ) ] }) ] }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-7 gap-1 mb-2 px-3", children: WEEK_DAYS_SHORT.map((day, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "div", { className: "h-9 flex items-center justify-center text-xs font-normal text-text-600", children: day }, `${day}-${index}` )) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-7 gap-1 px-3", children: calendarData.map((day) => { if (!day.isCurrentMonth) { return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "div", { className: "flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-9 h-9" }) }, day.date.getTime() ); } const { dayStyle, textStyle } = getDayStyles( day, variant, showActivities ); let spanClass = ""; if (day.isSelected && day.isToday) { spanClass = "h-6 w-6 rounded-full bg-primary-800 text-text"; } else if (day.isSelected) { spanClass = "h-6 w-6 rounded-full bg-primary-950 text-text"; } return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "div", { className: "flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "button", { className: ` w-9 h-9 flex items-center justify-center text-md font-normal cursor-pointer rounded-full ${dayStyle} ${textStyle} `, onClick: () => handleDateSelect(day), "aria-label": `${day.date.getDate()} de ${MONTH_NAMES[day.date.getMonth()]}`, "aria-current": day.isToday ? "date" : void 0, tabIndex: 0, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: spanClass, children: day.date.getDate() }) } ) }, day.date.getTime() ); }) }) ] }); } return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: cn("bg-background rounded-xl p-4", className), children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between mb-3.5", children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative", ref: monthPickerContainerRef, children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( "button", { onClick: toggleMonthPicker, className: "flex items-center gap-2 hover:bg-background-100 rounded px-2 py-1 transition-colors", children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h2", { className: "text-lg font-semibold text-text-950", children: [ MONTH_NAMES[currentDate.getMonth()], " ", currentDate.getFullYear() ] }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "svg", { className: `w-4 h-4 text-text-400 transition-transform ${isMonthPickerOpen ? "rotate-180" : ""}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" } ) } ) ] } ), isMonthPickerOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsx)( MonthYearPicker, { monthPickerRef, availableYears, currentDate, onYearChange: handleYearChange, onMonthChange: goToMonth } ) ] }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-1", children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "button", { onClick: goToPreviousMonth, className: "p-1 rounded-md hover:bg-background-100 transition-colors", "aria-label": "M\xEAs anterior", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "svg", { className: "w-6 h-6 text-primary-950", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" } ) } ) } ), /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "button", { onClick: goToNextMonth, className: "p-1 rounded-md hover:bg-background-100 transition-colors", "aria-label": "Pr\xF3ximo m\xEAs", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "svg", { className: "w-6 h-6 text-primary-950", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" } ) } ) } ) ] }) ] }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-7 mb-2", children: WEEK_DAYS.map((day) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "div", { className: "h-4 flex items-center justify-center text-xs font-semibold text-text-500", children: day }, day )) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-7", children: calendarData.map((day) => { if (!day.isCurrentMonth) { return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "div", { className: "flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-10 h-10" }) }, day.date.getTime() ); } const { dayStyle, textStyle } = getDayStyles( day, variant, showActivities ); return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "div", { className: "flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "button", { className: ` w-9 h-9 flex items-center justify-center text-lg font-normal cursor-pointer rounded-full focus:outline-none focus:ring-2 focus:ring-primary-600 focus:ring-offset-1 ${dayStyle} ${textStyle} `, onClick: () => handleDateSelect(day), "aria-label": `${day.date.getDate()} de ${MONTH_NAMES[day.date.getMonth()]}`, "aria-current": day.isToday ? "date" : void 0, tabIndex: 0, children: day.date.getDate() } ) }, day.date.getTime() ); }) }) ] }); }; var Calendar_default = Calendar; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { WEEK_DAYS }); //# sourceMappingURL=index.js.map