import { add, differenceInMonths, format, getDay, getDaysInMonth, isAfter, isSameDay, isSameMonth, lastDayOfMonth, startOfMonth, startOfWeek, sub, } from 'date-fns/fp' import * as R from 'ramda' import React, { useState } from 'react' import Arrow from '../../styling/icons/arrow/month_change.svg?react' import RightArrow from '../../styling/icons/arrow/month_change_right.svg?react' import Tile from './Tile' import classes from './Calendar.module.css' const Calendar = ({ minDate, maxDate, handleSelect, ...props }) => { const [currentDisplayedMonth, setCurrentDisplayedMonth] = useState(new Date()) const weekdays = Array.from(Array(7)).map((_, i) => format('EEEEE', add({ days: i }, startOfWeek(new Date()))), ) const monthLength = month => getDaysInMonth(month) const monthdays = month => { const lastMonth = sub({ months: 1 }, month) const lastMonthRange = R.range(0, getDay(startOfMonth(month))).reverse() const lastMonthDays = R.map(i => sub({ days: i }, lastDayOfMonth(lastMonth)), )(lastMonthRange) const thisMonthRange = R.range(0, monthLength(month)) const thisMonthDays = R.map(i => add({ days: i }, startOfMonth(month)))( thisMonthRange, ) const nextMonth = add({ months: 1 }, month) const nextMonthRange = R.range( 0, 42 - lastMonthDays.length - thisMonthDays.length, ) const nextMonthDays = R.map(i => add({ days: i }, startOfMonth(nextMonth)))( nextMonthRange, ) return R.concat(R.concat(lastMonthDays, thisMonthDays), nextMonthDays) } const getRow = (month, row) => monthdays(month).slice(row * 7 - 7, row * 7) const handleNavPrev = currentMonth => { const prevMonth = sub({ months: 1 }, currentMonth) if (!minDate) setCurrentDisplayedMonth(prevMonth) else { setCurrentDisplayedMonth( isSameMonth(minDate, prevMonth) || differenceInMonths(minDate, prevMonth) > 0 ? prevMonth : currentDisplayedMonth, ) } } const handleNavNext = currentMonth => { const nextMonth = add({ months: 1 }, currentMonth) if (!maxDate) setCurrentDisplayedMonth(nextMonth) else { setCurrentDisplayedMonth( isSameMonth(maxDate, nextMonth) || differenceInMonths(nextMonth, maxDate) > 0 ? nextMonth : currentDisplayedMonth, ) } } return (
{`${format('MMMM', currentDisplayedMonth)} ${format( 'yyyy', currentDisplayedMonth, )}`}
{weekdays.map((day, key) => ( ))} {R.range(1, 8).map((row, key) => ( {getRow(currentDisplayedMonth, row).map((day, key) => ( ))} ))}
{day}
handleSelect(day)}> {format('d', day)}
) } export default Calendar