@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,192 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useItemLinks } from "@withpotter/lib/use-item-links";
|
|
3
|
+
import Link from "next/link";
|
|
4
|
+
import { CreditCard, ChevronRight, Video } from "lucide-react";
|
|
5
|
+
import { joinLabelOf, meetingLinkOf } from "@withpotter/lib/booking-meeting-link";
|
|
6
|
+
import { TableShell, Th, TableRow } from "@withpotter/ui-kit/table-shell";
|
|
7
|
+
import { StatusBadge } from "@withpotter/components/shared/status-badge";
|
|
8
|
+
import { useEntityLabel } from "@withpotter/lib/intents/use-entity-label";
|
|
9
|
+
import {
|
|
10
|
+
useBookingStatusConfig
|
|
11
|
+
} from "./booking-constants";
|
|
12
|
+
function shortDate(dateString) {
|
|
13
|
+
return new Date(dateString).toLocaleString("en-US", {
|
|
14
|
+
month: "short",
|
|
15
|
+
day: "numeric",
|
|
16
|
+
hour: "numeric",
|
|
17
|
+
minute: "2-digit"
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function JoinLink({ link }) {
|
|
21
|
+
return /* @__PURE__ */ jsxs(
|
|
22
|
+
"a",
|
|
23
|
+
{
|
|
24
|
+
href: link,
|
|
25
|
+
target: "_blank",
|
|
26
|
+
rel: "noreferrer",
|
|
27
|
+
onClick: (e) => e.stopPropagation(),
|
|
28
|
+
className: "mt-1 inline-flex items-center gap-1 text-xs font-medium text-[var(--text-link)] underline-offset-2 hover:underline",
|
|
29
|
+
children: [
|
|
30
|
+
/* @__PURE__ */ jsx(Video, {}),
|
|
31
|
+
joinLabelOf(link)
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
function bookingAmountOf(booking) {
|
|
37
|
+
return booking.data?.paymentAmount || booking.data?.total || booking.content?.price || 0;
|
|
38
|
+
}
|
|
39
|
+
function BookingsTable({
|
|
40
|
+
bookings,
|
|
41
|
+
formatCurrency,
|
|
42
|
+
formatDate,
|
|
43
|
+
formatTime,
|
|
44
|
+
onSelectRow,
|
|
45
|
+
footer,
|
|
46
|
+
toolbar
|
|
47
|
+
}) {
|
|
48
|
+
const links = useItemLinks();
|
|
49
|
+
const statuses = useBookingStatusConfig();
|
|
50
|
+
const bookingLabel = useEntityLabel("booking");
|
|
51
|
+
const itemLabel = useEntityLabel("item");
|
|
52
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
53
|
+
/* @__PURE__ */ jsx("div", { className: "hidden lg:block", children: /* @__PURE__ */ jsx(
|
|
54
|
+
TableShell,
|
|
55
|
+
{
|
|
56
|
+
bare: true,
|
|
57
|
+
toolbar,
|
|
58
|
+
footer,
|
|
59
|
+
minWidth: 780,
|
|
60
|
+
head: /* @__PURE__ */ jsxs("tr", { className: "h-[44px]", children: [
|
|
61
|
+
/* @__PURE__ */ jsx(Th, { children: bookingLabel.singular }),
|
|
62
|
+
/* @__PURE__ */ jsx(Th, { children: "Customer" }),
|
|
63
|
+
/* @__PURE__ */ jsx(Th, { children: itemLabel.singular }),
|
|
64
|
+
/* @__PURE__ */ jsx(Th, { children: "Date & Time" }),
|
|
65
|
+
/* @__PURE__ */ jsx(Th, { children: "Status" }),
|
|
66
|
+
/* @__PURE__ */ jsx(Th, { children: "Payment" }),
|
|
67
|
+
/* @__PURE__ */ jsx(Th, { align: "right", children: "Amount" }),
|
|
68
|
+
/* @__PURE__ */ jsx("th", { className: "w-12" })
|
|
69
|
+
] }),
|
|
70
|
+
children: bookings.map((booking) => {
|
|
71
|
+
const rowStatuses = statuses(booking.type);
|
|
72
|
+
const statusConfig = rowStatuses[booking.status] || rowStatuses.pending;
|
|
73
|
+
const isPaid = booking.data?.isPaid === true;
|
|
74
|
+
const bookingAmount = bookingAmountOf(booking);
|
|
75
|
+
const meetingLink = meetingLinkOf(booking);
|
|
76
|
+
return /* @__PURE__ */ jsxs(TableRow, { onClick: () => onSelectRow?.(booking), children: [
|
|
77
|
+
/* @__PURE__ */ jsxs("td", { children: [
|
|
78
|
+
/* @__PURE__ */ jsxs("div", { className: "text-sm font-medium text-[var(--text-primary)]", children: [
|
|
79
|
+
"#",
|
|
80
|
+
booking.bookingNumber
|
|
81
|
+
] }),
|
|
82
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-[var(--text-tertiary)] mt-0.5", children: formatDate(booking.createdAt) })
|
|
83
|
+
] }),
|
|
84
|
+
/* @__PURE__ */ jsxs("td", { children: [
|
|
85
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-[var(--text-primary)]", children: booking.customerName || "Guest" }),
|
|
86
|
+
booking.customerEmail && /* @__PURE__ */ jsx("div", { className: "text-xs text-[var(--text-tertiary)] truncate", children: booking.customerEmail })
|
|
87
|
+
] }),
|
|
88
|
+
/* @__PURE__ */ jsx("td", { className: "text-sm text-[var(--text-primary)]", children: booking.content?.title || "\u2014" }),
|
|
89
|
+
/* @__PURE__ */ jsxs("td", { children: [
|
|
90
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-[var(--text-primary)]", children: formatDate(booking.date) }),
|
|
91
|
+
/* @__PURE__ */ jsxs("div", { className: "text-xs text-[var(--text-tertiary)]", children: [
|
|
92
|
+
booking.startTime && formatTime(booking.startTime),
|
|
93
|
+
booking.endTime && ` \u2013 ${formatTime(booking.endTime)}`
|
|
94
|
+
] }),
|
|
95
|
+
meetingLink && /* @__PURE__ */ jsx(JoinLink, { link: meetingLink })
|
|
96
|
+
] }),
|
|
97
|
+
/* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(
|
|
98
|
+
StatusBadge,
|
|
99
|
+
{
|
|
100
|
+
neutral: true,
|
|
101
|
+
status: booking.status,
|
|
102
|
+
icon: statusConfig.icon,
|
|
103
|
+
label: statusConfig.label
|
|
104
|
+
}
|
|
105
|
+
) }),
|
|
106
|
+
/* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(
|
|
107
|
+
StatusBadge,
|
|
108
|
+
{
|
|
109
|
+
neutral: true,
|
|
110
|
+
status: isPaid ? "paid" : "unpaid",
|
|
111
|
+
icon: /* @__PURE__ */ jsx(CreditCard, {}),
|
|
112
|
+
label: isPaid ? "Paid" : "Unpaid"
|
|
113
|
+
}
|
|
114
|
+
) }),
|
|
115
|
+
/* @__PURE__ */ jsx("td", { className: "text-right text-sm font-medium text-[var(--text-primary)]", children: bookingAmount > 0 ? formatCurrency(bookingAmount) : "\u2014" }),
|
|
116
|
+
/* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(ChevronRight, { className: "size-4 text-[var(--text-muted)]" }) })
|
|
117
|
+
] }, booking.id);
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
) }),
|
|
121
|
+
/* @__PURE__ */ jsx("div", { className: "lg:hidden", children: /* @__PURE__ */ jsx("div", { className: "bg-[var(--bg-subtle)] rounded-ios-lg overflow-hidden divide-y divide-[var(--border-subtle)]", children: bookings.map((booking) => {
|
|
122
|
+
const rowStatuses = statuses(booking.type);
|
|
123
|
+
const statusConfig = rowStatuses[booking.status] || rowStatuses.pending;
|
|
124
|
+
const isPaid = booking.data?.isPaid === true;
|
|
125
|
+
const bookingAmount = bookingAmountOf(booking);
|
|
126
|
+
const meetingLink = meetingLinkOf(booking);
|
|
127
|
+
return (
|
|
128
|
+
/* The card is a link, so the Join cannot live inside it — an
|
|
129
|
+
anchor in an anchor is invalid, and React silently renders a
|
|
130
|
+
target nobody can press. It sits under the card instead, still
|
|
131
|
+
inside the one divided cell. */
|
|
132
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
133
|
+
/* @__PURE__ */ jsxs(
|
|
134
|
+
Link,
|
|
135
|
+
{
|
|
136
|
+
href: links.bookingDetail(booking.id),
|
|
137
|
+
className: "flex items-center gap-3 px-3 py-3 active:bg-[var(--bg-muted)] transition-colors",
|
|
138
|
+
children: [
|
|
139
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
140
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-[var(--text-primary)] truncate block", children: booking.content?.title || `#${booking.bookingNumber}` }),
|
|
141
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-0.5", children: [
|
|
142
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-[var(--text-secondary)] truncate", children: booking.customerName || "Guest" }),
|
|
143
|
+
/* @__PURE__ */ jsx("span", { className: "text-[var(--text-muted)] flex-shrink-0", children: "\xB7" }),
|
|
144
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-[var(--text-muted)] flex-shrink-0", children: shortDate(booking.date) }),
|
|
145
|
+
bookingAmount > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
146
|
+
/* @__PURE__ */ jsx("span", { className: "text-[var(--text-muted)] flex-shrink-0", children: "\xB7" }),
|
|
147
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-[var(--text-primary)] flex-shrink-0", children: formatCurrency(bookingAmount) })
|
|
148
|
+
] })
|
|
149
|
+
] }),
|
|
150
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
151
|
+
/* @__PURE__ */ jsx(
|
|
152
|
+
"span",
|
|
153
|
+
{
|
|
154
|
+
className: `inline-flex items-center px-2 py-0.5 rounded-full text-3xs font-medium ${statusConfig.bgColor} ${statusConfig.color}`,
|
|
155
|
+
children: statusConfig.label
|
|
156
|
+
}
|
|
157
|
+
),
|
|
158
|
+
/* @__PURE__ */ jsx(
|
|
159
|
+
"span",
|
|
160
|
+
{
|
|
161
|
+
className: `inline-flex items-center px-2 py-0.5 rounded-full text-3xs font-medium ${isPaid ? "bg-[var(--success-bg)] text-[var(--success)]" : "bg-[var(--warning-bg)] text-[var(--warning)]"}`,
|
|
162
|
+
children: isPaid ? "Paid" : "Unpaid"
|
|
163
|
+
}
|
|
164
|
+
)
|
|
165
|
+
] })
|
|
166
|
+
] }),
|
|
167
|
+
/* @__PURE__ */ jsx(ChevronRight, { className: "size-4 text-[var(--text-muted)] flex-shrink-0" })
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
),
|
|
171
|
+
meetingLink && /* @__PURE__ */ jsxs(
|
|
172
|
+
"a",
|
|
173
|
+
{
|
|
174
|
+
href: meetingLink,
|
|
175
|
+
target: "_blank",
|
|
176
|
+
rel: "noreferrer",
|
|
177
|
+
className: "flex items-center gap-1 px-3 pb-3 text-xs font-medium text-[var(--text-link)]",
|
|
178
|
+
children: [
|
|
179
|
+
/* @__PURE__ */ jsx(Video, {}),
|
|
180
|
+
joinLabelOf(meetingLink)
|
|
181
|
+
]
|
|
182
|
+
}
|
|
183
|
+
)
|
|
184
|
+
] }, booking.id)
|
|
185
|
+
);
|
|
186
|
+
}) }) })
|
|
187
|
+
] });
|
|
188
|
+
}
|
|
189
|
+
export {
|
|
190
|
+
BookingsTable
|
|
191
|
+
};
|
|
192
|
+
//# sourceMappingURL=bookings-table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/dashboard/%28bookings%29/bookings/_components/bookings-table.tsx"],"sourcesContent":["import { useItemLinks } from '@withpotter/lib/use-item-links';\nimport Link from 'next/link';\nimport { CreditCard, ChevronRight, Video } from 'lucide-react';\nimport type { BookingItem } from '@withpotter/lib/api/types';\nimport { joinLabelOf, meetingLinkOf } from '@withpotter/lib/booking-meeting-link';\nimport { TableShell, Th, TableRow } from '@withpotter/ui-kit/table-shell';\nimport { StatusBadge } from '@withpotter/components/shared/status-badge';\nimport { useEntityLabel } from '@withpotter/lib/intents/use-entity-label';\nimport {\n useBookingStatusConfig,\n type BookingStatus,\n} from './booking-constants';\n\ninterface BookingsTableProps {\n /** Pagination, rendered inside the table container rather than below it. */\n footer?: React.ReactNode;\n /**\n * Search and filters, inside the table container above the rows — the same\n * reasoning as `footer`, at the other end.\n */\n toolbar?: React.ReactNode;\n bookings: BookingItem[];\n formatCurrency: (amount: number) => string;\n formatDate: (dateString: string) => string;\n formatTime: (time?: string) => string;\n /** Selecting a row opens the booking's detail page. */\n onSelectRow?: (booking: BookingItem) => void;\n}\n\nfunction shortDate(dateString: string): string {\n return new Date(dateString).toLocaleString('en-US', {\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n });\n}\n\n/**\n * The way into an online booking, on the row.\n *\n * A merchant running a day of consultations wants the list to BE the day: the\n * link is what the row is for at the hour it happens, and sending them into the\n * record to find it costs a screen each time. It sits under the time because\n * that is the fact it belongs to.\n *\n * `stopPropagation` because the row itself opens the booking — without it,\n * pressing Join opens the detail page behind the call.\n */\nfunction JoinLink({ link }: { link: string }) {\n return (\n <a\n href={link}\n target=\"_blank\"\n rel=\"noreferrer\"\n onClick={(e) => e.stopPropagation()}\n className=\"mt-1 inline-flex items-center gap-1 text-xs font-medium text-[var(--text-link)] underline-offset-2 hover:underline\"\n >\n <Video />\n {joinLabelOf(link)}\n </a>\n );\n}\n\nfunction bookingAmountOf(booking: BookingItem): number {\n return (\n (booking.data?.paymentAmount as number) ||\n (booking.data?.total as number) ||\n booking.content?.price ||\n 0\n );\n}\n\nexport function BookingsTable({\n bookings,\n formatCurrency,\n formatDate,\n formatTime,\n onSelectRow,\n footer,\n toolbar,\n}: BookingsTableProps) {\n const links = useItemLinks();\n const statuses = useBookingStatusConfig();\n /* The merchant's nouns, not ours. A spa's list read \"Booking / Item\" over\n columns it calls appointments and services. */\n const bookingLabel = useEntityLabel('booking');\n const itemLabel = useEntityLabel('item');\n\n return (\n <>\n {/* Desktop Table — the shared quiet-table frame */}\n <div className=\"hidden lg:block\">\n <TableShell\n bare\n toolbar={toolbar}\n footer={footer}\n minWidth={780}\n head={\n <tr className=\"h-[44px]\">\n <Th>{bookingLabel.singular}</Th>\n <Th>Customer</Th>\n <Th>{itemLabel.singular}</Th>\n <Th>Date & Time</Th>\n <Th>Status</Th>\n <Th>Payment</Th>\n <Th align=\"right\">Amount</Th>\n <th className=\"w-12\"></th>\n </tr>\n }\n >\n {bookings.map((booking) => {\n // This row's own words: a table reads Served, an appointment does\n // not, and a mixed business has both in one list.\n const rowStatuses = statuses(booking.type);\n const statusConfig =\n rowStatuses[booking.status as BookingStatus] ||\n rowStatuses.pending;\n const isPaid = booking.data?.isPaid === true;\n const bookingAmount = bookingAmountOf(booking);\n const meetingLink = meetingLinkOf(booking);\n\n return (\n <TableRow key={booking.id} onClick={() => onSelectRow?.(booking)}>\n <td>\n <div className=\"text-sm font-medium text-[var(--text-primary)]\">\n #{booking.bookingNumber}\n </div>\n <div className=\"text-xs text-[var(--text-tertiary)] mt-0.5\">\n {formatDate(booking.createdAt)}\n </div>\n </td>\n <td>\n <div className=\"text-sm font-medium text-[var(--text-primary)]\">\n {booking.customerName || 'Guest'}\n </div>\n {booking.customerEmail && (\n <div className=\"text-xs text-[var(--text-tertiary)] truncate\">\n {booking.customerEmail}\n </div>\n )}\n </td>\n <td className=\"text-sm text-[var(--text-primary)]\">\n {booking.content?.title || '—'}\n </td>\n <td>\n <div className=\"text-sm text-[var(--text-primary)]\">\n {formatDate(booking.date)}\n </div>\n <div className=\"text-xs text-[var(--text-tertiary)]\">\n {booking.startTime && formatTime(booking.startTime)}\n {booking.endTime && ` – ${formatTime(booking.endTime)}`}\n </div>\n {meetingLink && <JoinLink link={meetingLink} />}\n </td>\n {/* Two status columns, so both go neutral — the same rule\n orders settled on. Payment was the louder mistake: every\n unpaid booking rendered amber, so a page of ordinary future\n bookings read as a page of problems. */}\n <td>\n <StatusBadge\n neutral\n status={booking.status}\n icon={statusConfig.icon}\n label={statusConfig.label}\n />\n </td>\n <td>\n <StatusBadge\n neutral\n status={isPaid ? 'paid' : 'unpaid'}\n icon={<CreditCard />}\n label={isPaid ? 'Paid' : 'Unpaid'}\n />\n </td>\n <td className=\"text-right text-sm font-medium text-[var(--text-primary)]\">\n {bookingAmount > 0 ? formatCurrency(bookingAmount) : '—'}\n </td>\n <td>\n <ChevronRight className=\"size-4 text-[var(--text-muted)]\" />\n </td>\n </TableRow>\n );\n })}\n </TableShell>\n </div>\n\n {/* Mobile Card List */}\n <div className=\"lg:hidden\">\n <div className=\"bg-[var(--bg-subtle)] rounded-ios-lg overflow-hidden divide-y divide-[var(--border-subtle)]\">\n {bookings.map((booking) => {\n // This row's own words: a table reads Served, an appointment does\n // not, and a mixed business has both in one list.\n const rowStatuses = statuses(booking.type);\n const statusConfig =\n rowStatuses[booking.status as BookingStatus] ||\n rowStatuses.pending;\n const isPaid = booking.data?.isPaid === true;\n const bookingAmount = bookingAmountOf(booking);\n const meetingLink = meetingLinkOf(booking);\n\n return (\n /* The card is a link, so the Join cannot live inside it — an\n anchor in an anchor is invalid, and React silently renders a\n target nobody can press. It sits under the card instead, still\n inside the one divided cell. */\n <div key={booking.id}>\n <Link\n href={links.bookingDetail(booking.id)}\n className=\"flex items-center gap-3 px-3 py-3 active:bg-[var(--bg-muted)] transition-colors\"\n >\n <div className=\"flex-1 min-w-0\">\n {/* Row 1: Service/item name */}\n <span className=\"text-sm font-medium text-[var(--text-primary)] truncate block\">\n {booking.content?.title || `#${booking.bookingNumber}`}\n </span>\n\n {/* Row 2: Customer · Date · Amount */}\n <div className=\"flex items-center gap-2 mt-0.5\">\n <span className=\"text-sm text-[var(--text-secondary)] truncate\">\n {booking.customerName || 'Guest'}\n </span>\n <span className=\"text-[var(--text-muted)] flex-shrink-0\">\n ·\n </span>\n <span className=\"text-sm text-[var(--text-muted)] flex-shrink-0\">\n {shortDate(booking.date)}\n </span>\n {bookingAmount > 0 && (\n <>\n <span className=\"text-[var(--text-muted)] flex-shrink-0\">\n ·\n </span>\n <span className=\"text-sm font-medium text-[var(--text-primary)] flex-shrink-0\">\n {formatCurrency(bookingAmount)}\n </span>\n </>\n )}\n </div>\n\n {/* Row 3: Status + Payment pills */}\n <div className=\"flex items-center gap-2 mt-2\">\n <span\n className={`inline-flex items-center px-2 py-0.5 rounded-full text-3xs font-medium ${statusConfig.bgColor} ${statusConfig.color}`}\n >\n {statusConfig.label}\n </span>\n <span\n className={`inline-flex items-center px-2 py-0.5 rounded-full text-3xs font-medium ${\n isPaid\n ? 'bg-[var(--success-bg)] text-[var(--success)]'\n : 'bg-[var(--warning-bg)] text-[var(--warning)]'\n }`}\n >\n {isPaid ? 'Paid' : 'Unpaid'}\n </span>\n </div>\n </div>\n\n <ChevronRight className=\"size-4 text-[var(--text-muted)] flex-shrink-0\" />\n </Link>\n {meetingLink && (\n <a\n href={meetingLink}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"flex items-center gap-1 px-3 pb-3 text-xs font-medium text-[var(--text-link)]\"\n >\n <Video />\n {joinLabelOf(meetingLink)}\n </a>\n )}\n </div>\n );\n })}\n </div>\n </div>\n </>\n );\n}\n"],"mappings":"AAmDI,SAkLoB,UA3KlB,KAPF;AAnDJ,SAAS,oBAAoB;AAC7B,OAAO,UAAU;AACjB,SAAS,YAAY,cAAc,aAAa;AAEhD,SAAS,aAAa,qBAAqB;AAC3C,SAAS,YAAY,IAAI,gBAAgB;AACzC,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,OAEK;AAkBP,SAAS,UAAU,YAA4B;AAC7C,SAAO,IAAI,KAAK,UAAU,EAAE,eAAe,SAAS;AAAA,IAClD,OAAO;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,EACV,CAAC;AACH;AAaA,SAAS,SAAS,EAAE,KAAK,GAAqB;AAC5C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,MACN,QAAO;AAAA,MACP,KAAI;AAAA,MACJ,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,MAClC,WAAU;AAAA,MAEV;AAAA,4BAAC,SAAM;AAAA,QACN,YAAY,IAAI;AAAA;AAAA;AAAA,EACnB;AAEJ;AAEA,SAAS,gBAAgB,SAA8B;AACrD,SACG,QAAQ,MAAM,iBACd,QAAQ,MAAM,SACf,QAAQ,SAAS,SACjB;AAEJ;AAEO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuB;AACrB,QAAM,QAAQ,aAAa;AAC3B,QAAM,WAAW,uBAAuB;AAGxC,QAAM,eAAe,eAAe,SAAS;AAC7C,QAAM,YAAY,eAAe,MAAM;AAEvC,SACE,iCAEE;AAAA,wBAAC,SAAI,WAAU,mBACb;AAAA,MAAC;AAAA;AAAA,QACC,MAAI;AAAA,QACJ;AAAA,QACA;AAAA,QACA,UAAU;AAAA,QACV,MACE,qBAAC,QAAG,WAAU,YACZ;AAAA,8BAAC,MAAI,uBAAa,UAAS;AAAA,UAC3B,oBAAC,MAAG,sBAAQ;AAAA,UACZ,oBAAC,MAAI,oBAAU,UAAS;AAAA,UACxB,oBAAC,MAAG,yBAAe;AAAA,UACnB,oBAAC,MAAG,oBAAM;AAAA,UACV,oBAAC,MAAG,qBAAO;AAAA,UACX,oBAAC,MAAG,OAAM,SAAQ,oBAAM;AAAA,UACxB,oBAAC,QAAG,WAAU,QAAO;AAAA,WACvB;AAAA,QAGD,mBAAS,IAAI,CAAC,YAAY;AAGzB,gBAAM,cAAc,SAAS,QAAQ,IAAI;AACzC,gBAAM,eACJ,YAAY,QAAQ,MAAuB,KAC3C,YAAY;AACd,gBAAM,SAAS,QAAQ,MAAM,WAAW;AACxC,gBAAM,gBAAgB,gBAAgB,OAAO;AAC7C,gBAAM,cAAc,cAAc,OAAO;AAEzC,iBACE,qBAAC,YAA0B,SAAS,MAAM,cAAc,OAAO,GAC7D;AAAA,iCAAC,QACC;AAAA,mCAAC,SAAI,WAAU,kDAAiD;AAAA;AAAA,gBAC5D,QAAQ;AAAA,iBACZ;AAAA,cACA,oBAAC,SAAI,WAAU,8CACZ,qBAAW,QAAQ,SAAS,GAC/B;AAAA,eACF;AAAA,YACA,qBAAC,QACC;AAAA,kCAAC,SAAI,WAAU,kDACZ,kBAAQ,gBAAgB,SAC3B;AAAA,cACC,QAAQ,iBACP,oBAAC,SAAI,WAAU,gDACZ,kBAAQ,eACX;AAAA,eAEJ;AAAA,YACA,oBAAC,QAAG,WAAU,sCACX,kBAAQ,SAAS,SAAS,UAC7B;AAAA,YACA,qBAAC,QACC;AAAA,kCAAC,SAAI,WAAU,sCACZ,qBAAW,QAAQ,IAAI,GAC1B;AAAA,cACA,qBAAC,SAAI,WAAU,uCACZ;AAAA,wBAAQ,aAAa,WAAW,QAAQ,SAAS;AAAA,gBACjD,QAAQ,WAAW,WAAM,WAAW,QAAQ,OAAO,CAAC;AAAA,iBACvD;AAAA,cACC,eAAe,oBAAC,YAAS,MAAM,aAAa;AAAA,eAC/C;AAAA,YAKA,oBAAC,QACC;AAAA,cAAC;AAAA;AAAA,gBACC,SAAO;AAAA,gBACP,QAAQ,QAAQ;AAAA,gBAChB,MAAM,aAAa;AAAA,gBACnB,OAAO,aAAa;AAAA;AAAA,YACtB,GACF;AAAA,YACA,oBAAC,QACC;AAAA,cAAC;AAAA;AAAA,gBACC,SAAO;AAAA,gBACP,QAAQ,SAAS,SAAS;AAAA,gBAC1B,MAAM,oBAAC,cAAW;AAAA,gBAClB,OAAO,SAAS,SAAS;AAAA;AAAA,YAC3B,GACF;AAAA,YACA,oBAAC,QAAG,WAAU,6DACX,0BAAgB,IAAI,eAAe,aAAa,IAAI,UACvD;AAAA,YACA,oBAAC,QACC,8BAAC,gBAAa,WAAU,mCAAkC,GAC5D;AAAA,eAzDa,QAAQ,EA0DvB;AAAA,QAEJ,CAAC;AAAA;AAAA,IACH,GACF;AAAA,IAGA,oBAAC,SAAI,WAAU,aACb,8BAAC,SAAI,WAAU,+FACZ,mBAAS,IAAI,CAAC,YAAY;AAGzB,YAAM,cAAc,SAAS,QAAQ,IAAI;AACzC,YAAM,eACJ,YAAY,QAAQ,MAAuB,KAC3C,YAAY;AACd,YAAM,SAAS,QAAQ,MAAM,WAAW;AACxC,YAAM,gBAAgB,gBAAgB,OAAO;AAC7C,YAAM,cAAc,cAAc,OAAO;AAEzC;AAAA;AAAA;AAAA;AAAA;AAAA,QAKE,qBAAC,SACC;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAM,MAAM,cAAc,QAAQ,EAAE;AAAA,cACpC,WAAU;AAAA,cAEV;AAAA,qCAAC,SAAI,WAAU,kBAEb;AAAA,sCAAC,UAAK,WAAU,iEACb,kBAAQ,SAAS,SAAS,IAAI,QAAQ,aAAa,IACtD;AAAA,kBAGA,qBAAC,SAAI,WAAU,kCACb;AAAA,wCAAC,UAAK,WAAU,iDACb,kBAAQ,gBAAgB,SAC3B;AAAA,oBACA,oBAAC,UAAK,WAAU,0CAAyC,kBAEzD;AAAA,oBACA,oBAAC,UAAK,WAAU,kDACb,oBAAU,QAAQ,IAAI,GACzB;AAAA,oBACC,gBAAgB,KACf,iCACE;AAAA,0CAAC,UAAK,WAAU,0CAAyC,kBAEzD;AAAA,sBACA,oBAAC,UAAK,WAAU,gEACb,yBAAe,aAAa,GAC/B;AAAA,uBACF;AAAA,qBAEJ;AAAA,kBAGA,qBAAC,SAAI,WAAU,gCACb;AAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,WAAW,0EAA0E,aAAa,OAAO,IAAI,aAAa,KAAK;AAAA,wBAE9H,uBAAa;AAAA;AAAA,oBAChB;AAAA,oBACA;AAAA,sBAAC;AAAA;AAAA,wBACC,WAAW,0EACT,SACI,iDACA,8CACN;AAAA,wBAEC,mBAAS,SAAS;AAAA;AAAA,oBACrB;AAAA,qBACF;AAAA,mBACF;AAAA,gBAEA,oBAAC,gBAAa,WAAU,iDAAgD;AAAA;AAAA;AAAA,UAC1E;AAAA,UACC,eACC;AAAA,YAAC;AAAA;AAAA,cACC,MAAM;AAAA,cACN,QAAO;AAAA,cACP,KAAI;AAAA,cACJ,WAAU;AAAA,cAEV;AAAA,oCAAC,SAAM;AAAA,gBACN,YAAY,WAAW;AAAA;AAAA;AAAA,UAC1B;AAAA,aAhEM,QAAQ,EAkElB;AAAA;AAAA,IAEJ,CAAC,GACH,GACF;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { CalendarClock } from "lucide-react";
|
|
4
|
+
import { StateView } from "@withpotter/ui-kit/state-view";
|
|
5
|
+
import { useApiQuery } from "@withpotter/hooks/use-api-query";
|
|
6
|
+
import { tenantApi } from "@withpotter/lib/api/tenant";
|
|
7
|
+
const BOOKING_KEYS = /* @__PURE__ */ new Set(["bookable", "schedulable"]);
|
|
8
|
+
function CannotTakeBookings() {
|
|
9
|
+
const { data } = useApiQuery(
|
|
10
|
+
["bookings-readiness"],
|
|
11
|
+
(slug) => tenantApi.readiness(slug)
|
|
12
|
+
);
|
|
13
|
+
const blockers = (data?.blockers ?? []).filter(
|
|
14
|
+
(b) => BOOKING_KEYS.has(b.key)
|
|
15
|
+
);
|
|
16
|
+
if (blockers.length === 0) return null;
|
|
17
|
+
return /* @__PURE__ */ jsx(
|
|
18
|
+
StateView,
|
|
19
|
+
{
|
|
20
|
+
kind: "first-run",
|
|
21
|
+
icon: CalendarClock,
|
|
22
|
+
title: "Your booking page is not ready yet",
|
|
23
|
+
description: "Add something customers can book, then choose when they can book it.",
|
|
24
|
+
action: {
|
|
25
|
+
label: "Create a session",
|
|
26
|
+
href: "/dashboard/catalog/new?intent=take-bookings"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
CannotTakeBookings
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=cannot-take-bookings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/dashboard/%28bookings%29/bookings/_components/cannot-take-bookings.tsx"],"sourcesContent":["'use client';\n\nimport { CalendarClock } from 'lucide-react';\nimport { StateView } from '@withpotter/ui-kit/state-view';\nimport { useApiQuery } from '@withpotter/hooks/use-api-query';\nimport { tenantApi } from '@withpotter/lib/api/tenant';\nimport type { StorefrontReadiness } from '@withpotter/lib/api/types';\n\n/**\n * Why nobody can book, on the screen the merchant opens every morning.\n *\n * A booking page draws a fortnight of selectable days whether or not a single\n * session exists — the day strip comes from a date helper, and availability is\n * never called without a service to ask about. So an empty setup does not read\n * as broken: it reads as a business with no free time for two weeks. The\n * customer meets that, decides the place is full or the site is broken, and\n * leaves. Nothing anywhere told the merchant.\n *\n * That is the shape of the churn: every gap in this product fails politely in\n * the dashboard and loudly in front of the customer. This is the counterweight\n * — the same server-side readiness the publish gate reads, said on the daily\n * surface rather than only at the moment of going live, because a business can\n * become unbookable long after it launched (the last person's hours removed,\n * the last session unpublished).\n *\n * Only booking blockers. The shipping and payout answers belong to the go-live\n * gate and to Settings; repeating them here would turn a specific, actionable\n * warning into a second checklist nobody reads.\n */\n\nconst BOOKING_KEYS = new Set(['bookable', 'schedulable']);\n\nexport function CannotTakeBookings() {\n const { data } = useApiQuery<StorefrontReadiness>(\n ['bookings-readiness'],\n (slug) => tenantApi.readiness(slug),\n );\n\n /**\n * Not-asked is not not-ready.\n *\n * `data` is undefined while the check is in flight and on any API that does\n * not serve the route, so anything written as \"warn unless proven ready\"\n * would put a red banner across the top of every booking list on an older\n * backend. It says something only about blockers it has actually been\n * handed.\n */\n const blockers = (data?.blockers ?? []).filter((b) =>\n BOOKING_KEYS.has(b.key),\n );\n if (blockers.length === 0) return null;\n\n return (\n <StateView\n kind=\"first-run\"\n icon={CalendarClock}\n title=\"Your booking page is not ready yet\"\n description=\"Add something customers can book, then choose when they can book it.\"\n action={{\n label: 'Create a session',\n href: '/dashboard/catalog/new?intent=take-bookings',\n }}\n />\n );\n}\n"],"mappings":";AAqDI;AAnDJ,SAAS,qBAAqB;AAC9B,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAyB1B,MAAM,eAAe,oBAAI,IAAI,CAAC,YAAY,aAAa,CAAC;AAEjD,SAAS,qBAAqB;AACnC,QAAM,EAAE,KAAK,IAAI;AAAA,IACf,CAAC,oBAAoB;AAAA,IACrB,CAAC,SAAS,UAAU,UAAU,IAAI;AAAA,EACpC;AAWA,QAAM,YAAY,MAAM,YAAY,CAAC,GAAG;AAAA,IAAO,CAAC,MAC9C,aAAa,IAAI,EAAE,GAAG;AAAA,EACxB;AACA,MAAI,SAAS,WAAW,EAAG,QAAO;AAElC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,MAAM;AAAA,MACN,OAAM;AAAA,MACN,aAAY;AAAA,MACZ,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,MACR;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
function mk(b) {
|
|
2
|
+
return b;
|
|
3
|
+
}
|
|
4
|
+
const DEMO_BOOKINGS = [
|
|
5
|
+
mk({
|
|
6
|
+
id: "demo-b1",
|
|
7
|
+
bookingNumber: "BK-2041",
|
|
8
|
+
type: "table",
|
|
9
|
+
status: "confirmed",
|
|
10
|
+
bookingMode: "reservation",
|
|
11
|
+
origin: "storefront",
|
|
12
|
+
actorType: "customer",
|
|
13
|
+
date: "2026-07-26",
|
|
14
|
+
startTime: "18:00",
|
|
15
|
+
endTime: "19:00",
|
|
16
|
+
durationMinutes: 60,
|
|
17
|
+
customerName: "Tunde Okafor",
|
|
18
|
+
customerEmail: "tunde.okafor@gmail.com",
|
|
19
|
+
customerPhone: "+2348032214408",
|
|
20
|
+
content: {
|
|
21
|
+
id: "c1",
|
|
22
|
+
title: "Braids \xB7 Medium",
|
|
23
|
+
slug: "court-1",
|
|
24
|
+
price: 1e4
|
|
25
|
+
},
|
|
26
|
+
data: { isPaid: true, total: 1e4, paymentAmount: 1e4 },
|
|
27
|
+
createdAt: "2026-07-24T09:12:00.000Z",
|
|
28
|
+
updatedAt: "2026-07-24T09:12:00.000Z"
|
|
29
|
+
}),
|
|
30
|
+
mk({
|
|
31
|
+
id: "demo-b2",
|
|
32
|
+
bookingNumber: "BK-2042",
|
|
33
|
+
type: "table",
|
|
34
|
+
status: "pending",
|
|
35
|
+
bookingMode: "reservation",
|
|
36
|
+
origin: "dashboard",
|
|
37
|
+
actorType: "staff",
|
|
38
|
+
date: "2026-07-26",
|
|
39
|
+
startTime: "19:00",
|
|
40
|
+
endTime: "20:00",
|
|
41
|
+
durationMinutes: 60,
|
|
42
|
+
customerName: "Amara Nwosu",
|
|
43
|
+
customerEmail: "amara.nwosu@gmail.com",
|
|
44
|
+
customerPhone: "+2348025541120",
|
|
45
|
+
content: {
|
|
46
|
+
id: "c2",
|
|
47
|
+
title: "Silk press",
|
|
48
|
+
slug: "court-2",
|
|
49
|
+
price: 12e3
|
|
50
|
+
},
|
|
51
|
+
// deposit taken, balance still due
|
|
52
|
+
data: { isPaid: false, total: 12e3, paymentAmount: 4e3 },
|
|
53
|
+
createdAt: "2026-07-25T14:40:00.000Z",
|
|
54
|
+
updatedAt: "2026-07-25T14:40:00.000Z"
|
|
55
|
+
}),
|
|
56
|
+
mk({
|
|
57
|
+
id: "demo-b3",
|
|
58
|
+
bookingNumber: "BK-2043",
|
|
59
|
+
type: "table",
|
|
60
|
+
status: "checked_in",
|
|
61
|
+
bookingMode: "reservation",
|
|
62
|
+
origin: "storefront",
|
|
63
|
+
actorType: "customer",
|
|
64
|
+
date: "2026-07-26",
|
|
65
|
+
startTime: "17:00",
|
|
66
|
+
endTime: "18:30",
|
|
67
|
+
durationMinutes: 90,
|
|
68
|
+
quantity: 4,
|
|
69
|
+
customerName: "Group \xB7 Emeka +3",
|
|
70
|
+
customerEmail: "emeka.obi@gmail.com",
|
|
71
|
+
customerPhone: "+2347061182093",
|
|
72
|
+
content: {
|
|
73
|
+
id: "c3",
|
|
74
|
+
title: "Locs retwist",
|
|
75
|
+
slug: "court-3",
|
|
76
|
+
price: 16e3
|
|
77
|
+
},
|
|
78
|
+
data: { isPaid: true, total: 16e3, paymentAmount: 16e3 },
|
|
79
|
+
createdAt: "2026-07-25T20:05:00.000Z",
|
|
80
|
+
updatedAt: "2026-07-26T16:58:00.000Z"
|
|
81
|
+
}),
|
|
82
|
+
mk({
|
|
83
|
+
id: "demo-b4",
|
|
84
|
+
bookingNumber: "BK-2039",
|
|
85
|
+
type: "appointment",
|
|
86
|
+
status: "completed",
|
|
87
|
+
bookingMode: "scheduled",
|
|
88
|
+
origin: "dashboard",
|
|
89
|
+
actorType: "staff",
|
|
90
|
+
date: "2026-07-25",
|
|
91
|
+
startTime: "10:00",
|
|
92
|
+
endTime: "11:00",
|
|
93
|
+
durationMinutes: 60,
|
|
94
|
+
customerName: "Ada Eze",
|
|
95
|
+
customerEmail: "ada.eze@yahoo.com",
|
|
96
|
+
customerPhone: "+2348094437781",
|
|
97
|
+
content: {
|
|
98
|
+
id: "c4",
|
|
99
|
+
title: "Coaching \xB7 Coach Zed",
|
|
100
|
+
slug: "coaching",
|
|
101
|
+
price: 15e3
|
|
102
|
+
},
|
|
103
|
+
data: { isPaid: true, total: 15e3, paymentAmount: 15e3 },
|
|
104
|
+
createdAt: "2026-07-22T08:00:00.000Z",
|
|
105
|
+
updatedAt: "2026-07-25T11:05:00.000Z"
|
|
106
|
+
}),
|
|
107
|
+
mk({
|
|
108
|
+
id: "demo-b5",
|
|
109
|
+
bookingNumber: "BK-2037",
|
|
110
|
+
type: "table",
|
|
111
|
+
status: "cancelled",
|
|
112
|
+
bookingMode: "reservation",
|
|
113
|
+
origin: "storefront",
|
|
114
|
+
actorType: "customer",
|
|
115
|
+
date: "2026-07-24",
|
|
116
|
+
startTime: "20:00",
|
|
117
|
+
endTime: "21:00",
|
|
118
|
+
durationMinutes: 60,
|
|
119
|
+
customerName: "Fatima Bello",
|
|
120
|
+
customerEmail: "fatima.bello@outlook.com",
|
|
121
|
+
customerPhone: "+2348119076621",
|
|
122
|
+
content: {
|
|
123
|
+
id: "c2",
|
|
124
|
+
title: "Silk press",
|
|
125
|
+
slug: "court-2",
|
|
126
|
+
price: 12e3
|
|
127
|
+
},
|
|
128
|
+
data: { isPaid: false, total: 12e3 },
|
|
129
|
+
createdAt: "2026-07-21T11:30:00.000Z",
|
|
130
|
+
updatedAt: "2026-07-23T18:12:00.000Z"
|
|
131
|
+
}),
|
|
132
|
+
mk({
|
|
133
|
+
id: "demo-b6",
|
|
134
|
+
bookingNumber: "BK-2035",
|
|
135
|
+
type: "table",
|
|
136
|
+
status: "no_show",
|
|
137
|
+
bookingMode: "reservation",
|
|
138
|
+
origin: "dashboard",
|
|
139
|
+
actorType: "staff",
|
|
140
|
+
date: "2026-07-23",
|
|
141
|
+
startTime: "07:00",
|
|
142
|
+
endTime: "08:00",
|
|
143
|
+
durationMinutes: 60,
|
|
144
|
+
customerName: "Ibrahim Sule",
|
|
145
|
+
customerEmail: "",
|
|
146
|
+
customerPhone: "+2348051129844",
|
|
147
|
+
content: {
|
|
148
|
+
id: "c1",
|
|
149
|
+
title: "Trim & style",
|
|
150
|
+
slug: "court-1",
|
|
151
|
+
price: 8e3
|
|
152
|
+
},
|
|
153
|
+
data: { isPaid: false, total: 8e3, paymentAmount: 2e3 },
|
|
154
|
+
createdAt: "2026-07-20T06:30:00.000Z",
|
|
155
|
+
updatedAt: "2026-07-23T08:10:00.000Z"
|
|
156
|
+
})
|
|
157
|
+
];
|
|
158
|
+
const DEMO_STATS = {
|
|
159
|
+
total: 23,
|
|
160
|
+
today: 6,
|
|
161
|
+
revenue: 268e3,
|
|
162
|
+
byStatus: {
|
|
163
|
+
pending: 3,
|
|
164
|
+
confirmed: 5,
|
|
165
|
+
checked_in: 2,
|
|
166
|
+
completed: 11,
|
|
167
|
+
cancelled: 1,
|
|
168
|
+
no_show: 1
|
|
169
|
+
},
|
|
170
|
+
byType: { table: 18, appointment: 5 }
|
|
171
|
+
};
|
|
172
|
+
export {
|
|
173
|
+
DEMO_BOOKINGS,
|
|
174
|
+
DEMO_STATS
|
|
175
|
+
};
|
|
176
|
+
//# sourceMappingURL=demo-data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/dashboard/%28bookings%29/bookings/_components/demo-data.ts"],"sourcesContent":["import type { BookingItem } from '@withpotter/lib/api/types';\n\n/**\n * Demo bookings for UI design/preview only (activated by `?demo=1`).\n *\n * The backend only runs on staging, so this lets us design the Bookings\n * surface against realistic data. Shapes mirror the real `BookingItem`\n * contract (money lives under `data`, the bookable under `content`) so\n * nothing here is a facade of a different model; swap for live data on staging.\n *\n * Flavoured for a salon: named services and named people, because that is\n * what a bookings business books. Nothing here is vertical-specific in shape.\n */\nfunction mk(b: Partial<BookingItem> & { id: string }): BookingItem {\n return b as unknown as BookingItem;\n}\n\nexport const DEMO_BOOKINGS: BookingItem[] = [\n mk({\n id: 'demo-b1',\n bookingNumber: 'BK-2041',\n type: 'table',\n status: 'confirmed',\n bookingMode: 'reservation',\n origin: 'storefront',\n actorType: 'customer',\n date: '2026-07-26',\n startTime: '18:00',\n endTime: '19:00',\n durationMinutes: 60,\n customerName: 'Tunde Okafor',\n customerEmail: 'tunde.okafor@gmail.com',\n customerPhone: '+2348032214408',\n content: {\n id: 'c1',\n title: 'Braids · Medium',\n slug: 'court-1',\n price: 10000,\n },\n data: { isPaid: true, total: 10000, paymentAmount: 10000 },\n createdAt: '2026-07-24T09:12:00.000Z',\n updatedAt: '2026-07-24T09:12:00.000Z',\n }),\n mk({\n id: 'demo-b2',\n bookingNumber: 'BK-2042',\n type: 'table',\n status: 'pending',\n bookingMode: 'reservation',\n origin: 'dashboard',\n actorType: 'staff',\n date: '2026-07-26',\n startTime: '19:00',\n endTime: '20:00',\n durationMinutes: 60,\n customerName: 'Amara Nwosu',\n customerEmail: 'amara.nwosu@gmail.com',\n customerPhone: '+2348025541120',\n content: {\n id: 'c2',\n title: 'Silk press',\n slug: 'court-2',\n price: 12000,\n },\n // deposit taken, balance still due\n data: { isPaid: false, total: 12000, paymentAmount: 4000 },\n createdAt: '2026-07-25T14:40:00.000Z',\n updatedAt: '2026-07-25T14:40:00.000Z',\n }),\n mk({\n id: 'demo-b3',\n bookingNumber: 'BK-2043',\n type: 'table',\n status: 'checked_in',\n bookingMode: 'reservation',\n origin: 'storefront',\n actorType: 'customer',\n date: '2026-07-26',\n startTime: '17:00',\n endTime: '18:30',\n durationMinutes: 90,\n quantity: 4,\n customerName: 'Group · Emeka +3',\n customerEmail: 'emeka.obi@gmail.com',\n customerPhone: '+2347061182093',\n content: {\n id: 'c3',\n title: 'Locs retwist',\n slug: 'court-3',\n price: 16000,\n },\n data: { isPaid: true, total: 16000, paymentAmount: 16000 },\n createdAt: '2026-07-25T20:05:00.000Z',\n updatedAt: '2026-07-26T16:58:00.000Z',\n }),\n mk({\n id: 'demo-b4',\n bookingNumber: 'BK-2039',\n type: 'appointment',\n status: 'completed',\n bookingMode: 'scheduled',\n origin: 'dashboard',\n actorType: 'staff',\n date: '2026-07-25',\n startTime: '10:00',\n endTime: '11:00',\n durationMinutes: 60,\n customerName: 'Ada Eze',\n customerEmail: 'ada.eze@yahoo.com',\n customerPhone: '+2348094437781',\n content: {\n id: 'c4',\n title: 'Coaching · Coach Zed',\n slug: 'coaching',\n price: 15000,\n },\n data: { isPaid: true, total: 15000, paymentAmount: 15000 },\n createdAt: '2026-07-22T08:00:00.000Z',\n updatedAt: '2026-07-25T11:05:00.000Z',\n }),\n mk({\n id: 'demo-b5',\n bookingNumber: 'BK-2037',\n type: 'table',\n status: 'cancelled',\n bookingMode: 'reservation',\n origin: 'storefront',\n actorType: 'customer',\n date: '2026-07-24',\n startTime: '20:00',\n endTime: '21:00',\n durationMinutes: 60,\n customerName: 'Fatima Bello',\n customerEmail: 'fatima.bello@outlook.com',\n customerPhone: '+2348119076621',\n content: {\n id: 'c2',\n title: 'Silk press',\n slug: 'court-2',\n price: 12000,\n },\n data: { isPaid: false, total: 12000 },\n createdAt: '2026-07-21T11:30:00.000Z',\n updatedAt: '2026-07-23T18:12:00.000Z',\n }),\n mk({\n id: 'demo-b6',\n bookingNumber: 'BK-2035',\n type: 'table',\n status: 'no_show',\n bookingMode: 'reservation',\n origin: 'dashboard',\n actorType: 'staff',\n date: '2026-07-23',\n startTime: '07:00',\n endTime: '08:00',\n durationMinutes: 60,\n customerName: 'Ibrahim Sule',\n customerEmail: '',\n customerPhone: '+2348051129844',\n content: {\n id: 'c1',\n title: 'Trim & style',\n slug: 'court-1',\n price: 8000,\n },\n data: { isPaid: false, total: 8000, paymentAmount: 2000 },\n createdAt: '2026-07-20T06:30:00.000Z',\n updatedAt: '2026-07-23T08:10:00.000Z',\n }),\n];\n\n/** Summary numbers for the 6 desktop stat cards in demo mode. */\nexport const DEMO_STATS = {\n total: 23,\n today: 6,\n revenue: 268000,\n byStatus: {\n pending: 3,\n confirmed: 5,\n checked_in: 2,\n completed: 11,\n cancelled: 1,\n no_show: 1,\n },\n byType: { table: 18, appointment: 5 },\n};\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BOOKING_STATUS_CONFIG } from "./booking-constants";
|
|
2
|
+
import { StatCard } from "@withpotter/components/shared/stat-card";
|
|
3
|
+
import { BookingsTable } from "./bookings-table";
|
|
4
|
+
export {
|
|
5
|
+
BOOKING_STATUS_CONFIG,
|
|
6
|
+
BookingsTable,
|
|
7
|
+
StatCard
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/dashboard/%28bookings%29/bookings/_components/index.ts"],"sourcesContent":["export { BOOKING_STATUS_CONFIG, type BookingStatus } from './booking-constants';\nexport { StatCard } from '@withpotter/components/shared/stat-card';\nexport { BookingsTable } from './bookings-table';\n"],"mappings":"AAAA,SAAS,6BAAiD;AAC1D,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;","names":[]}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import Link from "next/link";
|
|
4
|
+
import { Check, Wallet, UserX } from "lucide-react";
|
|
5
|
+
import { Button } from "@withpotter/ui-kit/button";
|
|
6
|
+
import {
|
|
7
|
+
BOOKING_STATUS_CONFIG
|
|
8
|
+
} from "../booking-constants";
|
|
9
|
+
import { toMinutes, isPaid, bookingTotal } from "../../_hooks/use-today-data";
|
|
10
|
+
function clock(min) {
|
|
11
|
+
if (min == null) return "";
|
|
12
|
+
const h = Math.floor(min / 60);
|
|
13
|
+
const m = min % 60;
|
|
14
|
+
const period = h >= 12 ? "PM" : "AM";
|
|
15
|
+
const h12 = h % 12 === 0 ? 12 : h % 12;
|
|
16
|
+
return `${h12}:${String(m).padStart(2, "0")} ${period}`;
|
|
17
|
+
}
|
|
18
|
+
function BookingCard({
|
|
19
|
+
booking,
|
|
20
|
+
formatCurrency,
|
|
21
|
+
pending,
|
|
22
|
+
onCheckIn,
|
|
23
|
+
onRecordPayment,
|
|
24
|
+
onNoShow
|
|
25
|
+
}) {
|
|
26
|
+
const paid = isPaid(booking);
|
|
27
|
+
const status = booking.status;
|
|
28
|
+
const statusCfg = BOOKING_STATUS_CONFIG[status];
|
|
29
|
+
const isDone = status === "no_show" || status === "completed" || status === "cancelled";
|
|
30
|
+
const start = toMinutes(booking.startTime);
|
|
31
|
+
const end = toMinutes(booking.endTime) ?? (start != null ? start + (booking.durationMinutes ?? 60) : null);
|
|
32
|
+
const spansDays = !!booking.endDate && booking.endDate !== booking.date;
|
|
33
|
+
const span = spansDays && booking.endDate ? Math.max(
|
|
34
|
+
1,
|
|
35
|
+
Math.round(
|
|
36
|
+
(Date.parse(`${booking.endDate}T00:00:00Z`) - Date.parse(`${booking.date}T00:00:00Z`)) / 864e5
|
|
37
|
+
)
|
|
38
|
+
) : 0;
|
|
39
|
+
const unit = booking.data?.rateUnit === "per-night" ? "night" : "day";
|
|
40
|
+
const stayLabel = (iso) => (/* @__PURE__ */ new Date(`${iso}T00:00:00`)).toLocaleDateString("en-US", {
|
|
41
|
+
month: "short",
|
|
42
|
+
day: "numeric"
|
|
43
|
+
});
|
|
44
|
+
const shell = isDone ? "border-[var(--border-subtle)] bg-[var(--bg-subtle)] opacity-70" : paid ? "border-[var(--border-default)] bg-[var(--bg-base)]" : "border-dashed border-[color:color-mix(in_srgb,var(--warning)_45%,transparent)] bg-[color:color-mix(in_srgb,var(--warning-bg)_40%,transparent)]";
|
|
45
|
+
const name = booking.customerName?.trim() || "Walk-in";
|
|
46
|
+
return /* @__PURE__ */ jsxs("div", { className: `rounded-md border p-3 ${shell}`, children: [
|
|
47
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
48
|
+
/* @__PURE__ */ jsx("span", { className: "truncate font-mono text-xs tabular-nums text-[var(--text-secondary)]", children: spansDays ? (
|
|
49
|
+
// Arrival plus length, not both dates: the checkout date is implied,
|
|
50
|
+
// and spelling it out wrapped the line in a narrow lane and threw
|
|
51
|
+
// the status pill onto a second row.
|
|
52
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
53
|
+
stayLabel(booking.date),
|
|
54
|
+
" \xB7 ",
|
|
55
|
+
span,
|
|
56
|
+
" ",
|
|
57
|
+
unit,
|
|
58
|
+
span === 1 ? "" : "s"
|
|
59
|
+
] })
|
|
60
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
61
|
+
clock(start),
|
|
62
|
+
end != null ? ` \u2013 ${clock(end)}` : ""
|
|
63
|
+
] }) }),
|
|
64
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
65
|
+
!paid && !isDone ? /* @__PURE__ */ jsx("span", { className: "inline-flex items-center rounded-full bg-[var(--warning-bg)] px-2 py-0.5 text-3xs font-medium text-[var(--warning)]", children: "Unpaid" }) : null,
|
|
66
|
+
statusCfg ? /* @__PURE__ */ jsx(
|
|
67
|
+
"span",
|
|
68
|
+
{
|
|
69
|
+
className: `inline-flex items-center rounded-full px-2 py-0.5 text-3xs font-medium ${statusCfg.bgColor} ${statusCfg.color}`,
|
|
70
|
+
children: statusCfg.label
|
|
71
|
+
}
|
|
72
|
+
) : null
|
|
73
|
+
] })
|
|
74
|
+
] }),
|
|
75
|
+
/* @__PURE__ */ jsxs(Link, { href: `/dashboard/bookings/${booking.id}`, className: "mt-2 block", children: [
|
|
76
|
+
/* @__PURE__ */ jsx("p", { className: "truncate text-md font-medium text-[var(--text-primary)] hover:text-brand-500", children: name }),
|
|
77
|
+
/* @__PURE__ */ jsxs("p", { className: "truncate text-xs text-[var(--text-tertiary)]", children: [
|
|
78
|
+
booking.customerPhone || booking.content?.title || booking.type,
|
|
79
|
+
bookingTotal(booking) > 0 ? ` \xB7 ${formatCurrency(bookingTotal(booking))}` : ""
|
|
80
|
+
] })
|
|
81
|
+
] }),
|
|
82
|
+
!isDone ? /* @__PURE__ */ jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [
|
|
83
|
+
!paid ? /* @__PURE__ */ jsx(
|
|
84
|
+
Button,
|
|
85
|
+
{
|
|
86
|
+
variant: "primary",
|
|
87
|
+
size: "sm",
|
|
88
|
+
loading: pending === "payment",
|
|
89
|
+
disabled: pending != null,
|
|
90
|
+
icon: /* @__PURE__ */ jsx(Wallet, { className: "h-[13px] w-[13px]" }),
|
|
91
|
+
onClick: onRecordPayment,
|
|
92
|
+
children: "Record payment"
|
|
93
|
+
}
|
|
94
|
+
) : null,
|
|
95
|
+
status === "confirmed" && !booking.checkedInAt ? /* @__PURE__ */ jsx(
|
|
96
|
+
Button,
|
|
97
|
+
{
|
|
98
|
+
variant: paid ? "primary" : "secondary",
|
|
99
|
+
size: "sm",
|
|
100
|
+
loading: pending === "checkin",
|
|
101
|
+
disabled: pending != null,
|
|
102
|
+
icon: /* @__PURE__ */ jsx(Check, { className: "h-[13px] w-[13px]" }),
|
|
103
|
+
onClick: onCheckIn,
|
|
104
|
+
children: "Check in"
|
|
105
|
+
}
|
|
106
|
+
) : null,
|
|
107
|
+
!booking.checkedInAt ? /* @__PURE__ */ jsxs(
|
|
108
|
+
"button",
|
|
109
|
+
{
|
|
110
|
+
type: "button",
|
|
111
|
+
onClick: onNoShow,
|
|
112
|
+
disabled: pending != null,
|
|
113
|
+
className: "ml-auto inline-flex items-center gap-1 text-xs text-[var(--text-tertiary)] transition-colors hover:text-[var(--error)] disabled:opacity-50",
|
|
114
|
+
children: [
|
|
115
|
+
/* @__PURE__ */ jsx(UserX, {}),
|
|
116
|
+
"No-show"
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
) : null
|
|
120
|
+
] }) : null
|
|
121
|
+
] });
|
|
122
|
+
}
|
|
123
|
+
export {
|
|
124
|
+
BookingCard
|
|
125
|
+
};
|
|
126
|
+
//# sourceMappingURL=booking-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../src/dashboard/%28bookings%29/bookings/_components/today/booking-card.tsx"],"sourcesContent":["'use client';\n\nimport Link from 'next/link';\nimport { Check, Wallet, UserX } from 'lucide-react';\nimport { Button } from '@withpotter/ui-kit/button';\nimport {\n BOOKING_STATUS_CONFIG,\n type BookingStatus,\n} from '../booking-constants';\nimport type { BookingItem } from '@withpotter/lib/api/types';\nimport { toMinutes, isPaid, bookingTotal } from '../../_hooks/use-today-data';\n\nfunction clock(min: number | null): string {\n if (min == null) return '';\n const h = Math.floor(min / 60);\n const m = min % 60;\n const period = h >= 12 ? 'PM' : 'AM';\n const h12 = h % 12 === 0 ? 12 : h % 12;\n return `${h12}:${String(m).padStart(2, '0')} ${period}`;\n}\n\ntype Pending = 'checkin' | 'payment' | 'noshow' | null;\n\nexport function BookingCard({\n booking,\n formatCurrency,\n pending,\n onCheckIn,\n onRecordPayment,\n onNoShow,\n}: {\n booking: BookingItem;\n formatCurrency: (n: number, currency?: string) => string;\n pending: Pending;\n onCheckIn: () => void;\n onRecordPayment: () => void;\n onNoShow: () => void;\n}) {\n const paid = isPaid(booking);\n const status = booking.status as BookingStatus;\n const statusCfg = BOOKING_STATUS_CONFIG[status];\n const isDone =\n status === 'no_show' || status === 'completed' || status === 'cancelled';\n const start = toMinutes(booking.startTime);\n const end =\n toMinutes(booking.endTime) ??\n (start != null ? start + (booking.durationMinutes ?? 60) : null);\n\n /**\n * A booking that runs over days is not an eight-hour appointment.\n *\n * Printing both clock times of a four-day reservation gave \"4:00 PM to\n * 12:00 PM\", which reads as a single afternoon and is wrong in the one way\n * that matters at a front desk.\n *\n * The unit comes from how the listing is let, because this archetype covers\n * short-lets, holiday rentals AND venues and they do not measure the same\n * way: a flat goes by the night, a hall booked Friday to Sunday is a two-day\n * hire. Absent for hourly and flat-rate lets, where \"days\" is true of both.\n */\n const spansDays = !!booking.endDate && booking.endDate !== booking.date;\n const span =\n spansDays && booking.endDate\n ? Math.max(\n 1,\n Math.round(\n (Date.parse(`${booking.endDate}T00:00:00Z`) -\n Date.parse(`${booking.date}T00:00:00Z`)) /\n 86_400_000,\n ),\n )\n : 0;\n const unit =\n (booking.data as { rateUnit?: string } | null | undefined)?.rateUnit ===\n 'per-night'\n ? 'night'\n : 'day';\n const stayLabel = (iso: string) =>\n new Date(`${iso}T00:00:00`).toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n });\n\n // Weight follows truth: paid + active is solid; money-not-landed is dashed and\n // wants attention; anything done is muted.\n const shell = isDone\n ? 'border-[var(--border-subtle)] bg-[var(--bg-subtle)] opacity-70'\n : paid\n ? 'border-[var(--border-default)] bg-[var(--bg-base)]'\n : 'border-dashed border-[color:color-mix(in_srgb,var(--warning)_45%,transparent)] bg-[color:color-mix(in_srgb,var(--warning-bg)_40%,transparent)]';\n\n const name = booking.customerName?.trim() || 'Walk-in';\n\n return (\n <div className={`rounded-md border p-3 ${shell}`}>\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"truncate font-mono text-xs tabular-nums text-[var(--text-secondary)]\">\n {spansDays ? (\n // Arrival plus length, not both dates: the checkout date is implied,\n // and spelling it out wrapped the line in a narrow lane and threw\n // the status pill onto a second row.\n <>\n {stayLabel(booking.date)} · {span} {unit}\n {span === 1 ? '' : 's'}\n </>\n ) : (\n <>\n {clock(start)}\n {end != null ? ` – ${clock(end)}` : ''}\n </>\n )}\n </span>\n <div className=\"flex shrink-0 items-center gap-2\">\n {!paid && !isDone ? (\n <span className=\"inline-flex items-center rounded-full bg-[var(--warning-bg)] px-2 py-0.5 text-3xs font-medium text-[var(--warning)]\">\n Unpaid\n </span>\n ) : null}\n {statusCfg ? (\n <span\n className={`inline-flex items-center rounded-full px-2 py-0.5 text-3xs font-medium ${statusCfg.bgColor} ${statusCfg.color}`}\n >\n {statusCfg.label}\n </span>\n ) : null}\n </div>\n </div>\n\n <Link href={`/dashboard/bookings/${booking.id}`} className=\"mt-2 block\">\n <p className=\"truncate text-md font-medium text-[var(--text-primary)] hover:text-brand-500\">\n {name}\n </p>\n <p className=\"truncate text-xs text-[var(--text-tertiary)]\">\n {booking.customerPhone || booking.content?.title || booking.type}\n {bookingTotal(booking) > 0\n ? ` · ${formatCurrency(bookingTotal(booking))}`\n : ''}\n </p>\n </Link>\n\n {!isDone ? (\n <div className=\"mt-3 flex flex-wrap items-center gap-2\">\n {!paid ? (\n <Button\n variant=\"primary\"\n size=\"sm\"\n loading={pending === 'payment'}\n disabled={pending != null}\n icon={<Wallet className=\"h-[13px] w-[13px]\" />}\n onClick={onRecordPayment}\n >\n Record payment\n </Button>\n ) : null}\n {status === 'confirmed' && !booking.checkedInAt ? (\n <Button\n variant={paid ? 'primary' : 'secondary'}\n size=\"sm\"\n loading={pending === 'checkin'}\n disabled={pending != null}\n icon={<Check className=\"h-[13px] w-[13px]\" />}\n onClick={onCheckIn}\n >\n Check in\n </Button>\n ) : null}\n {!booking.checkedInAt ? (\n <button\n type=\"button\"\n onClick={onNoShow}\n disabled={pending != null}\n className=\"ml-auto inline-flex items-center gap-1 text-xs text-[var(--text-tertiary)] transition-colors hover:text-[var(--error)] disabled:opacity-50\"\n >\n <UserX />\n No-show\n </button>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|