mirror of
https://github.com/tomru/pfadi-bussle.git
synced 2026-03-03 14:37:13 +01:00
It also brings the problem of consolidating bookers over multiple bookings. The amount of data is not justifying having it in an own entity
187 lines
4.1 KiB
TypeScript
187 lines
4.1 KiB
TypeScript
import React, { useEffect, useReducer } from 'react'
|
|
import { useRouter } from 'next/router'
|
|
import { clearBookingData, loadBookingData } from '../helpers/storage'
|
|
|
|
import { createBooking } from '../helpers/booking'
|
|
import { Booking } from '../db/booking'
|
|
|
|
export type BookFormData = Omit<Booking, 'uuid'> & {
|
|
storeData?: boolean
|
|
}
|
|
|
|
type BookingProviderState = {
|
|
postData?: boolean
|
|
postDataError?: string
|
|
postDataSuccess?: boolean
|
|
formData: BookFormData
|
|
formDataChanged: string[]
|
|
booking?: Booking
|
|
dataStored: boolean
|
|
dataStoredLoaded: boolean
|
|
}
|
|
|
|
type BookProvider = {
|
|
state: BookingProviderState
|
|
dispatch: React.Dispatch<BookAction>
|
|
onChange: (data: object) => void
|
|
onChangeEvent: (event: React.ChangeEvent<React.ElementRef<'input'>>) => void
|
|
onSubmit: () => void
|
|
forgetData: () => void
|
|
}
|
|
|
|
type BookAction = {
|
|
type: string
|
|
payload?: any
|
|
}
|
|
|
|
export const BookContext: React.Context<BookProvider> = React.createContext<
|
|
BookProvider
|
|
>(null)
|
|
|
|
export const ACTIONS = {
|
|
SET_FORM_DATA: 'setFormData',
|
|
POST_DATA: 'postData',
|
|
POST_DATA_ERROR: 'postDataError',
|
|
DATA_STORED: 'dataStored',
|
|
DATA_STORED_LOADED: 'dataStoredLoaded',
|
|
DATA_STORED_FORGOTTEN: 'dataStoredForgotten',
|
|
}
|
|
|
|
function reducer(state: BookingProviderState, action: BookAction) {
|
|
switch (action.type) {
|
|
case ACTIONS.SET_FORM_DATA:
|
|
return {
|
|
...state,
|
|
formData: {
|
|
...state.formData,
|
|
...action.payload,
|
|
},
|
|
formDataChanged: [
|
|
...state.formDataChanged,
|
|
...Object.keys(action.payload),
|
|
],
|
|
}
|
|
case ACTIONS.POST_DATA:
|
|
return {
|
|
...state,
|
|
postData: true,
|
|
postDataError: null,
|
|
postDataSuccess: null,
|
|
}
|
|
case ACTIONS.POST_DATA_ERROR:
|
|
return {
|
|
...state,
|
|
postData: false,
|
|
postDataError: action.payload,
|
|
postDataSuccess: null,
|
|
}
|
|
case ACTIONS.DATA_STORED_LOADED:
|
|
return {
|
|
...state,
|
|
dataStoredLoaded: true,
|
|
formData: {
|
|
...state.formData,
|
|
...action.payload,
|
|
},
|
|
}
|
|
case ACTIONS.DATA_STORED_FORGOTTEN:
|
|
return {
|
|
...state,
|
|
dataStored: undefined,
|
|
dataStoredLoaded: undefined,
|
|
formData: { ...initialState.formData },
|
|
}
|
|
case ACTIONS.DATA_STORED:
|
|
return {
|
|
...state,
|
|
dataStored: action.payload,
|
|
}
|
|
default:
|
|
throw new Error(`Unkown Action type ${action.type}`)
|
|
}
|
|
}
|
|
|
|
const initialState: BookingProviderState = {
|
|
postData: false,
|
|
postDataError: null,
|
|
postDataSuccess: null,
|
|
formData: {
|
|
startDate: '',
|
|
endDate: '',
|
|
purpose: '',
|
|
org: '',
|
|
destination: '',
|
|
name: '',
|
|
email: '',
|
|
phone: '',
|
|
street: '',
|
|
zip: '',
|
|
city: '',
|
|
},
|
|
formDataChanged: [],
|
|
dataStored: undefined,
|
|
dataStoredLoaded: undefined,
|
|
}
|
|
|
|
export default function BookProvider({ children }) {
|
|
const router = useRouter()
|
|
const [state, dispatch] = useReducer(reducer, initialState)
|
|
|
|
useEffect(() => {
|
|
const data = loadBookingData()
|
|
if (data !== null) {
|
|
dispatch({ type: ACTIONS.DATA_STORED_LOADED, payload: data })
|
|
}
|
|
}, [])
|
|
|
|
const onChangeEvent = (
|
|
event: React.ChangeEvent<React.ElementRef<'input'>>
|
|
) => {
|
|
const { name, value } = event.target
|
|
|
|
dispatch({
|
|
type: ACTIONS.SET_FORM_DATA,
|
|
payload: { [name]: value },
|
|
})
|
|
}
|
|
|
|
const onChange = (data: object) => {
|
|
dispatch({
|
|
type: ACTIONS.SET_FORM_DATA,
|
|
payload: data,
|
|
})
|
|
}
|
|
|
|
const onSubmit = async () => {
|
|
dispatch({ type: ACTIONS.POST_DATA })
|
|
|
|
try {
|
|
const booking = await createBooking(state.formData)
|
|
router.push(`/booking/${booking.uuid}/stored`)
|
|
} catch (error) {
|
|
console.error(error)
|
|
dispatch({ type: ACTIONS.POST_DATA_ERROR, payload: error.message })
|
|
}
|
|
}
|
|
|
|
const forgetData = () => {
|
|
clearBookingData()
|
|
dispatch({ type: ACTIONS.DATA_STORED_FORGOTTEN })
|
|
}
|
|
|
|
return (
|
|
<BookContext.Provider
|
|
value={{
|
|
state,
|
|
dispatch,
|
|
onChangeEvent,
|
|
onChange,
|
|
onSubmit,
|
|
forgetData,
|
|
}}
|
|
>
|
|
{children}
|
|
</BookContext.Provider>
|
|
)
|
|
}
|