@zorgo/next 1.3.0 → 2.0.0

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.
Files changed (66) hide show
  1. package/dist/cli.d.mts +9 -0
  2. package/dist/cli.d.ts +9 -0
  3. package/dist/cli.js +44 -66
  4. package/dist/cli.js.map +1 -1
  5. package/dist/cli.mjs +43 -65
  6. package/dist/cli.mjs.map +1 -1
  7. package/dist/components.d.mts +735 -5
  8. package/dist/components.d.ts +735 -5
  9. package/dist/components.js +3692 -525
  10. package/dist/components.js.map +1 -1
  11. package/dist/components.mjs +3663 -540
  12. package/dist/components.mjs.map +1 -1
  13. package/dist/images.d.mts +25 -13
  14. package/dist/images.d.ts +25 -13
  15. package/dist/images.js +18 -8
  16. package/dist/images.js.map +1 -1
  17. package/dist/images.mjs +15 -8
  18. package/dist/images.mjs.map +1 -1
  19. package/dist/index.d.mts +315 -9
  20. package/dist/index.d.ts +315 -9
  21. package/dist/index.js +58 -52
  22. package/dist/index.js.map +1 -1
  23. package/dist/index.mjs +58 -52
  24. package/dist/index.mjs.map +1 -1
  25. package/dist/item-page.d.mts +6 -0
  26. package/dist/item-page.d.ts +6 -0
  27. package/dist/item-page.js +4 -2
  28. package/dist/item-page.js.map +1 -1
  29. package/dist/item-page.mjs +4 -2
  30. package/dist/item-page.mjs.map +1 -1
  31. package/dist/legal.d.mts +31 -0
  32. package/dist/legal.d.ts +31 -0
  33. package/dist/legal.js +322 -0
  34. package/dist/legal.js.map +1 -0
  35. package/dist/legal.mjs +293 -0
  36. package/dist/legal.mjs.map +1 -0
  37. package/dist/seo.d.mts +56 -1
  38. package/dist/seo.d.ts +56 -1
  39. package/dist/seo.js +111 -2
  40. package/dist/seo.js.map +1 -1
  41. package/dist/seo.mjs +106 -1
  42. package/dist/seo.mjs.map +1 -1
  43. package/dist/server.d.mts +27 -1
  44. package/dist/server.d.ts +27 -1
  45. package/dist/server.js +322 -102
  46. package/dist/server.js.map +1 -1
  47. package/dist/server.mjs +322 -104
  48. package/dist/server.mjs.map +1 -1
  49. package/dist/slugs.d.mts +2 -1
  50. package/dist/slugs.d.ts +2 -1
  51. package/dist/slugs.js +2 -0
  52. package/dist/slugs.js.map +1 -1
  53. package/dist/slugs.mjs +1 -0
  54. package/dist/tree/README.md +2 -2
  55. package/dist/tree/app/error.tsx +12 -3
  56. package/dist/tree/app/global-error.tsx +21 -4
  57. package/dist/tree/app/globals.css +41 -0
  58. package/dist/tree/app/not-found.tsx +17 -3
  59. package/dist/tree/app/privacy/page.tsx.gen.ts +28 -9
  60. package/dist/tree/app/terms/page.tsx.gen.ts +26 -10
  61. package/dist/tree/gitignore +6 -1
  62. package/dist/tree/next.config.ts +6 -5
  63. package/dist/tree/open-next.config.ts +7 -0
  64. package/dist/tree/package.json.gen.ts +8 -2
  65. package/package.json +7 -2
  66. package/dist/tree/app/globals.css.gen.ts +0 -124
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _stripe_stripe_js from '@stripe/stripe-js';
2
2
  import { StripeElementsOptions } from '@stripe/stripe-js';
3
- import * as React from 'react';
4
- import React__default, { RefObject } from 'react';
3
+ import * as React$1 from 'react';
4
+ import React__default, { RefObject, SVGProps } from 'react';
5
5
  import { z } from 'zod';
6
6
  import * as react_jsx_runtime from 'react/jsx-runtime';
7
7
 
@@ -42,12 +42,48 @@ declare const PortionSchemeSchema: z.ZodObject<{
42
42
  }, z.core.$strip>;
