mirror of
https://github.com/tomru/pfadi-bussle.git
synced 2026-03-04 15:07:13 +01:00
It also brings the problem of consolidating bookers over multiple bookings. The amount of data is not justifying having it in an own entity
110 lines
3.3 KiB
TypeScript
110 lines
3.3 KiB
TypeScript
import React, { useEffect, useState } from 'react'
|
|
import { GetServerSideProps } from 'next'
|
|
import { useRouter } from 'next/router'
|
|
import Link from 'next/link'
|
|
import Footer from '../../../../components/footer'
|
|
import Header from '../../../../components/header'
|
|
import Calendar from '../../../../components/calendar'
|
|
import withSession, {
|
|
isAdminSession,
|
|
redirectToLogin,
|
|
} from '../../../../lib/session'
|
|
import { getServerSideBooking } from '../../../../lib/getServerSideProps'
|
|
import { Booking } from '../../../../db/booking'
|
|
import { getBookingStatus, patchBooking } from '../../../../helpers/booking'
|
|
import { daysFormatFrontend } from '../../../../helpers/date'
|
|
import { BOOKING_STATUS } from '../../../../db/enums'
|
|
|
|
export const getServerSideProps: GetServerSideProps = withSession(
|
|
async (context) => {
|
|
const { req, res } = context
|
|
|
|
const adminUser = isAdminSession(req)
|
|
|
|
if (!adminUser) {
|
|
redirectToLogin(req, res)
|
|
return { props: {} }
|
|
}
|
|
|
|
const result = await getServerSideBooking(context)
|
|
return {
|
|
...result,
|
|
// TODO: have a closer look at this type issue. Seems like a bug
|
|
// @ts-ignore
|
|
props: { ...result.props, user: adminUser },
|
|
}
|
|
}
|
|
)
|
|
|
|
export default function ShowBookingAdmin({
|
|
booking: bookingProp,
|
|
}: {
|
|
booking: Booking
|
|
}) {
|
|
const router = useRouter()
|
|
const [booking, setBooking] = useState(bookingProp)
|
|
const [storingBooking, setStoringBooking] = useState(false)
|
|
const [storingBookingError, setStoringBookingError] = useState(null)
|
|
|
|
// in case the props change, update the internal state
|
|
useEffect(() => setBooking(bookingProp), [bookingProp])
|
|
|
|
const onStoreBooking = async (confirmed: boolean) => {
|
|
try {
|
|
setStoringBookingError(null)
|
|
setStoringBooking(true)
|
|
const updatedBooking = await patchBooking(booking.uuid, {
|
|
status: confirmed ? BOOKING_STATUS.CONFIRMED : BOOKING_STATUS.REJECTED,
|
|
})
|
|
setBooking(updatedBooking)
|
|
} catch (error) {
|
|
setStoringBookingError('Buchung konnte nicht gespeichert werden.')
|
|
console.error('Failed to store booking', error)
|
|
}
|
|
setStoringBooking(false)
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<Header />
|
|
<main className="main py-3">
|
|
<h2 className="text-3xl">Buchung {booking.uuid}</h2>
|
|
<Calendar start={booking.startDate} end={booking.endDate} />
|
|
<div>
|
|
<strong>Buchungszeitraum:</strong> {daysFormatFrontend(booking.days)}
|
|
</div>
|
|
<div>
|
|
<strong>Bucher:</strong> {booking.name}
|
|
</div>
|
|
<div>
|
|
<strong>Buchungsstatus:</strong> {getBookingStatus(booking.status)}
|
|
</div>
|
|
{storingBookingError && (
|
|
<div className="error-message flex-grow">{storingBookingError}</div>
|
|
)}
|
|
<div className="my-6">
|
|
<button
|
|
onClick={() => onStoreBooking(true)}
|
|
className="btn btn-blue"
|
|
disabled={storingBooking}
|
|
>
|
|
Buchung Bestätigen
|
|
</button>
|
|
<button
|
|
onClick={() => onStoreBooking(false)}
|
|
className="btn btn-red"
|
|
disabled={storingBooking}
|
|
>
|
|
Buchung Abweisen
|
|
</button>
|
|
<Link href={`${router.asPath}/bill`}>
|
|
<a className="btn btn-gray">Rechnung</a>
|
|
</Link>
|
|
</div>
|
|
</main>
|
|
|
|
<Footer />
|
|
</>
|
|
)
|
|
}
|