move CRUD operations to helpers

This commit is contained in:
Thomas Ruoff
2021-06-07 23:32:54 +02:00
parent 865bbb20fa
commit 92477e5325
9 changed files with 102 additions and 93 deletions

View File

@@ -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<Bill> {
return fetch(`/api/admin/booking/${bookingUuid}/bill`, {
method: 'POST',
body: bill,
})
}
export async function patchBill(
bookingUuid: string,
bill: Bill
): Promise<Bill> {
return fetch(`/api/admin/booking/${bookingUuid}/bill`, {
method: 'POST',
body: bill,
})
}

View File

@@ -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 },
})
}

40
helpers/fetch.ts Normal file
View File

@@ -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<RequestInit, 'body'> & {
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()
}

View File

@@ -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(

View File

@@ -0,0 +1,39 @@
import { VALIDATION_ERRORS } from '../db/enums'
interface ValidationErrors {
[key: string]: { properties: { message: string }; kind: string }
}
function getDefinedValidationMessage(kind: string) {
switch (kind) {
case VALIDATION_ERRORS.AT_LEAST_ONE_DAY_BOOKED:
return 'Mindestens ein angefragter Tag ist nicht mehr verfügbar'
default:
return null
}
}
export class ValidationError extends Error {
private errors: ValidationErrors
constructor(errors: ValidationErrors) {
super()
if (Error.captureStackTrace) {
Error.captureStackTrace(this, ValidationError)
}
this.name = this.constructor.name
this.errors = errors
}
get message() {
return Object.entries<{ properties: { message: string }; kind: string }>(
this.errors
)
.map(([_key, value]) => {
const validationMessage = getDefinedValidationMessage(value.kind)
return validationMessage || `${value?.properties?.message}`
})
.join(',')
}
}