2021-06-24 22:15:18 +00:00
|
|
|
import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/react/solid";
|
|
|
|
import { useEffect, useState } from "react";
|
|
|
|
import dayjs, { Dayjs } from "dayjs";
|
|
|
|
import isToday from "dayjs/plugin/isToday";
|
|
|
|
dayjs.extend(isToday);
|
2021-06-21 20:26:04 +00:00
|
|
|
|
2021-06-24 22:15:18 +00:00
|
|
|
const DatePicker = ({ weekStart, onDatePicked, workingHours, disableToday }) => {
|
|
|
|
const workingDays = workingHours.reduce((workingDays: number[], wh) => [...workingDays, ...wh.days], []);
|
2021-06-21 20:26:04 +00:00
|
|
|
const [selectedMonth, setSelectedMonth] = useState(dayjs().month());
|
2021-06-24 22:15:18 +00:00
|
|
|
const [selectedDate, setSelectedDate] = useState();
|
2021-06-21 20:26:04 +00:00
|
|
|
|
|
|
|
useEffect(() => {
|
2021-06-24 22:15:18 +00:00
|
|
|
if (selectedDate) onDatePicked(selectedDate);
|
2021-06-27 21:28:35 +00:00
|
|
|
}, [selectedDate]);
|
2021-06-21 20:26:04 +00:00
|
|
|
|
|
|
|
// Handle month changes
|
|
|
|
const incrementMonth = () => {
|
|
|
|
setSelectedMonth(selectedMonth + 1);
|
2021-06-24 22:15:18 +00:00
|
|
|
};
|
2021-06-21 20:26:04 +00:00
|
|
|
|
|
|
|
const decrementMonth = () => {
|
|
|
|
setSelectedMonth(selectedMonth - 1);
|
2021-06-24 22:15:18 +00:00
|
|
|
};
|
2021-06-21 20:26:04 +00:00
|
|
|
|
|
|
|
// Set up calendar
|
2021-06-24 22:15:18 +00:00
|
|
|
const daysInMonth = dayjs().month(selectedMonth).daysInMonth();
|
|
|
|
const days = [];
|
2021-06-21 20:26:04 +00:00
|
|
|
for (let i = 1; i <= daysInMonth; i++) {
|
|
|
|
days.push(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create placeholder elements for empty days in first week
|
|
|
|
let weekdayOfFirst = dayjs().month(selectedMonth).date(1).day();
|
2021-06-24 22:15:18 +00:00
|
|
|
if (weekStart === "Monday") {
|
2021-06-21 20:26:04 +00:00
|
|
|
weekdayOfFirst -= 1;
|
2021-06-24 22:15:18 +00:00
|
|
|
if (weekdayOfFirst < 0) weekdayOfFirst = 6;
|
2021-06-21 20:26:04 +00:00
|
|
|
}
|
2021-06-24 22:15:18 +00:00
|
|
|
const emptyDays = Array(weekdayOfFirst)
|
|
|
|
.fill(null)
|
|
|
|
.map((day, i) => (
|
|
|
|
<div key={`e-${i}`} className={"text-center w-10 h-10 rounded-full mx-auto"}>
|
|
|
|
{null}
|
|
|
|
</div>
|
|
|
|
));
|
|
|
|
|
|
|
|
const isDisabled = (day: number) => {
|
|
|
|
const date: Dayjs = dayjs().month(selectedMonth).date(day);
|
|
|
|
return (
|
|
|
|
date.isBefore(dayjs()) || !workingDays.includes(+date.format("d")) || (date.isToday() && disableToday)
|
|
|
|
);
|
|
|
|
};
|
2021-06-21 20:26:04 +00:00
|
|
|
|
|
|
|
// Combine placeholder days with actual days
|
2021-06-24 22:15:18 +00:00
|
|
|
const calendar = [
|
|
|
|
...emptyDays,
|
|
|
|
...days.map((day) => (
|
|
|
|
<button
|
|
|
|
key={day}
|
|
|
|
onClick={() => setSelectedDate(dayjs().month(selectedMonth).date(day))}
|
|
|
|
disabled={
|
|
|
|
(selectedMonth < parseInt(dayjs().format("MM")) &&
|
|
|
|
dayjs().month(selectedMonth).format("D") > day) ||
|
|
|
|
isDisabled(day)
|
|
|
|
}
|
|
|
|
className={
|
|
|
|
"text-center w-10 h-10 rounded-full mx-auto" +
|
|
|
|
(isDisabled(day) ? " text-gray-400 font-light" : " text-blue-600 font-medium") +
|
|
|
|
(selectedDate && selectedDate.isSame(dayjs().month(selectedMonth).date(day), "day")
|
|
|
|
? " bg-blue-600 text-white-important"
|
|
|
|
: !isDisabled(day)
|
|
|
|
? " bg-blue-50"
|
|
|
|
: "")
|
|
|
|
}>
|
|
|
|
{day}
|
|
|
|
</button>
|
|
|
|
)),
|
|
|
|
];
|
2021-06-21 20:26:04 +00:00
|
|
|
|
|
|
|
return (
|
2021-06-24 22:15:18 +00:00
|
|
|
<div className={"mt-8 sm:mt-0 " + (selectedDate ? "sm:w-1/3 border-r sm:px-4" : "sm:w-1/2 sm:pl-4")}>
|
2021-06-21 20:26:04 +00:00
|
|
|
<div className="flex text-gray-600 font-light text-xl mb-4 ml-2">
|
2021-06-24 22:15:18 +00:00
|
|
|
<span className="w-1/2">{dayjs().month(selectedMonth).format("MMMM YYYY")}</span>
|
2021-06-21 20:26:04 +00:00
|
|
|
<div className="w-1/2 text-right">
|
|
|
|
<button
|
|
|
|
onClick={decrementMonth}
|
2021-06-24 22:15:18 +00:00
|
|
|
className={"mr-4 " + (selectedMonth < parseInt(dayjs().format("MM")) && "text-gray-400")}
|
|
|
|
disabled={selectedMonth < parseInt(dayjs().format("MM"))}>
|
2021-06-21 20:26:04 +00:00
|
|
|
<ChevronLeftIcon className="w-5 h-5" />
|
|
|
|
</button>
|
|
|
|
<button onClick={incrementMonth}>
|
|
|
|
<ChevronRightIcon className="w-5 h-5" />
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="grid grid-cols-7 gap-y-4 text-center">
|
2021-06-24 22:15:18 +00:00
|
|
|
{["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
|
|
|
|
.sort((a, b) => (weekStart.startsWith(a) ? -1 : weekStart.startsWith(b) ? 1 : 0))
|
|
|
|
.map((weekDay) => (
|
|
|
|
<div key={weekDay} className="uppercase text-gray-400 text-xs tracking-widest">
|
|
|
|
{weekDay}
|
|
|
|
</div>
|
|
|
|
))}
|
2021-06-21 20:26:04 +00:00
|
|
|
{calendar}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
2021-06-24 22:15:18 +00:00
|
|
|
};
|
2021-06-21 20:26:04 +00:00
|
|
|
|
2021-06-24 22:15:18 +00:00
|
|
|
export default DatePicker;
|