diff --git a/components/contact.js b/components/contact.js index 22b78f4..3784b39 100644 --- a/components/contact.js +++ b/components/contact.js @@ -1,5 +1,6 @@ import { useContext } from 'react' import { WizardContext, ACTIONS } from '../context/wizardStore' +import Required from './required' import Form from 'react-bootstrap/Form' import Col from 'react-bootstrap/Col' @@ -12,54 +13,69 @@ export default function Contact() { return ( <> - Name + + Name + - E-Mail + + E-Mail + - Straße + + Straße + - PLZ + + PLZ + - Stadt + + Stadt + diff --git a/components/dateSelect.js b/components/dateSelect.js index 19678cd..84d4c99 100644 --- a/components/dateSelect.js +++ b/components/dateSelect.js @@ -9,13 +9,14 @@ import moment from 'moment' import 'react-dates/initialize' import { DateRangePicker, SingleDatePicker } from 'react-dates' +import Required from './required' import { dateFormat } from '../lib/dateHelper' const fetcher = (path) => fetch(path).then((r) => r.json()) export default function DateSelect() { const [focusedInput, setFocusedInput] = useState(null) - const { state, onChange, onChangeEvent } = useContext(WizardContext) + const { state, onChange } = useContext(WizardContext) const { data: daysBooked, error: fetchBookedOnError } = useSWR( '/api/daysbooked', fetcher @@ -41,7 +42,9 @@ export default function DateSelect() { return ( <> - Willst du einen odere mehrere Tage buchen? + + Willst du einen odere mehrere Tage buchen? + - Datum + Datum {multipleDays === false && ( onChange({ startDate: date && dateFormat(date), @@ -104,6 +108,7 @@ export default function DateSelect() { startDateId="startDate" startDatePlaceholderText="Start" endDatePlaceholderText="Ende" + required numberOfMonths={1} endDate={endDate && moment(endDate)} endDateId="endDate" diff --git a/components/reason.js b/components/reason.js index e8c82b7..1308bed 100644 --- a/components/reason.js +++ b/components/reason.js @@ -1,5 +1,6 @@ import { useContext } from 'react' import { WizardContext, ACTIONS } from '../context/wizardStore' +import Required from './required' import Form from 'react-bootstrap/Form' @@ -11,13 +12,16 @@ export default function Contact() { return ( <> - Zweck der Fahrt + + Zweck der Fahrt + @@ -31,13 +35,16 @@ export default function Contact() { /> - Ziel der Fahrt + + Ziel der Fahrt + diff --git a/components/required.js b/components/required.js new file mode 100644 index 0000000..c375ea8 --- /dev/null +++ b/components/required.js @@ -0,0 +1,3 @@ +import react from 'react' + +export default () => * diff --git a/components/wizard.js b/components/wizard.js index 1f3ed94..a4d9e7b 100644 --- a/components/wizard.js +++ b/components/wizard.js @@ -1,4 +1,4 @@ -import { useContext, useRef } from 'react' +import { useContext } from 'react' import Button from 'react-bootstrap/Button' import Form from 'react-bootstrap/Form' @@ -11,7 +11,23 @@ import Contact from './contact' //import Driver from './driver' function WizardInternal() { - const { state, storeBooking } = useContext(WizardContext) + const { onSubmit, state } = useContext(WizardContext) + const { postData, postDataSuccess, postDataError } = state + + if (postDataSuccess) { + return ( + <> +

Danke, die Buchung ist in Bearbeitung!

+

Wir melden uns per E-Mail sobald die Buchung bestätigt ist.

+

+ Sollen die eingegebenen Daten in Deinem Browser für die nächste + Buchung gespeichert werden? +

+ + + ) + } + const onChange = (payload) => dispatch({ action: ACTIONS.SET_FORM_DATA, payload }) @@ -19,14 +35,16 @@ function WizardInternal() {
{ event.preventDefault() - - storeBooking() + onSubmit() }} > - +
{postDataError}
+ ) } diff --git a/context/wizardStore.js b/context/wizardStore.js index 5fb7297..3266e7b 100644 --- a/context/wizardStore.js +++ b/context/wizardStore.js @@ -4,6 +4,9 @@ export const WizardContext = React.createContext() export const ACTIONS = { SET_FORM_DATA: 'setFormData', + POST_DATA: 'postData', + POST_DATA_ERROR: 'postDataError', + POST_DATA_SUCCESS: 'postDataSuccess', } function reducer(state, action) { @@ -16,6 +19,31 @@ function reducer(state, action) { ...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.POST_DATA_SUCCESS: + return { + ...state, + formData: { + ...state.formData, + ...action.payload, + }, + postData: false, + postDataError: null, + postDataSuccess: true, + } default: throw new Error(`Unkown Action type ${action.type}`) } @@ -28,8 +56,26 @@ function debugReducer(state, action) { return newState } -async function createBooking(state) { - const { name, email, startDate, endDate } = state.formData +const initialState = { + postData: false, + postDataError: null, + postDataSuccess: null, + formData: { + multipleDays: true, + //startDate: '2020-08-10', + //endDate: '2020-08-17', + //purpose: 'Sommerlager 2021', + //org: 'VCP Rosenfeld', + //destination: 'Lüneburger Heide', + //name: 'Thomas Ruoff', + //email: 'thomasruoff@gmail.com', + //street: 'Mömpelgardgasse 25', + //zip: '72348', + //city: 'Rosenfeld', + }, +} + +async function createBooking(formData) { const response = await fetch('/api/booking', { method: 'POST', mode: 'cors', @@ -39,23 +85,14 @@ async function createBooking(state) { 'Content-Type': 'application/json', }, referrerPolicy: 'no-referrer', - body: JSON.stringify({ name, email, startDate, endDate }), + body: JSON.stringify(formData), }) - return response.json() } -const initialState = { - formData: { - multipleDays: null, - }, -} - export default function WizardStore({ children }) { const [state, dispatch] = useReducer(debugReducer, initialState) - const storeBooking = () => createBooking(state) - const onChangeEvent = (event) => { const { name, value } = event.target @@ -72,9 +109,21 @@ export default function WizardStore({ children }) { }) } + const onSubmit = async () => { + dispatch({ type: ACTIONS.POST_DATA }) + + try { + const bookingData = await createBooking(state.formData) + dispatch({ type: ACTIONS.POST_DATA_SUCCESS, payload: bookingData }) + } catch (error) { + console.error(error) + dispatch({ type: ACTIONS.POST_DATA_ERROR, payload: error.message }) + } + } + return ( {children}