@aglyn/plugins-commerce 1.0.0-beta.232 → 1.0.0-beta.234

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 (228) hide show
  1. package/package.json +13 -13
  2. package/src/lib/components/cart-extras.d.ts +6 -0
  3. package/src/lib/components/cart-extras.js +4 -1
  4. package/src/lib/components/cart-extras.js.map +1 -1
  5. package/src/lib/components/cart-fulfillment.d.ts +117 -0
  6. package/src/lib/components/cart-fulfillment.js +367 -0
  7. package/src/lib/components/cart-fulfillment.js.map +1 -0
  8. package/src/lib/components/cart.js +52 -10
  9. package/src/lib/components/cart.js.map +1 -1
  10. package/src/lib/components/commerce-console-page.js +42 -1
  11. package/src/lib/components/commerce-console-page.js.map +1 -1
  12. package/src/lib/components/console/host-orders-card.component.js +38 -10
  13. package/src/lib/components/console/host-orders-card.component.js.map +1 -1
  14. package/src/lib/components/console/local-delivery-settings-card.component.d.ts +37 -0
  15. package/src/lib/components/console/local-delivery-settings-card.component.js +542 -0
  16. package/src/lib/components/console/local-delivery-settings-card.component.js.map +1 -0
  17. package/src/lib/components/console/locations-card.component.js +177 -3
  18. package/src/lib/components/console/locations-card.component.js.map +1 -1
  19. package/src/lib/components/console/order-detail-dialog.component.js +10 -0
  20. package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
  21. package/src/lib/components/console/order-local-fulfillment-panel.component.d.ts +44 -0
  22. package/src/lib/components/console/order-local-fulfillment-panel.component.js +265 -0
  23. package/src/lib/components/console/order-local-fulfillment-panel.component.js.map +1 -0
  24. package/src/lib/components/console/order-offline-notice.component.d.ts +12 -0
  25. package/src/lib/components/console/order-offline-notice.component.js +53 -0
  26. package/src/lib/components/console/order-offline-notice.component.js.map +1 -0
  27. package/src/lib/components/console/pickup-delivery-queue-card.component.d.ts +35 -0
  28. package/src/lib/components/console/pickup-delivery-queue-card.component.js +222 -0
  29. package/src/lib/components/console/pickup-delivery-queue-card.component.js.map +1 -0
  30. package/src/lib/components/console/pos/pos-api.d.ts +24 -1
  31. package/src/lib/components/console/pos/pos-api.js +13 -0
  32. package/src/lib/components/console/pos/pos-api.js.map +1 -1
  33. package/src/lib/components/console/pos/pos-item-dialog.component.d.ts +12 -0
  34. package/src/lib/components/console/pos/pos-item-dialog.component.js +10 -8
  35. package/src/lib/components/console/pos/pos-item-dialog.component.js.map +1 -1
  36. package/src/lib/components/console/pos/pos-kiosk-queue.component.d.ts +22 -0
  37. package/src/lib/components/console/pos/pos-kiosk-queue.component.js +168 -0
  38. package/src/lib/components/console/pos/pos-kiosk-queue.component.js.map +1 -0
  39. package/src/lib/components/console/pos/pos-tender-dialogs.component.d.ts +18 -0
  40. package/src/lib/components/console/pos/pos-tender-dialogs.component.js +116 -1
  41. package/src/lib/components/console/pos/pos-tender-dialogs.component.js.map +1 -1
  42. package/src/lib/components/console/pos/pos-tender-panel.component.d.ts +8 -0
  43. package/src/lib/components/console/pos/pos-tender-panel.component.js +77 -18
  44. package/src/lib/components/console/pos/pos-tender-panel.component.js.map +1 -1
  45. package/src/lib/components/console/pos/use-pos-display.d.ts +5 -2
  46. package/src/lib/components/console/pos/use-pos-display.js +3 -2
  47. package/src/lib/components/console/pos/use-pos-display.js.map +1 -1
  48. package/src/lib/components/console/pos-devices-card.component.js +2 -2
  49. package/src/lib/components/console/pos-devices-card.component.js.map +1 -1
  50. package/src/lib/components/console/pos-display/pairing-screen.d.ts +5 -2
  51. package/src/lib/components/console/pos-display/pairing-screen.js +7 -5
  52. package/src/lib/components/console/pos-display/pairing-screen.js.map +1 -1
  53. package/src/lib/components/console/pos-display/pos-display-api.d.ts +7 -1
  54. package/src/lib/components/console/pos-display/pos-display-api.js +7 -2
  55. package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -1
  56. package/src/lib/components/console/pos-kiosk/kiosk-checkout.d.ts +41 -0
  57. package/src/lib/components/console/pos-kiosk/kiosk-checkout.js +275 -0
  58. package/src/lib/components/console/pos-kiosk/kiosk-checkout.js.map +1 -0
  59. package/src/lib/components/console/pos-kiosk/kiosk-menu.d.ts +32 -0
  60. package/src/lib/components/console/pos-kiosk/kiosk-menu.js +344 -0
  61. package/src/lib/components/console/pos-kiosk/kiosk-menu.js.map +1 -0
  62. package/src/lib/components/console/pos-kiosk/kiosk-staff.d.ts +12 -0
  63. package/src/lib/components/console/pos-kiosk/kiosk-staff.js +257 -0
  64. package/src/lib/components/console/pos-kiosk/kiosk-staff.js.map +1 -0
  65. package/src/lib/components/console/pos-kiosk/pos-kiosk-api.d.ts +114 -0
  66. package/src/lib/components/console/pos-kiosk/pos-kiosk-api.js +189 -0
  67. package/src/lib/components/console/pos-kiosk/pos-kiosk-api.js.map +1 -0
  68. package/src/lib/components/console/pos-kiosk/use-kiosk-idle.d.ts +16 -0
  69. package/src/lib/components/console/pos-kiosk/use-kiosk-idle.js +80 -0
  70. package/src/lib/components/console/pos-kiosk/use-kiosk-idle.js.map +1 -0
  71. package/src/lib/components/console/pos-kiosk-page.component.d.ts +28 -0
  72. package/src/lib/components/console/pos-kiosk-page.component.js +791 -0
  73. package/src/lib/components/console/pos-kiosk-page.component.js.map +1 -0
  74. package/src/lib/components/console/pos-offline/pos-offline-api.d.ts +44 -0
  75. package/src/lib/components/console/pos-offline/pos-offline-api.js +69 -0
  76. package/src/lib/components/console/pos-offline/pos-offline-api.js.map +1 -0
  77. package/src/lib/components/console/pos-offline/pos-offline-banner.component.d.ts +7 -0
  78. package/src/lib/components/console/pos-offline/pos-offline-banner.component.js +135 -0
  79. package/src/lib/components/console/pos-offline/pos-offline-banner.component.js.map +1 -0
  80. package/src/lib/components/console/pos-offline/pos-offline-checkout.component.d.ts +32 -0
  81. package/src/lib/components/console/pos-offline/pos-offline-checkout.component.js +287 -0
  82. package/src/lib/components/console/pos-offline/pos-offline-checkout.component.js.map +1 -0
  83. package/src/lib/components/console/pos-offline/pos-offline-store.d.ts +63 -0
  84. package/src/lib/components/console/pos-offline/pos-offline-store.js +145 -0
  85. package/src/lib/components/console/pos-offline/pos-offline-store.js.map +1 -0
  86. package/src/lib/components/console/pos-offline/register-offline.d.ts +24 -0
  87. package/src/lib/components/console/pos-offline/register-offline.js +24 -0
  88. package/src/lib/components/console/pos-offline/register-offline.js.map +1 -0
  89. package/src/lib/components/console/pos-offline/use-pos-offline.d.ts +85 -0
  90. package/src/lib/components/console/pos-offline/use-pos-offline.js +542 -0
  91. package/src/lib/components/console/pos-offline/use-pos-offline.js.map +1 -0
  92. package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js +72 -17
  93. package/src/lib/components/console/pos-ops/pos-shift-history-card.component.js.map +1 -1
  94. package/src/lib/components/console/pos-page.component.js +174 -27
  95. package/src/lib/components/console/pos-page.component.js.map +1 -1
  96. package/src/lib/components/console/products-hub-card.component.js +35 -10
  97. package/src/lib/components/console/products-hub-card.component.js.map +1 -1
  98. package/src/lib/components/console/shipping-settings-card.component.js +1 -1
  99. package/src/lib/components/console/shipping-settings-card.component.js.map +1 -1
  100. package/src/lib/components/console/stock-movements-card.component.js +48 -16
  101. package/src/lib/components/console/stock-movements-card.component.js.map +1 -1
  102. package/src/lib/components/console/store-zones.d.ts +8 -1
  103. package/src/lib/components/console/store-zones.js +11 -1
  104. package/src/lib/components/console/store-zones.js.map +1 -1
  105. package/src/lib/components/order-status.js +66 -0
  106. package/src/lib/components/order-status.js.map +1 -1
  107. package/src/lib/components/product-detail.js +42 -15
  108. package/src/lib/components/product-detail.js.map +1 -1
  109. package/src/lib/constants/local-fulfillment-list-query.d.ts +48 -0
  110. package/src/lib/constants/local-fulfillment-list-query.js +84 -0
  111. package/src/lib/constants/local-fulfillment-list-query.js.map +1 -0
  112. package/src/lib/constants/orders-list-query.d.ts +7 -2
  113. package/src/lib/constants/orders-list-query.js +89 -8
  114. package/src/lib/constants/orders-list-query.js.map +1 -1
  115. package/src/lib/constants/pos-shift-list-query.d.ts +22 -0
  116. package/src/lib/constants/pos-shift-list-query.js +115 -0
  117. package/src/lib/constants/pos-shift-list-query.js.map +1 -0
  118. package/src/lib/constants/product-list-query.d.ts +6 -1
  119. package/src/lib/constants/product-list-query.js +77 -8
  120. package/src/lib/constants/product-list-query.js.map +1 -1
  121. package/src/lib/constants/stock-movement-query.d.ts +3 -2
  122. package/src/lib/constants/stock-movement-query.js +52 -8
  123. package/src/lib/constants/stock-movement-query.js.map +1 -1
  124. package/src/lib/model/buyer-notifications.d.ts +5 -3
  125. package/src/lib/model/buyer-notifications.js +25 -4
  126. package/src/lib/model/buyer-notifications.js.map +1 -1
  127. package/src/lib/model/commerce-orders.d.ts +59 -0
  128. package/src/lib/model/commerce-orders.js.map +1 -1
  129. package/src/lib/model/commerce-pos-kiosk.d.ts +175 -0
  130. package/src/lib/model/commerce-pos-kiosk.js +147 -0
  131. package/src/lib/model/commerce-pos-kiosk.js.map +1 -0
  132. package/src/lib/model/commerce-pos-offline.d.ts +234 -0
  133. package/src/lib/model/commerce-pos-offline.js +301 -0
  134. package/src/lib/model/commerce-pos-offline.js.map +1 -0
  135. package/src/lib/model/commerce-pos-ops.d.ts +16 -6
  136. package/src/lib/model/commerce-pos-ops.js +12 -4
  137. package/src/lib/model/commerce-pos-ops.js.map +1 -1
  138. package/src/lib/model/commerce-pos.d.ts +13 -1
  139. package/src/lib/model/commerce-pos.js +5 -4
  140. package/src/lib/model/commerce-pos.js.map +1 -1
  141. package/src/lib/model/commerce-stock-holds.d.ts +24 -3
  142. package/src/lib/model/commerce-stock-holds.js +26 -8
  143. package/src/lib/model/commerce-stock-holds.js.map +1 -1
  144. package/src/lib/model/commerce.d.ts +3 -0
  145. package/src/lib/model/commerce.js.map +1 -1
  146. package/src/lib/model/index.d.ts +4 -0
  147. package/src/lib/model/index.js +4 -0
  148. package/src/lib/model/index.js.map +1 -1
  149. package/src/lib/model/local-fulfillment-settings.d.ts +178 -0
  150. package/src/lib/model/local-fulfillment-settings.js +361 -0
  151. package/src/lib/model/local-fulfillment-settings.js.map +1 -0
  152. package/src/lib/model/order-list-fields.d.ts +10 -1
  153. package/src/lib/model/order-list-fields.js +1 -0
  154. package/src/lib/model/order-list-fields.js.map +1 -1
  155. package/src/lib/model/order-local-fulfillment.d.ts +131 -0
  156. package/src/lib/model/order-local-fulfillment.js +125 -0
  157. package/src/lib/model/order-local-fulfillment.js.map +1 -0
  158. package/src/lib/model/order-shipping-export.js +4 -0
  159. package/src/lib/model/order-shipping-export.js.map +1 -1
  160. package/src/lib/model/order-status-view.d.ts +20 -1
  161. package/src/lib/model/order-status-view.js +60 -6
  162. package/src/lib/model/order-status-view.js.map +1 -1
  163. package/src/lib/plugin-config.js +6 -2
  164. package/src/lib/plugin-config.js.map +1 -1
  165. package/src/lib/plugin.js +8 -0
  166. package/src/lib/plugin.js.map +1 -1
  167. package/src/lib/pos-kiosk-config.d.ts +26 -0
  168. package/src/lib/pos-kiosk-config.js +59 -0
  169. package/src/lib/pos-kiosk-config.js.map +1 -0
  170. package/src/lib/server/api-v1/openapi.js +8 -0
  171. package/src/lib/server/api-v1/openapi.js.map +1 -1
  172. package/src/lib/server/api-v1/order-view.d.ts +19 -0
  173. package/src/lib/server/api-v1/order-view.js +35 -0
  174. package/src/lib/server/api-v1/order-view.js.map +1 -1
  175. package/src/lib/server/billing-webhook.js +238 -87
  176. package/src/lib/server/billing-webhook.js.map +1 -1
  177. package/src/lib/server/cart-checkout.d.ts +2 -0
  178. package/src/lib/server/cart-checkout.js +173 -13
  179. package/src/lib/server/cart-checkout.js.map +1 -1
  180. package/src/lib/server/checkout-extras.js +18 -4
  181. package/src/lib/server/checkout-extras.js.map +1 -1
  182. package/src/lib/server/checkout.js +71 -14
  183. package/src/lib/server/checkout.js.map +1 -1
  184. package/src/lib/server/local-fulfillment-status.d.ts +86 -0
  185. package/src/lib/server/local-fulfillment-status.js +379 -0
  186. package/src/lib/server/local-fulfillment-status.js.map +1 -0
  187. package/src/lib/server/local-fulfillment.d.ts +190 -0
  188. package/src/lib/server/local-fulfillment.js +580 -0
  189. package/src/lib/server/local-fulfillment.js.map +1 -0
  190. package/src/lib/server/membership-register.js +3 -1
  191. package/src/lib/server/membership-register.js.map +1 -1
  192. package/src/lib/server/order-notifications.js +61 -0
  193. package/src/lib/server/order-notifications.js.map +1 -1
  194. package/src/lib/server/pos-display.d.ts +27 -1
  195. package/src/lib/server/pos-display.js +50 -9
  196. package/src/lib/server/pos-display.js.map +1 -1
  197. package/src/lib/server/pos-kiosk-principal.d.ts +29 -0
  198. package/src/lib/server/pos-kiosk-principal.js +42 -0
  199. package/src/lib/server/pos-kiosk-principal.js.map +1 -0
  200. package/src/lib/server/pos-kiosk.d.ts +54 -0
  201. package/src/lib/server/pos-kiosk.js +972 -0
  202. package/src/lib/server/pos-kiosk.js.map +1 -0
  203. package/src/lib/server/pos-offline-sync.d.ts +85 -0
  204. package/src/lib/server/pos-offline-sync.js +765 -0
  205. package/src/lib/server/pos-offline-sync.js.map +1 -0
  206. package/src/lib/server/pos-order.js +22 -4
  207. package/src/lib/server/pos-order.js.map +1 -1
  208. package/src/lib/server/pos-payment.d.ts +6 -0
  209. package/src/lib/server/pos-payment.js +225 -6
  210. package/src/lib/server/pos-payment.js.map +1 -1
  211. package/src/lib/server/pos-print.js +5 -0
  212. package/src/lib/server/pos-print.js.map +1 -1
  213. package/src/lib/server/pos-return.js +27 -0
  214. package/src/lib/server/pos-return.js.map +1 -1
  215. package/src/lib/server/pos-sale.d.ts +6 -0
  216. package/src/lib/server/pos-sale.js +2 -0
  217. package/src/lib/server/pos-sale.js.map +1 -1
  218. package/src/lib/server/pos-shift.js +8 -1
  219. package/src/lib/server/pos-shift.js.map +1 -1
  220. package/src/lib/server/refund.js +3 -0
  221. package/src/lib/server/refund.js.map +1 -1
  222. package/src/lib/server/stock-hold.d.ts +9 -1
  223. package/src/lib/server/stock-hold.js +15 -7
  224. package/src/lib/server/stock-hold.js.map +1 -1
  225. package/src/lib/server.js +16 -0
  226. package/src/lib/server.js.map +1 -1
  227. package/src/lib/tenant-emails.js +161 -0
  228. package/src/lib/tenant-emails.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/components/commerce-console-page.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport type { ConsolePluginPageProps } from '@aglyn/aglyn'\nimport { GridItems } from '@aglyn/shared-ui-jsx'\nimport { HubSections } from '@aglyn/shared-ui-next'\nimport type { ReactNode } from 'react'\nimport type { CommerceConsoleSectionId } from './commerce-console-sections'\nimport CatalogOrganizationCard from './console/catalog-organization-card.component'\nimport CommerceAnalyticsCard from './console/commerce-analytics-card.component'\nimport CustomerNotificationsCard from './console/customer-notifications-card.component'\nimport DiscountsCard from './console/discounts-card.component'\nimport GiftCardsCard from './console/gift-cards-card.component'\nimport HostCouponsCard from './console/host-coupons-card.component'\nimport HostOrdersCard from './console/host-orders-card.component'\nimport LocationsCard from './console/locations-card.component'\nimport MemberPostsCard from './console/member-posts-card.component'\nimport OrderWebhooksCard from './console/order-webhooks-card.component'\nimport PaymentsSettingsCard from './console/payments-settings-card.component'\nimport PosShiftHistoryCard from './console/pos-ops/pos-shift-history-card.component'\nimport PosStaffPinsCard from './console/pos-ops/pos-staff-pins-card.component'\nimport PaymentMethodsCard from './console/payment-methods-card.component'\nimport ProductsHubCard from './console/products-hub-card.component'\nimport RecoveryQueueCard from './console/recovery-queue-card.component'\nimport RegistersCard from './console/registers-card.component'\nimport RegisterHardwareCards from './console/register-hardware-card.component'\nimport PosDevicesCard from './console/pos-devices-card.component'\nimport ReservationsCard from './console/reservations-card.component'\nimport ReturnSettingsCard from './console/return-settings-card.component'\nimport ReturnsCard from './console/returns-card.component'\nimport ReviewsModerationCard from './console/reviews-moderation-card.component'\nimport ShippingSettingsCard from './console/shipping-settings-card.component'\nimport ShipStationCard from './console/shipstation-card.component'\nimport ShippingEasyCard from './console/shippingeasy-card.component'\nimport StockMovementsCard from './console/stock-movements-card.component'\nimport StoreSettingsCard from './console/store-settings-card.component'\nimport StorefrontTaxSummaryCard from './console/storefront-tax-summary-card.component'\nimport SuppliersCard from './console/suppliers-card.component'\nimport TaxSettingsCard from './console/tax-settings-card.component'\nimport { COMMERCE_SETTINGS_ZONE } from './console/store-zones'\nimport { useConsoleWidgetSlot } from '@aglyn/aglyn/app-utils/console-widget-slot-context'\n\n/**\n * The `commerceSettings` zone (AGL-3612): other plugins' settings for the\n * store — label settings and carrier accounts — under the store's own.\n */\nfunction CommerceSettingsZone(props: { hostId: string }) {\n const WidgetSlot = useConsoleWidgetSlot()\n return WidgetSlot ? (\n <WidgetSlot slot={COMMERCE_SETTINGS_ZONE.id} hostId={props.hostId} orgId={undefined} />\n ) : null\n}\n\n/**\n * The body of one commerce section, built only when that section is the one\n * being read (AGL-2501).\n *\n * A function rather than a map of nodes on purpose: a `Record<id, ReactNode>`\n * would CONSTRUCT all six every render, and each card opens its Firestore\n * listens on mount — which is the entire cost this page exists to stop paying.\n * Only the returned branch is ever built.\n */\nfunction sectionBody(\n section: CommerceConsoleSectionId,\n hostId: string,\n): ReactNode {\n switch (section) {\n case 'catalog':\n return (\n <GridItems\n spacing={3}\n items={[\n { size: { xs: 12 }, children: <ProductsHubCard hostId={hostId} /> },\n {\n size: { xs: 12 },\n children: <CatalogOrganizationCard hostId={hostId} />,\n },\n // The ledger every stock writer fills and nothing displayed\n // (AGL-2341). Directly under the catalog, because the question\n // it answers — \"why does this count disagree with the shelf\" —\n // is asked while looking at the count.\n {\n size: { xs: 12 },\n children: <StockMovementsCard hostId={hostId} />,\n },\n { size: { xs: 12 }, children: <MemberPostsCard hostId={hostId} /> },\n ]}\n />\n )\n case 'orders':\n return (\n <GridItems\n spacing={3}\n items={[\n { size: { xs: 12 }, children: <HostOrdersCard hostId={hostId} /> },\n // The two queues that feed orders rather than record them\n // (AGL-2227): checkouts that stalled and shoppers waiting on\n // stock. Beneath the orders list because both are pre-order.\n {\n size: { xs: 12 },\n children: <RecoveryQueueCard hostId={hostId} />,\n },\n {\n size: { xs: 12 },\n children: <PosShiftHistoryCard hostId={hostId} />,\n },\n ]}\n />\n )\n case 'returns':\n // Returns (AGL-3611); `?return={id}` opens one on arrival.\n return <ReturnsCard hostId={hostId} />\n case 'promotions':\n return (\n <GridItems\n spacing={3}\n items={[\n { size: { xs: 12 }, children: <DiscountsCard hostId={hostId} /> },\n { size: { xs: 12 }, children: <HostCouponsCard hostId={hostId} /> },\n // Store credit lives with the other money-off surfaces\n // (AGL-2226) — it had no console anywhere before this.\n { size: { xs: 12 }, children: <GiftCardsCard hostId={hostId} /> },\n {\n size: { xs: 12 },\n children: <ReviewsModerationCard hostId={hostId} />,\n },\n ]}\n />\n )\n case 'reservations':\n return <ReservationsCard hostId={hostId} />\n case 'settings':\n return (\n <GridItems\n spacing={3}\n items={[\n {\n size: { xs: 12 },\n children: <PaymentsSettingsCard hostId={hostId} />,\n },\n // What shoppers may pay with (AGL-3629), beside the account the\n // money lands in.\n {\n size: { xs: 12 },\n children: <PaymentMethodsCard hostId={hostId} />,\n },\n {\n size: { xs: 12 },\n children: <StoreSettingsCard hostId={hostId} />,\n },\n {\n size: { xs: 12 },\n children: <ReturnSettingsCard hostId={hostId} />,\n },\n {\n size: { xs: 12 },\n children: <CustomerNotificationsCard hostId={hostId} />,\n },\n { size: { xs: 12 }, children: <TaxSettingsCard hostId={hostId} /> },\n { size: { xs: 12 }, children: <LocationsCard hostId={hostId} /> },\n { size: { xs: 12 }, children: <RegistersCard hostId={hostId} /> },\n { size: { xs: 12 }, children: <PosStaffPinsCard hostId={hostId} /> },\n // A register's printers, cash drawer and status (AGL-3619), one\n // card per register, after the list that names them.\n {\n size: { xs: 12 },\n children: <RegisterHardwareCards hostId={hostId} />,\n },\n { size: { xs: 12 }, children: <PosDevicesCard hostId={hostId} /> },\n {\n size: { xs: 12 },\n children: <ShippingSettingsCard hostId={hostId} />,\n },\n { size: { xs: 12 }, children: <SuppliersCard hostId={hostId} /> },\n { size: { xs: 12 }, children: <ShipStationCard hostId={hostId} /> },\n // ShippingEasy, with the merchant's own keys (AGL-3633).\n { size: { xs: 12 }, children: <ShippingEasyCard hostId={hostId} /> },\n // The store's own endpoints for order events (AGL-3611). Renders\n // nothing for a person who may not manage them.\n {\n size: { xs: 12 },\n children: <OrderWebhooksCard hostId={hostId} />,\n },\n {\n size: { xs: 12 },\n children: <CommerceSettingsZone hostId={hostId} />,\n },\n ]}\n />\n )\n case 'analytics':\n return (\n // Two cards since AGL-2440. The tax summary lives here rather\n // than under Settings → Tax because that tab CONFIGURES tax and\n // this REPORTS what was collected — a merchant reading a figure\n // they may file from should not be one field away from changing\n // the rate that produced it.\n <GridItems\n spacing={3}\n items={[\n {\n size: { xs: 12 },\n children: <CommerceAnalyticsCard hostId={hostId} />,\n },\n {\n size: { xs: 12 },\n children: <StorefrontTaxSummaryCard hostId={hostId} />,\n },\n ]}\n />\n )\n default:\n return null\n }\n}\n\n/**\n * Commerce console page (AGL-395): the Products management surface, owned by\n * the commerce plugin and rendered by the shell's generic plugin route. The\n * product editor's media browser is supplied by the shell's\n * ConsoleMediaPickerProvider (the media library is org/session coupled and\n * stays in the app).\n *\n * ## Sections are ROUTES (AGL-2501)\n *\n * The six sections hold thirty-two Firestore listens between them, and a tab\n * strip mounts every panel: opening Catalog also subscribed the orders,\n * promotions, reservations, settings and analytics cards. The `limit()` on\n * those queries is the bill — several ask for 500, and one load reached a\n * ceiling of ~4,460 documents to render one tab.\n *\n * `HubTabs lazy` bought that back as a flag somebody has to remember. A URL\n * per section makes it structural instead: the page builds one section's body\n * and the others do not exist to subscribe. Three things come with it that the\n * tab version faked — a section is linkable, the back button walks sections,\n * and which one is open is a fact about the URL rather than state kept in sync\n * with it. `commerce-console-read-cost.spec.tsx` meters it at the Firestore\n * boundary and refuses a section that listens before it is opened.\n *\n * The shell resolves the section, gates it and hands back the rail's hrefs;\n * this page only has to say what each section contains.\n */\nexport function CommerceConsolePage(props: ConsolePluginPageProps) {\n const { hostId, section, sections, basePath } = props\n\n /*\n * Nothing, deliberately, while the redirect is in flight.\n *\n * Rendering the default section here instead would issue that section's\n * listens on a URL that is about to be replaced — paying for Catalog on\n * every arrival at `/products`, which is every click of the nav tab.\n */\n if (!section || !sections?.length || !basePath) return null\n\n return (\n <HubSections sections={sections}>\n {sectionBody(section as CommerceConsoleSectionId, hostId)}\n </HubSections>\n )\n}\nCommerceConsolePage.displayName = 'CommerceConsolePage'\n\nexport default CommerceConsolePage\n"],"names":["GridItems","HubSections","CatalogOrganizationCard","CommerceAnalyticsCard","CustomerNotificationsCard","DiscountsCard","GiftCardsCard","HostCouponsCard","HostOrdersCard","LocationsCard","MemberPostsCard","OrderWebhooksCard","PaymentsSettingsCard","PosShiftHistoryCard","PosStaffPinsCard","PaymentMethodsCard","ProductsHubCard","RecoveryQueueCard","RegistersCard","RegisterHardwareCards","PosDevicesCard","ReservationsCard","ReturnSettingsCard","ReturnsCard","ReviewsModerationCard","ShippingSettingsCard","ShipStationCard","ShippingEasyCard","StockMovementsCard","StoreSettingsCard","StorefrontTaxSummaryCard","SuppliersCard","TaxSettingsCard","COMMERCE_SETTINGS_ZONE","useConsoleWidgetSlot","CommerceSettingsZone","props","WidgetSlot","slot","id","hostId","orgId","undefined","sectionBody","section","spacing","items","size","xs","children","CommerceConsolePage","sections","basePath","length","displayName"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAGA,SAASA,SAAS,QAAQ,uBAAsB;AAChD,SAASC,WAAW,QAAQ,wBAAuB;AAGnD,OAAOC,6BAA6B,mDAA+C;AACnF,OAAOC,2BAA2B,iDAA6C;AAC/E,OAAOC,+BAA+B,qDAAiD;AACvF,OAAOC,mBAAmB,wCAAoC;AAC9D,OAAOC,mBAAmB,yCAAqC;AAC/D,OAAOC,qBAAqB,2CAAuC;AACnE,OAAOC,oBAAoB,0CAAsC;AACjE,OAAOC,mBAAmB,wCAAoC;AAC9D,OAAOC,qBAAqB,2CAAuC;AACnE,OAAOC,uBAAuB,6CAAyC;AACvE,OAAOC,0BAA0B,gDAA4C;AAC7E,OAAOC,yBAAyB,wDAAoD;AACpF,OAAOC,sBAAsB,qDAAiD;AAC9E,OAAOC,wBAAwB,8CAA0C;AACzE,OAAOC,qBAAqB,2CAAuC;AACnE,OAAOC,uBAAuB,6CAAyC;AACvE,OAAOC,mBAAmB,wCAAoC;AAC9D,OAAOC,2BAA2B,gDAA4C;AAC9E,OAAOC,oBAAoB,0CAAsC;AACjE,OAAOC,sBAAsB,2CAAuC;AACpE,OAAOC,wBAAwB,8CAA0C;AACzE,OAAOC,iBAAiB,sCAAkC;AAC1D,OAAOC,2BAA2B,iDAA6C;AAC/E,OAAOC,0BAA0B,gDAA4C;AAC7E,OAAOC,qBAAqB,0CAAsC;AAClE,OAAOC,sBAAsB,2CAAuC;AACpE,OAAOC,wBAAwB,8CAA0C;AACzE,OAAOC,uBAAuB,6CAAyC;AACvE,OAAOC,8BAA8B,qDAAiD;AACtF,OAAOC,mBAAmB,wCAAoC;AAC9D,OAAOC,qBAAqB,2CAAuC;AACnE,SAASC,sBAAsB,QAAQ,2BAAuB;AAC9D,SAASC,oBAAoB,QAAQ,qDAAoD;AAEzF;;;CAGC,GACD,SAASC,qBAAqBC,KAAyB;IACrD,MAAMC,aAAaH;IACnB,OAAOG,2BACL,KAACA;QAAWC,MAAML,uBAAuBM,EAAE;QAAEC,QAAQJ,MAAMI,MAAM;QAAEC,OAAOC;SACxE;AACN;AAEA;;;;;;;;CAQC,GACD,SAASC,YACPC,OAAiC,EACjCJ,MAAc;IAEd,OAAQI;QACN,KAAK;YACH,qBACE,KAAC5C;gBACC6C,SAAS;gBACTC,OAAO;oBACL;wBAAEC,MAAM;4BAAEC,IAAI;wBAAG;wBAAGC,wBAAU,KAACjC;4BAAgBwB,QAAQA;;oBAAW;oBAClE;wBACEO,MAAM;4BAAEC,IAAI;wBAAG;wBACfC,wBAAU,KAAC/C;4BAAwBsC,QAAQA;;oBAC7C;oBACA,4DAA4D;oBAC5D,+DAA+D;oBAC/D,+DAA+D;oBAC/D,uCAAuC;oBACvC;wBACEO,MAAM;4BAAEC,IAAI;wBAAG;wBACfC,wBAAU,KAACrB;4BAAmBY,QAAQA;;oBACxC;oBACA;wBAAEO,MAAM;4BAAEC,IAAI;wBAAG;wBAAGC,wBAAU,KAACvC;4BAAgB8B,QAAQA;;oBAAW;iBACnE;;QAGP,KAAK;YACH,qBACE,KAACxC;gBACC6C,SAAS;gBACTC,OAAO;oBACL;wBAAEC,MAAM;4BAAEC,IAAI;wBAAG;wBAAGC,wBAAU,KAACzC;4BAAegC,QAAQA;;oBAAW;oBACjE,0DAA0D;oBAC1D,6DAA6D;oBAC7D,6DAA6D;oBAC7D;wBACEO,MAAM;4BAAEC,IAAI;wBAAG;wBACfC,wBAAU,KAAChC;4BAAkBuB,QAAQA;;oBACvC;oBACA;wBACEO,MAAM;4BAAEC,IAAI;wBAAG;wBACfC,wBAAU,KAACpC;4BAAoB2B,QAAQA;;oBACzC;iBACD;;QAGP,KAAK;YACH,2DAA2D;YAC3D,qBAAO,KAACjB;gBAAYiB,QAAQA;;QAC9B,KAAK;YACH,qBACE,KAACxC;gBACC6C,SAAS;gBACTC,OAAO;oBACL;wBAAEC,MAAM;4BAAEC,IAAI;wBAAG;wBAAGC,wBAAU,KAAC5C;4BAAcmC,QAAQA;;oBAAW;oBAChE;wBAAEO,MAAM;4BAAEC,IAAI;wBAAG;wBAAGC,wBAAU,KAAC1C;4BAAgBiC,QAAQA;;oBAAW;oBAClE,uDAAuD;oBACvD,uDAAuD;oBACvD;wBAAEO,MAAM;4BAAEC,IAAI;wBAAG;wBAAGC,wBAAU,KAAC3C;4BAAckC,QAAQA;;oBAAW;oBAChE;wBACEO,MAAM;4BAAEC,IAAI;wBAAG;wBACfC,wBAAU,KAACzB;4BAAsBgB,QAAQA;;oBAC3C;iBACD;;QAGP,KAAK;YACH,qBAAO,KAACnB;gBAAiBmB,QAAQA;;QACnC,KAAK;YACH,qBACE,KAACxC;gBACC6C,SAAS;gBACTC,OAAO;oBACL;wBACEC,MAAM;4BAAEC,IAAI;wBAAG;wBACfC,wBAAU,KAACrC;4BAAqB4B,QAAQA;;oBAC1C;oBACA,gEAAgE;oBAChE,kBAAkB;oBAClB;wBACEO,MAAM;4BAAEC,IAAI;wBAAG;wBACfC,wBAAU,KAAClC;4BAAmByB,QAAQA;;oBACxC;oBACA;wBACEO,MAAM;4BAAEC,IAAI;wBAAG;wBACfC,wBAAU,KAACpB;4BAAkBW,QAAQA;;oBACvC;oBACA;wBACEO,MAAM;4BAAEC,IAAI;wBAAG;wBACfC,wBAAU,KAAC3B;4BAAmBkB,QAAQA;;oBACxC;oBACA;wBACEO,MAAM;4BAAEC,IAAI;wBAAG;wBACfC,wBAAU,KAAC7C;4BAA0BoC,QAAQA;;oBAC/C;oBACA;wBAAEO,MAAM;4BAAEC,IAAI;wBAAG;wBAAGC,wBAAU,KAACjB;4BAAgBQ,QAAQA;;oBAAW;oBAClE;wBAAEO,MAAM;4BAAEC,IAAI;wBAAG;wBAAGC,wBAAU,KAACxC;4BAAc+B,QAAQA;;oBAAW;oBAChE;wBAAEO,MAAM;4BAAEC,IAAI;wBAAG;wBAAGC,wBAAU,KAAC/B;4BAAcsB,QAAQA;;oBAAW;oBAChE;wBAAEO,MAAM;4BAAEC,IAAI;wBAAG;wBAAGC,wBAAU,KAACnC;4BAAiB0B,QAAQA;;oBAAW;oBACnE,gEAAgE;oBAChE,qDAAqD;oBACrD;wBACEO,MAAM;4BAAEC,IAAI;wBAAG;wBACfC,wBAAU,KAAC9B;4BAAsBqB,QAAQA;;oBAC3C;oBACA;wBAAEO,MAAM;4BAAEC,IAAI;wBAAG;wBAAGC,wBAAU,KAAC7B;4BAAeoB,QAAQA;;oBAAW;oBACjE;wBACEO,MAAM;4BAAEC,IAAI;wBAAG;wBACfC,wBAAU,KAACxB;4BAAqBe,QAAQA;;oBAC1C;oBACA;wBAAEO,MAAM;4BAAEC,IAAI;wBAAG;wBAAGC,wBAAU,KAAClB;4BAAcS,QAAQA;;oBAAW;oBAChE;wBAAEO,MAAM;4BAAEC,IAAI;wBAAG;wBAAGC,wBAAU,KAACvB;4BAAgBc,QAAQA;;oBAAW;oBAClE,yDAAyD;oBACzD;wBAAEO,MAAM;4BAAEC,IAAI;wBAAG;wBAAGC,wBAAU,KAACtB;4BAAiBa,QAAQA;;oBAAW;oBACnE,iEAAiE;oBACjE,gDAAgD;oBAChD;wBACEO,MAAM;4BAAEC,IAAI;wBAAG;wBACfC,wBAAU,KAACtC;4BAAkB6B,QAAQA;;oBACvC;oBACA;wBACEO,MAAM;4BAAEC,IAAI;wBAAG;wBACfC,wBAAU,KAACd;4BAAqBK,QAAQA;;oBAC1C;iBACD;;QAGP,KAAK;YACH,OACE,8DAA8D;YAC9D,gEAAgE;YAChE,gEAAgE;YAChE,gEAAgE;YAChE,6BAA6B;0BAC7B,KAACxC;gBACC6C,SAAS;gBACTC,OAAO;oBACL;wBACEC,MAAM;4BAAEC,IAAI;wBAAG;wBACfC,wBAAU,KAAC9C;4BAAsBqC,QAAQA;;oBAC3C;oBACA;wBACEO,MAAM;4BAAEC,IAAI;wBAAG;wBACfC,wBAAU,KAACnB;4BAAyBU,QAAQA;;oBAC9C;iBACD;;QAGP;YACE,OAAO;IACX;AACF;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;CAyBC,GACD,OAAO,SAASU,oBAAoBd,KAA6B;IAC/D,MAAM,EAAEI,MAAM,EAAEI,OAAO,EAAEO,QAAQ,EAAEC,QAAQ,EAAE,GAAGhB;IAEhD;;;;;;GAMC,GACD,IAAI,CAACQ,WAAW,EAACO,4BAAAA,SAAUE,MAAM,KAAI,CAACD,UAAU,OAAO;IAEvD,qBACE,KAACnD;QAAYkD,UAAUA;kBACpBR,YAAYC,SAAqCJ;;AAGxD;AACAU,oBAAoBI,WAAW,GAAG;AAElC,eAAeJ,oBAAmB"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/components/commerce-console-page.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport type { ConsolePluginPageProps } from '@aglyn/aglyn'\nimport { GridItems } from '@aglyn/shared-ui-jsx'\nimport { HubSections } from '@aglyn/shared-ui-next'\nimport type { ReactNode } from 'react'\nimport type { CommerceConsoleSectionId } from './commerce-console-sections'\nimport CatalogOrganizationCard from './console/catalog-organization-card.component'\nimport CommerceAnalyticsCard from './console/commerce-analytics-card.component'\nimport CustomerNotificationsCard from './console/customer-notifications-card.component'\nimport DiscountsCard from './console/discounts-card.component'\nimport GiftCardsCard from './console/gift-cards-card.component'\nimport HostCouponsCard from './console/host-coupons-card.component'\nimport HostOrdersCard from './console/host-orders-card.component'\nimport LocationsCard from './console/locations-card.component'\nimport LocalDeliverySettingsCard from './console/local-delivery-settings-card.component'\nimport PickupDeliveryQueueCard from './console/pickup-delivery-queue-card.component'\nimport MemberPostsCard from './console/member-posts-card.component'\nimport OrderWebhooksCard from './console/order-webhooks-card.component'\nimport PaymentsSettingsCard from './console/payments-settings-card.component'\nimport PosShiftHistoryCard from './console/pos-ops/pos-shift-history-card.component'\nimport PosStaffPinsCard from './console/pos-ops/pos-staff-pins-card.component'\nimport PaymentMethodsCard from './console/payment-methods-card.component'\nimport ProductsHubCard from './console/products-hub-card.component'\nimport RecoveryQueueCard from './console/recovery-queue-card.component'\nimport RegistersCard from './console/registers-card.component'\nimport RegisterHardwareCards from './console/register-hardware-card.component'\nimport PosDevicesCard from './console/pos-devices-card.component'\nimport ReservationsCard from './console/reservations-card.component'\nimport ReturnSettingsCard from './console/return-settings-card.component'\nimport ReturnsCard from './console/returns-card.component'\nimport ReviewsModerationCard from './console/reviews-moderation-card.component'\nimport ShippingSettingsCard from './console/shipping-settings-card.component'\nimport ShipStationCard from './console/shipstation-card.component'\nimport ShippingEasyCard from './console/shippingeasy-card.component'\nimport StockMovementsCard from './console/stock-movements-card.component'\nimport StoreSettingsCard from './console/store-settings-card.component'\nimport StorefrontTaxSummaryCard from './console/storefront-tax-summary-card.component'\nimport SuppliersCard from './console/suppliers-card.component'\nimport TaxSettingsCard from './console/tax-settings-card.component'\nimport { COMMERCE_PROMOTIONS_ZONE, COMMERCE_SETTINGS_ZONE } from './console/store-zones'\nimport { useConsoleWidgetSlot } from '@aglyn/aglyn/app-utils/console-widget-slot-context'\n\n/**\n * The `commerceSettings` zone (AGL-3612): other plugins' settings for the\n * store — label settings and carrier accounts — under the store's own.\n */\nfunction CommerceSettingsZone(props: { hostId: string }) {\n const WidgetSlot = useConsoleWidgetSlot()\n return WidgetSlot ? (\n <WidgetSlot slot={COMMERCE_SETTINGS_ZONE.id} hostId={props.hostId} orgId={undefined} />\n ) : null\n}\n\n/**\n * The `commercePromotions` zone (AGL-3640): other plugins' programs beside\n * the store's own money-off surfaces — a rewards program first.\n */\nfunction CommercePromotionsZone(props: { hostId: string }) {\n const WidgetSlot = useConsoleWidgetSlot()\n return WidgetSlot ? (\n <WidgetSlot slot={COMMERCE_PROMOTIONS_ZONE.id} hostId={props.hostId} orgId={undefined} />\n ) : null\n}\n\n/**\n * The body of one commerce section, built only when that section is the one\n * being read (AGL-2501).\n *\n * A function rather than a map of nodes on purpose: a `Record<id, ReactNode>`\n * would CONSTRUCT all six every render, and each card opens its Firestore\n * listens on mount — which is the entire cost this page exists to stop paying.\n * Only the returned branch is ever built.\n */\nfunction sectionBody(\n section: CommerceConsoleSectionId,\n hostId: string,\n): ReactNode {\n switch (section) {\n case 'catalog':\n return (\n <GridItems\n spacing={3}\n items={[\n { size: { xs: 12 }, children: <ProductsHubCard hostId={hostId} /> },\n {\n size: { xs: 12 },\n children: <CatalogOrganizationCard hostId={hostId} />,\n },\n // The ledger every stock writer fills and nothing displayed\n // (AGL-2341). Directly under the catalog, because the question\n // it answers — \"why does this count disagree with the shelf\" —\n // is asked while looking at the count.\n {\n size: { xs: 12 },\n children: <StockMovementsCard hostId={hostId} />,\n },\n { size: { xs: 12 }, children: <MemberPostsCard hostId={hostId} /> },\n ]}\n />\n )\n case 'orders':\n return (\n <GridItems\n spacing={3}\n items={[\n { size: { xs: 12 }, children: <HostOrdersCard hostId={hostId} /> },\n // What to prepare, hand over and drive out (AGL-3624). Renders\n // nothing for a store with no pickup and no local delivery.\n {\n size: { xs: 12 },\n children: <PickupDeliveryQueueCard hostId={hostId} />,\n },\n // The two queues that feed orders rather than record them\n // (AGL-2227): checkouts that stalled and shoppers waiting on\n // stock. Beneath the orders list because both are pre-order.\n {\n size: { xs: 12 },\n children: <RecoveryQueueCard hostId={hostId} />,\n },\n {\n size: { xs: 12 },\n children: <PosShiftHistoryCard hostId={hostId} />,\n },\n ]}\n />\n )\n case 'returns':\n // Returns (AGL-3611); `?return={id}` opens one on arrival.\n return <ReturnsCard hostId={hostId} />\n case 'promotions':\n return (\n <GridItems\n spacing={3}\n items={[\n { size: { xs: 12 }, children: <DiscountsCard hostId={hostId} /> },\n { size: { xs: 12 }, children: <HostCouponsCard hostId={hostId} /> },\n // Store credit lives with the other money-off surfaces\n // (AGL-2226) — it had no console anywhere before this.\n { size: { xs: 12 }, children: <GiftCardsCard hostId={hostId} /> },\n {\n size: { xs: 12 },\n children: <ReviewsModerationCard hostId={hostId} />,\n },\n {\n size: { xs: 12 },\n children: <CommercePromotionsZone hostId={hostId} />,\n },\n ]}\n />\n )\n case 'reservations':\n return <ReservationsCard hostId={hostId} />\n case 'settings':\n return (\n <GridItems\n spacing={3}\n items={[\n {\n size: { xs: 12 },\n children: <PaymentsSettingsCard hostId={hostId} />,\n },\n // What shoppers may pay with (AGL-3629), beside the account the\n // money lands in.\n {\n size: { xs: 12 },\n children: <PaymentMethodsCard hostId={hostId} />,\n },\n {\n size: { xs: 12 },\n children: <StoreSettingsCard hostId={hostId} />,\n },\n {\n size: { xs: 12 },\n children: <ReturnSettingsCard hostId={hostId} />,\n },\n {\n size: { xs: 12 },\n children: <CustomerNotificationsCard hostId={hostId} />,\n },\n { size: { xs: 12 }, children: <TaxSettingsCard hostId={hostId} /> },\n { size: { xs: 12 }, children: <LocationsCard hostId={hostId} /> },\n { size: { xs: 12 }, children: <RegistersCard hostId={hostId} /> },\n { size: { xs: 12 }, children: <PosStaffPinsCard hostId={hostId} /> },\n // A register's printers, cash drawer and status (AGL-3619), one\n // card per register, after the list that names them.\n {\n size: { xs: 12 },\n children: <RegisterHardwareCards hostId={hostId} />,\n },\n { size: { xs: 12 }, children: <PosDevicesCard hostId={hostId} /> },\n {\n size: { xs: 12 },\n children: <ShippingSettingsCard hostId={hostId} />,\n },\n // The store's own delivery (AGL-3624); pickup is per location,\n // on the Inventory locations card above.\n {\n size: { xs: 12 },\n children: <LocalDeliverySettingsCard hostId={hostId} />,\n },\n { size: { xs: 12 }, children: <SuppliersCard hostId={hostId} /> },\n { size: { xs: 12 }, children: <ShipStationCard hostId={hostId} /> },\n // ShippingEasy, with the merchant's own keys (AGL-3633).\n { size: { xs: 12 }, children: <ShippingEasyCard hostId={hostId} /> },\n // The store's own endpoints for order events (AGL-3611). Renders\n // nothing for a person who may not manage them.\n {\n size: { xs: 12 },\n children: <OrderWebhooksCard hostId={hostId} />,\n },\n {\n size: { xs: 12 },\n children: <CommerceSettingsZone hostId={hostId} />,\n },\n ]}\n />\n )\n case 'analytics':\n return (\n // Two cards since AGL-2440. The tax summary lives here rather\n // than under Settings → Tax because that tab CONFIGURES tax and\n // this REPORTS what was collected — a merchant reading a figure\n // they may file from should not be one field away from changing\n // the rate that produced it.\n <GridItems\n spacing={3}\n items={[\n {\n size: { xs: 12 },\n children: <CommerceAnalyticsCard hostId={hostId} />,\n },\n {\n size: { xs: 12 },\n children: <StorefrontTaxSummaryCard hostId={hostId} />,\n },\n ]}\n />\n )\n default:\n return null\n }\n}\n\n/**\n * Commerce console page (AGL-395): the Products management surface, owned by\n * the commerce plugin and rendered by the shell's generic plugin route. The\n * product editor's media browser is supplied by the shell's\n * ConsoleMediaPickerProvider (the media library is org/session coupled and\n * stays in the app).\n *\n * ## Sections are ROUTES (AGL-2501)\n *\n * The six sections hold thirty-two Firestore listens between them, and a tab\n * strip mounts every panel: opening Catalog also subscribed the orders,\n * promotions, reservations, settings and analytics cards. The `limit()` on\n * those queries is the bill — several ask for 500, and one load reached a\n * ceiling of ~4,460 documents to render one tab.\n *\n * `HubTabs lazy` bought that back as a flag somebody has to remember. A URL\n * per section makes it structural instead: the page builds one section's body\n * and the others do not exist to subscribe. Three things come with it that the\n * tab version faked — a section is linkable, the back button walks sections,\n * and which one is open is a fact about the URL rather than state kept in sync\n * with it. `commerce-console-read-cost.spec.tsx` meters it at the Firestore\n * boundary and refuses a section that listens before it is opened.\n *\n * The shell resolves the section, gates it and hands back the rail's hrefs;\n * this page only has to say what each section contains.\n */\nexport function CommerceConsolePage(props: ConsolePluginPageProps) {\n const { hostId, section, sections, basePath } = props\n\n /*\n * Nothing, deliberately, while the redirect is in flight.\n *\n * Rendering the default section here instead would issue that section's\n * listens on a URL that is about to be replaced — paying for Catalog on\n * every arrival at `/products`, which is every click of the nav tab.\n */\n if (!section || !sections?.length || !basePath) return null\n\n return (\n <HubSections sections={sections}>\n {sectionBody(section as CommerceConsoleSectionId, hostId)}\n </HubSections>\n )\n}\nCommerceConsolePage.displayName = 'CommerceConsolePage'\n\nexport default CommerceConsolePage\n"],"names":["GridItems","HubSections","CatalogOrganizationCard","CommerceAnalyticsCard","CustomerNotificationsCard","DiscountsCard","GiftCardsCard","HostCouponsCard","HostOrdersCard","LocationsCard","LocalDeliverySettingsCard","PickupDeliveryQueueCard","MemberPostsCard","OrderWebhooksCard","PaymentsSettingsCard","PosShiftHistoryCard","PosStaffPinsCard","PaymentMethodsCard","ProductsHubCard","RecoveryQueueCard","RegistersCard","RegisterHardwareCards","PosDevicesCard","ReservationsCard","ReturnSettingsCard","ReturnsCard","ReviewsModerationCard","ShippingSettingsCard","ShipStationCard","ShippingEasyCard","StockMovementsCard","StoreSettingsCard","StorefrontTaxSummaryCard","SuppliersCard","TaxSettingsCard","COMMERCE_PROMOTIONS_ZONE","COMMERCE_SETTINGS_ZONE","useConsoleWidgetSlot","CommerceSettingsZone","props","WidgetSlot","slot","id","hostId","orgId","undefined","CommercePromotionsZone","sectionBody","section","spacing","items","size","xs","children","CommerceConsolePage","sections","basePath","length","displayName"],"mappings":"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"}
@@ -23,6 +23,7 @@ import { ListPagination } from "@aglyn/shared-ui-jsx/components/list-pagination.
23
23
  import { ListQueryNotices, listQueryRefusals } from "@aglyn/shared-ui-jsx/components/list-query-notices.component";
24
24
  import { ListTable } from "@aglyn/shared-ui-jsx/components/list-table.component";
25
25
  import { hiddenFilterVisibility } from "@aglyn/shared-ui-jsx/const/list-filter";
26
+ import { useListColumnSort } from "@aglyn/shared-ui-jsx/hooks/use-list-column-sort";
26
27
  import { listFilterGridColumns, upsertListFilterClause } from "@aglyn/shared-ui-jsx/const/list-grid-filter";
27
28
  import { useListGridFilter } from "@aglyn/shared-ui-jsx/hooks/use-list-grid-filter";
28
29
  import { useSnackbar } from "@aglyn/shared-ui-snackstack";
@@ -40,7 +41,7 @@ import { commerceListFilter } from "../../transfer/list-filter.js";
40
41
  import { COMMERCE_ORDERS_TRANSFER } from "../../transfer/transfer-keys.js";
41
42
  import OrderShippingActions from "./order-shipping-actions.component.js";
42
43
  import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
43
- import { OPEN_DISPUTE_CLAUSE, ORDER_CHANNEL_OPTIONS, ORDER_DISPUTE_OPTIONS, ORDER_LIST_FIELDS, ORDER_LIST_HEADERS, ORDER_LIST_QUERY, ORDER_LIST_SELECT_FIELDS, ORDER_STATUS_OPTIONS, ordersCustomerClause } from "../../constants/orders-list-query.js";
44
+ import { OPEN_DISPUTE_CLAUSE, ORDER_CHANNEL_OPTIONS, ORDER_LIST_COLUMN_SORTS, ORDER_DISPUTE_OPTIONS, ORDER_LIST_FIELDS, ORDER_LIST_HEADERS, ORDER_LIST_QUERY, ORDER_LIST_SELECT_FIELDS, ORDER_STATUS_OPTIONS, ordersCustomerClause } from "../../constants/orders-list-query.js";
44
45
  import CommerceStatTile from "./commerce-stat-tile.component.js";
45
46
  import { bulkFulfillOrders, BULK_FULFILLABLE_STATUSES, describeBulkFulfill } from "./bulk-fulfill.js";
46
47
  import { ORDERS_BULK_ZONE } from "./store-zones.js";
@@ -72,6 +73,12 @@ const STATS_ORDER_CEILING = 500;
72
73
  'createdAtMs'
73
74
  ];
74
75
  const ORDER_HIDDEN_COLUMNS = hiddenFilterVisibility(ORDER_LIST_FIELDS, ORDER_VISIBLE_COLUMNS);
76
+ /** Total is computed from the refunds, so it sorts the page on screen (AGL-3680). */ const ORDER_PAGE_SORTS = {
77
+ netCents: (row)=>row.netCents
78
+ };
79
+ const ORDER_PAGE_SORT_HEADERS = {
80
+ netCents: 'Total'
81
+ };
75
82
  /**
76
83
  * Orders console (AGL-287): filterable list over webhook-written order
77
84
  * docs with a detail dialog (timeline, fulfill, refund, cancel, notes,
@@ -144,6 +151,14 @@ const ORDER_HIDDEN_COLUMNS = hiddenFilterVisibility(ORDER_LIST_FIELDS, ORDER_VIS
144
151
  });
145
152
  const filtering = clauses.length > 0 || gridFilter.searchWords.some((word)=>word.trim());
146
153
  /*
154
+ * Every header sorts (AGL-3680). Date, Order, Customer, Channel and Status
155
+ * are the query's order over every order (`ORDER_LIST_COLUMN_SORTS`);
156
+ * Total is computed from the refunds, so it sorts the page on screen.
157
+ * Newest first until a header is clicked. A header order other than Date
158
+ * holds only with no filter or search on — the plan falls back to newest
159
+ * first and `ListQueryNotices` says so.
160
+ */ const [askedSort, setAskedSort] = useState(ORDER_LIST_COLUMN_SORTS[0]);
161
+ /*
147
162
  * The open disputes, on their OWN query (AGL-1796). Raised whatever the
148
163
  * list is filtered to — a merchant filtered to "delivered" still has a
149
164
  * deadline running on a `paid` order, and the evidence window is days —
@@ -176,7 +191,8 @@ const ORDER_HIDDEN_COLUMNS = hiddenFilterVisibility(ORDER_LIST_FIELDS, ORDER_VIS
176
191
  declaration: ORDER_LIST_QUERY,
177
192
  request: {
178
193
  clauses,
179
- search: gridFilter.searchWords
194
+ search: gridFilter.searchWords,
195
+ sort: askedSort
180
196
  },
181
197
  deps: [
182
198
  firestore,
@@ -249,6 +265,16 @@ const ORDER_HIDDEN_COLUMNS = hiddenFilterVisibility(ORDER_LIST_FIELDS, ORDER_VIS
249
265
  orders,
250
266
  productNames
251
267
  ]);
268
+ const columnSort = useListColumnSort({
269
+ sorts: ORDER_LIST_COLUMN_SORTS,
270
+ defaultSort: ORDER_LIST_COLUMN_SORTS[0],
271
+ sort: askedSort,
272
+ onSortChange: setAskedSort,
273
+ orderBy: plan.orderBy,
274
+ rows: orderRows,
275
+ pageSorts: ORDER_PAGE_SORTS,
276
+ headers: ORDER_PAGE_SORT_HEADERS
277
+ });
252
278
  const productOptions = useMemo(()=>productWindow.rows.map((product)=>{
253
279
  var _product_name;
254
280
  return {
@@ -634,7 +660,7 @@ const ORDER_HIDDEN_COLUMNS = hiddenFilterVisibility(ORDER_LIST_FIELDS, ORDER_VIS
634
660
  * The store is empty only when an UNFILTERED first page came back empty; a
635
661
  * filter or search that matches nothing keeps the grid, its chips and its
636
662
  * panel, so the reader can take the filter back off.
637
- */ const empty = listStatus === 'success' && !filtering && page === 0 && orders.length === 0;
663
+ */ const empty = listStatus === 'success' && !filtering && askedSort === ORDER_LIST_COLUMN_SORTS[0] && page === 0 && orders.length === 0;
638
664
  return /*#__PURE__*/ _jsxs(CardDisplay, {
639
665
  header: 'Orders',
640
666
  // Shipping actions live in the card header (AGL-3613): the orders
@@ -788,11 +814,14 @@ const ORDER_HIDDEN_COLUMNS = hiddenFilterVisibility(ORDER_LIST_FIELDS, ORDER_VIS
788
814
  }),
789
815
  /*#__PURE__*/ _jsx(ListQueryNotices, {
790
816
  refused: refused,
791
- notices: plan.notices
817
+ notices: [
818
+ ...plan.notices,
819
+ ...columnSort.notices
820
+ ]
792
821
  }),
793
822
  /*#__PURE__*/ _jsx(ListTable, {
794
823
  "aria-label": "Orders",
795
- rows: orderRows,
824
+ rows: columnSort.rows,
796
825
  columns: columns,
797
826
  onOpen: (id)=>setSelectedId(id),
798
827
  selectable: {
@@ -801,15 +830,14 @@ const ORDER_HIDDEN_COLUMNS = hiddenFilterVisibility(ORDER_LIST_FIELDS, ORDER_VIS
801
830
  },
802
831
  loading: listStatus === 'loading',
803
832
  /*
804
- * The grid must NOT also filter, search or sort: the query
805
- * answers all three, and the list has one order — newest first —
806
- * which the query already holds.
833
+ * The grid must NOT also filter, search or sort on its own: the
834
+ * query answers the filters and the search, and every header
835
+ * order is the query's or the page's (`columnSort`).
807
836
  */ filterMode: "server",
808
837
  filterModel: gridFilter.filterModel,
809
838
  onFilterModelChange: gridFilter.onFilterModelChange,
810
839
  quickFilter: true,
811
- sortingMode: "server",
812
- disableColumnSorting: true,
840
+ columnSort: columnSort,
813
841
  // `ListPagination` below pages the query.
814
842
  hideFooter: true,
815
843
  initialState: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/host-orders-card.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n'use client'\n\nimport * as CommerceModel from '../../model'\nimport { CardDisplay } from '@aglyn/shared-ui-jsx'\nimport ListFilterChips from '@aglyn/shared-ui-jsx/components/list-filter-chips.component'\nimport { ListPagination } from '@aglyn/shared-ui-jsx/components/list-pagination.component'\nimport {\n ListQueryNotices,\n listQueryRefusals,\n} from '@aglyn/shared-ui-jsx/components/list-query-notices.component'\nimport { ListTable } from '@aglyn/shared-ui-jsx/components/list-table.component'\nimport { hiddenFilterVisibility } from '@aglyn/shared-ui-jsx/const/list-filter'\nimport {\n type ListFilterClause,\n listFilterGridColumns,\n upsertListFilterClause,\n} from '@aglyn/shared-ui-jsx/const/list-grid-filter'\nimport { useListGridFilter } from '@aglyn/shared-ui-jsx/hooks/use-list-grid-filter'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { checkEntitlement, pluginDocsHelp } from '@aglyn/aglyn'\nimport { ORDERS_CUSTOMER_PARAM, ORDERS_ORDER_PARAM } from '../../model/commerce-record-routes'\nimport {\n Alert,\n AlertTitle,\n Button,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n MenuItem,\n Stack,\n TextField,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport type { GridColDef } from '@mui/x-data-grid'\nimport {\n collection,\n doc,\n getDoc,\n limit,\n orderBy,\n query,\n where,\n} from 'firebase/firestore'\nimport { useSearchParams } from 'next/navigation'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport {\n ceilingedWindow,\n collectionCeiling,\n useFirestore,\n useOrgPlan,\n useUser,\n} from '@aglyn/tenant-feature-instance'\nimport { useFirestoreCollection } from '@aglyn/tenant-feature-instance'\nimport { useListQuery } from '@aglyn/tenant-feature-instance/hooks/use-list-query'\nimport { useTransferLauncher } from '@aglyn/aglyn/app-utils/transfer-launcher-context'\nimport { commerceListFilter } from '../../transfer/list-filter'\nimport { COMMERCE_ORDERS_TRANSFER } from '../../transfer/transfer-keys'\nimport OrderShippingActions from './order-shipping-actions.component'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\n\nimport {\n OPEN_DISPUTE_CLAUSE,\n ORDER_CHANNEL_OPTIONS,\n ORDER_DISPUTE_OPTIONS,\n ORDER_LIST_FIELDS,\n ORDER_LIST_HEADERS,\n ORDER_LIST_QUERY,\n ORDER_LIST_SELECT_FIELDS,\n ORDER_STATUS_OPTIONS,\n ordersCustomerClause,\n} from '../../constants/orders-list-query'\nimport CommerceStatTile from './commerce-stat-tile.component'\nimport { bulkFulfillOrders, BULK_FULFILLABLE_STATUSES, describeBulkFulfill } from './bulk-fulfill'\nimport { ORDERS_BULK_ZONE } from './store-zones'\nimport { useConsoleWidgetSlot } from '@aglyn/aglyn/app-utils/console-widget-slot-context'\nimport OrderDetailDialog, {\n DISPUTE_COLOR,\n} from './order-detail-dialog.component'\n\n/**\n * The products the card reads to NAME a legacy row and the CSV, to offer the\n * Product filter's choices and to fill the draft dialog's picker. A picker's\n * reach, not the list's: the orders themselves are paged by their query and\n * the Product filter asks it for any product id, named here or not.\n */\nconst PRODUCT_NAME_WINDOW = 100\n\n/**\n * How many open disputes the banner reads. Its own query, `disputeKey ==\n * 'open'`, so a deadline is raised whatever the list is filtered to and\n * however deep in the store the order sits; a store past this many open\n * cases is told \"more than\".\n */\nconst OPEN_DISPUTE_CEILING = 50\n\n/**\n * The money tiles read the last sixty days (thirty, and the thirty before it)\n * on their own bounded query. They are analytics over a period, not a filter\n * over the list, and share the analytics card's bound.\n */\nconst STATS_WINDOW_MS = 60 * 24 * 60 * 60 * 1000\nconst STATS_ORDER_CEILING = 500\n\n/** The columns the grid draws; every other declared field is a hidden filter column. */\nconst ORDER_VISIBLE_COLUMNS = [\n 'orderLabel',\n 'customerEmail',\n 'channelKey',\n 'statusKey',\n 'createdAtMs',\n]\nconst ORDER_HIDDEN_COLUMNS = hiddenFilterVisibility(\n ORDER_LIST_FIELDS,\n ORDER_VISIBLE_COLUMNS,\n)\n\nexport interface HostOrdersCardProps {\n hostId: string\n}\n\n/**\n * Orders console (AGL-287): filterable list over webhook-written order\n * docs with a detail dialog (timeline, fulfill, refund, cancel, notes,\n * packing slip) and draft orders that send the buyer a payment link.\n *\n * ## Every filter and the search are on the query (AGL-3321)\n *\n * The list used to read the newest two hundred orders and match its Filters\n * panel and search over them, so a Status filter on a busy store answered\n * \"none\" about every order past the two hundredth. Now each clause and the\n * search word are predicates on ONE Firestore query (`ORDER_LIST_QUERY`),\n * over the fields every writer stamps (`orderListFields`), and the footer\n * pages that query's answer. A combination one query cannot hold is refused\n * by name above the grid and never applied to some rows only.\n */\nexport function HostOrdersCard(props: HostOrdersCardProps) {\n const { hostId } = props\n const firestore = useFirestore()\n const ordersRef = useMemo(\n () => collection(firestore, 'hosts', hostId, 'orders'),\n [firestore, hostId],\n )\n const { data: productDocs } = useFirestoreCollection<any>(\n () =>\n collectionCeiling(\n collection(firestore, 'hosts', hostId, 'products'),\n PRODUCT_NAME_WINDOW,\n ),\n [firestore, hostId],\n { idField: '$id' },\n )\n const productWindow = useMemo(\n () => ceilingedWindow<any>(productDocs ?? undefined, PRODUCT_NAME_WINDOW),\n [productDocs],\n )\n const productNames = useMemo(() => {\n const map: Record<string, string> = {}\n for (const product of productWindow.rows) {\n map[product.$id] = product.name ?? product.$id\n }\n return map\n }, [productWindow])\n\n /**\n * The money tiles are the `commerceAnalytics` surface (AGL-1938,\n * AGL-2056), and this is the third place they appear. Rendering them\n * ungated here would undo both of those passes and hand a Starter org\n * the Pro figures one tab away from the upgrade prompt that refuses\n * them. The TABLE below is not gated — a list of your own orders is not\n * a paid feature.\n */\n const { org, ready: orgReady } = useOrgPlan(hostId)\n const showStats =\n orgReady && checkEntitlement(org as never, 'commerceAnalytics')\n\n /*\n * The grid's clauses (AGL-96, AGL-3317), held here so two things outside\n * the grid can set one: the CRM's contact page links with the buyer's\n * address to answer \"what has this customer ordered\" (AGL-2622) — a whole\n * address is that buyer, a domain every buyer at a company\n * (`ordersCustomerClause`) — and the dispute banner's \"Show them\".\n */\n const searchParams = useSearchParams()\n const [clauses, setClauses] = useState<ListFilterClause[]>(() => {\n const customer = ordersCustomerClause(\n searchParams?.get(ORDERS_CUSTOMER_PARAM) ?? '',\n )\n return customer ? [customer] : []\n })\n const gridFilter = useListGridFilter({\n clauses,\n onChange: setClauses,\n selectFields: ORDER_LIST_SELECT_FIELDS,\n })\n const filtering =\n clauses.length > 0 || gridFilter.searchWords.some((word) => word.trim())\n\n /*\n * The open disputes, on their OWN query (AGL-1796). Raised whatever the\n * list is filtered to — a merchant filtered to \"delivered\" still has a\n * deadline running on a `paid` order, and the evidence window is days —\n * and however far back the order is. Asked before the list so the list's\n * plan is the one a spec reads last.\n */\n const {\n rows: disputedRows,\n hasMore: moreDisputes,\n } = useListQuery<any>({\n collection: ordersRef,\n declaration: ORDER_LIST_QUERY,\n request: { clauses: [OPEN_DISPUTE_CLAUSE] },\n deps: [firestore, hostId],\n idField: '$id',\n pageSize: OPEN_DISPUTE_CEILING,\n // A dispute that closes leaves this query; confirm it before believing it.\n confirmDisappearances: true,\n })\n\n /*\n * THE LIST: every clause and the search word on one query, newest first,\n * paged by the footer. A status, a dispute or a paid draft's address can\n * move an order out of the filtered query mid-session, so a disappearance\n * is confirmed against the server before it is believed (AGL-1196).\n */\n const {\n rows: orders,\n data: loadedOrders,\n hasMore,\n page,\n setPage,\n pageSize,\n setPageSize,\n plan,\n status: listStatus,\n } = useListQuery<any>({\n collection: ordersRef,\n declaration: ORDER_LIST_QUERY,\n request: { clauses, search: gridFilter.searchWords },\n deps: [firestore, hostId],\n idField: '$id',\n confirmDisappearances: true,\n })\n\n const [selectedId, setSelectedId] = useState<string | null>(null)\n // Rows ticked for a bulk act (AGL-3611); the row click still opens one.\n const [checkedIds, setCheckedIds] = useState<string[]>([])\n const [bulkBusy, setBulkBusy] = useState(false)\n const WidgetSlot = useConsoleWidgetSlot()\n /*\n * An order named in the URL opens in its dialog on arrival (AGL-2622). A\n * contact's timeline names the order that made the person a customer,\n * and the address it links to is this list with `?order={id}`. The list\n * shows one page, and an order from last year is not on it, so the\n * document is read once by id and held beside the page for the dialog; an\n * order that IS loaded is found there first and the read is skipped. Once\n * per id — the ref keeps a re-render from reopening a dialog the merchant\n * has since closed — and the landing read is judged against the ref\n * rather than an effect cleanup, because the `setSelectedId` above\n * re-renders before the read lands and a cleanup keyed on any dep would\n * cancel the answer to the question just asked.\n */\n const seededOrderId = searchParams?.get(ORDERS_ORDER_PARAM) ?? null\n const [seededOrder, setSeededOrder] = useState<any | null>(null)\n const seededOpened = useRef<string | null>(null)\n useEffect(() => {\n if (!seededOrderId || seededOpened.current === seededOrderId) return\n if (listStatus === 'loading') return\n seededOpened.current = seededOrderId\n setSelectedId(seededOrderId)\n if (loadedOrders.some((order: any) => order.$id === seededOrderId)) return\n void getDoc(doc(firestore, 'hosts', hostId, 'orders', seededOrderId))\n .then((snapshot) => {\n if (seededOpened.current !== snapshot.id || !snapshot.exists()) return\n setSeededOrder({ ...snapshot.data(), $id: snapshot.id })\n })\n .catch(() => undefined)\n }, [seededOrderId, loadedOrders, listStatus, firestore, hostId])\n const [draft, setDraft] = useState<{\n productId: string\n variantId: string\n quantity: string\n email: string\n /** Destination the merchant declared, once they have been asked. */\n shipTo?: string\n /**\n * Revealed only when the server refuses for want of a destination\n * (AGL-1792). A merchant whose rates are the same everywhere — or who\n * configured none — is never asked and never sees this field.\n */\n shipCountries?: string[]\n /** The postal code, once live carrier rates ask for one (AGL-3612). */\n shipPostal?: string\n askPostal?: boolean\n busy?: boolean\n } | null>(null)\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n /**\n * Each order on the page with the values the grid DRAWS. What it filters\n * by is on the query; this is presentation only. `liftLegacyOrder` names\n * a status and channel on a row that predates them, and the item name\n * reads the line items first (AGL-1747): the flat `productId` is written\n * only by the two buy-now Stripe paths.\n */\n const orderRows = useMemo(\n () =>\n orders.map((order: any) => {\n const lifted = CommerceModel.liftLegacyOrder(order)\n return {\n ...order,\n orderLabel: CommerceModel.formatOrderNumber(lifted, order.$id),\n itemName:\n lifted.lineItems?.[0]?.name ??\n productNames[order.productId] ??\n order.productId ??\n '',\n statusKey: lifted.status,\n channelKey: lifted.channel ?? 'online',\n netCents: CommerceModel.orderNetCents(lifted),\n disputeBadge: CommerceModel.describeOrderDispute(lifted),\n }\n }),\n [orders, productNames],\n )\n const productOptions = useMemo(\n () =>\n productWindow.rows.map((product: any) => ({\n value: String(product.$id),\n label: String(product.name ?? product.$id),\n })),\n [productWindow],\n )\n const filterOptions = useMemo(\n () => ({\n statusKey: ORDER_STATUS_OPTIONS,\n channelKey: ORDER_CHANNEL_OPTIONS,\n productIds: productOptions,\n disputeKey: ORDER_DISPUTE_OPTIONS,\n }),\n [productOptions],\n )\n const refused = useMemo(\n () =>\n listQueryRefusals(plan.refused, {\n fields: ORDER_LIST_FIELDS,\n headers: ORDER_LIST_HEADERS,\n options: filterOptions,\n }),\n [plan, filterOptions],\n )\n const showingOpenDisputes = clauses.some(\n (clause) =>\n clause.field === OPEN_DISPUTE_CLAUSE.field &&\n clause.op === OPEN_DISPUTE_CLAUSE.op &&\n clause.value === OPEN_DISPUTE_CLAUSE.value,\n )\n\n const openDisputes = useMemo(\n () =>\n CommerceModel.summariseOpenDisputes(\n disputedRows.map((order: any) => CommerceModel.liftLegacyOrder(order)),\n ),\n [disputedRows],\n )\n\n /*\n * 30-day money summary with the prior 30 days behind it (AGL-2136).\n * ANALYTICS, NOT A FILTER: the tiles describe a period, not the list, so\n * they keep their own bounded read — sixty days by `createdAtMs`, the\n * newest `STATS_ORDER_CEILING` of them, read only when the tiles show.\n * Range and order are the same field, so it needs no composite.\n */\n const statsSince = useMemo(() => Date.now() - STATS_WINDOW_MS, [])\n const { data: statsDocs } = useFirestoreCollection<any>(\n () =>\n showStats\n ? query(\n ordersRef,\n where('createdAtMs', '>=', statsSince),\n orderBy('createdAtMs', 'desc'),\n limit(STATS_ORDER_CEILING + 1),\n )\n : null,\n [firestore, hostId, showStats, statsSince],\n { idField: '$id' },\n )\n const statsWindow = useMemo(\n () => ceilingedWindow<any>(statsDocs ?? undefined, STATS_ORDER_CEILING),\n [statsDocs],\n )\n const summary = useMemo(\n () =>\n CommerceModel.summarizeOrderWindow(statsWindow.rows, { nowMs: Date.now() }),\n [statsWindow],\n )\n\n /**\n * Export (AGL-3531) opens the console's export dialog on the\n * `commerce.orders` resource: the fields the person picks, for what the\n * QUERY matches — every clause and the search the grid is showing, not the\n * page on screen — read and streamed on the server however many orders\n * match. Orders are exported only; there is no Import.\n */\n const transfer = useTransferLauncher()\n const openExport = useCallback(() => {\n transfer?.openExport({\n resource: COMMERCE_ORDERS_TRANSFER,\n scope: 'host',\n hostId,\n ...(filtering\n ? {\n filter: {\n label: 'the orders the list’s filters and search find',\n value: commerceListFilter(plan),\n },\n }\n : {}),\n })\n }, [transfer, hostId, filtering, plan])\n\n /**\n * Idempotency key for ONE draft attempt (AGL-1697).\n *\n * Minted lazily on the first create click, NOT per call — two clicks (or a\n * click retried after a lost response) must present ONE key so the server\n * replays the original payment link instead of minting a second order.\n * Retired whenever a content field changes: an edited draft is a different\n * order, and replaying the old one against it would hand the merchant a\n * link priced for fields they no longer see. Answering the shipping-country\n * ask also retires it, which is safe — that refusal is served before the\n * server takes the claim, so the first key was never spent.\n */\n const draftAttemptKey = useRef('')\n useEffect(() => {\n draftAttemptKey.current = ''\n }, [\n draft?.productId,\n draft?.variantId,\n draft?.quantity,\n draft?.email,\n draft?.shipTo,\n draft?.shipPostal,\n ])\n\n const handleDraftCreate = useCallback(async () => {\n if (!draft?.productId) return\n setDraft((prev) => (prev ? { ...prev, busy: true } : prev))\n try {\n if (!draftAttemptKey.current) {\n draftAttemptKey.current =\n globalThis.crypto?.randomUUID?.() ??\n `${Date.now()}-${Math.random().toString(36).slice(2)}`\n }\n const response = await authorizedFetch(\n user,\n '/api/commerce/draft-order',\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n // Stable across a retry of THIS attempt (AGL-1697), so a\n // double-click cannot mint two live payment links.\n 'Idempotency-Key': draftAttemptKey.current,\n },\n body: JSON.stringify({\n hostId,\n productId: draft.productId,\n variantId: draft.variantId || undefined,\n quantity: Number(draft.quantity) || 1,\n email: draft.email || undefined,\n // A request, never an instruction: the server resolves the\n // rates for this country AND restricts the payment link's\n // collectable addresses to it, so declaring one cannot buy a\n // cheaper zone's rate than the address the buyer then enters\n // (AGL-1721).\n ...(draft.shipTo ? { shippingCountry: draft.shipTo } : {}),\n ...(draft.shipPostal?.trim() ? { shippingPostalCode: draft.shipPostal.trim() } : {}),\n }),\n },\n )\n const payload = await response.json()\n if (!response.ok) {\n // The merchant's rates differ by destination, so the server will not\n // price this order until it knows one (AGL-1792). Reveal the field and\n // let them answer; a store whose rates are the same everywhere, or\n // which configured none, never sends this and never shows it.\n if (payload?.needsShippingCountry) {\n setDraft((prev) =>\n prev\n ? {\n ...prev,\n shipCountries: (\n payload.shippingCountries as string[] | undefined\n )?.length\n ? (payload.shippingCountries as string[])\n : [...CommerceModel.CHECKOUT_SHIPPING_COUNTRIES],\n ...(payload?.needsShippingPostalCode ? { askPostal: true } : {}),\n }\n : prev,\n )\n }\n return void enqueueSnackbar(payload?.error ?? 'Draft order failed', {\n variant: 'error',\n allowDuplicate: true,\n })\n }\n await navigator.clipboard.writeText(payload.url).catch(() => undefined)\n enqueueSnackbar('Draft created — payment link copied', {\n variant: 'success',\n persist: false,\n })\n setDraft(null)\n } finally {\n setDraft((prev) => (prev ? { ...prev, busy: false } : prev))\n }\n }, [draft, user, hostId, enqueueSnackbar])\n\n /*\n * Bulk \"Mark as fulfilled\" (AGL-3611): one route call per ticked order, so\n * each gets its own transition check. Only paid and partially fulfilled\n * rows count; the button says how many.\n */\n const checkedOrders = useMemo(\n () => orderRows.filter((row: any) => checkedIds.includes(String(row.$id))),\n [orderRows, checkedIds],\n )\n const fulfillableCount = checkedOrders.filter((row: any) =>\n BULK_FULFILLABLE_STATUSES.includes(String(row.status)),\n ).length\n const handleBulkFulfill = useCallback(async () => {\n if (!checkedOrders.length) return\n setBulkBusy(true)\n try {\n const batchKey =\n globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`\n const result = await bulkFulfillOrders(user, hostId, checkedOrders as any[], batchKey)\n enqueueSnackbar(describeBulkFulfill(result), {\n variant: result.unknown.length ? 'error' : result.refused.length ? 'warning' : 'success',\n allowDuplicate: true,\n })\n if (!result.unknown.length) setCheckedIds([])\n } finally {\n setBulkBusy(false)\n }\n }, [checkedOrders, user, hostId, enqueueSnackbar])\n\n const selectedOrder =\n loadedOrders.find((order: any) => order.$id === selectedId) ??\n (seededOrder && seededOrder.$id === selectedId ? seededOrder : null)\n\n /**\n * Shared by the two triggers (AGL-1805) so the empty state and the toolbar\n * cannot drift into opening the dialog with different starting fields.\n */\n const openDraft = useCallback(\n () => setDraft({ productId: '', variantId: '', quantity: '1', email: '' }),\n [],\n )\n\n /** What the draft dialog can actually offer. */\n const selectableProducts = useMemo(\n () => productWindow.rows.filter((product: any) => !product.deletedAt),\n [productWindow],\n )\n\n /*\n * The six columns `/product/commerce` advertises, in the order the mockup\n * shows them — every fact scannable on its own, Channel included.\n */\n const orderColumns = useMemo<GridColDef[]>(\n () => [\n {\n field: 'orderLabel',\n headerName: 'Order',\n flex: 1,\n minWidth: 160,\n renderCell: ({ row }: any) => {\n const extraItems = Math.max(0, (row.lineItems?.length ?? 0) - 1)\n return (\n <Stack sx={{ minWidth: 0 }}>\n <Typography variant=\"body2\" noWrap>\n {row.orderLabel}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" noWrap>\n {extraItems ? `${row.itemName} +${extraItems} more` : row.itemName}\n </Typography>\n </Stack>\n )\n },\n },\n {\n field: 'customerEmail',\n headerName: 'Customer',\n flex: 1,\n minWidth: 180,\n renderCell: ({ row }: any) => (\n <Typography variant=\"body2\" noWrap>\n {row.customerEmail || '—'}\n </Typography>\n ),\n },\n {\n field: 'channelKey',\n headerName: 'Channel',\n width: 120,\n renderCell: ({ row }: any) => (\n <Typography variant=\"body2\">\n {CommerceModel.orderChannelLabel(row.channelKey)}\n </Typography>\n ),\n },\n {\n field: 'netCents',\n headerName: 'Total',\n type: 'number',\n width: 150,\n align: 'right',\n headerAlign: 'right',\n renderCell: ({ row }: any) => (\n <Stack sx={{ alignItems: 'flex-end', minWidth: 0, width: 1 }}>\n <Typography variant=\"body2\">\n {`$${(row.netCents / 100).toFixed(2)}`}\n </Typography>\n {row.refundedCents ? (\n <Typography variant=\"caption\" color=\"text.secondary\" noWrap>\n {`$${((row.totals?.totalCents ?? row.amountCents ?? 0) / 100).toFixed(2)} less refunds`}\n </Typography>\n ) : null}\n </Stack>\n ),\n },\n {\n field: 'statusKey',\n headerName: 'Status',\n width: 230,\n renderCell: ({ row }: any) => {\n // A lost chargeback leaves `status: 'refunded'` (AGL-1787), so the\n // status pill cannot tell the two apart either — which is why the\n // dispute chip sits beside it rather than being folded into it.\n const dispute: ReturnType<typeof CommerceModel.describeOrderDispute> =\n row.disputeBadge\n return (\n <Stack sx={{ minWidth: 0 }}>\n <Stack direction=\"row\" spacing={0.5} sx={{ alignItems: 'center' }}>\n <Chip\n label={\n CommerceModel.ORDER_STATUS_LABELS[\n row.statusKey as CommerceModel.OrderStatus\n ] ?? row.statusKey\n }\n size=\"small\"\n color={\n CommerceModel.ORDER_STATUS_COLOR[\n row.statusKey as CommerceModel.OrderStatus\n ] ?? 'default'\n }\n variant=\"outlined\"\n />\n {dispute ? (\n <Tooltip title={dispute.detail}>\n <Chip\n label={dispute.label}\n size=\"small\"\n color={DISPUTE_COLOR[dispute.tone]}\n variant=\"filled\"\n />\n </Tooltip>\n ) : null}\n </Stack>\n {/*\n The deadline on the row itself, while the case is open — the\n one fact on this screen that expires.\n */}\n {dispute?.evidenceDaysLeft !== undefined ? (\n <Typography\n variant=\"caption\"\n component=\"div\"\n color={dispute.evidenceDaysLeft < 0 ? 'error' : 'warning.main'}\n >\n {dispute.evidenceDaysLeft < 0\n ? 'Evidence deadline passed'\n : `Evidence due in ${dispute.evidenceDaysLeft} day${\n dispute.evidenceDaysLeft === 1 ? '' : 's'\n }`}\n </Typography>\n ) : null}\n </Stack>\n )\n },\n },\n {\n field: 'createdAtMs',\n headerName: 'Date',\n width: 130,\n renderCell: ({ row }: any) => {\n const createdAt =\n row.createdAt?.toDate?.() ??\n (row.createdAtMs ? new Date(row.createdAtMs) : null)\n return (\n <Stack sx={{ minWidth: 0 }}>\n <Typography variant=\"body2\" noWrap>\n {createdAt ? createdAt.toLocaleDateString() : '—'}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" noWrap>\n {createdAt ? createdAt.toLocaleTimeString() : ''}\n </Typography>\n </Stack>\n )\n },\n },\n ],\n [],\n )\n\n\n const columns = useMemo(\n () =>\n listFilterGridColumns(\n orderColumns,\n ORDER_LIST_FIELDS,\n filterOptions,\n ORDER_LIST_HEADERS,\n ),\n [orderColumns, filterOptions],\n )\n\n /*\n * The store is empty only when an UNFILTERED first page came back empty; a\n * filter or search that matches nothing keeps the grid, its chips and its\n * panel, so the reader can take the filter back off.\n */\n const empty =\n listStatus === 'success' && !filtering && page === 0 && orders.length === 0\n\n return (\n <CardDisplay\n header={'Orders'}\n // Shipping actions live in the card header (AGL-3613): the orders\n // still to ship for a label tool, and its tracking numbers back.\n HeaderProps={{ action: <OrderShippingActions hostId={hostId} /> }}\n help={pluginDocsHelp('commerce', {\n anchor: '#orders-screen',\n excerpt:\n 'Every order with its channel, status and net total. A refunded ' +\n 'order shows what is left, with the gross beneath it.',\n })}\n contentGutterX\n contentGutterY\n >\n {empty ? (\n /*\n * An invitation, not a report (AGL-1805). The \"Draft order\" button\n * used to live in the other arm of this ternary, so the one state a\n * draft order exists for — no sales yet, invoice the customer you\n * already have — was the only state that could not reach it, and\n * every other route into the dialog needs an order to exist first.\n *\n * The filters stay behind deliberately: they belong to a list with\n * rows in it. Export orders likewise — a header-only file is not\n * something a merchant on day one is looking for.\n */\n <Stack spacing={1} sx={{ alignItems: 'flex-start' }}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {\n 'No orders yet. Storefront sales, POS sales and draft orders ' +\n 'all appear here as they come in.'\n }\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {\n 'Selling to someone directly? Draft their order and send them ' +\n 'a payment link.'\n }\n </Typography>\n <Button\n size=\"small\"\n variant=\"contained\"\n color=\"primary\"\n onClick={openDraft}\n >\n {'Draft order'}\n </Button>\n </Stack>\n ) : (\n <Stack spacing={1}>\n {showStats ? (\n <Stack\n useFlexGap\n direction=\"row\"\n spacing={3}\n sx={{ flexWrap: 'wrap', rowGap: 1 }}\n >\n <CommerceStatTile\n label=\"Revenue · 30d\"\n value={`$${(summary.revenueCents / 100).toFixed(2)}`}\n deltaPct={summary.revenueDeltaPct}\n deltaCaption=\"vs the previous 30 days\"\n />\n <CommerceStatTile\n label=\"Orders · 30d\"\n value={String(summary.orders)}\n deltaPct={summary.ordersDeltaPct}\n deltaCaption=\"vs the previous 30 days\"\n />\n <CommerceStatTile\n label=\"Avg order value\"\n value={`$${(summary.aovCents / 100).toFixed(2)}`}\n deltaPct={summary.aovDeltaPct}\n deltaCaption=\"vs the previous 30 days\"\n />\n </Stack>\n ) : null}\n {showStats && statsWindow.truncated ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`Figures count the ${STATS_ORDER_CEILING} most recent orders of the last 60 days.`}\n </Typography>\n ) : null}\n {openDisputes.count > 0 ? (\n <Alert\n severity={openDisputes.overdue ? 'error' : 'warning'}\n action={\n showingOpenDisputes ? undefined : (\n <Button\n size=\"small\"\n color=\"inherit\"\n onClick={() =>\n setClauses(\n upsertListFilterClause(\n clauses,\n OPEN_DISPUTE_CLAUSE.field,\n OPEN_DISPUTE_CLAUSE,\n ),\n )\n }\n >\n {'Show them'}\n </Button>\n )\n }\n >\n <AlertTitle>\n {moreDisputes\n ? `More than ${OPEN_DISPUTE_CEILING} charges are disputed with the shopper’s bank`\n : openDisputes.count === 1\n ? 'A shopper has disputed a charge with their bank'\n : `${openDisputes.count} charges are disputed with the shopper’s bank`}\n </AlertTitle>\n {openDisputes.soonestDaysLeft === undefined\n ? 'Answer in the Stripe dashboard while the case is open — an unanswered dispute is decided for the shopper.'\n : openDisputes.soonestDaysLeft < 0\n ? 'The evidence deadline has passed on at least one of these. Stripe decides an unanswered dispute for the shopper.'\n : `Evidence is due to Stripe in ${openDisputes.soonestDaysLeft} day${\n openDisputes.soonestDaysLeft === 1 ? '' : 's'\n } on the tightest of these. An unanswered dispute is decided for the shopper.`}\n </Alert>\n ) : null}\n {/*\n The buttons stay beside the grid: Export orders writes every order\n the query matches, with the fields the person picks, which the grid's\n own export — one page — cannot.\n */}\n <Stack\n direction=\"row\"\n spacing={1}\n useFlexGap\n sx={{ alignItems: 'center', justifyContent: 'flex-end', flexWrap: 'wrap' }}\n >\n {checkedIds.length ? (\n <Button\n size=\"small\"\n variant=\"outlined\"\n disabled={bulkBusy || fulfillableCount === 0}\n onClick={handleBulkFulfill}\n >\n {`Mark as fulfilled (${fulfillableCount})`}\n </Button>\n ) : null}\n {/* Other plugins' bulk actions on the ticked orders (AGL-3612). */}\n {checkedIds.length && WidgetSlot ? (\n <WidgetSlot\n slot={ORDERS_BULK_ZONE.id}\n hostId={hostId}\n orgId={undefined}\n selectedOrderIds={checkedIds}\n storeName=\"\"\n />\n ) : null}\n {/* Only for whom the route takes it (AGL-3554). */}\n {transfer?.can('export', { resource: COMMERCE_ORDERS_TRANSFER, scope: 'host', hostId }) ? (\n <Button size=\"small\" onClick={openExport}>\n {'Export orders'}\n </Button>\n ) : null}\n <Button\n size=\"small\"\n variant=\"contained\"\n color=\"primary\"\n onClick={openDraft}\n >\n {'Draft order'}\n </Button>\n </Stack>\n <ListFilterChips\n fields={ORDER_LIST_FIELDS}\n headers={ORDER_LIST_HEADERS}\n clauses={clauses}\n onChange={setClauses}\n options={filterOptions}\n />\n <ListQueryNotices refused={refused} notices={plan.notices} />\n <ListTable\n aria-label=\"Orders\"\n rows={orderRows}\n columns={columns}\n onOpen={(id) => setSelectedId(id)}\n selectable={{ selected: checkedIds, onChange: setCheckedIds }}\n loading={listStatus === 'loading'}\n /*\n * The grid must NOT also filter, search or sort: the query\n * answers all three, and the list has one order — newest first —\n * which the query already holds.\n */\n filterMode=\"server\"\n filterModel={gridFilter.filterModel}\n onFilterModelChange={gridFilter.onFilterModelChange}\n quickFilter\n sortingMode=\"server\"\n disableColumnSorting\n // `ListPagination` below pages the query.\n hideFooter\n initialState={{\n columns: { columnVisibilityModel: ORDER_HIDDEN_COLUMNS },\n }}\n noRowsLabel=\"No orders match these filters\"\n />\n <ListPagination\n page={page}\n pageSize={pageSize}\n rowCount={orderRows.length}\n hasMore={hasMore}\n onPageChange={setPage}\n onPageSizeChange={setPageSize}\n />\n </Stack>\n )}\n {selectedOrder ? (\n <OrderDetailDialog\n hostId={hostId}\n order={selectedOrder}\n onClose={() => setSelectedId(null)}\n />\n ) : null}\n <Dialog\n open={Boolean(draft)}\n onClose={() => setDraft(null)}\n maxWidth=\"xs\"\n fullWidth\n >\n <DialogTitle>{'Draft order'}</DialogTitle>\n <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <TextField\n label=\"Product\"\n value={draft?.productId ?? ''}\n onChange={(event) =>\n setDraft((prev) =>\n prev\n ? { ...prev, productId: event.target.value, variantId: '' }\n : prev,\n )\n }\n size=\"small\"\n select\n sx={{ mt: 1 }}\n /*\n * The second dead end behind the first (AGL-1805): a store with\n * no orders may have no products either, and a draft order is\n * composed from one — so \"Create & copy link\" stays disabled. Say\n * why, rather than opening an empty menu onto nothing.\n */\n helperText={\n selectableProducts.length === 0\n ? 'Add a product to this store first — a draft order is built from one.'\n : undefined\n }\n >\n {selectableProducts.map((product: any) => (\n <MenuItem key={product.$id} value={product.$id}>\n {product.name ?? product.$id}\n </MenuItem>\n ))}\n </TextField>\n {(() => {\n const product = productWindow.rows.find(\n (item: any) => item.$id === draft?.productId,\n )\n const variants = product\n ? CommerceModel.liftLegacyProduct(product).variants\n : []\n return variants.length > 1 ? (\n <TextField\n label=\"Variant\"\n value={draft?.variantId ?? ''}\n onChange={(event) =>\n setDraft((prev) =>\n prev ? { ...prev, variantId: event.target.value } : prev,\n )\n }\n size=\"small\"\n select\n >\n {variants.map((variant) => (\n <MenuItem key={variant.id} value={variant.id}>\n {`${Object.values(variant.options ?? {}).join(' / ') || 'Default'} — $${variant.priceUsd}`}\n </MenuItem>\n ))}\n </TextField>\n ) : null\n })()}\n <TextField\n label=\"Quantity\"\n value={draft?.quantity ?? '1'}\n onChange={(event) =>\n setDraft((prev) =>\n prev\n ? {\n ...prev,\n quantity: event.target.value.replace(/[^0-9]/g, ''),\n }\n : prev,\n )\n }\n size=\"small\"\n slotProps={{ htmlInput: { inputMode: 'numeric' } }}\n />\n <TextField\n label=\"Buyer email (optional)\"\n value={draft?.email ?? ''}\n onChange={(event) =>\n setDraft((prev) =>\n prev ? { ...prev, email: event.target.value } : prev,\n )\n }\n size=\"small\"\n />\n {draft?.shipCountries?.length ? (\n <TextField\n label=\"Ships to\"\n value={draft?.shipTo ?? ''}\n onChange={(event) =>\n setDraft((prev) =>\n prev ? { ...prev, shipTo: event.target.value } : prev,\n )\n }\n size=\"small\"\n select\n helperText={\n 'This store’s shipping rates differ by destination, so the ' +\n 'payment link has to be priced for one.'\n }\n >\n {draft.shipCountries.map((code) => (\n <MenuItem key={code} value={code}>\n {CommerceModel.CHECKOUT_SHIPPING_COUNTRY_NAMES[code] ?? code}\n </MenuItem>\n ))}\n </TextField>\n ) : null}\n {draft?.askPostal ? (\n <TextField\n label=\"Postal code\"\n value={draft?.shipPostal ?? ''}\n onChange={(event) =>\n setDraft((prev) => (prev ? { ...prev, shipPostal: event.target.value } : prev))\n }\n size=\"small\"\n helperText=\"This store prices shipping by carrier, which needs the postal code.\"\n />\n ) : null}\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setDraft(null)}>{'Cancel'}</Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={\n !draft?.productId ||\n draft?.busy ||\n // Once asked, the answer is required: retrying without one is\n // refused again, so the button would only look broken.\n Boolean(draft?.shipCountries?.length && !draft?.shipTo) ||\n Boolean(draft?.askPostal && !draft?.shipPostal?.trim())\n }\n onClick={handleDraftCreate}\n >\n {'Create & copy link'}\n </Button>\n </DialogActions>\n </Dialog>\n </CardDisplay>\n )\n}\nHostOrdersCard.displayName = 'HostOrdersCard'\n\nexport default HostOrdersCard\n"],"names":["CommerceModel","CardDisplay","ListFilterChips","ListPagination","ListQueryNotices","listQueryRefusals","ListTable","hiddenFilterVisibility","listFilterGridColumns","upsertListFilterClause","useListGridFilter","useSnackbar","checkEntitlement","pluginDocsHelp","ORDERS_CUSTOMER_PARAM","ORDERS_ORDER_PARAM","Alert","AlertTitle","Button","Chip","Dialog","DialogActions","DialogContent","DialogTitle","MenuItem","Stack","TextField","Tooltip","Typography","collection","doc","getDoc","limit","orderBy","query","where","useSearchParams","useCallback","useEffect","useMemo","useRef","useState","ceilingedWindow","collectionCeiling","useFirestore","useOrgPlan","useUser","useFirestoreCollection","useListQuery","useTransferLauncher","commerceListFilter","COMMERCE_ORDERS_TRANSFER","OrderShippingActions","authorizedFetch","OPEN_DISPUTE_CLAUSE","ORDER_CHANNEL_OPTIONS","ORDER_DISPUTE_OPTIONS","ORDER_LIST_FIELDS","ORDER_LIST_HEADERS","ORDER_LIST_QUERY","ORDER_LIST_SELECT_FIELDS","ORDER_STATUS_OPTIONS","ordersCustomerClause","CommerceStatTile","bulkFulfillOrders","BULK_FULFILLABLE_STATUSES","describeBulkFulfill","ORDERS_BULK_ZONE","useConsoleWidgetSlot","OrderDetailDialog","DISPUTE_COLOR","PRODUCT_NAME_WINDOW","OPEN_DISPUTE_CEILING","STATS_WINDOW_MS","STATS_ORDER_CEILING","ORDER_VISIBLE_COLUMNS","ORDER_HIDDEN_COLUMNS","HostOrdersCard","props","loadedOrders","draft","hostId","firestore","ordersRef","data","productDocs","idField","productWindow","undefined","productNames","map","product","rows","$id","name","org","ready","orgReady","showStats","searchParams","clauses","setClauses","customer","get","gridFilter","onChange","selectFields","filtering","length","searchWords","some","word","trim","disputedRows","hasMore","moreDisputes","declaration","request","deps","pageSize","confirmDisappearances","orders","page","setPage","setPageSize","plan","status","listStatus","search","selectedId","setSelectedId","checkedIds","setCheckedIds","bulkBusy","setBulkBusy","WidgetSlot","seededOrderId","seededOrder","setSeededOrder","seededOpened","current","order","then","snapshot","id","exists","catch","setDraft","user","enqueueSnackbar","orderRows","lifted","liftLegacyOrder","orderLabel","formatOrderNumber","itemName","lineItems","productId","statusKey","channelKey","channel","netCents","orderNetCents","disputeBadge","describeOrderDispute","productOptions","value","String","label","filterOptions","productIds","disputeKey","refused","fields","headers","options","showingOpenDisputes","clause","field","op","openDisputes","summariseOpenDisputes","statsSince","Date","now","statsDocs","statsWindow","summary","summarizeOrderWindow","nowMs","transfer","openExport","resource","scope","filter","draftAttemptKey","variantId","quantity","email","shipTo","shipPostal","handleDraftCreate","prev","busy","globalThis","crypto","randomUUID","Math","random","toString","slice","response","method","body","JSON","stringify","Number","shippingCountry","shippingPostalCode","payload","json","ok","needsShippingCountry","shipCountries","shippingCountries","CHECKOUT_SHIPPING_COUNTRIES","needsShippingPostalCode","askPostal","error","variant","allowDuplicate","navigator","clipboard","writeText","url","persist","checkedOrders","row","includes","fulfillableCount","handleBulkFulfill","batchKey","result","unknown","selectedOrder","find","openDraft","selectableProducts","deletedAt","orderColumns","headerName","flex","minWidth","renderCell","extraItems","max","sx","noWrap","color","customerEmail","width","orderChannelLabel","type","align","headerAlign","alignItems","toFixed","refundedCents","totals","totalCents","amountCents","dispute","direction","spacing","ORDER_STATUS_LABELS","size","ORDER_STATUS_COLOR","title","detail","tone","evidenceDaysLeft","component","createdAt","toDate","createdAtMs","toLocaleDateString","toLocaleTimeString","columns","empty","header","HeaderProps","action","help","anchor","excerpt","contentGutterX","contentGutterY","onClick","useFlexGap","flexWrap","rowGap","revenueCents","deltaPct","revenueDeltaPct","deltaCaption","ordersDeltaPct","aovCents","aovDeltaPct","truncated","count","severity","overdue","soonestDaysLeft","justifyContent","disabled","slot","orgId","selectedOrderIds","storeName","can","notices","aria-label","onOpen","selectable","selected","loading","filterMode","filterModel","onFilterModelChange","quickFilter","sortingMode","disableColumnSorting","hideFooter","initialState","columnVisibilityModel","noRowsLabel","rowCount","onPageChange","onPageSizeChange","onClose","open","Boolean","maxWidth","fullWidth","display","flexDirection","gap","event","target","select","mt","helperText","item","variants","liftLegacyProduct","Object","values","join","priceUsd","replace","slotProps","htmlInput","inputMode","code","CHECKOUT_SHIPPING_COUNTRY_NAMES","displayName"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/host-orders-card.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n'use client'\n\nimport * as CommerceModel from '../../model'\nimport { CardDisplay } from '@aglyn/shared-ui-jsx'\nimport ListFilterChips from '@aglyn/shared-ui-jsx/components/list-filter-chips.component'\nimport { ListPagination } from '@aglyn/shared-ui-jsx/components/list-pagination.component'\nimport {\n ListQueryNotices,\n listQueryRefusals,\n} from '@aglyn/shared-ui-jsx/components/list-query-notices.component'\nimport { ListTable } from '@aglyn/shared-ui-jsx/components/list-table.component'\nimport { hiddenFilterVisibility } from '@aglyn/shared-ui-jsx/const/list-filter'\nimport type { ListQuerySort } from '@aglyn/shared-ui-jsx/const/list-query-plan'\nimport { useListColumnSort } from '@aglyn/shared-ui-jsx/hooks/use-list-column-sort'\nimport {\n type ListFilterClause,\n listFilterGridColumns,\n upsertListFilterClause,\n} from '@aglyn/shared-ui-jsx/const/list-grid-filter'\nimport { useListGridFilter } from '@aglyn/shared-ui-jsx/hooks/use-list-grid-filter'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { checkEntitlement, pluginDocsHelp } from '@aglyn/aglyn'\nimport { ORDERS_CUSTOMER_PARAM, ORDERS_ORDER_PARAM } from '../../model/commerce-record-routes'\nimport {\n Alert,\n AlertTitle,\n Button,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n MenuItem,\n Stack,\n TextField,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport type { GridColDef } from '@mui/x-data-grid'\nimport {\n collection,\n doc,\n getDoc,\n limit,\n orderBy,\n query,\n where,\n} from 'firebase/firestore'\nimport { useSearchParams } from 'next/navigation'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport {\n ceilingedWindow,\n collectionCeiling,\n useFirestore,\n useOrgPlan,\n useUser,\n} from '@aglyn/tenant-feature-instance'\nimport { useFirestoreCollection } from '@aglyn/tenant-feature-instance'\nimport { useListQuery } from '@aglyn/tenant-feature-instance/hooks/use-list-query'\nimport { useTransferLauncher } from '@aglyn/aglyn/app-utils/transfer-launcher-context'\nimport { commerceListFilter } from '../../transfer/list-filter'\nimport { COMMERCE_ORDERS_TRANSFER } from '../../transfer/transfer-keys'\nimport OrderShippingActions from './order-shipping-actions.component'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\n\nimport {\n OPEN_DISPUTE_CLAUSE,\n ORDER_CHANNEL_OPTIONS,\n ORDER_LIST_COLUMN_SORTS,\n ORDER_DISPUTE_OPTIONS,\n ORDER_LIST_FIELDS,\n ORDER_LIST_HEADERS,\n ORDER_LIST_QUERY,\n ORDER_LIST_SELECT_FIELDS,\n ORDER_STATUS_OPTIONS,\n ordersCustomerClause,\n} from '../../constants/orders-list-query'\nimport CommerceStatTile from './commerce-stat-tile.component'\nimport { bulkFulfillOrders, BULK_FULFILLABLE_STATUSES, describeBulkFulfill } from './bulk-fulfill'\nimport { ORDERS_BULK_ZONE } from './store-zones'\nimport { useConsoleWidgetSlot } from '@aglyn/aglyn/app-utils/console-widget-slot-context'\nimport OrderDetailDialog, {\n DISPUTE_COLOR,\n} from './order-detail-dialog.component'\n\n/**\n * The products the card reads to NAME a legacy row and the CSV, to offer the\n * Product filter's choices and to fill the draft dialog's picker. A picker's\n * reach, not the list's: the orders themselves are paged by their query and\n * the Product filter asks it for any product id, named here or not.\n */\nconst PRODUCT_NAME_WINDOW = 100\n\n/**\n * How many open disputes the banner reads. Its own query, `disputeKey ==\n * 'open'`, so a deadline is raised whatever the list is filtered to and\n * however deep in the store the order sits; a store past this many open\n * cases is told \"more than\".\n */\nconst OPEN_DISPUTE_CEILING = 50\n\n/**\n * The money tiles read the last sixty days (thirty, and the thirty before it)\n * on their own bounded query. They are analytics over a period, not a filter\n * over the list, and share the analytics card's bound.\n */\nconst STATS_WINDOW_MS = 60 * 24 * 60 * 60 * 1000\nconst STATS_ORDER_CEILING = 500\n\n/** The columns the grid draws; every other declared field is a hidden filter column. */\nconst ORDER_VISIBLE_COLUMNS = [\n 'orderLabel',\n 'customerEmail',\n 'channelKey',\n 'statusKey',\n 'createdAtMs',\n]\nconst ORDER_HIDDEN_COLUMNS = hiddenFilterVisibility(\n ORDER_LIST_FIELDS,\n ORDER_VISIBLE_COLUMNS,\n)\n\nexport interface HostOrdersCardProps {\n hostId: string\n}\n\n/** Total is computed from the refunds, so it sorts the page on screen (AGL-3680). */\nconst ORDER_PAGE_SORTS = {\n netCents: (row: { netCents: number }) => row.netCents,\n}\nconst ORDER_PAGE_SORT_HEADERS = { netCents: 'Total' }\n\n/**\n * Orders console (AGL-287): filterable list over webhook-written order\n * docs with a detail dialog (timeline, fulfill, refund, cancel, notes,\n * packing slip) and draft orders that send the buyer a payment link.\n *\n * ## Every filter and the search are on the query (AGL-3321)\n *\n * The list used to read the newest two hundred orders and match its Filters\n * panel and search over them, so a Status filter on a busy store answered\n * \"none\" about every order past the two hundredth. Now each clause and the\n * search word are predicates on ONE Firestore query (`ORDER_LIST_QUERY`),\n * over the fields every writer stamps (`orderListFields`), and the footer\n * pages that query's answer. A combination one query cannot hold is refused\n * by name above the grid and never applied to some rows only.\n */\nexport function HostOrdersCard(props: HostOrdersCardProps) {\n const { hostId } = props\n const firestore = useFirestore()\n const ordersRef = useMemo(\n () => collection(firestore, 'hosts', hostId, 'orders'),\n [firestore, hostId],\n )\n const { data: productDocs } = useFirestoreCollection<any>(\n () =>\n collectionCeiling(\n collection(firestore, 'hosts', hostId, 'products'),\n PRODUCT_NAME_WINDOW,\n ),\n [firestore, hostId],\n { idField: '$id' },\n )\n const productWindow = useMemo(\n () => ceilingedWindow<any>(productDocs ?? undefined, PRODUCT_NAME_WINDOW),\n [productDocs],\n )\n const productNames = useMemo(() => {\n const map: Record<string, string> = {}\n for (const product of productWindow.rows) {\n map[product.$id] = product.name ?? product.$id\n }\n return map\n }, [productWindow])\n\n /**\n * The money tiles are the `commerceAnalytics` surface (AGL-1938,\n * AGL-2056), and this is the third place they appear. Rendering them\n * ungated here would undo both of those passes and hand a Starter org\n * the Pro figures one tab away from the upgrade prompt that refuses\n * them. The TABLE below is not gated — a list of your own orders is not\n * a paid feature.\n */\n const { org, ready: orgReady } = useOrgPlan(hostId)\n const showStats =\n orgReady && checkEntitlement(org as never, 'commerceAnalytics')\n\n /*\n * The grid's clauses (AGL-96, AGL-3317), held here so two things outside\n * the grid can set one: the CRM's contact page links with the buyer's\n * address to answer \"what has this customer ordered\" (AGL-2622) — a whole\n * address is that buyer, a domain every buyer at a company\n * (`ordersCustomerClause`) — and the dispute banner's \"Show them\".\n */\n const searchParams = useSearchParams()\n const [clauses, setClauses] = useState<ListFilterClause[]>(() => {\n const customer = ordersCustomerClause(\n searchParams?.get(ORDERS_CUSTOMER_PARAM) ?? '',\n )\n return customer ? [customer] : []\n })\n const gridFilter = useListGridFilter({\n clauses,\n onChange: setClauses,\n selectFields: ORDER_LIST_SELECT_FIELDS,\n })\n const filtering =\n clauses.length > 0 || gridFilter.searchWords.some((word) => word.trim())\n /*\n * Every header sorts (AGL-3680). Date, Order, Customer, Channel and Status\n * are the query's order over every order (`ORDER_LIST_COLUMN_SORTS`);\n * Total is computed from the refunds, so it sorts the page on screen.\n * Newest first until a header is clicked. A header order other than Date\n * holds only with no filter or search on — the plan falls back to newest\n * first and `ListQueryNotices` says so.\n */\n const [askedSort, setAskedSort] = useState<ListQuerySort | null>(\n ORDER_LIST_COLUMN_SORTS[0],\n )\n\n /*\n * The open disputes, on their OWN query (AGL-1796). Raised whatever the\n * list is filtered to — a merchant filtered to \"delivered\" still has a\n * deadline running on a `paid` order, and the evidence window is days —\n * and however far back the order is. Asked before the list so the list's\n * plan is the one a spec reads last.\n */\n const {\n rows: disputedRows,\n hasMore: moreDisputes,\n } = useListQuery<any>({\n collection: ordersRef,\n declaration: ORDER_LIST_QUERY,\n request: { clauses: [OPEN_DISPUTE_CLAUSE] },\n deps: [firestore, hostId],\n idField: '$id',\n pageSize: OPEN_DISPUTE_CEILING,\n // A dispute that closes leaves this query; confirm it before believing it.\n confirmDisappearances: true,\n })\n\n /*\n * THE LIST: every clause and the search word on one query, newest first,\n * paged by the footer. A status, a dispute or a paid draft's address can\n * move an order out of the filtered query mid-session, so a disappearance\n * is confirmed against the server before it is believed (AGL-1196).\n */\n const {\n rows: orders,\n data: loadedOrders,\n hasMore,\n page,\n setPage,\n pageSize,\n setPageSize,\n plan,\n status: listStatus,\n } = useListQuery<any>({\n collection: ordersRef,\n declaration: ORDER_LIST_QUERY,\n request: { clauses, search: gridFilter.searchWords, sort: askedSort },\n deps: [firestore, hostId],\n idField: '$id',\n confirmDisappearances: true,\n })\n\n const [selectedId, setSelectedId] = useState<string | null>(null)\n // Rows ticked for a bulk act (AGL-3611); the row click still opens one.\n const [checkedIds, setCheckedIds] = useState<string[]>([])\n const [bulkBusy, setBulkBusy] = useState(false)\n const WidgetSlot = useConsoleWidgetSlot()\n /*\n * An order named in the URL opens in its dialog on arrival (AGL-2622). A\n * contact's timeline names the order that made the person a customer,\n * and the address it links to is this list with `?order={id}`. The list\n * shows one page, and an order from last year is not on it, so the\n * document is read once by id and held beside the page for the dialog; an\n * order that IS loaded is found there first and the read is skipped. Once\n * per id — the ref keeps a re-render from reopening a dialog the merchant\n * has since closed — and the landing read is judged against the ref\n * rather than an effect cleanup, because the `setSelectedId` above\n * re-renders before the read lands and a cleanup keyed on any dep would\n * cancel the answer to the question just asked.\n */\n const seededOrderId = searchParams?.get(ORDERS_ORDER_PARAM) ?? null\n const [seededOrder, setSeededOrder] = useState<any | null>(null)\n const seededOpened = useRef<string | null>(null)\n useEffect(() => {\n if (!seededOrderId || seededOpened.current === seededOrderId) return\n if (listStatus === 'loading') return\n seededOpened.current = seededOrderId\n setSelectedId(seededOrderId)\n if (loadedOrders.some((order: any) => order.$id === seededOrderId)) return\n void getDoc(doc(firestore, 'hosts', hostId, 'orders', seededOrderId))\n .then((snapshot) => {\n if (seededOpened.current !== snapshot.id || !snapshot.exists()) return\n setSeededOrder({ ...snapshot.data(), $id: snapshot.id })\n })\n .catch(() => undefined)\n }, [seededOrderId, loadedOrders, listStatus, firestore, hostId])\n const [draft, setDraft] = useState<{\n productId: string\n variantId: string\n quantity: string\n email: string\n /** Destination the merchant declared, once they have been asked. */\n shipTo?: string\n /**\n * Revealed only when the server refuses for want of a destination\n * (AGL-1792). A merchant whose rates are the same everywhere — or who\n * configured none — is never asked and never sees this field.\n */\n shipCountries?: string[]\n /** The postal code, once live carrier rates ask for one (AGL-3612). */\n shipPostal?: string\n askPostal?: boolean\n busy?: boolean\n } | null>(null)\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n /**\n * Each order on the page with the values the grid DRAWS. What it filters\n * by is on the query; this is presentation only. `liftLegacyOrder` names\n * a status and channel on a row that predates them, and the item name\n * reads the line items first (AGL-1747): the flat `productId` is written\n * only by the two buy-now Stripe paths.\n */\n const orderRows = useMemo(\n () =>\n orders.map((order: any) => {\n const lifted = CommerceModel.liftLegacyOrder(order)\n return {\n ...order,\n orderLabel: CommerceModel.formatOrderNumber(lifted, order.$id),\n itemName:\n lifted.lineItems?.[0]?.name ??\n productNames[order.productId] ??\n order.productId ??\n '',\n statusKey: lifted.status,\n channelKey: lifted.channel ?? 'online',\n netCents: CommerceModel.orderNetCents(lifted),\n disputeBadge: CommerceModel.describeOrderDispute(lifted),\n }\n }),\n [orders, productNames],\n )\n const columnSort = useListColumnSort({\n sorts: ORDER_LIST_COLUMN_SORTS,\n defaultSort: ORDER_LIST_COLUMN_SORTS[0],\n sort: askedSort,\n onSortChange: setAskedSort,\n orderBy: plan.orderBy,\n rows: orderRows,\n pageSorts: ORDER_PAGE_SORTS,\n headers: ORDER_PAGE_SORT_HEADERS,\n })\n const productOptions = useMemo(\n () =>\n productWindow.rows.map((product: any) => ({\n value: String(product.$id),\n label: String(product.name ?? product.$id),\n })),\n [productWindow],\n )\n const filterOptions = useMemo(\n () => ({\n statusKey: ORDER_STATUS_OPTIONS,\n channelKey: ORDER_CHANNEL_OPTIONS,\n productIds: productOptions,\n disputeKey: ORDER_DISPUTE_OPTIONS,\n }),\n [productOptions],\n )\n const refused = useMemo(\n () =>\n listQueryRefusals(plan.refused, {\n fields: ORDER_LIST_FIELDS,\n headers: ORDER_LIST_HEADERS,\n options: filterOptions,\n }),\n [plan, filterOptions],\n )\n const showingOpenDisputes = clauses.some(\n (clause) =>\n clause.field === OPEN_DISPUTE_CLAUSE.field &&\n clause.op === OPEN_DISPUTE_CLAUSE.op &&\n clause.value === OPEN_DISPUTE_CLAUSE.value,\n )\n\n const openDisputes = useMemo(\n () =>\n CommerceModel.summariseOpenDisputes(\n disputedRows.map((order: any) => CommerceModel.liftLegacyOrder(order)),\n ),\n [disputedRows],\n )\n\n /*\n * 30-day money summary with the prior 30 days behind it (AGL-2136).\n * ANALYTICS, NOT A FILTER: the tiles describe a period, not the list, so\n * they keep their own bounded read — sixty days by `createdAtMs`, the\n * newest `STATS_ORDER_CEILING` of them, read only when the tiles show.\n * Range and order are the same field, so it needs no composite.\n */\n const statsSince = useMemo(() => Date.now() - STATS_WINDOW_MS, [])\n const { data: statsDocs } = useFirestoreCollection<any>(\n () =>\n showStats\n ? query(\n ordersRef,\n where('createdAtMs', '>=', statsSince),\n orderBy('createdAtMs', 'desc'),\n limit(STATS_ORDER_CEILING + 1),\n )\n : null,\n [firestore, hostId, showStats, statsSince],\n { idField: '$id' },\n )\n const statsWindow = useMemo(\n () => ceilingedWindow<any>(statsDocs ?? undefined, STATS_ORDER_CEILING),\n [statsDocs],\n )\n const summary = useMemo(\n () =>\n CommerceModel.summarizeOrderWindow(statsWindow.rows, { nowMs: Date.now() }),\n [statsWindow],\n )\n\n /**\n * Export (AGL-3531) opens the console's export dialog on the\n * `commerce.orders` resource: the fields the person picks, for what the\n * QUERY matches — every clause and the search the grid is showing, not the\n * page on screen — read and streamed on the server however many orders\n * match. Orders are exported only; there is no Import.\n */\n const transfer = useTransferLauncher()\n const openExport = useCallback(() => {\n transfer?.openExport({\n resource: COMMERCE_ORDERS_TRANSFER,\n scope: 'host',\n hostId,\n ...(filtering\n ? {\n filter: {\n label: 'the orders the list’s filters and search find',\n value: commerceListFilter(plan),\n },\n }\n : {}),\n })\n }, [transfer, hostId, filtering, plan])\n\n /**\n * Idempotency key for ONE draft attempt (AGL-1697).\n *\n * Minted lazily on the first create click, NOT per call — two clicks (or a\n * click retried after a lost response) must present ONE key so the server\n * replays the original payment link instead of minting a second order.\n * Retired whenever a content field changes: an edited draft is a different\n * order, and replaying the old one against it would hand the merchant a\n * link priced for fields they no longer see. Answering the shipping-country\n * ask also retires it, which is safe — that refusal is served before the\n * server takes the claim, so the first key was never spent.\n */\n const draftAttemptKey = useRef('')\n useEffect(() => {\n draftAttemptKey.current = ''\n }, [\n draft?.productId,\n draft?.variantId,\n draft?.quantity,\n draft?.email,\n draft?.shipTo,\n draft?.shipPostal,\n ])\n\n const handleDraftCreate = useCallback(async () => {\n if (!draft?.productId) return\n setDraft((prev) => (prev ? { ...prev, busy: true } : prev))\n try {\n if (!draftAttemptKey.current) {\n draftAttemptKey.current =\n globalThis.crypto?.randomUUID?.() ??\n `${Date.now()}-${Math.random().toString(36).slice(2)}`\n }\n const response = await authorizedFetch(\n user,\n '/api/commerce/draft-order',\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n // Stable across a retry of THIS attempt (AGL-1697), so a\n // double-click cannot mint two live payment links.\n 'Idempotency-Key': draftAttemptKey.current,\n },\n body: JSON.stringify({\n hostId,\n productId: draft.productId,\n variantId: draft.variantId || undefined,\n quantity: Number(draft.quantity) || 1,\n email: draft.email || undefined,\n // A request, never an instruction: the server resolves the\n // rates for this country AND restricts the payment link's\n // collectable addresses to it, so declaring one cannot buy a\n // cheaper zone's rate than the address the buyer then enters\n // (AGL-1721).\n ...(draft.shipTo ? { shippingCountry: draft.shipTo } : {}),\n ...(draft.shipPostal?.trim() ? { shippingPostalCode: draft.shipPostal.trim() } : {}),\n }),\n },\n )\n const payload = await response.json()\n if (!response.ok) {\n // The merchant's rates differ by destination, so the server will not\n // price this order until it knows one (AGL-1792). Reveal the field and\n // let them answer; a store whose rates are the same everywhere, or\n // which configured none, never sends this and never shows it.\n if (payload?.needsShippingCountry) {\n setDraft((prev) =>\n prev\n ? {\n ...prev,\n shipCountries: (\n payload.shippingCountries as string[] | undefined\n )?.length\n ? (payload.shippingCountries as string[])\n : [...CommerceModel.CHECKOUT_SHIPPING_COUNTRIES],\n ...(payload?.needsShippingPostalCode ? { askPostal: true } : {}),\n }\n : prev,\n )\n }\n return void enqueueSnackbar(payload?.error ?? 'Draft order failed', {\n variant: 'error',\n allowDuplicate: true,\n })\n }\n await navigator.clipboard.writeText(payload.url).catch(() => undefined)\n enqueueSnackbar('Draft created — payment link copied', {\n variant: 'success',\n persist: false,\n })\n setDraft(null)\n } finally {\n setDraft((prev) => (prev ? { ...prev, busy: false } : prev))\n }\n }, [draft, user, hostId, enqueueSnackbar])\n\n /*\n * Bulk \"Mark as fulfilled\" (AGL-3611): one route call per ticked order, so\n * each gets its own transition check. Only paid and partially fulfilled\n * rows count; the button says how many.\n */\n const checkedOrders = useMemo(\n () => orderRows.filter((row: any) => checkedIds.includes(String(row.$id))),\n [orderRows, checkedIds],\n )\n const fulfillableCount = checkedOrders.filter((row: any) =>\n BULK_FULFILLABLE_STATUSES.includes(String(row.status)),\n ).length\n const handleBulkFulfill = useCallback(async () => {\n if (!checkedOrders.length) return\n setBulkBusy(true)\n try {\n const batchKey =\n globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`\n const result = await bulkFulfillOrders(user, hostId, checkedOrders as any[], batchKey)\n enqueueSnackbar(describeBulkFulfill(result), {\n variant: result.unknown.length ? 'error' : result.refused.length ? 'warning' : 'success',\n allowDuplicate: true,\n })\n if (!result.unknown.length) setCheckedIds([])\n } finally {\n setBulkBusy(false)\n }\n }, [checkedOrders, user, hostId, enqueueSnackbar])\n\n const selectedOrder =\n loadedOrders.find((order: any) => order.$id === selectedId) ??\n (seededOrder && seededOrder.$id === selectedId ? seededOrder : null)\n\n /**\n * Shared by the two triggers (AGL-1805) so the empty state and the toolbar\n * cannot drift into opening the dialog with different starting fields.\n */\n const openDraft = useCallback(\n () => setDraft({ productId: '', variantId: '', quantity: '1', email: '' }),\n [],\n )\n\n /** What the draft dialog can actually offer. */\n const selectableProducts = useMemo(\n () => productWindow.rows.filter((product: any) => !product.deletedAt),\n [productWindow],\n )\n\n /*\n * The six columns `/product/commerce` advertises, in the order the mockup\n * shows them — every fact scannable on its own, Channel included.\n */\n const orderColumns = useMemo<GridColDef[]>(\n () => [\n {\n field: 'orderLabel',\n headerName: 'Order',\n flex: 1,\n minWidth: 160,\n renderCell: ({ row }: any) => {\n const extraItems = Math.max(0, (row.lineItems?.length ?? 0) - 1)\n return (\n <Stack sx={{ minWidth: 0 }}>\n <Typography variant=\"body2\" noWrap>\n {row.orderLabel}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" noWrap>\n {extraItems ? `${row.itemName} +${extraItems} more` : row.itemName}\n </Typography>\n </Stack>\n )\n },\n },\n {\n field: 'customerEmail',\n headerName: 'Customer',\n flex: 1,\n minWidth: 180,\n renderCell: ({ row }: any) => (\n <Typography variant=\"body2\" noWrap>\n {row.customerEmail || '—'}\n </Typography>\n ),\n },\n {\n field: 'channelKey',\n headerName: 'Channel',\n width: 120,\n renderCell: ({ row }: any) => (\n <Typography variant=\"body2\">\n {CommerceModel.orderChannelLabel(row.channelKey)}\n </Typography>\n ),\n },\n {\n field: 'netCents',\n headerName: 'Total',\n type: 'number',\n width: 150,\n align: 'right',\n headerAlign: 'right',\n renderCell: ({ row }: any) => (\n <Stack sx={{ alignItems: 'flex-end', minWidth: 0, width: 1 }}>\n <Typography variant=\"body2\">\n {`$${(row.netCents / 100).toFixed(2)}`}\n </Typography>\n {row.refundedCents ? (\n <Typography variant=\"caption\" color=\"text.secondary\" noWrap>\n {`$${((row.totals?.totalCents ?? row.amountCents ?? 0) / 100).toFixed(2)} less refunds`}\n </Typography>\n ) : null}\n </Stack>\n ),\n },\n {\n field: 'statusKey',\n headerName: 'Status',\n width: 230,\n renderCell: ({ row }: any) => {\n // A lost chargeback leaves `status: 'refunded'` (AGL-1787), so the\n // status pill cannot tell the two apart either — which is why the\n // dispute chip sits beside it rather than being folded into it.\n const dispute: ReturnType<typeof CommerceModel.describeOrderDispute> =\n row.disputeBadge\n return (\n <Stack sx={{ minWidth: 0 }}>\n <Stack direction=\"row\" spacing={0.5} sx={{ alignItems: 'center' }}>\n <Chip\n label={\n CommerceModel.ORDER_STATUS_LABELS[\n row.statusKey as CommerceModel.OrderStatus\n ] ?? row.statusKey\n }\n size=\"small\"\n color={\n CommerceModel.ORDER_STATUS_COLOR[\n row.statusKey as CommerceModel.OrderStatus\n ] ?? 'default'\n }\n variant=\"outlined\"\n />\n {dispute ? (\n <Tooltip title={dispute.detail}>\n <Chip\n label={dispute.label}\n size=\"small\"\n color={DISPUTE_COLOR[dispute.tone]}\n variant=\"filled\"\n />\n </Tooltip>\n ) : null}\n </Stack>\n {/*\n The deadline on the row itself, while the case is open — the\n one fact on this screen that expires.\n */}\n {dispute?.evidenceDaysLeft !== undefined ? (\n <Typography\n variant=\"caption\"\n component=\"div\"\n color={dispute.evidenceDaysLeft < 0 ? 'error' : 'warning.main'}\n >\n {dispute.evidenceDaysLeft < 0\n ? 'Evidence deadline passed'\n : `Evidence due in ${dispute.evidenceDaysLeft} day${\n dispute.evidenceDaysLeft === 1 ? '' : 's'\n }`}\n </Typography>\n ) : null}\n </Stack>\n )\n },\n },\n {\n field: 'createdAtMs',\n headerName: 'Date',\n width: 130,\n renderCell: ({ row }: any) => {\n const createdAt =\n row.createdAt?.toDate?.() ??\n (row.createdAtMs ? new Date(row.createdAtMs) : null)\n return (\n <Stack sx={{ minWidth: 0 }}>\n <Typography variant=\"body2\" noWrap>\n {createdAt ? createdAt.toLocaleDateString() : '—'}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" noWrap>\n {createdAt ? createdAt.toLocaleTimeString() : ''}\n </Typography>\n </Stack>\n )\n },\n },\n ],\n [],\n )\n\n\n const columns = useMemo(\n () =>\n listFilterGridColumns(\n orderColumns,\n ORDER_LIST_FIELDS,\n filterOptions,\n ORDER_LIST_HEADERS,\n ),\n [orderColumns, filterOptions],\n )\n\n /*\n * The store is empty only when an UNFILTERED first page came back empty; a\n * filter or search that matches nothing keeps the grid, its chips and its\n * panel, so the reader can take the filter back off.\n */\n const empty =\n listStatus === 'success' &&\n !filtering &&\n askedSort === ORDER_LIST_COLUMN_SORTS[0] &&\n page === 0 &&\n orders.length === 0\n\n return (\n <CardDisplay\n header={'Orders'}\n // Shipping actions live in the card header (AGL-3613): the orders\n // still to ship for a label tool, and its tracking numbers back.\n HeaderProps={{ action: <OrderShippingActions hostId={hostId} /> }}\n help={pluginDocsHelp('commerce', {\n anchor: '#orders-screen',\n excerpt:\n 'Every order with its channel, status and net total. A refunded ' +\n 'order shows what is left, with the gross beneath it.',\n })}\n contentGutterX\n contentGutterY\n >\n {empty ? (\n /*\n * An invitation, not a report (AGL-1805). The \"Draft order\" button\n * used to live in the other arm of this ternary, so the one state a\n * draft order exists for — no sales yet, invoice the customer you\n * already have — was the only state that could not reach it, and\n * every other route into the dialog needs an order to exist first.\n *\n * The filters stay behind deliberately: they belong to a list with\n * rows in it. Export orders likewise — a header-only file is not\n * something a merchant on day one is looking for.\n */\n <Stack spacing={1} sx={{ alignItems: 'flex-start' }}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {\n 'No orders yet. Storefront sales, POS sales and draft orders ' +\n 'all appear here as they come in.'\n }\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {\n 'Selling to someone directly? Draft their order and send them ' +\n 'a payment link.'\n }\n </Typography>\n <Button\n size=\"small\"\n variant=\"contained\"\n color=\"primary\"\n onClick={openDraft}\n >\n {'Draft order'}\n </Button>\n </Stack>\n ) : (\n <Stack spacing={1}>\n {showStats ? (\n <Stack\n useFlexGap\n direction=\"row\"\n spacing={3}\n sx={{ flexWrap: 'wrap', rowGap: 1 }}\n >\n <CommerceStatTile\n label=\"Revenue · 30d\"\n value={`$${(summary.revenueCents / 100).toFixed(2)}`}\n deltaPct={summary.revenueDeltaPct}\n deltaCaption=\"vs the previous 30 days\"\n />\n <CommerceStatTile\n label=\"Orders · 30d\"\n value={String(summary.orders)}\n deltaPct={summary.ordersDeltaPct}\n deltaCaption=\"vs the previous 30 days\"\n />\n <CommerceStatTile\n label=\"Avg order value\"\n value={`$${(summary.aovCents / 100).toFixed(2)}`}\n deltaPct={summary.aovDeltaPct}\n deltaCaption=\"vs the previous 30 days\"\n />\n </Stack>\n ) : null}\n {showStats && statsWindow.truncated ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`Figures count the ${STATS_ORDER_CEILING} most recent orders of the last 60 days.`}\n </Typography>\n ) : null}\n {openDisputes.count > 0 ? (\n <Alert\n severity={openDisputes.overdue ? 'error' : 'warning'}\n action={\n showingOpenDisputes ? undefined : (\n <Button\n size=\"small\"\n color=\"inherit\"\n onClick={() =>\n setClauses(\n upsertListFilterClause(\n clauses,\n OPEN_DISPUTE_CLAUSE.field,\n OPEN_DISPUTE_CLAUSE,\n ),\n )\n }\n >\n {'Show them'}\n </Button>\n )\n }\n >\n <AlertTitle>\n {moreDisputes\n ? `More than ${OPEN_DISPUTE_CEILING} charges are disputed with the shopper’s bank`\n : openDisputes.count === 1\n ? 'A shopper has disputed a charge with their bank'\n : `${openDisputes.count} charges are disputed with the shopper’s bank`}\n </AlertTitle>\n {openDisputes.soonestDaysLeft === undefined\n ? 'Answer in the Stripe dashboard while the case is open — an unanswered dispute is decided for the shopper.'\n : openDisputes.soonestDaysLeft < 0\n ? 'The evidence deadline has passed on at least one of these. Stripe decides an unanswered dispute for the shopper.'\n : `Evidence is due to Stripe in ${openDisputes.soonestDaysLeft} day${\n openDisputes.soonestDaysLeft === 1 ? '' : 's'\n } on the tightest of these. An unanswered dispute is decided for the shopper.`}\n </Alert>\n ) : null}\n {/*\n The buttons stay beside the grid: Export orders writes every order\n the query matches, with the fields the person picks, which the grid's\n own export — one page — cannot.\n */}\n <Stack\n direction=\"row\"\n spacing={1}\n useFlexGap\n sx={{ alignItems: 'center', justifyContent: 'flex-end', flexWrap: 'wrap' }}\n >\n {checkedIds.length ? (\n <Button\n size=\"small\"\n variant=\"outlined\"\n disabled={bulkBusy || fulfillableCount === 0}\n onClick={handleBulkFulfill}\n >\n {`Mark as fulfilled (${fulfillableCount})`}\n </Button>\n ) : null}\n {/* Other plugins' bulk actions on the ticked orders (AGL-3612). */}\n {checkedIds.length && WidgetSlot ? (\n <WidgetSlot\n slot={ORDERS_BULK_ZONE.id}\n hostId={hostId}\n orgId={undefined}\n selectedOrderIds={checkedIds}\n storeName=\"\"\n />\n ) : null}\n {/* Only for whom the route takes it (AGL-3554). */}\n {transfer?.can('export', { resource: COMMERCE_ORDERS_TRANSFER, scope: 'host', hostId }) ? (\n <Button size=\"small\" onClick={openExport}>\n {'Export orders'}\n </Button>\n ) : null}\n <Button\n size=\"small\"\n variant=\"contained\"\n color=\"primary\"\n onClick={openDraft}\n >\n {'Draft order'}\n </Button>\n </Stack>\n <ListFilterChips\n fields={ORDER_LIST_FIELDS}\n headers={ORDER_LIST_HEADERS}\n clauses={clauses}\n onChange={setClauses}\n options={filterOptions}\n />\n <ListQueryNotices\n refused={refused}\n notices={[...plan.notices, ...columnSort.notices]}\n />\n <ListTable\n aria-label=\"Orders\"\n rows={columnSort.rows}\n columns={columns}\n onOpen={(id) => setSelectedId(id)}\n selectable={{ selected: checkedIds, onChange: setCheckedIds }}\n loading={listStatus === 'loading'}\n /*\n * The grid must NOT also filter, search or sort on its own: the\n * query answers the filters and the search, and every header\n * order is the query's or the page's (`columnSort`).\n */\n filterMode=\"server\"\n filterModel={gridFilter.filterModel}\n onFilterModelChange={gridFilter.onFilterModelChange}\n quickFilter\n columnSort={columnSort}\n // `ListPagination` below pages the query.\n hideFooter\n initialState={{\n columns: { columnVisibilityModel: ORDER_HIDDEN_COLUMNS },\n }}\n noRowsLabel=\"No orders match these filters\"\n />\n <ListPagination\n page={page}\n pageSize={pageSize}\n rowCount={orderRows.length}\n hasMore={hasMore}\n onPageChange={setPage}\n onPageSizeChange={setPageSize}\n />\n </Stack>\n )}\n {selectedOrder ? (\n <OrderDetailDialog\n hostId={hostId}\n order={selectedOrder}\n onClose={() => setSelectedId(null)}\n />\n ) : null}\n <Dialog\n open={Boolean(draft)}\n onClose={() => setDraft(null)}\n maxWidth=\"xs\"\n fullWidth\n >\n <DialogTitle>{'Draft order'}</DialogTitle>\n <DialogContent sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <TextField\n label=\"Product\"\n value={draft?.productId ?? ''}\n onChange={(event) =>\n setDraft((prev) =>\n prev\n ? { ...prev, productId: event.target.value, variantId: '' }\n : prev,\n )\n }\n size=\"small\"\n select\n sx={{ mt: 1 }}\n /*\n * The second dead end behind the first (AGL-1805): a store with\n * no orders may have no products either, and a draft order is\n * composed from one — so \"Create & copy link\" stays disabled. Say\n * why, rather than opening an empty menu onto nothing.\n */\n helperText={\n selectableProducts.length === 0\n ? 'Add a product to this store first — a draft order is built from one.'\n : undefined\n }\n >\n {selectableProducts.map((product: any) => (\n <MenuItem key={product.$id} value={product.$id}>\n {product.name ?? product.$id}\n </MenuItem>\n ))}\n </TextField>\n {(() => {\n const product = productWindow.rows.find(\n (item: any) => item.$id === draft?.productId,\n )\n const variants = product\n ? CommerceModel.liftLegacyProduct(product).variants\n : []\n return variants.length > 1 ? (\n <TextField\n label=\"Variant\"\n value={draft?.variantId ?? ''}\n onChange={(event) =>\n setDraft((prev) =>\n prev ? { ...prev, variantId: event.target.value } : prev,\n )\n }\n size=\"small\"\n select\n >\n {variants.map((variant) => (\n <MenuItem key={variant.id} value={variant.id}>\n {`${Object.values(variant.options ?? {}).join(' / ') || 'Default'} — $${variant.priceUsd}`}\n </MenuItem>\n ))}\n </TextField>\n ) : null\n })()}\n <TextField\n label=\"Quantity\"\n value={draft?.quantity ?? '1'}\n onChange={(event) =>\n setDraft((prev) =>\n prev\n ? {\n ...prev,\n quantity: event.target.value.replace(/[^0-9]/g, ''),\n }\n : prev,\n )\n }\n size=\"small\"\n slotProps={{ htmlInput: { inputMode: 'numeric' } }}\n />\n <TextField\n label=\"Buyer email (optional)\"\n value={draft?.email ?? ''}\n onChange={(event) =>\n setDraft((prev) =>\n prev ? { ...prev, email: event.target.value } : prev,\n )\n }\n size=\"small\"\n />\n {draft?.shipCountries?.length ? (\n <TextField\n label=\"Ships to\"\n value={draft?.shipTo ?? ''}\n onChange={(event) =>\n setDraft((prev) =>\n prev ? { ...prev, shipTo: event.target.value } : prev,\n )\n }\n size=\"small\"\n select\n helperText={\n 'This store’s shipping rates differ by destination, so the ' +\n 'payment link has to be priced for one.'\n }\n >\n {draft.shipCountries.map((code) => (\n <MenuItem key={code} value={code}>\n {CommerceModel.CHECKOUT_SHIPPING_COUNTRY_NAMES[code] ?? code}\n </MenuItem>\n ))}\n </TextField>\n ) : null}\n {draft?.askPostal ? (\n <TextField\n label=\"Postal code\"\n value={draft?.shipPostal ?? ''}\n onChange={(event) =>\n setDraft((prev) => (prev ? { ...prev, shipPostal: event.target.value } : prev))\n }\n size=\"small\"\n helperText=\"This store prices shipping by carrier, which needs the postal code.\"\n />\n ) : null}\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setDraft(null)}>{'Cancel'}</Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={\n !draft?.productId ||\n draft?.busy ||\n // Once asked, the answer is required: retrying without one is\n // refused again, so the button would only look broken.\n Boolean(draft?.shipCountries?.length && !draft?.shipTo) ||\n Boolean(draft?.askPostal && !draft?.shipPostal?.trim())\n }\n onClick={handleDraftCreate}\n >\n {'Create & copy link'}\n </Button>\n </DialogActions>\n </Dialog>\n </CardDisplay>\n )\n}\nHostOrdersCard.displayName = 'HostOrdersCard'\n\nexport default HostOrdersCard\n"],"names":["CommerceModel","CardDisplay","ListFilterChips","ListPagination","ListQueryNotices","listQueryRefusals","ListTable","hiddenFilterVisibility","useListColumnSort","listFilterGridColumns","upsertListFilterClause","useListGridFilter","useSnackbar","checkEntitlement","pluginDocsHelp","ORDERS_CUSTOMER_PARAM","ORDERS_ORDER_PARAM","Alert","AlertTitle","Button","Chip","Dialog","DialogActions","DialogContent","DialogTitle","MenuItem","Stack","TextField","Tooltip","Typography","collection","doc","getDoc","limit","orderBy","query","where","useSearchParams","useCallback","useEffect","useMemo","useRef","useState","ceilingedWindow","collectionCeiling","useFirestore","useOrgPlan","useUser","useFirestoreCollection","useListQuery","useTransferLauncher","commerceListFilter","COMMERCE_ORDERS_TRANSFER","OrderShippingActions","authorizedFetch","OPEN_DISPUTE_CLAUSE","ORDER_CHANNEL_OPTIONS","ORDER_LIST_COLUMN_SORTS","ORDER_DISPUTE_OPTIONS","ORDER_LIST_FIELDS","ORDER_LIST_HEADERS","ORDER_LIST_QUERY","ORDER_LIST_SELECT_FIELDS","ORDER_STATUS_OPTIONS","ordersCustomerClause","CommerceStatTile","bulkFulfillOrders","BULK_FULFILLABLE_STATUSES","describeBulkFulfill","ORDERS_BULK_ZONE","useConsoleWidgetSlot","OrderDetailDialog","DISPUTE_COLOR","PRODUCT_NAME_WINDOW","OPEN_DISPUTE_CEILING","STATS_WINDOW_MS","STATS_ORDER_CEILING","ORDER_VISIBLE_COLUMNS","ORDER_HIDDEN_COLUMNS","ORDER_PAGE_SORTS","netCents","row","ORDER_PAGE_SORT_HEADERS","HostOrdersCard","props","loadedOrders","draft","hostId","firestore","ordersRef","data","productDocs","idField","productWindow","undefined","productNames","map","product","rows","$id","name","org","ready","orgReady","showStats","searchParams","clauses","setClauses","customer","get","gridFilter","onChange","selectFields","filtering","length","searchWords","some","word","trim","askedSort","setAskedSort","disputedRows","hasMore","moreDisputes","declaration","request","deps","pageSize","confirmDisappearances","orders","page","setPage","setPageSize","plan","status","listStatus","search","sort","selectedId","setSelectedId","checkedIds","setCheckedIds","bulkBusy","setBulkBusy","WidgetSlot","seededOrderId","seededOrder","setSeededOrder","seededOpened","current","order","then","snapshot","id","exists","catch","setDraft","user","enqueueSnackbar","orderRows","lifted","liftLegacyOrder","orderLabel","formatOrderNumber","itemName","lineItems","productId","statusKey","channelKey","channel","orderNetCents","disputeBadge","describeOrderDispute","columnSort","sorts","defaultSort","onSortChange","pageSorts","headers","productOptions","value","String","label","filterOptions","productIds","disputeKey","refused","fields","options","showingOpenDisputes","clause","field","op","openDisputes","summariseOpenDisputes","statsSince","Date","now","statsDocs","statsWindow","summary","summarizeOrderWindow","nowMs","transfer","openExport","resource","scope","filter","draftAttemptKey","variantId","quantity","email","shipTo","shipPostal","handleDraftCreate","prev","busy","globalThis","crypto","randomUUID","Math","random","toString","slice","response","method","body","JSON","stringify","Number","shippingCountry","shippingPostalCode","payload","json","ok","needsShippingCountry","shipCountries","shippingCountries","CHECKOUT_SHIPPING_COUNTRIES","needsShippingPostalCode","askPostal","error","variant","allowDuplicate","navigator","clipboard","writeText","url","persist","checkedOrders","includes","fulfillableCount","handleBulkFulfill","batchKey","result","unknown","selectedOrder","find","openDraft","selectableProducts","deletedAt","orderColumns","headerName","flex","minWidth","renderCell","extraItems","max","sx","noWrap","color","customerEmail","width","orderChannelLabel","type","align","headerAlign","alignItems","toFixed","refundedCents","totals","totalCents","amountCents","dispute","direction","spacing","ORDER_STATUS_LABELS","size","ORDER_STATUS_COLOR","title","detail","tone","evidenceDaysLeft","component","createdAt","toDate","createdAtMs","toLocaleDateString","toLocaleTimeString","columns","empty","header","HeaderProps","action","help","anchor","excerpt","contentGutterX","contentGutterY","onClick","useFlexGap","flexWrap","rowGap","revenueCents","deltaPct","revenueDeltaPct","deltaCaption","ordersDeltaPct","aovCents","aovDeltaPct","truncated","count","severity","overdue","soonestDaysLeft","justifyContent","disabled","slot","orgId","selectedOrderIds","storeName","can","notices","aria-label","onOpen","selectable","selected","loading","filterMode","filterModel","onFilterModelChange","quickFilter","hideFooter","initialState","columnVisibilityModel","noRowsLabel","rowCount","onPageChange","onPageSizeChange","onClose","open","Boolean","maxWidth","fullWidth","display","flexDirection","gap","event","target","select","mt","helperText","item","variants","liftLegacyProduct","Object","values","join","priceUsd","replace","slotProps","htmlInput","inputMode","code","CHECKOUT_SHIPPING_COUNTRY_NAMES","displayName"],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ export interface LocalDeliverySettingsCardProps {
18
+ hostId: string;
19
+ }
20
+ /**
21
+ * Local delivery (AGL-3624): the store's OWN delivery — zones by postal code
22
+ * or by distance, each with a fee, a minimum order and a free-over
23
+ * threshold, and the delivery windows a buyer books at the cart. Stored on
24
+ * `settings/store.localDelivery`, written whole so a cleared field is
25
+ * cleared. Marketplace couriers (DoorDash and the rest) are the Delivery apps
26
+ * plugin's, and nothing here touches them.
27
+ *
28
+ * DISTANCE ZONES are offered only where the store's shipping address check
29
+ * can place an address on a map (`GET /api/commerce/local-fulfillment`), and
30
+ * need the store placed first ("Place on map"). Postal-code zones need
31
+ * nothing.
32
+ */
33
+ export declare function LocalDeliverySettingsCard(props: LocalDeliverySettingsCardProps): import("react").JSX.Element;
34
+ export declare namespace LocalDeliverySettingsCard {
35
+ var displayName: string;
36
+ }
37
+ export default LocalDeliverySettingsCard;