diff --git a/components/contact.js b/components/contact.js
index 85ac856..22b78f4 100644
--- a/components/contact.js
+++ b/components/contact.js
@@ -5,7 +5,7 @@ import Form from 'react-bootstrap/Form'
import Col from 'react-bootstrap/Col'
export default function Contact() {
- const { state } = useContext(WizardContext)
+ const { state, onChangeEvent } = useContext(WizardContext)
const { name, email, street, zip, city } = state.formData
@@ -13,38 +13,53 @@ export default function Contact() {
<>
Name
-
+
E-Mail
Straße
PLZ
-
+
Stadt
diff --git a/components/dateSelect.js b/components/dateSelect.js
index 34dfbb5..19678cd 100644
--- a/components/dateSelect.js
+++ b/components/dateSelect.js
@@ -9,11 +9,13 @@ import moment from 'moment'
import 'react-dates/initialize'
import { DateRangePicker, SingleDatePicker } from 'react-dates'
+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, dispatch } = useContext(WizardContext)
+ const { state, onChange, onChangeEvent } = useContext(WizardContext)
const { data: daysBooked, error: fetchBookedOnError } = useSWR(
'/api/daysbooked',
fetcher
@@ -49,13 +51,10 @@ export default function DateSelect() {
checked={multipleDays === false}
onChange={() => {
setFocusedInput(null)
- dispatch({
- type: ACTIONS.SET_FORM_DATA,
- payload: {
- multipleDays: false,
- startDate: null,
- endDate: null,
- },
+ onChange({
+ multipleDays: false,
+ startDate: null,
+ endDate: null,
})
}}
/>
@@ -68,13 +67,10 @@ export default function DateSelect() {
checked={multipleDays === true}
onChange={() => {
setFocusedInput(null)
- dispatch({
- type: ACTIONS.SET_FORM_DATA,
- payload: {
- multipleDays: true,
- startDate: null,
- endDate: null,
- },
+ onChange({
+ multipleDays: true,
+ startDate: null,
+ endDate: null,
})
}}
/>
@@ -91,11 +87,8 @@ export default function DateSelect() {
placeholder="Datum"
numberOfMonths={1}
onDateChange={(date) =>
- dispatch({
- type: ACTIONS.SET_FORM_DATA,
- payload: {
- startDate: date && date.toISOString(),
- },
+ onChange({
+ startDate: date && dateFormat(date),
})
}
focused={typeof focusedInput === 'boolean' && focusedInput}
@@ -115,12 +108,9 @@ export default function DateSelect() {
endDate={endDate && moment(endDate)}
endDateId="endDate"
onDatesChange={({ startDate, endDate }) => {
- dispatch({
- type: ACTIONS.SET_FORM_DATA,
- payload: {
- startDate: startDate && startDate.toISOString(),
- endDate: endDate && endDate.toISOString(),
- },
+ onChange({
+ startDate: startDate && dateFormat(startDate),
+ endDate: endDate && dateFormat(endDate),
})
}}
focusedInput={focusedInput}
diff --git a/components/reason.js b/components/reason.js
index 7dad69f..e8c82b7 100644
--- a/components/reason.js
+++ b/components/reason.js
@@ -4,7 +4,7 @@ import { WizardContext, ACTIONS } from '../context/wizardStore'
import Form from 'react-bootstrap/Form'
export default function Contact() {
- const { state } = useContext(WizardContext)
+ const { state, onChangeEvent } = useContext(WizardContext)
const { purpose, destination, org } = state.formData
@@ -14,22 +14,30 @@ export default function Contact() {
Zweck der Fahrt
Verein
-
+
Ziel der Fahrt
>
diff --git a/components/wizard.js b/components/wizard.js
index c6b9fef..1f3ed94 100644
--- a/components/wizard.js
+++ b/components/wizard.js
@@ -1,4 +1,4 @@
-import { useContext } from 'react'
+import { useContext, useRef } from 'react'
import Button from 'react-bootstrap/Button'
import Form from 'react-bootstrap/Form'
@@ -10,50 +10,23 @@ import Reason from './reason'
import Contact from './contact'
//import Driver from './driver'
-const STEPS = [
- { id: 'DATE_SELECT', component: DateSelect },
- { id: 'REASON', component: Reason },
- { id: 'CONTACT', component: Contact },
-]
-
function WizardInternal() {
- const { state, dispatch, onSubmit } = useContext(WizardContext)
- const { currentStep } = state
-
- const isFirstStep = currentStep === 0
- const isLastStep = currentStep === STEPS.length - 1
-
- const CurrentStepComponent = STEPS[currentStep].component
+ const { state, storeBooking } = useContext(WizardContext)
+ const onChange = (payload) =>
+ dispatch({ action: ACTIONS.SET_FORM_DATA, payload })
return (
)
}
diff --git a/context/wizardStore.js b/context/wizardStore.js
index 3a4009c..5fb7297 100644
--- a/context/wizardStore.js
+++ b/context/wizardStore.js
@@ -3,23 +3,11 @@ import React, { useReducer } from 'react'
export const WizardContext = React.createContext()
export const ACTIONS = {
- NEXT_STEP: 'nextStep',
- PREV_STEP: 'prevStep',
SET_FORM_DATA: 'setFormData',
}
function reducer(state, action) {
switch (action.type) {
- case ACTIONS.NEXT_STEP:
- return {
- ...state,
- currentStep: state.currentStep + 1, // wizards steps unkown here
- }
- case ACTIONS.PREV_STEP:
- return {
- ...state,
- currentStep: Math.max(0, state.currentStep - 1),
- }
case ACTIONS.SET_FORM_DATA:
return {
...state,
@@ -59,27 +47,35 @@ async function createBooking(state) {
const initialState = {
formData: {
- name: 'Thomas Ruoff',
- email: 'thomasruoff@gmail.com',
multipleDays: null,
},
- currentStep: 0,
- bookedOn: [
- '2020-07-10',
- '2020-07-11',
- '2020-07-12',
- '2020-07-23',
- '2020-08-01',
- ],
}
export default function WizardStore({ children }) {
const [state, dispatch] = useReducer(debugReducer, initialState)
- const onSubmit = () => createBooking(state)
+ const storeBooking = () => createBooking(state)
+
+ const onChangeEvent = (event) => {
+ const { name, value } = event.target
+
+ dispatch({
+ type: ACTIONS.SET_FORM_DATA,
+ payload: { [name]: value },
+ })
+ }
+
+ const onChange = (data) => {
+ dispatch({
+ type: ACTIONS.SET_FORM_DATA,
+ payload: data,
+ })
+ }
return (
-
+
{children}
)
diff --git a/db/index.js b/db/index.js
index fe0b871..cddc493 100644
--- a/db/index.js
+++ b/db/index.js
@@ -34,16 +34,15 @@ export async function getBookedDays() {
}
export async function createBooking({ name, email, startDate, endDate }) {
- const booker = new Booker({ name, email })
- await booker.save()
+ const ignoreCaseEmailMatcher = new RegExp(email, 'i')
+ let booker = await Booker.findOne({ email: ignoreCaseEmailMatcher }).exec()
+ if (!booker) {
+ booker = new Booker({ name, email })
+ await booker.save()
+ }
+
const booking = new Booking({ startDate, endDate, booker: booker._id })
await booking.save()
- return {
- booker: booking.booker._id,
- startDate: booking.startDate,
- endDate: booking.endDate,
- bookedDate: booking.bookedDate,
- confirmed: booking.confirmed,
- confirmedDate: booking.confimredDate,
- }
+ await booking.populate('booker').execPopulate()
+ return booking.toJSON({ getters: true, virtuals: true })
}
diff --git a/db/schema.js b/db/schema.js
index 0a250da..c248582 100644
--- a/db/schema.js
+++ b/db/schema.js
@@ -1,18 +1,34 @@
import { Schema } from 'mongoose'
-export const BookerSchema = new Schema({
- name: { type: String, required: true },
- email: { type: String, required: true },
-})
+import { getDays, dateFormat } from '../lib/dateHelper'
-export const BookingSchema = new Schema({
- booker: { type: Schema.Types.ObjectId, ref: 'Booker', required: true },
- startDate: { type: Date, required: true },
- endDate: { type: Date, required: false },
- status: {
- type: String,
- enum: ['requested', 'confirmed', 'rejected'],
- required: true,
- default: 'requested',
+export const BookerSchema = new Schema(
+ {
+ name: { type: String, required: true },
+ email: { type: String, required: true, unique: true },
},
+ { timestamps: true }
+)
+
+export const BookingSchema = new Schema(
+ {
+ booker: { type: Schema.Types.ObjectId, ref: 'Booker', required: true },
+ startDate: {
+ type: Date,
+ required: true,
+ get: dateFormat,
+ },
+ endDate: { type: Date, required: false, get: dateFormat },
+ status: {
+ type: String,
+ enum: ['requested', 'confirmed', 'rejected'],
+ required: true,
+ default: 'requested',
+ },
+ },
+ { timestamps: true }
+)
+
+BookingSchema.virtual('days').get(function () {
+ return getDays({ startDate: this.startDate, endDate: this.endDate })
})