import type { Payload } from "payload"; import type { BookingRequest, Customer, Event, Offer } from "@/payload-types"; export type AdminCalendarItem = { id: string; kind: "booking" | "event"; title: string; subtitle?: string; date: string; startTime: string; endTime: string; status: string; // booking status, or "public" for a standalone Event appointmentType?: "onsite" | "online"; href: string; }; /** * Combines private BookingRequests with standalone public Events (excluding * the auto-generated Events already represented by a confirmed online * booking, so Anna never sees the same appointment listed twice) into one * unified calendar feed for the admin view. */ export async function getAdminCalendarItems( payload: Payload, range: { from: Date; to: Date }, ): Promise { const fromISO = range.from.toISOString(); const toISO = range.to.toISOString(); const [{ docs: bookings }, { docs: events }] = await Promise.all([ payload.find({ collection: "booking-requests", where: { and: [{ date: { greater_than_equal: fromISO } }, { date: { less_than_equal: toISO } }] }, depth: 2, limit: 500, }), payload.find({ collection: "events", where: { and: [ { date: { greater_than_equal: fromISO } }, { date: { less_than_equal: toISO } }, { isPrivateBooking: { not_equals: true } }, ], }, depth: 0, limit: 500, }), ]); const bookingItems: AdminCalendarItem[] = (bookings as BookingRequest[]).map((b) => { const offer = typeof b.offer === "object" ? (b.offer as Offer) : null; const customer = typeof b.user === "object" ? (b.user as Customer) : null; return { id: `booking-${b.id}`, kind: "booking", title: offer?.title ?? "Buchung", subtitle: customer?.name, date: b.date, startTime: b.startTime, endTime: b.endTime, status: b.status, appointmentType: b.appointmentType, href: `/admin/collections/booking-requests/${b.id}`, }; }); const eventItems: AdminCalendarItem[] = (events as Event[]).map((e) => ({ id: `event-${e.id}`, kind: "event", title: e.title, date: e.date, startTime: e.startTime ?? e.date, endTime: e.endTime ?? e.date, status: "public", appointmentType: e.isOnline ? "online" : "onsite", href: `/admin/collections/events/${e.id}`, })); return [...bookingItems, ...eventItems].sort((a, b) => new Date(a.startTime).getTime() - new Date(b.startTime).getTime()); }