add appStore and use router for booking

This commit is contained in:
Thomas Ruoff
2020-08-19 00:59:45 +02:00
parent 194ac0aca1
commit e1d1de469b
8 changed files with 80 additions and 26 deletions

View File

@@ -1,9 +1,9 @@
import React, { useContext } from 'react' import React, { useContext } from 'react'
import { WizardContext } from '../context/wizardStore' import { AppContext } from '../context/appStore'
import Required from './required' import Required from './required'
export default function Contact() { export default function Contact() {
const { state, onChangeEvent } = useContext(WizardContext) const { state, onChangeEvent } = useContext(AppContext)
const { name, email, street, zip, city } = state.formData const { name, email, street, zip, city } = state.formData

View File

@@ -1,7 +1,7 @@
import React, { useContext, useState, useRef, useEffect } from 'react' import React, { useContext, useState, useRef, useEffect } from 'react'
import useSWR from 'swr' import useSWR from 'swr'
import { WizardContext } from '../context/wizardStore' import { AppContext } from '../context/appStore'
import { DateUtils } from 'react-day-picker' import { DateUtils } from 'react-day-picker'
import DayPickerInput from 'react-day-picker/DayPickerInput' import DayPickerInput from 'react-day-picker/DayPickerInput'
@@ -19,7 +19,7 @@ import 'moment/locale/de'
const fetcher = (path) => fetch(path).then((r) => r.json()) const fetcher = (path) => fetch(path).then((r) => r.json())
export default function DateSelect() { export default function DateSelect() {
const { state, onChange } = useContext(WizardContext) const { state, onChange } = useContext(AppContext)
const [range, setRange] = useState({ const [range, setRange] = useState({
form: state.startDate && new Date(state.startDate), form: state.startDate && new Date(state.startDate),
to: state.endDate && new Date(state.endDate), to: state.endDate && new Date(state.endDate),

View File

@@ -1,9 +1,9 @@
import React, { useContext } from 'react' import React, { useContext } from 'react'
import { WizardContext } from '../context/wizardStore' import { AppContext } from '../context/appStore'
import Required from './required' import Required from './required'
export default function Contact() { export default function Contact() {
const { state, onChangeEvent } = useContext(WizardContext) const { state, onChangeEvent } = useContext(AppContext)
const { formDataChanged } = state const { formDataChanged } = state
const { purpose, destination, org } = state.formData const { purpose, destination, org } = state.formData

View File

@@ -1,14 +1,14 @@
import React, { useContext } from 'react' import React, { useContext } from 'react'
import WizardStore, { WizardContext } from '../context/wizardStore' import { AppContext } from '../context/appStore'
import DateSelect from './dateSelect' import DateSelect from './dateSelect'
import Reason from './reason' import Reason from './reason'
import Contact from './contact' import Contact from './contact'
//import Driver from './driver' //import Driver from './driver'
function WizardInternal() { export default function Wizard() {
const { onSubmit, state, storeData, forgetData } = useContext(WizardContext) const { onSubmit, state, storeData, forgetData } = useContext(AppContext)
const { const {
postData, postData,
postDataSuccess, postDataSuccess,
@@ -22,7 +22,7 @@ function WizardInternal() {
<> <>
<h3>Danke, die Buchung ist in Bearbeitung!</h3> <h3>Danke, die Buchung ist in Bearbeitung!</h3>
<p>Nach Prüfung bestätigen wir die Buchung bald per E-Mail!</p> <p>Nach Prüfung bestätigen wir die Buchung bald per E-Mail!</p>
{typeof dataStored !== 'boolean' && ( {!dataStoredLoaded && typeof dataStored !== 'boolean' && (
<> <>
<p> <p>
Sollen die eingegebenen Daten in <strong>Deinem Browser</strong>{' '} Sollen die eingegebenen Daten in <strong>Deinem Browser</strong>{' '}
@@ -55,9 +55,11 @@ function WizardInternal() {
}} }}
> >
{dataStoredLoaded && ( {dataStoredLoaded && (
<p> <p className="my-12">
Gespeicherte Daten wurden aus Deinem Browser geladen.{' '} Gespeicherte Daten wurden aus Deinem Browser geladen.{' '}
<a onClick={forgetData}>Daten vergessen</a> <a className="link" onClick={forgetData} href="">
Daten wieder vergessen
</a>
</p> </p>
)} )}
<DateSelect /> <DateSelect />
@@ -72,11 +74,3 @@ function WizardInternal() {
</form> </form>
) )
} }
export default function Wizard() {
return (
<WizardStore>
<WizardInternal />
</WizardStore>
)
}

View File

@@ -1,8 +1,10 @@
import React, { useReducer, useEffect } from 'react' import React, { useReducer, useEffect } from 'react'
import { useRouter } from 'next/router'
import { storeFormData, loadFormData, clearFormData } from '../helpers/storage' import { storeFormData, loadFormData, clearFormData } from '../helpers/storage'
export const WizardContext = React.createContext() export const AppContext = React.createContext()
export const ACTIONS = { export const ACTIONS = {
SET_FORM_DATA: 'setFormData', SET_FORM_DATA: 'setFormData',
@@ -47,8 +49,8 @@ function reducer(state, action) {
...state, ...state,
formData: { formData: {
...state.formData, ...state.formData,
...action.payload,
}, },
booking: { ...action.payload },
postData: false, postData: false,
postDataError: null, postDataError: null,
postDataSuccess: true, postDataSuccess: true,
@@ -120,9 +122,11 @@ async function createBooking(formData) {
return response.json() return response.json()
} }
export default function WizardStore({ children }) { export default function AppStore({ children }) {
const [state, dispatch] = useReducer(debugReducer, initialState) const [state, dispatch] = useReducer(debugReducer, initialState)
const router = useRouter()
useEffect(() => { useEffect(() => {
const data = loadFormData() const data = loadFormData()
if (data !== null) { if (data !== null) {
@@ -152,6 +156,8 @@ export default function WizardStore({ children }) {
try { try {
const bookingData = await createBooking(state.formData) const bookingData = await createBooking(state.formData)
dispatch({ type: ACTIONS.POST_DATA_SUCCESS, payload: bookingData }) dispatch({ type: ACTIONS.POST_DATA_SUCCESS, payload: bookingData })
router.push('/booking/[id]', `/booking/${bookingData._id}`)
} catch (error) { } catch (error) {
console.error(error) console.error(error)
dispatch({ type: ACTIONS.POST_DATA_ERROR, payload: error.message }) dispatch({ type: ACTIONS.POST_DATA_ERROR, payload: error.message })
@@ -172,7 +178,7 @@ export default function WizardStore({ children }) {
} }
return ( return (
<WizardContext.Provider <AppContext.Provider
value={{ value={{
state, state,
dispatch, dispatch,
@@ -184,6 +190,6 @@ export default function WizardStore({ children }) {
}} }}
> >
{children} {children}
</WizardContext.Provider> </AppContext.Provider>
) )
} }

View File

@@ -4,6 +4,12 @@ import '../styles/index.css'
import 'react-day-picker/lib/style.css' import 'react-day-picker/lib/style.css'
import AppStore from '../context/appStore'
export default function MyApp({ Component, pageProps }) { export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} /> return (
<AppStore>
<Component {...pageProps} />
</AppStore>
)
} }

40
pages/booking/[id].js Normal file
View File

@@ -0,0 +1,40 @@
import React, { useContext } from 'react'
import { AppContext } from '../../context/appStore'
import Footer from '../../components/footer'
export default function Booking() {
const { dataStored, dataStoredLoaded } = state
return (
<div className="mx-3 flex flex-col min-h-screen">
<main className="flex-grow">
<h1 className="text-3xl">Pfadi Bussle Buchung</h1>
<h3>Danke, die Buchung ist in Bearbeitung!</h3>
<p>Nach Prüfung bestätigen wir die Buchung bald per E-Mail!</p>
{!dataStoredLoaded && typeof dataStored !== 'boolean' && (
<>
<p>
Sollen die eingegebenen Daten in <strong>Deinem Browser</strong>{' '}
für die nächste Buchung gespeichert werden?
</p>
<button onClick={() => storeData(true)} className="btn btn-blue">
Ja, bitte speichern
</button>
<button
onClick={() => storeData(false)}
className="btn btn-grey ml-2"
>
Nein danke
</button>
</>
)}
{dataStored === true && (
<p>Ok, die Daten wurden für die nächste Buchung gespeichert.</p>
)}
</main>
<Footer />
</div>
)
}

View File

@@ -76,6 +76,14 @@
@apply bg-gray-700; @apply bg-gray-700;
} }
.link {
@apply font-medium text-blue-500 underline;
}
.link:hover {
@apply text-blue-700;
}
@screen sm { @screen sm {
.fs { .fs {
@apply w-1/2 mb-0; @apply w-1/2 mb-0;