43
43
  type PortionScheme = z.infer<typeof PortionSchemeSchema>;
44
44
 
45
+ declare const EventSchema: z.ZodObject<{
46
+ id: z.ZodNumber;
47
+ created_at: z.ZodString;
48
+ severity: z.ZodEnum<{
49
+ error: "error";
50
+ debug: "debug";
51
+ info: "info";
52
+ warn: "warn";
53
+ }>;
54
+ event_name: z.ZodString;
55
+ source: z.ZodEnum<{
56
+ pos: "pos";
57
+ kds: "kds";
58
+ kiosk: "kiosk";
59
+ restaurant_site: "restaurant_site";
60
+ developer_dashboard: "developer_dashboard";
61
+ zorgo_site: "zorgo_site";
62
+ backend: "backend";
63
+ }>;
64
+ service: z.ZodNullable<z.ZodString>;
65
+ device_id: z.ZodNullable<z.ZodNumber>;
66
+ session_id: z.ZodNullable<z.ZodString>;
67
+ request_id: z.ZodNullable<z.ZodString>;
68
+ franchise_id: z.ZodNullable<z.ZodNumber>;
69
+ location_id: z.ZodNullable<z.ZodNumber>;
70
+ user_id: z.ZodNullable<z.ZodString>;
71
+ anonymous_id: z.ZodNullable<z.ZodString>;
72
+ customer_id: z.ZodNullable<z.ZodNumber>;
73
+ order_id: z.ZodNullable<z.ZodNumber>;
74
+ payload: z.ZodRecord<z.ZodString, z.ZodUnknown>;
75
+ stack_trace: z.ZodNullable<z.ZodString>;
76
+ }, z.core.$strip>;
77
+ type EventRow = z.infer<typeof EventSchema>;
78
+
45
79
  type LocationStatus = "active" | "permanently_closed";
