added app context with reducer

This commit is contained in:
Thomas Ruoff
2020-07-01 00:25:36 +02:00
parent 96c62e3e9f
commit 563d57a8ba
6 changed files with 207 additions and 124 deletions

View File

@@ -17,18 +17,6 @@ export default function Contact({}) {
<label htmlFor="destination">Fahrtziel</label> <label htmlFor="destination">Fahrtziel</label>
<input id="destination" name="destination" type="text" /> <input id="destination" name="destination" type="text" />
</div> </div>
<div>
<label htmlFor="driver1">Fahrer 1</label>
<input id="driver1" name="driver1" type="text" />
<label htmlFor="driver">Alter</label>
<input id="ageDriver1" name="ageDriver1" type="number" min="20" />
</div>
<div>
<label htmlFor="driver">Fahrer 2</label>
<input id="driver2" name="driver2" type="text" />
<label htmlFor="driver">Alter</label>
<input id="ageDriver2" name="ageDriver2" type="number" min="20" />
</div>
</> </>
) )
} }

View File

@@ -1,80 +1,102 @@
import { useContext } from 'react'
import { AppContext, ACTIONS } from '../context/appStore'
import TimeSelect from './timeSelect'
import moment from 'moment' import moment from 'moment'
import 'react-dates/initialize' import 'react-dates/initialize'
import { DateRangePicker, SingleDatePicker } from 'react-dates' import { DateRangePicker, SingleDatePicker } from 'react-dates'
import TimeSelect from './timeSelect' export default function DateSelect() {
const { state, dispatch } = useContext(AppContext)
export default function DateSelect({ const {
multipleDays, multipleDays,
startDate, startDate,
setStartDate, endDate,
endDate, focusedInput,
setEndDate, pickupTime,
focusedInput, dropoffTime,
setFocusedInput, bookedOn,
pickupTime, } = state
setPickupTime,
dropoffTime, function isDayBlocked(momentDay) {
setDropoffTime, return bookedOn.some((rawDay) => momentDay.isSame(rawDay))
}) { }
const timeSelect = (
if (multipleDays === null || multipleDays === undefined) {
return null
}
return (
<> <>
<div>
{state.multipleDays === false && (
<SingleDatePicker
date={startDate && moment(startDate)}
onDateChange={(date) =>
dispatch({
type: ACTIONS.SET_DATE,
payload: { startDate: date.toISOString() },
})
}
focused={typeof focusedInput === 'boolean' && focusedInput}
onFocusChange={({ focused }) =>
dispatch({
type: ACTIONS.SET_FOCUSED_INPUT,
payload: focused,
})
}
isDayBlocked={isDayBlocked}
id="your_unique_id"
/>
)}
{state.multipleDays === true && (
<DateRangePicker
startDate={startDate && moment(startDate)}
startDateId="bussle_start_date_id"
endDate={endDate && moment(endDate)}
endDateId="bussle_end_date_id"
onDatesChange={({ startDate, endDate }) => {
dispatch({
type: ACTIONS.SET_DATE,
payload: {
startDate: startDate && startDate.toISOString(),
endDate: endDate && endDate.toISOString(),
},
})
}}
focusedInput={focusedInput}
onFocusChange={(focusedInput) =>
dispatch({
type: ACTIONS.SET_FOCUSED_INPUT,
payload: focusedInput,
})
}
isDayBlocked={isDayBlocked}
minDate={moment()}
/>
)}
</div>
<TimeSelect <TimeSelect
id="pickup" id="pickup"
name="pickupTime" name="pickupTime"
label="Abholung Uhrzeit" label="Abholung Uhrzeit"
value={pickupTime} value={pickupTime}
setValue={setPickupTime} setValue={(payload) =>
dispatch({ type: ACTIONS.SET_PICKUP_TIME, payload })
}
/> />
<TimeSelect <TimeSelect
id="dropoff" id="dropoff"
name="dropoffTime" name="dropoffTime"
label="Rückgabe Uhrzeit" label="Rückgabe Uhrzeit"
value={dropoffTime} value={dropoffTime}
setValue={setDropoffTime} setValue={(payload) =>
dispatch({ type: ACTIONS.SET_DROPOFF_TIME, payload })
}
/> />
</> </>
) )
if (multipleDays === false) {
return (
<>
<div>
<SingleDatePicker
date={startDate}
onDateChange={(date) => setStartDate(date)}
focused={typeof focusedInput === 'boolean' && focusedInput}
onFocusChange={({ focused }) => setFocusedInput(focused)}
id="your_unique_id"
/>
</div>
{timeSelect}
</>
)
}
if (multipleDays === true) {
return (
<>
<div>
<DateRangePicker
startDate={startDate}
startDateId="bussle_start_date_id"
endDate={endDate}
endDateId="bussle_end_date_id"
onDatesChange={({ startDate, endDate }) => {
setStartDate(startDate)
setEndDate(endDate)
}}
focusedInput={focusedInput}
onFocusChange={(focusedInput) => setFocusedInput(focusedInput)}
minDate={moment()}
/>
</div>
{timeSelect}
</>
)
}
return null
} }

18
components/driver.js Normal file
View File

