mirror of
https://github.com/tomru/pfadi-bussle.git
synced 2026-03-04 15:07:13 +01:00
enable to select dates in calendar
This commit is contained in:
committed by
Thomas Ruoff
parent
928d6b3d4e
commit
898e6b8295
@@ -1,13 +1,18 @@
|
|||||||
import React from 'react'
|
import React, { useContext } from 'react'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import { isPast } from 'date-fns'
|
import { isPast, isSameDay, isAfter, isWithinInterval } from 'date-fns'
|
||||||
import useSWR from 'swr'
|
import useSWR from 'swr'
|
||||||
import Calendar from 'react-calendar'
|
import Calendar, { DateCallback } from 'react-calendar'
|
||||||
import { dateFormatBackend } from '../../helpers/date'
|
import { dateFormatBackend } from '../../helpers/date'
|
||||||
|
import { WizardContext } from './context/wizardStore'
|
||||||
|
|
||||||
const fetcher = (path: string) => fetch(path).then((r) => r.json())
|
const fetcher = (path: string) => fetch(path).then((r) => r.json())
|
||||||
|
|
||||||
export default function MyCalendar() {
|
export default function MyCalendar() {
|
||||||
|
const { onChange, state } = useContext(WizardContext)
|
||||||
|
const { startDate: start, endDate: end } = state.formData
|
||||||
|
const startDate = (start && new Date(start)) || null
|
||||||
|
const endDate = (end && new Date(end)) || null
|
||||||
const { data: daysBooked, error: fetchBookedOnError } = useSWR(
|
const { data: daysBooked, error: fetchBookedOnError } = useSWR(
|
||||||
'/api/daysbooked',
|
'/api/daysbooked',
|
||||||
fetcher
|
fetcher
|
||||||
@@ -16,13 +21,21 @@ export default function MyCalendar() {
|
|||||||
function tileClassName({ date, view }) {
|
function tileClassName({ date, view }) {
|
||||||
const isMonthView = view === 'month'
|
const isMonthView = view === 'month'
|
||||||
const isDaysBookedLoaded = !!daysBooked
|
const isDaysBookedLoaded = !!daysBooked
|
||||||
|
const isInPast = isPast(date)
|
||||||
const isBooked = daysBooked?.includes(dateFormatBackend(date))
|
const isBooked = daysBooked?.includes(dateFormatBackend(date))
|
||||||
return classnames({
|
return classnames({
|
||||||
'react-calendar__tile--past': isPast(date),
|
'react-calendar__tile--past': isInPast,
|
||||||
'react-calendar__tile--booked':
|
'react-calendar__tile--booked':
|
||||||
isMonthView && isDaysBookedLoaded && isBooked,
|
isMonthView && isDaysBookedLoaded && isBooked && !isInPast,
|
||||||
'react-calendar__tile--free':
|
'react-calendar__tile--free':
|
||||||
isMonthView && isDaysBookedLoaded && !isBooked,
|
isMonthView && isDaysBookedLoaded && !isBooked && !isInPast,
|
||||||
|
'react-calendar__tile--selected':
|
||||||
|
(startDate &&
|
||||||
|
isWithinInterval(date, {
|
||||||
|
start: startDate,
|
||||||
|
end: endDate || startDate,
|
||||||
|
})) ||
|
||||||
|
isSameDay(date, startDate),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +51,37 @@ export default function MyCalendar() {
|
|||||||
return (
|
return (
|
||||||
<div className="mb-12 p-6 bg-blue-100 rounded">
|
<div className="mb-12 p-6 bg-blue-100 rounded">
|
||||||
<h2 className="text-xl">Buchungsübersicht</h2>
|
<h2 className="text-xl">Buchungsübersicht</h2>
|
||||||
<Calendar minDate={new Date()} tileClassName={tileClassName} />
|
<Calendar
|
||||||
|
minDate={new Date()}
|
||||||
|
// @ts-ignore
|
||||||
|
onClickDay={(date, event: React.MouseEvent<HTMLInputElement>) => {
|
||||||
|
event.preventDefault()
|
||||||
|
event.stopPropagation()
|
||||||
|
|
||||||
|
const targetClassList = event.currentTarget.classList
|
||||||
|
|
||||||
|
if (
|
||||||
|
targetClassList.contains('react-calendar__tile--past') ||
|
||||||
|
targetClassList.contains('react-calendar__tile--booked')
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!startDate || !!endDate) {
|
||||||
|
onChange({ startDate: dateFormatBackend(date), endDate: null })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// when startDate set, but end missing
|
||||||
|
if (isAfter(date, startDate)) {
|
||||||
|
onChange({ endDate: dateFormatBackend(date) })
|
||||||
|
} else {
|
||||||
|
onChange({ startDate: dateFormatBackend(date), endDate: start })
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
tileClassName={tileClassName}
|
||||||
|
value={null}
|
||||||
|
/>
|
||||||
<div className="mt-6 flex justify-center">
|
<div className="mt-6 flex justify-center">
|
||||||
<div>
|
<div>
|
||||||
<div className="inline-block w-5 h-5 bg-green-200 rounded align-text-bottom"></div>
|
<div className="inline-block w-5 h-5 bg-green-200 rounded align-text-bottom"></div>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export default function DateSelect() {
|
|||||||
required
|
required
|
||||||
type="date"
|
type="date"
|
||||||
name="startDate"
|
name="startDate"
|
||||||
value={startDate}
|
value={startDate || ''}
|
||||||
onChange={onChangeEvent}
|
onChange={onChangeEvent}
|
||||||
min={today}
|
min={today}
|
||||||
/>
|
/>
|
||||||
@@ -32,7 +32,7 @@ export default function DateSelect() {
|
|||||||
required
|
required
|
||||||
type="date"
|
type="date"
|
||||||
name="endDate"
|
name="endDate"
|
||||||
value={endDate}
|
value={endDate || ''}
|
||||||
placeholder="Von"
|
placeholder="Von"
|
||||||
onChange={onChangeEvent}
|
onChange={onChangeEvent}
|
||||||
min={startDate || today}
|
min={startDate || today}
|
||||||
|
|||||||
@@ -128,10 +128,6 @@
|
|||||||
@apply outline-none;
|
@apply outline-none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.react-calendar button:enabled:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.react-calendar__navigation {
|
.react-calendar__navigation {
|
||||||
@apply text-gray-100 bg-gray-900;
|
@apply text-gray-100 bg-gray-900;
|
||||||
}
|
}
|
||||||
@@ -141,9 +137,6 @@
|
|||||||
min-width: 2rem;
|
min-width: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.react-calendar__navigation button:enabled:hover,
|
|
||||||
.react-calendar__navigation button:enabled:focus {
|
|
||||||
}
|
|
||||||
.react-calendar__navigation button[disabled] {
|
.react-calendar__navigation button[disabled] {
|
||||||
@apply text-gray-700 cursor-not-allowed;
|
@apply text-gray-700 cursor-not-allowed;
|
||||||
}
|
}
|
||||||
@@ -181,7 +174,9 @@
|
|||||||
|
|
||||||
.react-calendar__tile--free {
|
.react-calendar__tile--free {
|
||||||
@apply bg-green-200;
|
@apply bg-green-200;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.react-calendar__tile--booked {
|
.react-calendar__tile--booked {
|
||||||
@apply bg-red-200 cursor-not-allowed;
|
@apply bg-red-200 cursor-not-allowed;
|
||||||
}
|
}
|
||||||
@@ -194,37 +189,17 @@
|
|||||||
@apply bg-gray-300;
|
@apply bg-gray-300;
|
||||||
}
|
}
|
||||||
|
|
||||||
.react-calendar__tile:enabled:hover,
|
.react-calendar__tile--selected {
|
||||||
.react-calendar__tile:enabled:focus {
|
@apply bg-blue-200;
|
||||||
|
}
|
||||||
|
|
||||||
|
.react-calendar__tile--free:hover {
|
||||||
@apply bg-gray-500;
|
@apply bg-gray-500;
|
||||||
}
|
}
|
||||||
.react-calendar__tile--now {
|
.react-calendar__tile--now {
|
||||||
@apply text-green-400;
|
@apply text-green-400;
|
||||||
}
|
}
|
||||||
|
|
||||||
.react-calendar__tile--now:enabled:hover,
|
|
||||||
.react-calendar__tile--now:enabled:focus {
|
|
||||||
background: #ffffa9;
|
|
||||||
}
|
|
||||||
.react-calendar__tile--hasActive {
|
|
||||||
background: #76baff;
|
|
||||||
}
|
|
||||||
.react-calendar__tile--hasActive:enabled:hover,
|
|
||||||
.react-calendar__tile--hasActive:enabled:focus {
|
|
||||||
background: #a9d4ff;
|
|
||||||
}
|
|
||||||
.react-calendar__tile--active {
|
|
||||||
background: #006edc;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.react-calendar__tile--active:enabled:hover,
|
|
||||||
.react-calendar__tile--active:enabled:focus {
|
|
||||||
background: #1087ff;
|
|
||||||
}
|
|
||||||
.react-calendar--selectRange .react-calendar__tile--hover {
|
|
||||||
background-color: #e6e6e6;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Start purging... */
|
/* Start purging... */
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
/* Stop purging. */
|
/* Stop purging. */
|
||||||
|
|||||||
Reference in New Issue
Block a user