UNPKG

phx-react

Version:

PHX REACT

142 lines 7.97 kB
import { ArrowLeftIcon, ArrowRightIcon } from '@heroicons/react/20/solid'; import React, { useState, useMemo, useCallback, useEffect } from 'react'; var getMonthName = function (month) { var 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) var weekdays = ['T2', 'T3', 'T4', 'T5', 'T6', 'T7', 'CN']; export function classNames() { var classes = []; for (var _i = 0; _i < arguments.length; _i++) { classes[_i] = arguments[_i]; } return classes.filter(Boolean).join(' '); } export var PHXCalendar = function (_a) { var defaultEndDate = _a.defaultEndDate, defaultStartDate = _a.defaultStartDate, onChange = _a.onChange; var _b = useState(new Date().getFullYear()), currentYear = _b[0], setCurrentYear = _b[1]; var _c = useState(new Date().getMonth()), currentMonth = _c[0], setCurrentMonth = _c[1]; var _d = useState(defaultStartDate), startDate = _d[0], setStartDate = _d[1]; var _e = useState(defaultEndDate), endDate = _e[0], setEndDate = _e[1]; var calendar = useMemo(function () { var createCalendar = function (year, month) { var firstDayOfMonth = new Date(year, month, 1); var daysInMonth = new Date(year, month + 1, 0).getDate(); var today = new Date(); var calendarData = []; // Tính thứ của ngày đầu tháng (T2 = 0, ..., CN = 6) var 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 (var day = 1; day <= daysInMonth; day++) { var date = new Date(year, month, day); var dayOfWeek = (firstDayIndex + day - 1) % 7; // T2 = 0, T3 = 1, ..., CN = 6 calendarData.push({ date: date, dayOfWeek: 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]); var handleChangeMonth = useCallback(function (type) { switch (type) { case 'next': setCurrentMonth(function (prev) { return (prev + 1) % 12; }); setCurrentYear(function (prev) { return prev + (currentMonth === 11 ? 1 : 0); }); break; case 'prev': setCurrentMonth(function (prev) { return (prev - 1 + 12) % 12; }); setCurrentYear(function (prev) { return prev - (currentMonth === 0 ? 1 : 0); }); break; default: break; } }, [currentMonth]); var handleSelectDate = useCallback(function (day) { var selectedDate = day.date; if (!startDate || (startDate && endDate)) { setStartDate(selectedDate); setEndDate(undefined); } else { if (selectedDate < startDate) { setStartDate(selectedDate); setEndDate(startDate); } else { setEndDate(selectedDate); var selectedMonth = selectedDate.getMonth(); var selectedYear = selectedDate.getFullYear(); var isSameMonthAsLeft = selectedMonth === currentMonth && selectedYear === currentYear; var isSameMonthAsRight = selectedMonth === (currentMonth + 1) % 12 && selectedYear === (currentMonth === 11 ? currentYear + 1 : currentYear); if (!isSameMonthAsLeft && !isSameMonthAsRight) { // Đặt currentMonth là tháng trước của endDate var newMonth = selectedMonth === 0 ? 11 : selectedMonth - 1; var newYear = selectedMonth === 0 ? selectedYear - 1 : selectedYear; setCurrentMonth(newMonth); setCurrentYear(newYear); } } } }, [startDate, endDate, currentMonth, currentYear]); useEffect(function () { if (startDate && endDate) { onChange(startDate, endDate); } }, [startDate, endDate, onChange]); useEffect(function () { if (defaultStartDate) setStartDate(defaultStartDate); if (defaultEndDate) setEndDate(defaultEndDate); }, [defaultStartDate, defaultEndDate]); return (React.createElement("div", { className: 'mt-4 flex gap-4' }, [calendar.left, calendar.right].map(function (monthData, calIdx) { var _a; return (React.createElement("div", { key: calIdx, className: 'flex-1' }, React.createElement("div", { className: 'relative mb-4 flex items-center justify-center' }, calIdx === 0 && (React.createElement("button", { className: 'absolute left-0 rounded-lg p-1 text-gray-500 hover:bg-gray-200', onClick: function () { return handleChangeMonth('prev'); }, type: 'button' }, React.createElement(ArrowLeftIcon, { className: 'h-5 w-5' }))), React.createElement("span", { className: 'text-xs font-medium' }, getMonthName(currentMonth + calIdx), ' ', calIdx === 0 ? currentYear : currentMonth === 11 ? currentYear + 1 : currentYear), calIdx === 1 && (React.createElement("button", { className: 'absolute right-0 rounded-lg p-1 text-gray-500 hover:bg-gray-200', onClick: function () { return handleChangeMonth('next'); }, type: 'button' }, React.createElement(ArrowRightIcon, { className: 'h-5 w-5' })))), React.createElement("div", { className: 'mb-4 grid grid-cols-7 gap-0 border-gray-200' }, weekdays.map(function (day, index) { return (React.createElement("div", { key: index, className: 'py-2 text-center text-xs font-medium text-gray-500' }, day)); })), React.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(function (_, index) { return (React.createElement("div", { key: "empty-".concat(index), className: 'py-2' }) // Ô trống trước ngày 1 ); }), monthData.map(function (day, index) { var isStart = startDate && day.date.getTime() === startDate.getTime(); var isEnd = endDate && day.date.getTime() === endDate.getTime(); var isInRange = startDate && endDate && day.date > startDate && day.date < endDate; var isSingleDay = startDate && !endDate && day.date.getTime() === startDate.getTime(); return (React.createElement("button", { key: index, className: classNames('relative py-2 text-xs text-gray-800 hover:bg-gray-200', 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'), onClick: function () { return handleSelectDate(day); }, type: 'button' }, day.date.getDate())); })))); }))); }; //# sourceMappingURL=Calendar.js.map