Files
pfadi-bussle/components/dateSelect.js
2020-08-11 22:52:16 +02:00

129 lines
3.4 KiB
JavaScript

import React, { useContext, useState, useRef, useEffect } from 'react'
import useSWR from 'swr'
import { WizardContext } from '../context/wizardStore'
import Form from 'react-bootstrap/Form'
import Button from 'react-bootstrap/Button'
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 { 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 fromRef = useRef()
const toRef = useRef()
function dayBooked(day) {
return daysBooked && daysBooked.includes(dateFormat(day))
}
function dayDisabled(day) {
return (
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 (
<div>
Entschuldige, aber die Buchungszeiten konnten nicht geladen werden.
Versuchen Sie es später nochmals.
</div>
)
}
return (
<Form.Group>
<Form.Label component="legend" style={{ display: 'block' }}>
Datum <Required />
</Form.Label>
<Form.Group>
<DayPickerInput
ref={fromRef}
component={Form.Control}
value={from}
placeholder="Von"
formatDate={dateFormat}
parseDate={parseDate}
dayPickerProps={{
className: 'Selectable',
selectedDays: [from, { from, to }],
disabledDays,
modifiers,
numberOfMonths: 1,
}}
onDayChange={(from) => setRange({ ...range, from })}
/>
<Form.Label className="px-2">bis</Form.Label>
<DayPickerInput
ref={toRef}
component={Form.Control}
inputProps={{ disabled: !from }}
value={to}
placeholder="Bis"
formatDate={dateFormat}
parseDate={parseDate}
dayPickerProps={{
className: 'Selectable',
selectedDays: [from, { from, to }],
disabledDays,
modifiers,
numberOfMonths: 1,
month: from,
fromMonth: from,
}}
onDayChange={(to) => setRange({ ...range, to })}
/>
<Button
className="ml-2"
variant="outline-secondary"
onClick={() => setRange({})}
>
Zurücksetzen
</Button>
</Form.Group>
</Form.Group>
)
}