Files
pfadi-bussle/components/dateSelect.js
2020-08-11 00:28:12 +02:00

188 lines
5.6 KiB
JavaScript

import React, { useContext, useState, useRef } from 'react'
import useSWR from 'swr'
import { WizardContext } from '../context/wizardStore'
import Form from 'react-bootstrap/Form'
import Button from 'react-bootstrap/Button'
import DayPicker, { 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: null, to: null })
const { data: daysBooked, error: fetchBookedOnError } = useSWR(
'/api/daysbooked',
fetcher
)
const prevBookedDay = getNextSmaller(daysBooked, dateFormat(range.from))
const nextBookedDay = getNextBigger(daysBooked, dateFormat(range.from))
console.log(range.from, range.to)
console.log(prevBookedDay, nextBookedDay)
const fromRef = useRef()
const toRef = useRef()
function dayBooked(day) {
return daysBooked && daysBooked.includes(dateFormat(day))
}
function dayDisabled(day) {
const result =
DateUtils.isPastDay(day) ||
dayBooked(day) ||
(prevBookedDay && day < new Date(prevBookedDay)) ||
(nextBookedDay && day > new Date(nextBookedDay))
console.log(day, result)
return result
}
function parseDate(value) {
return new Date(value)
}
const { multipleDays } = state.formData
const { from, to } = range
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 controlId="dateSelect">
<Form.Label>
Willst du einen odere mehrere Tage buchen? <Required />
</Form.Label>
<Form.Check
type="radio"
id={'multipleDays-single'}
label="Einen Tag"
name="multipleDays"
value="single"
checked={multipleDays === false}
onChange={() => {
//setFocusedInput(null)
onChange({
multipleDays: false,
startDate: null,
endDate: null,
})
}}
/>
<Form.Check
type="radio"
id={'multipleDays-multiple'}
label="Mehrere Tage"
name="multipleDays"
value="multiple"
checked={multipleDays === true}
onChange={() => {
//setFocusedInput(null)
onChange({
multipleDays: true,
startDate: null,
endDate: null,
})
}}
/>
</Form.Group>
{multipleDays !== null && (
<Form.Group>
<Form.Label component="legend" style={{ display: 'block' }}>
Datum <Required />
</Form.Label>
{multipleDays === false && <p>not implemented</p>}
{multipleDays === false && (
<DayPicker
className="Selectable"
numberOfMonths={2}
selectedDays={[from, { from, to }]}
disabledDays={disabledDays}
modifiers={modifiers}
onDayClick={(day, modifiers, event) => {
console.log(modifiers, event)
if (modifiers.disabled) {
return
}
const newRange = DateUtils.addDayToRange(day, range)
setRange(newRange)
}}
/>
)}
{
<>
<Form.Group>
<DayPickerInput
ref={fromRef}
// seems this makes getInput NOT work anymore :(
component={(props) => <Form.Control {...props} />}
value={from}
placeholder="Von"
formatDate={dateFormat}
parseDate={parseDate}
dayPickerProps={{
className: 'Selectable',
selectedDays: [from, { from, to }],
disabledDays,
modifiers,
numberOfMonths: 1,
onDayClick: () => toRef.current?.getInput().focus(),
}}
onDayChange={(from) => setRange({ ...range, from })}
/>
<Form.Label className="px-2">bis</Form.Label>
<DayPickerInput
ref={toRef}
component={(props) => <Form.Control {...props} />}
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>
)}
</>
)
}