Files
myeasycms-v2/apps/web/app/[locale]/home/[account]/bookings/new/page.tsx
2026-03-29 19:44:57 +02:00

236 lines
8.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Link from 'next/link';
import { ArrowLeft, BedDouble } from 'lucide-react';
import { getSupabaseServerClient } from '@kit/supabase/server-client';
import { Button } from '@kit/ui/button';
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@kit/ui/card';
import { createBookingManagementApi } from '@kit/booking-management/api';
import { CmsPageShell } from '~/components/cms-page-shell';
interface PageProps {
params: Promise<{ account: string }>;
}
export default async function NewBookingPage({ params }: PageProps) {
const { account } = await params;
const client = getSupabaseServerClient();
const { data: acct } = await client
.from('accounts')
.select('id')
.eq('slug', account)
.single();
if (!acct) return <div>Konto nicht gefunden</div>;
const api = createBookingManagementApi(client);
const [rooms, guests] = await Promise.all([
api.listRooms(acct.id),
api.listGuests(acct.id),
]);
return (
<CmsPageShell account={account} title="Neue Buchung">
<div className="flex w-full flex-col gap-6">
{/* Header */}
<div className="flex items-center gap-4">
<Link href={`/home/${account}/bookings`}>
<Button variant="ghost" size="icon">
<ArrowLeft className="h-4 w-4" />
</Button>
</Link>
<div>
<h1 className="text-2xl font-bold">Neue Buchung</h1>
<p className="text-muted-foreground">
Buchung für ein Zimmer erstellen
</p>
</div>
</div>
<form className="flex flex-col gap-6">
{/* Zimmer & Gast */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<BedDouble className="h-5 w-5" />
Zimmer &amp; Gast
</CardTitle>
<CardDescription>
Wählen Sie Zimmer und Gast für die Buchung aus
</CardDescription>
</CardHeader>
<CardContent className="grid grid-cols-1 gap-4 md:grid-cols-2">
<div className="flex flex-col gap-1.5">
<label
htmlFor="room_id"
className="text-sm font-medium"
>
Zimmer
</label>
<select
id="room_id"
name="room_id"
required
className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
>
<option value="">Zimmer wählen</option>
{rooms.map((room: Record<string, unknown>) => (
<option key={String(room.id)} value={String(room.id)}>
{String(room.room_number)} {String(room.name ?? room.room_type ?? '')}
</option>
))}
</select>
</div>
<div className="flex flex-col gap-1.5">
<label
htmlFor="guest_id"
className="text-sm font-medium"
>
Gast
</label>
<select
id="guest_id"
name="guest_id"
required
className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
>
<option value="">Gast wählen</option>
{guests.map((guest: Record<string, unknown>) => (
<option key={String(guest.id)} value={String(guest.id)}>
{String(guest.last_name)}, {String(guest.first_name)}
{guest.email ? ` (${String(guest.email)})` : ''}
</option>
))}
</select>
</div>
</CardContent>
</Card>
{/* Aufenthalt */}
<Card>
<CardHeader>
<CardTitle>Aufenthalt</CardTitle>
<CardDescription>
Reisedaten und Personenanzahl
</CardDescription>
</CardHeader>
<CardContent className="grid grid-cols-1 gap-4 md:grid-cols-2">
<div className="flex flex-col gap-1.5">
<label htmlFor="check_in" className="text-sm font-medium">
Anreise
</label>
<input
id="check_in"
name="check_in"
type="date"
required
className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
/>
</div>
<div className="flex flex-col gap-1.5">
<label htmlFor="check_out" className="text-sm font-medium">
Abreise
</label>
<input
id="check_out"
name="check_out"
type="date"
required
className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
/>
</div>
<div className="flex flex-col gap-1.5">
<label htmlFor="adults" className="text-sm font-medium">
Erwachsene
</label>
<input
id="adults"
name="adults"
type="number"
min={1}
defaultValue={1}
required
className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
/>
</div>
<div className="flex flex-col gap-1.5">
<label htmlFor="children" className="text-sm font-medium">
Kinder
</label>
<input
id="children"
name="children"
type="number"
min={0}
defaultValue={0}
className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
/>
</div>
</CardContent>
</Card>
{/* Preis & Notizen */}
<Card>
<CardHeader>
<CardTitle>Preis &amp; Notizen</CardTitle>
</CardHeader>
<CardContent className="flex flex-col gap-4">
<div className="flex flex-col gap-1.5 md:w-1/2">
<label htmlFor="total_price" className="text-sm font-medium">
Preis ()
</label>
<input
id="total_price"
name="total_price"
type="number"
step="0.01"
min={0}
placeholder="0.00"
className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
/>
</div>
<div className="flex flex-col gap-1.5">
<label htmlFor="notes" className="text-sm font-medium">
Notizen
</label>
<textarea
id="notes"
name="notes"
rows={3}
placeholder="Zusätzliche Informationen zur Buchung…"
className="flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
/>
</div>
</CardContent>
</Card>
{/* Actions */}
<div className="flex items-center justify-end gap-3">
<Link href={`/home/${account}/bookings`}>
<Button type="button" variant="outline">
Abbrechen
</Button>
</Link>
<Button type="submit">Buchung erstellen</Button>
</div>
</form>
</div>
</CmsPageShell>
);
}