UNPKG

phx-react

Version:

PHX REACT

159 lines 9.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PHXCalendar = void 0; exports.classNames = classNames; const tslib_1 = require("tslib"); const solid_1 = require("@heroicons/react/20/solid"); const react_1 = tslib_1.__importStar(require("react")); const getMonthName = (month) => { const monthNames = [ 'Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6', 'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12', ]; return monthNames[month]; }; // Mảng tên các ngày trong tuần (T2 -> CN) const weekdays = ['T2', 'T3', 'T4', 'T5', 'T6', 'T7', 'CN']; function classNames(...classes) { return classes.filter(Boolean).join(' '); } const PHXCalendar = ({ defaultEndDate, defaultStartDate, max, onChange }) => { const [currentYear, setCurrentYear] = (0, react_1.useState)(new Date().getFullYear()); const [currentMonth, setCurrentMonth] = (0, react_1.useState)(new Date().getMonth()); const [startDate, setStartDate] = (0, react_1.useState)(defaultStartDate); const [endDate, setEndDate] = (0, react_1.useState)(defaultEndDate); const calendar = (0, react_1.useMemo)(() => { const createCalendar = (year, month) => { const firstDayOfMonth = new Date(year, month, 1); const daysInMonth = new Date(year, month + 1, 0).getDate(); const today = new Date(); const calendarData = []; // Tính thứ của ngày đầu tháng (T2 = 0, ..., CN = 6) const firstDayIndex = (firstDayOfMonth.getDay() + 6) % 7; // Chuyển Chủ Nhật (0) thành 6, Thứ Hai (1) thành 0 // Chỉ thêm các ngày trong tháng hiện tại for (let day = 1; day <= daysInMonth; day++) { const date = new Date(year, month, day); const dayOfWeek = (firstDayIndex + day - 1) % 7; // T2 = 0, T3 = 1, ..., CN = 6 calendarData.push({ date, dayOfWeek, isCurrentMonth: true, isToday: date.getDate() === today.getDate() && date.getMonth() === today.getMonth() && date.getFullYear() === today.getFullYear(), currentMonth: month + 1, }); } return calendarData; }; return { left: createCalendar(currentYear, currentMonth), right: createCalendar(currentMonth === 11 ? currentYear + 1 : currentYear, currentMonth === 11 ? 0 : currentMonth + 1), }; }, [currentYear, currentMonth]); const handleChangeMonth = (0, react_1.useCallback)((type) => { switch (type) { case 'next': if (max) { const rightMonthYear = currentMonth === 11 ? currentYear + 1 : currentYear; const rightMonth = currentMonth === 11 ? 0 : currentMonth + 1; const nextMonthYear = rightMonth === 11 ? rightMonthYear + 1 : rightMonthYear; const nextMonth = (rightMonth + 1) % 12; if (new Date(nextMonthYear, nextMonth, 1) <= max) { setCurrentMonth((prev) => (prev + 1) % 12); setCurrentYear((prev) => prev + (currentMonth === 11 ? 1 : 0)); } } else { setCurrentMonth((prev) => (prev + 1) % 12); setCurrentYear((prev) => prev + (currentMonth === 11 ? 1 : 0)); } break; case 'prev': setCurrentMonth((prev) => (prev - 1 + 12) % 12); setCurrentYear((prev) => prev - (currentMonth === 0 ? 1 : 0)); break; default: break; } }, [currentMonth, max]); const handleSelectDate = (0, react_1.useCallback)((day) => { if (max && day.date > max) return; const selectedDate = day.date; if (!startDate || (startDate && endDate)) { setStartDate(selectedDate); setEndDate(undefined); } else { if (selectedDate < startDate) { setStartDate(selectedDate); setEndDate(startDate); } else { setEndDate(selectedDate); const selectedMonth = selectedDate.getMonth(); const selectedYear = selectedDate.getFullYear(); const isSameMonthAsLeft = selectedMonth === currentMonth && selectedYear === currentYear; const isSameMonthAsRight = selectedMonth === (currentMonth + 1) % 12 && selectedYear === (currentMonth === 11 ? currentYear + 1 : currentYear); if (!isSameMonthAsLeft && !isSameMonthAsRight) { // Đặt currentMonth là tháng trước của endDate const newMonth = selectedMonth === 0 ? 11 : selectedMonth - 1; const newYear = selectedMonth === 0 ? selectedYear - 1 : selectedYear; setCurrentMonth(newMonth); setCurrentYear(newYear); } } } }, [startDate, endDate, currentMonth, currentYear, max]); (0, react_1.useEffect)(() => { onChange(startDate, endDate); }, [startDate, endDate, onChange]); (0, react_1.useEffect)(() => { if (defaultStartDate) setStartDate(defaultStartDate); if (defaultEndDate) setEndDate(defaultEndDate); }, [defaultStartDate, defaultEndDate]); return (react_1.default.createElement("div", { className: 'mt-4 flex gap-4' }, [calendar.left, calendar.right].map((monthData, calIdx) => { var _a; return (react_1.default.createElement("div", { key: calIdx, className: 'flex-1' }, react_1.default.createElement("div", { className: 'relative mb-4 flex items-center justify-center' }, calIdx === 0 && (react_1.default.createElement("button", { className: 'absolute left-0 rounded-lg p-1 text-gray-500 hover:bg-gray-200', onClick: () => handleChangeMonth('prev'), type: 'button' }, react_1.default.createElement(solid_1.ArrowLeftIcon, { className: 'h-5 w-5' }))), react_1.default.createElement("span", { className: 'text-xs font-medium' }, getMonthName(currentMonth + calIdx), ' ', calIdx === 0 ? currentYear : currentMonth === 11 ? currentYear + 1 : currentYear), calIdx === 1 && (react_1.default.createElement("button", { className: classNames('absolute right-0 rounded-lg p-1 text-gray-500 hover:bg-gray-200', max && new Date(currentMonth === 11 ? currentYear + 1 : currentYear, currentMonth === 11 ? 0 : currentMonth + 1, 1) > max && 'cursor-not-allowed opacity-50'), disabled: max && new Date(currentMonth === 11 ? currentYear + 1 : currentYear, currentMonth === 11 ? 0 : currentMonth + 1, 1) > max, onClick: () => handleChangeMonth('next'), type: 'button' }, react_1.default.createElement(solid_1.ArrowRightIcon, { className: 'h-5 w-5' })))), react_1.default.createElement("div", { className: 'mb-4 grid grid-cols-7 gap-0 border-gray-200' }, weekdays.map((day, index) => (react_1.default.createElement("div", { key: index, className: 'py-2 text-center text-xs font-medium text-gray-600' }, day)))), react_1.default.createElement("div", { className: 'grid grid-cols-7 gap-0' }, Array.from({ length: ((_a = monthData[0]) === null || _a === void 0 ? void 0 : _a.dayOfWeek) || 0 }).map((_, index) => (react_1.default.createElement("div", { key: `empty-${index}`, className: 'py-2' }) // Ô trống trước ngày 1 )), monthData.map((day, index) => { const isStart = startDate && day.date.getTime() === startDate.getTime(); const isEnd = endDate && day.date.getTime() === endDate.getTime(); const isInRange = startDate && endDate && day.date > startDate && day.date < endDate; const isSingleDay = startDate && !endDate && day.date.getTime() === startDate.getTime(); const isDisabled = max && day.date > max; return (react_1.default.createElement("button", { key: index, className: classNames('relative py-2 text-xs text-gray-800 ', day.isToday && 'font-semibold text-gray-900', isInRange && 'bg-gray-300', isStart && 'rounded-l-lg bg-gray-800 text-white', isEnd && 'rounded-r-lg bg-gray-800 text-white', isSingleDay && 'rounded-lg bg-gray-800 text-white', isDisabled ? 'cursor-not-allowed opacity-50' : isInRange ? '' : 'hover:bg-gray-200'), disabled: isDisabled, onClick: () => handleSelectDate(day), type: 'button' }, day.date.getDate())); })))); }))); }; exports.PHXCalendar = PHXCalendar; //# sourceMappingURL=Calendar.js.map