@@ -0,0 +1,18 @@
export default function Driver({}) {
return (
<>
<div>
<label htmlFor="driver1">Fahrer 1</label>
<input id="driver1" name="driver1" type="text" />
<label htmlFor="driver">Alter</label>
<input id="ageDriver1" name="ageDriver1" type="number" min="20" />
</div>
<div>
<label htmlFor="driver">Fahrer 2</label>
<input id="driver2" name="driver2" type="text" />
<label htmlFor="driver">Alter</label>
<input id="ageDriver2" name="ageDriver2" type="number" min="20" />
</div>
</>
)
}

View File

@@ -1,23 +1,31 @@
export default function RangeSelect({ multipleDays, setMultipleDays }) { import { useContext } from 'react'
return ( import { AppContext, ACTIONS } from '../context/appStore'
<div> export default function RangeSelect() {
Ich will das Bussle für const { state, dispatch } = useContext(AppContext)
<input
type="radio" return (
id="single" <div>
name="days" Ich will das Bussle für
value="singleDay" <input
onChange={() => setMultipleDays(false)} type="radio"
/> id="single"
<label htmlFor="single">einen Tag</label> name="days"
<input checked={state.multipleDays === false}
type="radio" onChange={() =>
id="multiple" dispatch({ type: ACTIONS.SET_MULTIPLE_DAYS, payload: false })
name="days" }
value="multipleDays" />
onChange={() => setMultipleDays(true)} <label htmlFor="single">einen Tag</label>
/> <input
<label htmlFor="multiple">mehrere Tage</label> mieten type="radio"
</div> id="multiple"
) name="days"
checked={state.multipleDays === true}
onChange={() =>
dispatch({ type: ACTIONS.SET_MULTIPLE_DAYS, payload: true })
}
/>
<label htmlFor="multiple">mehrere Tage</label> mieten
</div>
)
} }

66
context/appStore.js Normal file
View File

@@ -0,0 +1,66 @@
import React, { useReducer } from 'react'
export const AppContext = React.createContext()
export const ACTIONS = {
SET_MULTIPLE_DAYS: 'setMultipleDays',
SET_DATE: 'setDate',
SET_FOCUSED_INPUT: 'setFocusedInput',
SET_PICKUP_TIME: 'setPickupTime',
SET_DROPOFF_TIME: 'setDropoffTime',
}
function reducer(state, action) {
switch (action.type) {
case ACTIONS.SET_MULTIPLE_DAYS:
return {
...state,
multipleDays: action.payload,
focusedInput: undefined,
startDate: undefined,
endDate: undefined,
}
case ACTIONS.SET_DATE:
return {
...state,
startDate: action.payload.startDate,
endDate: action.payload.endDate,
}
case ACTIONS.SET_FOCUSED_INPUT:
return { ...state, focusedInput: action.payload }
case ACTIONS.SET_PICKUP_TIME:
return { ...state, pickupTime: action.payload }
case ACTIONS.SET_DROPOFF_TIME:
return { ...state, dropoffTime: action.payload }
default:
throw new Error(`Unkown Action type ${action.type}`)
}
}
function debugReducer(state, action) {
console.debug('applying action', action)
const newState = reducer(state, action)
console.debug(newState)
return newState
}
const initialState = {
multipleDays: null,
bookedOn: [
'2020-07-10',
'2020-07-11',
'2020-07-12',
'2020-07-23',
'2020-08-01',
],
}
export default function AppStore({ children }) {
const [state, dispatch] = useReducer(debugReducer, initialState)
return (
<AppContext.Provider value={{ state, dispatch }}>
{children}
</AppContext.Provider>
)
}

View File

@@ -1,20 +1,15 @@
import { useState } from 'react' import { useContext } from 'react'
import Head from 'next/head' import Head from 'next/head'
import AppStore from '../context/appStore'
import RangeSelect from '../components/rangeSelect' import RangeSelect from '../components/rangeSelect'
import DateSelect from '../components/dateSelect' import DateSelect from '../components/dateSelect'
import Contact from '../components/contact' import Contact from '../components/contact'
import Driver from '../components/driver'
export default function Home() { export default function Home() {
const [multipleDays, setMultipleDays] = useState(null)
const [startDate, setStartDate] = useState(null)
const [endDate, setEndDate] = useState(null)
const [focusedInput, setFocusedInput] = useState(null)
const [pickupTime, setPickupTime] = useState('')
const [dropoffTime, setDropoffTime] = useState('')
return ( return (
<div className="container"> <div className="container">
<Head> <Head>
@@ -29,29 +24,15 @@ export default function Home() {
Du willst das Pfadi Bussle buchen? Hier bist du richtig! Du willst das Pfadi Bussle buchen? Hier bist du richtig!
</p> </p>
<form className="bookingForm"> <AppStore>
<RangeSelect <form className="bookingForm">
multipleDay={multipleDays} <RangeSelect />
setMultipleDays={setMultipleDays} <DateSelect />
/> <Contact />
<DateSelect
multipleDays={multipleDays}
startDate={startDate}
setStartDate={setStartDate}
endDate={endDate}
setEndDate={setEndDate}
focusedInput={focusedInput}
setFocusedInput={setFocusedInput}
pickupTime={pickupTime}
setPickupTime={setPickupTime}
dropoffTime={dropoffTime}
setDropoffTime={setDropoffTime}
/>
<Contact /> <input type="submit" />
</form>
<input type="submit" /> </AppStore>
</form>
</main> </main>
<footer> <footer>