46
80
  interface Location {
47
81
  location_id: number;
48
82
  franchise_id: number;
49
83
  name: string;
50
84
  address?: string;
85
+ /** Public storefront number, as staff typed it. Display only. */
86
+ phone?: string;
51
87
  force_close?: boolean;
52
88
  status?: LocationStatus | null;
53
89
  lat?: number | null;
@@ -81,6 +117,7 @@ interface Category {
81
117
  name: string;
82
118
  is_catering?: boolean;
83
119
  rules: Rule[];
120
+ sort_index?: number | null;
84
121
  active_promo_id?: number;
85
122
  }
86
123
  interface ItemVariant {
@@ -92,6 +129,7 @@ interface ItemVariant {
92
129
  rules?: Rule[];
93
130
  portion_scheme_id?: number | null;
94
131
  portion_scheme?: PortionScheme | null;
132
+ sort_index?: number | null;
95
133
  display_price?: number;
96
134
  active_promo_id?: number;
97
135
  }
@@ -114,6 +152,7 @@ interface MenuItem {
114
152
  variants: ItemVariant[];
115
153
  rules: Rule[];
116
154
  description?: string | null;
155
+ sort_index?: number | null;
117
156
  active_promo_id?: number;
118
157
  is_catering?: boolean;
119
158
  }
@@ -149,6 +188,7 @@ interface Rule {
149
188
  max_selection?: number;
150
189
  included_quantity: number;
151
190
  is_portionable?: boolean;
191
+ sort_index?: number | null;
152
192
  items?: RuleItem[];
153
193
  components?: RuleComponent[];
154
194
  }
@@ -159,6 +199,7 @@ interface RuleItem {
159
199
  upcharge_price: number;
160
200
  description?: string | null;
161
201
  behavior?: ScalingBehavior;
202
+ sort_index?: number | null;
162
203
  }
163
204
  interface RuleComponent {
164
205
  component_id: number;
@@ -168,6 +209,7 @@ interface RuleComponent {
168
209
  description?: string | null;
169
210
  behavior?: ScalingBehavior;
170
211
  serving_weight?: number;
212
+ sort_index?: number | null;
171
213
  }
172
214
  interface CustomizationOption {
173
215
  key: string;
@@ -244,6 +286,8 @@ interface Selection {
244
286
  serving_weight?: number;
245
287
  measurement_type?: "weight" | "count";
246
288
  display_unit?: string;
289
+ /** Only populated when type === "item" and the item has its own recipe (item_components). */
290
+ components?: OrderComponent[];
247
291
  }
248
292
  interface Customer {
249
293
  customer_id?: number;
@@ -292,6 +336,10 @@ interface Order {
292
336
  updated_at?: Date | string;
293
337
  table_number?: number;
294
338
  }
339
+ type DetailedOrder = Order & {
340
+ events: EventRow[];
341
+ actorNames?: Record<string, string>;
342
+ };
295
343
  interface Charge {
296
344
  id?: number;
297
345
  order_id?: number;
@@ -364,6 +412,56 @@ interface RecommendationResult {
364
412
  molecular_score?: number;
365
413
  }
366
414
 
415
+ declare const franchiseFeatureConfigs: {
416
+ readonly catering: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodObject<{
417
+ notification_emails: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
418
+ email: z.ZodEmail;
419
+ location_id: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
420
+ }, z.core.$strip>>>>;
421
+ minimum_notice_hours: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
422
+ minimum_people_required: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
423
+ minimum_price: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
424
+ does_cater: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
425
+ preferred_time: z.ZodOptional<z.ZodNullable<z.ZodString>>;
426
+ }, z.core.$strip>>;
427
+ readonly delivery: z.ZodObject<{
428
+ does_deliver: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
429
+ delivery_fee_cents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
430
+ max_delivery_radius_miles: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
431
+ cents_per_mile: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
432
+ }, z.core.$strip>;
433
+ readonly contact: z.ZodObject<{
434
+ forms: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
435
+ key: z.ZodString;
436
+ enabled: z.ZodDefault<z.ZodBoolean>;
437
+ email: z.ZodOptional<z.ZodNullable<z.ZodEmail>>;
438
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
439
+ }, z.core.$strip>>>>;
440
+ }, z.core.$strip>;
441
+ readonly catering_bulk_discount: z.ZodObject<{
442
+ is_active: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
443
+ full_discount_at: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
444
+ maximum_percent_off: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
445
+ }, z.core.$strip>;
446
+ readonly food_truck: z.ZodObject<{
447
+ base_price_per_person_cents: z.ZodNumber;
448
+ default_service_hours: z.ZodNumber;
449
+ additional_hour_rate_cents: z.ZodNumber;
450
+ service_fee_percent: z.ZodNumber;
451
+ sales_tax_percent: z.ZodNumber;
452
+ minimum_booking_fee_cents: z.ZodNumber;
453
+ date_hold_deposit_cents: z.ZodNumber;
454
+ add_ons: z.ZodDefault<z.ZodArray<z.ZodObject<{
455
+ key: z.ZodString;
456
+ label: z.ZodString;
457
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
458
+ price_per_person_cents: z.ZodNumber;
459
+ }, z.core.$strip>>>;
460
+ }, z.core.$strip>;
461
+ };
462
+ type FranchiseFeatureId = keyof typeof franchiseFeatureConfigs;
463
+ type FranchiseFeatureConfig<T extends FranchiseFeatureId> = z.infer<(typeof franchiseFeatureConfigs)[T]>;
464
+
367
465
  interface Menu {
368
466
  items: MenuItem[];
369
467
  categories: Category[];
@@ -371,6 +469,9 @@ interface Menu {
371
469
  rules: Rule[];
372
470
  }
373
471
 
472
+ declare const CAPABILITIES: readonly ["ztech.page.franchises", "ztech.page.locations", "ztech.page.performance", "ztech.page.orders", "ztech.page.configure-location", "ztech.page.franchise-details", "ztech.page.integrations", "ztech.page.menu", "ztech.page.components", "ztech.page.catering", "ztech.page.promotions", "ztech.page.skills", "ztech.page.receipts", "ztech.page.users", "ztech.page.ingredient-inventory", "ztech.page.batch-prep", "ztech.page.devices", "ztech.page.tables", "portal.page.sales", "portal.page.analytics", "portal.page.analytics.overview", "portal.page.analytics.devices", "portal.page.analytics.backend", "portal.page.analytics.website", "portal.page.settings", "orders.view", "orders.refund", "orders.modify", "catering.view", "catering.confirm", "menu.edit", "promotions.edit", "staff.manage", "notifications.manage_self", "notifications.receive"];
473
+ type Capability = (typeof CAPABILITIES)[number];
474
+
374
475
  interface ModalInstance {
375
476
  type: string;
376
477
  props: any;
@@ -426,6 +527,8 @@ declare function useCart(): {
426
527
  };
427
528
  declare function useLocation(options?: {
428
529
  promptLocationSelection?: boolean;
530
+ /** Location id to select for the user when nothing is selected yet. */
531
+ autoSelectLocationId?: number;
429
532
  }): {
430
533
  availableLocations: Location[];
431
534
  currentLocation: Location | null;
@@ -436,8 +539,12 @@ declare function useLocation(options?: {
436
539
  /**
437
540
  * Reactive menu data for the configured franchise.
438
541
  *
439
- * `items` excludes catering categories; use `allItems`,
440
- * `cateringPrimaryItem`, or `cateringAddOns` when building catering flows.
542
+ * `items` excludes catering categories (Category.is_catering — the sole catering
543
+ * signal per ZOR-396); `allItems` includes them.
544
+ *
545
+ * There is no catering-specific accessor here. A website builds its catering flow
546
+ * from the prebuilt `lib/generated/menu.ts` and `lib/generated/featureConfig.ts`,
547
+ * which is build-time-constant data and doesn't belong behind a reactive hook.
441
548
  *
442
549
  * @example
443
550
  * const { items, categories } = useMenu();
@@ -508,7 +615,7 @@ declare function useItemCustomization(baseItemId: number, seed?: OrderItem, edit
508
615
  quantity: number;
509
616
  setQuantity: (next: number | ((current: number) => number)) => void;
510
617
  comments: string;
511
- setComments: React.Dispatch<React.SetStateAction<string>>;
618
+ setComments: React$1.Dispatch<React$1.SetStateAction<string>>;
512
619
  /**
513
620
  * Set a component's servings for the whole item, or for one section when
514
621
  * `portion` is given. 0 removes it — "no cheese", or "no cheese on the
@@ -531,12 +638,15 @@ declare function usePromotions(): {
531
638
  removePromo: () => void;
532
639
  activePromotions: Promotion[];
533
640
  };
534
- declare function usePayment(): {
641
+ declare function usePayment(options?: {
642
+ appearance?: StripeElementsOptions["appearance"];
643
+ }): {
535
644
  clientSecret: string | null;
536
645
  intentType: "payment_intent" | "setup_intent" | null;
537
646
  stripe: _stripe_stripe_js.Stripe | undefined;
538
647
  elementOptions: StripeElementsOptions | null;
539
648
  total: number | null;
649
+ orderId: number | null;
540
650
  isLoading: boolean;
541
651
  error: string | null;
542
652
  isReady: boolean;
@@ -563,7 +673,11 @@ declare function usePayment(): {
563
673
  amount?: number;
564
674
  paymentIntentId?: string;
565
675
  error?: string;
676
+ isHold: boolean;
677
+ orderId?: number;
678
+ orderToken?: string;
566
679
  };
680
+ mintOrderLinkToken: (orderId: number, email: string) => Promise<string | null>;
567
681
  getReturnUrl: () => string | undefined;
568
682
  };
569
683
  declare function useCateringConfig(): {
@@ -691,6 +805,8 @@ declare const TextFieldSchema: z.ZodObject<{
691
805
  sanitize: z.ZodAny;
692
806
  min: z.ZodOptional<z.ZodString>;
693
807
  max: z.ZodOptional<z.ZodString>;
808
+ multiline: z.ZodDefault<z.ZodBoolean>;
809
+ rows: z.ZodDefault<z.ZodNumber>;
694
810
  }, z.core.$strip>;
695
811
  type TextFieldInput = Partial<z.infer<typeof TextFieldSchema>> & {
696
812
  fieldId: string;
@@ -736,9 +852,9 @@ declare const ClickableSchema: z.ZodObject<{
736
852
  optionSublabelClassName: z.ZodDefault<z.ZodString>;
737
853
  inputClassName: z.ZodDefault<z.ZodString>;
738
854
  }, z.core.$strip>;
739
- type ClickableInput = Partial<z.infer<typeof ClickableSchema>> & {
855
+ type ClickableInput = Omit<Partial<z.infer<typeof ClickableSchema>>, "options"> & {
740
856
  fieldId: string;
741
- options: z.infer<typeof ClickableSchema>["options"];
857
+ options: z.input<typeof ClickableSchema>["options"];
742
858
  };
743
859
 
744
860
  declare function TextField(raw: TextFieldInput): react_jsx_runtime.JSX.Element;
@@ -819,6 +935,8 @@ declare const LocationFieldSchema: z.ZodObject<{
819
935
  sanitize: z.ZodAny;
820
936
  min: z.ZodOptional<z.ZodString>;
821
937
  max: z.ZodOptional<z.ZodString>;
938
+ multiline: z.ZodDefault<z.ZodBoolean>;
939
+ rows: z.ZodDefault<z.ZodNumber>;
822
940
  fieldId: z.ZodDefault<z.ZodString>;
823
941
  label: z.ZodDefault<z.ZodString>;
824
942
  placeholder: z.ZodDefault<z.ZodString>;
@@ -1014,6 +1132,8 @@ declare const NameFieldsSchema: z.ZodObject<{
1014
1132
  sanitize: z.ZodAny;
1015
1133
  min: z.ZodOptional<z.ZodString>;
1016
1134
  max: z.ZodOptional<z.ZodString>;
1135
+ multiline: z.ZodDefault<z.ZodBoolean>;
1136
+ rows: z.ZodDefault<z.ZodNumber>;
1017
1137
  fieldId: z.ZodDefault<z.ZodString>;
1018
1138
  outerClassName: z.ZodDefault<z.ZodString>;
1019
1139
  firstNamePlaceholder: z.ZodDefault<z.ZodString>;
@@ -1183,6 +1303,163 @@ declare function useFormValues(): Record<string, unknown>;
1183
1303
 
1184
1304
  declare function useFormValidity(): boolean;
1185
1305
 
1306
+ type IconComponent = React.FC<SVGProps<SVGSVGElement>>;
1307
+ type StatusColor = "blue" | "green" | "red" | "gray";
1308
+ declare function resolveEventDisplay(eventName: string): {
1309
+ label: string;
1310
+ color: StatusColor;
1311
+ icon?: IconComponent;
1312
+ };
1313
+ interface OrderApproval {
1314
+ status: "requested" | "confirmed" | "rejected";
1315
+ via: "pos" | "email_link" | "dashboard" | null;
1316
+ when: string;
1317
+ actorName: string | null;
1318
+ }
1319
+ /** null means no approval event exists yet — nearly every order today, since the
1320
+ * email-link path never recorded a userId before this ticket. Render that honestly
1321
+ * rather than a blank timeline. */
1322
+ declare function deriveApproval(order: DetailedOrder): OrderApproval | null;
1323
+ interface OrderStatusInfo {
1324
+ label: string;
1325
+ color: StatusColor;
1326
+ }
1327
+ declare function deriveOrderStatus(order: DetailedOrder): OrderStatusInfo;
1328
+ /** Mirrors confirmOrder's own promotable-status check — the button only appears when
1329
+ * clicking it wouldn't just no-op. */
1330
+ declare function isConfirmable(order: DetailedOrder): boolean;
1331
+ interface StatusColorClasses {
1332
+ /** Field behind the status pill or a timeline icon. */
1333
+ bg: string;
1334
+ /** Ink on that field, and on the event's own label. */
1335
+ text: string;
1336
+ /** The bare dot drawn for an event that has no icon of its own. */
1337
+ dot: string;
1338
+ }
1339
+ interface OrderStatusClasses {
1340
+ root: string;
1341
+ statusPill: string;
1342
+ approval: string;
1343
+ approvalEmpty: string;
1344
+ timeline: string;
1345
+ eventIcon: string;
1346
+ eventLabel: string;
1347
+ eventTime: string;
1348
+ connectorLine: string;
1349
+ connectorDelta: string;
1350
+ confirmButton: string;
1351
+ confirmError: string;
1352
+ colors: Record<StatusColor, StatusColorClasses>;
1353
+ }
1354
+ type OrderStatusItemClasses = Partial<Omit<OrderStatusClasses, "colors"> & {
1355
+ colors: Partial<Record<StatusColor, Partial<StatusColorClasses>>>;
1356
+ }>;
1357
+ /** ztech's dark chrome — what this component rendered before it took classes at all,
1358
+ * so a caller that passes none is unchanged. */
1359
+ declare const ORDER_STATUS_DEFAULT_ITEM_CLASSES: OrderStatusClasses;
1360
+ /**
1361
+ * A slot **replaces** its default rather than appending to it: a site theming this is
1362
+ * swapping `text-white` for its own ink, and two conflicting Tailwind classes in one
1363
+ * string resolve by stylesheet order, not by who wrote them last.
1364
+ *
1365
+ * A restaurant site should expect to pass most of them. It reaches this component
1366
+ * through @zorgo/next's index bundle, which its Tailwind never scans (only
1367
+ * dist/components.mjs is @source'd), so a class named *only* in the defaults above
1368
+ * never reaches that site's CSS.
1369
+ */
1370
+ declare function mergeOrderStatusItemClasses(overrides?: OrderStatusItemClasses): OrderStatusClasses;
1371
+ interface OrderStatusProps {
1372
+ order: DetailedOrder;
1373
+ /** A predicate over whichever capabilities the caller already resolved — ztech passes
1374
+ * `useAccess().can`, a token-gated page passes one built from the server's resolved list.
1375
+ * This component never fetches and holds no session of its own. */
1376
+ can: (capability: Capability) => boolean;
1377
+ onConfirm?: () => void | Promise<void>;
1378
+ confirming?: boolean;
1379
+ confirmError?: string | null;
1380
+ /** Per-slot Tailwind classes. Omitted slots keep the dark defaults above. */
1381
+ itemClasses?: OrderStatusItemClasses;
1382
+ }
1383
+ declare function OrderStatus({ order, can, onConfirm, confirming, confirmError, itemClasses }: OrderStatusProps): react_jsx_runtime.JSX.Element;
1384
+
1385
+ interface ItemizedAddOn {
1386
+ name: string;
1387
+ /** The rule/group this selection came from, e.g. "Proteins". */
1388
+ groupName?: string;
1389
+ /** Per-unit upcharge in cents. 0 means included at no extra cost. */
1390
+ upcharge: number;
1391
+ }
1392
+ interface ItemizedLine {
1393
+ name: string;
1394
+ quantity: number;
1395
+ /** One unit priced the way the line is: base + selection upcharges. */
1396
+ unitPrice: number;
1397
+ /** unitPrice * quantity — equals calculateItemPrice(item). */
1398
+ lineTotal: number;
1399
+ /** true = catering per-guest line, false = catering add-on, null/undefined = plain item. */
1400
+ perPerson?: boolean | null;
1401
+ addOns: ItemizedAddOn[];
1402
+ }
1403
+ interface ItemizedOrder {
1404
+ lines: ItemizedLine[];
1405
+ subtotal: number;
1406
+ discount: number;
1407
+ tax: number;
1408
+ serviceFee: number;
1409
+ tip: number;
1410
+ /** What they were charged: charges.total + tip. */
1411
+ total: number;
1412
+ }
1413
+ /**
1414
+ * The receipt: every line with its add-ons, plus the charge breakdown.
1415
+ *
1416
+ * Catering and standard carts are the same shape — a list of items carrying
1417
+ * selections — so there is one loop, and `perPerson` only labels a line for the
1418
+ * UI rather than pricing it differently.
1419
+ *
1420
+ * Totals prefer the order's own settled charges — what was actually billed —
1421
+ * over `calculateCharges`, which reprices against the current menu. A placed
1422
+ * order's money is what Stripe took, not what today's menu would charge; an
1423
+ * un-charged cart (still in checkout) has nothing settled, so it still prices
1424
+ * itself live. Tip is passed in because it lives on the cart, not the order.
1425
+ */
1426
+ declare function itemizeOrder(order: Order, promotion?: Promotion, tip?: number): ItemizedOrder;
1427
+
1428
+ interface OrderItemizedClasses {
1429
+ root: string;
1430
+ line: string;
1431
+ lineName: string;
1432
+ lineSublabel: string;
1433
+ linePrice: string;
1434
+ addOn: string;
1435
+ addOnName: string;
1436
+ addOnPrice: string;
1437
+ totalsRow: string;
1438
+ discountRow: string;
1439
+ totalRow: string;
1440
+ }
1441
+ type OrderItemizedItemClasses = Partial<OrderItemizedClasses>;
1442
+ /** ztech's dark chrome, matching OrderStatus's defaults — a caller that passes none is unchanged. */
1443
+ declare const ORDER_ITEMIZED_DEFAULT_ITEM_CLASSES: OrderItemizedClasses;
1444
+ /**
1445
+ * A slot **replaces** its default rather than appending to it — see OrderStatus's
1446
+ * mergeOrderStatusItemClasses for why (a restaurant site's Tailwind only scans
1447
+ * dist/components.mjs, so a class named only in the defaults never reaches it).
1448
+ */
1449
+ declare function mergeOrderItemizedItemClasses(overrides?: OrderItemizedItemClasses): OrderItemizedClasses;
1450
+ declare function formatCateringLineLabel(line: ItemizedLine): string;
1451
+ declare function formatAddOnPrice(addOn: ItemizedAddOn, perPerson?: boolean | null): string;
1452
+ interface OrderItemizedProps {
1453
+ order: Order;
1454
+ promotion?: Promotion;
1455
+ tip?: number;
1456
+ /** Per-slot Tailwind classes. Omitted slots keep the dark defaults above. */
1457
+ itemClasses?: OrderItemizedItemClasses;
1458
+ }
1459
+ /** The receipt: every line with its add-ons, plus the charge breakdown. Pure render from
1460
+ * itemizeOrder(order) — never fetches, same contract as OrderStatus. */
1461
+ declare function OrderItemized({ order, promotion, tip, itemClasses }: OrderItemizedProps): react_jsx_runtime.JSX.Element;
1462
+
1186
1463
  declare function parsePortion(portion: string): {
1187
1464
  index: number;
1188
1465
  divisions: number;
@@ -1274,4 +1551,33 @@ interface PortionGroup {
1274
1551
  declare function groupItemPortions(item: Pick<OrderItem, "selections" | "components" | "portion_scheme">): PortionGroup[];
1275
1552
  declare function radialSectionPath(index: number, divisions: number, r?: number): string;
1276
1553
 
1277
- export { type Category, CheckboxField, ClickableField, ConditionalRenderer, type Customer, type CustomizationOption, type CustomizationRule, DateField, DateTime, DateTimeRange, DisclaimerText, DiscreteNumberField, DynamicFormShell, EmailField, FieldError, FieldLabel, GuestCountField, Header, IncrementField, type ItemVariant, type Location, LocationField, type Menu, type MenuItem, NameFields, type Order, type OrderComponent, type OrderItem, PhoneField, Platforms, type PortionGroup, PerPersonSummary as PricePreview, type Promotion, type RecommendationRequest, type RecommendationResult, type RecommendationStrategy, type Rule, type RuleComponent, type RuleItem, type RuleSelection, SectionLabel, type Selection, SliderField, SubmitButton, TextField, type TimeConstraints, TimeField, divisionsFor, groupItemPortions, parsePortion, parsePortionKey, portionGlyph, portionKey, portionLabel, portionRows, portionWeight, radialSectionPath, remapPortion, sectionLabel, selectionWeight, setZorgoBoot, setZorgoPathnameHook, splitUpcharge, useCart, useCateringConfig, useCustomer, useField, useFormStatus, useFormValidity, useFormValues, useHydrateMenu, useHydrateStore, useItemCustomization, useLocation, useMenu, useModal, usePayment, usePromotions, useRecommendations, useRegisterField, weightedUpcharges };
1554
+ /** Same opinionated TZ as legacy menu checks. */
1555
+ declare const LOCATION_ORDERING_TIMEZONE = "America/New_York";
1556
+ declare const DAYS: readonly ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
1557
+ /** The open/close instants of one calendar day's window, in LOCATION_ORDERING_TIMEZONE. */
1558
+ interface LocationWindow {
1559
+ /** Lowercase weekday the window's hours were read from. */
1560
+ day: (typeof DAYS)[number];
1561
+ open: Date;
1562
+ close: Date;
1563
+ }
1564
+ /**
1565
+ * The open/close instants for the day `dayOffset` days from `at`, read in
1566
+ * LOCATION_ORDERING_TIMEZONE. Null when that weekday has no hours set.
1567
+ *
1568
+ * A close at or before the open is read as closing after midnight, so an
1569
+ * 11pm–2am window is one continuous night rather than a closed day.
1570
+ */
1571
+ declare function locationWindowOn(at: Date, location: Location, dayOffset?: number): LocationWindow | null;
1572
+ /**
1573
+ * True when the location is outside its weekly open window at `at`
1574
+ * (includes `force_close`). Yesterday's window is checked too, so the small
1575
+ * hours of an overnight window still count as open.
1576
+ */
1577
+ declare function isLocationClosedByWeeklySchedule(at: Date, location: Location): boolean;
1578
+
1579
+ type CateringSiteConfig = Omit<FranchiseFeatureConfig<"catering">, "notification_emails">;
1580
+ type CateringBulkDiscount = FranchiseFeatureConfig<"catering_bulk_discount">;
1581
+ type FoodTruckConfigValue = FranchiseFeatureConfig<"food_truck">;
1582
+
1583
+ export { type Capability, type Category, type CateringBulkDiscount, type CateringSiteConfig, CheckboxField, ClickableField, ConditionalRenderer, type Customer, type CustomizationOption, type CustomizationRule, DateField, DateTime, DateTimeRange, type DetailedOrder, DisclaimerText, DiscreteNumberField, DynamicFormShell, EmailField, type EventRow, FieldError, FieldLabel, type FoodTruckConfigValue, type FranchiseFeatureConfig, GuestCountField, Header, IncrementField, type ItemVariant, type ItemizedAddOn, type ItemizedLine, type ItemizedOrder, LOCATION_ORDERING_TIMEZONE, type Location, LocationField, type LocationWindow, type Menu, type MenuItem, NameFields, ORDER_ITEMIZED_DEFAULT_ITEM_CLASSES, ORDER_STATUS_DEFAULT_ITEM_CLASSES, type Order, type OrderApproval, type OrderComponent, type OrderItem, OrderItemized, type OrderItemizedClasses, type OrderItemizedItemClasses, type OrderItemizedProps, OrderStatus, type OrderStatusClasses, type OrderStatusInfo, type OrderStatusItemClasses, type OrderStatusProps, PhoneField, Platforms, type PortionGroup, PerPersonSummary as PricePreview, type Promotion, type RecommendationRequest, type RecommendationResult, type RecommendationStrategy, type Rule, type RuleComponent, type RuleItem, type RuleSelection, SectionLabel, type Selection, SliderField, type StatusColorClasses, SubmitButton, TextField, type TimeConstraints, TimeField, deriveApproval, deriveOrderStatus, divisionsFor, formatAddOnPrice, formatCateringLineLabel, groupItemPortions, isConfirmable, isLocationClosedByWeeklySchedule, itemizeOrder, locationWindowOn, mergeOrderItemizedItemClasses, mergeOrderStatusItemClasses, parsePortion, parsePortionKey, portionGlyph, portionKey, portionLabel, portionRows, portionWeight, radialSectionPath, remapPortion, resolveEventDisplay, sectionLabel, selectionWeight, setZorgoBoot, setZorgoPathnameHook, splitUpcharge, useCart, useCateringConfig, useCustomer, useField, useFormStatus, useFormValidity, useFormValues, useHydrateMenu, useHydrateStore, useItemCustomization, useLocation, useMenu, useModal, usePayment, usePromotions, useRecommendations, useRegisterField, weightedUpcharges };