@aglyn/plugins-commerce 1.0.0-beta.143
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +10 -0
- package/package.json +57 -0
- package/src/index.d.ts +38 -0
- package/src/index.js +38 -0
- package/src/index.js.map +1 -0
- package/src/lib/components/account.d.ts +31 -0
- package/src/lib/components/account.js +645 -0
- package/src/lib/components/account.js.map +1 -0
- package/src/lib/components/cart.d.ts +38 -0
- package/src/lib/components/cart.js +851 -0
- package/src/lib/components/cart.js.map +1 -0
- package/src/lib/components/commerce-console-page.d.ts +32 -0
- package/src/lib/components/commerce-console-page.js +296 -0
- package/src/lib/components/commerce-console-page.js.map +1 -0
- package/src/lib/components/commerce-console-sections.d.ts +34 -0
- package/src/lib/components/commerce-console-sections.js +62 -0
- package/src/lib/components/commerce-console-sections.js.map +1 -0
- package/src/lib/components/console/catalog-organization-card.component.d.ts +14 -0
- package/src/lib/components/console/catalog-organization-card.component.js +1087 -0
- package/src/lib/components/console/catalog-organization-card.component.js.map +1 -0
- package/src/lib/components/console/commerce-analytics-card.component.d.ts +27 -0
- package/src/lib/components/console/commerce-analytics-card.component.js +310 -0
- package/src/lib/components/console/commerce-analytics-card.component.js.map +1 -0
- package/src/lib/components/console/commerce-glance-card.component.d.ts +20 -0
- package/src/lib/components/console/commerce-glance-card.component.js +340 -0
- package/src/lib/components/console/commerce-glance-card.component.js.map +1 -0
- package/src/lib/components/console/commerce-stat-tile.component.d.ts +37 -0
- package/src/lib/components/console/commerce-stat-tile.component.js +72 -0
- package/src/lib/components/console/commerce-stat-tile.component.js.map +1 -0
- package/src/lib/components/console/discounts-card.component.d.ts +14 -0
- package/src/lib/components/console/discounts-card.component.js +443 -0
- package/src/lib/components/console/discounts-card.component.js.map +1 -0
- package/src/lib/components/console/entitlement-gate.component.d.ts +76 -0
- package/src/lib/components/console/entitlement-gate.component.js +115 -0
- package/src/lib/components/console/entitlement-gate.component.js.map +1 -0
- package/src/lib/components/console/gift-cards-card.component.d.ts +29 -0
- package/src/lib/components/console/gift-cards-card.component.js +379 -0
- package/src/lib/components/console/gift-cards-card.component.js.map +1 -0
- package/src/lib/components/console/host-coupons-card.component.d.ts +14 -0
- package/src/lib/components/console/host-coupons-card.component.js +252 -0
- package/src/lib/components/console/host-coupons-card.component.js.map +1 -0
- package/src/lib/components/console/host-orders-card.component.d.ts +13 -0
- package/src/lib/components/console/host-orders-card.component.js +861 -0
- package/src/lib/components/console/host-orders-card.component.js.map +1 -0
- package/src/lib/components/console/locations-card.component.d.ts +14 -0
- package/src/lib/components/console/locations-card.component.js +256 -0
- package/src/lib/components/console/locations-card.component.js.map +1 -0
- package/src/lib/components/console/member-posts-card.component.d.ts +8 -0
- package/src/lib/components/console/member-posts-card.component.js +283 -0
- package/src/lib/components/console/member-posts-card.component.js.map +1 -0
- package/src/lib/components/console/newest-site-users-card.component.d.ts +36 -0
- package/src/lib/components/console/newest-site-users-card.component.js +126 -0
- package/src/lib/components/console/newest-site-users-card.component.js.map +1 -0
- package/src/lib/components/console/order-detail-dialog.component.d.ts +28 -0
- package/src/lib/components/console/order-detail-dialog.component.js +976 -0
- package/src/lib/components/console/order-detail-dialog.component.js.map +1 -0
- package/src/lib/components/console/paid-media.d.ts +127 -0
- package/src/lib/components/console/paid-media.js +397 -0
- package/src/lib/components/console/paid-media.js.map +1 -0
- package/src/lib/components/console/payments-settings-card.component.d.ts +13 -0
- package/src/lib/components/console/payments-settings-card.component.js +295 -0
- package/src/lib/components/console/payments-settings-card.component.js.map +1 -0
- package/src/lib/components/console/pos-page.component.d.ts +13 -0
- package/src/lib/components/console/pos-page.component.js +916 -0
- package/src/lib/components/console/pos-page.component.js.map +1 -0
- package/src/lib/components/console/product-editor-dialog.component.d.ts +32 -0
- package/src/lib/components/console/product-editor-dialog.component.js +1374 -0
- package/src/lib/components/console/product-editor-dialog.component.js.map +1 -0
- package/src/lib/components/console/products-hub-card.component.d.ts +16 -0
- package/src/lib/components/console/products-hub-card.component.js +1280 -0
- package/src/lib/components/console/products-hub-card.component.js.map +1 -0
- package/src/lib/components/console/products-hub-zone.component.d.ts +50 -0
- package/src/lib/components/console/products-hub-zone.component.js +200 -0
- package/src/lib/components/console/products-hub-zone.component.js.map +1 -0
- package/src/lib/components/console/recovery-queue-card.component.d.ts +39 -0
- package/src/lib/components/console/recovery-queue-card.component.js +262 -0
- package/src/lib/components/console/recovery-queue-card.component.js.map +1 -0
- package/src/lib/components/console/registers-card.component.d.ts +21 -0
- package/src/lib/components/console/registers-card.component.js +296 -0
- package/src/lib/components/console/registers-card.component.js.map +1 -0
- package/src/lib/components/console/reservations-card.component.d.ts +14 -0
- package/src/lib/components/console/reservations-card.component.js +650 -0
- package/src/lib/components/console/reservations-card.component.js.map +1 -0
- package/src/lib/components/console/reviews-moderation-card.component.d.ts +8 -0
- package/src/lib/components/console/reviews-moderation-card.component.js +235 -0
- package/src/lib/components/console/reviews-moderation-card.component.js.map +1 -0
- package/src/lib/components/console/shipping-settings-card.component.d.ts +38 -0
- package/src/lib/components/console/shipping-settings-card.component.js +560 -0
- package/src/lib/components/console/shipping-settings-card.component.js.map +1 -0
- package/src/lib/components/console/stock-movements-card.component.d.ts +31 -0
- package/src/lib/components/console/stock-movements-card.component.js +333 -0
- package/src/lib/components/console/stock-movements-card.component.js.map +1 -0
- package/src/lib/components/console/store-settings-card.component.d.ts +14 -0
- package/src/lib/components/console/store-settings-card.component.js +300 -0
- package/src/lib/components/console/store-settings-card.component.js.map +1 -0
- package/src/lib/components/console/storefront-tax-summary-card.component.d.ts +73 -0
- package/src/lib/components/console/storefront-tax-summary-card.component.js +408 -0
- package/src/lib/components/console/storefront-tax-summary-card.component.js.map +1 -0
- package/src/lib/components/console/suppliers-card.component.d.ts +8 -0
- package/src/lib/components/console/suppliers-card.component.js +328 -0
- package/src/lib/components/console/suppliers-card.component.js.map +1 -0
- package/src/lib/components/console/tax-settings-card.component.d.ts +14 -0
- package/src/lib/components/console/tax-settings-card.component.js +473 -0
- package/src/lib/components/console/tax-settings-card.component.js.map +1 -0
- package/src/lib/components/gate.d.ts +39 -0
- package/src/lib/components/gate.js +202 -0
- package/src/lib/components/gate.js.map +1 -0
- package/src/lib/components/gated-video.d.ts +40 -0
- package/src/lib/components/gated-video.js +366 -0
- package/src/lib/components/gated-video.js.map +1 -0
- package/src/lib/components/member-feed.d.ts +32 -0
- package/src/lib/components/member-feed.js +198 -0
- package/src/lib/components/member-feed.js.map +1 -0
- package/src/lib/components/member-recovery.d.ts +35 -0
- package/src/lib/components/member-recovery.js +313 -0
- package/src/lib/components/member-recovery.js.map +1 -0
- package/src/lib/components/member-signin.d.ts +35 -0
- package/src/lib/components/member-signin.js +257 -0
- package/src/lib/components/member-signin.js.map +1 -0
- package/src/lib/components/member-signup.d.ts +34 -0
- package/src/lib/components/member-signup.js +287 -0
- package/src/lib/components/member-signup.js.map +1 -0
- package/src/lib/components/newsletter-signup.d.ts +39 -0
- package/src/lib/components/newsletter-signup.js +229 -0
- package/src/lib/components/newsletter-signup.js.map +1 -0
- package/src/lib/components/product-detail.d.ts +38 -0
- package/src/lib/components/product-detail.js +1022 -0
- package/src/lib/components/product-detail.js.map +1 -0
- package/src/lib/components/product-grid.d.ts +67 -0
- package/src/lib/components/product-grid.js +909 -0
- package/src/lib/components/product-grid.js.map +1 -0
- package/src/lib/components/product-reviews.d.ts +32 -0
- package/src/lib/components/product-reviews.js +349 -0
- package/src/lib/components/product-reviews.js.map +1 -0
- package/src/lib/components/related-products.d.ts +33 -0
- package/src/lib/components/related-products.js +232 -0
- package/src/lib/components/related-products.js.map +1 -0
- package/src/lib/components/reservation-widget.d.ts +33 -0
- package/src/lib/components/reservation-widget.js +418 -0
- package/src/lib/components/reservation-widget.js.map +1 -0
- package/src/lib/components/storefront-payment-element-fallback.d.ts +18 -0
- package/src/lib/components/storefront-payment-element-fallback.js +51 -0
- package/src/lib/components/storefront-payment-element-fallback.js.map +1 -0
- package/src/lib/components/storefront-payment-element.d.ts +78 -0
- package/src/lib/components/storefront-payment-element.js +156 -0
- package/src/lib/components/storefront-payment-element.js.map +1 -0
- package/src/lib/components/wishlist.d.ts +46 -0
- package/src/lib/components/wishlist.js +304 -0
- package/src/lib/components/wishlist.js.map +1 -0
- package/src/lib/constants/bundle-common.d.ts +18 -0
- package/src/lib/constants/bundle-common.js +18 -0
- package/src/lib/constants/bundle-common.js.map +1 -0
- package/src/lib/constants/product-filters.d.ts +35 -0
- package/src/lib/constants/product-filters.js +109 -0
- package/src/lib/constants/product-filters.js.map +1 -0
- package/src/lib/model/commerce-cart.d.ts +52 -0
- package/src/lib/model/commerce-cart.js +102 -0
- package/src/lib/model/commerce-cart.js.map +1 -0
- package/src/lib/model/commerce-connect-transfer.d.ts +243 -0
- package/src/lib/model/commerce-connect-transfer.js +231 -0
- package/src/lib/model/commerce-connect-transfer.js.map +1 -0
- package/src/lib/model/commerce-discounts.d.ts +164 -0
- package/src/lib/model/commerce-discounts.js +231 -0
- package/src/lib/model/commerce-discounts.js.map +1 -0
- package/src/lib/model/commerce-dispute.d.ts +124 -0
- package/src/lib/model/commerce-dispute.js +225 -0
- package/src/lib/model/commerce-dispute.js.map +1 -0
- package/src/lib/model/commerce-gift-cards.d.ts +107 -0
- package/src/lib/model/commerce-gift-cards.js +121 -0
- package/src/lib/model/commerce-gift-cards.js.map +1 -0
- package/src/lib/model/commerce-io.d.ts +36 -0
- package/src/lib/model/commerce-io.js +245 -0
- package/src/lib/model/commerce-io.js.map +1 -0
- package/src/lib/model/commerce-orders.d.ts +1040 -0
- package/src/lib/model/commerce-orders.js +1022 -0
- package/src/lib/model/commerce-orders.js.map +1 -0
- package/src/lib/model/commerce-promotions.d.ts +188 -0
- package/src/lib/model/commerce-promotions.js +199 -0
- package/src/lib/model/commerce-promotions.js.map +1 -0
- package/src/lib/model/commerce-reservations.d.ts +175 -0
- package/src/lib/model/commerce-reservations.js +157 -0
- package/src/lib/model/commerce-reservations.js.map +1 -0
- package/src/lib/model/commerce-shipping.d.ts +316 -0
- package/src/lib/model/commerce-shipping.js +484 -0
- package/src/lib/model/commerce-shipping.js.map +1 -0
- package/src/lib/model/commerce-stock-holds.d.ts +199 -0
- package/src/lib/model/commerce-stock-holds.js +190 -0
- package/src/lib/model/commerce-stock-holds.js.map +1 -0
- package/src/lib/model/commerce-subscription-status.d.ts +67 -0
- package/src/lib/model/commerce-subscription-status.js +76 -0
- package/src/lib/model/commerce-subscription-status.js.map +1 -0
- package/src/lib/model/commerce-tax-decision.d.ts +222 -0
- package/src/lib/model/commerce-tax-decision.js +165 -0
- package/src/lib/model/commerce-tax-decision.js.map +1 -0
- package/src/lib/model/commerce-tax.d.ts +176 -0
- package/src/lib/model/commerce-tax.js +92 -0
- package/src/lib/model/commerce-tax.js.map +1 -0
- package/src/lib/model/commerce.d.ts +551 -0
- package/src/lib/model/commerce.js +739 -0
- package/src/lib/model/commerce.js.map +1 -0
- package/src/lib/model/index.d.ts +40 -0
- package/src/lib/model/index.js +40 -0
- package/src/lib/model/index.js.map +1 -0
- package/src/lib/model/order-figures.d.ts +48 -0
- package/src/lib/model/order-figures.js +74 -0
- package/src/lib/model/order-figures.js.map +1 -0
- package/src/lib/model/plugin-permissions.d.ts +23 -0
- package/src/lib/model/plugin-permissions.js +34 -0
- package/src/lib/model/plugin-permissions.js.map +1 -0
- package/src/lib/model/purchase-analytics.d.ts +186 -0
- package/src/lib/model/purchase-analytics.js +216 -0
- package/src/lib/model/purchase-analytics.js.map +1 -0
- package/src/lib/plugin-config.d.ts +62 -0
- package/src/lib/plugin-config.js +78 -0
- package/src/lib/plugin-config.js.map +1 -0
- package/src/lib/plugin.d.ts +28 -0
- package/src/lib/plugin.js +147 -0
- package/src/lib/plugin.js.map +1 -0
- package/src/lib/server/billing-webhook.d.ts +26 -0
- package/src/lib/server/billing-webhook.js +4011 -0
- package/src/lib/server/billing-webhook.js.map +1 -0
- package/src/lib/server/cancel-order.d.ts +87 -0
- package/src/lib/server/cancel-order.js +368 -0
- package/src/lib/server/cancel-order.js.map +1 -0
- package/src/lib/server/cart-checkout.d.ts +25 -0
- package/src/lib/server/cart-checkout.js +976 -0
- package/src/lib/server/cart-checkout.js.map +1 -0
- package/src/lib/server/cart-cookie.d.ts +32 -0
- package/src/lib/server/cart-cookie.js +77 -0
- package/src/lib/server/cart-cookie.js.map +1 -0
- package/src/lib/server/cart.d.ts +34 -0
- package/src/lib/server/cart.js +181 -0
- package/src/lib/server/cart.js.map +1 -0
- package/src/lib/server/catalog.d.ts +127 -0
- package/src/lib/server/catalog.js +277 -0
- package/src/lib/server/catalog.js.map +1 -0
- package/src/lib/server/checkout.d.ts +36 -0
- package/src/lib/server/checkout.js +915 -0
- package/src/lib/server/checkout.js.map +1 -0
- package/src/lib/server/connect.d.ts +26 -0
- package/src/lib/server/connect.js +238 -0
- package/src/lib/server/connect.js.map +1 -0
- package/src/lib/server/contact-refund.d.ts +117 -0
- package/src/lib/server/contact-refund.js +196 -0
- package/src/lib/server/contact-refund.js.map +1 -0
- package/src/lib/server/download.d.ts +39 -0
- package/src/lib/server/download.js +206 -0
- package/src/lib/server/download.js.map +1 -0
- package/src/lib/server/draft-order.d.ts +26 -0
- package/src/lib/server/draft-order.js +706 -0
- package/src/lib/server/draft-order.js.map +1 -0
- package/src/lib/server/feed.d.ts +24 -0
- package/src/lib/server/feed.js +59 -0
- package/src/lib/server/feed.js.map +1 -0
- package/src/lib/server/fulfill-order.d.ts +97 -0
- package/src/lib/server/fulfill-order.js +235 -0
- package/src/lib/server/fulfill-order.js.map +1 -0
- package/src/lib/server/gate.d.ts +36 -0
- package/src/lib/server/gate.js +112 -0
- package/src/lib/server/gate.js.map +1 -0
- package/src/lib/server/gift-cards.d.ts +42 -0
- package/src/lib/server/gift-cards.js +219 -0
- package/src/lib/server/gift-cards.js.map +1 -0
- package/src/lib/server/low-stock.d.ts +49 -0
- package/src/lib/server/low-stock.js +60 -0
- package/src/lib/server/low-stock.js.map +1 -0
- package/src/lib/server/manual-tax-rate.d.ts +82 -0
- package/src/lib/server/manual-tax-rate.js +113 -0
- package/src/lib/server/manual-tax-rate.js.map +1 -0
- package/src/lib/server/member-feed.d.ts +24 -0
- package/src/lib/server/member-feed.js +72 -0
- package/src/lib/server/member-feed.js.map +1 -0
- package/src/lib/server/member-name-search.d.ts +37 -0
- package/src/lib/server/member-name-search.js +42 -0
- package/src/lib/server/member-name-search.js.map +1 -0
- package/src/lib/server/member-post.d.ts +23 -0
- package/src/lib/server/member-post.js +166 -0
- package/src/lib/server/member-post.js.map +1 -0
- package/src/lib/server/membership-account.d.ts +37 -0
- package/src/lib/server/membership-account.js +148 -0
- package/src/lib/server/membership-account.js.map +1 -0
- package/src/lib/server/membership-admin-password.d.ts +33 -0
- package/src/lib/server/membership-admin-password.js +202 -0
- package/src/lib/server/membership-admin-password.js.map +1 -0
- package/src/lib/server/membership-content.d.ts +23 -0
- package/src/lib/server/membership-content.js +105 -0
- package/src/lib/server/membership-content.js.map +1 -0
- package/src/lib/server/membership-login.d.ts +19 -0
- package/src/lib/server/membership-login.js +137 -0
- package/src/lib/server/membership-login.js.map +1 -0
- package/src/lib/server/membership-logout.d.ts +19 -0
- package/src/lib/server/membership-logout.js +35 -0
- package/src/lib/server/membership-logout.js.map +1 -0
- package/src/lib/server/membership-recover.d.ts +60 -0
- package/src/lib/server/membership-recover.js +244 -0
- package/src/lib/server/membership-recover.js.map +1 -0
- package/src/lib/server/membership-register.d.ts +22 -0
- package/src/lib/server/membership-register.js +241 -0
- package/src/lib/server/membership-register.js.map +1 -0
- package/src/lib/server/membership-reset.d.ts +26 -0
- package/src/lib/server/membership-reset.js +88 -0
- package/src/lib/server/membership-reset.js.map +1 -0
- package/src/lib/server/membership-wishlist.d.ts +23 -0
- package/src/lib/server/membership-wishlist.js +89 -0
- package/src/lib/server/membership-wishlist.js.map +1 -0
- package/src/lib/server/membership.d.ts +96 -0
- package/src/lib/server/membership.js +222 -0
- package/src/lib/server/membership.js.map +1 -0
- package/src/lib/server/native-checkout.d.ts +170 -0
- package/src/lib/server/native-checkout.js +193 -0
- package/src/lib/server/native-checkout.js.map +1 -0
- package/src/lib/server/newsletter.d.ts +23 -0
- package/src/lib/server/newsletter.js +323 -0
- package/src/lib/server/newsletter.js.map +1 -0
- package/src/lib/server/notify-restock.d.ts +22 -0
- package/src/lib/server/notify-restock.js +84 -0
- package/src/lib/server/notify-restock.js.map +1 -0
- package/src/lib/server/order-analytics.d.ts +134 -0
- package/src/lib/server/order-analytics.js +263 -0
- package/src/lib/server/order-analytics.js.map +1 -0
- package/src/lib/server/order-figures.d.ts +33 -0
- package/src/lib/server/order-figures.js +220 -0
- package/src/lib/server/order-figures.js.map +1 -0
- package/src/lib/server/paid-media-delivery.d.ts +173 -0
- package/src/lib/server/paid-media-delivery.js +212 -0
- package/src/lib/server/paid-media-delivery.js.map +1 -0
- package/src/lib/server/pos-order.d.ts +54 -0
- package/src/lib/server/pos-order.js +1137 -0
- package/src/lib/server/pos-order.js.map +1 -0
- package/src/lib/server/process-abandoned.d.ts +54 -0
- package/src/lib/server/process-abandoned.js +222 -0
- package/src/lib/server/process-abandoned.js.map +1 -0
- package/src/lib/server/process-restock.d.ts +42 -0
- package/src/lib/server/process-restock.js +219 -0
- package/src/lib/server/process-restock.js.map +1 -0
- package/src/lib/server/product-card.d.ts +29 -0
- package/src/lib/server/product-card.js +54 -0
- package/src/lib/server/product-card.js.map +1 -0
- package/src/lib/server/product.d.ts +70 -0
- package/src/lib/server/product.js +105 -0
- package/src/lib/server/product.js.map +1 -0
- package/src/lib/server/promotion-hold.d.ts +144 -0
- package/src/lib/server/promotion-hold.js +174 -0
- package/src/lib/server/promotion-hold.js.map +1 -0
- package/src/lib/server/reconcile-stock.d.ts +106 -0
- package/src/lib/server/reconcile-stock.js +349 -0
- package/src/lib/server/reconcile-stock.js.map +1 -0
- package/src/lib/server/refund.d.ts +45 -0
- package/src/lib/server/refund.js +607 -0
- package/src/lib/server/refund.js.map +1 -0
- package/src/lib/server/related.d.ts +24 -0
- package/src/lib/server/related.js +104 -0
- package/src/lib/server/related.js.map +1 -0
- package/src/lib/server/reservation-availability.d.ts +23 -0
- package/src/lib/server/reservation-availability.js +111 -0
- package/src/lib/server/reservation-availability.js.map +1 -0
- package/src/lib/server/reserve-stock.d.ts +156 -0
- package/src/lib/server/reserve-stock.js +146 -0
- package/src/lib/server/reserve-stock.js.map +1 -0
- package/src/lib/server/reserve.d.ts +25 -0
- package/src/lib/server/reserve.js +426 -0
- package/src/lib/server/reserve.js.map +1 -0
- package/src/lib/server/restock-flag.d.ts +202 -0
- package/src/lib/server/restock-flag.js +449 -0
- package/src/lib/server/restock-flag.js.map +1 -0
- package/src/lib/server/reviews.d.ts +51 -0
- package/src/lib/server/reviews.js +132 -0
- package/src/lib/server/reviews.js.map +1 -0
- package/src/lib/server/site-page-enricher.d.ts +42 -0
- package/src/lib/server/site-page-enricher.js +149 -0
- package/src/lib/server/site-page-enricher.js.map +1 -0
- package/src/lib/server/site-page-resolver.d.ts +26 -0
- package/src/lib/server/site-page-resolver.js +223 -0
- package/src/lib/server/site-page-resolver.js.map +1 -0
- package/src/lib/server/stock-hold.d.ts +127 -0
- package/src/lib/server/stock-hold.js +258 -0
- package/src/lib/server/stock-hold.js.map +1 -0
- package/src/lib/server/storefront-tax-record.d.ts +22 -0
- package/src/lib/server/storefront-tax-record.js +218 -0
- package/src/lib/server/storefront-tax-record.js.map +1 -0
- package/src/lib/server/storefront-tax.d.ts +197 -0
- package/src/lib/server/storefront-tax.js +245 -0
- package/src/lib/server/storefront-tax.js.map +1 -0
- package/src/lib/server/stream.d.ts +25 -0
- package/src/lib/server/stream.js +191 -0
- package/src/lib/server/stream.js.map +1 -0
- package/src/lib/server/subscription-portal.d.ts +24 -0
- package/src/lib/server/subscription-portal.js +91 -0
- package/src/lib/server/subscription-portal.js.map +1 -0
- package/src/lib/server/supplier-outbox.d.ts +190 -0
- package/src/lib/server/supplier-outbox.js +342 -0
- package/src/lib/server/supplier-outbox.js.map +1 -0
- package/src/lib/server/supplier-update.d.ts +23 -0
- package/src/lib/server/supplier-update.js +289 -0
- package/src/lib/server/supplier-update.js.map +1 -0
- package/src/lib/server/tax-profile.d.ts +29 -0
- package/src/lib/server/tax-profile.js +40 -0
- package/src/lib/server/tax-profile.js.map +1 -0
- package/src/lib/server.d.ts +32 -0
- package/src/lib/server.js +311 -0
- package/src/lib/server.js.map +1 -0
- package/src/lib/site.d.ts +27 -0
- package/src/lib/site.js +134 -0
- package/src/lib/site.js.map +1 -0
- package/src/lib/utils/escape-html.d.ts +41 -0
- package/src/lib/utils/escape-html.js +41 -0
- package/src/lib/utils/escape-html.js.map +1 -0
- package/src/lib/utils/generate-preset-id.d.ts +19 -0
- package/src/lib/utils/generate-preset-id.js +25 -0
- package/src/lib/utils/generate-preset-id.js.map +1 -0
- package/src/lib/utils/member-continue.d.ts +45 -0
- package/src/lib/utils/member-continue.js +49 -0
- package/src/lib/utils/member-continue.js.map +1 -0
- package/src/lib/utils/use-storefront-purchase-event.d.ts +60 -0
- package/src/lib/utils/use-storefront-purchase-event.js +142 -0
- package/src/lib/utils/use-storefront-purchase-event.js.map +1 -0
|
@@ -0,0 +1,115 @@
|
|
|
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, Fragment as _Fragment } from "react/jsx-runtime";
|
|
18
|
+
import { checkEntitlement, planLabelGrantingFeature } from "@aglyn/aglyn";
|
|
19
|
+
import { AppLink, CardDisplay } from "@aglyn/shared-ui-jsx";
|
|
20
|
+
import { Alert, Typography } from "@mui/material";
|
|
21
|
+
import { useConsoleHostRoute, useOrgPlan } from "@aglyn/tenant-feature-instance";
|
|
22
|
+
/**
|
|
23
|
+
* The three-state entitlement read every commerce console surface needs
|
|
24
|
+
* (AGL-2080), factored out of the copy-pasted pair that
|
|
25
|
+
* `CommerceAnalyticsCard` and `CommerceGlanceCard` grew in AGL-2056.
|
|
26
|
+
*
|
|
27
|
+
* Three states, not two. `checkEntitlement(undefined)` resolves the FREE
|
|
28
|
+
* tier rather than "unknown", so a surface that refuses on `!entitled`
|
|
29
|
+
* alone shows a paying customer an upgrade prompt for the render or two
|
|
30
|
+
* their org doc is in flight. `ready` is the difference, and it is why this
|
|
31
|
+
* returns a struct rather than a boolean — a boolean is the API that caused
|
|
32
|
+
* the bug.
|
|
33
|
+
*
|
|
34
|
+
* `planLabel` comes from `planGrantingFeature`, derived from
|
|
35
|
+
* `PLAN_ENTITLEMENTS` on every call, so the upsell can never name a tier
|
|
36
|
+
* that no longer carries the feature.
|
|
37
|
+
*/ export function useCommerceEntitlement(hostId, feature) {
|
|
38
|
+
const consoleRoute = useConsoleHostRoute(hostId);
|
|
39
|
+
const { org, ready } = useOrgPlan(hostId);
|
|
40
|
+
return {
|
|
41
|
+
ready,
|
|
42
|
+
entitled: checkEntitlement(org, feature),
|
|
43
|
+
upgradeHref: consoleRoute.orgSlug ? `/${consoleRoute.orgSlug}/billing` : undefined,
|
|
44
|
+
planLabel: planLabelGrantingFeature(feature)
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The locked-state notice: what the feature is, which plan carries it, and
|
|
49
|
+
* one click to the plan grid.
|
|
50
|
+
*
|
|
51
|
+
* The plan name is not decoration. "This is a paid feature" is a dead end;
|
|
52
|
+
* "this is on Business" plus an Upgrade button is the upgrade path AGL-1859
|
|
53
|
+
* asks to keep prominent and one-click. Always `AppLink` — a MUI `href`
|
|
54
|
+
* bypasses the client router and full-reloads the console.
|
|
55
|
+
*/ export function EntitlementUpsell(props) {
|
|
56
|
+
const { children, planLabel, upgradeHref } = props;
|
|
57
|
+
return /*#__PURE__*/ _jsxs(Alert, {
|
|
58
|
+
severity: "info",
|
|
59
|
+
action: upgradeHref ? /*#__PURE__*/ _jsx(AppLink, {
|
|
60
|
+
componentVariant: "button",
|
|
61
|
+
color: "inherit",
|
|
62
|
+
size: "small",
|
|
63
|
+
href: upgradeHref,
|
|
64
|
+
children: 'Upgrade'
|
|
65
|
+
}) : undefined,
|
|
66
|
+
children: [
|
|
67
|
+
children,
|
|
68
|
+
planLabel ? ` Included from ${planLabel}.` : null
|
|
69
|
+
]
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* A whole console card behind an entitlement (AGL-2080).
|
|
74
|
+
*
|
|
75
|
+
* The refusal happens BEFORE the operator can configure anything, which is
|
|
76
|
+
* the entire point: five commerce features were fully configurable by an
|
|
77
|
+
* unentitled org and only failed at checkout — a refusal delivered to the
|
|
78
|
+
* buyer instead of the operator. A warning after configuration would be the
|
|
79
|
+
* same defect with better manners.
|
|
80
|
+
*/ export function EntitlementGatedCard(props) {
|
|
81
|
+
const { hostId, feature, header, help, upsell, children } = props;
|
|
82
|
+
const { ready, entitled, upgradeHref, planLabel } = useCommerceEntitlement(hostId, feature);
|
|
83
|
+
if (!ready) {
|
|
84
|
+
return /*#__PURE__*/ _jsx(CardDisplay, {
|
|
85
|
+
header: header,
|
|
86
|
+
help: help,
|
|
87
|
+
contentGutterX: true,
|
|
88
|
+
contentGutterY: true,
|
|
89
|
+
children: /*#__PURE__*/ _jsx(Typography, {
|
|
90
|
+
variant: "body2",
|
|
91
|
+
color: "text.secondary",
|
|
92
|
+
children: 'Checking your plan…'
|
|
93
|
+
})
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
if (!entitled) {
|
|
97
|
+
return /*#__PURE__*/ _jsx(CardDisplay, {
|
|
98
|
+
header: header,
|
|
99
|
+
help: help,
|
|
100
|
+
contentGutterX: true,
|
|
101
|
+
contentGutterY: true,
|
|
102
|
+
children: /*#__PURE__*/ _jsx(EntitlementUpsell, {
|
|
103
|
+
planLabel: planLabel,
|
|
104
|
+
upgradeHref: upgradeHref,
|
|
105
|
+
children: upsell
|
|
106
|
+
})
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return /*#__PURE__*/ _jsx(_Fragment, {
|
|
110
|
+
children: children
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
export default EntitlementGatedCard;
|
|
114
|
+
|
|
115
|
+
//# sourceMappingURL=entitlement-gate.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/entitlement-gate.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 { checkEntitlement, planLabelGrantingFeature } from '@aglyn/aglyn'\nimport type { OrgFeatureFlags } from '@aglyn/aglyn'\nimport {\n AppLink,\n CardDisplay,\n type HelpTipContent,\n} from '@aglyn/shared-ui-jsx'\nimport { Alert, Typography } from '@mui/material'\nimport type { ReactNode } from 'react'\nimport { useConsoleHostRoute, useOrgPlan } from '@aglyn/tenant-feature-instance'\n\nexport interface CommerceEntitlementState {\n /** The plan doc has settled. NEVER refuse before this is true. */\n ready: boolean\n entitled: boolean\n /** Console billing route, or undefined before the org slug resolves. */\n upgradeHref: string | undefined\n /** Cheapest plan carrying the feature — \"Business\". */\n planLabel: string | undefined\n}\n\n/**\n * The three-state entitlement read every commerce console surface needs\n * (AGL-2080), factored out of the copy-pasted pair that\n * `CommerceAnalyticsCard` and `CommerceGlanceCard` grew in AGL-2056.\n *\n * Three states, not two. `checkEntitlement(undefined)` resolves the FREE\n * tier rather than \"unknown\", so a surface that refuses on `!entitled`\n * alone shows a paying customer an upgrade prompt for the render or two\n * their org doc is in flight. `ready` is the difference, and it is why this\n * returns a struct rather than a boolean — a boolean is the API that caused\n * the bug.\n *\n * `planLabel` comes from `planGrantingFeature`, derived from\n * `PLAN_ENTITLEMENTS` on every call, so the upsell can never name a tier\n * that no longer carries the feature.\n */\nexport function useCommerceEntitlement(\n hostId: string | undefined,\n feature: keyof OrgFeatureFlags,\n): CommerceEntitlementState {\n const consoleRoute = useConsoleHostRoute(hostId)\n const { org, ready } = useOrgPlan(hostId)\n return {\n ready,\n entitled: checkEntitlement(org as never, feature),\n upgradeHref: consoleRoute.orgSlug\n ? `/${consoleRoute.orgSlug}/billing`\n : undefined,\n planLabel: planLabelGrantingFeature(feature),\n }\n}\n\nexport interface EntitlementUpsellProps {\n /** What the feature is and what it does, in the operator's terms. */\n children: ReactNode\n planLabel: string | undefined\n upgradeHref: string | undefined\n}\n\n/**\n * The locked-state notice: what the feature is, which plan carries it, and\n * one click to the plan grid.\n *\n * The plan name is not decoration. \"This is a paid feature\" is a dead end;\n * \"this is on Business\" plus an Upgrade button is the upgrade path AGL-1859\n * asks to keep prominent and one-click. Always `AppLink` — a MUI `href`\n * bypasses the client router and full-reloads the console.\n */\nexport function EntitlementUpsell(props: EntitlementUpsellProps) {\n const { children, planLabel, upgradeHref } = props\n return (\n <Alert\n severity=\"info\"\n action={\n upgradeHref ? (\n <AppLink\n componentVariant=\"button\"\n color=\"inherit\"\n size=\"small\"\n href={upgradeHref}\n >\n {'Upgrade'}\n </AppLink>\n ) : undefined\n }\n >\n {children}\n {planLabel ? ` Included from ${planLabel}.` : null}\n </Alert>\n )\n}\n\nexport interface EntitlementGatedCardProps {\n hostId: string\n feature: keyof OrgFeatureFlags\n header: string\n /**\n * Help affordance for the two branches this component renders itself\n * (AGL-2213).\n *\n * Required, not optional. The entitled branch renders `children`, which is\n * the real card and carries its own help; the branches rendered HERE are\n * \"checking your plan\" and the refusal — and the refusal is the one a\n * reader reaches precisely because they do not have what it takes. That is\n * the branch AGL-2130 found carrying no explanation on two console cards,\n * and an optional prop would let it happen again silently.\n */\n help: HelpTipContent\n /** Locked-state copy: what this does, so the upsell sells something. */\n upsell: ReactNode\n children: ReactNode\n}\n\n/**\n * A whole console card behind an entitlement (AGL-2080).\n *\n * The refusal happens BEFORE the operator can configure anything, which is\n * the entire point: five commerce features were fully configurable by an\n * unentitled org and only failed at checkout — a refusal delivered to the\n * buyer instead of the operator. A warning after configuration would be the\n * same defect with better manners.\n */\nexport function EntitlementGatedCard(props: EntitlementGatedCardProps) {\n const { hostId, feature, header, help, upsell, children } = props\n const { ready, entitled, upgradeHref, planLabel } = useCommerceEntitlement(\n hostId,\n feature,\n )\n\n if (!ready) {\n return (\n <CardDisplay header={header} help={help} contentGutterX contentGutterY>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Checking your plan…'}\n </Typography>\n </CardDisplay>\n )\n }\n\n if (!entitled) {\n return (\n <CardDisplay header={header} help={help} contentGutterX contentGutterY>\n <EntitlementUpsell planLabel={planLabel} upgradeHref={upgradeHref}>\n {upsell}\n </EntitlementUpsell>\n </CardDisplay>\n )\n }\n\n return <>{children}</>\n}\n\nexport default EntitlementGatedCard\n"],"names":["checkEntitlement","planLabelGrantingFeature","AppLink","CardDisplay","Alert","Typography","useConsoleHostRoute","useOrgPlan","useCommerceEntitlement","hostId","feature","consoleRoute","org","ready","entitled","upgradeHref","orgSlug","undefined","planLabel","EntitlementUpsell","props","children","severity","action","componentVariant","color","size","href","EntitlementGatedCard","header","help","upsell","contentGutterX","contentGutterY","variant"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GACD;;AAEA,SAASA,gBAAgB,EAAEC,wBAAwB,QAAQ,eAAc;AAEzE,SACEC,OAAO,EACPC,WAAW,QAEN,uBAAsB;AAC7B,SAASC,KAAK,EAAEC,UAAU,QAAQ,gBAAe;AAEjD,SAASC,mBAAmB,EAAEC,UAAU,QAAQ,iCAAgC;AAYhF;;;;;;;;;;;;;;;CAeC,GACD,OAAO,SAASC,uBACdC,MAA0B,EAC1BC,OAA8B;IAE9B,MAAMC,eAAeL,oBAAoBG;IACzC,MAAM,EAAEG,GAAG,EAAEC,KAAK,EAAE,GAAGN,WAAWE;IAClC,OAAO;QACLI;QACAC,UAAUd,iBAAiBY,KAAcF;QACzCK,aAAaJ,aAAaK,OAAO,GAC7B,CAAC,CAAC,EAAEL,aAAaK,OAAO,CAAC,QAAQ,CAAC,GAClCC;QACJC,WAAWjB,yBAAyBS;IACtC;AACF;AASA;;;;;;;;CAQC,GACD,OAAO,SAASS,kBAAkBC,KAA6B;IAC7D,MAAM,EAAEC,QAAQ,EAAEH,SAAS,EAAEH,WAAW,EAAE,GAAGK;IAC7C,qBACE,MAAChB;QACCkB,UAAS;QACTC,QACER,4BACE,KAACb;YACCsB,kBAAiB;YACjBC,OAAM;YACNC,MAAK;YACLC,MAAMZ;sBAEL;aAEDE;;YAGLI;YACAH,YAAY,CAAC,eAAe,EAAEA,UAAU,CAAC,CAAC,GAAG;;;AAGpD;AAuBA;;;;;;;;CAQC,GACD,OAAO,SAASU,qBAAqBR,KAAgC;IACnE,MAAM,EAAEX,MAAM,EAAEC,OAAO,EAAEmB,MAAM,EAAEC,IAAI,EAAEC,MAAM,EAAEV,QAAQ,EAAE,GAAGD;IAC5D,MAAM,EAAEP,KAAK,EAAEC,QAAQ,EAAEC,WAAW,EAAEG,SAAS,EAAE,GAAGV,uBAClDC,QACAC;IAGF,IAAI,CAACG,OAAO;QACV,qBACE,KAACV;YAAY0B,QAAQA;YAAQC,MAAMA;YAAME,cAAc;YAACC,cAAc;sBACpE,cAAA,KAAC5B;gBAAW6B,SAAQ;gBAAQT,OAAM;0BAC/B;;;IAIT;IAEA,IAAI,CAACX,UAAU;QACb,qBACE,KAACX;YAAY0B,QAAQA;YAAQC,MAAMA;YAAME,cAAc;YAACC,cAAc;sBACpE,cAAA,KAACd;gBAAkBD,WAAWA;gBAAWH,aAAaA;0BACnDgB;;;IAIT;IAEA,qBAAO;kBAAGV;;AACZ;AAEA,eAAeO,qBAAoB"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface GiftCardsCardProps {
|
|
2
|
+
hostId: string;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Gift cards & store credit (AGL-2226).
|
|
6
|
+
*
|
|
7
|
+
* `hosts/{hostId}/giftCards` has existed since AGL-322 with no console at
|
|
8
|
+
* either end: `billing-webhook.ts` mints a card when one is bought,
|
|
9
|
+
* `cart-checkout.ts` decrements it at redemption, and nothing in the product
|
|
10
|
+
* ever showed the merchant a code, a balance, or the total they owe.
|
|
11
|
+
*
|
|
12
|
+
* The total is the point. Outstanding gift-card balance is a real liability
|
|
13
|
+
* on the merchant's books, and it was invisible — which is also why AGL-1767
|
|
14
|
+
* (a redemption resurrecting a deleted card at a NEGATIVE balance,
|
|
15
|
+
* understating that liability) could not have been noticed from the console.
|
|
16
|
+
* The sum below deliberately floors each card at zero so a stray negative row
|
|
17
|
+
* cannot flatter the number the way that bug did.
|
|
18
|
+
*
|
|
19
|
+
* Reads are client-side because the Firestore host catch-all already grants
|
|
20
|
+
* them and the merchant wants the list live. The two operations that MOVE
|
|
21
|
+
* MONEY — issue and void — go through `commerce/gift-cards`, because that same
|
|
22
|
+
* catch-all would otherwise let any site admin write their own `balanceCents`
|
|
23
|
+
* and redeem it at checkout.
|
|
24
|
+
*/
|
|
25
|
+
export declare function GiftCardsCard(props: GiftCardsCardProps): import("react").JSX.Element;
|
|
26
|
+
export declare namespace GiftCardsCard {
|
|
27
|
+
var displayName: string;
|
|
28
|
+
}
|
|
29
|
+
export default GiftCardsCard;
|
|
@@ -0,0 +1,379 @@
|
|
|
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 { _ as _extends } from "@swc/helpers/_/_extends";
|
|
18
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
19
|
+
import { CardDisplay, useConfirmationContext } from "@aglyn/shared-ui-jsx";
|
|
20
|
+
import { ListPagination } from "@aglyn/shared-ui-jsx/components/list-pagination.component";
|
|
21
|
+
import { useSnackbar } from "@aglyn/shared-ui-snackstack";
|
|
22
|
+
import { Button, Chip, Stack, TextField, Typography } from "@mui/material";
|
|
23
|
+
import { collection, count, getAggregateFromServer, limit, orderBy, query, sum, where } from "firebase/firestore";
|
|
24
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
25
|
+
import { useFirestore, usePagedCollection, useUser } from "@aglyn/tenant-feature-instance";
|
|
26
|
+
import { pluginDocsHelp } from "@aglyn/aglyn";
|
|
27
|
+
import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
|
|
28
|
+
import { EntitlementGatedCard } from "./entitlement-gate.component.js";
|
|
29
|
+
const usd = (cents)=>`$${((cents != null ? cents : 0) / 100).toFixed(2)}`;
|
|
30
|
+
const giftCardsHelp = pluginDocsHelp('commerce', {
|
|
31
|
+
anchor: '#gift-cards',
|
|
32
|
+
title: 'Gift cards',
|
|
33
|
+
excerpt: 'Every gift card your store has issued, what is left on it, and what ' + 'that adds up to in outstanding store credit.'
|
|
34
|
+
});
|
|
35
|
+
/**
|
|
36
|
+
* Gift cards & store credit (AGL-2226).
|
|
37
|
+
*
|
|
38
|
+
* `hosts/{hostId}/giftCards` has existed since AGL-322 with no console at
|
|
39
|
+
* either end: `billing-webhook.ts` mints a card when one is bought,
|
|
40
|
+
* `cart-checkout.ts` decrements it at redemption, and nothing in the product
|
|
41
|
+
* ever showed the merchant a code, a balance, or the total they owe.
|
|
42
|
+
*
|
|
43
|
+
* The total is the point. Outstanding gift-card balance is a real liability
|
|
44
|
+
* on the merchant's books, and it was invisible — which is also why AGL-1767
|
|
45
|
+
* (a redemption resurrecting a deleted card at a NEGATIVE balance,
|
|
46
|
+
* understating that liability) could not have been noticed from the console.
|
|
47
|
+
* The sum below deliberately floors each card at zero so a stray negative row
|
|
48
|
+
* cannot flatter the number the way that bug did.
|
|
49
|
+
*
|
|
50
|
+
* Reads are client-side because the Firestore host catch-all already grants
|
|
51
|
+
* them and the merchant wants the list live. The two operations that MOVE
|
|
52
|
+
* MONEY — issue and void — go through `commerce/gift-cards`, because that same
|
|
53
|
+
* catch-all would otherwise let any site admin write their own `balanceCents`
|
|
54
|
+
* and redeem it at checkout.
|
|
55
|
+
*/ export function GiftCardsCard(props) {
|
|
56
|
+
const { hostId } = props;
|
|
57
|
+
const firestore = useFirestore();
|
|
58
|
+
const { data: user } = useUser();
|
|
59
|
+
const { enqueueSnackbar } = useSnackbar();
|
|
60
|
+
const { confirm } = useConfirmationContext();
|
|
61
|
+
/*
|
|
62
|
+
* Ordered by the server, and a growing window rather than a fixed 300.
|
|
63
|
+
*
|
|
64
|
+
* `limit(300)` with no `orderBy` returns DOCUMENT-ID order, and a gift card
|
|
65
|
+
* is keyed by its CODE, so the window was three hundred cards chosen by
|
|
66
|
+
* code — sorted by date afterwards to look newest-first. Past three hundred
|
|
67
|
+
* cards, one issued this morning was not in it.
|
|
68
|
+
*/ const { rows: allCards, hasMore, page, setPage, pageSize, setPageSize } = usePagedCollection((pageLimit)=>query(collection(firestore, 'hosts', hostId, 'giftCards'), orderBy('createdAtMs', 'desc'), limit(pageLimit)), [
|
|
69
|
+
firestore,
|
|
70
|
+
hostId
|
|
71
|
+
], {
|
|
72
|
+
idField: '$id'
|
|
73
|
+
});
|
|
74
|
+
const [search, setSearch] = useState('');
|
|
75
|
+
const [amount, setAmount] = useState('');
|
|
76
|
+
const [recipient, setRecipient] = useState('');
|
|
77
|
+
const [busy, setBusy] = useState(false);
|
|
78
|
+
const cards = useMemo(()=>{
|
|
79
|
+
const term = search.trim().toUpperCase();
|
|
80
|
+
if (!term) return allCards;
|
|
81
|
+
return allCards.filter((card)=>{
|
|
82
|
+
var _card_recipientEmail;
|
|
83
|
+
return card.$id.includes(term) || String((_card_recipientEmail = card.recipientEmail) != null ? _card_recipientEmail : '').toUpperCase().includes(term);
|
|
84
|
+
});
|
|
85
|
+
}, [
|
|
86
|
+
allCards,
|
|
87
|
+
search
|
|
88
|
+
]);
|
|
89
|
+
/*==========================================
|
|
90
|
+
* OUTSTANDING LIABILITY IS A SERVER AGGREGATE, not a page total.
|
|
91
|
+
*
|
|
92
|
+
* These two numbers are what the merchant owes their customers, and they
|
|
93
|
+
* were `reduce`d over whatever the window happened to hold — 300 cards
|
|
94
|
+
* chosen by code. A shop with 400 gift cards under-reported its own
|
|
95
|
+
* liability and had no way to know: the chip does not say "of the cards on
|
|
96
|
+
* screen", and there is no reading of "$X outstanding" under which a
|
|
97
|
+
* sample is the answer.
|
|
98
|
+
*
|
|
99
|
+
* `where('balanceCents','>',0)` IS the per-card floor the reduce applied
|
|
100
|
+
* by hand. A negative balance is a data fault (AGL-1767), not credit the
|
|
101
|
+
* merchant gets back; excluding it contributes zero, exactly as flooring
|
|
102
|
+
* it did. Zero-balance cards contribute nothing either way and are what
|
|
103
|
+
* `liveCount` was already counting.
|
|
104
|
+
*
|
|
105
|
+
* An aggregation is billed per 1,000 documents scanned rather than per
|
|
106
|
+
* document, so this is cheaper than the read it replaces as well as
|
|
107
|
+
* correct.
|
|
108
|
+
*=========================================*/ const [totalsEpoch, setTotalsEpoch] = useState(0);
|
|
109
|
+
const [totals, setTotals] = useState(null);
|
|
110
|
+
useEffect(()=>{
|
|
111
|
+
let active = true;
|
|
112
|
+
const cardsRef = collection(firestore, 'hosts', hostId, 'giftCards');
|
|
113
|
+
void Promise.all([
|
|
114
|
+
getAggregateFromServer(query(cardsRef, where('balanceCents', '>', 0)), {
|
|
115
|
+
outstandingCents: sum('balanceCents'),
|
|
116
|
+
liveCount: count()
|
|
117
|
+
}),
|
|
118
|
+
// "Issued" is every card ever, so this one carries no predicate.
|
|
119
|
+
getAggregateFromServer(cardsRef, {
|
|
120
|
+
issuedCount: count()
|
|
121
|
+
})
|
|
122
|
+
]).then(([balances, issued])=>{
|
|
123
|
+
var _balances_data_outstandingCents, _balances_data_liveCount, _issued_data_issuedCount;
|
|
124
|
+
if (!active) return;
|
|
125
|
+
setTotals({
|
|
126
|
+
outstandingCents: Number((_balances_data_outstandingCents = balances.data().outstandingCents) != null ? _balances_data_outstandingCents : 0),
|
|
127
|
+
liveCount: Number((_balances_data_liveCount = balances.data().liveCount) != null ? _balances_data_liveCount : 0),
|
|
128
|
+
issuedCount: Number((_issued_data_issuedCount = issued.data().issuedCount) != null ? _issued_data_issuedCount : 0)
|
|
129
|
+
});
|
|
130
|
+
}).catch(()=>{
|
|
131
|
+
// Held at null rather than zeroed. "$0.00 outstanding" is a
|
|
132
|
+
// confident wrong number in the flattering direction; an absent one
|
|
133
|
+
// renders as unknown and cannot be mistaken for a settled book.
|
|
134
|
+
if (active) setTotals(null);
|
|
135
|
+
});
|
|
136
|
+
return ()=>{
|
|
137
|
+
active = false;
|
|
138
|
+
};
|
|
139
|
+
}, [
|
|
140
|
+
firestore,
|
|
141
|
+
hostId,
|
|
142
|
+
totalsEpoch
|
|
143
|
+
]);
|
|
144
|
+
const post = useCallback(async (payload, success)=>{
|
|
145
|
+
setBusy(true);
|
|
146
|
+
try {
|
|
147
|
+
const response = await authorizedFetch(user, '/api/commerce/gift-cards', {
|
|
148
|
+
method: 'POST',
|
|
149
|
+
headers: {
|
|
150
|
+
'Content-Type': 'application/json'
|
|
151
|
+
},
|
|
152
|
+
body: JSON.stringify(_extends({
|
|
153
|
+
hostId
|
|
154
|
+
}, payload))
|
|
155
|
+
});
|
|
156
|
+
const body = await response.json().catch(()=>({}));
|
|
157
|
+
if (!response.ok) {
|
|
158
|
+
var _ref;
|
|
159
|
+
return void enqueueSnackbar((_ref = body == null ? void 0 : body.error) != null ? _ref : 'Gift card action failed', {
|
|
160
|
+
variant: 'error',
|
|
161
|
+
allowDuplicate: true
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
enqueueSnackbar(success(body), {
|
|
165
|
+
variant: 'success',
|
|
166
|
+
persist: false
|
|
167
|
+
});
|
|
168
|
+
// Issuing, voiding or adjusting moves the liability. The list is a
|
|
169
|
+
// live listener and updates itself; the aggregate is a one-shot read
|
|
170
|
+
// and would otherwise keep reporting the balance from before.
|
|
171
|
+
setTotalsEpoch((epoch)=>epoch + 1);
|
|
172
|
+
} finally{
|
|
173
|
+
setBusy(false);
|
|
174
|
+
}
|
|
175
|
+
}, [
|
|
176
|
+
user,
|
|
177
|
+
hostId,
|
|
178
|
+
enqueueSnackbar
|
|
179
|
+
]);
|
|
180
|
+
const handleIssue = useCallback(async ()=>{
|
|
181
|
+
const dollars = Number(amount);
|
|
182
|
+
if (!Number.isFinite(dollars) || dollars <= 0) {
|
|
183
|
+
return void enqueueSnackbar('Enter an amount above zero', {
|
|
184
|
+
variant: 'error',
|
|
185
|
+
allowDuplicate: true
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
await post({
|
|
189
|
+
action: 'issue',
|
|
190
|
+
amountCents: Math.round(dollars * 100),
|
|
191
|
+
recipientEmail: recipient.trim()
|
|
192
|
+
}, (body)=>body.emailed ? `Issued ${body.code} — emailed to ${recipient.trim()}` : `Issued ${body.code}`);
|
|
193
|
+
setAmount('');
|
|
194
|
+
setRecipient('');
|
|
195
|
+
}, [
|
|
196
|
+
amount,
|
|
197
|
+
recipient,
|
|
198
|
+
post,
|
|
199
|
+
enqueueSnackbar
|
|
200
|
+
]);
|
|
201
|
+
const handleVoid = useCallback(async (card)=>{
|
|
202
|
+
// This provider REJECTS on dismissal rather than resolving false, so
|
|
203
|
+
// the `.then/.catch` pair is the read — awaiting the promise bare would
|
|
204
|
+
// throw out of the handler on a cancel.
|
|
205
|
+
const confirmed = await confirm({
|
|
206
|
+
title: `Void ${card.$id}?`,
|
|
207
|
+
description: `This zeroes the ${usd(card.balanceCents)} left on the card. The ` + 'holder will no longer be able to redeem it, and it cannot be undone.',
|
|
208
|
+
confirmationText: 'Void gift card',
|
|
209
|
+
confirmationButtonProps: {
|
|
210
|
+
color: 'error'
|
|
211
|
+
}
|
|
212
|
+
}).then(()=>true).catch(()=>false);
|
|
213
|
+
if (!confirmed) return;
|
|
214
|
+
await post({
|
|
215
|
+
action: 'void',
|
|
216
|
+
code: card.$id
|
|
217
|
+
}, ()=>`${card.$id} voided`);
|
|
218
|
+
}, [
|
|
219
|
+
confirm,
|
|
220
|
+
post
|
|
221
|
+
]);
|
|
222
|
+
return /*#__PURE__*/ _jsx(EntitlementGatedCard, {
|
|
223
|
+
help: giftCardsHelp,
|
|
224
|
+
hostId: hostId,
|
|
225
|
+
feature: "giftCards",
|
|
226
|
+
header: 'Gift cards',
|
|
227
|
+
upsell: 'Gift cards let shoppers buy store credit for someone else, and let ' + 'you issue credit by hand for a goodwill gesture or a service ' + 'recovery. Balances apply automatically at checkout.',
|
|
228
|
+
children: /*#__PURE__*/ _jsx(CardDisplay, {
|
|
229
|
+
header: 'Gift cards',
|
|
230
|
+
help: giftCardsHelp,
|
|
231
|
+
contentGutterX: true,
|
|
232
|
+
contentGutterY: true,
|
|
233
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
234
|
+
spacing: 2,
|
|
235
|
+
children: [
|
|
236
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
237
|
+
direction: "row",
|
|
238
|
+
spacing: 1,
|
|
239
|
+
useFlexGap: true,
|
|
240
|
+
sx: {
|
|
241
|
+
flexWrap: 'wrap'
|
|
242
|
+
},
|
|
243
|
+
children: [
|
|
244
|
+
/*#__PURE__*/ _jsx(Chip, {
|
|
245
|
+
size: "small",
|
|
246
|
+
color: (totals == null ? void 0 : totals.outstandingCents) ? 'warning' : 'default',
|
|
247
|
+
label: totals ? `${usd(totals.outstandingCents)} outstanding` : 'Outstanding unavailable'
|
|
248
|
+
}),
|
|
249
|
+
totals ? /*#__PURE__*/ _jsx(Chip, {
|
|
250
|
+
size: "small",
|
|
251
|
+
label: `${totals.liveCount} with a balance`
|
|
252
|
+
}) : null,
|
|
253
|
+
totals ? /*#__PURE__*/ _jsx(Chip, {
|
|
254
|
+
size: "small",
|
|
255
|
+
label: `${totals.issuedCount} issued`
|
|
256
|
+
}) : null
|
|
257
|
+
]
|
|
258
|
+
}),
|
|
259
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
260
|
+
variant: "caption",
|
|
261
|
+
color: "text.secondary",
|
|
262
|
+
children: 'Outstanding balance is store credit your customers have already ' + 'paid for and not yet spent — it is a liability, not revenue.'
|
|
263
|
+
}),
|
|
264
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
265
|
+
direction: "row",
|
|
266
|
+
spacing: 1,
|
|
267
|
+
useFlexGap: true,
|
|
268
|
+
sx: {
|
|
269
|
+
flexWrap: 'wrap'
|
|
270
|
+
},
|
|
271
|
+
children: [
|
|
272
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
273
|
+
label: "Issue amount (USD)",
|
|
274
|
+
value: amount,
|
|
275
|
+
onChange: (event)=>setAmount(event.target.value),
|
|
276
|
+
size: "small",
|
|
277
|
+
type: "number",
|
|
278
|
+
sx: {
|
|
279
|
+
maxWidth: 180
|
|
280
|
+
}
|
|
281
|
+
}),
|
|
282
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
283
|
+
label: "Email it to (optional)",
|
|
284
|
+
value: recipient,
|
|
285
|
+
onChange: (event)=>setRecipient(event.target.value),
|
|
286
|
+
size: "small",
|
|
287
|
+
sx: {
|
|
288
|
+
minWidth: 240
|
|
289
|
+
}
|
|
290
|
+
}),
|
|
291
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
292
|
+
variant: "contained",
|
|
293
|
+
size: "small",
|
|
294
|
+
disabled: busy || !amount,
|
|
295
|
+
onClick: handleIssue,
|
|
296
|
+
children: 'Issue card'
|
|
297
|
+
})
|
|
298
|
+
]
|
|
299
|
+
}),
|
|
300
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
301
|
+
label: "Find in the cards below",
|
|
302
|
+
value: search,
|
|
303
|
+
onChange: (event)=>setSearch(event.target.value),
|
|
304
|
+
size: "small",
|
|
305
|
+
sx: {
|
|
306
|
+
maxWidth: 320
|
|
307
|
+
}
|
|
308
|
+
}),
|
|
309
|
+
cards.length ? /*#__PURE__*/ _jsx(Stack, {
|
|
310
|
+
spacing: 1,
|
|
311
|
+
children: cards.map((card)=>{
|
|
312
|
+
var _card_balanceCents, _card_balanceCents1;
|
|
313
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
314
|
+
direction: "row",
|
|
315
|
+
spacing: 1,
|
|
316
|
+
useFlexGap: true,
|
|
317
|
+
sx: {
|
|
318
|
+
flexWrap: 'wrap',
|
|
319
|
+
alignItems: 'center'
|
|
320
|
+
},
|
|
321
|
+
children: [
|
|
322
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
323
|
+
variant: "body2",
|
|
324
|
+
sx: {
|
|
325
|
+
fontFamily: 'monospace'
|
|
326
|
+
},
|
|
327
|
+
children: card.$id
|
|
328
|
+
}),
|
|
329
|
+
/*#__PURE__*/ _jsx(Chip, {
|
|
330
|
+
size: "small",
|
|
331
|
+
color: Number((_card_balanceCents = card.balanceCents) != null ? _card_balanceCents : 0) > 0 ? 'success' : 'default',
|
|
332
|
+
label: `${usd(card.balanceCents)} of ${usd(card.initialCents)}`
|
|
333
|
+
}),
|
|
334
|
+
card.recipientEmail ? /*#__PURE__*/ _jsx(Typography, {
|
|
335
|
+
variant: "body2",
|
|
336
|
+
color: "text.secondary",
|
|
337
|
+
children: card.recipientEmail
|
|
338
|
+
}) : null,
|
|
339
|
+
card.orderId ? null : /*#__PURE__*/ _jsx(Chip, {
|
|
340
|
+
size: "small",
|
|
341
|
+
variant: "outlined",
|
|
342
|
+
label: 'Issued by hand'
|
|
343
|
+
}),
|
|
344
|
+
card.voidedAtMs ? /*#__PURE__*/ _jsx(Chip, {
|
|
345
|
+
size: "small",
|
|
346
|
+
variant: "outlined",
|
|
347
|
+
label: 'Voided'
|
|
348
|
+
}) : Number((_card_balanceCents1 = card.balanceCents) != null ? _card_balanceCents1 : 0) > 0 ? /*#__PURE__*/ _jsx(Button, {
|
|
349
|
+
size: "small",
|
|
350
|
+
color: "error",
|
|
351
|
+
disabled: busy,
|
|
352
|
+
onClick: ()=>handleVoid(card),
|
|
353
|
+
children: 'Void'
|
|
354
|
+
}) : null
|
|
355
|
+
]
|
|
356
|
+
}, card.$id);
|
|
357
|
+
})
|
|
358
|
+
}) : /*#__PURE__*/ _jsx(Typography, {
|
|
359
|
+
variant: "body2",
|
|
360
|
+
color: "text.secondary",
|
|
361
|
+
children: search ? 'No gift card on this page matches that code or email — ' + 'the search reads the page in front of you.' : 'No gift cards yet. Sell a gift-card product, or issue one above.'
|
|
362
|
+
}),
|
|
363
|
+
/*#__PURE__*/ _jsx(ListPagination, {
|
|
364
|
+
page: page,
|
|
365
|
+
pageSize: pageSize,
|
|
366
|
+
rowCount: cards.length,
|
|
367
|
+
hasMore: hasMore,
|
|
368
|
+
onPageChange: setPage,
|
|
369
|
+
onPageSizeChange: setPageSize
|
|
370
|
+
})
|
|
371
|
+
]
|
|
372
|
+
})
|
|
373
|
+
})
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
GiftCardsCard.displayName = 'GiftCardsCard';
|
|
377
|
+
export default GiftCardsCard;
|
|
378
|
+
|
|
379
|
+
//# sourceMappingURL=gift-cards-card.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/plugins/commerce/src/lib/components/console/gift-cards-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 { CardDisplay, useConfirmationContext } from '@aglyn/shared-ui-jsx'\nimport { ListPagination } from '@aglyn/shared-ui-jsx/components/list-pagination.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport {\n Button,\n Chip,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport {\n collection,\n count,\n getAggregateFromServer,\n limit,\n orderBy,\n query,\n sum,\n where,\n} from 'firebase/firestore'\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport {\n useFirestore,\n usePagedCollection,\n useUser,\n} from '@aglyn/tenant-feature-instance'\nimport { pluginDocsHelp } from '@aglyn/aglyn'\nimport { authorizedFetch } from '@aglyn/shared-util-http/authorized-token'\nimport { EntitlementGatedCard } from './entitlement-gate.component'\n\nexport interface GiftCardsCardProps {\n hostId: string\n}\n\nconst usd = (cents: number | undefined) => `$${((cents ?? 0) / 100).toFixed(2)}`\n\nconst giftCardsHelp = pluginDocsHelp('commerce', {\n anchor: '#gift-cards',\n title: 'Gift cards',\n excerpt:\n 'Every gift card your store has issued, what is left on it, and what ' +\n 'that adds up to in outstanding store credit.',\n})\n\n/**\n * Gift cards & store credit (AGL-2226).\n *\n * `hosts/{hostId}/giftCards` has existed since AGL-322 with no console at\n * either end: `billing-webhook.ts` mints a card when one is bought,\n * `cart-checkout.ts` decrements it at redemption, and nothing in the product\n * ever showed the merchant a code, a balance, or the total they owe.\n *\n * The total is the point. Outstanding gift-card balance is a real liability\n * on the merchant's books, and it was invisible — which is also why AGL-1767\n * (a redemption resurrecting a deleted card at a NEGATIVE balance,\n * understating that liability) could not have been noticed from the console.\n * The sum below deliberately floors each card at zero so a stray negative row\n * cannot flatter the number the way that bug did.\n *\n * Reads are client-side because the Firestore host catch-all already grants\n * them and the merchant wants the list live. The two operations that MOVE\n * MONEY — issue and void — go through `commerce/gift-cards`, because that same\n * catch-all would otherwise let any site admin write their own `balanceCents`\n * and redeem it at checkout.\n */\nexport function GiftCardsCard(props: GiftCardsCardProps) {\n const { hostId } = props\n const firestore = useFirestore()\n const { data: user } = useUser()\n const { enqueueSnackbar } = useSnackbar()\n const { confirm } = useConfirmationContext()\n /*\n * Ordered by the server, and a growing window rather than a fixed 300.\n *\n * `limit(300)` with no `orderBy` returns DOCUMENT-ID order, and a gift card\n * is keyed by its CODE, so the window was three hundred cards chosen by\n * code — sorted by date afterwards to look newest-first. Past three hundred\n * cards, one issued this morning was not in it.\n */\n const {\n rows: allCards,\n hasMore,\n page,\n setPage,\n pageSize,\n setPageSize,\n } = usePagedCollection<any>(\n (pageLimit) =>\n query(\n collection(firestore, 'hosts', hostId, 'giftCards'),\n orderBy('createdAtMs', 'desc'),\n limit(pageLimit),\n ),\n [firestore, hostId],\n { idField: '$id' },\n )\n const [search, setSearch] = useState('')\n const [amount, setAmount] = useState('')\n const [recipient, setRecipient] = useState('')\n const [busy, setBusy] = useState(false)\n\n const cards = useMemo(() => {\n const term = search.trim().toUpperCase()\n if (!term) return allCards\n return allCards.filter(\n (card: any) =>\n card.$id.includes(term) ||\n String(card.recipientEmail ?? '').toUpperCase().includes(term),\n )\n }, [allCards, search])\n\n /*==========================================\n * OUTSTANDING LIABILITY IS A SERVER AGGREGATE, not a page total.\n *\n * These two numbers are what the merchant owes their customers, and they\n * were `reduce`d over whatever the window happened to hold — 300 cards\n * chosen by code. A shop with 400 gift cards under-reported its own\n * liability and had no way to know: the chip does not say \"of the cards on\n * screen\", and there is no reading of \"$X outstanding\" under which a\n * sample is the answer.\n *\n * `where('balanceCents','>',0)` IS the per-card floor the reduce applied\n * by hand. A negative balance is a data fault (AGL-1767), not credit the\n * merchant gets back; excluding it contributes zero, exactly as flooring\n * it did. Zero-balance cards contribute nothing either way and are what\n * `liveCount` was already counting.\n *\n * An aggregation is billed per 1,000 documents scanned rather than per\n * document, so this is cheaper than the read it replaces as well as\n * correct.\n *=========================================*/\n const [totalsEpoch, setTotalsEpoch] = useState(0)\n const [totals, setTotals] = useState<{\n outstandingCents: number\n liveCount: number\n issuedCount: number\n } | null>(null)\n useEffect(() => {\n let active = true\n const cardsRef = collection(firestore, 'hosts', hostId, 'giftCards')\n void Promise.all([\n getAggregateFromServer(query(cardsRef, where('balanceCents', '>', 0)), {\n outstandingCents: sum('balanceCents'),\n liveCount: count(),\n }),\n // \"Issued\" is every card ever, so this one carries no predicate.\n getAggregateFromServer(cardsRef, { issuedCount: count() }),\n ])\n .then(([balances, issued]) => {\n if (!active) return\n setTotals({\n outstandingCents: Number(balances.data().outstandingCents ?? 0),\n liveCount: Number(balances.data().liveCount ?? 0),\n issuedCount: Number(issued.data().issuedCount ?? 0),\n })\n })\n .catch(() => {\n // Held at null rather than zeroed. \"$0.00 outstanding\" is a\n // confident wrong number in the flattering direction; an absent one\n // renders as unknown and cannot be mistaken for a settled book.\n if (active) setTotals(null)\n })\n return () => {\n active = false\n }\n }, [firestore, hostId, totalsEpoch])\n\n const post = useCallback(\n async (payload: Record<string, unknown>, success: (body: any) => string) => {\n setBusy(true)\n try {\n const response = await authorizedFetch(\n user,\n '/api/commerce/gift-cards',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ hostId, ...payload }),\n },\n )\n const body = await response.json().catch(() => ({}))\n if (!response.ok) {\n return void enqueueSnackbar(body?.error ?? 'Gift card action failed', {\n variant: 'error',\n allowDuplicate: true,\n })\n }\n enqueueSnackbar(success(body), { variant: 'success', persist: false })\n // Issuing, voiding or adjusting moves the liability. The list is a\n // live listener and updates itself; the aggregate is a one-shot read\n // and would otherwise keep reporting the balance from before.\n setTotalsEpoch((epoch) => epoch + 1)\n } finally {\n setBusy(false)\n }\n },\n [user, hostId, enqueueSnackbar],\n )\n\n const handleIssue = useCallback(async () => {\n const dollars = Number(amount)\n if (!Number.isFinite(dollars) || dollars <= 0) {\n return void enqueueSnackbar('Enter an amount above zero', {\n variant: 'error',\n allowDuplicate: true,\n })\n }\n await post(\n {\n action: 'issue',\n amountCents: Math.round(dollars * 100),\n recipientEmail: recipient.trim(),\n },\n (body) =>\n body.emailed\n ? `Issued ${body.code} — emailed to ${recipient.trim()}`\n : `Issued ${body.code}`,\n )\n setAmount('')\n setRecipient('')\n }, [amount, recipient, post, enqueueSnackbar])\n\n const handleVoid = useCallback(\n async (card: any) => {\n // This provider REJECTS on dismissal rather than resolving false, so\n // the `.then/.catch` pair is the read — awaiting the promise bare would\n // throw out of the handler on a cancel.\n const confirmed = await confirm({\n title: `Void ${card.$id}?`,\n description:\n `This zeroes the ${usd(card.balanceCents)} left on the card. The ` +\n 'holder will no longer be able to redeem it, and it cannot be undone.',\n confirmationText: 'Void gift card',\n confirmationButtonProps: { color: 'error' },\n })\n .then(() => true)\n .catch(() => false)\n if (!confirmed) return\n await post({ action: 'void', code: card.$id }, () => `${card.$id} voided`)\n },\n [confirm, post],\n )\n\n return (\n <EntitlementGatedCard\n help={giftCardsHelp}\n hostId={hostId}\n feature=\"giftCards\"\n header={'Gift cards'}\n upsell={\n 'Gift cards let shoppers buy store credit for someone else, and let ' +\n 'you issue credit by hand for a goodwill gesture or a service ' +\n 'recovery. Balances apply automatically at checkout.'\n }\n >\n <CardDisplay\n header={'Gift cards'}\n help={giftCardsHelp}\n contentGutterX\n contentGutterY\n >\n <Stack spacing={2}>\n <Stack direction=\"row\" spacing={1} useFlexGap sx={{ flexWrap: 'wrap' }}>\n <Chip\n size=\"small\"\n color={totals?.outstandingCents ? 'warning' : 'default'}\n label={\n totals\n ? `${usd(totals.outstandingCents)} outstanding`\n : 'Outstanding unavailable'\n }\n />\n {totals ? (\n <Chip\n size=\"small\"\n label={`${totals.liveCount} with a balance`}\n />\n ) : null}\n {totals ? (\n <Chip size=\"small\" label={`${totals.issuedCount} issued`} />\n ) : null}\n </Stack>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'Outstanding balance is store credit your customers have already ' +\n 'paid for and not yet spent — it is a liability, not revenue.'}\n </Typography>\n\n <Stack direction=\"row\" spacing={1} useFlexGap sx={{ flexWrap: 'wrap' }}>\n <TextField\n label=\"Issue amount (USD)\"\n value={amount}\n onChange={(event) => setAmount(event.target.value)}\n size=\"small\"\n type=\"number\"\n sx={{ maxWidth: 180 }}\n />\n <TextField\n label=\"Email it to (optional)\"\n value={recipient}\n onChange={(event) => setRecipient(event.target.value)}\n size=\"small\"\n sx={{ minWidth: 240 }}\n />\n <Button\n variant=\"contained\"\n size=\"small\"\n disabled={busy || !amount}\n onClick={handleIssue}\n >\n {'Issue card'}\n </Button>\n </Stack>\n\n <TextField\n label=\"Find in the cards below\"\n value={search}\n onChange={(event) => setSearch(event.target.value)}\n size=\"small\"\n sx={{ maxWidth: 320 }}\n />\n\n {cards.length ? (\n <Stack spacing={1}>\n {cards.map((card: any) => (\n <Stack\n key={card.$id}\n direction=\"row\"\n spacing={1}\n useFlexGap\n sx={{ flexWrap: 'wrap', alignItems: 'center' }}\n >\n <Typography variant=\"body2\" sx={{ fontFamily: 'monospace' }}>\n {card.$id}\n </Typography>\n <Chip\n size=\"small\"\n color={\n Number(card.balanceCents ?? 0) > 0 ? 'success' : 'default'\n }\n label={`${usd(card.balanceCents)} of ${usd(card.initialCents)}`}\n />\n {card.recipientEmail ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {card.recipientEmail}\n </Typography>\n ) : null}\n {card.orderId ? null : (\n <Chip size=\"small\" variant=\"outlined\" label={'Issued by hand'} />\n )}\n {card.voidedAtMs ? (\n <Chip size=\"small\" variant=\"outlined\" label={'Voided'} />\n ) : Number(card.balanceCents ?? 0) > 0 ? (\n <Button\n size=\"small\"\n color=\"error\"\n disabled={busy}\n onClick={() => handleVoid(card)}\n >\n {'Void'}\n </Button>\n ) : null}\n </Stack>\n ))}\n </Stack>\n ) : (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {search\n ? 'No gift card on this page matches that code or email — ' +\n 'the search reads the page in front of you.'\n : 'No gift cards yet. Sell a gift-card product, or issue one above.'}\n </Typography>\n )}\n <ListPagination\n page={page}\n pageSize={pageSize}\n rowCount={cards.length}\n hasMore={hasMore}\n onPageChange={setPage}\n onPageSizeChange={setPageSize}\n />\n </Stack>\n </CardDisplay>\n </EntitlementGatedCard>\n )\n}\nGiftCardsCard.displayName = 'GiftCardsCard'\n\nexport default GiftCardsCard\n"],"names":["CardDisplay","useConfirmationContext","ListPagination","useSnackbar","Button","Chip","Stack","TextField","Typography","collection","count","getAggregateFromServer","limit","orderBy","query","sum","where","useCallback","useEffect","useMemo","useState","useFirestore","usePagedCollection","useUser","pluginDocsHelp","authorizedFetch","EntitlementGatedCard","usd","cents","toFixed","giftCardsHelp","anchor","title","excerpt","GiftCardsCard","props","hostId","firestore","data","user","enqueueSnackbar","confirm","rows","allCards","hasMore","page","setPage","pageSize","setPageSize","pageLimit","idField","search","setSearch","amount","setAmount","recipient","setRecipient","busy","setBusy","cards","term","trim","toUpperCase","filter","card","$id","includes","String","recipientEmail","totalsEpoch","setTotalsEpoch","totals","setTotals","active","cardsRef","Promise","all","outstandingCents","liveCount","issuedCount","then","balances","issued","Number","catch","post","payload","success","response","method","headers","body","JSON","stringify","json","ok","error","variant","allowDuplicate","persist","epoch","handleIssue","dollars","isFinite","action","amountCents","Math","round","emailed","code","handleVoid","confirmed","description","balanceCents","confirmationText","confirmationButtonProps","color","help","feature","header","upsell","contentGutterX","contentGutterY","spacing","direction","useFlexGap","sx","flexWrap","size","label","value","onChange","event","target","type","maxWidth","minWidth","disabled","onClick","length","map","alignItems","fontFamily","initialCents","orderId","voidedAtMs","rowCount","onPageChange","onPageSizeChange","displayName"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface HostCouponsCardProps {
|
|
2
|
+
hostId: string;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Coupon codes (AGL-96), extracted from the retired Commerce Starter
|
|
6
|
+
* card when the products hub landed (AGL-279). Percent-off codes at
|
|
7
|
+
* `hosts/{hostId}/coupons/{CODE}`; the discounts engine (AGL-305)
|
|
8
|
+
* supersedes these.
|
|
9
|
+
*/
|
|
10
|
+
export declare function HostCouponsCard(props: HostCouponsCardProps): import("react").JSX.Element;
|
|
11
|
+
export declare namespace HostCouponsCard {
|
|
12
|
+
var displayName: string;
|
|
13
|
+
}
|
|
14
|
+
export default HostCouponsCard;
|