@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/register-hardware-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 * as CommerceModel from '../../model'\nimport { CardDisplay, useConfirmationContext } from '@aglyn/shared-ui-jsx'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport { pluginDocsHelp } from '@aglyn/aglyn'\nimport {\n Alert,\n Autocomplete,\n Box,\n Button,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Divider,\n FormControlLabel,\n MenuItem,\n Stack,\n Switch,\n TextField,\n Typography,\n} from '@mui/material'\nimport { collection, limit, orderBy, query, where } from 'firebase/firestore'\nimport { useCallback, useEffect, useState } from 'react'\nimport {\n useFirestore,\n useFirestoreCollection,\n useUser,\n} from '@aglyn/tenant-feature-instance'\n\n/**\n * The Hardware card for one register (AGL-3619): the cloud receipt printers\n * paired with it, with their live status and recent jobs, and the way to add\n * one — brand, model, MAC or ID — and get the URL to paste into the printer;\n * then, read-only, the card readers and customer displays the register uses.\n *\n * Every write goes through `/api/commerce/printers`: the printer documents\n * and the queue are server-written, so this card only reads Firestore.\n */\n\ntype PrinterRow = CommerceModel.PosPrinter & { $id: string }\ntype JobRow = CommerceModel.PrintJob & { $id: string }\n\nconst STATE_COLOR: Record<string, 'success' | 'warning' | 'error' | 'default'> =\n {\n online: 'success',\n paper_low: 'warning',\n paper_out: 'error',\n cover_open: 'error',\n error: 'error',\n offline: 'default',\n unknown: 'default',\n }\n\nconst JOB_LABELS: Record<CommerceModel.PrintJobKind, string> = {\n receipt: 'Receipt',\n kitchen: 'Kitchen ticket',\n drawer: 'Open drawer',\n test: 'Test print',\n report: 'Shift report',\n}\n\n/** \"just now\", \"3 min ago\", \"2 h ago\". */\nexport function seenAgo(atMs: number | undefined, nowMs: number): string {\n if (!atMs) return 'never'\n const seconds = Math.max(0, Math.round((nowMs - atMs) / 1000))\n if (seconds < 45) return 'just now'\n const minutes = Math.round(seconds / 60)\n if (minutes < 60) return `${minutes} min ago`\n const hours = Math.round(minutes / 60)\n if (hours < 48) return `${hours} h ago`\n return `${Math.round(hours / 24)} days ago`\n}\n\nfunction useNow(intervalMs: number): number {\n const [now, setNow] = useState(() => Date.now())\n useEffect(() => {\n const id = setInterval(() => setNow(Date.now()), intervalMs)\n return () => clearInterval(id)\n }, [intervalMs])\n return now\n}\n\nfunction usePrintersApi(hostId: string) {\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n return useCallback(\n async (\n body: Record<string, unknown>,\n ): Promise<Record<string, any> | null> => {\n try {\n const response = await authorizedFetch(user, '/api/commerce/printers', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ hostId, ...body }),\n })\n const payload = await response.json().catch(() => ({}))\n if (!response.ok) {\n enqueueSnackbar(\n payload?.error ?? 'The printer could not be updated',\n {\n variant: 'warning',\n persist: false,\n },\n )\n return null\n }\n return payload\n } catch {\n enqueueSnackbar(\n 'The printer could not be reached. Check your connection.',\n {\n variant: 'warning',\n persist: false,\n },\n )\n return null\n }\n },\n [user, hostId, enqueueSnackbar],\n )\n}\n\n/** Where each brand's poll URL goes, step by step. */\nexport function printerSetupSteps(brand: CommerceModel.PrinterBrand): string[] {\n return brand === 'star'\n ? [\n 'Open the printer’s web page: print a self-test (hold FEED while switching on) to find its IP address, then browse to it and sign in (default user root, password public, or the password on the printer’s label).',\n 'Go to Settings → CloudPRNT. Turn CloudPRNT on and paste the URL below as the Server URL.',\n 'Set the polling interval to 5 seconds, then Submit and Save → Restart device.',\n 'Come back here: the printer shows Online within a minute. Send a test print.',\n ]\n : [\n 'Open EPSON TMNet WebConfig: browse to the printer’s IP address (print a status sheet by holding FEED while switching on).',\n 'Open Server Direct Print (under Web Service Settings on most models). Select Enable and enter the ID below.',\n 'Paste the URL below as Server 1 URL and set the interval to 5 seconds. Submit, then reset the printer.',\n 'Come back here: the printer shows Online within a minute. Send a test print.',\n ]\n}\n\ninterface PrinterFormState {\n brand: CommerceModel.PrinterBrand\n name: string\n model: string\n deviceId: string\n paperWidthMm: CommerceModel.PrinterPaperWidth\n autoPrintReceipts: boolean\n kickDrawer: boolean\n kitchenTickets: boolean\n logoKey: string\n}\n\nconst EMPTY_FORM: PrinterFormState = {\n brand: 'star',\n name: '',\n model: '',\n deviceId: '',\n paperWidthMm: 80,\n autoPrintReceipts: true,\n kickDrawer: true,\n kitchenTickets: false,\n logoKey: '',\n}\n\nfunction PrinterForm(props: {\n value: PrinterFormState\n onChange: (next: PrinterFormState) => void\n brandLocked?: boolean\n}) {\n const { value, onChange, brandLocked } = props\n const set = <K extends keyof PrinterFormState>(\n key: K,\n next: PrinterFormState[K],\n ) => onChange({ ...value, [key]: next })\n return (\n <Stack spacing={2} sx={{ pt: 1 }}>\n <TextField\n select\n label=\"Brand\"\n value={value.brand}\n disabled={brandLocked}\n onChange={(event) =>\n set('brand', event.target.value as CommerceModel.PrinterBrand)\n }\n >\n {CommerceModel.PRINTER_BRANDS.map((brand) => (\n <MenuItem key={brand} value={brand}>\n {CommerceModel.PRINTER_BRAND_LABELS[brand]}\n </MenuItem>\n ))}\n </TextField>\n <Autocomplete\n freeSolo\n options={[...CommerceModel.PRINTER_MODEL_SUGGESTIONS[value.brand]]}\n value={value.model}\n onInputChange={(_event, next) => set('model', next)}\n renderInput={(params) => <TextField {...params} label=\"Model\" />}\n />\n <TextField\n label=\"Name\"\n value={value.name}\n placeholder=\"Counter printer\"\n onChange={(event) => set('name', event.target.value)}\n />\n <TextField\n label={\n value.brand === 'star' ? 'MAC address' : 'Server Direct Print ID'\n }\n value={value.deviceId}\n placeholder={value.brand === 'star' ? '00:11:62:12:34:56' : 'counter-1'}\n helperText={\n value.brand === 'star'\n ? 'The Ethernet MAC on the self-test print, even if the printer uses Wi-Fi.'\n : 'Any ID you choose (letters, digits, - _ .), entered again in WebConfig.'\n }\n onChange={(event) => set('deviceId', event.target.value)}\n />\n <TextField\n select\n label=\"Paper\"\n value={value.paperWidthMm}\n onChange={(event) =>\n set('paperWidthMm', Number(event.target.value) === 58 ? 58 : 80)\n }\n >\n <MenuItem value={80}>{'80 mm (3 1/8 in)'}</MenuItem>\n <MenuItem value={58}>{'58 mm (2 1/4 in)'}</MenuItem>\n </TextField>\n <TextField\n label=\"Stored logo (optional)\"\n value={value.logoKey}\n placeholder={value.brand === 'star' ? '1' : '48,48'}\n helperText={\n value.brand === 'star'\n ? 'The logo number saved in the printer with Star Quick Setup Utility.'\n : 'The key saved in the printer with Epson TM Utility, as two numbers.'\n }\n onChange={(event) => set('logoKey', event.target.value)}\n />\n <FormControlLabel\n control={\n <Switch\n checked={value.autoPrintReceipts}\n onChange={(event) => set('autoPrintReceipts', event.target.checked)}\n />\n }\n label=\"Print a receipt for every sale on this register\"\n />\n <FormControlLabel\n control={\n <Switch\n checked={value.kickDrawer}\n onChange={(event) => set('kickDrawer', event.target.checked)}\n />\n }\n label=\"A cash drawer is plugged into this printer\"\n />\n <FormControlLabel\n control={\n <Switch\n checked={value.kitchenTickets}\n onChange={(event) => set('kitchenTickets', event.target.checked)}\n />\n }\n label=\"Print a kitchen ticket for every sale (items and quantities, no prices)\"\n />\n </Stack>\n )\n}\n\nfunction PollUrlPanel(props: {\n credentials: {\n brand: CommerceModel.PrinterBrand\n pollUrl: string\n deviceId: string\n }\n}) {\n const { credentials } = props\n const { enqueueSnackbar } = useSnackbar()\n const copy = async () => {\n try {\n await navigator.clipboard.writeText(credentials.pollUrl)\n enqueueSnackbar('Copied', { variant: 'success', persist: false })\n } catch {\n enqueueSnackbar('Select the URL and copy it', {\n variant: 'info',\n persist: false,\n })\n }\n }\n return (\n <Stack spacing={1.5}>\n <Alert severity=\"info\">\n {'This URL is the printer’s password: anyone with it can collect this register’s receipts. ' +\n 'Regenerate it if it is ever shared.'}\n </Alert>\n <TextField\n label={\n credentials.brand === 'star'\n ? 'CloudPRNT Server URL'\n : 'Server Direct Print URL'\n }\n value={credentials.pollUrl}\n multiline\n slotProps={{ htmlInput: { readOnly: true } }}\n />\n {credentials.brand === 'epson' ? (\n <TextField\n label=\"ID\"\n value={credentials.deviceId}\n slotProps={{ htmlInput: { readOnly: true } }}\n />\n ) : null}\n <Box>\n <Button size=\"small\" onClick={copy}>\n {'Copy URL'}\n </Button>\n </Box>\n <Box component=\"ol\" sx={{ pl: 2.5, m: 0 }}>\n {printerSetupSteps(credentials.brand).map((step) => (\n <Typography\n component=\"li\"\n variant=\"body2\"\n key={step}\n sx={{ mb: 0.5 }}\n >\n {step}\n </Typography>\n ))}\n </Box>\n </Stack>\n )\n}\n\nfunction PrinterRowView(props: {\n printer: PrinterRow\n now: number\n call: ReturnType<typeof usePrintersApi>\n onSettings: (printer: PrinterRow) => void\n}) {\n const { printer, now, call, onSettings } = props\n const { enqueueSnackbar } = useSnackbar()\n const { confirm } = useConfirmationContext()\n const state = CommerceModel.printerDisplayState(printer.status, now)\n const label =\n state === 'offline' ? 'Offline' : CommerceModel.PRINTER_STATE_LABELS[state]\n const send = async (action: 'test' | 'drawer') => {\n const result = await call({ action, printerId: printer.$id })\n if (result) {\n enqueueSnackbar(\n action === 'test' ? 'Test print sent' : 'Drawer kick sent',\n {\n variant: 'success',\n persist: false,\n },\n )\n }\n }\n const remove = async () => {\n const confirmed = await confirm({\n title: `Remove ${printer.name}?`,\n description:\n 'Its URL stops working and anything it has not printed is canceled.',\n confirmationText: 'Remove',\n confirmationButtonProps: { color: 'error' },\n })\n .then(() => true)\n .catch(() => false)\n if (confirmed) await call({ action: 'remove', printerId: printer.$id })\n }\n return (\n <Stack spacing={0.5}>\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center', flexWrap: 'wrap', rowGap: 1 }}\n >\n <Typography\n variant=\"body2\"\n sx={{ flex: '1 1 160px', minWidth: 0 }}\n noWrap\n >\n {printer.name}\n <Typography component=\"span\" variant=\"caption\" color=\"text.secondary\">\n {` · ${printer.brand === 'star' ? 'Star' : 'Epson'}${printer.model ? ` ${printer.model}` : ''}`}\n </Typography>\n </Typography>\n <Chip\n size=\"small\"\n variant=\"outlined\"\n color={STATE_COLOR[state]}\n label={label}\n />\n <Button size=\"small\" onClick={() => send('test')}>\n {'Test print'}\n </Button>\n {printer.kickDrawer ? (\n <Button size=\"small\" onClick={() => send('drawer')}>\n {'Open drawer'}\n </Button>\n ) : null}\n <Button size=\"small\" onClick={() => onSettings(printer)}>\n {'Settings'}\n </Button>\n <Button size=\"small\" color=\"error\" onClick={remove}>\n {'Remove'}\n </Button>\n </Stack>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {printer.status?.atMs\n ? `Last seen ${seenAgo(printer.status.atMs, now)}${printer.status.detail ? ` · ${printer.status.detail}` : ''}`\n : 'Waiting for the printer to poll — paste its URL into the printer to finish.'}\n {printer.autoPrintReceipts ? ' · Prints every sale' : ''}\n {printer.kickDrawer ? ' · Cash drawer' : ''}\n {printer.kitchenTickets ? ' · Kitchen tickets' : ''}\n </Typography>\n </Stack>\n )\n}\n\nexport interface RegisterHardwareCardProps {\n hostId: string\n registerId: string\n registerName: string\n}\n\ntype ReaderRow = {\n $id: string\n label?: string\n deviceType?: string\n status?: string\n registerId?: string\n}\ntype DisplayRow = { id: string; label: string; lastSeenAtMs: number }\n\n/** A customer display that polled within this long is shown as connected. */\nconst DISPLAY_CONNECTED_MS = 120_000\n\n/**\n * The register's other devices, read-only: the Stripe Terminal card readers\n * assigned to it and the customer displays paired with it. Each is added and\n * removed where it is set up; this list is the one place a manager sees\n * everything plugged into the till. Nothing renders when there are none.\n */\nexport function RegisterOtherDevices(props: {\n hostId: string\n registerId: string\n now: number\n}) {\n const { hostId, registerId, now } = props\n const firestore = useFirestore()\n const { data: user } = useUser()\n const { data: readerDocs } = useFirestoreCollection<ReaderRow>(\n () =>\n query(\n collection(firestore, 'hosts', hostId, 'terminalReaders'),\n where('registerId', '==', registerId),\n limit(10),\n ),\n [firestore, hostId, registerId],\n { idField: '$id' },\n )\n const [displays, setDisplays] = useState<DisplayRow[]>([])\n useEffect(() => {\n if (!user) return\n let live = true\n void (async () => {\n try {\n const response = await authorizedFetch(user as any, '/api/commerce/pos-display', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ hostId, registerId, action: 'displays' }),\n })\n if (!response.ok) return\n const answer = (await response.json().catch(() => ({}))) as { displays?: DisplayRow[] }\n if (live) setDisplays(Array.isArray(answer.displays) ? answer.displays : [])\n } catch {\n // Offline: the list stays as it was; the printers above still show.\n }\n })()\n return () => {\n live = false\n }\n }, [user, hostId, registerId])\n const readers = readerDocs ?? []\n if (!readers.length && !displays.length) return null\n return (\n <>\n <Divider />\n <Typography variant=\"subtitle2\">{'Card readers and customer displays'}</Typography>\n {readers.map((reader) => (\n <Stack key={reader.$id} direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Typography variant=\"body2\" sx={{ flex: 1, minWidth: 0 }} noWrap>\n {reader.label || 'Card reader'}\n <Typography component=\"span\" variant=\"caption\" color=\"text.secondary\">\n {` · Card reader${reader.deviceType ? ` · ${reader.deviceType}` : ''}`}\n </Typography>\n </Typography>\n <Chip\n size=\"small\"\n variant=\"outlined\"\n color={reader.status === 'online' ? 'success' : 'default'}\n label={reader.status === 'online' ? 'Online' : 'Offline'}\n />\n </Stack>\n ))}\n {displays.map((display) => {\n const connected = now - display.lastSeenAtMs < DISPLAY_CONNECTED_MS\n return (\n <Stack key={display.id} direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Typography variant=\"body2\" sx={{ flex: 1, minWidth: 0 }} noWrap>\n {display.label || 'Customer display'}\n <Typography component=\"span\" variant=\"caption\" color=\"text.secondary\">\n {` · Customer display · seen ${seenAgo(display.lastSeenAtMs, now)}`}\n </Typography>\n </Typography>\n <Chip\n size=\"small\"\n variant=\"outlined\"\n color={connected ? 'success' : 'default'}\n label={connected ? 'Connected' : 'Offline'}\n />\n </Stack>\n )\n })}\n </>\n )\n}\nRegisterOtherDevices.displayName = 'RegisterOtherDevices'\n\nexport function RegisterHardwareCard(props: RegisterHardwareCardProps) {\n const { hostId, registerId, registerName } = props\n const firestore = useFirestore()\n const call = usePrintersApi(hostId)\n const now = useNow(15_000)\n const { data: printerDocs } = useFirestoreCollection<PrinterRow>(\n () =>\n query(\n collection(firestore, 'hosts', hostId, 'printers'),\n where('registerId', '==', registerId),\n limit(4),\n ),\n [firestore, hostId, registerId],\n { idField: '$id' },\n )\n const { data: jobDocs } = useFirestoreCollection<JobRow>(\n () =>\n query(\n collection(firestore, 'hosts', hostId, 'printJobs'),\n where('registerId', '==', registerId),\n orderBy('createdAtMs', 'desc'),\n limit(6),\n ),\n [firestore, hostId, registerId],\n { idField: '$id' },\n )\n const printers = [...(printerDocs ?? [])].sort(\n (a, b) => a.createdAtMs - b.createdAtMs,\n )\n const jobs = jobDocs ?? []\n\n const [adding, setAdding] = useState(false)\n const [form, setForm] = useState<PrinterFormState>(EMPTY_FORM)\n const [editing, setEditing] = useState<PrinterRow | null>(null)\n const [credentials, setCredentials] = useState<{\n brand: CommerceModel.PrinterBrand\n pollUrl: string\n deviceId: string\n } | null>(null)\n const [busy, setBusy] = useState(false)\n\n const openAdd = () => {\n setForm(EMPTY_FORM)\n setCredentials(null)\n setAdding(true)\n }\n const create = async () => {\n setBusy(true)\n const created = await call({ action: 'create', registerId, ...form })\n setBusy(false)\n if (created) setCredentials(created as any)\n }\n const openSettings = async (printer: PrinterRow) => {\n setEditing(printer)\n setForm({\n brand: printer.brand,\n name: printer.name,\n model: printer.model ?? '',\n deviceId: printer.deviceId,\n paperWidthMm: printer.paperWidthMm ?? 80,\n autoPrintReceipts: printer.autoPrintReceipts,\n kickDrawer: printer.kickDrawer,\n kitchenTickets: Boolean(printer.kitchenTickets),\n logoKey: printer.logoKey ?? '',\n })\n setCredentials(null)\n const shown = await call({ action: 'credentials', printerId: printer.$id })\n if (shown) setCredentials(shown as any)\n }\n const save = async () => {\n if (!editing) return\n setBusy(true)\n const { brand: _brand, ...settings } = form\n const saved = await call({\n action: 'update',\n printerId: editing.$id,\n ...settings,\n })\n setBusy(false)\n if (saved) setEditing(null)\n }\n const regenerate = async () => {\n if (!editing) return\n const next = await call({ action: 'regenerate', printerId: editing.$id })\n if (next) setCredentials(next as any)\n }\n const cancelJob = (job: JobRow) => () =>\n void call({ action: 'cancel', jobId: job.$id })\n const printerName = (id: string) =>\n printers.find((printer) => printer.$id === id)?.name ?? 'Removed printer'\n\n return (\n <CardDisplay\n header={`Hardware · ${registerName}`}\n help={pluginDocsHelp('posHardware', { anchor: '#receipt-printers' })}\n HeaderProps={{\n action: (\n <Button\n size=\"small\"\n onClick={openAdd}\n disabled={printers.length >= 4}\n >\n {'Add printer'}\n </Button>\n ),\n }}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={1.5}>\n <Typography variant=\"subtitle2\">{'Receipt printers'}</Typography>\n {printers.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Pair a Star CloudPRNT or Epson Server Direct Print printer to print receipts from this register ' +\n 'on any device, with no driver, and to open its cash drawer on cash sales.'}\n </Typography>\n ) : (\n printers.map((printer) => (\n <PrinterRowView\n key={printer.$id}\n printer={printer}\n now={now}\n call={call}\n onSettings={openSettings}\n />\n ))\n )}\n {jobs.length ? (\n <>\n <Divider />\n <Typography variant=\"subtitle2\">{'Recent print jobs'}</Typography>\n {jobs.map((job) => (\n <Stack\n key={job.$id}\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center' }}\n >\n <Typography\n variant=\"body2\"\n sx={{ flex: 1, minWidth: 0 }}\n noWrap\n >\n {JOB_LABELS[job.kind]}\n {job.receipt?.orderNumber\n ? ` #${job.receipt.orderNumber}`\n : ''}\n <Typography\n component=\"span\"\n variant=\"caption\"\n color=\"text.secondary\"\n >\n {` · ${printerName(job.printerId)} · ${seenAgo(job.createdAtMs, now)}`}\n {job.error ? ` · ${job.error}` : ''}\n </Typography>\n </Typography>\n <Chip\n size=\"small\"\n variant=\"outlined\"\n color={\n job.status === 'done'\n ? 'success'\n : job.status === 'failed'\n ? 'error'\n : 'default'\n }\n label={CommerceModel.PRINT_JOB_STATUS_LABELS[job.status]}\n />\n {job.status === 'queued' ? (\n <Button size=\"small\" onClick={cancelJob(job)}>\n {'Cancel'}\n </Button>\n ) : null}\n </Stack>\n ))}\n </>\n ) : null}\n <RegisterOtherDevices hostId={hostId} registerId={registerId} now={now} />\n </Stack>\n\n <Dialog\n open={adding}\n onClose={() => setAdding(false)}\n fullWidth\n maxWidth=\"sm\"\n >\n <DialogTitle>\n {credentials\n ? 'Connect the printer'\n : `Add a printer to ${registerName}`}\n </DialogTitle>\n <DialogContent>\n {credentials ? (\n <PollUrlPanel credentials={credentials} />\n ) : (\n <PrinterForm value={form} onChange={setForm} />\n )}\n </DialogContent>\n <DialogActions>\n {credentials ? (\n <Button onClick={() => setAdding(false)}>{'Done'}</Button>\n ) : (\n <>\n <Button onClick={() => setAdding(false)}>{'Cancel'}</Button>\n <Button\n onClick={create}\n disabled={busy || !form.name.trim() || !form.deviceId.trim()}\n >\n {'Add printer'}\n </Button>\n </>\n )}\n </DialogActions>\n </Dialog>\n\n <Dialog\n open={Boolean(editing)}\n onClose={() => setEditing(null)}\n fullWidth\n maxWidth=\"sm\"\n >\n <DialogTitle>{editing?.name ?? 'Printer'}</DialogTitle>\n <DialogContent>\n <PrinterForm value={form} onChange={setForm} brandLocked />\n <Divider sx={{ my: 2 }} />\n {credentials ? <PollUrlPanel credentials={credentials} /> : null}\n </DialogContent>\n <DialogActions>\n <Button color=\"warning\" onClick={regenerate}>\n {'Regenerate URL'}\n </Button>\n <Box sx={{ flex: 1 }} />\n <Button onClick={() => setEditing(null)}>{'Cancel'}</Button>\n <Button onClick={save} disabled={busy || !form.name.trim()}>\n {'Save'}\n </Button>\n </DialogActions>\n </Dialog>\n </CardDisplay>\n )\n}\nRegisterHardwareCard.displayName = 'RegisterHardwareCard'\n\n/** One Hardware card per register on the site. */\nexport function RegisterHardwareCards(props: { hostId: string }) {\n const { hostId } = props\n const firestore = useFirestore()\n const { data: registerDocs } = useFirestoreCollection<{\n $id: string\n name?: string\n }>(\n () => query(collection(firestore, 'hosts', hostId, 'registers'), limit(25)),\n [firestore, hostId],\n { idField: '$id' },\n )\n const registers = [...(registerDocs ?? [])].sort((a, b) =>\n String(a.name ?? '').localeCompare(String(b.name ?? '')),\n )\n if (!registers.length) return null\n return (\n <Stack spacing={3}>\n {registers.map((register) => (\n <RegisterHardwareCard\n key={register.$id}\n hostId={hostId}\n registerId={register.$id}\n registerName={register.name || 'Register'}\n />\n ))}\n </Stack>\n )\n}\n\nexport default RegisterHardwareCards\n"],"names":["CommerceModel","CardDisplay","useConfirmationContext","useSnackbar","authorizedFetch","pluginDocsHelp","Alert","Autocomplete","Box","Button","Chip","Dialog","DialogActions","DialogContent","DialogTitle","Divider","FormControlLabel","MenuItem","Stack","Switch","TextField","Typography","collection","limit","orderBy","query","where","useCallback","useEffect","useState","useFirestore","useFirestoreCollection","useUser","STATE_COLOR","online","paper_low","paper_out","cover_open","error","offline","unknown","JOB_LABELS","receipt","kitchen","drawer","test","report","seenAgo","atMs","nowMs","seconds","Math","max","round","minutes","hours","useNow","intervalMs","now","setNow","Date","id","setInterval","clearInterval","usePrintersApi","hostId","data","user","enqueueSnackbar","body","response","method","headers","JSON","stringify","payload","json","catch","ok","variant","persist","printerSetupSteps","brand","EMPTY_FORM","name","model","deviceId","paperWidthMm","autoPrintReceipts","kickDrawer","kitchenTickets","logoKey","PrinterForm","props","value","onChange","brandLocked","set","key","next","spacing","sx","pt","select","label","disabled","event","target","PRINTER_BRANDS","map","PRINTER_BRAND_LABELS","freeSolo","options","PRINTER_MODEL_SUGGESTIONS","onInputChange","_event","renderInput","params","placeholder","helperText","Number","control","checked","PollUrlPanel","credentials","copy","navigator","clipboard","writeText","pollUrl","severity","multiline","slotProps","htmlInput","readOnly","size","onClick","component","pl","m","step","mb","PrinterRowView","printer","call","onSettings","confirm","state","printerDisplayState","status","PRINTER_STATE_LABELS","send","action","result","printerId","$id","remove","confirmed","title","description","confirmationText","confirmationButtonProps","color","then","direction","alignItems","flexWrap","rowGap","flex","minWidth","noWrap","detail","DISPLAY_CONNECTED_MS","RegisterOtherDevices","registerId","firestore","readerDocs","idField","displays","setDisplays","live","answer","Array","isArray","readers","length","reader","deviceType","display","connected","lastSeenAtMs","displayName","RegisterHardwareCard","registerName","printerDocs","jobDocs","printers","sort","a","b","createdAtMs","jobs","adding","setAdding","form","setForm","editing","setEditing","setCredentials","busy","setBusy","openAdd","create","created","openSettings","Boolean","shown","save","_brand","settings","saved","regenerate","cancelJob","job","jobId","printerName","find","header","help","anchor","HeaderProps","contentGutterX","contentGutterY","kind","orderNumber","PRINT_JOB_STATUS_LABELS","open","onClose","fullWidth","maxWidth","trim","my","RegisterHardwareCards","registerDocs","registers","String","localeCompare","register"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/register-hardware-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 * as CommerceModel from '../../model'\nimport { CardDisplay, useConfirmationContext } from '@aglyn/shared-ui-jsx'\nimport { BlockedControl } from '@aglyn/shared-ui-jsx/components/blocked-control.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport { pluginDocsHelp } from '@aglyn/aglyn'\nimport {\n Alert,\n Autocomplete,\n Box,\n Button,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Divider,\n FormControlLabel,\n MenuItem,\n Stack,\n Switch,\n TextField,\n Typography,\n} from '@mui/material'\nimport { collection, limit, orderBy, query, where } from 'firebase/firestore'\nimport { useCallback, useEffect, useState } from 'react'\nimport {\n useFirestore,\n useFirestoreCollection,\n useUser,\n} from '@aglyn/tenant-feature-instance'\n\n/**\n * The Hardware card for one register (AGL-3619): the cloud receipt printers\n * paired with it, with their live status and recent jobs, and the way to add\n * one — brand, model, MAC or ID — and get the URL to paste into the printer;\n * then, read-only, the card readers and customer displays the register uses.\n *\n * Every write goes through `/api/commerce/printers`: the printer documents\n * and the queue are server-written, so this card only reads Firestore.\n */\n\ntype PrinterRow = CommerceModel.PosPrinter & { $id: string }\ntype JobRow = CommerceModel.PrintJob & { $id: string }\n\nconst STATE_COLOR: Record<string, 'success' | 'warning' | 'error' | 'default'> =\n {\n online: 'success',\n paper_low: 'warning',\n paper_out: 'error',\n cover_open: 'error',\n error: 'error',\n offline: 'default',\n unknown: 'default',\n }\n\nconst JOB_LABELS: Record<CommerceModel.PrintJobKind, string> = {\n receipt: 'Receipt',\n kitchen: 'Kitchen ticket',\n drawer: 'Open drawer',\n test: 'Test print',\n report: 'Shift report',\n}\n\n/** \"just now\", \"3 min ago\", \"2 h ago\". */\nexport function seenAgo(atMs: number | undefined, nowMs: number): string {\n if (!atMs) return 'never'\n const seconds = Math.max(0, Math.round((nowMs - atMs) / 1000))\n if (seconds < 45) return 'just now'\n const minutes = Math.round(seconds / 60)\n if (minutes < 60) return `${minutes} min ago`\n const hours = Math.round(minutes / 60)\n if (hours < 48) return `${hours} h ago`\n return `${Math.round(hours / 24)} days ago`\n}\n\nfunction useNow(intervalMs: number): number {\n const [now, setNow] = useState(() => Date.now())\n useEffect(() => {\n const id = setInterval(() => setNow(Date.now()), intervalMs)\n return () => clearInterval(id)\n }, [intervalMs])\n return now\n}\n\nfunction usePrintersApi(hostId: string) {\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n return useCallback(\n async (\n body: Record<string, unknown>,\n ): Promise<Record<string, any> | null> => {\n try {\n const response = await authorizedFetch(user, '/api/commerce/printers', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ hostId, ...body }),\n })\n const payload = await response.json().catch(() => ({}))\n if (!response.ok) {\n enqueueSnackbar(\n payload?.error ?? 'The printer could not be updated',\n {\n variant: 'warning',\n persist: false,\n },\n )\n return null\n }\n return payload\n } catch {\n enqueueSnackbar(\n 'The printer could not be reached. Check your connection.',\n {\n variant: 'warning',\n persist: false,\n },\n )\n return null\n }\n },\n [user, hostId, enqueueSnackbar],\n )\n}\n\n/** Where each brand's poll URL goes, step by step. */\nexport function printerSetupSteps(brand: CommerceModel.PrinterBrand): string[] {\n return brand === 'star'\n ? [\n 'Open the printer’s web page: print a self-test (hold FEED while switching on) to find its IP address, then browse to it and sign in (default user root, password public, or the password on the printer’s label).',\n 'Go to Settings → CloudPRNT. Turn CloudPRNT on and paste the URL below as the Server URL.',\n 'Set the polling interval to 5 seconds, then Submit and Save → Restart device.',\n 'Come back here: the printer shows Online within a minute. Send a test print.',\n ]\n : [\n 'Open EPSON TMNet WebConfig: browse to the printer’s IP address (print a status sheet by holding FEED while switching on).',\n 'Open Server Direct Print (under Web Service Settings on most models). Select Enable and enter the ID below.',\n 'Paste the URL below as Server 1 URL and set the interval to 5 seconds. Submit, then reset the printer.',\n 'Come back here: the printer shows Online within a minute. Send a test print.',\n ]\n}\n\ninterface PrinterFormState {\n brand: CommerceModel.PrinterBrand\n name: string\n model: string\n deviceId: string\n paperWidthMm: CommerceModel.PrinterPaperWidth\n autoPrintReceipts: boolean\n kickDrawer: boolean\n kitchenTickets: boolean\n logoKey: string\n}\n\nconst EMPTY_FORM: PrinterFormState = {\n brand: 'star',\n name: '',\n model: '',\n deviceId: '',\n paperWidthMm: 80,\n autoPrintReceipts: true,\n kickDrawer: true,\n kitchenTickets: false,\n logoKey: '',\n}\n\nfunction PrinterForm(props: {\n value: PrinterFormState\n onChange: (next: PrinterFormState) => void\n brandLocked?: boolean\n}) {\n const { value, onChange, brandLocked } = props\n const set = <K extends keyof PrinterFormState>(\n key: K,\n next: PrinterFormState[K],\n ) => onChange({ ...value, [key]: next })\n return (\n <Stack spacing={2} sx={{ pt: 1 }}>\n <TextField\n select\n label=\"Brand\"\n value={value.brand}\n disabled={brandLocked}\n onChange={(event) =>\n set('brand', event.target.value as CommerceModel.PrinterBrand)\n }\n >\n {CommerceModel.PRINTER_BRANDS.map((brand) => (\n <MenuItem key={brand} value={brand}>\n {CommerceModel.PRINTER_BRAND_LABELS[brand]}\n </MenuItem>\n ))}\n </TextField>\n <Autocomplete\n freeSolo\n options={[...CommerceModel.PRINTER_MODEL_SUGGESTIONS[value.brand]]}\n value={value.model}\n onInputChange={(_event, next) => set('model', next)}\n renderInput={(params) => <TextField {...params} label=\"Model\" />}\n />\n <TextField\n label=\"Name\"\n value={value.name}\n placeholder=\"Counter printer\"\n onChange={(event) => set('name', event.target.value)}\n />\n <TextField\n label={\n value.brand === 'star' ? 'MAC address' : 'Server Direct Print ID'\n }\n value={value.deviceId}\n placeholder={value.brand === 'star' ? '00:11:62:12:34:56' : 'counter-1'}\n helperText={\n value.brand === 'star'\n ? 'The Ethernet MAC on the self-test print, even if the printer uses Wi-Fi.'\n : 'Any ID you choose (letters, digits, - _ .), entered again in WebConfig.'\n }\n onChange={(event) => set('deviceId', event.target.value)}\n />\n <TextField\n select\n label=\"Paper\"\n value={value.paperWidthMm}\n onChange={(event) =>\n set('paperWidthMm', Number(event.target.value) === 58 ? 58 : 80)\n }\n >\n <MenuItem value={80}>{'80 mm (3 1/8 in)'}</MenuItem>\n <MenuItem value={58}>{'58 mm (2 1/4 in)'}</MenuItem>\n </TextField>\n <TextField\n label=\"Stored logo (optional)\"\n value={value.logoKey}\n placeholder={value.brand === 'star' ? '1' : '48,48'}\n helperText={\n value.brand === 'star'\n ? 'The logo number saved in the printer with Star Quick Setup Utility.'\n : 'The key saved in the printer with Epson TM Utility, as two numbers.'\n }\n onChange={(event) => set('logoKey', event.target.value)}\n />\n <FormControlLabel\n control={\n <Switch\n checked={value.autoPrintReceipts}\n onChange={(event) => set('autoPrintReceipts', event.target.checked)}\n />\n }\n label=\"Print a receipt for every sale on this register\"\n />\n <FormControlLabel\n control={\n <Switch\n checked={value.kickDrawer}\n onChange={(event) => set('kickDrawer', event.target.checked)}\n />\n }\n label=\"A cash drawer is plugged into this printer\"\n />\n <FormControlLabel\n control={\n <Switch\n checked={value.kitchenTickets}\n onChange={(event) => set('kitchenTickets', event.target.checked)}\n />\n }\n label=\"Print a kitchen ticket for every sale (items and quantities, no prices)\"\n />\n </Stack>\n )\n}\n\nfunction PollUrlPanel(props: {\n credentials: {\n brand: CommerceModel.PrinterBrand\n pollUrl: string\n deviceId: string\n }\n}) {\n const { credentials } = props\n const { enqueueSnackbar } = useSnackbar()\n const copy = async () => {\n try {\n await navigator.clipboard.writeText(credentials.pollUrl)\n enqueueSnackbar('Copied', { variant: 'success', persist: false })\n } catch {\n enqueueSnackbar('Select the URL and copy it', {\n variant: 'info',\n persist: false,\n })\n }\n }\n return (\n <Stack spacing={1.5}>\n <Alert severity=\"info\">\n {'This URL is the printer’s password: anyone with it can collect this register’s receipts. ' +\n 'Regenerate it if it is ever shared.'}\n </Alert>\n <TextField\n label={\n credentials.brand === 'star'\n ? 'CloudPRNT Server URL'\n : 'Server Direct Print URL'\n }\n value={credentials.pollUrl}\n multiline\n slotProps={{ htmlInput: { readOnly: true } }}\n />\n {credentials.brand === 'epson' ? (\n <TextField\n label=\"ID\"\n value={credentials.deviceId}\n slotProps={{ htmlInput: { readOnly: true } }}\n />\n ) : null}\n <Box>\n <Button size=\"small\" onClick={copy}>\n {'Copy URL'}\n </Button>\n </Box>\n <Box component=\"ol\" sx={{ pl: 2.5, m: 0 }}>\n {printerSetupSteps(credentials.brand).map((step) => (\n <Typography\n component=\"li\"\n variant=\"body2\"\n key={step}\n sx={{ mb: 0.5 }}\n >\n {step}\n </Typography>\n ))}\n </Box>\n </Stack>\n )\n}\n\nfunction PrinterRowView(props: {\n printer: PrinterRow\n now: number\n call: ReturnType<typeof usePrintersApi>\n onSettings: (printer: PrinterRow) => void\n /** Why the viewer may not set printers up, or open the drawer (AGL-4047). */\n blocked?: RegisterHardwareBlocked\n}) {\n const { printer, now, call, onSettings } = props\n const devices = props.blocked?.devices\n const drawer = props.blocked?.drawer\n const { enqueueSnackbar } = useSnackbar()\n const { confirm } = useConfirmationContext()\n const state = CommerceModel.printerDisplayState(printer.status, now)\n const label =\n state === 'offline' ? 'Offline' : CommerceModel.PRINTER_STATE_LABELS[state]\n const send = async (action: 'test' | 'drawer') => {\n const result = await call({ action, printerId: printer.$id })\n if (result) {\n enqueueSnackbar(\n action === 'test' ? 'Test print sent' : 'Drawer kick sent',\n {\n variant: 'success',\n persist: false,\n },\n )\n }\n }\n const remove = async () => {\n const confirmed = await confirm({\n title: `Remove ${printer.name}?`,\n description:\n 'Its URL stops working and anything it has not printed is canceled.',\n confirmationText: 'Remove',\n confirmationButtonProps: { color: 'error' },\n })\n .then(() => true)\n .catch(() => false)\n if (confirmed) await call({ action: 'remove', printerId: printer.$id })\n }\n return (\n <Stack spacing={0.5}>\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center', flexWrap: 'wrap', rowGap: 1 }}\n >\n <Typography\n variant=\"body2\"\n sx={{ flex: '1 1 160px', minWidth: 0 }}\n noWrap\n >\n {printer.name}\n <Typography component=\"span\" variant=\"caption\" color=\"text.secondary\">\n {` · ${printer.brand === 'star' ? 'Star' : 'Epson'}${printer.model ? ` ${printer.model}` : ''}`}\n </Typography>\n </Typography>\n <Chip\n size=\"small\"\n variant=\"outlined\"\n color={STATE_COLOR[state]}\n label={label}\n />\n <BlockedControl blocked={Boolean(devices)} reason={devices ?? ''}>\n <Button size=\"small\" onClick={() => send('test')}>\n {'Test print'}\n </Button>\n </BlockedControl>\n {printer.kickDrawer ? (\n <BlockedControl blocked={Boolean(drawer)} reason={drawer ?? ''}>\n <Button size=\"small\" onClick={() => send('drawer')}>\n {'Open drawer'}\n </Button>\n </BlockedControl>\n ) : null}\n <BlockedControl blocked={Boolean(devices)} reason={devices ?? ''}>\n <Button size=\"small\" onClick={() => onSettings(printer)}>\n {'Settings'}\n </Button>\n </BlockedControl>\n <BlockedControl blocked={Boolean(devices)} reason={devices ?? ''}>\n <Button size=\"small\" color=\"error\" onClick={remove}>\n {'Remove'}\n </Button>\n </BlockedControl>\n </Stack>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {printer.status?.atMs\n ? `Last seen ${seenAgo(printer.status.atMs, now)}${printer.status.detail ? ` · ${printer.status.detail}` : ''}`\n : 'Waiting for the printer to poll — paste its URL into the printer to finish.'}\n {printer.autoPrintReceipts ? ' · Prints every sale' : ''}\n {printer.kickDrawer ? ' · Cash drawer' : ''}\n {printer.kitchenTickets ? ' · Kitchen tickets' : ''}\n </Typography>\n </Stack>\n )\n}\n\n/**\n * Why the viewer may not do a printer action (AGL-4047), by the register key\n * it needs: setting printers up (`posDevices`) and opening the drawer without\n * a sale (`posCashDrawer`). Absent: allowed.\n */\nexport interface RegisterHardwareBlocked {\n devices?: string\n drawer?: string\n}\n\nexport interface RegisterHardwareCardProps {\n hostId: string\n registerId: string\n registerName: string\n blocked?: RegisterHardwareBlocked\n}\n\ntype ReaderRow = {\n $id: string\n label?: string\n deviceType?: string\n status?: string\n registerId?: string\n}\ntype DisplayRow = { id: string; label: string; lastSeenAtMs: number }\n\n/** A customer display that polled within this long is shown as connected. */\nconst DISPLAY_CONNECTED_MS = 120_000\n\n/**\n * The register's other devices, read-only: the Stripe Terminal card readers\n * assigned to it and the customer displays paired with it. Each is added and\n * removed where it is set up; this list is the one place a manager sees\n * everything plugged into the till. Nothing renders when there are none.\n */\nexport function RegisterOtherDevices(props: {\n hostId: string\n registerId: string\n now: number\n}) {\n const { hostId, registerId, now } = props\n const firestore = useFirestore()\n const { data: user } = useUser()\n const { data: readerDocs } = useFirestoreCollection<ReaderRow>(\n () =>\n query(\n collection(firestore, 'hosts', hostId, 'terminalReaders'),\n where('registerId', '==', registerId),\n limit(10),\n ),\n [firestore, hostId, registerId],\n { idField: '$id' },\n )\n const [displays, setDisplays] = useState<DisplayRow[]>([])\n useEffect(() => {\n if (!user) return\n let live = true\n void (async () => {\n try {\n const response = await authorizedFetch(user as any, '/api/commerce/pos-display', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ hostId, registerId, action: 'displays' }),\n })\n if (!response.ok) return\n const answer = (await response.json().catch(() => ({}))) as { displays?: DisplayRow[] }\n if (live) setDisplays(Array.isArray(answer.displays) ? answer.displays : [])\n } catch {\n // Offline: the list stays as it was; the printers above still show.\n }\n })()\n return () => {\n live = false\n }\n }, [user, hostId, registerId])\n const readers = readerDocs ?? []\n if (!readers.length && !displays.length) return null\n return (\n <>\n <Divider />\n <Typography variant=\"subtitle2\">{'Card readers and customer displays'}</Typography>\n {readers.map((reader) => (\n <Stack key={reader.$id} direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Typography variant=\"body2\" sx={{ flex: 1, minWidth: 0 }} noWrap>\n {reader.label || 'Card reader'}\n <Typography component=\"span\" variant=\"caption\" color=\"text.secondary\">\n {` · Card reader${reader.deviceType ? ` · ${reader.deviceType}` : ''}`}\n </Typography>\n </Typography>\n <Chip\n size=\"small\"\n variant=\"outlined\"\n color={reader.status === 'online' ? 'success' : 'default'}\n label={reader.status === 'online' ? 'Online' : 'Offline'}\n />\n </Stack>\n ))}\n {displays.map((display) => {\n const connected = now - display.lastSeenAtMs < DISPLAY_CONNECTED_MS\n return (\n <Stack key={display.id} direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Typography variant=\"body2\" sx={{ flex: 1, minWidth: 0 }} noWrap>\n {display.label || 'Customer display'}\n <Typography component=\"span\" variant=\"caption\" color=\"text.secondary\">\n {` · Customer display · seen ${seenAgo(display.lastSeenAtMs, now)}`}\n </Typography>\n </Typography>\n <Chip\n size=\"small\"\n variant=\"outlined\"\n color={connected ? 'success' : 'default'}\n label={connected ? 'Connected' : 'Offline'}\n />\n </Stack>\n )\n })}\n </>\n )\n}\nRegisterOtherDevices.displayName = 'RegisterOtherDevices'\n\nexport function RegisterHardwareCard(props: RegisterHardwareCardProps) {\n const { hostId, registerId, registerName } = props\n const devicesBlocked = props.blocked?.devices\n const firestore = useFirestore()\n const call = usePrintersApi(hostId)\n const now = useNow(15_000)\n const { data: printerDocs } = useFirestoreCollection<PrinterRow>(\n () =>\n query(\n collection(firestore, 'hosts', hostId, 'printers'),\n where('registerId', '==', registerId),\n limit(4),\n ),\n [firestore, hostId, registerId],\n { idField: '$id' },\n )\n const { data: jobDocs } = useFirestoreCollection<JobRow>(\n () =>\n query(\n collection(firestore, 'hosts', hostId, 'printJobs'),\n where('registerId', '==', registerId),\n orderBy('createdAtMs', 'desc'),\n limit(6),\n ),\n [firestore, hostId, registerId],\n { idField: '$id' },\n )\n const printers = [...(printerDocs ?? [])].sort(\n (a, b) => a.createdAtMs - b.createdAtMs,\n )\n const jobs = jobDocs ?? []\n\n const [adding, setAdding] = useState(false)\n const [form, setForm] = useState<PrinterFormState>(EMPTY_FORM)\n const [editing, setEditing] = useState<PrinterRow | null>(null)\n const [credentials, setCredentials] = useState<{\n brand: CommerceModel.PrinterBrand\n pollUrl: string\n deviceId: string\n } | null>(null)\n const [busy, setBusy] = useState(false)\n\n const openAdd = () => {\n setForm(EMPTY_FORM)\n setCredentials(null)\n setAdding(true)\n }\n const create = async () => {\n setBusy(true)\n const created = await call({ action: 'create', registerId, ...form })\n setBusy(false)\n if (created) setCredentials(created as any)\n }\n const openSettings = async (printer: PrinterRow) => {\n setEditing(printer)\n setForm({\n brand: printer.brand,\n name: printer.name,\n model: printer.model ?? '',\n deviceId: printer.deviceId,\n paperWidthMm: printer.paperWidthMm ?? 80,\n autoPrintReceipts: printer.autoPrintReceipts,\n kickDrawer: printer.kickDrawer,\n kitchenTickets: Boolean(printer.kitchenTickets),\n logoKey: printer.logoKey ?? '',\n })\n setCredentials(null)\n const shown = await call({ action: 'credentials', printerId: printer.$id })\n if (shown) setCredentials(shown as any)\n }\n const save = async () => {\n if (!editing) return\n setBusy(true)\n const { brand: _brand, ...settings } = form\n const saved = await call({\n action: 'update',\n printerId: editing.$id,\n ...settings,\n })\n setBusy(false)\n if (saved) setEditing(null)\n }\n const regenerate = async () => {\n if (!editing) return\n const next = await call({ action: 'regenerate', printerId: editing.$id })\n if (next) setCredentials(next as any)\n }\n const cancelJob = (job: JobRow) => () =>\n void call({ action: 'cancel', jobId: job.$id })\n const printerName = (id: string) =>\n printers.find((printer) => printer.$id === id)?.name ?? 'Removed printer'\n\n return (\n <CardDisplay\n header={`Hardware · ${registerName}`}\n help={pluginDocsHelp('posHardware', { anchor: '#receipt-printers' })}\n HeaderProps={{\n action: (\n <BlockedControl blocked={Boolean(devicesBlocked)} reason={devicesBlocked ?? ''}>\n <Button\n size=\"small\"\n onClick={openAdd}\n disabled={printers.length >= 4}\n >\n {'Add printer'}\n </Button>\n </BlockedControl>\n ),\n }}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={1.5}>\n <Typography variant=\"subtitle2\">{'Receipt printers'}</Typography>\n {printers.length === 0 ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Pair a Star CloudPRNT or Epson Server Direct Print printer to print receipts from this register ' +\n 'on any device, with no driver, and to open its cash drawer on cash sales.'}\n </Typography>\n ) : (\n printers.map((printer) => (\n <PrinterRowView\n key={printer.$id}\n printer={printer}\n now={now}\n call={call}\n onSettings={openSettings}\n {...(props.blocked ? { blocked: props.blocked } : {})}\n />\n ))\n )}\n {jobs.length ? (\n <>\n <Divider />\n <Typography variant=\"subtitle2\">{'Recent print jobs'}</Typography>\n {jobs.map((job) => (\n <Stack\n key={job.$id}\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center' }}\n >\n <Typography\n variant=\"body2\"\n sx={{ flex: 1, minWidth: 0 }}\n noWrap\n >\n {JOB_LABELS[job.kind]}\n {job.receipt?.orderNumber\n ? ` #${job.receipt.orderNumber}`\n : ''}\n <Typography\n component=\"span\"\n variant=\"caption\"\n color=\"text.secondary\"\n >\n {` · ${printerName(job.printerId)} · ${seenAgo(job.createdAtMs, now)}`}\n {job.error ? ` · ${job.error}` : ''}\n </Typography>\n </Typography>\n <Chip\n size=\"small\"\n variant=\"outlined\"\n color={\n job.status === 'done'\n ? 'success'\n : job.status === 'failed'\n ? 'error'\n : 'default'\n }\n label={CommerceModel.PRINT_JOB_STATUS_LABELS[job.status]}\n />\n {job.status === 'queued' ? (\n <Button size=\"small\" onClick={cancelJob(job)}>\n {'Cancel'}\n </Button>\n ) : null}\n </Stack>\n ))}\n </>\n ) : null}\n <RegisterOtherDevices hostId={hostId} registerId={registerId} now={now} />\n </Stack>\n\n <Dialog\n open={adding}\n onClose={() => setAdding(false)}\n fullWidth\n maxWidth=\"sm\"\n >\n <DialogTitle>\n {credentials\n ? 'Connect the printer'\n : `Add a printer to ${registerName}`}\n </DialogTitle>\n <DialogContent>\n {credentials ? (\n <PollUrlPanel credentials={credentials} />\n ) : (\n <PrinterForm value={form} onChange={setForm} />\n )}\n </DialogContent>\n <DialogActions>\n {credentials ? (\n <Button onClick={() => setAdding(false)}>{'Done'}</Button>\n ) : (\n <>\n <Button onClick={() => setAdding(false)}>{'Cancel'}</Button>\n <Button\n onClick={create}\n disabled={busy || !form.name.trim() || !form.deviceId.trim()}\n >\n {'Add printer'}\n </Button>\n </>\n )}\n </DialogActions>\n </Dialog>\n\n <Dialog\n open={Boolean(editing)}\n onClose={() => setEditing(null)}\n fullWidth\n maxWidth=\"sm\"\n >\n <DialogTitle>{editing?.name ?? 'Printer'}</DialogTitle>\n <DialogContent>\n <PrinterForm value={form} onChange={setForm} brandLocked />\n <Divider sx={{ my: 2 }} />\n {credentials ? <PollUrlPanel credentials={credentials} /> : null}\n </DialogContent>\n <DialogActions>\n <Button color=\"warning\" onClick={regenerate}>\n {'Regenerate URL'}\n </Button>\n <Box sx={{ flex: 1 }} />\n <Button onClick={() => setEditing(null)}>{'Cancel'}</Button>\n <Button onClick={save} disabled={busy || !form.name.trim()}>\n {'Save'}\n </Button>\n </DialogActions>\n </Dialog>\n </CardDisplay>\n )\n}\nRegisterHardwareCard.displayName = 'RegisterHardwareCard'\n\n/** One Hardware card per register on the site. */\nexport function RegisterHardwareCards(props: { hostId: string; blocked?: RegisterHardwareBlocked }) {\n const { hostId } = props\n const firestore = useFirestore()\n const { data: registerDocs } = useFirestoreCollection<{\n $id: string\n name?: string\n }>(\n () => query(collection(firestore, 'hosts', hostId, 'registers'), limit(25)),\n [firestore, hostId],\n { idField: '$id' },\n )\n const registers = [...(registerDocs ?? [])].sort((a, b) =>\n String(a.name ?? '').localeCompare(String(b.name ?? '')),\n )\n if (!registers.length) return null\n return (\n <Stack spacing={3}>\n {registers.map((register) => (\n <RegisterHardwareCard\n key={register.$id}\n hostId={hostId}\n registerId={register.$id}\n registerName={register.name || 'Register'}\n {...(props.blocked ? { blocked: props.blocked } : {})}\n />\n ))}\n </Stack>\n )\n}\n\nexport default RegisterHardwareCards\n"],"names":["CommerceModel","CardDisplay","useConfirmationContext","BlockedControl","useSnackbar","authorizedFetch","pluginDocsHelp","Alert","Autocomplete","Box","Button","Chip","Dialog","DialogActions","DialogContent","DialogTitle","Divider","FormControlLabel","MenuItem","Stack","Switch","TextField","Typography","collection","limit","orderBy","query","where","useCallback","useEffect","useState","useFirestore","useFirestoreCollection","useUser","STATE_COLOR","online","paper_low","paper_out","cover_open","error","offline","unknown","JOB_LABELS","receipt","kitchen","drawer","test","report","seenAgo","atMs","nowMs","seconds","Math","max","round","minutes","hours","useNow","intervalMs","now","setNow","Date","id","setInterval","clearInterval","usePrintersApi","hostId","data","user","enqueueSnackbar","body","response","method","headers","JSON","stringify","payload","json","catch","ok","variant","persist","printerSetupSteps","brand","EMPTY_FORM","name","model","deviceId","paperWidthMm","autoPrintReceipts","kickDrawer","kitchenTickets","logoKey","PrinterForm","props","value","onChange","brandLocked","set","key","next","spacing","sx","pt","select","label","disabled","event","target","PRINTER_BRANDS","map","PRINTER_BRAND_LABELS","freeSolo","options","PRINTER_MODEL_SUGGESTIONS","onInputChange","_event","renderInput","params","placeholder","helperText","Number","control","checked","PollUrlPanel","credentials","copy","navigator","clipboard","writeText","pollUrl","severity","multiline","slotProps","htmlInput","readOnly","size","onClick","component","pl","m","step","mb","PrinterRowView","printer","call","onSettings","devices","blocked","confirm","state","printerDisplayState","status","PRINTER_STATE_LABELS","send","action","result","printerId","$id","remove","confirmed","title","description","confirmationText","confirmationButtonProps","color","then","direction","alignItems","flexWrap","rowGap","flex","minWidth","noWrap","Boolean","reason","detail","DISPLAY_CONNECTED_MS","RegisterOtherDevices","registerId","firestore","readerDocs","idField","displays","setDisplays","live","answer","Array","isArray","readers","length","reader","deviceType","display","connected","lastSeenAtMs","displayName","RegisterHardwareCard","registerName","devicesBlocked","printerDocs","jobDocs","printers","sort","a","b","createdAtMs","jobs","adding","setAdding","form","setForm","editing","setEditing","setCredentials","busy","setBusy","openAdd","create","created","openSettings","shown","save","_brand","settings","saved","regenerate","cancelJob","job","jobId","printerName","find","header","help","anchor","HeaderProps","contentGutterX","contentGutterY","kind","orderNumber","PRINT_JOB_STATUS_LABELS","open","onClose","fullWidth","maxWidth","trim","my","RegisterHardwareCards","registerDocs","registers","String","localeCompare","register"],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ export interface ReservationGuestsDialogProps {
2
+ /** The stay whose guests change; the dialog is open while it is set. */
3
+ reservationId: string | null;
4
+ hostId: string;
5
+ onClose: () => void;
6
+ /** What the route did: the new count and the check-ins it added and took away. */
7
+ onDone: (answer: {
8
+ guests: number;
9
+ added: number;
10
+ removed: number;
11
+ unchanged: boolean;
12
+ }) => void;
13
+ }
14
+ /**
15
+ * How many guests a stay is for, after it is booked (AGL-4043): from the
16
+ * Reservations card and the check-in screens, through
17
+ * `/api/commerce/reservations/guests`. The stay and its resource are read
18
+ * when it opens, for the count and what the resource sleeps; the route is
19
+ * the one that decides, so a read the member cannot make still leaves the
20
+ * field working. When the stay is checked in one guest at a time, the route
21
+ * brings today's check-ins in line and refuses a count below how many are
22
+ * already checked in, in its own words.
23
+ */
24
+ export declare function ReservationGuestsDialog(props: ReservationGuestsDialogProps): import("react").JSX.Element;
25
+ export declare namespace ReservationGuestsDialog {
26
+ var displayName: string;
27
+ }
28
+ export default ReservationGuestsDialog;
@@ -0,0 +1,189 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ 'use client';
17
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
18
+ import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
19
+ import { useFirestore, useUser } from "@aglyn/tenant-feature-instance";
20
+ import { Alert, Button, Dialog, DialogActions, DialogContent, DialogTitle, Stack, TextField, Typography } from "@mui/material";
21
+ import { doc, getDoc } from "firebase/firestore";
22
+ import { useEffect, useState } from "react";
23
+ import { reservationGuests, reservationGuestsProblem, resourceGuestCeiling, RESERVATION_GUESTS_ROUTE } from "../../model/commerce-reservations.js";
24
+ /**
25
+ * How many guests a stay is for, after it is booked (AGL-4043): from the
26
+ * Reservations card and the check-in screens, through
27
+ * `/api/commerce/reservations/guests`. The stay and its resource are read
28
+ * when it opens, for the count and what the resource sleeps; the route is
29
+ * the one that decides, so a read the member cannot make still leaves the
30
+ * field working. When the stay is checked in one guest at a time, the route
31
+ * brings today's check-ins in line and refuses a count below how many are
32
+ * already checked in, in its own words.
33
+ */ export function ReservationGuestsDialog(props) {
34
+ const { reservationId, hostId, onClose, onDone } = props;
35
+ const firestore = useFirestore();
36
+ const { data: user } = useUser();
37
+ const [loaded, setLoaded] = useState(null);
38
+ const [typed, setTyped] = useState('');
39
+ const [busy, setBusy] = useState(false);
40
+ const [error, setError] = useState('');
41
+ useEffect(()=>{
42
+ setLoaded(null);
43
+ setTyped('');
44
+ setError('');
45
+ if (!reservationId) return;
46
+ let live = true;
47
+ void (async ()=>{
48
+ try {
49
+ var _stay_data, _reservation_guestName;
50
+ const stay = await getDoc(doc(firestore, 'hosts', hostId, 'reservations', reservationId));
51
+ const reservation = (_stay_data = stay.data()) != null ? _stay_data : {};
52
+ const resource = reservation.resourceId ? (await getDoc(doc(firestore, 'hosts', hostId, 'resources', reservation.resourceId))).data() : undefined;
53
+ if (!live) return;
54
+ const guests = reservationGuests(reservation);
55
+ setLoaded({
56
+ guests,
57
+ ceiling: resourceGuestCeiling(resource),
58
+ label: [
59
+ resource == null ? void 0 : resource.name,
60
+ (_reservation_guestName = reservation.guestName) != null ? _reservation_guestName : reservation.guestEmail
61
+ ].filter(Boolean).join(' · ')
62
+ });
63
+ setTyped(String(guests));
64
+ } catch (unused) {
65
+ if (live) setLoaded({
66
+ guests: 0,
67
+ ceiling: null,
68
+ label: ''
69
+ });
70
+ }
71
+ })();
72
+ return ()=>{
73
+ live = false;
74
+ };
75
+ }, [
76
+ firestore,
77
+ hostId,
78
+ reservationId
79
+ ]);
80
+ const count = typed.trim() ? Number(typed) : NaN;
81
+ const problem = !typed.trim() ? 'How many guests?' : (loaded == null ? void 0 : loaded.ceiling) ? reservationGuestsProblem(count, {
82
+ capacity: loaded.ceiling
83
+ }) : reservationGuestsProblem(count, null);
84
+ const save = async ()=>{
85
+ if (!reservationId || problem) return;
86
+ setBusy(true);
87
+ setError('');
88
+ try {
89
+ var _answer_guests, _ref, _ref1;
90
+ var _answer_checkIns, _answer_checkIns1;
91
+ const response = await authorizedFetch(user, RESERVATION_GUESTS_ROUTE, {
92
+ method: 'POST',
93
+ headers: {
94
+ 'Content-Type': 'application/json'
95
+ },
96
+ body: JSON.stringify({
97
+ hostId,
98
+ reservationId,
99
+ guests: count
100
+ })
101
+ });
102
+ const answer = await response.json().catch(()=>({}));
103
+ if (!response.ok) {
104
+ var _answer_error;
105
+ setError((_answer_error = answer.error) != null ? _answer_error : 'The guests could not be changed. Try again.');
106
+ return;
107
+ }
108
+ onDone({
109
+ guests: (_answer_guests = answer.guests) != null ? _answer_guests : count,
110
+ added: (_ref = (_answer_checkIns = answer.checkIns) == null ? void 0 : _answer_checkIns.added) != null ? _ref : 0,
111
+ removed: (_ref1 = (_answer_checkIns1 = answer.checkIns) == null ? void 0 : _answer_checkIns1.removed) != null ? _ref1 : 0,
112
+ unchanged: answer.unchanged === true
113
+ });
114
+ } catch (unused) {
115
+ setError('The guests could not be changed. Check the connection and try again.');
116
+ } finally{
117
+ setBusy(false);
118
+ }
119
+ };
120
+ return /*#__PURE__*/ _jsxs(Dialog, {
121
+ open: Boolean(reservationId),
122
+ onClose: onClose,
123
+ maxWidth: "xs",
124
+ fullWidth: true,
125
+ children: [
126
+ /*#__PURE__*/ _jsx(DialogTitle, {
127
+ children: 'Guests'
128
+ }),
129
+ /*#__PURE__*/ _jsx(DialogContent, {
130
+ children: /*#__PURE__*/ _jsxs(Stack, {
131
+ spacing: 2,
132
+ sx: {
133
+ pt: 1
134
+ },
135
+ children: [
136
+ (loaded == null ? void 0 : loaded.label) ? /*#__PURE__*/ _jsx(Typography, {
137
+ variant: "body2",
138
+ color: "text.secondary",
139
+ children: loaded.label
140
+ }) : null,
141
+ /*#__PURE__*/ _jsx(TextField, {
142
+ label: "Guests",
143
+ value: typed,
144
+ onChange: (event)=>setTyped(event.target.value.replace(/\D/g, '')),
145
+ error: Boolean(typed) && Boolean(problem),
146
+ helperText: typed && problem || ((loaded == null ? void 0 : loaded.ceiling) ? `Up to ${loaded.ceiling}, what this stay sleeps` : 'At least 1'),
147
+ disabled: !loaded,
148
+ autoFocus: true,
149
+ size: "small",
150
+ slotProps: {
151
+ htmlInput: {
152
+ inputMode: 'numeric',
153
+ 'aria-label': 'Guests'
154
+ }
155
+ }
156
+ }),
157
+ /*#__PURE__*/ _jsx(Typography, {
158
+ variant: "caption",
159
+ color: "text.secondary",
160
+ children: 'When the stay is checked in one guest at a time, today’s check-ins follow: an added guest gets their own, and a guest already checked in stays.'
161
+ }),
162
+ error ? /*#__PURE__*/ _jsx(Alert, {
163
+ severity: "warning",
164
+ children: error
165
+ }) : null
166
+ ]
167
+ })
168
+ }),
169
+ /*#__PURE__*/ _jsxs(DialogActions, {
170
+ children: [
171
+ /*#__PURE__*/ _jsx(Button, {
172
+ onClick: onClose,
173
+ children: 'Cancel'
174
+ }),
175
+ /*#__PURE__*/ _jsx(Button, {
176
+ variant: "contained",
177
+ disabled: busy || !loaded || Boolean(problem),
178
+ onClick: ()=>void save(),
179
+ children: 'Save'
180
+ })
181
+ ]
182
+ })
183
+ ]
184
+ });
185
+ }
186
+ ReservationGuestsDialog.displayName = 'ReservationGuestsDialog';
187
+ export default ReservationGuestsDialog;
188
+
189
+ //# sourceMappingURL=reservation-guests-dialog.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/reservation-guests-dialog.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 { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport { useFirestore, useUser } from '@aglyn/tenant-feature-instance'\nimport {\n Alert,\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { doc, getDoc } from 'firebase/firestore'\nimport { useEffect, useState } from 'react'\nimport {\n reservationGuests,\n reservationGuestsProblem,\n resourceGuestCeiling,\n RESERVATION_GUESTS_ROUTE,\n type HostReservation,\n type HostResource,\n} from '../../model/commerce-reservations'\n\nexport interface ReservationGuestsDialogProps {\n /** The stay whose guests change; the dialog is open while it is set. */\n reservationId: string | null\n hostId: string\n onClose: () => void\n /** What the route did: the new count and the check-ins it added and took away. */\n onDone: (answer: { guests: number; added: number; removed: number; unchanged: boolean }) => void\n}\n\ninterface Loaded {\n guests: number\n ceiling: number | null\n label: string\n}\n\n/**\n * How many guests a stay is for, after it is booked (AGL-4043): from the\n * Reservations card and the check-in screens, through\n * `/api/commerce/reservations/guests`. The stay and its resource are read\n * when it opens, for the count and what the resource sleeps; the route is\n * the one that decides, so a read the member cannot make still leaves the\n * field working. When the stay is checked in one guest at a time, the route\n * brings today's check-ins in line and refuses a count below how many are\n * already checked in, in its own words.\n */\nexport function ReservationGuestsDialog(props: ReservationGuestsDialogProps) {\n const { reservationId, hostId, onClose, onDone } = props\n const firestore = useFirestore()\n const { data: user } = useUser()\n const [loaded, setLoaded] = useState<Loaded | null>(null)\n const [typed, setTyped] = useState('')\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState('')\n\n useEffect(() => {\n setLoaded(null)\n setTyped('')\n setError('')\n if (!reservationId) return\n let live = true\n void (async () => {\n try {\n const stay = await getDoc(doc(firestore, 'hosts', hostId, 'reservations', reservationId))\n const reservation = (stay.data() ?? {}) as Partial<HostReservation>\n const resource = reservation.resourceId\n ? ((await getDoc(doc(firestore, 'hosts', hostId, 'resources', reservation.resourceId))).data() as\n | HostResource\n | undefined)\n : undefined\n if (!live) return\n const guests = reservationGuests(reservation)\n setLoaded({\n guests,\n ceiling: resourceGuestCeiling(resource),\n label: [resource?.name, reservation.guestName ?? reservation.guestEmail].filter(Boolean).join(' · '),\n })\n setTyped(String(guests))\n } catch {\n if (live) setLoaded({ guests: 0, ceiling: null, label: '' })\n }\n })()\n return () => {\n live = false\n }\n }, [firestore, hostId, reservationId])\n\n const count = typed.trim() ? Number(typed) : NaN\n const problem = !typed.trim()\n ? 'How many guests?'\n : loaded?.ceiling\n ? reservationGuestsProblem(count, { capacity: loaded.ceiling })\n : reservationGuestsProblem(count, null)\n\n const save = async () => {\n if (!reservationId || problem) return\n setBusy(true)\n setError('')\n try {\n const response = await authorizedFetch(user as never, RESERVATION_GUESTS_ROUTE, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ hostId, reservationId, guests: count }),\n })\n const answer = (await response.json().catch(() => ({}))) as {\n error?: string\n guests?: number\n unchanged?: boolean\n checkIns?: { added?: number; removed?: number }\n }\n if (!response.ok) {\n setError(answer.error ?? 'The guests could not be changed. Try again.')\n return\n }\n onDone({\n guests: answer.guests ?? count,\n added: answer.checkIns?.added ?? 0,\n removed: answer.checkIns?.removed ?? 0,\n unchanged: answer.unchanged === true,\n })\n } catch {\n setError('The guests could not be changed. Check the connection and try again.')\n } finally {\n setBusy(false)\n }\n }\n\n return (\n <Dialog open={Boolean(reservationId)} onClose={onClose} maxWidth=\"xs\" fullWidth>\n <DialogTitle>{'Guests'}</DialogTitle>\n <DialogContent>\n <Stack spacing={2} sx={{ pt: 1 }}>\n {loaded?.label ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {loaded.label}\n </Typography>\n ) : null}\n <TextField\n label=\"Guests\"\n value={typed}\n onChange={(event) => setTyped(event.target.value.replace(/\\D/g, ''))}\n error={Boolean(typed) && Boolean(problem)}\n helperText={\n (typed && problem) ||\n (loaded?.ceiling ? `Up to ${loaded.ceiling}, what this stay sleeps` : 'At least 1')\n }\n disabled={!loaded}\n autoFocus\n size=\"small\"\n slotProps={{ htmlInput: { inputMode: 'numeric', 'aria-label': 'Guests' } }}\n />\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'When the stay is checked in one guest at a time, today’s check-ins follow: an added guest gets their own, and a guest already checked in stays.'}\n </Typography>\n {error ? <Alert severity=\"warning\">{error}</Alert> : null}\n </Stack>\n </DialogContent>\n <DialogActions>\n <Button onClick={onClose}>{'Cancel'}</Button>\n <Button variant=\"contained\" disabled={busy || !loaded || Boolean(problem)} onClick={() => void save()}>\n {'Save'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\n\nReservationGuestsDialog.displayName = 'ReservationGuestsDialog'\n\nexport default ReservationGuestsDialog\n"],"names":["authorizedFetch","useFirestore","useUser","Alert","Button","Dialog","DialogActions","DialogContent","DialogTitle","Stack","TextField","Typography","doc","getDoc","useEffect","useState","reservationGuests","reservationGuestsProblem","resourceGuestCeiling","RESERVATION_GUESTS_ROUTE","ReservationGuestsDialog","props","reservationId","hostId","onClose","onDone","firestore","data","user","loaded","setLoaded","typed","setTyped","busy","setBusy","error","setError","live","stay","reservation","resource","resourceId","undefined","guests","ceiling","label","name","guestName","guestEmail","filter","Boolean","join","String","count","trim","Number","NaN","problem","capacity","save","answer","response","method","headers","body","JSON","stringify","json","catch","ok","added","checkIns","removed","unchanged","open","maxWidth","fullWidth","spacing","sx","pt","variant","color","value","onChange","event","target","replace","helperText","disabled","autoFocus","size","slotProps","htmlInput","inputMode","severity","onClick","displayName"],"mappings":"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"}
@@ -1,5 +1,14 @@
1
1
  export interface ReservationsCardProps {
2
2
  hostId: string;
3
+ /**
4
+ * "Manage reservations" (`commerce.reservations`, AGL-4047) on this site:
5
+ * edit, cancel and check out stays and change what can be booked. The rules
6
+ * decide it; this only disables the controls with the reason. Absent reads
7
+ * as held, so a surface that does not pass it shows the card as before.
8
+ */
9
+ canManage?: boolean;
10
+ /** "Book walk-ins and change guests" (`commerce.walkIns`), which the routes ask. */
11
+ canWalkIn?: boolean;
3
12
  }
4
13
  /**
5
14
  * Reservations console (AGL-311): resources CRUD (nightly pricing,