diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..1ff94f7 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["next/babel"] +} diff --git a/.eslintrc.json b/.eslintrc.json index be19e49..7b88757 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,23 +1,18 @@ { - "env": { - "browser": true, - "es2020": true, - "node": true + "env": { + "browser": true, + "es2020": true, + "node": true, + "jest": true + }, + "extends": ["eslint:recommended", "plugin:react/recommended"], + "parserOptions": { + "ecmaFeatures": { + "jsx": true }, - "extends": [ - "eslint:recommended", - "plugin:react/recommended" - ], - "parserOptions": { - "ecmaFeatures": { - "jsx": true - }, - "ecmaVersion": 11, - "sourceType": "module" - }, - "plugins": [ - "react" - ], - "rules": { - } + "ecmaVersion": 11, + "sourceType": "module" + }, + "plugins": ["react"], + "rules": {} } diff --git a/components/contact.js b/components/contact.js index 3784b39..93821eb 100644 --- a/components/contact.js +++ b/components/contact.js @@ -1,5 +1,5 @@ -import { useContext } from 'react' -import { WizardContext, ACTIONS } from '../context/wizardStore' +import React, { useContext } from 'react' +import { WizardContext } from '../context/wizardStore' import Required from './required' import Form from 'react-bootstrap/Form' diff --git a/components/dateSelect.js b/components/dateSelect.js index f5c5c4f..8787a4f 100644 --- a/components/dateSelect.js +++ b/components/dateSelect.js @@ -1,35 +1,69 @@ -import { useContext, useState } from 'react' +import React, { useContext, useState, useRef, useEffect } from 'react' import useSWR from 'swr' -import { WizardContext, ACTIONS } from '../context/wizardStore' +import { WizardContext } from '../context/wizardStore' import Form from 'react-bootstrap/Form' +import Button from 'react-bootstrap/Button' -import moment from 'moment' -import 'react-dates/initialize' -import { DateRangePicker, SingleDatePicker } from 'react-dates' +import { DateUtils } from 'react-day-picker' +import DayPickerInput from 'react-day-picker/DayPickerInput' import Required from './required' import { dateFormat } from '../helpers/date' +import { getNextSmaller, getNextBigger } from '../helpers/array' const fetcher = (path) => fetch(path).then((r) => r.json()) export default function DateSelect() { - const [focusedInput, setFocusedInput] = useState(null) const { state, onChange } = useContext(WizardContext) + const [range, setRange] = useState({ + form: state.startDate && new Date(state.StartDate), + to: state.endDate && new Date(state.endDate), + }) + const { from, to } = range const { data: daysBooked, error: fetchBookedOnError } = useSWR( '/api/daysbooked', fetcher ) + const prevBookedDay = getNextSmaller(daysBooked, dateFormat(from || to)) + const nextBookedDay = getNextBigger(daysBooked, dateFormat(from || to)) - const { multipleDays, startDate, endDate } = state.formData + const fromRef = useRef() + const toRef = useRef() - function isDayBlocked(momentDay) { + function dayBooked(day) { + return daysBooked && daysBooked.includes(dateFormat(day)) + } + + function dayDisabled(day) { return ( - daysBooked && daysBooked.some((rawDay) => momentDay.isSame(rawDay, 'day')) + DateUtils.isPastDay(day) || + dayBooked(day) || + (prevBookedDay && day < new Date(prevBookedDay)) || + (nextBookedDay && day > new Date(nextBookedDay)) ) } + function parseDate(value) { + return new Date(value) + } + + useEffect(() => { + toRef.current?.getInput().focus() + }, [from]) + + useEffect(() => { + onChange({ startDate: from?.toISOString(), endDate: to?.toISOString() }) + }, [from, to]) + + const disabledDays = [dayDisabled] + const modifiers = { + dayBooked, + start: from, + end: to, + } + if (fetchBookedOnError) { return (