fix: harden booking and meeting flows
This commit is contained in:
@@ -27,6 +27,7 @@ export function BookingWidget({
|
||||
}) {
|
||||
const [slotsByDay, setSlotsByDay] = useState<SlotsResponse["slots"]>({});
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [loadError, setLoadError] = useState(false);
|
||||
const [selectedDay, setSelectedDay] = useState<Date | null>(null);
|
||||
const [selectedSlot, setSelectedSlot] = useState<string | null>(null);
|
||||
const [appointmentType, setAppointmentType] = useState<"onsite" | "online">("onsite");
|
||||
@@ -35,12 +36,15 @@ export function BookingWidget({
|
||||
const [result, setResult] = useState<{ ok: boolean; error?: string } | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const controller = new AbortController();
|
||||
const from = new Date();
|
||||
const to = new Date(from.getTime() + 28 * 24 * 60 * 60 * 1000);
|
||||
fetch(`/api/booking/slots?offer=${encodeURIComponent(offerSlug)}&from=${dateKey(from)}&to=${dateKey(to)}`)
|
||||
.then((res) => res.json())
|
||||
fetch(`/api/booking/slots?offer=${encodeURIComponent(offerSlug)}&from=${dateKey(from)}&to=${dateKey(to)}`, { signal: controller.signal })
|
||||
.then((res) => { if (!res.ok) throw new Error("Slots unavailable"); return res.json(); })
|
||||
.then((data: SlotsResponse) => setSlotsByDay(data.slots ?? {}))
|
||||
.finally(() => setLoading(false));
|
||||
.catch(() => { if (!controller.signal.aborted) setLoadError(true); })
|
||||
.finally(() => { if (!controller.signal.aborted) setLoading(false); });
|
||||
return () => controller.abort();
|
||||
}, [offerSlug]);
|
||||
|
||||
if (result?.ok) {
|
||||
@@ -126,11 +130,12 @@ export function BookingWidget({
|
||||
if (loading) {
|
||||
return <p className="text-sm text-anouma-plum/70">Verfügbare Termine werden geladen …</p>;
|
||||
}
|
||||
if (loadError) return <FormError>Verfügbare Termine konnten nicht geladen werden. Bitte lade die Seite erneut.</FormError>;
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="grid gap-6 lg:grid-cols-[minmax(0,340px)_1fr]">
|
||||
<MonthCalendar markers={markers} onSelectDay={setSelectedDay} selectedDay={selectedDay} />
|
||||
<MonthCalendar markers={markers} onSelectDay={(day) => { setSelectedDay(day); setSelectedSlot(null); }} selectedDay={selectedDay} />
|
||||
<div>
|
||||
{!selectedDay && <p className="text-sm text-anouma-plum/70">Wähle einen markierten Tag, um freie Zeiten zu sehen.</p>}
|
||||
{selectedDay && daySlots.length === 0 && (
|
||||
|
||||
Reference in New Issue
Block a user