update mongoose to 5.8.3 (lots of types changes)

This commit is contained in:
Thomas Ruoff
2024-09-10 22:44:25 +02:00
parent 3ecbd16a2c
commit 32818b7492
22 changed files with 136 additions and 251 deletions

View File

@@ -2,12 +2,12 @@ import React from 'react'
import Link from 'next/link' import Link from 'next/link'
import { daysFormatFrontend } from '../helpers/date' import { daysFormatFrontend } from '../helpers/date'
import { BookingDocument } from '../db/booking' import { IBooking } from '../db/booking'
export default function BookingTable({ export default function BookingTable({
booking, booking,
}: { }: {
booking: BookingDocument booking: IBooking
}) { }) {
const data = [ const data = [
{ name: 'Status', value: booking.status }, { name: 'Status', value: booking.status },
@@ -51,7 +51,7 @@ export default function BookingTable({
</h3> </h3>
<p className="mt-1 max-w-2xl text-sm text-gray-500"> <p className="mt-1 max-w-2xl text-sm text-gray-500">
Created{' '} Created{' '}
{new Date(booking.createdAt as string).toLocaleString( {new Date(booking.createdAt).toLocaleString(
new Intl.Locale('de') new Intl.Locale('de')
)} )}
</p> </p>

View File

@@ -4,9 +4,9 @@ import { clearBookingData, loadBookingData } from '../helpers/storage'
import { log } from '../helpers/log' import { log } from '../helpers/log'
import { createBooking } from '../helpers/booking' import { createBooking } from '../helpers/booking'
import { Booking } from '../db/booking' import { IBooking } from '../db/booking'
export type BookFormData = Omit<Booking, 'uuid' | 'calendarEventId'> export type BookFormData = Omit<IBooking, 'uuid' | 'calendarEventId'>
type BookingProviderState = { type BookingProviderState = {
postData?: boolean postData?: boolean
@@ -14,7 +14,7 @@ type BookingProviderState = {
postDataSuccess?: boolean postDataSuccess?: boolean
formData: BookFormData formData: BookFormData
formDataChanged: string[] formDataChanged: string[]
booking?: Booking booking?: IBooking
dataStored: boolean dataStored: boolean
dataStoredLoaded: boolean dataStoredLoaded: boolean
} }

View File

@@ -2,27 +2,30 @@ import * as mongoose from 'mongoose'
import { BILL_STATUS, MILAGE_TARIFS } from './enums' import { BILL_STATUS, MILAGE_TARIFS } from './enums'
import { getBillTotal } from '../helpers/bill' import { getBillTotal } from '../helpers/bill'
export type AdditionalCost = { export interface IAdditionalCost {
name: string name: string
value: number value: number
} }
export type Bill = { export interface IBill {
milageStart: number milageStart: number
milageEnd: number milageEnd: number
milage?: number milage?: number
tarif: MILAGE_TARIFS tarif: MILAGE_TARIFS
status: BILL_STATUS status: BILL_STATUS
additionalCosts: AdditionalCost[] additionalCosts: IAdditionalCost[]
createdAt?: string
updatedAt?: string
} }
export type BillDocument = Bill & export type BillDocument = IBill &
mongoose.SchemaTimestampsConfig & mongoose.SchemaTimestampsConfig &
mongoose.Document mongoose.Document
export type BillModel = mongoose.Model<BillDocument> export type BillModel = mongoose.Model<IBill>
const BillSchema = new mongoose.Schema<BillDocument>( const BillSchema = new mongoose.Schema<IBill>(
{ {
milageStart: { milageStart: {
type: Number, type: Number,
@@ -88,4 +91,4 @@ BillSchema.virtual('total').get(function (): number {
}) })
export default (mongoose.models.Bill || export default (mongoose.models.Bill ||
mongoose.model<BillDocument, BillModel>('Bill', BillSchema)) as BillModel mongoose.model<BillDocument, BillModel>('Bill', BillSchema)) as BillModel

View File

@@ -8,10 +8,10 @@ import {
} from '../helpers/date' } from '../helpers/date'
import { createCalendarEvent, deleteCalendarEvent } from '../lib/googlecalendar' import { createCalendarEvent, deleteCalendarEvent } from '../lib/googlecalendar'
import { Bill } from './bill' import { IBill } from './bill'
import { BOOKING_STATUS, VALIDATION_ERRORS } from './enums' import { BOOKING_STATUS, VALIDATION_ERRORS } from './enums'
export type Booking = { export interface IBooking {
uuid: string uuid: string
name: string name: string
email: string email: string
@@ -19,7 +19,7 @@ export type Booking = {
street: string street: string
zip: string zip: string
city: string city: string
bill?: Bill bill?: IBill
// format YYYY-MM-DD // format YYYY-MM-DD
startDate: string startDate: string
// format YYYY-MM-DD // format YYYY-MM-DD
@@ -30,17 +30,17 @@ export type Booking = {
destination?: string destination?: string
days?: string[] days?: string[]
calendarEventId: string calendarEventId: string
createdAt?: string
updatedAt?: string
toJSON?: () => IBooking
} }
export type BookingDocument = Booking & export type BookingModel = mongoose.Model<IBooking> & {
mongoose.Document &
mongoose.SchemaTimestampsConfig
export type BookingModel = mongoose.Model<BookingDocument> & {
findBookedDays(uuidsToIngore?: string[]): Promise<string[]> findBookedDays(uuidsToIngore?: string[]): Promise<string[]>
} }
const BookingSchema = new mongoose.Schema<BookingDocument>( const BookingSchema = new mongoose.Schema(
{ {
// need a seperate uuid to be able to target a booking anonimously // need a seperate uuid to be able to target a booking anonimously
uuid: { uuid: {
@@ -78,7 +78,7 @@ const BookingSchema = new mongoose.Schema<BookingDocument>(
required: true, required: true,
validate: { validate: {
validator: async function (days: string[]): Promise<boolean> { validator: async function (days: string[]): Promise<boolean> {
const booking = this as Booking const booking = this
const uuid = booking.uuid && [booking.uuid] const uuid = booking.uuid && [booking.uuid]
const bookedDays = await BookingModel.findBookedDays(uuid) const bookedDays = await BookingModel.findBookedDays(uuid)
@@ -111,7 +111,7 @@ const BookingSchema = new mongoose.Schema<BookingDocument>(
) )
BookingSchema.pre('validate', function (next: () => void): void { BookingSchema.pre('validate', function (next: () => void): void {
const booking = this as BookingDocument const booking = this
booking.days = getDays({ booking.days = getDays({
startDate: new Date(booking.startDate), startDate: new Date(booking.startDate),
endDate: new Date(booking.endDate), endDate: new Date(booking.endDate),
@@ -120,16 +120,16 @@ BookingSchema.pre('validate', function (next: () => void): void {
}) })
BookingSchema.pre('save', async function (next: () => void): Promise<void> { BookingSchema.pre('save', async function (next: () => void): Promise<void> {
const booking = this as BookingDocument const booking = this
if (!booking.calendarEventId) { if (!booking.calendarEventId) {
// create calendar event before saving to database // create calendar event before saving to database
await createCalendarEvent(booking) await createCalendarEvent(booking.toJSON())
} else if ( } else if (
[BOOKING_STATUS.CANCELED, BOOKING_STATUS.REJECTED].includes(booking.status) [BOOKING_STATUS.CANCELED, BOOKING_STATUS.REJECTED].includes(booking.status)
) { ) {
// event has been canceled or rejected, delete calendar event again to free up the slot // event has been canceled or rejected, delete calendar event again to free up the slot
await deleteCalendarEvent(booking) await deleteCalendarEvent(booking.toJSON())
} }
next() next()
@@ -138,31 +138,26 @@ BookingSchema.pre('save', async function (next: () => void): Promise<void> {
BookingSchema.static( BookingSchema.static(
'findBookedDays', 'findBookedDays',
async function (uuidsToIngore: string[] = []): Promise<string[]> { async function (uuidsToIngore: string[] = []): Promise<string[]> {
const model = this as BookingModel const booking = this
const now = nowInTz() const now = nowInTz()
const bookedDays = await model const bookedDays = await booking.find(
.find( {
{ status: { $in: [BOOKING_STATUS.REQUESTED, BOOKING_STATUS.CONFIRMED] },
status: { $in: [BOOKING_STATUS.REQUESTED, BOOKING_STATUS.CONFIRMED] }, uuid: { $nin: uuidsToIngore },
uuid: { $nin: uuidsToIngore }, // dateFormatBackend uses YYYY-MM-DD, which is startOfDay anyway
// dateFormatBackend uses YYYY-MM-DD, which is startOfDay anyway endDate: { $gt: dateFormatBackend(now) },
endDate: { $gt: dateFormatBackend(now) }, },
}, 'days'
'days' )
)
.exec()
return bookedDays return bookedDays
.map((b) => b.days) .map((b: { days: any }) => b.days)
.flat() .flat()
.sort() .sort()
} }
) )
const BookingModel = (mongoose.models.Booking || const BookingModel = (mongoose.models.Booking ||
mongoose.model<BookingDocument, BookingModel>( mongoose.model<IBooking>('Booking', BookingSchema)) as BookingModel
'Booking',
BookingSchema
)) as BookingModel
export default BookingModel export default BookingModel

View File

@@ -1,6 +1,6 @@
import * as mongoose from 'mongoose' import * as mongoose from 'mongoose'
import BookingModel, { Booking, BookingDocument } from './booking' import BookingModel, { IBooking } from './booking'
import BillModel, { Bill } from './bill' import BillModel, { IBill } from './bill'
import { getBookedDays as calendarGetBookedDays } from '../lib/googlecalendar' import { getBookedDays as calendarGetBookedDays } from '../lib/googlecalendar'
import { BOOKING_STATUS } from './enums' import { BOOKING_STATUS } from './enums'
import { uniqueFilter } from '../helpers/array' import { uniqueFilter } from '../helpers/array'
@@ -9,7 +9,7 @@ export const MONGO_URI = process.env.MONGO_URI
mongoose.set('strictQuery', false); mongoose.set('strictQuery', false);
mongoose.connect(process.env.MONGO_URI, { mongoose.connect(MONGO_URI, {
serverSelectionTimeoutMS: 3000, serverSelectionTimeoutMS: 3000,
}) })
@@ -23,7 +23,7 @@ export async function getBookedDays(
return [...bookedInDatabase, ...bookedInCalendar].filter(uniqueFilter).sort() return [...bookedInDatabase, ...bookedInCalendar].filter(uniqueFilter).sort()
} }
export async function getBookingByUUID(uuid: string): Promise<BookingDocument> { export async function getBookingByUUID(uuid: string): Promise<mongoose.HydratedDocument<IBooking>> {
return BookingModel.findOne({ uuid }) return BookingModel.findOne({ uuid })
} }
@@ -31,7 +31,7 @@ export async function getBookings({
status = [BOOKING_STATUS.CONFIRMED, BOOKING_STATUS.REQUESTED], status = [BOOKING_STATUS.CONFIRMED, BOOKING_STATUS.REQUESTED],
startDateGreaterThan = '2000-01-01T00:00:00Z', startDateGreaterThan = '2000-01-01T00:00:00Z',
}: { status?: BOOKING_STATUS[]; startDateGreaterThan?: string } = {}): Promise< }: { status?: BOOKING_STATUS[]; startDateGreaterThan?: string } = {}): Promise<
BookingDocument[] IBooking[]
> { > {
return await BookingModel.find({ return await BookingModel.find({
status: { $in: status }, status: { $in: status },
@@ -53,7 +53,7 @@ export async function createBooking({
street, street,
zip, zip,
city, city,
}: Booking): Promise<Booking> { }: IBooking): Promise<mongoose.FlattenMaps<IBooking & { _id: mongoose.Types.ObjectId }>> {
const booking = new BookingModel({ const booking = new BookingModel({
startDate, startDate,
endDate, endDate,
@@ -69,25 +69,25 @@ export async function createBooking({
}) })
await booking.save() await booking.save()
return booking.toJSON<Booking>() return booking.toJSON()
} }
export async function patchBooking( export async function patchBooking(
bookingUUID: string, bookingUUID: string,
bookingData: Booking bookingData: IBooking
): Promise<{ current: Booking; previous: Booking }> { ): Promise<{ current: IBooking; previous: IBooking }> {
const booking = await getBookingByUUID(bookingUUID) const booking = await getBookingByUUID(bookingUUID)
const oldBooking = booking.toJSON<Booking>() const oldBooking = booking.toJSON()
booking.set(bookingData) booking.set(bookingData)
await booking.save() await booking.save()
return { current: booking.toJSON<Booking>(), previous: oldBooking } return { current: booking.toJSON(), previous: oldBooking }
} }
export async function createBill( export async function createBill(
bookingUUID: string, bookingUUID: string,
billData: Bill billData: IBill
): Promise<Bill> { ): Promise<IBill> {
const booking = await getBookingByUUID(bookingUUID) const booking = await getBookingByUUID(bookingUUID)
const bill = new BillModel() const bill = new BillModel()
@@ -95,16 +95,16 @@ export async function createBill(
await bill.save() await bill.save()
booking.bill = bill._id booking.bill = bill
await booking.save() await booking.save()
return bill.toJSON<Bill>() return bill.toJSON()
} }
export async function patchBill( export async function patchBill(
bookingUUID: string, bookingUUID: string,
billData: Bill billData: IBill
): Promise<Bill> { ): Promise<IBill> {
const booking = await getBookingByUUID(bookingUUID) const booking = await getBookingByUUID(bookingUUID)
const bill = const bill =
(booking.bill && (await BillModel.findById(booking.bill))) || (booking.bill && (await BillModel.findById(booking.bill))) ||
@@ -113,12 +113,12 @@ export async function patchBill(
bill.set(billData) bill.set(billData)
await bill.save() await bill.save()
if (booking.bill !== bill._id) { if (booking.bill !== bill) {
booking.bill = bill._id booking.bill = bill
await booking.save() await booking.save()
} }
return bill.toJSON<Bill>() return bill.toJSON()
} }
export async function getMilageMax(): Promise<number> { export async function getMilageMax(): Promise<number> {

View File

@@ -1,13 +0,0 @@
import { getNextSmaller, getNextBigger } from './array'
test('getPreviousInOrder', () => {
const result = getNextSmaller([3, 1, 2, 0, 8, 9, 10], 5)
expect(result).toEqual(3)
})
test('getNextInOrder', () => {
const result = getNextBigger([7, 8, 9, 3, 1, 2], 4)
expect(result).toEqual(7)
})

View File

@@ -1,5 +1,5 @@
import { MILAGE_TARIFS } from '../db/enums' import { MILAGE_TARIFS } from '../db/enums'
import { AdditionalCost, Bill } from '../db/bill' import { IAdditionalCost, IBill } from '../db/bill'
import fetch from './fetch' import fetch from './fetch'
function roundToCent(amount: number): number { function roundToCent(amount: number): number {
@@ -61,7 +61,7 @@ export function getBillTotal({
}: { }: {
tarif: MILAGE_TARIFS tarif: MILAGE_TARIFS
milage?: number milage?: number
additionalCosts: AdditionalCost[] additionalCosts: IAdditionalCost[]
}): number { }): number {
const milageCosts = getMilageCosts({ tarif, km: milage }) const milageCosts = getMilageCosts({ tarif, km: milage })
const additionalCostsSum = additionalCosts const additionalCostsSum = additionalCosts
@@ -73,8 +73,8 @@ export function getBillTotal({
export async function createBill( export async function createBill(
bookingUuid: string, bookingUuid: string,
bill: Bill bill: IBill
): Promise<Bill> { ): Promise<IBill> {
return fetch(`/api/bookings/${bookingUuid}/bill`, { return fetch(`/api/bookings/${bookingUuid}/bill`, {
method: 'POST', method: 'POST',
body: bill, body: bill,
@@ -83,8 +83,8 @@ export async function createBill(
export async function patchBill( export async function patchBill(
bookingUuid: string, bookingUuid: string,
bill: Bill bill: IBill
): Promise<Bill> { ): Promise<IBill> {
return fetch(`/api/bookings/${bookingUuid}/bill`, { return fetch(`/api/bookings/${bookingUuid}/bill`, {
method: 'POST', method: 'POST',
body: bill, body: bill,

View File

@@ -1,12 +0,0 @@
import { daysFormatFrontend } from './date'
test('daysFormatFrontend', () => {
expect(daysFormatFrontend([])).toEqual('')
expect(daysFormatFrontend(['2020-01-01'])).toEqual('01.01.2020')
expect(daysFormatFrontend(['2020-01-01', '2020-01-02'])).toEqual(
'01.01.2020-02.01.2020'
)
expect(
daysFormatFrontend(['2020-01-01', '2020-01-02', '2020-01-05'])
).toEqual('01.01.2020-05.01.2020')
})

View File

@@ -1,5 +1,5 @@
import { createEvents, createEvent, EventStatus } from 'ics' import { createEvents, createEvent, EventStatus } from 'ics'
import { Booking } from '../db/booking' import { IBooking } from '../db/booking'
import { BOOKING_STATUS } from '../db/enums' import { BOOKING_STATUS } from '../db/enums'
import { getBaseURL } from './url' import { getBaseURL } from './url'
import { daysFormatFrontend } from './date' import { daysFormatFrontend } from './date'
@@ -12,7 +12,7 @@ function convertDay(value: string): [number, number, number] {
return [Number(parts[0]), Number(parts[1]), Number(parts[2])] return [Number(parts[0]), Number(parts[1]), Number(parts[2])]
} }
export function generateCalendarEntry(booking: Booking): string { export function generateCalendarEntry(booking: IBooking): string {
const { error, value } = createEvent({ const { error, value } = createEvent({
productId: 'app.vercel.pfadi-bussle/ics', productId: 'app.vercel.pfadi-bussle/ics',
title: `Pfadi-Bussle Buchung`, title: `Pfadi-Bussle Buchung`,
@@ -38,7 +38,7 @@ Buchungs-Link: ${getBaseURL()}/bookings/${booking.uuid}
return value return value
} }
export function generateBookedCalendar(bookings: Booking[]): string { export function generateBookedCalendar(bookings: IBooking[]): string {
const events = bookings.map( const events = bookings.map(
( (
booking booking
@@ -80,4 +80,4 @@ Link: ${getBaseURL()}/admin/bookings/${booking.uuid}
} }
return value return value
} }

View File

@@ -1,4 +1,4 @@
import { Booking } from '../db/booking' import { IBooking } from '../db/booking'
import { getBaseURL } from '../helpers/url' import { getBaseURL } from '../helpers/url'
import { daysFormatFrontend } from './date' import { daysFormatFrontend } from './date'
import { generateCalendarEntry } from './ical' import { generateCalendarEntry } from './ical'
@@ -49,7 +49,7 @@ Tel. 0151/212 253 62
${getBaseURL()} ${getBaseURL()}
` `
function getReceivedBookingBookerText(booking: Booking): string { function getReceivedBookingBookerText(booking: IBooking): string {
return `Hallo liebe/r ${booking.name}, return `Hallo liebe/r ${booking.name},
Vielen Dank für Deine Buchungsanfrage zum ${daysFormatFrontend(booking.days)}! Vielen Dank für Deine Buchungsanfrage zum ${daysFormatFrontend(booking.days)}!
@@ -66,7 +66,7 @@ ${footer}
` `
} }
function getBookingConfirmedText(booking: Booking): string { function getBookingConfirmedText(booking: IBooking): string {
return `Hallo liebe/r ${booking.name}, return `Hallo liebe/r ${booking.name},
deine Buchunganfrage zum ${daysFormatFrontend( deine Buchunganfrage zum ${daysFormatFrontend(
@@ -83,7 +83,7 @@ ${footer}
` `
} }
function getBookingRejectedText(booking: Booking): string { function getBookingRejectedText(booking: IBooking): string {
return `Hallo liebe/r ${booking.name}, return `Hallo liebe/r ${booking.name},
es tut uns leid, aber deine Buchungsanfrage zum ${daysFormatFrontend( es tut uns leid, aber deine Buchungsanfrage zum ${daysFormatFrontend(
@@ -97,7 +97,7 @@ ${footer}
` `
} }
function getBookingCanceledText(booking: Booking): string { function getBookingCanceledText(booking: IBooking): string {
return `Hallo liebe/r ${booking.name}, return `Hallo liebe/r ${booking.name},
deine Buchungsanfrage zum ${daysFormatFrontend(booking.days)} wurde storniert. deine Buchungsanfrage zum ${daysFormatFrontend(booking.days)} wurde storniert.
@@ -118,7 +118,7 @@ MfG`
} }
export async function sendReceivedBookingAdminMail( export async function sendReceivedBookingAdminMail(
booking: Booking booking: IBooking
): Promise<void> { ): Promise<void> {
await sendMail({ await sendMail({
to: [{ address: adminEmail, name: 'Pfadi-Bussle Wart' }], to: [{ address: adminEmail, name: 'Pfadi-Bussle Wart' }],
@@ -129,7 +129,7 @@ export async function sendReceivedBookingAdminMail(
} }
export async function sendReceivedBookingBookerMail( export async function sendReceivedBookingBookerMail(
booking: Booking booking: IBooking
): Promise<void> { ): Promise<void> {
await sendMail({ await sendMail({
to: [{ address: booking.email, name: booking.name }], to: [{ address: booking.email, name: booking.name }],
@@ -139,7 +139,7 @@ export async function sendReceivedBookingBookerMail(
}) })
} }
export async function sendBookingConfirmed(booking: Booking): Promise<void> { export async function sendBookingConfirmed(booking: IBooking): Promise<void> {
await sendMail({ await sendMail({
to: [{ address: booking.email, name: booking.name }], to: [{ address: booking.email, name: booking.name }],
from: { address: fromEmail, name: 'Pfadi-Bussle Wart' }, from: { address: fromEmail, name: 'Pfadi-Bussle Wart' },
@@ -157,7 +157,7 @@ export async function sendBookingConfirmed(booking: Booking): Promise<void> {
}) })
} }
export async function sendBookingRejected(booking: Booking): Promise<void> { export async function sendBookingRejected(booking: IBooking): Promise<void> {
await sendMail({ await sendMail({
to: [{ address: booking.email, name: booking.name }], to: [{ address: booking.email, name: booking.name }],
from: { address: fromEmail, name: 'Pfadi-Bussle Wart' }, from: { address: fromEmail, name: 'Pfadi-Bussle Wart' },
@@ -166,7 +166,7 @@ export async function sendBookingRejected(booking: Booking): Promise<void> {
}) })
} }
export async function sendBookingCanceled(booking: Booking): Promise<void> { export async function sendBookingCanceled(booking: IBooking): Promise<void> {
await sendMail({ await sendMail({
to: [{ address: booking.email, name: booking.name }], to: [{ address: booking.email, name: booking.name }],
from: { address: fromEmail, name: 'Pfadi-Bussle Wart' }, from: { address: fromEmail, name: 'Pfadi-Bussle Wart' },

View File

@@ -1,4 +1,4 @@
import { Booking } from '../db/booking' import { IBooking } from '../db/booking'
import { log } from '../helpers/log' import { log } from '../helpers/log'
const BOOKING_DATA_KEY = 'pfadiBussleBookingData' const BOOKING_DATA_KEY = 'pfadiBussleBookingData'
@@ -7,7 +7,7 @@ function getStorage() {
return localStorage return localStorage
} }
export function storeBookingData(booking: Booking) { export function storeBookingData(booking: IBooking) {
const { name, email, street, zip, city, org } = booking const { name, email, street, zip, city, org } = booking
getStorage().setItem( getStorage().setItem(
@@ -30,4 +30,4 @@ export function loadBookingData() {
} }
return result return result
} }

View File

@@ -1,6 +1,6 @@
import { google } from 'googleapis' import { google } from 'googleapis'
import { getBaseURL } from '../helpers/url' import { getBaseURL } from '../helpers/url'
import { Booking } from '../db/booking' import { IBooking } from '../db/booking'
import { getDays, getNextDay, dateFormatBackend } from '../helpers/date' import { getDays, getNextDay, dateFormatBackend } from '../helpers/date'
import { log } from '../helpers/log' import { log } from '../helpers/log'
@@ -47,7 +47,7 @@ export async function getBookedDays() {
) )
} }
function getSummary(booking: Partial<Booking>): string { function getSummary(booking: Partial<IBooking>): string {
let summary = '' let summary = ''
if (booking.org) { if (booking.org) {
@@ -59,13 +59,15 @@ function getSummary(booking: Partial<Booking>): string {
return summary return summary
} }
function getDescription(booking: Booking): string { function getDescription(booking: IBooking): string {
const bookingUrl = `${getBaseURL()}/admin/bookings/${booking.uuid}` const bookingUrl = `${getBaseURL()}/admin/bookings/${booking.uuid}`
return `Managelink ${bookingUrl}` return `Managelink ${bookingUrl}`
} }
export async function createCalendarEvent(booking: Booking): Promise<Booking> { export async function createCalendarEvent(
booking: IBooking
): Promise<IBooking> {
const exclusiveEndDate = dateFormatBackend( const exclusiveEndDate = dateFormatBackend(
getNextDay(new Date(booking.endDate)) getNextDay(new Date(booking.endDate))
) )
@@ -85,7 +87,7 @@ export async function createCalendarEvent(booking: Booking): Promise<Booking> {
return booking return booking
} }
export async function deleteCalendarEvent(booking: Booking) { export async function deleteCalendarEvent(booking: IBooking) {
await calendar.events.delete({ await calendar.events.delete({
calendarId, calendarId,
eventId: booking.calendarEventId, eventId: booking.calendarEventId,
@@ -95,12 +97,3 @@ export async function deleteCalendarEvent(booking: Booking) {
booking.calendarEventId = null booking.calendarEventId = null
} }
//export async function patchCalendarEvent(booking: { calendarEventId: string } & Partial<Booking> ) : Promise<Booking> {
// const response = await calendar.events.patch({
// calendarId,
// eventId: booking.calendarEventId,
// });
//
// return booking;
//}

View File

@@ -9,11 +9,11 @@ const nextConfig = {
// Optionally, add any other Next.js config below // Optionally, add any other Next.js config below
async redirects() { async redirects() {
return [ return [
{ // {
source: '/admin', // source: '/admin',
destination: '/nope', // destination: '/nope',
permanent: true, // permanent: true,
}, // },
] ]
}, },
} }

113
package-lock.json generated
View File

@@ -20,7 +20,7 @@
"date-fns-tz": "2.0.1", "date-fns-tz": "2.0.1",
"googleapis": "142.0.0", "googleapis": "142.0.0",
"ics": "3.7.6", "ics": "3.7.6",
"mongoose": "8.3.5", "mongoose": "^8.5.4",
"next": "^14.0.1", "next": "^14.0.1",
"next-auth": "4.24.7", "next-auth": "4.24.7",
"next-axiom": "^1.1.0", "next-axiom": "^1.1.0",
@@ -4987,19 +4987,6 @@
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
"peer": true "peer": true
}, },
"node_modules/abort-controller": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
"optional": true,
"peer": true,
"dependencies": {
"event-target-shim": "^5.0.0"
},
"engines": {
"node": ">=6.5"
}
},
"node_modules/acorn": { "node_modules/acorn": {
"version": "8.11.3", "version": "8.11.3",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
@@ -5028,19 +5015,6 @@
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
} }
}, },
"node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"optional": true,
"peer": true,
"dependencies": {
"debug": "4"
},
"engines": {
"node": ">= 6.0.0"
}
},
"node_modules/ajv": { "node_modules/ajv": {
"version": "6.12.6", "version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -7195,16 +7169,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/event-target-shim": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
"optional": true,
"peer": true,
"engines": {
"node": ">=6"
}
},
"node_modules/events": { "node_modules/events": {
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
@@ -7564,37 +7528,6 @@
"node": ">= 14" "node": ">= 14"
} }
}, },
"node_modules/gcp-metadata": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.3.0.tgz",
"integrity": "sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==",
"optional": true,
"peer": true,
"dependencies": {
"gaxios": "^5.0.0",
"json-bigint": "^1.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/gcp-metadata/node_modules/gaxios": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.0.0.tgz",
"integrity": "sha512-VD/yc5ln6XU8Ch1hyYY6kRMBE0Yc2np3fPyeJeYHhrPs1i8rgnsApPMWyrugkl7LLoSqpOJVBWlQIa87OAvt8Q==",
"optional": true,
"peer": true,
"dependencies": {
"abort-controller": "^3.0.0",
"extend": "^3.0.2",
"https-proxy-agent": "^5.0.0",
"is-stream": "^2.0.0",
"node-fetch": "^2.6.7"
},
"engines": {
"node": ">=12"
}
},
"node_modules/gensync": { "node_modules/gensync": {
"version": "1.0.0-beta.2", "version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -8044,20 +7977,6 @@
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
"dev": true "dev": true
}, },
"node_modules/https-proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
"integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
"optional": true,
"peer": true,
"dependencies": {
"agent-base": "6",
"debug": "4"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/human-signals": { "node_modules/human-signals": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
@@ -10532,13 +10451,13 @@
} }
}, },
"node_modules/mongoose": { "node_modules/mongoose": {
"version": "8.3.5", "version": "8.5.4",
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.3.5.tgz", "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.4.tgz",
"integrity": "sha512-2zqeAjHjCqT1o5HeUCvkE9tUHsXwemnwEZ2SKnUxsaP8p1a+UcSQSNbnSuOzUVePMwLETrsvLIRdFLjsNfCgWA==", "integrity": "sha512-nG3eehhWf9l1q80WuHvp5DV+4xDNFpDWLE5ZgcFD5tslUV2USJ56ogun8gaZ62MKAocJnoStjAdno08b8U57hg==",
"dependencies": { "dependencies": {
"bson": "^6.5.0", "bson": "^6.7.0",
"kareem": "2.6.3", "kareem": "2.6.3",
"mongodb": "6.5.0", "mongodb": "6.7.0",
"mpath": "0.9.0", "mpath": "0.9.0",
"mquery": "5.0.0", "mquery": "5.0.0",
"ms": "2.1.3", "ms": "2.1.3",
@@ -10553,28 +10472,28 @@
} }
}, },
"node_modules/mongoose/node_modules/@types/whatwg-url": { "node_modules/mongoose/node_modules/@types/whatwg-url": {
"version": "11.0.4", "version": "11.0.5",
"resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.4.tgz", "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz",
"integrity": "sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw==", "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==",
"dependencies": { "dependencies": {
"@types/webidl-conversions": "*" "@types/webidl-conversions": "*"
} }
}, },
"node_modules/mongoose/node_modules/bson": { "node_modules/mongoose/node_modules/bson": {
"version": "6.7.0", "version": "6.8.0",
"resolved": "https://registry.npmjs.org/bson/-/bson-6.7.0.tgz", "resolved": "https://registry.npmjs.org/bson/-/bson-6.8.0.tgz",
"integrity": "sha512-w2IquM5mYzYZv6rs3uN2DZTOBe2a0zXLj53TGDqwF4l6Sz/XsISrisXOJihArF9+BZ6Cq/GjVht7Sjfmri7ytQ==", "integrity": "sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==",
"engines": { "engines": {
"node": ">=16.20.1" "node": ">=16.20.1"
} }
}, },
"node_modules/mongoose/node_modules/mongodb": { "node_modules/mongoose/node_modules/mongodb": {
"version": "6.5.0", "version": "6.7.0",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.5.0.tgz", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.7.0.tgz",
"integrity": "sha512-Fozq68InT+JKABGLqctgtb8P56pRrJFkbhW0ux+x1mdHeyinor8oNzJqwLjV/t5X5nJGfTlluxfyMnOXNggIUA==", "integrity": "sha512-TMKyHdtMcO0fYBNORiYdmM25ijsHs+Njs963r4Tro4OQZzqYigAzYQouwWRg4OIaiLRUEGUh/1UAcH5lxdSLIA==",
"dependencies": { "dependencies": {
"@mongodb-js/saslprep": "^1.1.5", "@mongodb-js/saslprep": "^1.1.5",
"bson": "^6.4.0", "bson": "^6.7.0",
"mongodb-connection-string-url": "^3.0.0" "mongodb-connection-string-url": "^3.0.0"
}, },
"engines": { "engines": {

View File

@@ -23,7 +23,7 @@
"date-fns-tz": "2.0.1", "date-fns-tz": "2.0.1",
"googleapis": "142.0.0", "googleapis": "142.0.0",
"ics": "3.7.6", "ics": "3.7.6",
"mongoose": "8.3.5", "mongoose": "^8.5.4",
"next": "^14.0.1", "next": "^14.0.1",
"next-auth": "4.24.7", "next-auth": "4.24.7",
"next-axiom": "^1.1.0", "next-axiom": "^1.1.0",

View File

@@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import Input from '../../../../components/input' import Input from '../../../../components/input'
import Select from '../../../../components/select' import Select from '../../../../components/select'
import { Booking } from '../../../../db/booking' import { IBooking } from '../../../../db/booking'
import { BILL_STATUS, MILAGE_TARIFS } from '../../../../db/enums' import { BILL_STATUS, MILAGE_TARIFS } from '../../../../db/enums'
import { getMilageMax } from '../../../../db/index' import { getMilageMax } from '../../../../db/index'
import { daysFormatFrontend } from '../../../../helpers/date' import { daysFormatFrontend } from '../../../../helpers/date'
@@ -67,7 +67,7 @@ function BookingBillPage({
booking: bookingProp, booking: bookingProp,
milageMax, milageMax,
}: { }: {
booking: Booking booking: IBooking
milageMax: number milageMax: number
}) { }) {
const [booking, setBooking] = useState(bookingProp) const [booking, setBooking] = useState(bookingProp)
@@ -262,4 +262,4 @@ function BookingBillPage({
BookingBillPage.authenticationRequired = true BookingBillPage.authenticationRequired = true
export default BookingBillPage export default BookingBillPage

View File

@@ -3,7 +3,7 @@ import { useRouter } from 'next/router'
import Link from 'next/link' import Link from 'next/link'
import Calendar from '../../../../components/calendar' import Calendar from '../../../../components/calendar'
import { getServerSideBooking } from '../../../../lib/getServerSideProps' import { getServerSideBooking } from '../../../../lib/getServerSideProps'
import { BookingDocument } from '../../../../db/booking' import { IBooking } from '../../../../db/booking'
import { patchBooking } from '../../../../helpers/booking' import { patchBooking } from '../../../../helpers/booking'
import { log } from '../../../../helpers/log' import { log } from '../../../../helpers/log'
import { BOOKING_STATUS } from '../../../../db/enums' import { BOOKING_STATUS } from '../../../../db/enums'
@@ -11,7 +11,7 @@ import BookingTable from '../../../../components/bookingTable'
export const getServerSideProps = getServerSideBooking export const getServerSideProps = getServerSideBooking
function ShowBookingAdmin({ booking: bookingProp }: { booking: BookingDocument }) { function ShowBookingAdmin({ booking: bookingProp }: { booking: IBooking }) {
const router = useRouter() const router = useRouter()
const [booking, setBooking] = useState(bookingProp) const [booking, setBooking] = useState(bookingProp)
const [storingBooking, setStoringBooking] = useState(false) const [storingBooking, setStoringBooking] = useState(false)

View File

@@ -1,5 +1,5 @@
import { NextApiRequest, NextApiResponse } from 'next' import { NextApiRequest, NextApiResponse } from 'next'
import { Bill } from '../../../../db/bill' import { IBill } from '../../../../db/bill'
import { createBill, patchBill } from '../../../../db/index' import { createBill, patchBill } from '../../../../db/index'
import { log } from '../../../../helpers/log' import { log } from '../../../../helpers/log'
@@ -13,7 +13,7 @@ export default async function billHandler(
} = req } = req
const bookingUUID = Array.isArray(uuids) ? uuids[0] : uuids const bookingUUID = Array.isArray(uuids) ? uuids[0] : uuids
let bill: Bill let bill: IBill
switch (method) { switch (method) {
case 'POST': case 'POST':
@@ -40,4 +40,4 @@ export default async function billHandler(
res.setHeader('Allow', ['POST', 'PATCH']) res.setHeader('Allow', ['POST', 'PATCH'])
res.status(405).end(`Method ${method} Not Allowed`) res.status(405).end(`Method ${method} Not Allowed`)
} }
} }

View File

@@ -1,5 +1,5 @@
import { NextApiRequest, NextApiResponse } from 'next' import { NextApiRequest, NextApiResponse } from 'next'
import { Booking } from '../../../../db/booking' import { IBooking } from '../../../../db/booking'
import { BOOKING_STATUS } from '../../../../db/enums' import { BOOKING_STATUS } from '../../../../db/enums'
import { patchBooking } from '../../../../db/index' import { patchBooking } from '../../../../db/index'
import { import {
@@ -10,8 +10,8 @@ import {
import { log } from '../../../../helpers/log' import { log } from '../../../../helpers/log'
function changedStatus( function changedStatus(
previous: Booking, previous: IBooking,
current: Partial<Booking>, current: Partial<IBooking>,
status: BOOKING_STATUS status: BOOKING_STATUS
): boolean { ): boolean {
return ( return (
@@ -19,15 +19,15 @@ function changedStatus(
current.status === status current.status === status
) )
} }
function wasRejected(previous: Booking, current: Partial<Booking>): boolean { function wasRejected(previous: IBooking, current: Partial<IBooking>): boolean {
return changedStatus(previous, current, BOOKING_STATUS.REJECTED) return changedStatus(previous, current, BOOKING_STATUS.REJECTED)
} }
function wasConfirmed(previous: Booking, current: Partial<Booking>): boolean { function wasConfirmed(previous: IBooking, current: Partial<IBooking>): boolean {
return changedStatus(previous, current, BOOKING_STATUS.CONFIRMED) return changedStatus(previous, current, BOOKING_STATUS.CONFIRMED)
} }
function wasCanceled(previous: Booking, current: Partial<Booking>): boolean { function wasCanceled(previous: IBooking, current: Partial<IBooking>): boolean {
return ( return (
[BOOKING_STATUS.REQUESTED, BOOKING_STATUS.CONFIRMED].includes( [BOOKING_STATUS.REQUESTED, BOOKING_STATUS.CONFIRMED].includes(
previous.status previous.status

View File

@@ -1,6 +1,6 @@
import { Error } from 'mongoose' import { Error } from 'mongoose'
import { NextApiRequest, NextApiResponse } from 'next' import { NextApiRequest, NextApiResponse } from 'next'
import { Booking } from '../../../db/booking' import { IBooking } from '../../../db/booking'
import { createBooking } from '../../../db/index' import { createBooking } from '../../../db/index'
import { log } from '../../../helpers/log' import { log } from '../../../helpers/log'
import { import {
@@ -14,7 +14,7 @@ export default async function userHandler(
): Promise<void> { ): Promise<void> {
const { method } = req const { method } = req
let booking: Booking let booking: IBooking
switch (method) { switch (method) {
case 'POST': case 'POST':

View File

@@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { getServerSideBooking } from '../../../lib/getServerSideProps' import { getServerSideBooking } from '../../../lib/getServerSideProps'
import { Booking } from '../../../db/booking' import { IBooking } from '../../../db/booking'
import { BOOKING_STATUS } from '../../../db/enums' import { BOOKING_STATUS } from '../../../db/enums'
import { daysFormatFrontend } from '../../../helpers/date' import { daysFormatFrontend } from '../../../helpers/date'
import { log } from '../../../helpers/log' import { log } from '../../../helpers/log'
@@ -11,7 +11,7 @@ export const getServerSideProps = getServerSideBooking
export default function ShowBooking({ export default function ShowBooking({
booking: bookingProp, booking: bookingProp,
}: { }: {
booking: Booking booking: IBooking
}) { }) {
const [booking, setBooking] = useState(bookingProp) const [booking, setBooking] = useState(bookingProp)
const [storingBooking, setStoringBooking] = useState(false) const [storingBooking, setStoringBooking] = useState(false)
@@ -65,4 +65,4 @@ export default function ShowBooking({
)} )}
</> </>
) )
} }

View File

@@ -1,12 +1,12 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import Link from 'next/link' import Link from 'next/link'
import { Booking } from '../../../db/booking' import { IBooking } from '../../../db/booking'
import { loadBookingData, storeBookingData } from '../../../helpers/storage' import { loadBookingData, storeBookingData } from '../../../helpers/storage'
import { getServerSideBooking } from '../../../lib/getServerSideProps' import { getServerSideBooking } from '../../../lib/getServerSideProps'
export const getServerSideProps = getServerSideBooking export const getServerSideProps = getServerSideBooking
export default function ShowBookingStored({ booking }: { booking: Booking }) { export default function ShowBookingStored({ booking }: { booking: IBooking }) {
const [storedBookingData, setStoredBookingData] = useState(null) const [storedBookingData, setStoredBookingData] = useState(null)
const [bookingDataStored, setBookingDataStored] = useState(false) const [bookingDataStored, setBookingDataStored] = useState(false)
@@ -53,4 +53,4 @@ export default function ShowBookingStored({ booking }: { booking: Booking }) {
)} )}
</> </>
) )
} }