From 92477e5325ccec689ec6b6673a0bf6188929b9d3 Mon Sep 17 00:00:00 2001 From: Thomas Ruoff Date: Mon, 7 Jun 2021 23:32:54 +0200 Subject: [PATCH] move CRUD operations to helpers --- components/wizard/context/wizardStore.tsx | 30 +------------- helpers/bill.ts | 31 +++++++++++++- helpers/booking.ts | 22 ++++++++++ helpers/fetch.ts | 40 +++++++++++++++++++ helpers/useDaysBooked.ts | 3 +- .../context => helpers}/validationError.ts | 2 +- pages/admin/booking/[uuid]/bill.tsx | 31 ++------------ pages/admin/booking/[uuid]/index.tsx | 17 +------- pages/booking/[uuid]/index.tsx | 19 +-------- 9 files changed, 102 insertions(+), 93 deletions(-) create mode 100644 helpers/fetch.ts rename {components/wizard/context => helpers}/validationError.ts (94%) diff --git a/components/wizard/context/wizardStore.tsx b/components/wizard/context/wizardStore.tsx index 50ef1d6..8f17a93 100644 --- a/components/wizard/context/wizardStore.tsx +++ b/components/wizard/context/wizardStore.tsx @@ -1,7 +1,8 @@ import React, { useEffect, useReducer } from 'react' import { useRouter } from 'next/router' import { clearBookingData, loadBookingData } from '../../../helpers/storage' -import { ValidationError } from './validationError' + +import { createBooking } from '../../../helpers/booking' interface WizardFormData { startDate: string @@ -136,33 +137,6 @@ const initialState: WizardStoreState = { dataStoredLoaded: undefined, } -async function createBooking(formData: WizardFormData) { - const response = await fetch('/api/booking', { - method: 'POST', - mode: 'cors', - cache: 'no-cache', - credentials: 'same-origin', - headers: { - 'Content-Type': 'application/json', - }, - referrerPolicy: 'no-referrer', - body: JSON.stringify(formData), - }) - - if (response.status === 400) { - const error = await response.json() - throw new ValidationError(error.errors) - } - - if (!response.ok) { - throw Error( - 'Sorry, konnte nicht gespeichert werden. Bitte versuch es später nochmal!' - ) - } - - return response.json() -} - export default function WizardStore({ children }) { const router = useRouter() const [state, dispatch] = useReducer(reducer, initialState) diff --git a/helpers/bill.ts b/helpers/bill.ts index bea0b2e..36fc134 100644 --- a/helpers/bill.ts +++ b/helpers/bill.ts @@ -1,11 +1,18 @@ import { MILAGE_TARIFS } from '../db/enums' -import { AdditionalCost } from '../db/bill' +import { AdditionalCost, Bill } from '../db/bill' +import fetch from './fetch' function roundToCent(amount: number): number { return Math.round(amount * 100) / 100 } -export function getMilageCosts({ tarif, km }: { tarif: MILAGE_TARIFS; km: number }): number { +export function getMilageCosts({ + tarif, + km, +}: { + tarif: MILAGE_TARIFS + km: number +}): number { if (tarif === MILAGE_TARIFS.NOCHARGE) { return 0 } @@ -63,3 +70,23 @@ export function getBillTotal({ return roundToCent(milageCosts + additionalCostsSum) } + +export async function createBill( + bookingUuid: string, + bill: Bill +): Promise { + return fetch(`/api/admin/booking/${bookingUuid}/bill`, { + method: 'POST', + body: bill, + }) +} + +export async function patchBill( + bookingUuid: string, + bill: Bill +): Promise { + return fetch(`/api/admin/booking/${bookingUuid}/bill`, { + method: 'POST', + body: bill, + }) +} diff --git a/helpers/booking.ts b/helpers/booking.ts index 53a62c4..e013944 100644 --- a/helpers/booking.ts +++ b/helpers/booking.ts @@ -1,4 +1,5 @@ import { BOOKING_STATUS } from '../db/enums' +import fetch from './fetch' export function getBookingStatus(status: BOOKING_STATUS) { switch (status) { @@ -14,3 +15,24 @@ export function getBookingStatus(status: BOOKING_STATUS) { return 'Unbekannt - bitte kontaktieren Sie uns!' } } + +export async function createBooking(formData: object) { + return fetch('/api/booking', { + method: 'POST', + body: formData, + }) +} + +export async function cancelBooking(uuid: string) { + return fetch(`/api/booking/${uuid}`, { + method: 'PATCH', + body: { status: BOOKING_STATUS.CANCELED }, + }) +} + +export async function patchBooking(uuid: string, bookingData: object) { + return fetch(`/api/admin/booking/${uuid}`, { + method: 'PATCH', + body: { ...bookingData }, + }) +} diff --git a/helpers/fetch.ts b/helpers/fetch.ts new file mode 100644 index 0000000..7173f02 --- /dev/null +++ b/helpers/fetch.ts @@ -0,0 +1,40 @@ +import { ValidationError } from './validationError' + +const DEFAULT_FETCH_OPTIONS = { + method: 'GET', + mode: 'cors' as RequestMode, + cache: 'no-cache' as RequestCache, + credentials: 'same-origin' as RequestCredentials, + headers: { + 'Content-Type': 'application/json', + }, + referrerPolicy: 'no-referrer' as ReferrerPolicy, +} + +export type FetchOptions = Omit & { + body?: object +} + +export default async function fetchJSON( + url: string, + options: FetchOptions = {} +) { + const response = await fetch(url, { + ...DEFAULT_FETCH_OPTIONS, + ...options, + body: !!options.body ? JSON.stringify(options.body) : undefined, + }) + + if (response.status === 400) { + const error = await response.json() + throw new ValidationError(error.errors) + } + + if (!response.ok) { + throw Error( + 'Sorry, konnte nicht gespeichert werden. Bitte versuch es später nochmal!' + ) + } + + return response.json() +} diff --git a/helpers/useDaysBooked.ts b/helpers/useDaysBooked.ts index e353e8b..7f7e75a 100644 --- a/helpers/useDaysBooked.ts +++ b/helpers/useDaysBooked.ts @@ -1,6 +1,7 @@ import useSWR from 'swr' +import fetch from './fetch' -const fetcher = (path: string) => fetch(path).then((r) => r.json()) +const fetcher = (path: string) => fetch(path) function useDaysBooked() { const { data: daysBooked, error: daysBookedError } = useSWR( diff --git a/components/wizard/context/validationError.ts b/helpers/validationError.ts similarity index 94% rename from components/wizard/context/validationError.ts rename to helpers/validationError.ts index 121b4e8..0dd4058 100644 --- a/components/wizard/context/validationError.ts +++ b/helpers/validationError.ts @@ -1,4 +1,4 @@ -import { VALIDATION_ERRORS } from '../../../db/enums' +import { VALIDATION_ERRORS } from '../db/enums' interface ValidationErrors { [key: string]: { properties: { message: string }; kind: string } diff --git a/pages/admin/booking/[uuid]/bill.tsx b/pages/admin/booking/[uuid]/bill.tsx index 4da40a9..330f4f2 100644 --- a/pages/admin/booking/[uuid]/bill.tsx +++ b/pages/admin/booking/[uuid]/bill.tsx @@ -3,12 +3,11 @@ import Footer from '../../../../components/footer' import Header from '../../../../components/header' import Input from '../../../../components/input' import Select from '../../../../components/select' -import { AdditionalCost, Bill } from '../../../../db/bill' import { Booking } from '../../../../db/booking' import { BILL_STATUS, MILAGE_TARIFS } from '../../../../db/enums' import { getMilageMax } from '../../../../db/index' import { daysFormatFrontend } from '../../../../helpers/date' -import { getBillTotal } from '../../../../helpers/bill' +import { getBillTotal, createBill, patchBill } from '../../../../helpers/bill' import { getBookingStatus } from '../../../../helpers/booking' import withSession, { isAdminSession, @@ -79,31 +78,6 @@ function getBillStatusLabel(status: BILL_STATUS) { } } -async function saveBill( - booking: Booking, - bill: { - milageStart: number - milageEnd: number - milage?: number - tarif: MILAGE_TARIFS - additionalCosts: AdditionalCost[] - status: BILL_STATUS - } -): Promise { - const response = await fetch(`/api/admin/booking/${booking.uuid}/bill`, { - method: !!booking.bill ? 'PATCH' : 'POST', - mode: 'cors', - cache: 'no-cache', - credentials: 'same-origin', - headers: { - 'Content-Type': 'application/json', - }, - referrerPolicy: 'no-referrer', - body: JSON.stringify(bill), - }) - return response.json() -} - export default function BookingBillPage({ booking: bookingProp, milageMax, @@ -136,7 +110,8 @@ export default function BookingBillPage({ setStoringError(null) try { - const bill = await saveBill(booking, { + const saveBill = !!booking.bill ? createBill : patchBill + const bill = await saveBill(booking.uuid, { milageStart, milageEnd, milage, diff --git a/pages/admin/booking/[uuid]/index.tsx b/pages/admin/booking/[uuid]/index.tsx index 76bc7c2..afe9772 100644 --- a/pages/admin/booking/[uuid]/index.tsx +++ b/pages/admin/booking/[uuid]/index.tsx @@ -11,7 +11,7 @@ import withSession, { } from '../../../../lib/session' import { getServerSideBooking } from '../../../../lib/getServerSideProps' import { Booking } from '../../../../db/booking' -import { getBookingStatus } from '../../../../helpers/booking' +import { getBookingStatus, patchBooking } from '../../../../helpers/booking' import { daysFormatFrontend } from '../../../../helpers/date' import { BOOKING_STATUS } from '../../../../db/enums' @@ -36,21 +36,6 @@ export const getServerSideProps: GetServerSideProps = withSession( } ) -async function patchBooking(uuid: string, bookingData: any) { - const response = await fetch(`/api/admin/booking/${uuid}`, { - method: 'PATCH', - mode: 'cors', - cache: 'no-cache', - credentials: 'same-origin', - headers: { - 'Content-Type': 'application/json', - }, - referrerPolicy: 'no-referrer', - body: JSON.stringify({ ...bookingData }), - }) - return response.json() -} - export default function ShowBookingAdmin({ booking: bookingProp, }: { diff --git a/pages/booking/[uuid]/index.tsx b/pages/booking/[uuid]/index.tsx index 6828ceb..0491468 100644 --- a/pages/booking/[uuid]/index.tsx +++ b/pages/booking/[uuid]/index.tsx @@ -5,25 +5,10 @@ import { getServerSideBooking } from '../../../lib/getServerSideProps' import { Booking } from '../../../db/booking' import { BOOKING_STATUS } from '../../../db/enums' import { daysFormatFrontend } from '../../../helpers/date' -import { getBookingStatus } from '../../../helpers/booking' +import { getBookingStatus, cancelBooking } from '../../../helpers/booking' export const getServerSideProps = getServerSideBooking -async function cancelBooking(booking: Booking) { - const response = await fetch(`/api/booking/${booking.uuid}`, { - method: 'PATCH', - mode: 'cors', - cache: 'no-cache', - credentials: 'same-origin', - headers: { - 'Content-Type': 'application/json', - }, - referrerPolicy: 'no-referrer', - body: JSON.stringify({ status: BOOKING_STATUS.CANCELED }), - }) - return response.json() -} - export default function ShowBooking({ booking: bookingProp, }: { @@ -44,7 +29,7 @@ export default function ShowBooking({ try { setStoringBookingError(null) setStoringBooking(true) - const updatedBooking = await cancelBooking(booking) + const updatedBooking = await cancelBooking(booking.uuid) setBooking(updatedBooking) } catch (error) { setStoringBookingError(