@aglyn/plugins-commerce 1.0.0-beta.285 → 1.0.0-beta.288

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 (430) hide show
  1. package/README.md +1 -1
  2. package/package.json +13 -13
  3. package/src/lib/components/cart.js +25 -12
  4. package/src/lib/components/cart.js.map +1 -1
  5. package/src/lib/components/commerce-console-page.js +70 -13
  6. package/src/lib/components/commerce-console-page.js.map +1 -1
  7. package/src/lib/components/console/order-detail-dialog.component.js +2 -1
  8. package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
  9. package/src/lib/components/console/order-webhooks-card.component.js +1 -1
  10. package/src/lib/components/console/order-webhooks-card.component.js.map +1 -1
  11. package/src/lib/components/console/payment-methods-card.component.js +1 -1
  12. package/src/lib/components/console/payment-methods-card.component.js.map +1 -1
  13. package/src/lib/components/console/pos/pos-cart-panel.component.d.ts +5 -0
  14. package/src/lib/components/console/pos/pos-cart-panel.component.js +18 -12
  15. package/src/lib/components/console/pos/pos-cart-panel.component.js.map +1 -1
  16. package/src/lib/components/console/pos/pos-hardware-api.d.ts +76 -5
  17. package/src/lib/components/console/pos/pos-hardware-api.js +53 -11
  18. package/src/lib/components/console/pos/pos-hardware-api.js.map +1 -1
  19. package/src/lib/components/console/pos/pos-hardware-buyer.component.d.ts +18 -0
  20. package/src/lib/components/console/pos/pos-hardware-buyer.component.js +629 -0
  21. package/src/lib/components/console/pos/pos-hardware-buyer.component.js.map +1 -0
  22. package/src/lib/components/console/pos/pos-hardware-sale-api.d.ts +162 -0
  23. package/src/lib/components/console/pos/pos-hardware-sale-api.js +122 -0
  24. package/src/lib/components/console/pos/pos-hardware-sale-api.js.map +1 -0
  25. package/src/lib/components/console/pos/pos-hardware-sale-terms.component.d.ts +39 -0
  26. package/src/lib/components/console/pos/pos-hardware-sale-terms.component.js +251 -0
  27. package/src/lib/components/console/pos/pos-hardware-sale-terms.component.js.map +1 -0
  28. package/src/lib/components/console/pos/use-pos-display.js +50 -0
  29. package/src/lib/components/console/pos/use-pos-display.js.map +1 -1
  30. package/src/lib/components/console/pos-cellular-control.component.d.ts +41 -0
  31. package/src/lib/components/console/pos-cellular-control.component.js +211 -0
  32. package/src/lib/components/console/pos-cellular-control.component.js.map +1 -0
  33. package/src/lib/components/console/pos-devices-card.component.d.ts +9 -1
  34. package/src/lib/components/console/pos-devices-card.component.js +47 -15
  35. package/src/lib/components/console/pos-devices-card.component.js.map +1 -1
  36. package/src/lib/components/console/pos-display/pos-display-api.d.ts +6 -0
  37. package/src/lib/components/console/pos-display/pos-display-api.js +8 -1
  38. package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -1
  39. package/src/lib/components/console/pos-display-page.component.d.ts +13 -0
  40. package/src/lib/components/console/pos-display-page.component.js +44 -2
  41. package/src/lib/components/console/pos-display-page.component.js.map +1 -1
  42. package/src/lib/components/console/pos-hardware-card.component.d.ts +12 -4
  43. package/src/lib/components/console/pos-hardware-card.component.js +157 -36
  44. package/src/lib/components/console/pos-hardware-card.component.js.map +1 -1
  45. package/src/lib/components/console/pos-hardware-orders-staff-page.component.js +360 -80
  46. package/src/lib/components/console/pos-hardware-orders-staff-page.component.js.map +1 -1
  47. package/src/lib/components/console/pos-hardware-terms-page.component.d.ts +34 -0
  48. package/src/lib/components/console/pos-hardware-terms-page.component.js +257 -0
  49. package/src/lib/components/console/pos-hardware-terms-page.component.js.map +1 -0
  50. package/src/lib/components/console/pos-hardware-terms-sign-page.component.d.ts +27 -0
  51. package/src/lib/components/console/pos-hardware-terms-sign-page.component.js +104 -0
  52. package/src/lib/components/console/pos-hardware-terms-sign-page.component.js.map +1 -0
  53. package/src/lib/components/console/pos-hardware-waiting-card.component.d.ts +24 -0
  54. package/src/lib/components/console/pos-hardware-waiting-card.component.js +205 -0
  55. package/src/lib/components/console/pos-hardware-waiting-card.component.js.map +1 -0
  56. package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js +297 -201
  57. package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js.map +1 -1
  58. package/src/lib/components/console/pos-ops/pos-check-ins-card.component.d.ts +3 -0
  59. package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js +260 -92
  60. package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js.map +1 -1
  61. package/src/lib/components/console/pos-ops/pos-operations-bar.component.d.ts +9 -0
  62. package/src/lib/components/console/pos-ops/pos-operations-bar.component.js +15 -6
  63. package/src/lib/components/console/pos-ops/pos-operations-bar.component.js.map +1 -1
  64. package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.d.ts +25 -0
  65. package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.js +136 -0
  66. package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.js.map +1 -0
  67. package/src/lib/components/console/pos-ops/pos-shift-panel.component.d.ts +6 -0
  68. package/src/lib/components/console/pos-ops/pos-shift-panel.component.js +48 -31
  69. package/src/lib/components/console/pos-ops/pos-shift-panel.component.js.map +1 -1
  70. package/src/lib/components/console/pos-page.component.d.ts +1 -1
  71. package/src/lib/components/console/pos-page.component.js +63 -12
  72. package/src/lib/components/console/pos-page.component.js.map +1 -1
  73. package/src/lib/components/console/pos-reader-splash-setting.component.js +1 -1
  74. package/src/lib/components/console/pos-reader-splash-setting.component.js.map +1 -1
  75. package/src/lib/components/console/product-check-in-fields.component.d.ts +4 -2
  76. package/src/lib/components/console/product-check-in-fields.component.js +60 -14
  77. package/src/lib/components/console/product-check-in-fields.component.js.map +1 -1
  78. package/src/lib/components/console/product-editor-dialog.component.js +44 -1
  79. package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
  80. package/src/lib/components/console/product-hardware-sku-field.component.d.ts +19 -0
  81. package/src/lib/components/console/product-hardware-sku-field.component.js +92 -0
  82. package/src/lib/components/console/product-hardware-sku-field.component.js.map +1 -0
  83. package/src/lib/components/console/product-kiosk-offer-field.component.d.ts +22 -0
  84. package/src/lib/components/console/product-kiosk-offer-field.component.js +94 -0
  85. package/src/lib/components/console/product-kiosk-offer-field.component.js.map +1 -0
  86. package/src/lib/components/console/product-register-fields.component.d.ts +4 -0
  87. package/src/lib/components/console/product-register-fields.component.js +31 -2
  88. package/src/lib/components/console/product-register-fields.component.js.map +1 -1
  89. package/src/lib/components/console/products-hub-card.component.js +11 -2
  90. package/src/lib/components/console/products-hub-card.component.js.map +1 -1
  91. package/src/lib/components/console/register-hardware-card.component.d.ts +11 -0
  92. package/src/lib/components/console/register-hardware-card.component.js +56 -27
  93. package/src/lib/components/console/register-hardware-card.component.js.map +1 -1
  94. package/src/lib/components/console/reservation-guests-dialog.component.d.ts +28 -0
  95. package/src/lib/components/console/reservation-guests-dialog.component.js +189 -0
  96. package/src/lib/components/console/reservation-guests-dialog.component.js.map +1 -0
  97. package/src/lib/components/console/reservations-card.component.d.ts +9 -0
  98. package/src/lib/components/console/reservations-card.component.js +158 -23
  99. package/src/lib/components/console/reservations-card.component.js.map +1 -1
  100. package/src/lib/components/console/shippingeasy-card.component.js +1 -1
  101. package/src/lib/components/console/shippingeasy-card.component.js.map +1 -1
  102. package/src/lib/components/console/shipstation-card.component.d.ts +1 -1
  103. package/src/lib/components/console/shipstation-card.component.js +3 -3
  104. package/src/lib/components/console/shipstation-card.component.js.map +1 -1
  105. package/src/lib/components/product-detail.d.ts +4 -0
  106. package/src/lib/components/product-detail.js +40 -5
  107. package/src/lib/components/product-detail.js.map +1 -1
  108. package/src/lib/components/product-reviews.js +28 -11
  109. package/src/lib/components/product-reviews.js.map +1 -1
  110. package/src/lib/components/reservation-widget.js +28 -5
  111. package/src/lib/components/reservation-widget.js.map +1 -1
  112. package/src/lib/components/use-day-picker.d.ts +25 -0
  113. package/src/lib/components/use-day-picker.js +57 -0
  114. package/src/lib/components/use-day-picker.js.map +1 -0
  115. package/src/lib/constants/operator-alerts.d.ts +55 -0
  116. package/src/lib/constants/operator-alerts.js +156 -1
  117. package/src/lib/constants/operator-alerts.js.map +1 -1
  118. package/src/lib/declarations.console-server.js +54 -1
  119. package/src/lib/declarations.console-server.js.map +1 -1
  120. package/src/lib/declarations.d.ts +4 -2
  121. package/src/lib/declarations.js +15 -4
  122. package/src/lib/declarations.js.map +1 -1
  123. package/src/lib/declarations.server.js +9 -0
  124. package/src/lib/declarations.server.js.map +1 -1
  125. package/src/lib/model/commerce-cart.d.ts +9 -1
  126. package/src/lib/model/commerce-cart.js +4 -3
  127. package/src/lib/model/commerce-cart.js.map +1 -1
  128. package/src/lib/model/commerce-check-in-product.d.ts +26 -0
  129. package/src/lib/model/commerce-check-in-product.js +64 -2
  130. package/src/lib/model/commerce-check-in-product.js.map +1 -1
  131. package/src/lib/model/commerce-check-in-record.d.ts +127 -0
  132. package/src/lib/model/commerce-check-in-record.js +36 -0
  133. package/src/lib/model/commerce-check-in-record.js.map +1 -0
  134. package/src/lib/model/commerce-check-in.d.ts +91 -87
  135. package/src/lib/model/commerce-check-in.js +186 -62
  136. package/src/lib/model/commerce-check-in.js.map +1 -1
  137. package/src/lib/model/commerce-kiosk-offer.d.ts +31 -0
  138. package/src/lib/model/commerce-kiosk-offer.js +35 -0
  139. package/src/lib/model/commerce-kiosk-offer.js.map +1 -0
  140. package/src/lib/model/commerce-orders.d.ts +76 -0
  141. package/src/lib/model/commerce-orders.js +6 -0
  142. package/src/lib/model/commerce-orders.js.map +1 -1
  143. package/src/lib/model/commerce-pos-day-report.d.ts +54 -1
  144. package/src/lib/model/commerce-pos-day-report.js +39 -2
  145. package/src/lib/model/commerce-pos-day-report.js.map +1 -1
  146. package/src/lib/model/commerce-pos-offline.d.ts +1 -1
  147. package/src/lib/model/commerce-pos-offline.js +6 -1
  148. package/src/lib/model/commerce-pos-offline.js.map +1 -1
  149. package/src/lib/model/commerce-pos-ops.js +3 -2
  150. package/src/lib/model/commerce-pos-ops.js.map +1 -1
  151. package/src/lib/model/commerce-pos.d.ts +36 -3
  152. package/src/lib/model/commerce-pos.js +14 -6
  153. package/src/lib/model/commerce-pos.js.map +1 -1
  154. package/src/lib/model/commerce-receipt.js +3 -2
  155. package/src/lib/model/commerce-receipt.js.map +1 -1
  156. package/src/lib/model/commerce-reservations.d.ts +69 -4
  157. package/src/lib/model/commerce-reservations.js +57 -5
  158. package/src/lib/model/commerce-reservations.js.map +1 -1
  159. package/src/lib/model/commerce.d.ts +66 -0
  160. package/src/lib/model/commerce.js +15 -0
  161. package/src/lib/model/commerce.js.map +1 -1
  162. package/src/lib/model/order-list-fields.d.ts +11 -0
  163. package/src/lib/model/order-list-fields.js +17 -1
  164. package/src/lib/model/order-list-fields.js.map +1 -1
  165. package/src/lib/model/own-store-tax-summary.d.ts +152 -0
  166. package/src/lib/model/own-store-tax-summary.js +288 -0
  167. package/src/lib/model/own-store-tax-summary.js.map +1 -0
  168. package/src/lib/model/plugin-permissions.d.ts +74 -0
  169. package/src/lib/model/plugin-permissions.js +224 -7
  170. package/src/lib/model/plugin-permissions.js.map +1 -1
  171. package/src/lib/model/pos-cellular.d.ts +223 -0
  172. package/src/lib/model/pos-cellular.js +293 -0
  173. package/src/lib/model/pos-cellular.js.map +1 -0
  174. package/src/lib/model/pos-hardware-in-person.d.ts +98 -0
  175. package/src/lib/model/pos-hardware-in-person.js +224 -0
  176. package/src/lib/model/pos-hardware-in-person.js.map +1 -0
  177. package/src/lib/model/pos-hardware-tax-summary.d.ts +166 -0
  178. package/src/lib/model/pos-hardware-tax-summary.js +225 -0
  179. package/src/lib/model/pos-hardware-tax-summary.js.map +1 -0
  180. package/src/lib/model/pos-hardware-terms.d.ts +74 -0
  181. package/src/lib/model/pos-hardware-terms.js +115 -0
  182. package/src/lib/model/pos-hardware-terms.js.map +1 -0
  183. package/src/lib/model/pos-hardware.d.ts +349 -7
  184. package/src/lib/model/pos-hardware.js +291 -20
  185. package/src/lib/model/pos-hardware.js.map +1 -1
  186. package/src/lib/model/product-write.d.ts +10 -0
  187. package/src/lib/model/product-write.js +4 -2
  188. package/src/lib/model/product-write.js.map +1 -1
  189. package/src/lib/model/workspace-site-permissions.d.ts +26 -0
  190. package/src/lib/model/workspace-site-permissions.js +81 -0
  191. package/src/lib/model/workspace-site-permissions.js.map +1 -0
  192. package/src/lib/plugin.js +16 -0
  193. package/src/lib/plugin.js.map +1 -1
  194. package/src/lib/server/billing-webhook.js +25 -1
  195. package/src/lib/server/billing-webhook.js.map +1 -1
  196. package/src/lib/server/cancel-order.js +7 -5
  197. package/src/lib/server/cancel-order.js.map +1 -1
  198. package/src/lib/server/cart-checkout.js +20 -8
  199. package/src/lib/server/cart-checkout.js.map +1 -1
  200. package/src/lib/server/cart.js +29 -0
  201. package/src/lib/server/cart.js.map +1 -1
  202. package/src/lib/server/checkout.js +42 -13
  203. package/src/lib/server/checkout.js.map +1 -1
  204. package/src/lib/server/collection-membership.d.ts +4 -0
  205. package/src/lib/server/collection-membership.js +5 -10
  206. package/src/lib/server/collection-membership.js.map +1 -1
  207. package/src/lib/server/commerce-site-keys.d.ts +48 -0
  208. package/src/lib/server/commerce-site-keys.js +61 -0
  209. package/src/lib/server/commerce-site-keys.js.map +1 -0
  210. package/src/lib/server/draft-order.js +8 -5
  211. package/src/lib/server/draft-order.js.map +1 -1
  212. package/src/lib/server/fulfill-order.js +7 -5
  213. package/src/lib/server/fulfill-order.js.map +1 -1
  214. package/src/lib/server/gift-cards.js +8 -5
  215. package/src/lib/server/gift-cards.js.map +1 -1
  216. package/src/lib/server/local-fulfillment-status.js +9 -6
  217. package/src/lib/server/local-fulfillment-status.js.map +1 -1
  218. package/src/lib/server/member-post.js +6 -5
  219. package/src/lib/server/member-post.js.map +1 -1
  220. package/src/lib/server/membership-admin-password.d.ts +4 -2
  221. package/src/lib/server/membership-admin-password.js +10 -8
  222. package/src/lib/server/membership-admin-password.js.map +1 -1
  223. package/src/lib/server/membership-admin-remove.d.ts +7 -5
  224. package/src/lib/server/membership-admin-remove.js +9 -9
  225. package/src/lib/server/membership-admin-remove.js.map +1 -1
  226. package/src/lib/server/order-notifications.js +5 -2
  227. package/src/lib/server/order-notifications.js.map +1 -1
  228. package/src/lib/server/order-print.js +7 -5
  229. package/src/lib/server/order-print.js.map +1 -1
  230. package/src/lib/server/order-receipt-send.js +8 -5
  231. package/src/lib/server/order-receipt-send.js.map +1 -1
  232. package/src/lib/server/order-webhooks.js +8 -8
  233. package/src/lib/server/order-webhooks.js.map +1 -1
  234. package/src/lib/server/orders-shipping-prepare.js +9 -6
  235. package/src/lib/server/orders-shipping-prepare.js.map +1 -1
  236. package/src/lib/server/own-store-tax-return-source.d.ts +47 -0
  237. package/src/lib/server/own-store-tax-return-source.js +312 -0
  238. package/src/lib/server/own-store-tax-return-source.js.map +1 -0
  239. package/src/lib/server/payment-methods.js +13 -9
  240. package/src/lib/server/payment-methods.js.map +1 -1
  241. package/src/lib/server/pos-auth.d.ts +37 -6
  242. package/src/lib/server/pos-auth.js +40 -15
  243. package/src/lib/server/pos-auth.js.map +1 -1
  244. package/src/lib/server/pos-cellular-billing.d.ts +81 -0
  245. package/src/lib/server/pos-cellular-billing.js +711 -0
  246. package/src/lib/server/pos-cellular-billing.js.map +1 -0
  247. package/src/lib/server/pos-cellular-notify.d.ts +47 -0
  248. package/src/lib/server/pos-cellular-notify.js +150 -0
  249. package/src/lib/server/pos-cellular-notify.js.map +1 -0
  250. package/src/lib/server/pos-cellular.d.ts +88 -0
  251. package/src/lib/server/pos-cellular.js +339 -0
  252. package/src/lib/server/pos-cellular.js.map +1 -0
  253. package/src/lib/server/pos-check-in.d.ts +5 -1
  254. package/src/lib/server/pos-check-in.js +296 -28
  255. package/src/lib/server/pos-check-in.js.map +1 -1
  256. package/src/lib/server/pos-day-report.js +29 -3
  257. package/src/lib/server/pos-day-report.js.map +1 -1
  258. package/src/lib/server/pos-display.d.ts +16 -0
  259. package/src/lib/server/pos-display.js +129 -2
  260. package/src/lib/server/pos-display.js.map +1 -1
  261. package/src/lib/server/pos-hardware-admin.d.ts +10 -1
  262. package/src/lib/server/pos-hardware-admin.js +250 -84
  263. package/src/lib/server/pos-hardware-admin.js.map +1 -1
  264. package/src/lib/server/pos-hardware-attach.d.ts +105 -0
  265. package/src/lib/server/pos-hardware-attach.js +443 -0
  266. package/src/lib/server/pos-hardware-attach.js.map +1 -0
  267. package/src/lib/server/pos-hardware-buyer-lookup.d.ts +58 -0
  268. package/src/lib/server/pos-hardware-buyer-lookup.js +180 -0
  269. package/src/lib/server/pos-hardware-buyer-lookup.js.map +1 -0
  270. package/src/lib/server/pos-hardware-buyer-record.d.ts +29 -0
  271. package/src/lib/server/pos-hardware-buyer-record.js +86 -0
  272. package/src/lib/server/pos-hardware-buyer-record.js.map +1 -0
  273. package/src/lib/server/pos-hardware-cancel.d.ts +58 -0
  274. package/src/lib/server/pos-hardware-cancel.js +147 -0
  275. package/src/lib/server/pos-hardware-cancel.js.map +1 -0
  276. package/src/lib/server/pos-hardware-closure-notices.d.ts +27 -0
  277. package/src/lib/server/pos-hardware-closure-notices.js +85 -0
  278. package/src/lib/server/pos-hardware-closure-notices.js.map +1 -0
  279. package/src/lib/server/pos-hardware-closure.d.ts +60 -0
  280. package/src/lib/server/pos-hardware-closure.js +153 -0
  281. package/src/lib/server/pos-hardware-closure.js.map +1 -0
  282. package/src/lib/server/pos-hardware-in-person.d.ts +61 -0
  283. package/src/lib/server/pos-hardware-in-person.js +236 -0
  284. package/src/lib/server/pos-hardware-in-person.js.map +1 -0
  285. package/src/lib/server/pos-hardware-notify.d.ts +40 -2
  286. package/src/lib/server/pos-hardware-notify.js +195 -14
  287. package/src/lib/server/pos-hardware-notify.js.map +1 -1
  288. package/src/lib/server/pos-hardware-readers.d.ts +115 -0
  289. package/src/lib/server/pos-hardware-readers.js +430 -0
  290. package/src/lib/server/pos-hardware-readers.js.map +1 -0
  291. package/src/lib/server/pos-hardware-returns.d.ts +116 -0
  292. package/src/lib/server/pos-hardware-returns.js +502 -0
  293. package/src/lib/server/pos-hardware-returns.js.map +1 -0
  294. package/src/lib/server/pos-hardware-sale-fields.d.ts +28 -0
  295. package/src/lib/server/pos-hardware-sale-fields.js +44 -0
  296. package/src/lib/server/pos-hardware-sale-fields.js.map +1 -0
  297. package/src/lib/server/pos-hardware-sale.d.ts +54 -0
  298. package/src/lib/server/pos-hardware-sale.js +369 -0
  299. package/src/lib/server/pos-hardware-sale.js.map +1 -0
  300. package/src/lib/server/pos-hardware-tax-return-source.d.ts +99 -0
  301. package/src/lib/server/pos-hardware-tax-return-source.js +462 -0
  302. package/src/lib/server/pos-hardware-tax-return-source.js.map +1 -0
  303. package/src/lib/server/pos-hardware-terms.d.ts +64 -0
  304. package/src/lib/server/pos-hardware-terms.js +154 -0
  305. package/src/lib/server/pos-hardware-terms.js.map +1 -0
  306. package/src/lib/server/pos-hardware-user-eraser.d.ts +3 -0
  307. package/src/lib/server/pos-hardware-user-eraser.js +31 -7
  308. package/src/lib/server/pos-hardware-user-eraser.js.map +1 -1
  309. package/src/lib/server/pos-hardware-webhook.d.ts +5 -0
  310. package/src/lib/server/pos-hardware-webhook.js +51 -6
  311. package/src/lib/server/pos-hardware-webhook.js.map +1 -1
  312. package/src/lib/server/pos-hardware.d.ts +74 -1
  313. package/src/lib/server/pos-hardware.js +175 -10
  314. package/src/lib/server/pos-hardware.js.map +1 -1
  315. package/src/lib/server/pos-kiosk.d.ts +2 -0
  316. package/src/lib/server/pos-kiosk.js +17 -12
  317. package/src/lib/server/pos-kiosk.js.map +1 -1
  318. package/src/lib/server/pos-offline-card-order.d.ts +64 -0
  319. package/src/lib/server/pos-offline-card-order.js +102 -0
  320. package/src/lib/server/pos-offline-card-order.js.map +1 -0
  321. package/src/lib/server/pos-offline-card-reconcile.d.ts +67 -1
  322. package/src/lib/server/pos-offline-card-reconcile.js +215 -18
  323. package/src/lib/server/pos-offline-card-reconcile.js.map +1 -1
  324. package/src/lib/server/pos-offline-sync.d.ts +39 -0
  325. package/src/lib/server/pos-offline-sync.js +190 -55
  326. package/src/lib/server/pos-offline-sync.js.map +1 -1
  327. package/src/lib/server/pos-ops-gate.d.ts +28 -9
  328. package/src/lib/server/pos-ops-gate.js +50 -19
  329. package/src/lib/server/pos-ops-gate.js.map +1 -1
  330. package/src/lib/server/pos-ops-routes.js +24 -0
  331. package/src/lib/server/pos-ops-routes.js.map +1 -1
  332. package/src/lib/server/pos-order-refund-ids.d.ts +28 -0
  333. package/src/lib/server/pos-order-refund-ids.js +31 -0
  334. package/src/lib/server/pos-order-refund-ids.js.map +1 -0
  335. package/src/lib/server/pos-order.js +52 -49
  336. package/src/lib/server/pos-order.js.map +1 -1
  337. package/src/lib/server/pos-payment.js +1 -1
  338. package/src/lib/server/pos-payment.js.map +1 -1
  339. package/src/lib/server/pos-reader-splash-admin.js +30 -32
  340. package/src/lib/server/pos-reader-splash-admin.js.map +1 -1
  341. package/src/lib/server/pos-reader-splash-images-route.d.ts +17 -0
  342. package/src/lib/server/pos-reader-splash-images-route.js +113 -0
  343. package/src/lib/server/pos-reader-splash-images-route.js.map +1 -0
  344. package/src/lib/server/pos-reader-splash-images.d.ts +51 -0
  345. package/src/lib/server/pos-reader-splash-images.js +123 -0
  346. package/src/lib/server/pos-reader-splash-images.js.map +1 -0
  347. package/src/lib/server/pos-reader-splash.d.ts +68 -1
  348. package/src/lib/server/pos-reader-splash.js +182 -11
  349. package/src/lib/server/pos-reader-splash.js.map +1 -1
  350. package/src/lib/server/pos-readers.d.ts +29 -0
  351. package/src/lib/server/pos-readers.js +134 -35
  352. package/src/lib/server/pos-readers.js.map +1 -1
  353. package/src/lib/server/pos-refund-authority.d.ts +3 -1
  354. package/src/lib/server/pos-refund-authority.js +3 -2
  355. package/src/lib/server/pos-refund-authority.js.map +1 -1
  356. package/src/lib/server/pos-return.d.ts +10 -0
  357. package/src/lib/server/pos-return.js +29 -7
  358. package/src/lib/server/pos-return.js.map +1 -1
  359. package/src/lib/server/pos-sale.js +6 -1
  360. package/src/lib/server/pos-sale.js.map +1 -1
  361. package/src/lib/server/pos-shift.js +11 -0
  362. package/src/lib/server/pos-shift.js.map +1 -1
  363. package/src/lib/server/pos-staff-pin.js +29 -24
  364. package/src/lib/server/pos-staff-pin.js.map +1 -1
  365. package/src/lib/server/pos-terminal.d.ts +14 -4
  366. package/src/lib/server/pos-terminal.js +34 -38
  367. package/src/lib/server/pos-terminal.js.map +1 -1
  368. package/src/lib/server/printers.d.ts +7 -3
  369. package/src/lib/server/printers.js +18 -12
  370. package/src/lib/server/printers.js.map +1 -1
  371. package/src/lib/server/product-drafts.d.ts +11 -1
  372. package/src/lib/server/product-drafts.js +12 -8
  373. package/src/lib/server/product-drafts.js.map +1 -1
  374. package/src/lib/server/product.d.ts +15 -1
  375. package/src/lib/server/product.js +16 -3
  376. package/src/lib/server/product.js.map +1 -1
  377. package/src/lib/server/products-write.d.ts +26 -2
  378. package/src/lib/server/products-write.js +19 -7
  379. package/src/lib/server/products-write.js.map +1 -1
  380. package/src/lib/server/refund.js +55 -42
  381. package/src/lib/server/refund.js.map +1 -1
  382. package/src/lib/server/reservation-availability-query.d.ts +8 -0
  383. package/src/lib/server/reservation-availability-query.js +11 -1
  384. package/src/lib/server/reservation-availability-query.js.map +1 -1
  385. package/src/lib/server/reservation-availability.d.ts +1 -1
  386. package/src/lib/server/reservation-availability.js +7 -2
  387. package/src/lib/server/reservation-availability.js.map +1 -1
  388. package/src/lib/server/reservation-guests.d.ts +32 -0
  389. package/src/lib/server/reservation-guests.js +285 -0
  390. package/src/lib/server/reservation-guests.js.map +1 -0
  391. package/src/lib/server/reservation-walk-in.d.ts +11 -1
  392. package/src/lib/server/reservation-walk-in.js +56 -12
  393. package/src/lib/server/reservation-walk-in.js.map +1 -1
  394. package/src/lib/server/reserve.js +18 -5
  395. package/src/lib/server/reserve.js.map +1 -1
  396. package/src/lib/server/returns.js +9 -6
  397. package/src/lib/server/returns.js.map +1 -1
  398. package/src/lib/server/reviews.d.ts +22 -2
  399. package/src/lib/server/reviews.js +88 -20
  400. package/src/lib/server/reviews.js.map +1 -1
  401. package/src/lib/server/shipping-connectors.js +10 -11
  402. package/src/lib/server/shipping-connectors.js.map +1 -1
  403. package/src/lib/server/site-page-resolver.js +20 -3
  404. package/src/lib/server/site-page-resolver.js.map +1 -1
  405. package/src/lib/server/store-day.d.ts +33 -0
  406. package/src/lib/server/store-day.js +46 -0
  407. package/src/lib/server/store-day.js.map +1 -0
  408. package/src/lib/server/store-setup-ai-writer.d.ts +2 -1
  409. package/src/lib/server/store-setup-ai-writer.js +5 -6
  410. package/src/lib/server/store-setup-ai-writer.js.map +1 -1
  411. package/src/lib/server/storefront-tax.d.ts +13 -0
  412. package/src/lib/server/storefront-tax.js +8 -1
  413. package/src/lib/server/storefront-tax.js.map +1 -1
  414. package/src/lib/server/tax-return-source.d.ts +32 -3
  415. package/src/lib/server/tax-return-source.js +99 -20
  416. package/src/lib/server/tax-return-source.js.map +1 -1
  417. package/src/lib/server.js +100 -2
  418. package/src/lib/server.js.map +1 -1
  419. package/src/lib/testing/fake-firestore.js +58 -16
  420. package/src/lib/testing/fake-firestore.js.map +1 -1
  421. package/src/lib/testing/pos-ops-memory-firestore.js +18 -4
  422. package/src/lib/testing/pos-ops-memory-firestore.js.map +1 -1
  423. package/src/lib/testing/site-register-permissions.d.ts +29 -0
  424. package/src/lib/testing/site-register-permissions.js +38 -0
  425. package/src/lib/testing/site-register-permissions.js.map +1 -0
  426. package/src/lib/transfer/tracking.server.js +8 -5
  427. package/src/lib/transfer/tracking.server.js.map +1 -1
  428. package/src/lib/utils/add-to-cart.d.ts +2 -0
  429. package/src/lib/utils/add-to-cart.js +6 -3
  430. package/src/lib/utils/add-to-cart.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/order-webhooks-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 { pluginDocsHelp } from '@aglyn/aglyn'\nimport { CardDisplay, useConfirmationContext } from '@aglyn/shared-ui-jsx'\nimport { ListPagination } from '@aglyn/shared-ui-jsx/components/list-pagination.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport {\n useFirestore,\n useFirestoreCollection,\n usePagedCollection,\n useUser,\n} from '@aglyn/tenant-feature-instance'\nimport {\n Alert,\n Button,\n Checkbox,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControlLabel,\n FormGroup,\n MenuItem,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { collection, limit, orderBy, query, where } from 'firebase/firestore'\nimport { useCallback, useEffect, useState } from 'react'\nimport * as Webhooks from '../../model/order-webhooks'\n\nexport interface OrderWebhooksCardProps {\n hostId: string\n}\n\ninterface WebhookEventOption {\n event: string\n label: string\n description: string\n}\n\ninterface WebhooksStatus {\n configured: boolean\n maxEndpoints: number\n events: WebhookEventOption[]\n}\n\ntype EndpointRow = Webhooks.OrderWebhookEndpoint & { $id: string }\ntype DeliveryRow = Webhooks.OrderWebhookDelivery & { $id: string }\n\nconst ROUTE = '/api/commerce/order-webhooks'\n\n/** POSTs one action to the webhooks route; answers the body or throws its error. */\nexport async function callOrderWebhooks(\n user: Parameters<typeof authorizedFetch>[0],\n hostId: string,\n body: Record<string, unknown>,\n): Promise<Record<string, any>> {\n const response = await authorizedFetch(user, ROUTE, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ hostId, ...body }),\n })\n const payload = (await response.json().catch(() => ({}))) as Record<string, any>\n if (!response.ok) throw Object.assign(new Error(String(payload.error ?? 'Request failed')), { status: response.status })\n return payload\n}\n\n/**\n * Order webhooks (AGL-3611): the store's endpoints for order and return\n * events, each with its signing secret, a test event and a delivery log. Shown\n * only to the people who may manage them — the route answers who — and only\n * where the deployment can sign.\n */\nexport function OrderWebhooksCard(props: OrderWebhooksCardProps) {\n const { hostId } = props\n const firestore = useFirestore()\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n const { confirm } = useConfirmationContext()\n const [status, setStatus] = useState<WebhooksStatus | null>(null)\n const [editing, setEditing] = useState<EndpointRow | 'new' | null>(null)\n const [secret, setSecret] = useState<string | null>(null)\n const [logFor, setLogFor] = useState<EndpointRow | null>(null)\n const [busy, setBusy] = useState(false)\n\n useEffect(() => {\n if (!user) return\n let active = true\n callOrderWebhooks(user, hostId, { action: 'status' })\n .then((payload) => {\n if (active) setStatus(payload as WebhooksStatus)\n })\n .catch(() => {\n // Not an admin of the whole workspace, or the route is down: the\n // card is not this person's to use.\n if (active) setStatus(null)\n })\n return () => {\n active = false\n }\n }, [user, hostId])\n\n const { data: endpointDocs } = useFirestoreCollection<EndpointRow>(\n () =>\n query(\n collection(firestore, 'hosts', hostId, 'orderWebhooks'),\n orderBy('createdAtMs', 'desc'),\n limit(Webhooks.ORDER_WEBHOOK_MAX_ENDPOINTS),\n ),\n [firestore, hostId],\n { idField: '$id' },\n )\n const endpoints = endpointDocs ?? []\n\n const run = useCallback(\n async (body: Record<string, unknown>, success?: string) => {\n setBusy(true)\n try {\n const payload = await callOrderWebhooks(user, hostId, body)\n if (success) enqueueSnackbar(success, { variant: 'success' })\n return payload\n } catch (error) {\n enqueueSnackbar(String((error as Error).message), { variant: 'error' })\n return null\n } finally {\n setBusy(false)\n }\n },\n [user, hostId, enqueueSnackbar],\n )\n\n const handleTest = useCallback(\n async (endpoint: EndpointRow) => {\n const payload = await run({ action: 'test', endpointId: endpoint.$id })\n if (!payload) return\n enqueueSnackbar(\n payload.delivered ? 'Test event delivered' : `Test event not delivered: ${payload.attempt?.error ?? 'no answer'}`,\n { variant: payload.delivered ? 'success' : 'warning' },\n )\n },\n [run, enqueueSnackbar],\n )\n\n const handleRoll = useCallback(\n async (endpoint: EndpointRow) => {\n const confirmed = await confirm({\n title: 'Roll the signing secret?',\n description:\n 'A new secret signs every event from now on. Update your endpoint before ' +\n 'the next order, or it will reject what it is sent.',\n confirmationText: 'Roll secret',\n })\n .then(() => true)\n .catch(() => false)\n if (!confirmed) return\n const payload = await run({ action: 'roll-secret', endpointId: endpoint.$id })\n if (payload?.secret) setSecret(String(payload.secret))\n },\n [confirm, run],\n )\n\n const handleDelete = useCallback(\n async (endpoint: EndpointRow) => {\n const confirmed = await confirm({\n title: 'Delete this endpoint?',\n description: `${endpoint.url} stops receiving order events. Its delivery log is kept for 30 days.`,\n confirmationText: 'Delete',\n confirmationButtonProps: { color: 'error' },\n })\n .then(() => true)\n .catch(() => false)\n if (!confirmed) return\n await run({ action: 'delete', endpointId: endpoint.$id }, 'Endpoint deleted')\n },\n [confirm, run],\n )\n\n if (!status?.configured) return null\n const labelFor = (event: string) => status.events.find((entry) => entry.event === event)?.label ?? event\n const atMax = endpoints.length >= status.maxEndpoints\n\n return (\n <CardDisplay\n header={'Order webhooks'}\n help={pluginDocsHelp('ordersAndReturns', { anchor: '#order-webhooks' })}\n contentGutterX\n contentGutterY\n HeaderProps={{\n action: (\n <Button size=\"small\" disabled={atMax || busy} onClick={() => setEditing('new')}>\n {'Add endpoint'}\n </Button>\n ),\n }}\n >\n <Stack spacing={2}>\n {endpoints.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Send order and return events to your own systems — a warehouse, an ERP or a ' +\n 'script. Each event is signed so your endpoint can check it came from this store.'}\n </Typography>\n ) : (\n endpoints.map((endpoint) => (\n <Stack key={endpoint.$id} spacing={1} data-testid=\"order-webhook-endpoint\">\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center', flexWrap: 'wrap' }}>\n <Typography variant=\"subtitle2\" sx={{ flex: 1, minWidth: 0, wordBreak: 'break-all' }}>\n {endpoint.description ? `${endpoint.description} · ${endpoint.url}` : endpoint.url}\n </Typography>\n <Chip\n size=\"small\"\n label={endpoint.enabled ? 'On' : 'Paused'}\n color={endpoint.enabled ? 'success' : 'default'}\n variant=\"outlined\"\n />\n {endpoint.lastDeliveryStatus ? (\n <Chip\n size=\"small\"\n label={`Last: ${Webhooks.ORDER_WEBHOOK_DELIVERY_STATUS_LABELS[endpoint.lastDeliveryStatus]}`}\n color={Webhooks.ORDER_WEBHOOK_DELIVERY_STATUS_COLOR[endpoint.lastDeliveryStatus]}\n variant=\"outlined\"\n />\n ) : null}\n </Stack>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`${endpoint.events.map(labelFor).join(', ')} · secret ends ${endpoint.secretHint}`}\n </Typography>\n <Stack direction=\"row\" spacing={1} sx={{ flexWrap: 'wrap' }}>\n <Button size=\"small\" disabled={busy || !endpoint.enabled} onClick={() => handleTest(endpoint)}>\n {'Send test event'}\n </Button>\n <Button size=\"small\" onClick={() => setLogFor(endpoint)}>\n {'Deliveries'}\n </Button>\n <Button size=\"small\" disabled={busy} onClick={() => setEditing(endpoint)}>\n {'Edit'}\n </Button>\n <Button\n size=\"small\"\n disabled={busy}\n onClick={() => run({ action: 'update', endpointId: endpoint.$id, enabled: !endpoint.enabled })}\n >\n {endpoint.enabled ? 'Pause' : 'Resume'}\n </Button>\n <Button size=\"small\" disabled={busy} onClick={() => handleRoll(endpoint)}>\n {'Roll secret'}\n </Button>\n <Button size=\"small\" color=\"error\" disabled={busy} onClick={() => handleDelete(endpoint)}>\n {'Delete'}\n </Button>\n </Stack>\n </Stack>\n ))\n )}\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`${endpoints.length}/${status.maxEndpoints} endpoints. A failed delivery is retried for about a day.`}\n </Typography>\n </Stack>\n {editing ? (\n <EndpointDialog\n endpoint={editing === 'new' ? null : editing}\n events={status.events}\n busy={busy}\n onClose={() => setEditing(null)}\n onSave={async (values) => {\n const payload =\n editing === 'new'\n ? await run({ action: 'create', ...values })\n : await run({ action: 'update', endpointId: editing.$id, ...values }, 'Endpoint saved')\n if (!payload) return\n setEditing(null)\n if (payload.secret) setSecret(String(payload.secret))\n }}\n />\n ) : null}\n {secret ? <SecretDialog secret={secret} onClose={() => setSecret(null)} /> : null}\n {logFor ? (\n <DeliveriesDialog\n hostId={hostId}\n endpoint={logFor}\n labelFor={labelFor}\n busy={busy}\n onResend={async (delivery) => {\n const payload = await run({ action: 'resend', deliveryId: delivery.$id })\n if (payload) {\n enqueueSnackbar(payload.delivered ? 'Delivered' : `Not delivered: ${payload.attempt?.error ?? 'no answer'}`, {\n variant: payload.delivered ? 'success' : 'warning',\n })\n }\n }}\n onClose={() => setLogFor(null)}\n />\n ) : null}\n </CardDisplay>\n )\n}\nOrderWebhooksCard.displayName = 'OrderWebhooksCard'\n\ninterface EndpointDialogProps {\n endpoint: EndpointRow | null\n events: WebhookEventOption[]\n busy: boolean\n onClose: () => void\n onSave: (values: { url: string; description: string; events: string[] }) => void | Promise<void>\n}\n\nfunction EndpointDialog(props: EndpointDialogProps) {\n const { endpoint, events, busy, onClose, onSave } = props\n const [url, setUrl] = useState(endpoint?.url ?? '')\n const [description, setDescription] = useState(endpoint?.description ?? '')\n const [chosen, setChosen] = useState<string[]>(endpoint?.events ?? events.map((entry) => entry.event))\n const toggle = (event: string) =>\n setChosen((current) => (current.includes(event) ? current.filter((entry) => entry !== event) : [...current, event]))\n const valid = /^https:\\/\\//i.test(url.trim()) && chosen.length > 0\n return (\n <Dialog open onClose={onClose} fullWidth maxWidth=\"sm\">\n <DialogTitle>{endpoint ? 'Edit endpoint' : 'Add endpoint'}</DialogTitle>\n <DialogContent>\n <Stack spacing={2} sx={{ pt: 1 }}>\n <TextField\n label=\"Endpoint URL\"\n value={url}\n onChange={(event) => setUrl(event.target.value)}\n placeholder=\"https://example.com/aglyn-webhooks\"\n helperText=\"An https address on a public server. Redirects are not followed.\"\n fullWidth\n autoFocus\n />\n <TextField\n label=\"Description\"\n value={description}\n onChange={(event) => setDescription(event.target.value)}\n placeholder=\"Warehouse\"\n fullWidth\n />\n <FormGroup>\n <Typography variant=\"subtitle2\">{'Events'}</Typography>\n {events.map((entry) => (\n <FormControlLabel\n key={entry.event}\n control={<Checkbox checked={chosen.includes(entry.event)} onChange={() => toggle(entry.event)} />}\n label={\n <Stack>\n <Typography variant=\"body2\">{`${entry.label} (${entry.event})`}</Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {entry.description}\n </Typography>\n </Stack>\n }\n />\n ))}\n </FormGroup>\n </Stack>\n </DialogContent>\n <DialogActions>\n <Button onClick={onClose}>{'Cancel'}</Button>\n <Button\n variant=\"contained\"\n disabled={!valid || busy}\n onClick={() => onSave({ url: url.trim(), description: description.trim(), events: chosen })}\n >\n {endpoint ? 'Save' : 'Add endpoint'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\nfunction SecretDialog(props: { secret: string; onClose: () => void }) {\n const { secret, onClose } = props\n const { enqueueSnackbar } = useSnackbar()\n return (\n <Dialog open onClose={onClose} fullWidth maxWidth=\"sm\">\n <DialogTitle>{'Signing secret'}</DialogTitle>\n <DialogContent>\n <Stack spacing={2}>\n <Alert severity=\"warning\">{'Copy it now. It is not shown again; roll a new one if it is lost.'}</Alert>\n <TextField value={secret} fullWidth slotProps={{ input: { readOnly: true } }} label=\"Secret\" />\n <Typography variant=\"body2\" color=\"text.secondary\">\n {`Each request carries an ${Webhooks.ORDER_WEBHOOK_SIGNATURE_HEADER} header, t=<timestamp>,v1=<signature>. ` +\n 'The signature is the HMAC-SHA256, in hex, of the timestamp, a period and the raw body, ' +\n `keyed with this secret. ${Webhooks.ORDER_WEBHOOK_EVENT_ID_HEADER} is the same on every retry.`}\n </Typography>\n </Stack>\n </DialogContent>\n <DialogActions>\n <Button\n onClick={() => {\n void navigator.clipboard\n ?.writeText(secret)\n .then(() => enqueueSnackbar('Secret copied', { variant: 'success' }))\n }}\n >\n {'Copy'}\n </Button>\n <Button variant=\"contained\" onClick={onClose}>\n {'Done'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\ninterface DeliveriesDialogProps {\n hostId: string\n endpoint: EndpointRow\n labelFor: (event: string) => string\n busy: boolean\n onResend: (delivery: DeliveryRow) => void | Promise<void>\n onClose: () => void\n}\n\n/** The endpoint's delivery log, newest first, filtered and paged by a Firestore query. */\nexport function DeliveriesDialog(props: DeliveriesDialogProps) {\n const { hostId, endpoint, labelFor, busy, onResend, onClose } = props\n const firestore = useFirestore()\n const [statusFilter, setStatusFilter] = useState<Webhooks.OrderWebhookDeliveryStatus | ''>('')\n const [openBody, setOpenBody] = useState<string | null>(null)\n const {\n rows: deliveries,\n hasMore,\n page,\n setPage,\n pageSize,\n setPageSize,\n } = usePagedCollection<DeliveryRow>(\n (pageLimit) =>\n query(\n collection(firestore, 'hosts', hostId, 'orderWebhookDeliveries'),\n where('endpointId', '==', endpoint.$id),\n ...(statusFilter ? [where('status', '==', statusFilter)] : []),\n orderBy('createdAtMs', 'desc'),\n limit(pageLimit),\n ),\n [firestore, hostId, endpoint.$id, statusFilter],\n { idField: '$id' },\n )\n return (\n <Dialog open onClose={onClose} fullWidth maxWidth=\"md\">\n <DialogTitle>{`Deliveries · ${endpoint.url}`}</DialogTitle>\n <DialogContent>\n <Stack spacing={2} sx={{ pt: 1 }}>\n <TextField\n select\n size=\"small\"\n label=\"Status\"\n value={statusFilter}\n onChange={(event) => setStatusFilter(event.target.value as Webhooks.OrderWebhookDeliveryStatus | '')}\n sx={{ maxWidth: 200 }}\n >\n <MenuItem value=\"\">{'All'}</MenuItem>\n {(Object.keys(Webhooks.ORDER_WEBHOOK_DELIVERY_STATUS_LABELS) as Webhooks.OrderWebhookDeliveryStatus[]).map((key) => (\n <MenuItem key={key} value={key}>\n {Webhooks.ORDER_WEBHOOK_DELIVERY_STATUS_LABELS[key]}\n </MenuItem>\n ))}\n </TextField>\n {deliveries.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'No deliveries in the last 30 days.'}\n </Typography>\n ) : (\n deliveries.map((delivery) => {\n const last = delivery.attempts?.[delivery.attempts.length - 1]\n return (\n <Stack key={delivery.$id} spacing={0.5} data-testid=\"order-webhook-delivery\">\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center', flexWrap: 'wrap' }}>\n <Typography variant=\"body2\" sx={{ flex: 1 }}>\n {`${delivery.test ? 'Test event' : labelFor(delivery.event)} · ${new Date(delivery.createdAtMs).toLocaleString()}`}\n </Typography>\n <Chip\n size=\"small\"\n variant=\"outlined\"\n label={Webhooks.ORDER_WEBHOOK_DELIVERY_STATUS_LABELS[delivery.status]}\n color={Webhooks.ORDER_WEBHOOK_DELIVERY_STATUS_COLOR[delivery.status]}\n />\n <Button size=\"small\" onClick={() => setOpenBody(openBody === delivery.$id ? null : delivery.$id)}>\n {openBody === delivery.$id ? 'Hide body' : 'Body'}\n </Button>\n <Button size=\"small\" disabled={busy} onClick={() => onResend(delivery)}>\n {'Resend'}\n </Button>\n </Stack>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`${delivery.attempts?.length ?? 0} attempt${delivery.attempts?.length === 1 ? '' : 's'}` +\n (last ? ` · last ${last.httpStatus ?? 'no answer'}${last.error ? ` — ${last.error}` : ''}` : '')}\n </Typography>\n {openBody === delivery.$id ? (\n <TextField\n value={delivery.body}\n multiline\n maxRows={12}\n fullWidth\n slotProps={{ input: { readOnly: true } }}\n />\n ) : null}\n </Stack>\n )\n })\n )}\n <ListPagination\n page={page}\n pageSize={pageSize}\n rowCount={deliveries.length}\n hasMore={hasMore}\n onPageChange={setPage}\n onPageSizeChange={setPageSize}\n />\n </Stack>\n </DialogContent>\n <DialogActions>\n <Button onClick={onClose}>{'Close'}</Button>\n </DialogActions>\n </Dialog>\n )\n}\n\nexport default OrderWebhooksCard\n"],"names":["pluginDocsHelp","CardDisplay","useConfirmationContext","ListPagination","useSnackbar","authorizedFetch","useFirestore","useFirestoreCollection","usePagedCollection","useUser","Alert","Button","Checkbox","Chip","Dialog","DialogActions","DialogContent","DialogTitle","FormControlLabel","FormGroup","MenuItem","Stack","TextField","Typography","collection","limit","orderBy","query","where","useCallback","useEffect","useState","Webhooks","ROUTE","callOrderWebhooks","user","hostId","body","payload","response","method","headers","JSON","stringify","json","catch","ok","Object","assign","Error","String","error","status","OrderWebhooksCard","props","firestore","data","enqueueSnackbar","confirm","setStatus","editing","setEditing","secret","setSecret","logFor","setLogFor","busy","setBusy","active","action","then","endpointDocs","ORDER_WEBHOOK_MAX_ENDPOINTS","idField","endpoints","run","success","variant","message","handleTest","endpoint","endpointId","$id","delivered","attempt","handleRoll","confirmed","title","description","confirmationText","handleDelete","url","confirmationButtonProps","color","configured","labelFor","event","events","find","entry","label","atMax","length","maxEndpoints","header","help","anchor","contentGutterX","contentGutterY","HeaderProps","size","disabled","onClick","spacing","map","data-testid","direction","sx","alignItems","flexWrap","flex","minWidth","wordBreak","enabled","lastDeliveryStatus","ORDER_WEBHOOK_DELIVERY_STATUS_LABELS","ORDER_WEBHOOK_DELIVERY_STATUS_COLOR","join","secretHint","EndpointDialog","onClose","onSave","values","SecretDialog","DeliveriesDialog","onResend","delivery","deliveryId","displayName","setUrl","setDescription","chosen","setChosen","toggle","current","includes","filter","valid","test","trim","open","fullWidth","maxWidth","pt","value","onChange","target","placeholder","helperText","autoFocus","control","checked","severity","slotProps","input","readOnly","ORDER_WEBHOOK_SIGNATURE_HEADER","ORDER_WEBHOOK_EVENT_ID_HEADER","navigator","clipboard","writeText","statusFilter","setStatusFilter","openBody","setOpenBody","rows","deliveries","hasMore","page","setPage","pageSize","setPageSize","pageLimit","select","keys","key","last","attempts","Date","createdAtMs","toLocaleString","httpStatus","multiline","maxRows","rowCount","onPageChange","onPageSizeChange"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;AAEA,SAASA,cAAc,QAAQ,eAAc;AAC7C,SAASC,WAAW,EAAEC,sBAAsB,QAAQ,uBAAsB;AAC1E,SAASC,cAAc,QAAQ,4DAA2D;AAC1F,SAASC,WAAW,QAAQ,8BAA6B;AACzD,SAASC,eAAe,QAAQ,2CAA0C;AAC1E,SACEC,YAAY,EACZC,sBAAsB,EACtBC,kBAAkB,EAClBC,OAAO,QACF,iCAAgC;AACvC,SACEC,KAAK,EACLC,MAAM,EACNC,QAAQ,EACRC,IAAI,EACJC,MAAM,EACNC,aAAa,EACbC,aAAa,EACbC,WAAW,EACXC,gBAAgB,EAChBC,SAAS,EACTC,QAAQ,EACRC,KAAK,EACLC,SAAS,EACTC,UAAU,QACL,gBAAe;AACtB,SAASC,UAAU,EAAEC,KAAK,EAAEC,OAAO,EAAEC,KAAK,EAAEC,KAAK,QAAQ,qBAAoB;AAC7E,SAASC,WAAW,EAAEC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AACxD,YAAYC,cAAc,gCAA4B;AAqBtD,MAAMC,QAAQ;AAEd,kFAAkF,GAClF,OAAO,eAAeC,kBACpBC,IAA2C,EAC3CC,MAAc,EACdC,IAA6B;QAQ0BC;IANvD,MAAMC,WAAW,MAAMlC,gBAAgB8B,MAAMF,OAAO;QAClDO,QAAQ;QACRC,SAAS;YAAE,gBAAgB;QAAmB;QAC9CJ,MAAMK,KAAKC,SAAS,CAAC;YAAEP;WAAWC;IACpC;IACA,MAAMC,UAAW,MAAMC,SAASK,IAAI,GAAGC,KAAK,CAAC,IAAO,CAAA,CAAC,CAAA;IACrD,IAAI,CAACN,SAASO,EAAE,EAAE,MAAMC,OAAOC,MAAM,CAAC,IAAIC,MAAMC,QAAOZ,iBAAAA,QAAQa,KAAK,YAAbb,iBAAiB,oBAAoB;QAAEc,QAAQb,SAASa,MAAM;IAAC;IACtH,OAAOd;AACT;AAEA;;;;;CAKC,GACD,OAAO,SAASe,kBAAkBC,KAA6B;IAC7D,MAAM,EAAElB,MAAM,EAAE,GAAGkB;IACnB,MAAMC,YAAYjD;IAClB,MAAM,EAAEkD,MAAMrB,IAAI,EAAE,GAAG1B;IACvB,MAAM,EAAEgD,eAAe,EAAE,GAAGrD;IAC5B,MAAM,EAAEsD,OAAO,EAAE,GAAGxD;IACpB,MAAM,CAACkD,QAAQO,UAAU,GAAG5B,SAAgC;IAC5D,MAAM,CAAC6B,SAASC,WAAW,GAAG9B,SAAqC;IACnE,MAAM,CAAC+B,QAAQC,UAAU,GAAGhC,SAAwB;IACpD,MAAM,CAACiC,QAAQC,UAAU,GAAGlC,SAA6B;IACzD,MAAM,CAACmC,MAAMC,QAAQ,GAAGpC,SAAS;IAEjCD,UAAU;QACR,IAAI,CAACK,MAAM;QACX,IAAIiC,SAAS;QACblC,kBAAkBC,MAAMC,QAAQ;YAAEiC,QAAQ;QAAS,GAChDC,IAAI,CAAC,CAAChC;YACL,IAAI8B,QAAQT,UAAUrB;QACxB,GACCO,KAAK,CAAC;YACL,iEAAiE;YACjE,oCAAoC;YACpC,IAAIuB,QAAQT,UAAU;QACxB;QACF,OAAO;YACLS,SAAS;QACX;IACF,GAAG;QAACjC;QAAMC;KAAO;IAEjB,MAAM,EAAEoB,MAAMe,YAAY,EAAE,GAAGhE,uBAC7B,IACEoB,MACEH,WAAW+B,WAAW,SAASnB,QAAQ,kBACvCV,QAAQ,eAAe,SACvBD,MAAMO,SAASwC,2BAA2B,IAE9C;QAACjB;QAAWnB;KAAO,EACnB;QAAEqC,SAAS;IAAM;IAEnB,MAAMC,YAAYH,uBAAAA,eAAgB,EAAE;IAEpC,MAAMI,MAAM9C,YACV,OAAOQ,MAA+BuC;QACpCT,QAAQ;QACR,IAAI;YACF,MAAM7B,UAAU,MAAMJ,kBAAkBC,MAAMC,QAAQC;YACtD,IAAIuC,SAASnB,gBAAgBmB,SAAS;gBAAEC,SAAS;YAAU;YAC3D,OAAOvC;QACT,EAAE,OAAOa,OAAO;YACdM,gBAAgBP,OAAO,AAACC,MAAgB2B,OAAO,GAAG;gBAAED,SAAS;YAAQ;YACrE,OAAO;QACT,SAAU;YACRV,QAAQ;QACV;IACF,GACA;QAAChC;QAAMC;QAAQqB;KAAgB;IAGjC,MAAMsB,aAAalD,YACjB,OAAOmD;;YAIuE1C;QAH5E,MAAMA,UAAU,MAAMqC,IAAI;YAAEN,QAAQ;YAAQY,YAAYD,SAASE,GAAG;QAAC;QACrE,IAAI,CAAC5C,SAAS;QACdmB,gBACEnB,QAAQ6C,SAAS,GAAG,yBAAyB,CAAC,0BAA0B,WAAE7C,mBAAAA,QAAQ8C,OAAO,qBAAf9C,iBAAiBa,KAAK,mBAAI,aAAa,EACjH;YAAE0B,SAASvC,QAAQ6C,SAAS,GAAG,YAAY;QAAU;IAEzD,GACA;QAACR;QAAKlB;KAAgB;IAGxB,MAAM4B,aAAaxD,YACjB,OAAOmD;QACL,MAAMM,YAAY,MAAM5B,QAAQ;YAC9B6B,OAAO;YACPC,aACE,6EACA;YACFC,kBAAkB;QACpB,GACGnB,IAAI,CAAC,IAAM,MACXzB,KAAK,CAAC,IAAM;QACf,IAAI,CAACyC,WAAW;QAChB,MAAMhD,UAAU,MAAMqC,IAAI;YAAEN,QAAQ;YAAeY,YAAYD,SAASE,GAAG;QAAC;QAC5E,IAAI5C,2BAAAA,QAASwB,MAAM,EAAEC,UAAUb,OAAOZ,QAAQwB,MAAM;IACtD,GACA;QAACJ;QAASiB;KAAI;IAGhB,MAAMe,eAAe7D,YACnB,OAAOmD;QACL,MAAMM,YAAY,MAAM5B,QAAQ;YAC9B6B,OAAO;YACPC,aAAa,GAAGR,SAASW,GAAG,CAAC,oEAAoE,CAAC;YAClGF,kBAAkB;YAClBG,yBAAyB;gBAAEC,OAAO;YAAQ;QAC5C,GACGvB,IAAI,CAAC,IAAM,MACXzB,KAAK,CAAC,IAAM;QACf,IAAI,CAACyC,WAAW;QAChB,MAAMX,IAAI;YAAEN,QAAQ;YAAUY,YAAYD,SAASE,GAAG;QAAC,GAAG;IAC5D,GACA;QAACxB;QAASiB;KAAI;IAGhB,IAAI,EAACvB,0BAAAA,OAAQ0C,UAAU,GAAE,OAAO;IAChC,MAAMC,WAAW,CAACC;;YAAkB5C;wBAAAA,sBAAAA,OAAO6C,MAAM,CAACC,IAAI,CAAC,CAACC,QAAUA,MAAMH,KAAK,KAAKA,2BAA9C5C,oBAAsDgD,KAAK,mBAAIJ;;IACnG,MAAMK,QAAQ3B,UAAU4B,MAAM,IAAIlD,OAAOmD,YAAY;IAErD,qBACE,MAACtG;QACCuG,QAAQ;QACRC,MAAMzG,eAAe,oBAAoB;YAAE0G,QAAQ;QAAkB;QACrEC,cAAc;QACdC,cAAc;QACdC,aAAa;YACXxC,sBACE,KAAC1D;gBAAOmG,MAAK;gBAAQC,UAAUV,SAASnC;gBAAM8C,SAAS,IAAMnD,WAAW;0BACrE;;QAGP;;0BAEA,MAACxC;gBAAM4F,SAAS;;oBACbvC,UAAU4B,MAAM,KAAK,kBACpB,KAAC/E;wBAAWsD,SAAQ;wBAAQgB,OAAM;kCAC/B,iFACC;yBAGJnB,UAAUwC,GAAG,CAAC,CAAClC,yBACb,MAAC3D;4BAAyB4F,SAAS;4BAAGE,eAAY;;8CAChD,MAAC9F;oCAAM+F,WAAU;oCAAMH,SAAS;oCAAGI,IAAI;wCAAEC,YAAY;wCAAUC,UAAU;oCAAO;;sDAC9E,KAAChG;4CAAWsD,SAAQ;4CAAYwC,IAAI;gDAAEG,MAAM;gDAAGC,UAAU;gDAAGC,WAAW;4CAAY;sDAChF1C,SAASQ,WAAW,GAAG,GAAGR,SAASQ,WAAW,CAAC,GAAG,EAAER,SAASW,GAAG,EAAE,GAAGX,SAASW,GAAG;;sDAEpF,KAAC9E;4CACCiG,MAAK;4CACLV,OAAOpB,SAAS2C,OAAO,GAAG,OAAO;4CACjC9B,OAAOb,SAAS2C,OAAO,GAAG,YAAY;4CACtC9C,SAAQ;;wCAETG,SAAS4C,kBAAkB,iBAC1B,KAAC/G;4CACCiG,MAAK;4CACLV,OAAO,CAAC,MAAM,EAAEpE,SAAS6F,oCAAoC,CAAC7C,SAAS4C,kBAAkB,CAAC,EAAE;4CAC5F/B,OAAO7D,SAAS8F,mCAAmC,CAAC9C,SAAS4C,kBAAkB,CAAC;4CAChF/C,SAAQ;6CAER;;;8CAEN,KAACtD;oCAAWsD,SAAQ;oCAAUgB,OAAM;8CACjC,GAAGb,SAASiB,MAAM,CAACiB,GAAG,CAACnB,UAAUgC,IAAI,CAAC,MAAM,eAAe,EAAE/C,SAASgD,UAAU,EAAE;;8CAErF,MAAC3G;oCAAM+F,WAAU;oCAAMH,SAAS;oCAAGI,IAAI;wCAAEE,UAAU;oCAAO;;sDACxD,KAAC5G;4CAAOmG,MAAK;4CAAQC,UAAU7C,QAAQ,CAACc,SAAS2C,OAAO;4CAAEX,SAAS,IAAMjC,WAAWC;sDACjF;;sDAEH,KAACrE;4CAAOmG,MAAK;4CAAQE,SAAS,IAAM/C,UAAUe;sDAC3C;;sDAEH,KAACrE;4CAAOmG,MAAK;4CAAQC,UAAU7C;4CAAM8C,SAAS,IAAMnD,WAAWmB;sDAC5D;;sDAEH,KAACrE;4CACCmG,MAAK;4CACLC,UAAU7C;4CACV8C,SAAS,IAAMrC,IAAI;oDAAEN,QAAQ;oDAAUY,YAAYD,SAASE,GAAG;oDAAEyC,SAAS,CAAC3C,SAAS2C,OAAO;gDAAC;sDAE3F3C,SAAS2C,OAAO,GAAG,UAAU;;sDAEhC,KAAChH;4CAAOmG,MAAK;4CAAQC,UAAU7C;4CAAM8C,SAAS,IAAM3B,WAAWL;sDAC5D;;sDAEH,KAACrE;4CAAOmG,MAAK;4CAAQjB,OAAM;4CAAQkB,UAAU7C;4CAAM8C,SAAS,IAAMtB,aAAaV;sDAC5E;;;;;2BA5CKA,SAASE,GAAG;kCAkD5B,KAAC3D;wBAAWsD,SAAQ;wBAAUgB,OAAM;kCACjC,GAAGnB,UAAU4B,MAAM,CAAC,CAAC,EAAElD,OAAOmD,YAAY,CAAC,yDAAyD,CAAC;;;;YAGzG3C,wBACC,KAACqE;gBACCjD,UAAUpB,YAAY,QAAQ,OAAOA;gBACrCqC,QAAQ7C,OAAO6C,MAAM;gBACrB/B,MAAMA;gBACNgE,SAAS,IAAMrE,WAAW;gBAC1BsE,QAAQ,OAAOC;oBACb,MAAM9F,UACJsB,YAAY,QACR,MAAMe,IAAI;wBAAEN,QAAQ;uBAAa+D,WACjC,MAAMzD,IAAI;wBAAEN,QAAQ;wBAAUY,YAAYrB,QAAQsB,GAAG;uBAAKkD,SAAU;oBAC1E,IAAI,CAAC9F,SAAS;oBACduB,WAAW;oBACX,IAAIvB,QAAQwB,MAAM,EAAEC,UAAUb,OAAOZ,QAAQwB,MAAM;gBACrD;iBAEA;YACHA,uBAAS,KAACuE;gBAAavE,QAAQA;gBAAQoE,SAAS,IAAMnE,UAAU;iBAAY;YAC5EC,uBACC,KAACsE;gBACClG,QAAQA;gBACR4C,UAAUhB;gBACV+B,UAAUA;gBACV7B,MAAMA;gBACNqE,UAAU,OAAOC;oBACf,MAAMlG,UAAU,MAAMqC,IAAI;wBAAEN,QAAQ;wBAAUoE,YAAYD,SAAStD,GAAG;oBAAC;oBACvE,IAAI5C,SAAS;;4BACyDA;wBAApEmB,gBAAgBnB,QAAQ6C,SAAS,GAAG,cAAc,CAAC,eAAe,WAAE7C,mBAAAA,QAAQ8C,OAAO,qBAAf9C,iBAAiBa,KAAK,mBAAI,aAAa,EAAE;4BAC3G0B,SAASvC,QAAQ6C,SAAS,GAAG,YAAY;wBAC3C;oBACF;gBACF;gBACA+C,SAAS,IAAMjE,UAAU;iBAEzB;;;AAGV;AACAZ,kBAAkBqF,WAAW,GAAG;AAUhC,SAAST,eAAe3E,KAA0B;;IAChD,MAAM,EAAE0B,QAAQ,EAAEiB,MAAM,EAAE/B,IAAI,EAAEgE,OAAO,EAAEC,MAAM,EAAE,GAAG7E;IACpD,MAAM,CAACqC,KAAKgD,OAAO,GAAG5G,iBAASiD,4BAAAA,SAAUW,GAAG,mBAAI;IAChD,MAAM,CAACH,aAAaoD,eAAe,GAAG7G,kBAASiD,4BAAAA,SAAUQ,WAAW,oBAAI;IACxE,MAAM,CAACqD,QAAQC,UAAU,GAAG/G,kBAAmBiD,4BAAAA,SAAUiB,MAAM,oBAAIA,OAAOiB,GAAG,CAAC,CAACf,QAAUA,MAAMH,KAAK;IACpG,MAAM+C,SAAS,CAAC/C,QACd8C,UAAU,CAACE,UAAaA,QAAQC,QAAQ,CAACjD,SAASgD,QAAQE,MAAM,CAAC,CAAC/C,QAAUA,UAAUH,SAAS;mBAAIgD;gBAAShD;aAAM;IACpH,MAAMmD,QAAQ,eAAeC,IAAI,CAACzD,IAAI0D,IAAI,OAAOR,OAAOvC,MAAM,GAAG;IACjE,qBACE,MAACxF;QAAOwI,IAAI;QAACpB,SAASA;QAASqB,SAAS;QAACC,UAAS;;0BAChD,KAACvI;0BAAa+D,WAAW,kBAAkB;;0BAC3C,KAAChE;0BACC,cAAA,MAACK;oBAAM4F,SAAS;oBAAGI,IAAI;wBAAEoC,IAAI;oBAAE;;sCAC7B,KAACnI;4BACC8E,OAAM;4BACNsD,OAAO/D;4BACPgE,UAAU,CAAC3D,QAAU2C,OAAO3C,MAAM4D,MAAM,CAACF,KAAK;4BAC9CG,aAAY;4BACZC,YAAW;4BACXP,SAAS;4BACTQ,SAAS;;sCAEX,KAACzI;4BACC8E,OAAM;4BACNsD,OAAOlE;4BACPmE,UAAU,CAAC3D,QAAU4C,eAAe5C,MAAM4D,MAAM,CAACF,KAAK;4BACtDG,aAAY;4BACZN,SAAS;;sCAEX,MAACpI;;8CACC,KAACI;oCAAWsD,SAAQ;8CAAa;;gCAChCoB,OAAOiB,GAAG,CAAC,CAACf,sBACX,KAACjF;wCAEC8I,uBAAS,KAACpJ;4CAASqJ,SAASpB,OAAOI,QAAQ,CAAC9C,MAAMH,KAAK;4CAAG2D,UAAU,IAAMZ,OAAO5C,MAAMH,KAAK;;wCAC5FI,qBACE,MAAC/E;;8DACC,KAACE;oDAAWsD,SAAQ;8DAAS,GAAGsB,MAAMC,KAAK,CAAC,EAAE,EAAED,MAAMH,KAAK,CAAC,CAAC,CAAC;;8DAC9D,KAACzE;oDAAWsD,SAAQ;oDAAUgB,OAAM;8DACjCM,MAAMX,WAAW;;;;uCANnBW,MAAMH,KAAK;;;;;;0BAe1B,MAACjF;;kCACC,KAACJ;wBAAOqG,SAASkB;kCAAU;;kCAC3B,KAACvH;wBACCkE,SAAQ;wBACRkC,UAAU,CAACoC,SAASjF;wBACpB8C,SAAS,IAAMmB,OAAO;gCAAExC,KAAKA,IAAI0D,IAAI;gCAAI7D,aAAaA,YAAY6D,IAAI;gCAAIpD,QAAQ4C;4BAAO;kCAExF7D,WAAW,SAAS;;;;;;AAK/B;AAEA,SAASqD,aAAa/E,KAA8C;IAClE,MAAM,EAAEQ,MAAM,EAAEoE,OAAO,EAAE,GAAG5E;IAC5B,MAAM,EAAEG,eAAe,EAAE,GAAGrD;IAC5B,qBACE,MAACU;QAAOwI,IAAI;QAACpB,SAASA;QAASqB,SAAS;QAACC,UAAS;;0BAChD,KAACvI;0BAAa;;0BACd,KAACD;0BACC,cAAA,MAACK;oBAAM4F,SAAS;;sCACd,KAACvG;4BAAMwJ,UAAS;sCAAW;;sCAC3B,KAAC5I;4BAAUoI,OAAO5F;4BAAQyF,SAAS;4BAACY,WAAW;gCAAEC,OAAO;oCAAEC,UAAU;gCAAK;4BAAE;4BAAGjE,OAAM;;sCACpF,KAAC7E;4BAAWsD,SAAQ;4BAAQgB,OAAM;sCAC/B,CAAC,wBAAwB,EAAE7D,SAASsI,8BAA8B,CAAC,uCAAuC,CAAC,GAC1G,4FACA,CAAC,wBAAwB,EAAEtI,SAASuI,6BAA6B,CAAC,4BAA4B,CAAC;;;;;0BAIvG,MAACxJ;;kCACC,KAACJ;wBACCqG,SAAS;gCACFwD;4BAAL,OAAKA,uBAAAA,UAAUC,SAAS,qBAAnBD,qBACDE,SAAS,CAAC5G,QACXQ,IAAI,CAAC,IAAMb,gBAAgB,iBAAiB;oCAAEoB,SAAS;gCAAU;wBACtE;kCAEC;;kCAEH,KAAClE;wBAAOkE,SAAQ;wBAAYmC,SAASkB;kCAClC;;;;;;AAKX;AAWA,wFAAwF,GACxF,OAAO,SAASI,iBAAiBhF,KAA4B;IAC3D,MAAM,EAAElB,MAAM,EAAE4C,QAAQ,EAAEe,QAAQ,EAAE7B,IAAI,EAAEqE,QAAQ,EAAEL,OAAO,EAAE,GAAG5E;IAChE,MAAMC,YAAYjD;IAClB,MAAM,CAACqK,cAAcC,gBAAgB,GAAG7I,SAAmD;IAC3F,MAAM,CAAC8I,UAAUC,YAAY,GAAG/I,SAAwB;IACxD,MAAM,EACJgJ,MAAMC,UAAU,EAChBC,OAAO,EACPC,IAAI,EACJC,OAAO,EACPC,QAAQ,EACRC,WAAW,EACZ,GAAG7K,mBACF,CAAC8K,YACC3J,MACEH,WAAW+B,WAAW,SAASnB,QAAQ,2BACvCR,MAAM,cAAc,MAAMoD,SAASE,GAAG,MAClCyF,eAAe;YAAC/I,MAAM,UAAU,MAAM+I;SAAc,GAAG,EAAE,EAC7DjJ,QAAQ,eAAe,SACvBD,MAAM6J,aAEV;QAAC/H;QAAWnB;QAAQ4C,SAASE,GAAG;QAAEyF;KAAa,EAC/C;QAAElG,SAAS;IAAM;IAEnB,qBACE,MAAC3D;QAAOwI,IAAI;QAACpB,SAASA;QAASqB,SAAS;QAACC,UAAS;;0BAChD,KAACvI;0BAAa,CAAC,aAAa,EAAE+D,SAASW,GAAG,EAAE;;0BAC5C,KAAC3E;0BACC,cAAA,MAACK;oBAAM4F,SAAS;oBAAGI,IAAI;wBAAEoC,IAAI;oBAAE;;sCAC7B,MAACnI;4BACCiK,MAAM;4BACNzE,MAAK;4BACLV,OAAM;4BACNsD,OAAOiB;4BACPhB,UAAU,CAAC3D,QAAU4E,gBAAgB5E,MAAM4D,MAAM,CAACF,KAAK;4BACvDrC,IAAI;gCAAEmC,UAAU;4BAAI;;8CAEpB,KAACpI;oCAASsI,OAAM;8CAAI;;gCAClB3G,OAAOyI,IAAI,CAACxJ,SAAS6F,oCAAoC,EAA4CX,GAAG,CAAC,CAACuE,oBAC1G,KAACrK;wCAAmBsI,OAAO+B;kDACxBzJ,SAAS6F,oCAAoC,CAAC4D,IAAI;uCADtCA;;;wBAKlBT,WAAW1E,MAAM,KAAK,kBACrB,KAAC/E;4BAAWsD,SAAQ;4BAAQgB,OAAM;sCAC/B;6BAGHmF,WAAW9D,GAAG,CAAC,CAACsB;sCAuBakD;gCAtBdlD,oBAqBHA,qBAAyCA;4BArBnD,MAAMkD,QAAOlD,qBAAAA,SAASmD,QAAQ,qBAAjBnD,kBAAmB,CAACA,SAASmD,QAAQ,CAACrF,MAAM,GAAG,EAAE;4BAC9D,qBACE,MAACjF;gCAAyB4F,SAAS;gCAAKE,eAAY;;kDAClD,MAAC9F;wCAAM+F,WAAU;wCAAMH,SAAS;wCAAGI,IAAI;4CAAEC,YAAY;4CAAUC,UAAU;wCAAO;;0DAC9E,KAAChG;gDAAWsD,SAAQ;gDAAQwC,IAAI;oDAAEG,MAAM;gDAAE;0DACvC,GAAGgB,SAASY,IAAI,GAAG,eAAerD,SAASyC,SAASxC,KAAK,EAAE,GAAG,EAAE,IAAI4F,KAAKpD,SAASqD,WAAW,EAAEC,cAAc,IAAI;;0DAEpH,KAACjL;gDACCiG,MAAK;gDACLjC,SAAQ;gDACRuB,OAAOpE,SAAS6F,oCAAoC,CAACW,SAASpF,MAAM,CAAC;gDACrEyC,OAAO7D,SAAS8F,mCAAmC,CAACU,SAASpF,MAAM,CAAC;;0DAEtE,KAACzC;gDAAOmG,MAAK;gDAAQE,SAAS,IAAM8D,YAAYD,aAAarC,SAAStD,GAAG,GAAG,OAAOsD,SAAStD,GAAG;0DAC5F2F,aAAarC,SAAStD,GAAG,GAAG,cAAc;;0DAE7C,KAACvE;gDAAOmG,MAAK;gDAAQC,UAAU7C;gDAAM8C,SAAS,IAAMuB,SAASC;0DAC1D;;;;kDAGL,KAACjH;wCAAWsD,SAAQ;wCAAUgB,OAAM;kDACjC,YAAG2C,sBAAAA,SAASmD,QAAQ,qBAAjBnD,oBAAmBlC,MAAM,mBAAI,EAAE,QAAQ,EAAEkC,EAAAA,sBAAAA,SAASmD,QAAQ,qBAAjBnD,oBAAmBlC,MAAM,MAAK,IAAI,KAAK,KAAK,GACtFoF,CAAAA,OAAO,CAAC,QAAQ,GAAEA,mBAAAA,KAAKK,UAAU,YAAfL,mBAAmB,cAAcA,KAAKvI,KAAK,GAAG,CAAC,GAAG,EAAEuI,KAAKvI,KAAK,EAAE,GAAG,IAAI,GAAG,EAAC;;oCAEjG0H,aAAarC,SAAStD,GAAG,iBACxB,KAAC5D;wCACCoI,OAAOlB,SAASnG,IAAI;wCACpB2J,SAAS;wCACTC,SAAS;wCACT1C,SAAS;wCACTY,WAAW;4CAAEC,OAAO;gDAAEC,UAAU;4CAAK;wCAAE;yCAEvC;;+BA9BM7B,SAAStD,GAAG;wBAiC5B;sCAEF,KAAC/E;4BACC+K,MAAMA;4BACNE,UAAUA;4BACVc,UAAUlB,WAAW1E,MAAM;4BAC3B2E,SAASA;4BACTkB,cAAchB;4BACdiB,kBAAkBf;;;;;0BAIxB,KAACtK;0BACC,cAAA,KAACJ;oBAAOqG,SAASkB;8BAAU;;;;;AAInC;AAEA,eAAe7E,kBAAiB"}
1
+ {"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/order-webhooks-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 { pluginDocsHelp } from '@aglyn/aglyn'\nimport { CardDisplay, useConfirmationContext } from '@aglyn/shared-ui-jsx'\nimport { ListPagination } from '@aglyn/shared-ui-jsx/components/list-pagination.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport {\n useFirestore,\n useFirestoreCollection,\n usePagedCollection,\n useUser,\n} from '@aglyn/tenant-feature-instance'\nimport {\n Alert,\n Button,\n Checkbox,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControlLabel,\n FormGroup,\n MenuItem,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { collection, limit, orderBy, query, where } from 'firebase/firestore'\nimport { useCallback, useEffect, useState } from 'react'\nimport * as Webhooks from '../../model/order-webhooks'\n\nexport interface OrderWebhooksCardProps {\n hostId: string\n}\n\ninterface WebhookEventOption {\n event: string\n label: string\n description: string\n}\n\ninterface WebhooksStatus {\n configured: boolean\n maxEndpoints: number\n events: WebhookEventOption[]\n}\n\ntype EndpointRow = Webhooks.OrderWebhookEndpoint & { $id: string }\ntype DeliveryRow = Webhooks.OrderWebhookDelivery & { $id: string }\n\nconst ROUTE = '/api/commerce/order-webhooks'\n\n/** POSTs one action to the webhooks route; answers the body or throws its error. */\nexport async function callOrderWebhooks(\n user: Parameters<typeof authorizedFetch>[0],\n hostId: string,\n body: Record<string, unknown>,\n): Promise<Record<string, any>> {\n const response = await authorizedFetch(user, ROUTE, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ hostId, ...body }),\n })\n const payload = (await response.json().catch(() => ({}))) as Record<string, any>\n if (!response.ok) throw Object.assign(new Error(String(payload.error ?? 'Request failed')), { status: response.status })\n return payload\n}\n\n/**\n * Order webhooks (AGL-3611): the store's endpoints for order and return\n * events, each with its signing secret, a test event and a delivery log. Shown\n * only to the people who may manage them — the route answers who — and only\n * where the deployment can sign.\n */\nexport function OrderWebhooksCard(props: OrderWebhooksCardProps) {\n const { hostId } = props\n const firestore = useFirestore()\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n const { confirm } = useConfirmationContext()\n const [status, setStatus] = useState<WebhooksStatus | null>(null)\n const [editing, setEditing] = useState<EndpointRow | 'new' | null>(null)\n const [secret, setSecret] = useState<string | null>(null)\n const [logFor, setLogFor] = useState<EndpointRow | null>(null)\n const [busy, setBusy] = useState(false)\n\n useEffect(() => {\n if (!user) return\n let active = true\n callOrderWebhooks(user, hostId, { action: 'status' })\n .then((payload) => {\n if (active) setStatus(payload as WebhooksStatus)\n })\n .catch(() => {\n // Without \"Manage order webhooks\" (AGL-4047), or the route is down: the\n // card is not this person's to use.\n if (active) setStatus(null)\n })\n return () => {\n active = false\n }\n }, [user, hostId])\n\n const { data: endpointDocs } = useFirestoreCollection<EndpointRow>(\n () =>\n query(\n collection(firestore, 'hosts', hostId, 'orderWebhooks'),\n orderBy('createdAtMs', 'desc'),\n limit(Webhooks.ORDER_WEBHOOK_MAX_ENDPOINTS),\n ),\n [firestore, hostId],\n { idField: '$id' },\n )\n const endpoints = endpointDocs ?? []\n\n const run = useCallback(\n async (body: Record<string, unknown>, success?: string) => {\n setBusy(true)\n try {\n const payload = await callOrderWebhooks(user, hostId, body)\n if (success) enqueueSnackbar(success, { variant: 'success' })\n return payload\n } catch (error) {\n enqueueSnackbar(String((error as Error).message), { variant: 'error' })\n return null\n } finally {\n setBusy(false)\n }\n },\n [user, hostId, enqueueSnackbar],\n )\n\n const handleTest = useCallback(\n async (endpoint: EndpointRow) => {\n const payload = await run({ action: 'test', endpointId: endpoint.$id })\n if (!payload) return\n enqueueSnackbar(\n payload.delivered ? 'Test event delivered' : `Test event not delivered: ${payload.attempt?.error ?? 'no answer'}`,\n { variant: payload.delivered ? 'success' : 'warning' },\n )\n },\n [run, enqueueSnackbar],\n )\n\n const handleRoll = useCallback(\n async (endpoint: EndpointRow) => {\n const confirmed = await confirm({\n title: 'Roll the signing secret?',\n description:\n 'A new secret signs every event from now on. Update your endpoint before ' +\n 'the next order, or it will reject what it is sent.',\n confirmationText: 'Roll secret',\n })\n .then(() => true)\n .catch(() => false)\n if (!confirmed) return\n const payload = await run({ action: 'roll-secret', endpointId: endpoint.$id })\n if (payload?.secret) setSecret(String(payload.secret))\n },\n [confirm, run],\n )\n\n const handleDelete = useCallback(\n async (endpoint: EndpointRow) => {\n const confirmed = await confirm({\n title: 'Delete this endpoint?',\n description: `${endpoint.url} stops receiving order events. Its delivery log is kept for 30 days.`,\n confirmationText: 'Delete',\n confirmationButtonProps: { color: 'error' },\n })\n .then(() => true)\n .catch(() => false)\n if (!confirmed) return\n await run({ action: 'delete', endpointId: endpoint.$id }, 'Endpoint deleted')\n },\n [confirm, run],\n )\n\n if (!status?.configured) return null\n const labelFor = (event: string) => status.events.find((entry) => entry.event === event)?.label ?? event\n const atMax = endpoints.length >= status.maxEndpoints\n\n return (\n <CardDisplay\n header={'Order webhooks'}\n help={pluginDocsHelp('ordersAndReturns', { anchor: '#order-webhooks' })}\n contentGutterX\n contentGutterY\n HeaderProps={{\n action: (\n <Button size=\"small\" disabled={atMax || busy} onClick={() => setEditing('new')}>\n {'Add endpoint'}\n </Button>\n ),\n }}\n >\n <Stack spacing={2}>\n {endpoints.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Send order and return events to your own systems — a warehouse, an ERP or a ' +\n 'script. Each event is signed so your endpoint can check it came from this store.'}\n </Typography>\n ) : (\n endpoints.map((endpoint) => (\n <Stack key={endpoint.$id} spacing={1} data-testid=\"order-webhook-endpoint\">\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center', flexWrap: 'wrap' }}>\n <Typography variant=\"subtitle2\" sx={{ flex: 1, minWidth: 0, wordBreak: 'break-all' }}>\n {endpoint.description ? `${endpoint.description} · ${endpoint.url}` : endpoint.url}\n </Typography>\n <Chip\n size=\"small\"\n label={endpoint.enabled ? 'On' : 'Paused'}\n color={endpoint.enabled ? 'success' : 'default'}\n variant=\"outlined\"\n />\n {endpoint.lastDeliveryStatus ? (\n <Chip\n size=\"small\"\n label={`Last: ${Webhooks.ORDER_WEBHOOK_DELIVERY_STATUS_LABELS[endpoint.lastDeliveryStatus]}`}\n color={Webhooks.ORDER_WEBHOOK_DELIVERY_STATUS_COLOR[endpoint.lastDeliveryStatus]}\n variant=\"outlined\"\n />\n ) : null}\n </Stack>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`${endpoint.events.map(labelFor).join(', ')} · secret ends ${endpoint.secretHint}`}\n </Typography>\n <Stack direction=\"row\" spacing={1} sx={{ flexWrap: 'wrap' }}>\n <Button size=\"small\" disabled={busy || !endpoint.enabled} onClick={() => handleTest(endpoint)}>\n {'Send test event'}\n </Button>\n <Button size=\"small\" onClick={() => setLogFor(endpoint)}>\n {'Deliveries'}\n </Button>\n <Button size=\"small\" disabled={busy} onClick={() => setEditing(endpoint)}>\n {'Edit'}\n </Button>\n <Button\n size=\"small\"\n disabled={busy}\n onClick={() => run({ action: 'update', endpointId: endpoint.$id, enabled: !endpoint.enabled })}\n >\n {endpoint.enabled ? 'Pause' : 'Resume'}\n </Button>\n <Button size=\"small\" disabled={busy} onClick={() => handleRoll(endpoint)}>\n {'Roll secret'}\n </Button>\n <Button size=\"small\" color=\"error\" disabled={busy} onClick={() => handleDelete(endpoint)}>\n {'Delete'}\n </Button>\n </Stack>\n </Stack>\n ))\n )}\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`${endpoints.length}/${status.maxEndpoints} endpoints. A failed delivery is retried for about a day.`}\n </Typography>\n </Stack>\n {editing ? (\n <EndpointDialog\n endpoint={editing === 'new' ? null : editing}\n events={status.events}\n busy={busy}\n onClose={() => setEditing(null)}\n onSave={async (values) => {\n const payload =\n editing === 'new'\n ? await run({ action: 'create', ...values })\n : await run({ action: 'update', endpointId: editing.$id, ...values }, 'Endpoint saved')\n if (!payload) return\n setEditing(null)\n if (payload.secret) setSecret(String(payload.secret))\n }}\n />\n ) : null}\n {secret ? <SecretDialog secret={secret} onClose={() => setSecret(null)} /> : null}\n {logFor ? (\n <DeliveriesDialog\n hostId={hostId}\n endpoint={logFor}\n labelFor={labelFor}\n busy={busy}\n onResend={async (delivery) => {\n const payload = await run({ action: 'resend', deliveryId: delivery.$id })\n if (payload) {\n enqueueSnackbar(payload.delivered ? 'Delivered' : `Not delivered: ${payload.attempt?.error ?? 'no answer'}`, {\n variant: payload.delivered ? 'success' : 'warning',\n })\n }\n }}\n onClose={() => setLogFor(null)}\n />\n ) : null}\n </CardDisplay>\n )\n}\nOrderWebhooksCard.displayName = 'OrderWebhooksCard'\n\ninterface EndpointDialogProps {\n endpoint: EndpointRow | null\n events: WebhookEventOption[]\n busy: boolean\n onClose: () => void\n onSave: (values: { url: string; description: string; events: string[] }) => void | Promise<void>\n}\n\nfunction EndpointDialog(props: EndpointDialogProps) {\n const { endpoint, events, busy, onClose, onSave } = props\n const [url, setUrl] = useState(endpoint?.url ?? '')\n const [description, setDescription] = useState(endpoint?.description ?? '')\n const [chosen, setChosen] = useState<string[]>(endpoint?.events ?? events.map((entry) => entry.event))\n const toggle = (event: string) =>\n setChosen((current) => (current.includes(event) ? current.filter((entry) => entry !== event) : [...current, event]))\n const valid = /^https:\\/\\//i.test(url.trim()) && chosen.length > 0\n return (\n <Dialog open onClose={onClose} fullWidth maxWidth=\"sm\">\n <DialogTitle>{endpoint ? 'Edit endpoint' : 'Add endpoint'}</DialogTitle>\n <DialogContent>\n <Stack spacing={2} sx={{ pt: 1 }}>\n <TextField\n label=\"Endpoint URL\"\n value={url}\n onChange={(event) => setUrl(event.target.value)}\n placeholder=\"https://example.com/aglyn-webhooks\"\n helperText=\"An https address on a public server. Redirects are not followed.\"\n fullWidth\n autoFocus\n />\n <TextField\n label=\"Description\"\n value={description}\n onChange={(event) => setDescription(event.target.value)}\n placeholder=\"Warehouse\"\n fullWidth\n />\n <FormGroup>\n <Typography variant=\"subtitle2\">{'Events'}</Typography>\n {events.map((entry) => (\n <FormControlLabel\n key={entry.event}\n control={<Checkbox checked={chosen.includes(entry.event)} onChange={() => toggle(entry.event)} />}\n label={\n <Stack>\n <Typography variant=\"body2\">{`${entry.label} (${entry.event})`}</Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {entry.description}\n </Typography>\n </Stack>\n }\n />\n ))}\n </FormGroup>\n </Stack>\n </DialogContent>\n <DialogActions>\n <Button onClick={onClose}>{'Cancel'}</Button>\n <Button\n variant=\"contained\"\n disabled={!valid || busy}\n onClick={() => onSave({ url: url.trim(), description: description.trim(), events: chosen })}\n >\n {endpoint ? 'Save' : 'Add endpoint'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\nfunction SecretDialog(props: { secret: string; onClose: () => void }) {\n const { secret, onClose } = props\n const { enqueueSnackbar } = useSnackbar()\n return (\n <Dialog open onClose={onClose} fullWidth maxWidth=\"sm\">\n <DialogTitle>{'Signing secret'}</DialogTitle>\n <DialogContent>\n <Stack spacing={2}>\n <Alert severity=\"warning\">{'Copy it now. It is not shown again; roll a new one if it is lost.'}</Alert>\n <TextField value={secret} fullWidth slotProps={{ input: { readOnly: true } }} label=\"Secret\" />\n <Typography variant=\"body2\" color=\"text.secondary\">\n {`Each request carries an ${Webhooks.ORDER_WEBHOOK_SIGNATURE_HEADER} header, t=<timestamp>,v1=<signature>. ` +\n 'The signature is the HMAC-SHA256, in hex, of the timestamp, a period and the raw body, ' +\n `keyed with this secret. ${Webhooks.ORDER_WEBHOOK_EVENT_ID_HEADER} is the same on every retry.`}\n </Typography>\n </Stack>\n </DialogContent>\n <DialogActions>\n <Button\n onClick={() => {\n void navigator.clipboard\n ?.writeText(secret)\n .then(() => enqueueSnackbar('Secret copied', { variant: 'success' }))\n }}\n >\n {'Copy'}\n </Button>\n <Button variant=\"contained\" onClick={onClose}>\n {'Done'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\ninterface DeliveriesDialogProps {\n hostId: string\n endpoint: EndpointRow\n labelFor: (event: string) => string\n busy: boolean\n onResend: (delivery: DeliveryRow) => void | Promise<void>\n onClose: () => void\n}\n\n/** The endpoint's delivery log, newest first, filtered and paged by a Firestore query. */\nexport function DeliveriesDialog(props: DeliveriesDialogProps) {\n const { hostId, endpoint, labelFor, busy, onResend, onClose } = props\n const firestore = useFirestore()\n const [statusFilter, setStatusFilter] = useState<Webhooks.OrderWebhookDeliveryStatus | ''>('')\n const [openBody, setOpenBody] = useState<string | null>(null)\n const {\n rows: deliveries,\n hasMore,\n page,\n setPage,\n pageSize,\n setPageSize,\n } = usePagedCollection<DeliveryRow>(\n (pageLimit) =>\n query(\n collection(firestore, 'hosts', hostId, 'orderWebhookDeliveries'),\n where('endpointId', '==', endpoint.$id),\n ...(statusFilter ? [where('status', '==', statusFilter)] : []),\n orderBy('createdAtMs', 'desc'),\n limit(pageLimit),\n ),\n [firestore, hostId, endpoint.$id, statusFilter],\n { idField: '$id' },\n )\n return (\n <Dialog open onClose={onClose} fullWidth maxWidth=\"md\">\n <DialogTitle>{`Deliveries · ${endpoint.url}`}</DialogTitle>\n <DialogContent>\n <Stack spacing={2} sx={{ pt: 1 }}>\n <TextField\n select\n size=\"small\"\n label=\"Status\"\n value={statusFilter}\n onChange={(event) => setStatusFilter(event.target.value as Webhooks.OrderWebhookDeliveryStatus | '')}\n sx={{ maxWidth: 200 }}\n >\n <MenuItem value=\"\">{'All'}</MenuItem>\n {(Object.keys(Webhooks.ORDER_WEBHOOK_DELIVERY_STATUS_LABELS) as Webhooks.OrderWebhookDeliveryStatus[]).map((key) => (\n <MenuItem key={key} value={key}>\n {Webhooks.ORDER_WEBHOOK_DELIVERY_STATUS_LABELS[key]}\n </MenuItem>\n ))}\n </TextField>\n {deliveries.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'No deliveries in the last 30 days.'}\n </Typography>\n ) : (\n deliveries.map((delivery) => {\n const last = delivery.attempts?.[delivery.attempts.length - 1]\n return (\n <Stack key={delivery.$id} spacing={0.5} data-testid=\"order-webhook-delivery\">\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center', flexWrap: 'wrap' }}>\n <Typography variant=\"body2\" sx={{ flex: 1 }}>\n {`${delivery.test ? 'Test event' : labelFor(delivery.event)} · ${new Date(delivery.createdAtMs).toLocaleString()}`}\n </Typography>\n <Chip\n size=\"small\"\n variant=\"outlined\"\n label={Webhooks.ORDER_WEBHOOK_DELIVERY_STATUS_LABELS[delivery.status]}\n color={Webhooks.ORDER_WEBHOOK_DELIVERY_STATUS_COLOR[delivery.status]}\n />\n <Button size=\"small\" onClick={() => setOpenBody(openBody === delivery.$id ? null : delivery.$id)}>\n {openBody === delivery.$id ? 'Hide body' : 'Body'}\n </Button>\n <Button size=\"small\" disabled={busy} onClick={() => onResend(delivery)}>\n {'Resend'}\n </Button>\n </Stack>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {`${delivery.attempts?.length ?? 0} attempt${delivery.attempts?.length === 1 ? '' : 's'}` +\n (last ? ` · last ${last.httpStatus ?? 'no answer'}${last.error ? ` — ${last.error}` : ''}` : '')}\n </Typography>\n {openBody === delivery.$id ? (\n <TextField\n value={delivery.body}\n multiline\n maxRows={12}\n fullWidth\n slotProps={{ input: { readOnly: true } }}\n />\n ) : null}\n </Stack>\n )\n })\n )}\n <ListPagination\n page={page}\n pageSize={pageSize}\n rowCount={deliveries.length}\n hasMore={hasMore}\n onPageChange={setPage}\n onPageSizeChange={setPageSize}\n />\n </Stack>\n </DialogContent>\n <DialogActions>\n <Button onClick={onClose}>{'Close'}</Button>\n </DialogActions>\n </Dialog>\n )\n}\n\nexport default OrderWebhooksCard\n"],"names":["pluginDocsHelp","CardDisplay","useConfirmationContext","ListPagination","useSnackbar","authorizedFetch","useFirestore","useFirestoreCollection","usePagedCollection","useUser","Alert","Button","Checkbox","Chip","Dialog","DialogActions","DialogContent","DialogTitle","FormControlLabel","FormGroup","MenuItem","Stack","TextField","Typography","collection","limit","orderBy","query","where","useCallback","useEffect","useState","Webhooks","ROUTE","callOrderWebhooks","user","hostId","body","payload","response","method","headers","JSON","stringify","json","catch","ok","Object","assign","Error","String","error","status","OrderWebhooksCard","props","firestore","data","enqueueSnackbar","confirm","setStatus","editing","setEditing","secret","setSecret","logFor","setLogFor","busy","setBusy","active","action","then","endpointDocs","ORDER_WEBHOOK_MAX_ENDPOINTS","idField","endpoints","run","success","variant","message","handleTest","endpoint","endpointId","$id","delivered","attempt","handleRoll","confirmed","title","description","confirmationText","handleDelete","url","confirmationButtonProps","color","configured","labelFor","event","events","find","entry","label","atMax","length","maxEndpoints","header","help","anchor","contentGutterX","contentGutterY","HeaderProps","size","disabled","onClick","spacing","map","data-testid","direction","sx","alignItems","flexWrap","flex","minWidth","wordBreak","enabled","lastDeliveryStatus","ORDER_WEBHOOK_DELIVERY_STATUS_LABELS","ORDER_WEBHOOK_DELIVERY_STATUS_COLOR","join","secretHint","EndpointDialog","onClose","onSave","values","SecretDialog","DeliveriesDialog","onResend","delivery","deliveryId","displayName","setUrl","setDescription","chosen","setChosen","toggle","current","includes","filter","valid","test","trim","open","fullWidth","maxWidth","pt","value","onChange","target","placeholder","helperText","autoFocus","control","checked","severity","slotProps","input","readOnly","ORDER_WEBHOOK_SIGNATURE_HEADER","ORDER_WEBHOOK_EVENT_ID_HEADER","navigator","clipboard","writeText","statusFilter","setStatusFilter","openBody","setOpenBody","rows","deliveries","hasMore","page","setPage","pageSize","setPageSize","pageLimit","select","keys","key","last","attempts","Date","createdAtMs","toLocaleString","httpStatus","multiline","maxRows","rowCount","onPageChange","onPageSizeChange"],"mappings":"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"}
@@ -274,7 +274,7 @@ import { PAYMENTS_SETTINGS_ANCHOR } from "./payments-settings-card.component.js"
274
274
  }),
275
275
  canEdit ? null : /*#__PURE__*/ _jsx(Alert, {
276
276
  severity: "info",
277
- children: 'Only a site admin can change which payment methods your store offers.'
277
+ children: 'Changing which payment methods your store offers takes the "Manage payment methods" permission — ask an organization admin.'
278
278
  }),
279
279
  view.accountConnected ? null : /*#__PURE__*/ _jsx(PrerequisiteNotice, {
280
280
  href: `#${PAYMENTS_SETTINGS_ANCHOR}`,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/payment-methods-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'use client'\n\nimport { pluginDocsHelp } from '@aglyn/aglyn'\nimport { CardDisplay } from '@aglyn/shared-ui-jsx'\nimport { PrerequisiteNotice } from '@aglyn/shared-ui-jsx/components/prerequisite-notice.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport {\n Alert,\n Button,\n Chip,\n Divider,\n Stack,\n Switch,\n Typography,\n} from '@mui/material'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport {\n STOREFRONT_PAYMENT_METHODS,\n type StorefrontPaymentMethodId,\n type StorefrontPaymentMethodSettings,\n type StorefrontPaymentMethodSpec,\n} from '../../model/commerce-payment-methods'\nimport { PAYMENTS_SETTINGS_ANCHOR } from './payments-settings-card.component'\n\nexport interface PaymentMethodsCardProps {\n hostId: string\n}\n\n/** One method as the route reports it (`server/payment-methods.ts`). */\nexport interface PaymentMethodRowView {\n id: StorefrontPaymentMethodId\n on: boolean\n platform: 'on' | 'unavailable' | null\n capability: 'active' | 'pending' | 'inactive' | 'unrequested' | null\n}\n\nexport interface PaymentMethodDomainView {\n domain: string\n enabled: boolean\n stripeId: string | null\n status: { applePay: string | null; googlePay: string | null }\n lastError: string | null\n}\n\nexport interface PaymentMethodsView {\n methods: PaymentMethodRowView[]\n domains: PaymentMethodDomainView[]\n accountConnected: boolean\n /** Absent from an older answer: read as allowed, and the route still judges. */\n canEdit?: boolean\n canFinish?: boolean\n warnings: string[]\n}\n\n/**\n * What a method's Stripe state means to the merchant, or null for nothing to\n * say. Only an ON method gets a verdict: an off one is the merchant's choice.\n */\nexport function capabilityVerdict(\n row: PaymentMethodRowView,\n accountConnected: boolean,\n): { label: string; color: 'success' | 'warning' | 'default' } | null {\n if (!row.on) return null\n if (!accountConnected) return { label: 'Connect Stripe first', color: 'default' }\n switch (row.capability) {\n case 'active':\n return { label: 'Ready', color: 'success' }\n case 'pending':\n return { label: 'Stripe is reviewing', color: 'warning' }\n case 'inactive':\n return { label: 'Stripe needs more details', color: 'warning' }\n case 'unrequested':\n return { label: 'Save to request', color: 'default' }\n default:\n return null\n }\n}\n\n/** The domain chip: what Apple Pay can do on this name right now. */\nexport function domainVerdict(domain: PaymentMethodDomainView): {\n label: string\n color: 'success' | 'warning' | 'default'\n} {\n if (domain.enabled && domain.status.applePay === 'active') {\n return { label: 'Apple Pay ready', color: 'success' }\n }\n if (domain.enabled) return { label: 'Registered', color: 'default' }\n if (domain.lastError) return { label: 'Retrying', color: 'warning' }\n return { label: 'Registers on first checkout', color: 'default' }\n}\n\n/**\n * The methods a merchant can see: everything the platform offers, and every\n * method we could not ask Stripe about except crypto, which is shown only once\n * the platform positively offers it (AGL-3629: hidden where unavailable).\n */\nexport function visibleMethods(\n rows: readonly PaymentMethodRowView[],\n): Array<{ row: PaymentMethodRowView; spec: StorefrontPaymentMethodSpec }> {\n return rows\n .map((row) => ({\n row,\n spec: STOREFRONT_PAYMENT_METHODS.find((method) => method.id === row.id),\n }))\n .filter(\n (entry): entry is { row: PaymentMethodRowView; spec: StorefrontPaymentMethodSpec } =>\n Boolean(entry.spec) &&\n entry.row.platform !== 'unavailable' &&\n !(entry.row.platform === null && entry.spec?.kind === 'crypto'),\n )\n}\n\n/**\n * Payment methods (AGL-3629): which wallets, buy-now-pay-later and crypto\n * options the storefront offers, what each needs, and whether Stripe is ready\n * for it. Cards are always on and are not listed.\n *\n * Read and saved through `/api/commerce/payment-methods` rather than a\n * Firestore listen, because two of the three facts per row — what the\n * platform offers and the payout account's capability — live at Stripe, and a\n * save is a Stripe request as well as a settings write.\n */\nexport function PaymentMethodsCard(props: PaymentMethodsCardProps) {\n const { hostId } = props\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n const [view, setView] = useState<PaymentMethodsView | null>(null)\n const [state, setState] = useState<'loading' | 'loaded' | 'error' | 'unconfigured'>(\n 'loading',\n )\n const [draft, setDraft] = useState<StorefrontPaymentMethodSettings>({})\n const [saving, setSaving] = useState(false)\n const [nonce, setNonce] = useState(0)\n // The load keys on the uid, not the user object: a refreshed token hands\n // back a new object, and reloading on it would throw away unsaved toggles.\n const userRef = useRef(user)\n userRef.current = user\n const uid = user?.uid\n\n useEffect(() => {\n const user = userRef.current\n if (!uid || !user || !hostId) return\n let cancelled = false\n setState('loading')\n void (async () => {\n try {\n const response = await authorizedFetch(\n user,\n `/api/commerce/payment-methods?hostId=${encodeURIComponent(hostId)}`,\n )\n if (cancelled) return\n if (response.status === 501) return void setState('unconfigured')\n if (!response.ok) return void setState('error')\n const payload = (await response.json()) as PaymentMethodsView\n if (cancelled) return\n setView(payload)\n setDraft({})\n setState('loaded')\n } catch {\n if (!cancelled) setState('error')\n }\n })()\n return () => {\n cancelled = true\n }\n }, [uid, hostId, nonce])\n\n const dirty = Object.keys(draft).length > 0\n\n const handleSave = useCallback(async () => {\n if (!dirty) return\n setSaving(true)\n try {\n const response = await authorizedFetch(user, '/api/commerce/payment-methods', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ hostId, methods: draft }),\n })\n const payload = await response.json().catch(() => ({}))\n if (!response.ok) {\n return void enqueueSnackbar(payload?.error ?? 'Payment methods were not saved', {\n variant: 'error',\n allowDuplicate: true,\n })\n }\n setView(payload as PaymentMethodsView)\n setDraft({})\n enqueueSnackbar('Payment methods saved', { variant: 'success', persist: false })\n } catch {\n enqueueSnackbar('Payment methods were not saved', {\n variant: 'error',\n allowDuplicate: true,\n })\n } finally {\n setSaving(false)\n }\n }, [dirty, draft, enqueueSnackbar, hostId, user])\n\n const handleFinish = useCallback(async () => {\n setSaving(true)\n try {\n const response = await authorizedFetch(user, '/api/commerce/payment-methods', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ hostId, action: 'finish' }),\n })\n const payload = await response.json().catch(() => ({}))\n if (response.ok && typeof payload?.url === 'string') {\n return void window.location.assign(payload.url)\n }\n enqueueSnackbar(payload?.error ?? 'Stripe could not be opened', {\n variant: 'error',\n allowDuplicate: true,\n })\n } catch {\n enqueueSnackbar('Stripe could not be opened', { variant: 'error', allowDuplicate: true })\n } finally {\n setSaving(false)\n }\n }, [enqueueSnackbar, hostId, user])\n\n const rows = view ? visibleMethods(view.methods) : []\n const canEdit = view?.canEdit !== false\n const canFinish = view?.canFinish !== false\n\n return (\n <CardDisplay\n header={'Payment methods'}\n help={pluginDocsHelp('commerce', { anchor: '#payment-methods' })}\n HeaderProps={{\n action:\n state === 'loaded' && canEdit ? (\n <Button\n size=\"small\"\n variant=\"contained\"\n disabled={!dirty || saving}\n onClick={handleSave}\n >\n {saving ? 'Saving…' : 'Save'}\n </Button>\n ) : null,\n }}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={1.5} data-testid=\"payment-methods-card\">\n {state === 'loading' ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Checking your payment methods…'}\n </Typography>\n ) : null}\n {state === 'unconfigured' ? (\n <Alert severity=\"info\">{'Payments are not configured on this deployment.'}</Alert>\n ) : null}\n {state === 'error' ? (\n <Alert\n severity=\"error\"\n action={\n <Button color=\"inherit\" size=\"small\" onClick={() => setNonce((n) => n + 1)}>\n {'Retry'}\n </Button>\n }\n >\n {'We couldn’t load your payment methods. Nothing has changed — ' +\n 'shoppers still see what they saw before.'}\n </Alert>\n ) : null}\n {state === 'loaded' && view ? (\n <>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Cards are always on. Turn off anything you don’t want to offer. ' +\n 'Stripe shows each method only on orders and to shoppers it suits, ' +\n 'using the limits below.'}\n </Typography>\n {canEdit ? null : (\n <Alert severity=\"info\">\n {'Only a site admin can change which payment methods your store offers.'}\n </Alert>\n )}\n {/* What every \"Connect Stripe first\" chip below waits on, and where\n it is done: the Payments card above (AGL-3982). */}\n {view.accountConnected ? null : (\n <PrerequisiteNotice href={`#${PAYMENTS_SETTINGS_ANCHOR}`} actionLabel=\"Connect Stripe\">\n {'Connect Stripe in the Payments card above to offer these methods. ' +\n 'Methods you turn on show at checkout once Stripe is connected and approves them.'}\n </PrerequisiteNotice>\n )}\n {view.warnings.map((warning) => (\n <Alert key={warning} severity=\"warning\">\n {warning}\n </Alert>\n ))}\n {rows.map(({ row, spec }) => {\n const on = draft[row.id] ?? row.on\n const verdict = capabilityVerdict({ ...row, on }, view.accountConnected)\n return (\n <Stack key={row.id} spacing={0.5} data-testid={`payment-method-${row.id}`}>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Switch\n checked={on}\n disabled={!canEdit || saving}\n onChange={(event) => {\n const next = event.target.checked\n setDraft((current) => {\n const copy = { ...current }\n if (next === row.on) delete copy[row.id]\n else copy[row.id] = next\n return copy\n })\n }}\n slotProps={{ input: { 'aria-label': spec.label } }}\n />\n <Typography variant=\"subtitle2\" sx={{ flex: 1 }}>\n {spec.label}\n </Typography>\n {spec.capability && verdict ? (\n <Chip size=\"small\" variant=\"outlined\" label={verdict.label} color={verdict.color} />\n ) : null}\n {on && row.capability === 'inactive' && canFinish ? (\n <Button size=\"small\" disabled={saving} onClick={handleFinish}>\n {'Finish in Stripe'}\n </Button>\n ) : null}\n </Stack>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {spec.requirements}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {spec.limits}\n </Typography>\n </Stack>\n )\n })}\n <Divider />\n <Typography variant=\"subtitle2\">{'Wallet domains'}</Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Apple Pay shows only on a domain registered with Stripe. Your ' +\n 'site’s domains are registered for you when you connect them and ' +\n 'on the first in-page checkout.'}\n </Typography>\n {view.domains.map((domain) => {\n const verdict = domainVerdict(domain)\n return (\n <Stack\n key={domain.domain}\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center' }}\n data-testid={`payment-domain-${domain.domain}`}\n >\n <Typography variant=\"body2\" sx={{ flex: 1 }}>\n {domain.domain}\n </Typography>\n <Chip size=\"small\" variant=\"outlined\" label={verdict.label} color={verdict.color} />\n </Stack>\n )\n })}\n </>\n ) : null}\n </Stack>\n </CardDisplay>\n )\n}\nPaymentMethodsCard.displayName = 'PaymentMethodsCard'\n\nexport default PaymentMethodsCard\n"],"names":["pluginDocsHelp","CardDisplay","PrerequisiteNotice","useSnackbar","authorizedFetch","useUser","Alert","Button","Chip","Divider","Stack","Switch","Typography","useCallback","useEffect","useRef","useState","STOREFRONT_PAYMENT_METHODS","PAYMENTS_SETTINGS_ANCHOR","capabilityVerdict","row","accountConnected","on","label","color","capability","domainVerdict","domain","enabled","status","applePay","lastError","visibleMethods","rows","map","spec","find","method","id","filter","entry","Boolean","platform","kind","PaymentMethodsCard","props","hostId","data","user","enqueueSnackbar","view","setView","state","setState","draft","setDraft","saving","setSaving","nonce","setNonce","userRef","current","uid","cancelled","response","encodeURIComponent","ok","payload","json","dirty","Object","keys","length","handleSave","headers","body","JSON","stringify","methods","catch","error","variant","allowDuplicate","persist","handleFinish","action","url","window","location","assign","canEdit","canFinish","header","help","anchor","HeaderProps","size","disabled","onClick","contentGutterX","contentGutterY","spacing","data-testid","severity","n","href","actionLabel","warnings","warning","verdict","direction","sx","alignItems","checked","onChange","event","next","target","copy","slotProps","input","flex","requirements","limits","domains","displayName"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/payment-methods-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'use client'\n\nimport { pluginDocsHelp } from '@aglyn/aglyn'\nimport { CardDisplay } from '@aglyn/shared-ui-jsx'\nimport { PrerequisiteNotice } from '@aglyn/shared-ui-jsx/components/prerequisite-notice.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport {\n Alert,\n Button,\n Chip,\n Divider,\n Stack,\n Switch,\n Typography,\n} from '@mui/material'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport {\n STOREFRONT_PAYMENT_METHODS,\n type StorefrontPaymentMethodId,\n type StorefrontPaymentMethodSettings,\n type StorefrontPaymentMethodSpec,\n} from '../../model/commerce-payment-methods'\nimport { PAYMENTS_SETTINGS_ANCHOR } from './payments-settings-card.component'\n\nexport interface PaymentMethodsCardProps {\n hostId: string\n}\n\n/** One method as the route reports it (`server/payment-methods.ts`). */\nexport interface PaymentMethodRowView {\n id: StorefrontPaymentMethodId\n on: boolean\n platform: 'on' | 'unavailable' | null\n capability: 'active' | 'pending' | 'inactive' | 'unrequested' | null\n}\n\nexport interface PaymentMethodDomainView {\n domain: string\n enabled: boolean\n stripeId: string | null\n status: { applePay: string | null; googlePay: string | null }\n lastError: string | null\n}\n\nexport interface PaymentMethodsView {\n methods: PaymentMethodRowView[]\n domains: PaymentMethodDomainView[]\n accountConnected: boolean\n /** Absent from an older answer: read as allowed, and the route still judges. */\n canEdit?: boolean\n canFinish?: boolean\n warnings: string[]\n}\n\n/**\n * What a method's Stripe state means to the merchant, or null for nothing to\n * say. Only an ON method gets a verdict: an off one is the merchant's choice.\n */\nexport function capabilityVerdict(\n row: PaymentMethodRowView,\n accountConnected: boolean,\n): { label: string; color: 'success' | 'warning' | 'default' } | null {\n if (!row.on) return null\n if (!accountConnected) return { label: 'Connect Stripe first', color: 'default' }\n switch (row.capability) {\n case 'active':\n return { label: 'Ready', color: 'success' }\n case 'pending':\n return { label: 'Stripe is reviewing', color: 'warning' }\n case 'inactive':\n return { label: 'Stripe needs more details', color: 'warning' }\n case 'unrequested':\n return { label: 'Save to request', color: 'default' }\n default:\n return null\n }\n}\n\n/** The domain chip: what Apple Pay can do on this name right now. */\nexport function domainVerdict(domain: PaymentMethodDomainView): {\n label: string\n color: 'success' | 'warning' | 'default'\n} {\n if (domain.enabled && domain.status.applePay === 'active') {\n return { label: 'Apple Pay ready', color: 'success' }\n }\n if (domain.enabled) return { label: 'Registered', color: 'default' }\n if (domain.lastError) return { label: 'Retrying', color: 'warning' }\n return { label: 'Registers on first checkout', color: 'default' }\n}\n\n/**\n * The methods a merchant can see: everything the platform offers, and every\n * method we could not ask Stripe about except crypto, which is shown only once\n * the platform positively offers it (AGL-3629: hidden where unavailable).\n */\nexport function visibleMethods(\n rows: readonly PaymentMethodRowView[],\n): Array<{ row: PaymentMethodRowView; spec: StorefrontPaymentMethodSpec }> {\n return rows\n .map((row) => ({\n row,\n spec: STOREFRONT_PAYMENT_METHODS.find((method) => method.id === row.id),\n }))\n .filter(\n (entry): entry is { row: PaymentMethodRowView; spec: StorefrontPaymentMethodSpec } =>\n Boolean(entry.spec) &&\n entry.row.platform !== 'unavailable' &&\n !(entry.row.platform === null && entry.spec?.kind === 'crypto'),\n )\n}\n\n/**\n * Payment methods (AGL-3629): which wallets, buy-now-pay-later and crypto\n * options the storefront offers, what each needs, and whether Stripe is ready\n * for it. Cards are always on and are not listed.\n *\n * Read and saved through `/api/commerce/payment-methods` rather than a\n * Firestore listen, because two of the three facts per row — what the\n * platform offers and the payout account's capability — live at Stripe, and a\n * save is a Stripe request as well as a settings write.\n */\nexport function PaymentMethodsCard(props: PaymentMethodsCardProps) {\n const { hostId } = props\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n const [view, setView] = useState<PaymentMethodsView | null>(null)\n const [state, setState] = useState<'loading' | 'loaded' | 'error' | 'unconfigured'>(\n 'loading',\n )\n const [draft, setDraft] = useState<StorefrontPaymentMethodSettings>({})\n const [saving, setSaving] = useState(false)\n const [nonce, setNonce] = useState(0)\n // The load keys on the uid, not the user object: a refreshed token hands\n // back a new object, and reloading on it would throw away unsaved toggles.\n const userRef = useRef(user)\n userRef.current = user\n const uid = user?.uid\n\n useEffect(() => {\n const user = userRef.current\n if (!uid || !user || !hostId) return\n let cancelled = false\n setState('loading')\n void (async () => {\n try {\n const response = await authorizedFetch(\n user,\n `/api/commerce/payment-methods?hostId=${encodeURIComponent(hostId)}`,\n )\n if (cancelled) return\n if (response.status === 501) return void setState('unconfigured')\n if (!response.ok) return void setState('error')\n const payload = (await response.json()) as PaymentMethodsView\n if (cancelled) return\n setView(payload)\n setDraft({})\n setState('loaded')\n } catch {\n if (!cancelled) setState('error')\n }\n })()\n return () => {\n cancelled = true\n }\n }, [uid, hostId, nonce])\n\n const dirty = Object.keys(draft).length > 0\n\n const handleSave = useCallback(async () => {\n if (!dirty) return\n setSaving(true)\n try {\n const response = await authorizedFetch(user, '/api/commerce/payment-methods', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ hostId, methods: draft }),\n })\n const payload = await response.json().catch(() => ({}))\n if (!response.ok) {\n return void enqueueSnackbar(payload?.error ?? 'Payment methods were not saved', {\n variant: 'error',\n allowDuplicate: true,\n })\n }\n setView(payload as PaymentMethodsView)\n setDraft({})\n enqueueSnackbar('Payment methods saved', { variant: 'success', persist: false })\n } catch {\n enqueueSnackbar('Payment methods were not saved', {\n variant: 'error',\n allowDuplicate: true,\n })\n } finally {\n setSaving(false)\n }\n }, [dirty, draft, enqueueSnackbar, hostId, user])\n\n const handleFinish = useCallback(async () => {\n setSaving(true)\n try {\n const response = await authorizedFetch(user, '/api/commerce/payment-methods', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ hostId, action: 'finish' }),\n })\n const payload = await response.json().catch(() => ({}))\n if (response.ok && typeof payload?.url === 'string') {\n return void window.location.assign(payload.url)\n }\n enqueueSnackbar(payload?.error ?? 'Stripe could not be opened', {\n variant: 'error',\n allowDuplicate: true,\n })\n } catch {\n enqueueSnackbar('Stripe could not be opened', { variant: 'error', allowDuplicate: true })\n } finally {\n setSaving(false)\n }\n }, [enqueueSnackbar, hostId, user])\n\n const rows = view ? visibleMethods(view.methods) : []\n const canEdit = view?.canEdit !== false\n const canFinish = view?.canFinish !== false\n\n return (\n <CardDisplay\n header={'Payment methods'}\n help={pluginDocsHelp('commerce', { anchor: '#payment-methods' })}\n HeaderProps={{\n action:\n state === 'loaded' && canEdit ? (\n <Button\n size=\"small\"\n variant=\"contained\"\n disabled={!dirty || saving}\n onClick={handleSave}\n >\n {saving ? 'Saving…' : 'Save'}\n </Button>\n ) : null,\n }}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={1.5} data-testid=\"payment-methods-card\">\n {state === 'loading' ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Checking your payment methods…'}\n </Typography>\n ) : null}\n {state === 'unconfigured' ? (\n <Alert severity=\"info\">{'Payments are not configured on this deployment.'}</Alert>\n ) : null}\n {state === 'error' ? (\n <Alert\n severity=\"error\"\n action={\n <Button color=\"inherit\" size=\"small\" onClick={() => setNonce((n) => n + 1)}>\n {'Retry'}\n </Button>\n }\n >\n {'We couldn’t load your payment methods. Nothing has changed — ' +\n 'shoppers still see what they saw before.'}\n </Alert>\n ) : null}\n {state === 'loaded' && view ? (\n <>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Cards are always on. Turn off anything you don’t want to offer. ' +\n 'Stripe shows each method only on orders and to shoppers it suits, ' +\n 'using the limits below.'}\n </Typography>\n {canEdit ? null : (\n <Alert severity=\"info\">\n {'Changing which payment methods your store offers takes the \"Manage payment methods\" permission — ask an organization admin.'}\n </Alert>\n )}\n {/* What every \"Connect Stripe first\" chip below waits on, and where\n it is done: the Payments card above (AGL-3982). */}\n {view.accountConnected ? null : (\n <PrerequisiteNotice href={`#${PAYMENTS_SETTINGS_ANCHOR}`} actionLabel=\"Connect Stripe\">\n {'Connect Stripe in the Payments card above to offer these methods. ' +\n 'Methods you turn on show at checkout once Stripe is connected and approves them.'}\n </PrerequisiteNotice>\n )}\n {view.warnings.map((warning) => (\n <Alert key={warning} severity=\"warning\">\n {warning}\n </Alert>\n ))}\n {rows.map(({ row, spec }) => {\n const on = draft[row.id] ?? row.on\n const verdict = capabilityVerdict({ ...row, on }, view.accountConnected)\n return (\n <Stack key={row.id} spacing={0.5} data-testid={`payment-method-${row.id}`}>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Switch\n checked={on}\n disabled={!canEdit || saving}\n onChange={(event) => {\n const next = event.target.checked\n setDraft((current) => {\n const copy = { ...current }\n if (next === row.on) delete copy[row.id]\n else copy[row.id] = next\n return copy\n })\n }}\n slotProps={{ input: { 'aria-label': spec.label } }}\n />\n <Typography variant=\"subtitle2\" sx={{ flex: 1 }}>\n {spec.label}\n </Typography>\n {spec.capability && verdict ? (\n <Chip size=\"small\" variant=\"outlined\" label={verdict.label} color={verdict.color} />\n ) : null}\n {on && row.capability === 'inactive' && canFinish ? (\n <Button size=\"small\" disabled={saving} onClick={handleFinish}>\n {'Finish in Stripe'}\n </Button>\n ) : null}\n </Stack>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {spec.requirements}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {spec.limits}\n </Typography>\n </Stack>\n )\n })}\n <Divider />\n <Typography variant=\"subtitle2\">{'Wallet domains'}</Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Apple Pay shows only on a domain registered with Stripe. Your ' +\n 'site’s domains are registered for you when you connect them and ' +\n 'on the first in-page checkout.'}\n </Typography>\n {view.domains.map((domain) => {\n const verdict = domainVerdict(domain)\n return (\n <Stack\n key={domain.domain}\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center' }}\n data-testid={`payment-domain-${domain.domain}`}\n >\n <Typography variant=\"body2\" sx={{ flex: 1 }}>\n {domain.domain}\n </Typography>\n <Chip size=\"small\" variant=\"outlined\" label={verdict.label} color={verdict.color} />\n </Stack>\n )\n })}\n </>\n ) : null}\n </Stack>\n </CardDisplay>\n )\n}\nPaymentMethodsCard.displayName = 'PaymentMethodsCard'\n\nexport default PaymentMethodsCard\n"],"names":["pluginDocsHelp","CardDisplay","PrerequisiteNotice","useSnackbar","authorizedFetch","useUser","Alert","Button","Chip","Divider","Stack","Switch","Typography","useCallback","useEffect","useRef","useState","STOREFRONT_PAYMENT_METHODS","PAYMENTS_SETTINGS_ANCHOR","capabilityVerdict","row","accountConnected","on","label","color","capability","domainVerdict","domain","enabled","status","applePay","lastError","visibleMethods","rows","map","spec","find","method","id","filter","entry","Boolean","platform","kind","PaymentMethodsCard","props","hostId","data","user","enqueueSnackbar","view","setView","state","setState","draft","setDraft","saving","setSaving","nonce","setNonce","userRef","current","uid","cancelled","response","encodeURIComponent","ok","payload","json","dirty","Object","keys","length","handleSave","headers","body","JSON","stringify","methods","catch","error","variant","allowDuplicate","persist","handleFinish","action","url","window","location","assign","canEdit","canFinish","header","help","anchor","HeaderProps","size","disabled","onClick","contentGutterX","contentGutterY","spacing","data-testid","severity","n","href","actionLabel","warnings","warning","verdict","direction","sx","alignItems","checked","onChange","event","next","target","copy","slotProps","input","flex","requirements","limits","domains","displayName"],"mappings":"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"}
@@ -24,6 +24,11 @@ export interface PosCartPanelProps {
24
24
  customer?: ReactNode;
25
25
  /** Lines can no longer change: a sale is open against them. */
26
26
  locked: boolean;
27
+ /**
28
+ * Why this member may not give a discount (AGL-4047): the "Give discounts
29
+ * at the register" key refused. The field stays, disabled with the reason.
30
+ */
31
+ discountBlocked?: string;
27
32
  }
28
33
  /**
29
34
  * The basket (AGL-3607): lines with large quantity steppers, the stock
@@ -15,6 +15,7 @@
15
15
  * limitations under the License.
16
16
  */ 'use client';
17
17
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
18
+ import { BlockedControl } from "@aglyn/shared-ui-jsx/components/blocked-control.component";
18
19
  import { Box, Button, ButtonBase, IconButton, Stack, TextField, Typography } from "@mui/material";
19
20
  import { POS_TOUCH_PX } from "./pos-product-grid.component.js";
20
21
  import { usd } from "./pos-api.js";
@@ -23,6 +24,7 @@ import { usd } from "./pos-api.js";
23
24
  * warning under any line the shelf cannot cover (AGL-2357, said and never
24
25
  * enforced), the cashier's discount and the customer the sale is for.
25
26
  */ export function PosCartPanel(props) {
27
+ var _props_discountBlocked;
26
28
  const { lines, locked } = props;
27
29
  return /*#__PURE__*/ _jsxs(Stack, {
28
30
  spacing: 1,
@@ -136,19 +138,23 @@ import { usd } from "./pos-api.js";
136
138
  /*#__PURE__*/ _jsx(Stack, {
137
139
  direction: "row",
138
140
  spacing: 1,
139
- children: /*#__PURE__*/ _jsx(TextField, {
140
- label: "Discount %",
141
- value: props.discountPct || '',
142
- onChange: (event)=>props.onDiscountPct(Math.min(100, Math.max(0, Number(event.target.value) || 0))),
143
- disabled: locked,
144
- sx: {
145
- width: 120
146
- },
147
- slotProps: {
148
- htmlInput: {
149
- inputMode: 'numeric'
141
+ children: /*#__PURE__*/ _jsx(BlockedControl, {
142
+ blocked: Boolean(props.discountBlocked),
143
+ reason: (_props_discountBlocked = props.discountBlocked) != null ? _props_discountBlocked : '',
144
+ children: /*#__PURE__*/ _jsx(TextField, {
145
+ label: "Discount %",
146
+ value: props.discountPct || '',
147
+ onChange: (event)=>props.onDiscountPct(Math.min(100, Math.max(0, Number(event.target.value) || 0))),
148
+ disabled: locked,
149
+ sx: {
150
+ width: 120
151
+ },
152
+ slotProps: {
153
+ htmlInput: {
154
+ inputMode: 'numeric'
155
+ }
150
156
  }
151
- }
157
+ })
152
158
  })
153
159
  }),
154
160
  props.customer
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../../../libs/plugins/commerce/src/lib/components/console/pos/pos-cart-panel.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'use client'\n\nimport type { ReactNode } from 'react'\nimport { Box, Button, ButtonBase, IconButton, Stack, TextField, Typography } from '@mui/material'\nimport type { ModifierSelection, StockShortfall } from '../../../model'\nimport { POS_TOUCH_PX } from './pos-product-grid.component'\nimport { usd } from './pos-api'\n\nexport interface RegisterLine {\n productId: string\n variantId?: string\n name: string\n variantLabel?: string\n /** Per unit, modifiers included: the register's estimate until the server prices it. */\n unitAmountCents: number\n quantity: number\n /** The modifier options picked (AGL-3607); the server prices them. */\n modifiers?: ModifierSelection[]\n}\n\nexport interface PosCartPanelProps {\n lines: RegisterLine[]\n shortfalls: Array<Pick<StockShortfall, 'available'> | null>\n onQuantity: (index: number, quantity: number) => void\n onRemove: (index: number) => void\n /** Opens the line in the item sheet to change its options or quantity. */\n onEdit?: (index: number) => void\n discountPct: number\n onDiscountPct: (value: number) => void\n /** The register's customer lookup (AGL-3609), under the discount. */\n customer?: ReactNode\n /** Lines can no longer change: a sale is open against them. */\n locked: boolean\n}\n\n/**\n * The basket (AGL-3607): lines with large quantity steppers, the stock\n * warning under any line the shelf cannot cover (AGL-2357, said and never\n * enforced), the cashier's discount and the customer the sale is for.\n */\nexport function PosCartPanel(props: PosCartPanelProps) {\n const { lines, locked } = props\n return (\n <Stack spacing={1} sx={{ minHeight: 0 }}>\n <Box sx={{ overflowY: 'auto', flex: 1 }}>\n {lines.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Tap products to add them.'}\n </Typography>\n ) : (\n lines.map((line, index) => (\n <Box key={`${line.productId}:${line.variantId ?? ''}:${index}`} sx={{ py: 0.5 }}>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <ButtonBase\n disabled={locked || !props.onEdit}\n onClick={() => props.onEdit?.(index)}\n aria-label={locked ? undefined : `Change ${line.name}`}\n sx={{\n flex: 1,\n minWidth: 0,\n minHeight: POS_TOUCH_PX,\n justifyContent: 'flex-start',\n textAlign: 'left',\n borderRadius: 1,\n }}\n >\n <Box sx={{ minWidth: 0 }}>\n <Typography variant=\"body2\" noWrap>\n {`${line.quantity}× ${line.name}`}\n </Typography>\n {line.variantLabel ? (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"p\" noWrap>\n {line.variantLabel}\n </Typography>\n ) : null}\n </Box>\n </ButtonBase>\n {!locked ? (\n <>\n <IconButton\n aria-label={`One fewer ${line.name}`}\n onClick={() => props.onQuantity(index, line.quantity - 1)}\n sx={{ width: POS_TOUCH_PX, height: POS_TOUCH_PX }}\n >\n {'−'}\n </IconButton>\n <IconButton\n aria-label={`One more ${line.name}`}\n onClick={() => props.onQuantity(index, line.quantity + 1)}\n sx={{ width: POS_TOUCH_PX, height: POS_TOUCH_PX }}\n >\n {'+'}\n </IconButton>\n </>\n ) : null}\n <Typography variant=\"body2\">{usd(line.unitAmountCents * line.quantity)}</Typography>\n {!locked ? (\n <Button\n color=\"error\"\n onClick={() => props.onRemove(index)}\n aria-label={`Remove ${line.name}`}\n sx={{ minWidth: POS_TOUCH_PX, minHeight: POS_TOUCH_PX }}\n >\n {'✕'}\n </Button>\n ) : null}\n </Stack>\n {props.shortfalls[index] ? (\n <Typography variant=\"caption\" color=\"warning.main\">\n {`Only ${props.shortfalls[index]?.available} in stock — selling ${line.quantity}`}\n </Typography>\n ) : null}\n </Box>\n ))\n )}\n </Box>\n <Stack direction=\"row\" spacing={1}>\n <TextField\n label=\"Discount %\"\n value={props.discountPct || ''}\n onChange={(event) =>\n props.onDiscountPct(Math.min(100, Math.max(0, Number(event.target.value) || 0)))\n }\n disabled={locked}\n sx={{ width: 120 }}\n slotProps={{ htmlInput: { inputMode: 'numeric' } }}\n />\n </Stack>\n {props.customer}\n </Stack>\n )\n}\nPosCartPanel.displayName = 'PosCartPanel'\n"],"names":["Box","Button","ButtonBase","IconButton","Stack","TextField","Typography","POS_TOUCH_PX","usd","PosCartPanel","props","lines","locked","spacing","sx","minHeight","overflowY","flex","length","variant","color","map","line","index","py","direction","alignItems","disabled","onEdit","onClick","aria-label","undefined","name","minWidth","justifyContent","textAlign","borderRadius","noWrap","quantity","variantLabel","component","onQuantity","width","height","unitAmountCents","onRemove","shortfalls","available","productId","variantId","label","value","discountPct","onChange","event","onDiscountPct","Math","min","max","Number","target","slotProps","htmlInput","inputMode","customer","displayName"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../../../libs/plugins/commerce/src/lib/components/console/pos/pos-cart-panel.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'use client'\n\nimport { BlockedControl } from '@aglyn/shared-ui-jsx/components/blocked-control.component'\nimport type { ReactNode } from 'react'\nimport { Box, Button, ButtonBase, IconButton, Stack, TextField, Typography } from '@mui/material'\nimport type { ModifierSelection, StockShortfall } from '../../../model'\nimport { POS_TOUCH_PX } from './pos-product-grid.component'\nimport { usd } from './pos-api'\n\nexport interface RegisterLine {\n productId: string\n variantId?: string\n name: string\n variantLabel?: string\n /** Per unit, modifiers included: the register's estimate until the server prices it. */\n unitAmountCents: number\n quantity: number\n /** The modifier options picked (AGL-3607); the server prices them. */\n modifiers?: ModifierSelection[]\n}\n\nexport interface PosCartPanelProps {\n lines: RegisterLine[]\n shortfalls: Array<Pick<StockShortfall, 'available'> | null>\n onQuantity: (index: number, quantity: number) => void\n onRemove: (index: number) => void\n /** Opens the line in the item sheet to change its options or quantity. */\n onEdit?: (index: number) => void\n discountPct: number\n onDiscountPct: (value: number) => void\n /** The register's customer lookup (AGL-3609), under the discount. */\n customer?: ReactNode\n /** Lines can no longer change: a sale is open against them. */\n locked: boolean\n /**\n * Why this member may not give a discount (AGL-4047): the \"Give discounts\n * at the register\" key refused. The field stays, disabled with the reason.\n */\n discountBlocked?: string\n}\n\n/**\n * The basket (AGL-3607): lines with large quantity steppers, the stock\n * warning under any line the shelf cannot cover (AGL-2357, said and never\n * enforced), the cashier's discount and the customer the sale is for.\n */\nexport function PosCartPanel(props: PosCartPanelProps) {\n const { lines, locked } = props\n return (\n <Stack spacing={1} sx={{ minHeight: 0 }}>\n <Box sx={{ overflowY: 'auto', flex: 1 }}>\n {lines.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Tap products to add them.'}\n </Typography>\n ) : (\n lines.map((line, index) => (\n <Box key={`${line.productId}:${line.variantId ?? ''}:${index}`} sx={{ py: 0.5 }}>\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <ButtonBase\n disabled={locked || !props.onEdit}\n onClick={() => props.onEdit?.(index)}\n aria-label={locked ? undefined : `Change ${line.name}`}\n sx={{\n flex: 1,\n minWidth: 0,\n minHeight: POS_TOUCH_PX,\n justifyContent: 'flex-start',\n textAlign: 'left',\n borderRadius: 1,\n }}\n >\n <Box sx={{ minWidth: 0 }}>\n <Typography variant=\"body2\" noWrap>\n {`${line.quantity}× ${line.name}`}\n </Typography>\n {line.variantLabel ? (\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"p\" noWrap>\n {line.variantLabel}\n </Typography>\n ) : null}\n </Box>\n </ButtonBase>\n {!locked ? (\n <>\n <IconButton\n aria-label={`One fewer ${line.name}`}\n onClick={() => props.onQuantity(index, line.quantity - 1)}\n sx={{ width: POS_TOUCH_PX, height: POS_TOUCH_PX }}\n >\n {'−'}\n </IconButton>\n <IconButton\n aria-label={`One more ${line.name}`}\n onClick={() => props.onQuantity(index, line.quantity + 1)}\n sx={{ width: POS_TOUCH_PX, height: POS_TOUCH_PX }}\n >\n {'+'}\n </IconButton>\n </>\n ) : null}\n <Typography variant=\"body2\">{usd(line.unitAmountCents * line.quantity)}</Typography>\n {!locked ? (\n <Button\n color=\"error\"\n onClick={() => props.onRemove(index)}\n aria-label={`Remove ${line.name}`}\n sx={{ minWidth: POS_TOUCH_PX, minHeight: POS_TOUCH_PX }}\n >\n {'✕'}\n </Button>\n ) : null}\n </Stack>\n {props.shortfalls[index] ? (\n <Typography variant=\"caption\" color=\"warning.main\">\n {`Only ${props.shortfalls[index]?.available} in stock — selling ${line.quantity}`}\n </Typography>\n ) : null}\n </Box>\n ))\n )}\n </Box>\n <Stack direction=\"row\" spacing={1}>\n <BlockedControl blocked={Boolean(props.discountBlocked)} reason={props.discountBlocked ?? ''}>\n <TextField\n label=\"Discount %\"\n value={props.discountPct || ''}\n onChange={(event) =>\n props.onDiscountPct(Math.min(100, Math.max(0, Number(event.target.value) || 0)))\n }\n disabled={locked}\n sx={{ width: 120 }}\n slotProps={{ htmlInput: { inputMode: 'numeric' } }}\n />\n </BlockedControl>\n </Stack>\n {props.customer}\n </Stack>\n )\n}\nPosCartPanel.displayName = 'PosCartPanel'\n"],"names":["BlockedControl","Box","Button","ButtonBase","IconButton","Stack","TextField","Typography","POS_TOUCH_PX","usd","PosCartPanel","props","lines","locked","spacing","sx","minHeight","overflowY","flex","length","variant","color","map","line","index","py","direction","alignItems","disabled","onEdit","onClick","aria-label","undefined","name","minWidth","justifyContent","textAlign","borderRadius","noWrap","quantity","variantLabel","component","onQuantity","width","height","unitAmountCents","onRemove","shortfalls","available","productId","variantId","blocked","Boolean","discountBlocked","reason","label","value","discountPct","onChange","event","onDiscountPct","Math","min","max","Number","target","slotProps","htmlInput","inputMode","customer","displayName"],"mappings":"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"}
@@ -15,12 +15,22 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  import { authorizedFetch } from '@aglyn/shared-util-http/authorized-token';
18
- import type { PosHardwareLine, PosHardwareOffer, PosHardwareOrderStatus, PosHardwareShippingMethod, PosHardwareTracking } from '../../../model/pos-hardware';
18
+ import type { PosHardwareAttachment, PosHardwareLine, PosHardwareOffer, PosHardwareOrderShippingMethod, PosHardwareOrderSource, PosHardwareOrderStatus, PosHardwarePaidTo, PosHardwareRefund, PosHardwareRegisterSale, PosHardwareReturnRequest, PosHardwareShippingMethod, PosHardwareTracking, PosHardwareUnit } from '../../../model/pos-hardware';
19
19
  type User = Parameters<typeof authorizedFetch>[0];
20
20
  export declare class PosHardwareRequestError extends Error {
21
21
  readonly status: number;
22
- constructor(message: string, status: number);
22
+ /** The route's `reason`, when it names a step the caller takes next. */
23
+ readonly reason?: string;
24
+ constructor(message: string, status: number,
25
+ /** The route's `reason`, when it names a step the caller takes next. */
26
+ reason?: string);
23
27
  }
28
+ /** One request to a hardware route, refused with the route's own words. */
29
+ export declare function sendPosHardwareRequest<T>(user: User, url: string, init: {
30
+ method: 'GET' | 'POST';
31
+ body?: unknown;
32
+ attemptKey?: string;
33
+ }): Promise<T>;
24
34
  export type PosHardwareCatalog = {
25
35
  available: false;
26
36
  } | {
@@ -48,6 +58,16 @@ export interface PosHardwareOrderRow {
48
58
  tracking: PosHardwareTracking | null;
49
59
  createdAtMs: number;
50
60
  updatedAtMs: number;
61
+ /** Bought in person at the platform's own store (AGL-4038), and its readers still to set up. */
62
+ source?: PosHardwareOrderSource;
63
+ discountCents?: number;
64
+ readersToSetUp?: number;
65
+ refundedCents?: number;
66
+ returnRequest?: {
67
+ state: PosHardwareReturnRequest['state'];
68
+ requestedAtMs: number;
69
+ note: string | null;
70
+ } | null;
51
71
  }
52
72
  /** Leaves the console for Stripe Checkout, which returns to the card. */
53
73
  export declare function openPosHardwareCheckout(url: string): void;
@@ -66,13 +86,40 @@ export declare function posHardwareCheckout(user: User, attemptKey: string, body
66
86
  url: string;
67
87
  orderId: string;
68
88
  }>;
89
+ /** A reader the workspace bought in person, waiting to be set up (AGL-4038). */
90
+ export interface WaitingReaderOrder extends PosHardwareOrderRow {
91
+ /** The store it is for; empty while the buyer has still to choose. */
92
+ hostId: string;
93
+ /** Readers whose serial was taken at the sale: they set themselves up. */
94
+ serialsTaken: number;
95
+ }
96
+ export interface WaitingReaders {
97
+ posPlan: boolean;
98
+ stores: Array<{
99
+ hostId: string;
100
+ name: string;
101
+ hasLocation: boolean;
102
+ setupUrl: string;
103
+ }>;
104
+ orders: WaitingReaderOrder[];
105
+ }
106
+ export declare function posHardwareWaiting(user: User, hostId: string): Promise<WaitingReaders>;
107
+ /** Chooses the store (`hostId`) a reader bought in person is for. */
108
+ export declare function posHardwareChooseStore(user: User, hostId: string, orderId: string): Promise<{
109
+ ok: true;
110
+ order: PosHardwareOrderRow;
111
+ }>;
112
+ export declare function posHardwareMarkSetUp(user: User, hostId: string, orderId: string): Promise<{
113
+ ok: true;
114
+ order: PosHardwareOrderRow;
115
+ }>;
69
116
  /** An order as the staff page lists it. */
70
117
  export interface StaffHardwareOrderRow extends Omit<PosHardwareOrderRow, 'shippingCents' | 'shippingLabel'> {
71
118
  orgId: string;
72
119
  hostId: string;
73
120
  contactEmail: string | null;
74
121
  shipping: {
75
- method: PosHardwareShippingMethod;
122
+ method: PosHardwareOrderShippingMethod;
76
123
  label: string;
77
124
  cents: number;
78
125
  name: string | null;
@@ -97,15 +144,30 @@ export interface StaffHardwareOrderRow extends Omit<PosHardwareOrderRow, 'shippi
97
144
  stripeHardwareOrderId: string | null;
98
145
  livemode: boolean;
99
146
  refundPending: boolean;
147
+ /** Sold in person at the platform's own store (AGL-4038), and what that sale says. */
148
+ source: PosHardwareOrderSource;
149
+ discountCents: number;
150
+ posSale: PosHardwareRegisterSale | null;
151
+ paidTo: PosHardwarePaidTo | null;
152
+ attachment: PosHardwareAttachment | null;
153
+ units: PosHardwareUnit[];
154
+ refundedCents: number;
155
+ refunds: PosHardwareRefund[];
156
+ returnRequest: PosHardwareReturnRequest | null;
100
157
  }
101
- export declare function staffHardwareOrders(user: User, status: PosHardwareOrderStatus | '', after?: string | null): Promise<{
158
+ /** The staff list's filter: one status, every order, or the in-person sales still to attach. */
159
+ export type StaffHardwareFilter = PosHardwareOrderStatus | '' | 'to-attach' | 'returns';
160
+ export declare function staffHardwareOrders(user: User, filter: StaffHardwareFilter, after?: string | null): Promise<{
102
161
  orders: StaffHardwareOrderRow[];
103
162
  next: string | null;
104
163
  pageSize: number;
105
164
  canWrite: boolean;
106
165
  }>;
107
166
  export declare function staffHardwareOrderAction(user: User, body: {
108
- action: 'update' | 'cancel' | 'refund';
167
+ action: 'update' | 'cancel' | 'refund' | 'refund-return' | 'forget-buyer' | 'decline-return';
168
+ /** An online return's restocking fee, in cents (AGL-4038). */
169
+ restockingFeeCents?: number;
170
+ note?: string;
109
171
  orgId: string;
110
172
  orderId: string;
111
173
  stripeHardwareOrderId?: string | null;
@@ -115,8 +177,17 @@ export declare function staffHardwareOrderAction(user: User, body: {
115
177
  url?: string;
116
178
  } | null;
117
179
  status?: PosHardwareOrderStatus;
180
+ /** A cancel or a refund: email the buyer about it (AGL-4038). */
181
+ notifyBuyer?: boolean;
118
182
  }): Promise<{
119
183
  ok: true;
120
184
  order: StaffHardwareOrderRow;
185
+ /** A cancel or a refund: what became of the buyer's email, `off` when staff chose none. */
186
+ buyerEmail?: "sent" | "already" | "skipped" | "failed" | "off";
187
+ }>;
188
+ /** Asks to return a card reader bought in person, with the reason (AGL-4038). */
189
+ export declare function posHardwareRequestReturn(user: User, hostId: string, orderId: string, reason: string): Promise<{
190
+ ok: true;
191
+ order: PosHardwareOrderRow;
121
192
  }>;
122
193
  export {};