@withpotter/pages-bookings 0.13.0-next.101
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dashboard/(bookings)/attendees/page.js +8 -0
- package/dist/dashboard/(bookings)/attendees/page.js.map +1 -0
- package/dist/dashboard/(bookings)/availability/_components/availability-screen.js +714 -0
- package/dist/dashboard/(bookings)/availability/_components/availability-screen.js.map +1 -0
- package/dist/dashboard/(bookings)/availability/_components/month-availability.js +130 -0
- package/dist/dashboard/(bookings)/availability/_components/month-availability.js.map +1 -0
- package/dist/dashboard/(bookings)/availability/page.js +10 -0
- package/dist/dashboard/(bookings)/availability/page.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/assign-resource-modal.js +133 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/assign-resource-modal.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-constants.js +26 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-constants.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-desktop-layout.js +194 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-desktop-layout.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-layout-props.js +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-layout-props.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-lede.js +189 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-lede.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-meta.js +38 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-meta.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-mobile-layout.js +315 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-mobile-layout.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-mobile-screen.js +94 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-mobile-screen.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-money.js +54 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-money.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-split.js +71 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-split.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/cancel-booking-modal.js +102 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/cancel-booking-modal.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/cancellation-notice.js +33 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/cancellation-notice.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/customer-info-card.js +65 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/customer-info-card.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/index.js +23 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/index.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/intake-answers-card.js +19 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/intake-answers-card.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/refund-booking-modal.js +156 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/refund-booking-modal.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/reschedule-booking-modal.js +120 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/reschedule-booking-modal.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/security-deposit-card.js +63 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/security-deposit-card.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/settle-deposit-modal.js +141 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/settle-deposit-modal.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/ticket-row-actions.js +49 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/ticket-row-actions.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/waiting-queue-notice.js +42 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/waiting-queue-notice.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_components.js +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_hooks/index.js +19 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_hooks/index.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_hooks/use-booking-detail-data.js +352 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_hooks/use-booking-detail-data.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/_hooks.js +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/layout.js +33 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/layout.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/page.js +356 -0
- package/dist/dashboard/(bookings)/bookings/[bookingId]/page.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/appointment-calendar-layout.js +34 -0
- package/dist/dashboard/(bookings)/bookings/_components/appointment-calendar-layout.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/booking-constants.js +92 -0
- package/dist/dashboard/(bookings)/bookings/_components/booking-constants.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/booking-tab-hints.js +32 -0
- package/dist/dashboard/(bookings)/bookings/_components/booking-tab-hints.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/bookings-filter-bar.js +131 -0
- package/dist/dashboard/(bookings)/bookings/_components/bookings-filter-bar.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/bookings-mobile-controls.js +119 -0
- package/dist/dashboard/(bookings)/bookings/_components/bookings-mobile-controls.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/bookings-screen.js +414 -0
- package/dist/dashboard/(bookings)/bookings/_components/bookings-screen.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/bookings-table.js +192 -0
- package/dist/dashboard/(bookings)/bookings/_components/bookings-table.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/cannot-take-bookings.js +34 -0
- package/dist/dashboard/(bookings)/bookings/_components/cannot-take-bookings.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/demo-data.js +176 -0
- package/dist/dashboard/(bookings)/bookings/_components/demo-data.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/index.js +9 -0
- package/dist/dashboard/(bookings)/bookings/_components/index.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/today/booking-card.js +126 -0
- package/dist/dashboard/(bookings)/bookings/_components/today/booking-card.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/today/demo-data.js +142 -0
- package/dist/dashboard/(bookings)/bookings/_components/today/demo-data.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/today/handover.js +128 -0
- package/dist/dashboard/(bookings)/bookings/_components/today/handover.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/today/index.js +17 -0
- package/dist/dashboard/(bookings)/bookings/_components/today/index.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/today/past-band.js +69 -0
- package/dist/dashboard/(bookings)/bookings/_components/today/past-band.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/today/resource-board.js +111 -0
- package/dist/dashboard/(bookings)/bookings/_components/today/resource-board.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/today/today-band.js +61 -0
- package/dist/dashboard/(bookings)/bookings/_components/today/today-band.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/today/upcoming-band.js +113 -0
- package/dist/dashboard/(bookings)/bookings/_components/today/upcoming-band.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/today/waiting-queue.js +62 -0
- package/dist/dashboard/(bookings)/bookings/_components/today/waiting-queue.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/today-board.js +192 -0
- package/dist/dashboard/(bookings)/bookings/_components/today-board.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_components/today.js +1 -0
- package/dist/dashboard/(bookings)/bookings/_components.js +1 -0
- package/dist/dashboard/(bookings)/bookings/_hooks/index.js +5 -0
- package/dist/dashboard/(bookings)/bookings/_hooks/index.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_hooks/use-bookings-data.js +331 -0
- package/dist/dashboard/(bookings)/bookings/_hooks/use-bookings-data.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_hooks/use-today-data.js +309 -0
- package/dist/dashboard/(bookings)/bookings/_hooks/use-today-data.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/_hooks.js +1 -0
- package/dist/dashboard/(bookings)/bookings/_lib/booking-link.js +13 -0
- package/dist/dashboard/(bookings)/bookings/_lib/booking-link.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/attendees/_components/attendee-cards.js +60 -0
- package/dist/dashboard/(bookings)/bookings/attendees/_components/attendee-cards.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/attendees/_components/qr-scanner-modal.js +225 -0
- package/dist/dashboard/(bookings)/bookings/attendees/_components/qr-scanner-modal.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/attendees/demo-data.js +195 -0
- package/dist/dashboard/(bookings)/bookings/attendees/demo-data.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/attendees/page.js +341 -0
- package/dist/dashboard/(bookings)/bookings/attendees/page.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/new/page.js +129 -0
- package/dist/dashboard/(bookings)/bookings/new/page.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/page.js +10 -0
- package/dist/dashboard/(bookings)/bookings/page.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/sessions/new/_components/save-buttons.js +36 -0
- package/dist/dashboard/(bookings)/bookings/sessions/new/_components/save-buttons.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/sessions/new/_components/session-creator.js +386 -0
- package/dist/dashboard/(bookings)/bookings/sessions/new/_components/session-creator.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/sessions/new/_lib/session-payload.js +62 -0
- package/dist/dashboard/(bookings)/bookings/sessions/new/_lib/session-payload.js.map +1 -0
- package/dist/dashboard/(bookings)/bookings/sessions/new/page.js +10 -0
- package/dist/dashboard/(bookings)/bookings/sessions/new/page.js.map +1 -0
- package/dist/dashboard/(bookings)/calendar/_components/calendar-nav.js +84 -0
- package/dist/dashboard/(bookings)/calendar/_components/calendar-nav.js.map +1 -0
- package/dist/dashboard/(bookings)/calendar/_components/calendar-range.js +84 -0
- package/dist/dashboard/(bookings)/calendar/_components/calendar-range.js.map +1 -0
- package/dist/dashboard/(bookings)/calendar/_components/day-board-view.js +279 -0
- package/dist/dashboard/(bookings)/calendar/_components/day-board-view.js.map +1 -0
- package/dist/dashboard/(bookings)/calendar/_components/event-detail-modal.js +113 -0
- package/dist/dashboard/(bookings)/calendar/_components/event-detail-modal.js.map +1 -0
- package/dist/dashboard/(bookings)/calendar/_components/format.js +22 -0
- package/dist/dashboard/(bookings)/calendar/_components/format.js.map +1 -0
- package/dist/dashboard/(bookings)/calendar/_components/month-grid.js +109 -0
- package/dist/dashboard/(bookings)/calendar/_components/month-grid.js.map +1 -0
- package/dist/dashboard/(bookings)/calendar/_components/resource-day-grid.js +325 -0
- package/dist/dashboard/(bookings)/calendar/_components/resource-day-grid.js.map +1 -0
- package/dist/dashboard/(bookings)/calendar/_components/slot-action-sheet.js +209 -0
- package/dist/dashboard/(bookings)/calendar/_components/slot-action-sheet.js.map +1 -0
- package/dist/dashboard/(bookings)/calendar/_components/use-block-drag.js +77 -0
- package/dist/dashboard/(bookings)/calendar/_components/use-block-drag.js.map +1 -0
- package/dist/dashboard/(bookings)/calendar/_components/use-calendar-nav.js +69 -0
- package/dist/dashboard/(bookings)/calendar/_components/use-calendar-nav.js.map +1 -0
- package/dist/dashboard/(bookings)/calendar/_components/week-grid.js +202 -0
- package/dist/dashboard/(bookings)/calendar/_components/week-grid.js.map +1 -0
- package/dist/dashboard/(bookings)/calendar/_components/year-grid.js +111 -0
- package/dist/dashboard/(bookings)/calendar/_components/year-grid.js.map +1 -0
- package/dist/dashboard/(bookings)/calendar/page.js +8 -0
- package/dist/dashboard/(bookings)/calendar/page.js.map +1 -0
- package/dist/dashboard/(bookings)/calendar-sync/_components/channel-feed-modal.js +126 -0
- package/dist/dashboard/(bookings)/calendar-sync/_components/channel-feed-modal.js.map +1 -0
- package/dist/dashboard/(bookings)/calendar-sync/_components/channel-feeds-section.js +99 -0
- package/dist/dashboard/(bookings)/calendar-sync/_components/channel-feeds-section.js.map +1 -0
- package/dist/dashboard/(bookings)/calendar-sync/demo-data.js +64 -0
- package/dist/dashboard/(bookings)/calendar-sync/demo-data.js.map +1 -0
- package/dist/dashboard/(bookings)/calendar-sync/page.js +15 -0
- package/dist/dashboard/(bookings)/calendar-sync/page.js.map +1 -0
- package/dist/dashboard/(bookings)/check-in/page.js +252 -0
- package/dist/dashboard/(bookings)/check-in/page.js.map +1 -0
- package/dist/dashboard/(bookings)/events/[eventId]/_components/event-attendees.js +108 -0
- package/dist/dashboard/(bookings)/events/[eventId]/_components/event-attendees.js.map +1 -0
- package/dist/dashboard/(bookings)/events/[eventId]/_components/event-share.js +73 -0
- package/dist/dashboard/(bookings)/events/[eventId]/_components/event-share.js.map +1 -0
- package/dist/dashboard/(bookings)/events/[eventId]/layout.js +10 -0
- package/dist/dashboard/(bookings)/events/[eventId]/layout.js.map +1 -0
- package/dist/dashboard/(bookings)/events/[eventId]/page.js +247 -0
- package/dist/dashboard/(bookings)/events/[eventId]/page.js.map +1 -0
- package/dist/dashboard/(bookings)/events/_components/event-grid.js +44 -0
- package/dist/dashboard/(bookings)/events/_components/event-grid.js.map +1 -0
- package/dist/dashboard/(bookings)/events/_components/event-poster.js +17 -0
- package/dist/dashboard/(bookings)/events/_components/event-poster.js.map +1 -0
- package/dist/dashboard/(bookings)/events/_hooks/use-events-data.js +55 -0
- package/dist/dashboard/(bookings)/events/_hooks/use-events-data.js.map +1 -0
- package/dist/dashboard/(bookings)/events/_lib/event-facts.js +68 -0
- package/dist/dashboard/(bookings)/events/_lib/event-facts.js.map +1 -0
- package/dist/dashboard/(bookings)/events/new/_components/event-composer.js +295 -0
- package/dist/dashboard/(bookings)/events/new/_components/event-composer.js.map +1 -0
- package/dist/dashboard/(bookings)/events/new/_components/event-poster.js +65 -0
- package/dist/dashboard/(bookings)/events/new/_components/event-poster.js.map +1 -0
- package/dist/dashboard/(bookings)/events/new/_components/ticket-tiers.js +75 -0
- package/dist/dashboard/(bookings)/events/new/_components/ticket-tiers.js.map +1 -0
- package/dist/dashboard/(bookings)/events/new/page.js +10 -0
- package/dist/dashboard/(bookings)/events/new/page.js.map +1 -0
- package/dist/dashboard/(bookings)/events/page.js +214 -0
- package/dist/dashboard/(bookings)/events/page.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/[resourceId]/layout.js +36 -0
- package/dist/dashboard/(bookings)/resources/[resourceId]/layout.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/[resourceId]/page.js +351 -0
- package/dist/dashboard/(bookings)/resources/[resourceId]/page.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components/block-time-modal.js +130 -0
- package/dist/dashboard/(bookings)/resources/_components/block-time-modal.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components/category-card.js +74 -0
- package/dist/dashboard/(bookings)/resources/_components/category-card.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components/category-form-dialog.js +197 -0
- package/dist/dashboard/(bookings)/resources/_components/category-form-dialog.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components/day-editor.js +194 -0
- package/dist/dashboard/(bookings)/resources/_components/day-editor.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components/group-dialog.js +170 -0
- package/dist/dashboard/(bookings)/resources/_components/group-dialog.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components/group-header.js +90 -0
- package/dist/dashboard/(bookings)/resources/_components/group-header.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components/index.js +22 -0
- package/dist/dashboard/(bookings)/resources/_components/index.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components/mobile-category-form-sheet.js +256 -0
- package/dist/dashboard/(bookings)/resources/_components/mobile-category-form-sheet.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components/resource-form.js +420 -0
- package/dist/dashboard/(bookings)/resources/_components/resource-form.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components/resource-picker.js +144 -0
- package/dist/dashboard/(bookings)/resources/_components/resource-picker.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components/resource-type-picker-empty.js +109 -0
- package/dist/dashboard/(bookings)/resources/_components/resource-type-picker-empty.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components/roster-empty.js +103 -0
- package/dist/dashboard/(bookings)/resources/_components/roster-empty.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components/roster-grid.js +160 -0
- package/dist/dashboard/(bookings)/resources/_components/roster-grid.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components/schedule-editor.js +244 -0
- package/dist/dashboard/(bookings)/resources/_components/schedule-editor.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components/schedule-timezone-field.js +25 -0
- package/dist/dashboard/(bookings)/resources/_components/schedule-timezone-field.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components/solo-schedule-view.js +146 -0
- package/dist/dashboard/(bookings)/resources/_components/solo-schedule-view.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components/team-onboarding-dialog.js +161 -0
- package/dist/dashboard/(bookings)/resources/_components/team-onboarding-dialog.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components/week-grid.js +175 -0
- package/dist/dashboard/(bookings)/resources/_components/week-grid.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_components.js +1 -0
- package/dist/dashboard/(bookings)/resources/_hooks/index.js +8 -0
- package/dist/dashboard/(bookings)/resources/_hooks/index.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_hooks/use-resource-categories-data.js +86 -0
- package/dist/dashboard/(bookings)/resources/_hooks/use-resource-categories-data.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_hooks/use-roster-page.js +138 -0
- package/dist/dashboard/(bookings)/resources/_hooks/use-roster-page.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_hooks/use-roster.js +182 -0
- package/dist/dashboard/(bookings)/resources/_hooks/use-roster.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_hooks.js +1 -0
- package/dist/dashboard/(bookings)/resources/_lib/presets.js +147 -0
- package/dist/dashboard/(bookings)/resources/_lib/presets.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_lib/schedule-timezone.js +17 -0
- package/dist/dashboard/(bookings)/resources/_lib/schedule-timezone.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_lib/shapes.js +105 -0
- package/dist/dashboard/(bookings)/resources/_lib/shapes.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/_lib/week.js +122 -0
- package/dist/dashboard/(bookings)/resources/_lib/week.js.map +1 -0
- package/dist/dashboard/(bookings)/resources/page.js +391 -0
- package/dist/dashboard/(bookings)/resources/page.js.map +1 -0
- package/dist/dashboard/(bookings)/schedule/page.js +8 -0
- package/dist/dashboard/(bookings)/schedule/page.js.map +1 -0
- package/dist/dashboard/(bookings)/today/page.js +14 -0
- package/dist/dashboard/(bookings)/today/page.js.map +1 -0
- package/dist/dashboard/(bookings)/waitlist/_components/demo-data.js +99 -0
- package/dist/dashboard/(bookings)/waitlist/_components/demo-data.js.map +1 -0
- package/dist/dashboard/(bookings)/waitlist/_components/offer-spot-modal.js +71 -0
- package/dist/dashboard/(bookings)/waitlist/_components/offer-spot-modal.js.map +1 -0
- package/dist/dashboard/(bookings)/waitlist/_components/waitlist-entry-editor.js +150 -0
- package/dist/dashboard/(bookings)/waitlist/_components/waitlist-entry-editor.js.map +1 -0
- package/dist/dashboard/(bookings)/waitlist/new/page.js +59 -0
- package/dist/dashboard/(bookings)/waitlist/new/page.js.map +1 -0
- package/dist/dashboard/(bookings)/waitlist/page.js +317 -0
- package/dist/dashboard/(bookings)/waitlist/page.js.map +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import Link from "next/link";
|
|
3
|
+
import {
|
|
4
|
+
Calendar,
|
|
5
|
+
ChevronDown,
|
|
6
|
+
ChevronRight,
|
|
7
|
+
Download,
|
|
8
|
+
Globe,
|
|
9
|
+
QrCode,
|
|
10
|
+
Ticket,
|
|
11
|
+
User,
|
|
12
|
+
Users,
|
|
13
|
+
Video
|
|
14
|
+
} from "lucide-react";
|
|
15
|
+
import { bookingsApi } from "@withpotter/lib/api/bookings";
|
|
16
|
+
import { joinLabelOf, meetingLinkOf } from "@withpotter/lib/booking-meeting-link";
|
|
17
|
+
import {
|
|
18
|
+
useBookingStatusConfig,
|
|
19
|
+
formatDateTime,
|
|
20
|
+
formatFullDate,
|
|
21
|
+
formatTime
|
|
22
|
+
} from "../_hooks";
|
|
23
|
+
import {
|
|
24
|
+
BOOKING_MODE_LABELS,
|
|
25
|
+
BOOKING_ORIGIN_LABELS,
|
|
26
|
+
BOOKING_TYPE_LABELS
|
|
27
|
+
} from "./booking-constants";
|
|
28
|
+
import { BookingMoney } from "./booking-money";
|
|
29
|
+
import { BookingSplit } from "./booking-split";
|
|
30
|
+
import { Badge } from "@withpotter/ui-kit";
|
|
31
|
+
import { StatusBadge } from "@withpotter/components/shared/status-badge";
|
|
32
|
+
import { TicketRowActions } from "./ticket-row-actions";
|
|
33
|
+
import { resolveTicketCode } from "@withpotter/lib/ticket-access";
|
|
34
|
+
function BookingMobileLayout({
|
|
35
|
+
booking,
|
|
36
|
+
tickets,
|
|
37
|
+
statusConfig,
|
|
38
|
+
formatCurrency,
|
|
39
|
+
isPaid,
|
|
40
|
+
bookingAmount,
|
|
41
|
+
bookingTotal,
|
|
42
|
+
paidAmount,
|
|
43
|
+
split,
|
|
44
|
+
paymentReference,
|
|
45
|
+
paidAt,
|
|
46
|
+
allowedTransitions,
|
|
47
|
+
updatingStatus,
|
|
48
|
+
showStatusDropdown,
|
|
49
|
+
setShowStatusDropdown,
|
|
50
|
+
handleStatusUpdate,
|
|
51
|
+
bookingSingular,
|
|
52
|
+
tenant,
|
|
53
|
+
securityDeposit
|
|
54
|
+
}) {
|
|
55
|
+
const statuses = useBookingStatusConfig();
|
|
56
|
+
const meetingLink = meetingLinkOf(booking);
|
|
57
|
+
return /* @__PURE__ */ jsxs("div", { className: "lg:hidden space-y-4", children: [
|
|
58
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
59
|
+
/* @__PURE__ */ jsx("div", { className: "w-10 h-10 bg-[var(--info-bg)] rounded-ios-sm flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx(Calendar, { className: "size-5 text-[var(--info)]" }) }),
|
|
60
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
61
|
+
booking.resourceName ? /* @__PURE__ */ jsx("span", { className: "text-2xs font-medium uppercase tracking-wide text-[var(--text-muted)]", children: booking.resourceName }) : booking.type && booking.type !== "resource" ? /* @__PURE__ */ jsx("span", { className: "text-2xs font-medium uppercase tracking-wide text-[var(--text-muted)]", children: BOOKING_TYPE_LABELS[booking.type] || booking.type }) : null,
|
|
62
|
+
booking.content ? /* @__PURE__ */ jsx(
|
|
63
|
+
Link,
|
|
64
|
+
{
|
|
65
|
+
href: `/dashboard/catalog/${booking.content.id}`,
|
|
66
|
+
className: "block text-xl font-semibold text-[var(--text-primary)] truncate active:opacity-70 transition-opacity",
|
|
67
|
+
children: booking.content.title
|
|
68
|
+
}
|
|
69
|
+
) : /* @__PURE__ */ jsxs("h2", { className: "text-xl font-semibold text-[var(--text-primary)] truncate", children: [
|
|
70
|
+
bookingSingular,
|
|
71
|
+
" #",
|
|
72
|
+
booking.bookingNumber
|
|
73
|
+
] }),
|
|
74
|
+
/* @__PURE__ */ jsxs("p", { className: "text-sm text-[var(--text-tertiary)]", children: [
|
|
75
|
+
formatFullDate(booking.date),
|
|
76
|
+
booking.startTime && ` at ${formatTime(booking.startTime)}`,
|
|
77
|
+
booking.durationMinutes && ` \xB7 ${booking.durationMinutes} min`
|
|
78
|
+
] })
|
|
79
|
+
] }),
|
|
80
|
+
bookingAmount > 0 && /* @__PURE__ */ jsx("span", { className: "text-lg font-semibold text-[var(--text-primary)] flex-shrink-0", children: formatCurrency(bookingAmount) })
|
|
81
|
+
] }),
|
|
82
|
+
typeof booking.metadata?.meetingLink === "string" && booking.metadata.meetingLink && /* @__PURE__ */ jsxs(
|
|
83
|
+
"a",
|
|
84
|
+
{
|
|
85
|
+
href: booking.metadata.meetingLink,
|
|
86
|
+
target: "_blank",
|
|
87
|
+
rel: "noopener noreferrer",
|
|
88
|
+
className: "flex items-center gap-3 rounded-ios-sm bg-[var(--info-bg)] px-4 py-3 transition-opacity active:opacity-70",
|
|
89
|
+
children: [
|
|
90
|
+
/* @__PURE__ */ jsx(Video, { className: "size-5 text-[var(--info)] flex-shrink-0" }),
|
|
91
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 min-w-0 text-sm font-medium text-[var(--text-primary)]", children: "Join the video call" }),
|
|
92
|
+
/* @__PURE__ */ jsx(ChevronRight, { className: "size-4 text-[var(--text-tertiary)] flex-shrink-0" })
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
),
|
|
96
|
+
(booking.customerName || booking.customerEmail) && /* @__PURE__ */ jsxs(
|
|
97
|
+
Link,
|
|
98
|
+
{
|
|
99
|
+
href: booking.memberId ? `/dashboard/customers/${booking.memberId}` : "#",
|
|
100
|
+
className: "flex items-center gap-3 active:opacity-70 transition-opacity",
|
|
101
|
+
children: [
|
|
102
|
+
/* @__PURE__ */ jsx("div", { className: "w-8 h-8 bg-[var(--bg-muted)] rounded-full flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx(User, { className: "size-4 text-[var(--text-tertiary)]" }) }),
|
|
103
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
104
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-[var(--text-primary)]", children: booking.customerName || "Guest" }),
|
|
105
|
+
booking.customerEmail && /* @__PURE__ */ jsx("span", { className: "text-sm text-[var(--text-tertiary)] ml-1.5", children: booking.customerEmail })
|
|
106
|
+
] }),
|
|
107
|
+
booking.memberId && /* @__PURE__ */ jsx(ChevronRight, { className: "size-4 text-[var(--text-muted)] flex-shrink-0" })
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
),
|
|
111
|
+
/* @__PURE__ */ jsx("div", { className: "-mx-4 px-4 overflow-x-auto scrollbar-none", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 w-max", children: [
|
|
112
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
113
|
+
/* @__PURE__ */ jsxs(
|
|
114
|
+
"button",
|
|
115
|
+
{
|
|
116
|
+
type: "button",
|
|
117
|
+
onClick: () => {
|
|
118
|
+
if (allowedTransitions.length > 0)
|
|
119
|
+
setShowStatusDropdown(!showStatusDropdown);
|
|
120
|
+
},
|
|
121
|
+
disabled: allowedTransitions.length === 0,
|
|
122
|
+
className: "inline-flex items-center gap-2 rounded-lg",
|
|
123
|
+
children: [
|
|
124
|
+
/* @__PURE__ */ jsx(StatusBadge, { status: booking.status, label: statusConfig.label }),
|
|
125
|
+
allowedTransitions.length > 0 && /* @__PURE__ */ jsx(ChevronDown, { className: "text-[var(--text-tertiary)]" })
|
|
126
|
+
]
|
|
127
|
+
}
|
|
128
|
+
),
|
|
129
|
+
showStatusDropdown && /* @__PURE__ */ jsx("div", { className: "absolute z-10 mt-1 w-48 bg-[var(--bg-base)] border border-[var(--border-default)] rounded-ios-lg shadow-lg py-1", children: allowedTransitions.map((status) => {
|
|
130
|
+
const config = statuses(booking?.type)[status];
|
|
131
|
+
return /* @__PURE__ */ jsxs(
|
|
132
|
+
"button",
|
|
133
|
+
{
|
|
134
|
+
type: "button",
|
|
135
|
+
onClick: () => handleStatusUpdate(status),
|
|
136
|
+
disabled: updatingStatus,
|
|
137
|
+
className: "w-full flex items-center gap-2 px-3 py-2 text-sm text-left active:bg-[var(--interactive-hover)]",
|
|
138
|
+
children: [
|
|
139
|
+
/* @__PURE__ */ jsx("span", { className: config.color, children: config.icon }),
|
|
140
|
+
config.label
|
|
141
|
+
]
|
|
142
|
+
},
|
|
143
|
+
status
|
|
144
|
+
);
|
|
145
|
+
}) })
|
|
146
|
+
] }),
|
|
147
|
+
(bookingTotal > 0 || paidAmount > 0 || securityDeposit != null) && /* @__PURE__ */ jsx(StatusBadge, { status: isPaid ? "paid" : "unpaid" }),
|
|
148
|
+
/* @__PURE__ */ jsxs(Badge, { className: "gap-2", children: [
|
|
149
|
+
/* @__PURE__ */ jsx(Ticket, {}),
|
|
150
|
+
BOOKING_MODE_LABELS[booking.bookingMode || "scheduled"] || "Scheduled"
|
|
151
|
+
] }),
|
|
152
|
+
booking.origin && /* @__PURE__ */ jsxs(Badge, { className: "gap-2", children: [
|
|
153
|
+
/* @__PURE__ */ jsx(Globe, {}),
|
|
154
|
+
BOOKING_ORIGIN_LABELS[booking.origin] || booking.origin
|
|
155
|
+
] })
|
|
156
|
+
] }) }),
|
|
157
|
+
meetingLink && /* @__PURE__ */ jsxs(
|
|
158
|
+
"a",
|
|
159
|
+
{
|
|
160
|
+
href: meetingLink,
|
|
161
|
+
target: "_blank",
|
|
162
|
+
rel: "noreferrer",
|
|
163
|
+
className: "flex items-center justify-center gap-2 rounded-ios-lg bg-[var(--bg-subtle)] px-3 py-3 text-sm font-medium text-[var(--text-link)] active:scale-[var(--motion-press-scale)]",
|
|
164
|
+
children: [
|
|
165
|
+
/* @__PURE__ */ jsx(Video, { className: "size-4" }),
|
|
166
|
+
joinLabelOf(meetingLink)
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
),
|
|
170
|
+
/* @__PURE__ */ jsxs("div", { className: "bg-[var(--bg-subtle)] rounded-ios-lg overflow-hidden", children: [
|
|
171
|
+
/* @__PURE__ */ jsxs("div", { className: "px-3 py-3 border-b border-[var(--border-subtle)]", children: [
|
|
172
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
173
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
174
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-[var(--text-tertiary)]", children: "Date" }),
|
|
175
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-[var(--text-primary)]", children: formatFullDate(booking.date) })
|
|
176
|
+
] }),
|
|
177
|
+
/* @__PURE__ */ jsxs("div", { className: "text-right", children: [
|
|
178
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-[var(--text-tertiary)]", children: "Time" }),
|
|
179
|
+
/* @__PURE__ */ jsxs("p", { className: "text-sm text-[var(--text-primary)]", children: [
|
|
180
|
+
booking.startTime && formatTime(booking.startTime),
|
|
181
|
+
booking.endTime && ` \u2013 ${formatTime(booking.endTime)}`,
|
|
182
|
+
!booking.startTime && "\u2014"
|
|
183
|
+
] })
|
|
184
|
+
] })
|
|
185
|
+
] }),
|
|
186
|
+
booking.quantity && booking.quantity > 1 && /* @__PURE__ */ jsxs("div", { className: "mt-2 flex justify-between", children: [
|
|
187
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-[var(--text-tertiary)]", children: "Guests" }),
|
|
188
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-[var(--text-primary)]", children: booking.quantity })
|
|
189
|
+
] }),
|
|
190
|
+
booking.schedulePayload && Object.keys(booking.schedulePayload).length > 0 && /* @__PURE__ */ jsxs("div", { className: "mt-2 space-y-1", children: [
|
|
191
|
+
booking.schedulePayload.partySize != null && /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
192
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-[var(--text-tertiary)]", children: "Party size" }),
|
|
193
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-[var(--text-primary)]", children: String(booking.schedulePayload.partySize) })
|
|
194
|
+
] }),
|
|
195
|
+
booking.schedulePayload.dropoffDate != null && /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
|
|
196
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-[var(--text-tertiary)]", children: "Drop-off date" }),
|
|
197
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-[var(--text-primary)]", children: formatFullDate(
|
|
198
|
+
String(booking.schedulePayload.dropoffDate)
|
|
199
|
+
) })
|
|
200
|
+
] })
|
|
201
|
+
] })
|
|
202
|
+
] }),
|
|
203
|
+
bookingTotal > 0 && /* @__PURE__ */ jsx(
|
|
204
|
+
BookingMoney,
|
|
205
|
+
{
|
|
206
|
+
total: bookingTotal,
|
|
207
|
+
paidAmount,
|
|
208
|
+
isPaid,
|
|
209
|
+
paymentReference,
|
|
210
|
+
paidAt,
|
|
211
|
+
formatCurrency,
|
|
212
|
+
formatDateTime
|
|
213
|
+
}
|
|
214
|
+
)
|
|
215
|
+
] }),
|
|
216
|
+
split && split.participants.length > 0 && /* @__PURE__ */ jsx(BookingSplit, { split, formatCurrency }),
|
|
217
|
+
booking.customerNote && /* @__PURE__ */ jsxs("div", { className: "bg-[var(--bg-subtle)] rounded-ios-lg overflow-hidden px-3 py-3", children: [
|
|
218
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium text-[var(--text-tertiary)] uppercase tracking-wide mb-2", children: "Customer note" }),
|
|
219
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-[var(--text-secondary)] bg-[var(--warning-bg)] p-3 rounded-ios-sm border border-[var(--warning)]/10", children: booking.customerNote })
|
|
220
|
+
] }),
|
|
221
|
+
booking.type === "event" && tickets.length > 0 && /* @__PURE__ */ jsxs("div", { className: "bg-[var(--bg-subtle)] rounded-ios-lg overflow-hidden", children: [
|
|
222
|
+
/* @__PURE__ */ jsxs("div", { className: "px-3 py-3 border-b border-[var(--border-subtle)] flex items-center justify-between", children: [
|
|
223
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
224
|
+
/* @__PURE__ */ jsx(Ticket, { className: "size-4 text-[var(--text-tertiary)]" }),
|
|
225
|
+
/* @__PURE__ */ jsxs("h3", { className: "text-sm font-medium text-[var(--text-tertiary)] uppercase tracking-wide", children: [
|
|
226
|
+
"Tickets (",
|
|
227
|
+
tickets.length,
|
|
228
|
+
")"
|
|
229
|
+
] })
|
|
230
|
+
] }),
|
|
231
|
+
tickets.length > 1 && tenant?.slug && /* @__PURE__ */ jsxs(
|
|
232
|
+
"a",
|
|
233
|
+
{
|
|
234
|
+
href: bookingsApi.getTicketsPdfUrl(tenant.slug, booking.id),
|
|
235
|
+
className: "inline-flex items-center gap-2 text-sm font-medium text-[var(--accent-primary)] active:opacity-70",
|
|
236
|
+
children: [
|
|
237
|
+
/* @__PURE__ */ jsx(Download, {}),
|
|
238
|
+
"PDF"
|
|
239
|
+
]
|
|
240
|
+
}
|
|
241
|
+
)
|
|
242
|
+
] }),
|
|
243
|
+
/* @__PURE__ */ jsx("div", { className: "divide-y divide-[var(--border-subtle)]", children: tickets.map((ticket, idx) => {
|
|
244
|
+
const ticketCode = resolveTicketCode({ ticket, booking });
|
|
245
|
+
return /* @__PURE__ */ jsxs(
|
|
246
|
+
"div",
|
|
247
|
+
{
|
|
248
|
+
className: "px-3 py-3 flex items-center gap-3",
|
|
249
|
+
children: [
|
|
250
|
+
/* @__PURE__ */ jsx(
|
|
251
|
+
"div",
|
|
252
|
+
{
|
|
253
|
+
className: `w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 ${ticket.checkedInAt ? "bg-[var(--success-bg)]" : ticket.status === "cancelled" ? "bg-[var(--bg-muted)]" : "bg-[var(--info-bg)]"}`,
|
|
254
|
+
children: /* @__PURE__ */ jsx(
|
|
255
|
+
QrCode,
|
|
256
|
+
{
|
|
257
|
+
className: `w-4 h-4 ${ticket.checkedInAt ? "text-[var(--success)]" : ticket.status === "cancelled" ? "text-[var(--text-muted)]" : "text-[var(--info)]"}`
|
|
258
|
+
}
|
|
259
|
+
)
|
|
260
|
+
}
|
|
261
|
+
),
|
|
262
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
263
|
+
/* @__PURE__ */ jsxs("p", { className: "text-sm font-medium text-[var(--text-primary)]", children: [
|
|
264
|
+
"Ticket ",
|
|
265
|
+
idx + 1,
|
|
266
|
+
ticket.attendeeName && /* @__PURE__ */ jsxs("span", { className: "text-[var(--text-tertiary)] font-normal", children: [
|
|
267
|
+
" ",
|
|
268
|
+
"\u2014 ",
|
|
269
|
+
ticket.attendeeName
|
|
270
|
+
] })
|
|
271
|
+
] }),
|
|
272
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--text-muted)] font-mono truncate", children: ticketCode ?? "Issued soon" }),
|
|
273
|
+
/* @__PURE__ */ jsx(
|
|
274
|
+
TicketRowActions,
|
|
275
|
+
{
|
|
276
|
+
tenantSlug: tenant?.slug,
|
|
277
|
+
bookingId: booking.id,
|
|
278
|
+
ticketId: ticket.id,
|
|
279
|
+
ticketCode,
|
|
280
|
+
className: "mt-1"
|
|
281
|
+
}
|
|
282
|
+
)
|
|
283
|
+
] }),
|
|
284
|
+
/* @__PURE__ */ jsx(
|
|
285
|
+
StatusBadge,
|
|
286
|
+
{
|
|
287
|
+
className: "flex-shrink-0",
|
|
288
|
+
status: ticket.checkedInAt ? "checked_in" : ticket.status === "cancelled" ? "cancelled" : "confirmed",
|
|
289
|
+
label: ticket.checkedInAt ? "Checked In" : ticket.status === "cancelled" ? "Cancelled" : "Active"
|
|
290
|
+
}
|
|
291
|
+
)
|
|
292
|
+
]
|
|
293
|
+
},
|
|
294
|
+
ticket.id
|
|
295
|
+
);
|
|
296
|
+
}) })
|
|
297
|
+
] }),
|
|
298
|
+
booking.type === "event" && booking.contentId && /* @__PURE__ */ jsxs(
|
|
299
|
+
Link,
|
|
300
|
+
{
|
|
301
|
+
href: `/dashboard/bookings/attendees?contentId=${booking.contentId}`,
|
|
302
|
+
className: "flex items-center gap-3 px-3 py-3 bg-[var(--bg-subtle)] rounded-ios-lg active:bg-[var(--bg-muted)] transition-colors",
|
|
303
|
+
children: [
|
|
304
|
+
/* @__PURE__ */ jsx(Users, { className: "size-5 text-[var(--info)]" }),
|
|
305
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 text-sm font-medium text-[var(--text-primary)]", children: "View all attendees" }),
|
|
306
|
+
/* @__PURE__ */ jsx(ChevronRight, { className: "size-4 text-[var(--text-muted)]" })
|
|
307
|
+
]
|
|
308
|
+
}
|
|
309
|
+
)
|
|
310
|
+
] });
|
|
311
|
+
}
|
|
312
|
+
export {
|
|
313
|
+
BookingMobileLayout
|
|
314
|
+
};
|
|
315
|
+
//# sourceMappingURL=booking-mobile-layout.js.map
|
package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-mobile-layout.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/dashboard/%28bookings%29/bookings/%5BbookingId%5D/_components/booking-mobile-layout.tsx"],"sourcesContent":["import Link from 'next/link';\nimport {\n Calendar,\n ChevronDown,\n ChevronRight,\n Download,\n Globe,\n QrCode,\n Ticket,\n User,\n Users,\n Video,\n} from 'lucide-react';\nimport { bookingsApi } from '@withpotter/lib/api/bookings';\nimport { joinLabelOf, meetingLinkOf } from '@withpotter/lib/booking-meeting-link';\nimport {\n useBookingStatusConfig,\n formatDateTime,\n formatFullDate,\n formatTime,\n} from '../_hooks';\nimport {\n BOOKING_MODE_LABELS,\n BOOKING_ORIGIN_LABELS,\n BOOKING_TYPE_LABELS,\n} from './booking-constants';\nimport { BookingMoney } from './booking-money';\nimport { BookingSplit } from './booking-split';\nimport type { BookingLayoutProps } from './booking-layout-props';\nimport { Badge } from '@withpotter/ui-kit';\nimport { StatusBadge } from '@withpotter/components/shared/status-badge';\nimport { TicketRowActions } from './ticket-row-actions';\nimport { resolveTicketCode } from '@withpotter/lib/ticket-access';\n\n/**\n * Legacy narrow-viewport booking-detail layout (renders below `lg`, when the\n * JS isMobile hook is false but the CSS breakpoint is still sub-desktop).\n * Extracted verbatim from the page during the detail-scaffold pass.\n */\nexport function BookingMobileLayout({\n booking,\n tickets,\n statusConfig,\n formatCurrency,\n isPaid,\n bookingAmount,\n bookingTotal,\n paidAmount,\n split,\n paymentReference,\n paidAt,\n allowedTransitions,\n updatingStatus,\n showStatusDropdown,\n setShowStatusDropdown,\n handleStatusUpdate,\n bookingSingular,\n tenant,\n securityDeposit,\n}: BookingLayoutProps) {\n const statuses = useBookingStatusConfig();\n const meetingLink = meetingLinkOf(booking);\n return (\n <div className=\"lg:hidden space-y-4\">\n {/* What's being booked — the headline */}\n <div className=\"flex items-center gap-3\">\n <div className=\"w-10 h-10 bg-[var(--info-bg)] rounded-ios-sm flex items-center justify-center flex-shrink-0\">\n <Calendar className=\"size-5 text-[var(--info)]\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n {/* Name the court, not the category it belongs to. Same rule as the\n desktop fact list. */}\n {booking.resourceName ? (\n <span className=\"text-2xs font-medium uppercase tracking-wide text-[var(--text-muted)]\">\n {booking.resourceName}\n </span>\n ) : booking.type && booking.type !== 'resource' ? (\n <span className=\"text-2xs font-medium uppercase tracking-wide text-[var(--text-muted)]\">\n {BOOKING_TYPE_LABELS[booking.type] || booking.type}\n </span>\n ) : null}\n {booking.content ? (\n <Link\n href={`/dashboard/catalog/${booking.content.id}`}\n className=\"block text-xl font-semibold text-[var(--text-primary)] truncate active:opacity-70 transition-opacity\"\n >\n {booking.content.title}\n </Link>\n ) : (\n <h2 className=\"text-xl font-semibold text-[var(--text-primary)] truncate\">\n {bookingSingular} #{booking.bookingNumber}\n </h2>\n )}\n <p className=\"text-sm text-[var(--text-tertiary)]\">\n {formatFullDate(booking.date)}\n {booking.startTime && ` at ${formatTime(booking.startTime)}`}\n {booking.durationMinutes && ` · ${booking.durationMinutes} min`}\n </p>\n </div>\n {bookingAmount > 0 && (\n <span className=\"text-lg font-semibold text-[var(--text-primary)] flex-shrink-0\">\n {formatCurrency(bookingAmount)}\n </span>\n )}\n </div>\n\n {/* JOIN THE CALL.\n The phone is where somebody actually joins, so on this layout the\n room is not a line of facts — it is the act, at the top, at the size\n of a thumb. Shown only when calendar sync minted a room. */}\n {typeof booking.metadata?.meetingLink === 'string' &&\n booking.metadata.meetingLink && (\n <a\n href={booking.metadata.meetingLink}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-3 rounded-ios-sm bg-[var(--info-bg)] px-4 py-3 transition-opacity active:opacity-70\"\n >\n <Video className=\"size-5 text-[var(--info)] flex-shrink-0\" />\n <span className=\"flex-1 min-w-0 text-sm font-medium text-[var(--text-primary)]\">\n Join the video call\n </span>\n <ChevronRight className=\"size-4 text-[var(--text-tertiary)] flex-shrink-0\" />\n </a>\n )}\n\n {/* Customer tag */}\n {(booking.customerName || booking.customerEmail) && (\n <Link\n href={\n booking.memberId ? `/dashboard/customers/${booking.memberId}` : '#'\n }\n className=\"flex items-center gap-3 active:opacity-70 transition-opacity\"\n >\n <div className=\"w-8 h-8 bg-[var(--bg-muted)] rounded-full flex items-center justify-center flex-shrink-0\">\n <User className=\"size-4 text-[var(--text-tertiary)]\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <span className=\"text-sm font-medium text-[var(--text-primary)]\">\n {booking.customerName || 'Guest'}\n </span>\n {booking.customerEmail && (\n <span className=\"text-sm text-[var(--text-tertiary)] ml-1.5\">\n {booking.customerEmail}\n </span>\n )}\n </div>\n {booking.memberId && (\n <ChevronRight className=\"size-4 text-[var(--text-muted)] flex-shrink-0\" />\n )}\n </Link>\n )}\n\n {/* Inline status pills */}\n <div className=\"-mx-4 px-4 overflow-x-auto scrollbar-none\">\n <div className=\"flex items-center gap-2 w-max\">\n {/* Booking Status */}\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={() => {\n if (allowedTransitions.length > 0)\n setShowStatusDropdown(!showStatusDropdown);\n }}\n disabled={allowedTransitions.length === 0}\n className=\"inline-flex items-center gap-2 rounded-lg\"\n >\n <StatusBadge status={booking.status} label={statusConfig.label} />\n {allowedTransitions.length > 0 && (\n <ChevronDown className=\"text-[var(--text-tertiary)]\" />\n )}\n </button>\n {showStatusDropdown && (\n <div className=\"absolute z-10 mt-1 w-48 bg-[var(--bg-base)] border border-[var(--border-default)] rounded-ios-lg shadow-lg py-1\">\n {allowedTransitions.map((status) => {\n const config = statuses(booking?.type)[status];\n return (\n <button\n type=\"button\"\n key={status}\n onClick={() => handleStatusUpdate(status)}\n disabled={updatingStatus}\n className=\"w-full flex items-center gap-2 px-3 py-2 text-sm text-left active:bg-[var(--interactive-hover)]\"\n >\n <span className={config.color}>{config.icon}</span>\n {config.label}\n </button>\n );\n })}\n </div>\n )}\n </div>\n\n {/* Payment Status, only where money is attached — a free booking is\n not unpaid, it is free. Same test the Payment card below uses. */}\n {(bookingTotal > 0 || paidAmount > 0 || securityDeposit != null) && (\n <StatusBadge status={isPaid ? 'paid' : 'unpaid'} />\n )}\n\n {/* Mode Badge */}\n <Badge className=\"gap-2\">\n <Ticket />\n {BOOKING_MODE_LABELS[booking.bookingMode || 'scheduled'] ||\n 'Scheduled'}\n </Badge>\n\n {/* Origin Badge */}\n {booking.origin && (\n <Badge className=\"gap-2\">\n <Globe />\n {BOOKING_ORIGIN_LABELS[booking.origin] || booking.origin}\n </Badge>\n )}\n </div>\n </div>\n\n {/* The room, when it has one — the same `metadata.meetingLink` the\n confirmation email carries. A phone at the hour of the call is the\n likeliest place this is wanted, so it is a full-width row rather than\n a line of small print. */}\n {meetingLink && (\n <a\n href={meetingLink}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"flex items-center justify-center gap-2 rounded-ios-lg bg-[var(--bg-subtle)] px-3 py-3 text-sm font-medium text-[var(--text-link)] active:scale-[var(--motion-press-scale)]\"\n >\n <Video className=\"size-4\" />\n {joinLabelOf(meetingLink)}\n </a>\n )}\n\n {/* Details card: schedule + guests + payment */}\n <div className=\"bg-[var(--bg-subtle)] rounded-ios-lg overflow-hidden\">\n {/* Date & Time */}\n <div className=\"px-3 py-3 border-b border-[var(--border-subtle)]\">\n <div className=\"flex items-center justify-between\">\n <div>\n <span className=\"text-sm text-[var(--text-tertiary)]\">Date</span>\n <p className=\"text-sm text-[var(--text-primary)]\">\n {formatFullDate(booking.date)}\n </p>\n </div>\n <div className=\"text-right\">\n <span className=\"text-sm text-[var(--text-tertiary)]\">Time</span>\n <p className=\"text-sm text-[var(--text-primary)]\">\n {booking.startTime && formatTime(booking.startTime)}\n {booking.endTime && ` – ${formatTime(booking.endTime)}`}\n {!booking.startTime && '—'}\n </p>\n </div>\n </div>\n {booking.quantity && booking.quantity > 1 && (\n <div className=\"mt-2 flex justify-between\">\n <span className=\"text-sm text-[var(--text-tertiary)]\">\n Guests\n </span>\n <span className=\"text-sm text-[var(--text-primary)]\">\n {booking.quantity}\n </span>\n </div>\n )}\n {/* Schedule Payload Summary */}\n {booking.schedulePayload &&\n Object.keys(booking.schedulePayload).length > 0 && (\n <div className=\"mt-2 space-y-1\">\n {booking.schedulePayload.partySize != null && (\n <div className=\"flex justify-between\">\n <span className=\"text-sm text-[var(--text-tertiary)]\">\n Party size\n </span>\n <span className=\"text-sm text-[var(--text-primary)]\">\n {String(booking.schedulePayload.partySize)}\n </span>\n </div>\n )}\n {booking.schedulePayload.dropoffDate != null && (\n <div className=\"flex justify-between\">\n <span className=\"text-sm text-[var(--text-tertiary)]\">\n Drop-off date\n </span>\n <span className=\"text-sm text-[var(--text-primary)]\">\n {formatFullDate(\n String(booking.schedulePayload.dropoffDate),\n )}\n </span>\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* Payment summary */}\n {bookingTotal > 0 && (\n <BookingMoney\n total={bookingTotal}\n paidAmount={paidAmount}\n isPaid={isPaid}\n paymentReference={paymentReference}\n paidAt={paidAt}\n formatCurrency={formatCurrency}\n formatDateTime={formatDateTime}\n />\n )}\n </div>\n\n {/* Group split */}\n {split && split.participants.length > 0 && (\n <BookingSplit split={split} formatCurrency={formatCurrency} />\n )}\n\n {/* Notes */}\n {booking.customerNote && (\n <div className=\"bg-[var(--bg-subtle)] rounded-ios-lg overflow-hidden px-3 py-3\">\n <h3 className=\"text-sm font-medium text-[var(--text-tertiary)] uppercase tracking-wide mb-2\">\n Customer note\n </h3>\n <p className=\"text-sm text-[var(--text-secondary)] bg-[var(--warning-bg)] p-3 rounded-ios-sm border border-[var(--warning)]/10\">\n {booking.customerNote}\n </p>\n </div>\n )}\n\n {/* Individual Tickets (event bookings) */}\n {booking.type === 'event' && tickets.length > 0 && (\n <div className=\"bg-[var(--bg-subtle)] rounded-ios-lg overflow-hidden\">\n <div className=\"px-3 py-3 border-b border-[var(--border-subtle)] flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <Ticket className=\"size-4 text-[var(--text-tertiary)]\" />\n <h3 className=\"text-sm font-medium text-[var(--text-tertiary)] uppercase tracking-wide\">\n Tickets ({tickets.length})\n </h3>\n </div>\n {tickets.length > 1 && tenant?.slug && (\n <a\n href={bookingsApi.getTicketsPdfUrl(tenant.slug, booking.id)}\n className=\"inline-flex items-center gap-2 text-sm font-medium text-[var(--accent-primary)] active:opacity-70\"\n >\n <Download />\n PDF\n </a>\n )}\n </div>\n <div className=\"divide-y divide-[var(--border-subtle)]\">\n {tickets.map((ticket, idx) => {\n const ticketCode = resolveTicketCode({ ticket, booking });\n return (\n <div\n key={ticket.id}\n className=\"px-3 py-3 flex items-center gap-3\"\n >\n <div\n className={`w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0 ${\n ticket.checkedInAt\n ? 'bg-[var(--success-bg)]'\n : ticket.status === 'cancelled'\n ? 'bg-[var(--bg-muted)]'\n : 'bg-[var(--info-bg)]'\n }`}\n >\n <QrCode\n className={`w-4 h-4 ${\n ticket.checkedInAt\n ? 'text-[var(--success)]'\n : ticket.status === 'cancelled'\n ? 'text-[var(--text-muted)]'\n : 'text-[var(--info)]'\n }`}\n />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">\n Ticket {idx + 1}\n {ticket.attendeeName && (\n <span className=\"text-[var(--text-tertiary)] font-normal\">\n {' '}\n — {ticket.attendeeName}\n </span>\n )}\n </p>\n <p className=\"text-xs text-[var(--text-muted)] font-mono truncate\">\n {ticketCode ?? 'Issued soon'}\n </p>\n <TicketRowActions\n tenantSlug={tenant?.slug}\n bookingId={booking.id}\n ticketId={ticket.id}\n ticketCode={ticketCode}\n className=\"mt-1\"\n />\n </div>\n <StatusBadge\n className=\"flex-shrink-0\"\n status={\n ticket.checkedInAt\n ? 'checked_in'\n : ticket.status === 'cancelled'\n ? 'cancelled'\n : 'confirmed'\n }\n label={\n ticket.checkedInAt\n ? 'Checked In'\n : ticket.status === 'cancelled'\n ? 'Cancelled'\n : 'Active'\n }\n />\n </div>\n );\n })}\n </div>\n </div>\n )}\n\n {/* View Attendees (event bookings only) */}\n {booking.type === 'event' && booking.contentId && (\n <Link\n href={`/dashboard/bookings/attendees?contentId=${booking.contentId}`}\n className=\"flex items-center gap-3 px-3 py-3 bg-[var(--bg-subtle)] rounded-ios-lg active:bg-[var(--bg-muted)] transition-colors\"\n >\n <Users className=\"size-5 text-[var(--info)]\" />\n <span className=\"flex-1 text-sm font-medium text-[var(--text-primary)]\">\n View all attendees\n </span>\n <ChevronRight className=\"size-4 text-[var(--text-muted)]\" />\n </Link>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { formatFullDate, formatTime } from "../_hooks";
|
|
4
|
+
import { BOOKING_TYPE_LABELS } from "./booking-constants";
|
|
5
|
+
import { CancelBookingModal } from "./cancel-booking-modal";
|
|
6
|
+
import { MobileBookingDetailScreen } from "@withpotter/components/mobile/screens/booking-detail";
|
|
7
|
+
import { joinLabelOf, meetingLinkOf } from "@withpotter/lib/booking-meeting-link";
|
|
8
|
+
function BookingMobileScreen({
|
|
9
|
+
booking,
|
|
10
|
+
bookingSingular,
|
|
11
|
+
statusConfig,
|
|
12
|
+
formatCurrency,
|
|
13
|
+
isPaid,
|
|
14
|
+
bookingAmount,
|
|
15
|
+
allowedTransitions,
|
|
16
|
+
handleStatusUpdate,
|
|
17
|
+
showCancelModal,
|
|
18
|
+
setShowCancelModal,
|
|
19
|
+
cancelReason,
|
|
20
|
+
setCancelReason,
|
|
21
|
+
updatingStatus,
|
|
22
|
+
handleCancel,
|
|
23
|
+
onBack
|
|
24
|
+
}) {
|
|
25
|
+
const customerName = booking.customerName || booking.customerEmail || "Guest";
|
|
26
|
+
const initials = customerName.split(" ").map((p) => p[0]).filter(Boolean).slice(0, 2).join("").toUpperCase();
|
|
27
|
+
const tone = statusConfig?.color?.includes("warning") ? "warn" : statusConfig?.color?.includes("success") ? "good" : statusConfig?.color?.includes("error") ? "bad" : "accent";
|
|
28
|
+
const facts = [
|
|
29
|
+
{ label: "Booking #", value: booking.bookingNumber },
|
|
30
|
+
// A resource booking's type is the word "resource" — true, and useless to
|
|
31
|
+
// someone running a club. What they need is WHICH court. For every other
|
|
32
|
+
// type the label is already their own word (Appointment, Table
|
|
33
|
+
// Reservation, Room Booking), so it stays.
|
|
34
|
+
...booking.resourceName ? [{ label: "Booked", value: booking.resourceName }] : booking.type && booking.type !== "resource" ? [
|
|
35
|
+
{
|
|
36
|
+
label: "Type",
|
|
37
|
+
value: BOOKING_TYPE_LABELS[booking.type] || booking.type
|
|
38
|
+
}
|
|
39
|
+
] : [],
|
|
40
|
+
...booking.durationMinutes ? [{ label: "Duration", value: `${booking.durationMinutes} min` }] : [],
|
|
41
|
+
...bookingAmount ? [{ label: "Total", value: formatCurrency(bookingAmount) }] : [],
|
|
42
|
+
...isPaid ? [{ label: "Payment", value: "Paid" }] : []
|
|
43
|
+
];
|
|
44
|
+
const meetingLink = meetingLinkOf(booking);
|
|
45
|
+
const canAccept = allowedTransitions?.includes(
|
|
46
|
+
"confirmed"
|
|
47
|
+
);
|
|
48
|
+
const canDecline = allowedTransitions?.includes(
|
|
49
|
+
"cancelled"
|
|
50
|
+
);
|
|
51
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
52
|
+
/* @__PURE__ */ jsx(
|
|
53
|
+
MobileBookingDetailScreen,
|
|
54
|
+
{
|
|
55
|
+
title: booking.bookingNumber ? `${bookingSingular} #${booking.bookingNumber}` : bookingSingular,
|
|
56
|
+
statusLabel: statusConfig?.label || booking.status || "Pending",
|
|
57
|
+
statusTone: tone,
|
|
58
|
+
whenLabel: booking.date ? `${formatFullDate(booking.date)}${booking.startTime ? ` \xB7 ${formatTime(booking.startTime)}` : ""}` : "",
|
|
59
|
+
whatLabel: booking.content?.title || "Booking",
|
|
60
|
+
guestName: customerName,
|
|
61
|
+
guestInitials: initials || "G",
|
|
62
|
+
guestMeta: booking.customerEmail,
|
|
63
|
+
guestPhone: booking.customerPhone,
|
|
64
|
+
guestEmail: booking.customerEmail,
|
|
65
|
+
reference: booking.bookingNumber ? `#${booking.bookingNumber}` : void 0,
|
|
66
|
+
noteFromGuest: booking.customerNote || void 0,
|
|
67
|
+
meetingLink: meetingLink ?? void 0,
|
|
68
|
+
meetingLabel: meetingLink ? joinLabelOf(meetingLink) : void 0,
|
|
69
|
+
facts,
|
|
70
|
+
onBack,
|
|
71
|
+
onAccept: canAccept ? () => handleStatusUpdate("confirmed") : void 0,
|
|
72
|
+
onDecline: canDecline ? () => setShowCancelModal(true) : void 0
|
|
73
|
+
}
|
|
74
|
+
),
|
|
75
|
+
showCancelModal && /* @__PURE__ */ jsx(
|
|
76
|
+
CancelBookingModal,
|
|
77
|
+
{
|
|
78
|
+
bookingNumber: booking.bookingNumber,
|
|
79
|
+
customerName: booking.customerName,
|
|
80
|
+
bookingDate: booking.date?.slice(0, 10),
|
|
81
|
+
resourceId: booking.resourceId,
|
|
82
|
+
onClose: () => setShowCancelModal(false),
|
|
83
|
+
handleCancel,
|
|
84
|
+
cancelReason,
|
|
85
|
+
setCancelReason,
|
|
86
|
+
updatingStatus
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
] });
|
|
90
|
+
}
|
|
91
|
+
export {
|
|
92
|
+
BookingMobileScreen
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=booking-mobile-screen.js.map
|
package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-mobile-screen.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/dashboard/%28bookings%29/bookings/%5BbookingId%5D/_components/booking-mobile-screen.tsx"],"sourcesContent":["'use client';\n\nimport type { BookingItem } from '@withpotter/lib/api/types';\nimport type { BookingStatus } from '../_hooks';\nimport { formatFullDate, formatTime } from '../_hooks';\nimport { BOOKING_TYPE_LABELS } from './booking-constants';\nimport { CancelBookingModal } from './cancel-booking-modal';\nimport { MobileBookingDetailScreen } from '@withpotter/components/mobile/screens/booking-detail';\nimport { joinLabelOf, meetingLinkOf } from '@withpotter/lib/booking-meeting-link';\n\n/**\n * The booking on a phone.\n *\n * Its own file for the house's reason — the page reached 523 lines — but also\n * because it IS its own thing: a native-shaped screen with an accept/decline\n * pair at the bottom, not a narrower copy of the record. Everything it needs is\n * handed to it, so the page stays a router between two layouts rather than a\n * screen with a second screen embedded in it.\n */\nexport function BookingMobileScreen({\n booking,\n bookingSingular,\n statusConfig,\n formatCurrency,\n isPaid,\n bookingAmount,\n allowedTransitions,\n handleStatusUpdate,\n showCancelModal,\n setShowCancelModal,\n cancelReason,\n setCancelReason,\n updatingStatus,\n handleCancel,\n onBack,\n}: {\n booking: BookingItem;\n bookingSingular: string;\n statusConfig: { label: string; color: string };\n formatCurrency: (n: number) => string;\n isPaid: boolean;\n bookingAmount: number;\n allowedTransitions: BookingStatus[];\n handleStatusUpdate: (status: BookingStatus) => void;\n showCancelModal: boolean;\n setShowCancelModal: (v: boolean) => void;\n cancelReason: string;\n setCancelReason: (v: string) => void;\n updatingStatus: boolean;\n handleCancel: () => void;\n onBack: () => void;\n}) {\n const customerName = booking.customerName || booking.customerEmail || 'Guest';\n const initials = customerName\n .split(' ')\n .map((p: string) => p[0])\n .filter(Boolean)\n .slice(0, 2)\n .join('')\n .toUpperCase();\n const tone = statusConfig?.color?.includes('warning')\n ? 'warn'\n : statusConfig?.color?.includes('success')\n ? 'good'\n : statusConfig?.color?.includes('error')\n ? 'bad'\n : 'accent';\n const facts: { label: string; value: string }[] = [\n { label: 'Booking #', value: booking.bookingNumber },\n // A resource booking's type is the word \"resource\" — true, and useless to\n // someone running a club. What they need is WHICH court. For every other\n // type the label is already their own word (Appointment, Table\n // Reservation, Room Booking), so it stays.\n ...(booking.resourceName\n ? [{ label: 'Booked', value: booking.resourceName }]\n : booking.type && booking.type !== 'resource'\n ? [\n {\n label: 'Type',\n value: BOOKING_TYPE_LABELS[booking.type] || booking.type,\n },\n ]\n : []),\n ...(booking.durationMinutes\n ? [{ label: 'Duration', value: `${booking.durationMinutes} min` }]\n : []),\n ...(bookingAmount\n ? [{ label: 'Total', value: formatCurrency(bookingAmount) }]\n : []),\n ...(isPaid ? [{ label: 'Payment', value: 'Paid' }] : []),\n ];\n const meetingLink = meetingLinkOf(booking);\n const canAccept = (allowedTransitions as string[] | undefined)?.includes(\n 'confirmed',\n );\n const canDecline = (allowedTransitions as string[] | undefined)?.includes(\n 'cancelled',\n );\n return (\n <>\n <MobileBookingDetailScreen\n title={\n booking.bookingNumber\n ? `${bookingSingular} #${booking.bookingNumber}`\n : bookingSingular\n }\n statusLabel={statusConfig?.label || booking.status || 'Pending'}\n statusTone={tone as 'warn' | 'good' | 'bad' | 'accent'}\n whenLabel={\n booking.date\n ? `${formatFullDate(booking.date)}${booking.startTime ? ` · ${formatTime(booking.startTime)}` : ''}`\n : ''\n }\n whatLabel={booking.content?.title || 'Booking'}\n guestName={customerName}\n guestInitials={initials || 'G'}\n guestMeta={booking.customerEmail}\n guestPhone={booking.customerPhone}\n guestEmail={booking.customerEmail}\n reference={\n booking.bookingNumber ? `#${booking.bookingNumber}` : undefined\n }\n noteFromGuest={booking.customerNote || undefined}\n meetingLink={meetingLink ?? undefined}\n meetingLabel={meetingLink ? joinLabelOf(meetingLink) : undefined}\n facts={facts}\n onBack={onBack}\n onAccept={canAccept ? () => handleStatusUpdate('confirmed') : undefined}\n onDecline={canDecline ? () => setShowCancelModal(true) : undefined}\n />\n {showCancelModal && (\n <CancelBookingModal\n bookingNumber={booking.bookingNumber}\n customerName={booking.customerName}\n bookingDate={booking.date?.slice(0, 10)}\n resourceId={booking.resourceId}\n onClose={() => setShowCancelModal(false)}\n handleCancel={handleCancel}\n cancelReason={cancelReason}\n setCancelReason={setCancelReason}\n updatingStatus={updatingStatus}\n />\n )}\n </>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Card } from "@withpotter/ui-kit";
|
|
4
|
+
import { StatusBadge } from "@withpotter/components/shared/status-badge";
|
|
5
|
+
function Row({
|
|
6
|
+
label,
|
|
7
|
+
children
|
|
8
|
+
}) {
|
|
9
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex justify-between gap-3 text-sm", children: [
|
|
10
|
+
/* @__PURE__ */ jsx("span", { className: "text-[var(--text-tertiary)]", children: label }),
|
|
11
|
+
children
|
|
12
|
+
] });
|
|
13
|
+
}
|
|
14
|
+
function BookingMoney({
|
|
15
|
+
total,
|
|
16
|
+
paidAmount,
|
|
17
|
+
isPaid,
|
|
18
|
+
paymentReference,
|
|
19
|
+
paidAt,
|
|
20
|
+
formatCurrency,
|
|
21
|
+
formatDateTime,
|
|
22
|
+
children
|
|
23
|
+
}) {
|
|
24
|
+
const settled = isPaid || total > 0 && paidAmount >= total;
|
|
25
|
+
const balance = Math.max(0, total - paidAmount);
|
|
26
|
+
const hasDeposit = !settled && paidAmount > 0;
|
|
27
|
+
return /* @__PURE__ */ jsxs(Card, { className: "space-y-4", children: [
|
|
28
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
29
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
30
|
+
/* @__PURE__ */ jsx("h2", { className: "text-sm font-medium text-[var(--text-primary)]", children: "Payment" }),
|
|
31
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-xl font-semibold tabular-nums text-[var(--text-primary)]", children: formatCurrency(balance > 0 ? balance : total) }),
|
|
32
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-[var(--text-tertiary)]", children: settled ? "Settled in full" : balance > 0 && paidAmount > 0 ? `still owed of ${formatCurrency(total)}` : "to collect" })
|
|
33
|
+
] }),
|
|
34
|
+
/* @__PURE__ */ jsx(
|
|
35
|
+
StatusBadge,
|
|
36
|
+
{
|
|
37
|
+
size: "md",
|
|
38
|
+
status: settled ? "paid" : hasDeposit ? "partial" : "unpaid",
|
|
39
|
+
label: settled ? "Settled" : hasDeposit ? "Deposit taken" : "Unpaid"
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
] }),
|
|
43
|
+
(hasDeposit || paymentReference || paidAt) && /* @__PURE__ */ jsxs("div", { className: "space-y-2 border-t border-[var(--border-subtle)] pt-3", children: [
|
|
44
|
+
hasDeposit && /* @__PURE__ */ jsx(Row, { label: "Taken so far", children: /* @__PURE__ */ jsx("span", { className: "font-medium tabular-nums text-[var(--success)]", children: formatCurrency(paidAmount) }) }),
|
|
45
|
+
paymentReference && /* @__PURE__ */ jsx(Row, { label: "Reference", children: /* @__PURE__ */ jsx("span", { className: "font-mono text-xs text-[var(--text-secondary)]", children: paymentReference }) }),
|
|
46
|
+
paidAt && /* @__PURE__ */ jsx(Row, { label: "Paid", children: /* @__PURE__ */ jsx("span", { className: "text-[var(--text-primary)]", children: formatDateTime(paidAt) }) })
|
|
47
|
+
] }),
|
|
48
|
+
children
|
|
49
|
+
] });
|
|
50
|
+
}
|
|
51
|
+
export {
|
|
52
|
+
BookingMoney
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=booking-money.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/dashboard/%28bookings%29/bookings/%5BbookingId%5D/_components/booking-money.tsx"],"sourcesContent":["'use client';\n\nimport { Card } from '@withpotter/ui-kit';\nimport { StatusBadge } from '@withpotter/components/shared/status-badge';\n\ninterface BookingMoneyProps {\n /** Full price of the booking. */\n total: number;\n /** Amount collected so far (a deposit, or the full total). */\n paidAmount: number;\n /** Server's paid flag — treated as fully settled. */\n isPaid: boolean;\n paymentReference?: string;\n paidAt?: string;\n formatCurrency: (n: number) => string;\n formatDateTime: (s: string) => string;\n /** The deposit panel, when this booking rents something out. */\n children?: React.ReactNode;\n}\n\nfunction Row({\n label,\n children,\n}: {\n label: string;\n children: React.ReactNode;\n}) {\n return (\n <div className=\"flex justify-between gap-3 text-sm\">\n <span className=\"text-[var(--text-tertiary)]\">{label}</span>\n {children}\n </div>\n );\n}\n\n/**\n * The booking's money as a record, not a boolean.\n *\n * Derives settled / deposit / balance-due from the amount collected, so a\n * booking with a deposit against it shows what is still owed instead of a flat\n * \"Unpaid\". Vertical-agnostic: every booking business (courts, tables, chairs,\n * rentals) reads deposit + balance the same way.\n *\n * THE FIGURE IS THE HEADLINE, and the state is a badge beside it. This opened\n * on a row reading \"Status Unpaid\" — a whole card whose only content was a\n * word the chip at the top of the page had already said — and on a booking with\n * no price that row was the entire panel. A payment section with no money in it\n * is not a payment section, so with nothing owed and nothing taken it does not\n * render at all (see `hasMoney`).\n *\n * The pill was its own colour map, hand-rolled here: `bg-[var(--success-bg)]`\n * against a private ternary. Statuses are `StatusBadge`, everywhere in `src/`.\n */\nexport function BookingMoney({\n total,\n paidAmount,\n isPaid,\n paymentReference,\n paidAt,\n formatCurrency,\n formatDateTime,\n children,\n}: BookingMoneyProps) {\n const settled = isPaid || (total > 0 && paidAmount >= total);\n const balance = Math.max(0, total - paidAmount);\n const hasDeposit = !settled && paidAmount > 0;\n\n return (\n <Card className=\"space-y-4\">\n <div className=\"flex items-start justify-between gap-3\">\n <div>\n <h2 className=\"text-sm font-medium text-[var(--text-primary)]\">\n Payment\n </h2>\n <p className=\"mt-1 text-xl font-semibold tabular-nums text-[var(--text-primary)]\">\n {formatCurrency(balance > 0 ? balance : total)}\n </p>\n <p className=\"mt-1 text-xs text-[var(--text-tertiary)]\">\n {settled\n ? 'Settled in full'\n : balance > 0 && paidAmount > 0\n ? `still owed of ${formatCurrency(total)}`\n : 'to collect'}\n </p>\n </div>\n <StatusBadge\n size=\"md\"\n status={settled ? 'paid' : hasDeposit ? 'partial' : 'unpaid'}\n label={settled ? 'Settled' : hasDeposit ? 'Deposit taken' : 'Unpaid'}\n />\n </div>\n\n {(hasDeposit || paymentReference || paidAt) && (\n <div className=\"space-y-2 border-t border-[var(--border-subtle)] pt-3\">\n {hasDeposit && (\n <Row label=\"Taken so far\">\n <span className=\"font-medium tabular-nums text-[var(--success)]\">\n {formatCurrency(paidAmount)}\n </span>\n </Row>\n )}\n {paymentReference && (\n <Row label=\"Reference\">\n <span className=\"font-mono text-xs text-[var(--text-secondary)]\">\n {paymentReference}\n </span>\n </Row>\n )}\n {paidAt && (\n <Row label=\"Paid\">\n <span className=\"text-[var(--text-primary)]\">\n {formatDateTime(paidAt)}\n </span>\n </Row>\n )}\n </div>\n )}\n\n {children}\n </Card>\n );\n}\n"],"mappings":";AA4BI,SACE,KADF;AA1BJ,SAAS,YAAY;AACrB,SAAS,mBAAmB;AAiB5B,SAAS,IAAI;AAAA,EACX;AAAA,EACA;AACF,GAGG;AACD,SACE,qBAAC,SAAI,WAAU,sCACb;AAAA,wBAAC,UAAK,WAAU,+BAA+B,iBAAM;AAAA,IACpD;AAAA,KACH;AAEJ;AAoBO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,QAAM,UAAU,UAAW,QAAQ,KAAK,cAAc;AACtD,QAAM,UAAU,KAAK,IAAI,GAAG,QAAQ,UAAU;AAC9C,QAAM,aAAa,CAAC,WAAW,aAAa;AAE5C,SACE,qBAAC,QAAK,WAAU,aACd;AAAA,yBAAC,SAAI,WAAU,0CACb;AAAA,2BAAC,SACC;AAAA,4BAAC,QAAG,WAAU,kDAAiD,qBAE/D;AAAA,QACA,oBAAC,OAAE,WAAU,sEACV,yBAAe,UAAU,IAAI,UAAU,KAAK,GAC/C;AAAA,QACA,oBAAC,OAAE,WAAU,4CACV,oBACG,oBACA,UAAU,KAAK,aAAa,IAC1B,iBAAiB,eAAe,KAAK,CAAC,KACtC,cACR;AAAA,SACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,QAAQ,UAAU,SAAS,aAAa,YAAY;AAAA,UACpD,OAAO,UAAU,YAAY,aAAa,kBAAkB;AAAA;AAAA,MAC9D;AAAA,OACF;AAAA,KAEE,cAAc,oBAAoB,WAClC,qBAAC,SAAI,WAAU,yDACZ;AAAA,oBACC,oBAAC,OAAI,OAAM,gBACT,8BAAC,UAAK,WAAU,kDACb,yBAAe,UAAU,GAC5B,GACF;AAAA,MAED,oBACC,oBAAC,OAAI,OAAM,aACT,8BAAC,UAAK,WAAU,kDACb,4BACH,GACF;AAAA,MAED,UACC,oBAAC,OAAI,OAAM,QACT,8BAAC,UAAK,WAAU,8BACb,yBAAe,MAAM,GACxB,GACF;AAAA,OAEJ;AAAA,IAGD;AAAA,KACH;AAEJ;","names":[]}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
const STATUS = {
|
|
3
|
+
paid: { label: "Paid", cls: "bg-[var(--success-bg)] text-[var(--success)]" },
|
|
4
|
+
pending: {
|
|
5
|
+
label: "Pending",
|
|
6
|
+
cls: "bg-[var(--warning-bg)] text-[var(--warning)]"
|
|
7
|
+
},
|
|
8
|
+
cancelled: {
|
|
9
|
+
label: "Out",
|
|
10
|
+
cls: "bg-[var(--bg-muted)] text-[var(--text-muted)]"
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
function BookingSplit({ split, formatCurrency }) {
|
|
14
|
+
const { participants, summary } = split;
|
|
15
|
+
return /* @__PURE__ */ jsxs("div", { className: "max-lg:bg-[var(--bg-subtle)] max-lg:rounded-ios-lg lg:surface overflow-hidden", children: [
|
|
16
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-b border-[var(--border-subtle)] px-4 py-3 lg:bg-[var(--bg-subtle)]", children: [
|
|
17
|
+
/* @__PURE__ */ jsx("h2", { className: "font-semibold text-[var(--text-primary)]", children: "Group split" }),
|
|
18
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-[var(--text-tertiary)]", children: [
|
|
19
|
+
summary.paidCount,
|
|
20
|
+
"/",
|
|
21
|
+
summary.activeCount,
|
|
22
|
+
" paid"
|
|
23
|
+
] })
|
|
24
|
+
] }),
|
|
25
|
+
/* @__PURE__ */ jsxs("div", { className: "p-4 space-y-3", children: [
|
|
26
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm", children: [
|
|
27
|
+
/* @__PURE__ */ jsx("span", { className: "text-[var(--text-secondary)]", children: "Collected" }),
|
|
28
|
+
/* @__PURE__ */ jsxs("span", { className: "font-medium text-[var(--text-primary)]", children: [
|
|
29
|
+
formatCurrency(summary.paidTotal),
|
|
30
|
+
" of",
|
|
31
|
+
" ",
|
|
32
|
+
formatCurrency(summary.pledgedTotal)
|
|
33
|
+
] })
|
|
34
|
+
] }),
|
|
35
|
+
summary.outstanding > 0 && /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm", children: [
|
|
36
|
+
/* @__PURE__ */ jsx("span", { className: "text-[var(--text-secondary)]", children: "Outstanding" }),
|
|
37
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold text-[var(--warning)]", children: formatCurrency(summary.outstanding) })
|
|
38
|
+
] }),
|
|
39
|
+
/* @__PURE__ */ jsx("div", { className: "divide-y divide-[var(--border-subtle)] border-t border-[var(--border-subtle)] pt-1", children: participants.map((p) => {
|
|
40
|
+
const s = STATUS[p.status];
|
|
41
|
+
return /* @__PURE__ */ jsxs(
|
|
42
|
+
"div",
|
|
43
|
+
{
|
|
44
|
+
className: "flex items-center justify-between gap-3 py-2",
|
|
45
|
+
children: [
|
|
46
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
47
|
+
/* @__PURE__ */ jsx("p", { className: "truncate text-sm font-medium text-[var(--text-primary)]", children: p.name }),
|
|
48
|
+
(p.email || p.phone) && /* @__PURE__ */ jsx("p", { className: "truncate text-xs text-[var(--text-tertiary)]", children: p.email || p.phone })
|
|
49
|
+
] }),
|
|
50
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
51
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-[var(--text-primary)]", children: formatCurrency(Number(p.shareAmount)) }),
|
|
52
|
+
/* @__PURE__ */ jsx(
|
|
53
|
+
"span",
|
|
54
|
+
{
|
|
55
|
+
className: `inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${s.cls}`,
|
|
56
|
+
children: s.label
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
] })
|
|
60
|
+
]
|
|
61
|
+
},
|
|
62
|
+
p.id
|
|
63
|
+
);
|
|
64
|
+
}) })
|
|
65
|
+
] })
|
|
66
|
+
] });
|
|
67
|
+
}
|
|
68
|
+
export {
|
|
69
|
+
BookingSplit
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=booking-split.js.map
|