From 563d57a8badb5dc894862e633783b1f2e2a3528f Mon Sep 17 00:00:00 2001 From: Thomas Ruoff Date: Wed, 1 Jul 2020 00:25:36 +0200 Subject: [PATCH] added app context with reducer --- components/contact.js | 12 ---- components/dateSelect.js | 138 ++++++++++++++++++++++---------------- components/driver.js | 18 +++++ components/rangeSelect.js | 52 ++++++++------ context/appStore.js | 66 ++++++++++++++++++ pages/index.js | 45 ++++--------- 6 files changed, 207 insertions(+), 124 deletions(-) create mode 100644 components/driver.js create mode 100644 context/appStore.js diff --git a/components/contact.js b/components/contact.js index 823d8e6..2619a4d 100644 --- a/components/contact.js +++ b/components/contact.js @@ -17,18 +17,6 @@ export default function Contact({}) { -
- - - - -
-
- - - - -
) } diff --git a/components/dateSelect.js b/components/dateSelect.js index 1aa6caf..94229f8 100644 --- a/components/dateSelect.js +++ b/components/dateSelect.js @@ -1,80 +1,102 @@ +import { useContext } from 'react' +import { AppContext, ACTIONS } from '../context/appStore' + +import TimeSelect from './timeSelect' + import moment from 'moment' import 'react-dates/initialize' import { DateRangePicker, SingleDatePicker } from 'react-dates' -import TimeSelect from './timeSelect' +export default function DateSelect() { + const { state, dispatch } = useContext(AppContext) -export default function DateSelect({ - multipleDays, - startDate, - setStartDate, - endDate, - setEndDate, - focusedInput, - setFocusedInput, - pickupTime, - setPickupTime, - dropoffTime, - setDropoffTime, -}) { - const timeSelect = ( + const { + multipleDays, + startDate, + endDate, + focusedInput, + pickupTime, + dropoffTime, + bookedOn, + } = state + + function isDayBlocked(momentDay) { + return bookedOn.some((rawDay) => momentDay.isSame(rawDay)) + } + + if (multipleDays === null || multipleDays === undefined) { + return null + } + + return ( <> +
+ {state.multipleDays === false && ( + + 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 && ( + { + 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()} + /> + )} +
+ dispatch({ type: ACTIONS.SET_PICKUP_TIME, payload }) + } /> + dispatch({ type: ACTIONS.SET_DROPOFF_TIME, payload }) + } /> ) - if (multipleDays === false) { - return ( - <> -
- setStartDate(date)} - focused={typeof focusedInput === 'boolean' && focusedInput} - onFocusChange={({ focused }) => setFocusedInput(focused)} - id="your_unique_id" - /> -
- {timeSelect} - - ) - } - - if (multipleDays === true) { - return ( - <> -
- { - setStartDate(startDate) - setEndDate(endDate) - }} - focusedInput={focusedInput} - onFocusChange={(focusedInput) => setFocusedInput(focusedInput)} - minDate={moment()} - /> -
- {timeSelect} - - ) - } - - return null } diff --git a/components/driver.js b/components/driver.js new file mode 100644 index 0000000..ddb9069 --- /dev/null +++ b/components/driver.js @@ -0,0 +1,18 @@ +export default function Driver({}) { + return ( + <> +
+ + + + +
+
+ + + + +
+ + ) +} diff --git a/components/rangeSelect.js b/components/rangeSelect.js index 83af2cc..8ece828 100644 --- a/components/rangeSelect.js +++ b/components/rangeSelect.js @@ -1,23 +1,31 @@ -export default function RangeSelect({ multipleDays, setMultipleDays }) { - return ( -
- Ich will das Bussle für - setMultipleDays(false)} - /> - - setMultipleDays(true)} - /> - mieten -
- ) +import { useContext } from 'react' +import { AppContext, ACTIONS } from '../context/appStore' +export default function RangeSelect() { + const { state, dispatch } = useContext(AppContext) + + return ( +
+ Ich will das Bussle für + + dispatch({ type: ACTIONS.SET_MULTIPLE_DAYS, payload: false }) + } + /> + + + dispatch({ type: ACTIONS.SET_MULTIPLE_DAYS, payload: true }) + } + /> + mieten +
+ ) } diff --git a/context/appStore.js b/context/appStore.js new file mode 100644 index 0000000..357548a --- /dev/null +++ b/context/appStore.js @@ -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 ( + + {children} + + ) +} diff --git a/pages/index.js b/pages/index.js index 59017fc..0cb7cb3 100644 --- a/pages/index.js +++ b/pages/index.js @@ -1,20 +1,15 @@ -import { useState } from 'react' +import { useContext } from 'react' + import Head from 'next/head' +import AppStore from '../context/appStore' + import RangeSelect from '../components/rangeSelect' import DateSelect from '../components/dateSelect' import Contact from '../components/contact' +import Driver from '../components/driver' 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 (
@@ -29,29 +24,15 @@ export default function Home() { Du willst das Pfadi Bussle buchen? Hier bist du richtig!

-
- - + + + + + - - - - + + +