@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,1022 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
|
|
3
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
4
|
+
/**
|
|
5
|
+
* @license
|
|
6
|
+
* Copyright 2026 Aglyn LLC
|
|
7
|
+
*
|
|
8
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
* you may not use this file except in compliance with the License.
|
|
10
|
+
* You may obtain a copy of the License at
|
|
11
|
+
*
|
|
12
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
*
|
|
14
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
* See the License for the specific language governing permissions and
|
|
18
|
+
* limitations under the License.
|
|
19
|
+
*/ import * as Aglyn from "@aglyn/aglyn";
|
|
20
|
+
import { buildAddToCartParams, buildBeginCheckoutParams, trackEvent, trackEventBeforeNavigation } from "@aglyn/aglyn/app-utils/analytics-events";
|
|
21
|
+
import { isPaymentsNotConfigured, storefrontPaymentsNotConfiguredText } from "@aglyn/aglyn/app-utils/payments-configured";
|
|
22
|
+
import * as CommerceModel from "../model/index.js";
|
|
23
|
+
import { mdiTagOutline } from "@aglyn/shared-data-mdi";
|
|
24
|
+
import Alert from "@mui/material/Alert";
|
|
25
|
+
import Box from "@mui/material/Box";
|
|
26
|
+
import Button from "@mui/material/Button";
|
|
27
|
+
import Chip from "@mui/material/Chip";
|
|
28
|
+
import MenuItem from "@mui/material/MenuItem";
|
|
29
|
+
import Skeleton from "@mui/material/Skeleton";
|
|
30
|
+
import TextField from "@mui/material/TextField";
|
|
31
|
+
import ToggleButton from "@mui/material/ToggleButton";
|
|
32
|
+
import ToggleButtonGroup from "@mui/material/ToggleButtonGroup";
|
|
33
|
+
import Typography from "@mui/material/Typography";
|
|
34
|
+
import { Suspense, forwardRef, lazy, useEffect, useMemo, useRef, useState } from "react";
|
|
35
|
+
import { BUNDLE_ID } from "../constants/bundle-common.js";
|
|
36
|
+
import { generatePresetId } from "../utils/generate-preset-id.js";
|
|
37
|
+
import { useStorefrontPurchaseEvent } from "../utils/use-storefront-purchase-event.js";
|
|
38
|
+
import { CART_UPDATED_EVENT } from "./cart.js";
|
|
39
|
+
import { ID as PRODUCT_REVIEWS_ID } from "./product-reviews.js";
|
|
40
|
+
import { ID as RELATED_PRODUCTS_ID } from "./related-products.js";
|
|
41
|
+
import { readLocalWishlist, toggleWishlist } from "./wishlist.js";
|
|
42
|
+
import { StorefrontPaymentElementFallback } from "./storefront-payment-element-fallback.js";
|
|
43
|
+
/**
|
|
44
|
+
* The Payment Element (AGL-1944), behind a lazy boundary rather than a plain
|
|
45
|
+
* import. Stripe.js and its React wrapper are a large dependency, the flag is
|
|
46
|
+
* OFF, and a static import would put the whole SDK into the bundle of every
|
|
47
|
+
* product page on every published site to serve a code path no shopper reaches.
|
|
48
|
+
* Split, it is fetched by the shoppers who actually get the in-page form.
|
|
49
|
+
*/ const StorefrontPaymentElement = /*#__PURE__*/ lazy(()=>import("./storefront-payment-element.js").then((module)=>({
|
|
50
|
+
default: module.StorefrontPaymentElement
|
|
51
|
+
})));
|
|
52
|
+
// Component ids are persisted in screen documents; never rename.
|
|
53
|
+
export const ID = 'product-detail';
|
|
54
|
+
const SAMPLE = {
|
|
55
|
+
id: 'sample',
|
|
56
|
+
name: 'Sample product',
|
|
57
|
+
slug: '#',
|
|
58
|
+
description: 'Drop this block on your product page template.',
|
|
59
|
+
mediaUrls: [],
|
|
60
|
+
options: [
|
|
61
|
+
{
|
|
62
|
+
name: 'Size',
|
|
63
|
+
values: [
|
|
64
|
+
'S',
|
|
65
|
+
'M',
|
|
66
|
+
'L'
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
variants: [
|
|
71
|
+
{
|
|
72
|
+
id: 'a',
|
|
73
|
+
options: {
|
|
74
|
+
Size: 'S'
|
|
75
|
+
},
|
|
76
|
+
priceUsd: 29,
|
|
77
|
+
soldOut: false
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
id: 'b',
|
|
81
|
+
options: {
|
|
82
|
+
Size: 'M'
|
|
83
|
+
},
|
|
84
|
+
priceUsd: 29,
|
|
85
|
+
soldOut: false
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: 'c',
|
|
89
|
+
options: {
|
|
90
|
+
Size: 'L'
|
|
91
|
+
},
|
|
92
|
+
priceUsd: 32,
|
|
93
|
+
soldOut: true
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* The GA4 `items` entry for one line of this product.
|
|
99
|
+
*
|
|
100
|
+
* `item_id` is the PRODUCT id and never the variant's, matching the
|
|
101
|
+
* `view_item` above and the cart's lines below: GA joins the funnel on that
|
|
102
|
+
* id, and a `begin_checkout` keyed on a variant would report a product nothing
|
|
103
|
+
* else on the storefront had ever mentioned.
|
|
104
|
+
*
|
|
105
|
+
* `price` is the resolved variant's, which arrived from the server's product
|
|
106
|
+
* payload — the same figure `checkout` prices the charge from, so the reported
|
|
107
|
+
* value and the amount Stripe collects come from one source.
|
|
108
|
+
*/ function buyItem(product, variant, quantity) {
|
|
109
|
+
return {
|
|
110
|
+
item_id: product.id,
|
|
111
|
+
item_name: product.name,
|
|
112
|
+
price: variant == null ? void 0 : variant.priceUsd,
|
|
113
|
+
quantity
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function slugFromLocation() {
|
|
117
|
+
if (typeof window === 'undefined') return '';
|
|
118
|
+
const match = window.location.pathname.match(/\/products\/([^/?#]+)/);
|
|
119
|
+
return match ? decodeURIComponent(match[1]) : '';
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Product detail block (AGL-292): gallery, option pickers that resolve
|
|
123
|
+
* the variant (price/media/stock follow), quantity, and a buy button
|
|
124
|
+
* that charges through the server-priced checkout with the selected
|
|
125
|
+
* variant. Resolves its product from the /products/{slug} URL unless a
|
|
126
|
+
* slug prop pins it; sample data on the inert canvas.
|
|
127
|
+
*/ const ProductDetail = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
128
|
+
var _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
|
|
129
|
+
var _site_pageData_commerce, _site_pageData;
|
|
130
|
+
const { slug: slugProp, buyLabel, hideDescription, showCoupon } = props, rest = _object_without_properties_loose(props, [
|
|
131
|
+
"slug",
|
|
132
|
+
"buyLabel",
|
|
133
|
+
"hideDescription",
|
|
134
|
+
"showCoupon"
|
|
135
|
+
]);
|
|
136
|
+
// Node styles ride the renderer-merged sx; recompose (stack.ts pattern).
|
|
137
|
+
const nodeSx = Array.isArray(props['sx']) ? props['sx'] : [
|
|
138
|
+
props['sx']
|
|
139
|
+
];
|
|
140
|
+
const site = Aglyn.useSite();
|
|
141
|
+
const siteFetch = Aglyn.useSiteFetch();
|
|
142
|
+
const { hostId } = site;
|
|
143
|
+
// The single-product ("buy now") path returns the shopper to this page
|
|
144
|
+
// rather than to the cart, so the PDP is the second of the two surfaces
|
|
145
|
+
// that has to be able to report `purchase` (AGL-1641). Both mount points
|
|
146
|
+
// share one guard, so a page carrying a cart AND a PDP still sends one.
|
|
147
|
+
useStorefrontPurchaseEvent(hostId, siteFetch);
|
|
148
|
+
// Seeded from the server-resolved page data (AGL-659) so the PDP renders
|
|
149
|
+
// its real content in the SSR HTML. Starting at null meant the server
|
|
150
|
+
// emitted a <Skeleton> and the crawler got a product page with no
|
|
151
|
+
// product in it. Absent in the besigner/preview, where the effect below
|
|
152
|
+
// still fetches — so this is an optimisation, not a new requirement.
|
|
153
|
+
const seededProduct = (_site_pageData = site.pageData) == null ? void 0 : (_site_pageData_commerce = _site_pageData.commerce) == null ? void 0 : _site_pageData_commerce.product;
|
|
154
|
+
const [detail, setDetail] = useState(seededProduct != null ? seededProduct : null);
|
|
155
|
+
const [selections, setSelections] = useState({});
|
|
156
|
+
const [quantity, setQuantity] = useState(1);
|
|
157
|
+
/** A discount or coupon code typed on the product page. */ const [coupon, setCoupon] = useState('');
|
|
158
|
+
const [activeImage, setActiveImage] = useState(0);
|
|
159
|
+
// `unconfigured` is not an `error` with softer words (AGL-2019). A store
|
|
160
|
+
// with no Stripe key answers 501, and rendering that at `severity="error"`
|
|
161
|
+
// tells a shopper their payment failed when nothing was ever attempted —
|
|
162
|
+
// the same distinction `ask` already makes, and the same one the cart's
|
|
163
|
+
// 423 lockdown branch makes. It is the terminal one: it latches Buy off,
|
|
164
|
+
// because every further click gets the identical refusal.
|
|
165
|
+
const [status, setStatus] = useState('idle');
|
|
166
|
+
const [message, setMessage] = useState('');
|
|
167
|
+
// Buy-now's half of AGL-1721: asked only when the server refuses to price
|
|
168
|
+
// shipping without a destination, so a digital product, a subscription, or
|
|
169
|
+
// a merchant whose rates are the same everywhere never shows it. `null` is
|
|
170
|
+
// "not asked" — the field appearing is the server's answer, not a guess.
|
|
171
|
+
const [shipTo, setShipTo] = useState('');
|
|
172
|
+
const [shipCountries, setShipCountries] = useState(null);
|
|
173
|
+
const [added, setAdded] = useState(false);
|
|
174
|
+
const [wishlisted, setWishlisted] = useState(false);
|
|
175
|
+
const [notifyEmail, setNotifyEmail] = useState('');
|
|
176
|
+
const [notifyState, setNotifyState] = useState('idle');
|
|
177
|
+
// Buyer-chosen billing (AGL-545): only meaningful when the product
|
|
178
|
+
// is subscriptionOptional; defaults to a one-time purchase.
|
|
179
|
+
const [billing, setBilling] = useState('once');
|
|
180
|
+
/**
|
|
181
|
+
* The in-page checkout session (AGL-1944), null on every store until the
|
|
182
|
+
* flag AND a publishable key say otherwise. A `clientSecret` is Stripe's
|
|
183
|
+
* instruction to the browser; holding it says nothing about money having
|
|
184
|
+
* moved, and nothing in this component ever claims it has.
|
|
185
|
+
*/ const [nativeCheckout, setNativeCheckout] = useState(null);
|
|
186
|
+
const slug = slugProp || slugFromLocation();
|
|
187
|
+
useEffect(()=>{
|
|
188
|
+
if (hostId && resolvedId) {
|
|
189
|
+
setWishlisted(readLocalWishlist(hostId).includes(resolvedId));
|
|
190
|
+
}
|
|
191
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
192
|
+
}, [
|
|
193
|
+
hostId,
|
|
194
|
+
detail
|
|
195
|
+
]);
|
|
196
|
+
useEffect(()=>{
|
|
197
|
+
if (!hostId || !slug) return;
|
|
198
|
+
// Already delivered with the page (AGL-659) — refetching the identical
|
|
199
|
+
// payload on hydrate would just be a wasted round trip per visitor.
|
|
200
|
+
if (seededProduct && seededProduct.slug === slug) return;
|
|
201
|
+
let active = true;
|
|
202
|
+
void fetch(`/api/commerce/product?hostId=${encodeURIComponent(hostId)}` + `&slug=${encodeURIComponent(slug)}`).then((response)=>response.ok ? response.json() : null).then((payload)=>{
|
|
203
|
+
if (!active) return;
|
|
204
|
+
const product = payload == null ? void 0 : payload.product;
|
|
205
|
+
setDetail(product != null ? product : 'missing');
|
|
206
|
+
if (product) {
|
|
207
|
+
var _product_variants_find, _ref;
|
|
208
|
+
// GA4 ecommerce mirror (AGL-327), through the shared taxonomy
|
|
209
|
+
// since AGL-1591 rather than raw gtag — same consent gate, same
|
|
210
|
+
// sanitizer, and the name is now checked by the compiler.
|
|
211
|
+
trackEvent('view_item', {
|
|
212
|
+
items: [
|
|
213
|
+
{
|
|
214
|
+
item_id: product.id,
|
|
215
|
+
item_name: product.name
|
|
216
|
+
}
|
|
217
|
+
]
|
|
218
|
+
});
|
|
219
|
+
const first = (_product_variants_find = product.variants.find((variant)=>!variant.soldOut)) != null ? _product_variants_find : product.variants[0];
|
|
220
|
+
setSelections((_ref = first == null ? void 0 : first.options) != null ? _ref : {});
|
|
221
|
+
}
|
|
222
|
+
}).catch(()=>{
|
|
223
|
+
if (active) setDetail('missing');
|
|
224
|
+
});
|
|
225
|
+
return ()=>{
|
|
226
|
+
active = false;
|
|
227
|
+
};
|
|
228
|
+
}, [
|
|
229
|
+
hostId,
|
|
230
|
+
slug
|
|
231
|
+
]);
|
|
232
|
+
const resolvedId = hostId && detail && detail !== 'missing' ? detail.id : null;
|
|
233
|
+
const resolved = hostId ? detail === 'missing' ? null : detail : SAMPLE;
|
|
234
|
+
const variant = useMemo(()=>{
|
|
235
|
+
var _CommerceModel_findVariant;
|
|
236
|
+
if (!resolved) return undefined;
|
|
237
|
+
return (_CommerceModel_findVariant = CommerceModel.findVariant({
|
|
238
|
+
variants: resolved.variants
|
|
239
|
+
}, selections)) != null ? _CommerceModel_findVariant : resolved.variants[0];
|
|
240
|
+
}, [
|
|
241
|
+
resolved,
|
|
242
|
+
selections
|
|
243
|
+
]);
|
|
244
|
+
// Add to cart (AGL-293) beside instant buy; badge refresh via event.
|
|
245
|
+
const handleAddToCart = async ()=>{
|
|
246
|
+
if (!hostId || !resolved || !variant) return;
|
|
247
|
+
setAdded(false);
|
|
248
|
+
const response = await siteFetch('/api/commerce/cart', {
|
|
249
|
+
method: 'POST',
|
|
250
|
+
headers: {
|
|
251
|
+
'Content-Type': 'application/json'
|
|
252
|
+
},
|
|
253
|
+
body: JSON.stringify({
|
|
254
|
+
hostId,
|
|
255
|
+
action: 'add',
|
|
256
|
+
productId: resolved.id,
|
|
257
|
+
variantId: variant.id,
|
|
258
|
+
quantity
|
|
259
|
+
})
|
|
260
|
+
}).catch(()=>null);
|
|
261
|
+
if (response == null ? void 0 : response.ok) {
|
|
262
|
+
setAdded(true);
|
|
263
|
+
// Priced (AGL-1591's shape, completed): the resolved variant's price
|
|
264
|
+
// and the chosen quantity are both known here and both come from the
|
|
265
|
+
// server's product payload, so GA4's "value added to cart" is a real
|
|
266
|
+
// number rather than the empty column an items-only hit leaves. The
|
|
267
|
+
// `value` describes what was JUST ADDED, not the cart's new total —
|
|
268
|
+
// see `buildAddToCartParams`.
|
|
269
|
+
trackEvent('add_to_cart', buildAddToCartParams({
|
|
270
|
+
items: [
|
|
271
|
+
buyItem(resolved, variant, quantity)
|
|
272
|
+
]
|
|
273
|
+
}));
|
|
274
|
+
window.dispatchEvent(new Event(CART_UPDATED_EVENT));
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
/**
|
|
278
|
+
* Idempotency key for ONE buy-now attempt (AGL-1697).
|
|
279
|
+
*
|
|
280
|
+
* Minted lazily on the first buy click, retired whenever the purchase
|
|
281
|
+
* changes shape — a different product, variant, quantity, billing choice
|
|
282
|
+
* or destination is a different attempt. A retry of THIS attempt presents
|
|
283
|
+
* the same key, so the server replays the original session instead of
|
|
284
|
+
* opening a second one (for a subscription product, a second RECURRING
|
|
285
|
+
* subscription).
|
|
286
|
+
*/ const attemptKey = useRef('');
|
|
287
|
+
useEffect(()=>{
|
|
288
|
+
attemptKey.current = '';
|
|
289
|
+
// `coupon` is in here because it CHANGES THE PRICE. Without it a shopper
|
|
290
|
+
// who buys, comes back, types a code and buys again presents the same
|
|
291
|
+
// key, and the server replays the original full-price session — a quoted
|
|
292
|
+
// number that is not the number charged, which is the whole defect class
|
|
293
|
+
// this path has been cleared of.
|
|
294
|
+
}, [
|
|
295
|
+
resolved == null ? void 0 : resolved.id,
|
|
296
|
+
variant == null ? void 0 : variant.id,
|
|
297
|
+
quantity,
|
|
298
|
+
billing,
|
|
299
|
+
shipTo,
|
|
300
|
+
coupon
|
|
301
|
+
]);
|
|
302
|
+
const handleBuy = async ()=>{
|
|
303
|
+
if (!hostId || !resolved || !variant || status === 'sending') return;
|
|
304
|
+
setStatus('sending');
|
|
305
|
+
setMessage('');
|
|
306
|
+
if (!attemptKey.current) {
|
|
307
|
+
var _ref;
|
|
308
|
+
var _globalThis_crypto_randomUUID, _globalThis_crypto;
|
|
309
|
+
attemptKey.current = (_ref = (_globalThis_crypto = globalThis.crypto) == null ? void 0 : (_globalThis_crypto_randomUUID = _globalThis_crypto.randomUUID) == null ? void 0 : _globalThis_crypto_randomUUID.call(_globalThis_crypto)) != null ? _ref : `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
310
|
+
}
|
|
311
|
+
try {
|
|
312
|
+
var _ref1;
|
|
313
|
+
const response = await siteFetch('/api/commerce/checkout', {
|
|
314
|
+
method: 'POST',
|
|
315
|
+
headers: {
|
|
316
|
+
'Content-Type': 'application/json',
|
|
317
|
+
'Idempotency-Key': attemptKey.current
|
|
318
|
+
},
|
|
319
|
+
body: JSON.stringify(_extends({
|
|
320
|
+
hostId,
|
|
321
|
+
productId: resolved.id,
|
|
322
|
+
variantId: variant.id,
|
|
323
|
+
quantity
|
|
324
|
+
}, resolved.subscriptionOptional ? {
|
|
325
|
+
billing
|
|
326
|
+
} : {}, shipTo ? {
|
|
327
|
+
shippingCountry: shipTo
|
|
328
|
+
} : {}, coupon.trim() ? {
|
|
329
|
+
couponCode: coupon.trim()
|
|
330
|
+
} : {}))
|
|
331
|
+
});
|
|
332
|
+
const payload = await response.json().catch(()=>({}));
|
|
333
|
+
// In-page payment (AGL-1944). A native session returns a client secret
|
|
334
|
+
// and NO url — the two are mutually exclusive by construction, so the
|
|
335
|
+
// redirect branch below is unreachable in native mode and vice versa.
|
|
336
|
+
// Checked FIRST so a server that somehow sent both cannot silently
|
|
337
|
+
// navigate the shopper away from the form we just decided to show.
|
|
338
|
+
if (response.ok && (payload == null ? void 0 : payload.clientSecret) && (payload == null ? void 0 : payload.publishableKey)) {
|
|
339
|
+
// Buy-now's `begin_checkout`. The cart path has reported this since
|
|
340
|
+
// AGL-1591 and this one never did, so a storefront whose shoppers
|
|
341
|
+
// skip the cart showed `view_item` → `add_to_cart` → nothing →
|
|
342
|
+
// `purchase`: GA4's shopping funnel put every single-product sale in
|
|
343
|
+
// the "abandoned checkout" bucket, and the merchant's checkout rate
|
|
344
|
+
// read as a collapse rather than as an unmeasured path.
|
|
345
|
+
//
|
|
346
|
+
// Reported on BOTH branches, and from the same place, for the reason
|
|
347
|
+
// the cart states: a count that halved the day the in-page payment
|
|
348
|
+
// flag flipped would look like a conversion collapse.
|
|
349
|
+
trackEvent('begin_checkout', buildBeginCheckoutParams({
|
|
350
|
+
items: [
|
|
351
|
+
buyItem(resolved, variant, quantity)
|
|
352
|
+
]
|
|
353
|
+
}));
|
|
354
|
+
setNativeCheckout({
|
|
355
|
+
clientSecret: String(payload.clientSecret),
|
|
356
|
+
publishableKey: String(payload.publishableKey)
|
|
357
|
+
});
|
|
358
|
+
setStatus('idle');
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
if (response.ok && (payload == null ? void 0 : payload.url)) {
|
|
362
|
+
// Awaited before the redirect (AGL-1580), for the reason spelled out
|
|
363
|
+
// on the cart's matching branch: delivery here is a synchronous
|
|
364
|
+
// `window.gtag` call today and the await costs nothing, but the
|
|
365
|
+
// property that makes a bare call safe is invisible from this file.
|
|
366
|
+
await trackEventBeforeNavigation('begin_checkout', buildBeginCheckoutParams({
|
|
367
|
+
items: [
|
|
368
|
+
buyItem(resolved, variant, quantity)
|
|
369
|
+
]
|
|
370
|
+
}));
|
|
371
|
+
window.location.assign(payload.url);
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
// Buy-now's half of AGL-2019. The server's own 501 wording is not
|
|
375
|
+
// rendered to a visitor; this surface is public.
|
|
376
|
+
if (isPaymentsNotConfigured(response.status)) {
|
|
377
|
+
setMessage(storefrontPaymentsNotConfiguredText());
|
|
378
|
+
setStatus('unconfigured');
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
if (payload == null ? void 0 : payload.needsShippingCountry) {
|
|
382
|
+
var _ref2;
|
|
383
|
+
var _payload_shippingCountries;
|
|
384
|
+
setShipCountries(((_payload_shippingCountries = payload.shippingCountries) == null ? void 0 : _payload_shippingCountries.length) ? payload.shippingCountries : [
|
|
385
|
+
...CommerceModel.CHECKOUT_SHIPPING_COUNTRIES
|
|
386
|
+
]);
|
|
387
|
+
setMessage(String((_ref2 = payload == null ? void 0 : payload.error) != null ? _ref2 : ''));
|
|
388
|
+
// An unserved destination is a refusal and reads as one; being
|
|
389
|
+
// asked the first time is not.
|
|
390
|
+
setStatus(shipTo ? 'error' : 'ask');
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
setMessage(String((_ref1 = payload == null ? void 0 : payload.error) != null ? _ref1 : ''));
|
|
394
|
+
setStatus('error');
|
|
395
|
+
} catch (unused) {
|
|
396
|
+
setStatus('error');
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
if (hostId && detail === null) {
|
|
400
|
+
return /*#__PURE__*/ _jsxs(Box, _extends({
|
|
401
|
+
ref: ref
|
|
402
|
+
}, rest, {
|
|
403
|
+
sx: [
|
|
404
|
+
{
|
|
405
|
+
display: 'flex',
|
|
406
|
+
gap: 3
|
|
407
|
+
},
|
|
408
|
+
...nodeSx
|
|
409
|
+
],
|
|
410
|
+
children: [
|
|
411
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
412
|
+
variant: "rectangular",
|
|
413
|
+
width: 320,
|
|
414
|
+
height: 320
|
|
415
|
+
}),
|
|
416
|
+
/*#__PURE__*/ _jsxs(Box, {
|
|
417
|
+
sx: {
|
|
418
|
+
flex: 1
|
|
419
|
+
},
|
|
420
|
+
children: [
|
|
421
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
422
|
+
width: "60%",
|
|
423
|
+
height: 36
|
|
424
|
+
}),
|
|
425
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
426
|
+
width: "25%"
|
|
427
|
+
}),
|
|
428
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
429
|
+
width: "90%"
|
|
430
|
+
})
|
|
431
|
+
]
|
|
432
|
+
})
|
|
433
|
+
]
|
|
434
|
+
}));
|
|
435
|
+
}
|
|
436
|
+
if (!resolved) {
|
|
437
|
+
return /*#__PURE__*/ _jsx(Box, _extends({
|
|
438
|
+
ref: ref
|
|
439
|
+
}, rest, {
|
|
440
|
+
sx: [
|
|
441
|
+
{
|
|
442
|
+
p: 3
|
|
443
|
+
},
|
|
444
|
+
...nodeSx
|
|
445
|
+
],
|
|
446
|
+
children: /*#__PURE__*/ _jsx(Typography, {
|
|
447
|
+
variant: "body2",
|
|
448
|
+
color: "text.secondary",
|
|
449
|
+
children: 'Product not found.'
|
|
450
|
+
})
|
|
451
|
+
}));
|
|
452
|
+
}
|
|
453
|
+
// Every rendered `<img src>` on this page goes through
|
|
454
|
+
// `siteRelativeMediaSrc` (AGL-1726). Commerce called NO resolver at all,
|
|
455
|
+
// which cost it two things at once: a `media:` reference — writable via
|
|
456
|
+
// the resources API and the CSV importer — would have reached an `<img>`
|
|
457
|
+
// as the literal string, and a stored absolute
|
|
458
|
+
// `https://{subdomain}.aglyn.app/api/media/cdn/…` stayed absolute, so a
|
|
459
|
+
// white-label storefront on the customer's own domain served product
|
|
460
|
+
// photos naming OUR platform, cross-origin, in page source and in every
|
|
461
|
+
// visitor's request. Production carried exactly one such document; the
|
|
462
|
+
// resolver fixes it at READ time, so no backfill stands between the
|
|
463
|
+
// defect and the fix.
|
|
464
|
+
//
|
|
465
|
+
// Deliberately NOT applied to `resolved.mediaUrls` wholesale: the
|
|
466
|
+
// schema.org `image` array below is read out of band by a crawler, where
|
|
467
|
+
// an absolute URL is the point. That one wants `absoluteMediaSrc` with
|
|
468
|
+
// the site's own origin, which is the tenant page's job (AGL-1725).
|
|
469
|
+
const galleryImage = Aglyn.siteRelativeMediaSrc((_ref = (_ref1 = variant == null ? void 0 : variant.imageUrl) != null ? _ref1 : resolved.mediaUrls[activeImage]) != null ? _ref : resolved.mediaUrls[0], {
|
|
470
|
+
hostId
|
|
471
|
+
});
|
|
472
|
+
// Subscription framing (AGL-545): subscription-only products price as
|
|
473
|
+
// $X/mo|/yr with a "Subscribe" button; subscriptionOptional products
|
|
474
|
+
// surface the one-time/subscribe toggle instead. Same price either way
|
|
475
|
+
// — the server re-prices from the product doc regardless.
|
|
476
|
+
const subscription = resolved.subscription;
|
|
477
|
+
const intervalSuffix = (subscription == null ? void 0 : subscription.interval) === 'year' ? '/yr' : '/mo';
|
|
478
|
+
const subscribing = Boolean(subscription) && (!resolved.subscriptionOptional || billing === 'subscribe');
|
|
479
|
+
// schema.org Product/Offer (AGL-299). Kept ONLY for the case where this
|
|
480
|
+
// block renders without server-seeded page data — the besigner preview,
|
|
481
|
+
// or a page whose resolver didn't supply it. When the tenant page seeds
|
|
482
|
+
// us it emits the same Product node server-side (AGL-660), and two
|
|
483
|
+
// Product nodes for one item is worse than one, so we stand down.
|
|
484
|
+
const structuredData = hostId && resolvedId && !seededProduct ? _extends({
|
|
485
|
+
'@context': 'https://schema.org',
|
|
486
|
+
'@type': 'Product',
|
|
487
|
+
name: resolved.name
|
|
488
|
+
}, resolved.description ? {
|
|
489
|
+
description: resolved.description
|
|
490
|
+
} : {}, resolved.mediaUrls.length ? {
|
|
491
|
+
image: resolved.mediaUrls
|
|
492
|
+
} : {}, {
|
|
493
|
+
offers: {
|
|
494
|
+
'@type': 'Offer',
|
|
495
|
+
priceCurrency: 'USD',
|
|
496
|
+
price: String((_ref2 = variant == null ? void 0 : variant.priceUsd) != null ? _ref2 : 0),
|
|
497
|
+
availability: (variant == null ? void 0 : variant.soldOut) ? 'https://schema.org/OutOfStock' : 'https://schema.org/InStock'
|
|
498
|
+
}
|
|
499
|
+
}) : null;
|
|
500
|
+
return /*#__PURE__*/ _jsxs(Box, _extends({
|
|
501
|
+
ref: ref
|
|
502
|
+
}, rest, {
|
|
503
|
+
sx: [
|
|
504
|
+
{
|
|
505
|
+
display: 'flex',
|
|
506
|
+
gap: 3,
|
|
507
|
+
flexDirection: {
|
|
508
|
+
xs: 'column',
|
|
509
|
+
md: 'row'
|
|
510
|
+
}
|
|
511
|
+
},
|
|
512
|
+
...nodeSx
|
|
513
|
+
],
|
|
514
|
+
children: [
|
|
515
|
+
/*#__PURE__*/ _jsxs(Box, {
|
|
516
|
+
sx: {
|
|
517
|
+
flex: 1,
|
|
518
|
+
minWidth: 0
|
|
519
|
+
},
|
|
520
|
+
children: [
|
|
521
|
+
galleryImage ? /*#__PURE__*/ _jsx(Box, {
|
|
522
|
+
component: "img",
|
|
523
|
+
src: galleryImage,
|
|
524
|
+
alt: resolved.name,
|
|
525
|
+
// DELIBERATELY NOT DEFERRED (AGL-2486). This is the gallery
|
|
526
|
+
// hero at the top of a product page — the one image on this
|
|
527
|
+
// surface that really is the LCP candidate, and the browser
|
|
528
|
+
// default here is already `eager`. Spreading
|
|
529
|
+
// `DEFERRED_IMAGE_ATTRIBUTES` over it to "finish the job" is
|
|
530
|
+
// the obvious next edit and it re-introduces the bug this
|
|
531
|
+
// issue opened with: an LCP image not discovered until after
|
|
532
|
+
// layout has run. The thumbnail strip below it IS deferred.
|
|
533
|
+
//
|
|
534
|
+
// No `fetchpriority` either, for the reason written out at
|
|
535
|
+
// `image.tsx`: `high` is a claim about every other request in
|
|
536
|
+
// flight, and a page whose real LCP is the product NAME would
|
|
537
|
+
// pay for that claim.
|
|
538
|
+
sx: {
|
|
539
|
+
width: '100%',
|
|
540
|
+
aspectRatio: '1 / 1',
|
|
541
|
+
objectFit: 'cover',
|
|
542
|
+
borderRadius: 1
|
|
543
|
+
}
|
|
544
|
+
}) : /*#__PURE__*/ _jsx(Box, {
|
|
545
|
+
sx: {
|
|
546
|
+
width: '100%',
|
|
547
|
+
aspectRatio: '1 / 1',
|
|
548
|
+
bgcolor: 'action.hover',
|
|
549
|
+
borderRadius: 1
|
|
550
|
+
}
|
|
551
|
+
}),
|
|
552
|
+
resolved.mediaUrls.length > 1 ? /*#__PURE__*/ _jsx(Box, {
|
|
553
|
+
sx: {
|
|
554
|
+
display: 'flex',
|
|
555
|
+
gap: 1,
|
|
556
|
+
mt: 1,
|
|
557
|
+
flexWrap: 'wrap'
|
|
558
|
+
},
|
|
559
|
+
children: resolved.mediaUrls.map((url, index)=>/*#__PURE__*/ _jsx(Box, _extends({
|
|
560
|
+
component: "img",
|
|
561
|
+
// Same resolver as the hero (AGL-1726) — a thumbnail is an
|
|
562
|
+
// `<img>` on the customer's page and leaks exactly as much.
|
|
563
|
+
src: Aglyn.siteRelativeMediaSrc(url, {
|
|
564
|
+
hostId
|
|
565
|
+
}),
|
|
566
|
+
alt: "",
|
|
567
|
+
onClick: ()=>setActiveImage(index),
|
|
568
|
+
sx: {
|
|
569
|
+
width: 56,
|
|
570
|
+
height: 56,
|
|
571
|
+
objectFit: 'cover',
|
|
572
|
+
borderRadius: 1,
|
|
573
|
+
cursor: 'pointer',
|
|
574
|
+
border: 2,
|
|
575
|
+
borderColor: index === activeImage ? 'primary.main' : 'transparent'
|
|
576
|
+
}
|
|
577
|
+
}, Aglyn.DEFERRED_IMAGE_ATTRIBUTES), `${url}-${index}`))
|
|
578
|
+
}) : null
|
|
579
|
+
]
|
|
580
|
+
}),
|
|
581
|
+
structuredData ? /*#__PURE__*/ _jsx("script", {
|
|
582
|
+
type: "application/ld+json",
|
|
583
|
+
dangerouslySetInnerHTML: {
|
|
584
|
+
__html: Aglyn.safeJsonLd(structuredData)
|
|
585
|
+
}
|
|
586
|
+
}) : null,
|
|
587
|
+
/*#__PURE__*/ _jsxs(Box, {
|
|
588
|
+
sx: {
|
|
589
|
+
flex: 1,
|
|
590
|
+
minWidth: 0
|
|
591
|
+
},
|
|
592
|
+
children: [
|
|
593
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
594
|
+
variant: "h4",
|
|
595
|
+
component: "h1",
|
|
596
|
+
gutterBottom: true,
|
|
597
|
+
children: resolved.name
|
|
598
|
+
}),
|
|
599
|
+
/*#__PURE__*/ _jsxs(Box, {
|
|
600
|
+
sx: {
|
|
601
|
+
display: 'flex',
|
|
602
|
+
gap: 1,
|
|
603
|
+
alignItems: 'center',
|
|
604
|
+
mb: 2
|
|
605
|
+
},
|
|
606
|
+
children: [
|
|
607
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
608
|
+
variant: "h6",
|
|
609
|
+
children: `$${(_ref3 = variant == null ? void 0 : variant.priceUsd) != null ? _ref3 : 0}${subscribing ? intervalSuffix : ''}`
|
|
610
|
+
}),
|
|
611
|
+
subscribing && (subscription == null ? void 0 : subscription.trialDays) ? /*#__PURE__*/ _jsx(Typography, {
|
|
612
|
+
variant: "caption",
|
|
613
|
+
color: "text.secondary",
|
|
614
|
+
children: `${subscription.trialDays}-day free trial`
|
|
615
|
+
}) : null,
|
|
616
|
+
(variant == null ? void 0 : variant.compareAtPriceUsd) ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
617
|
+
children: [
|
|
618
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
619
|
+
variant: "body1",
|
|
620
|
+
color: "text.disabled",
|
|
621
|
+
sx: {
|
|
622
|
+
textDecoration: 'line-through'
|
|
623
|
+
},
|
|
624
|
+
children: `$${variant.compareAtPriceUsd}`
|
|
625
|
+
}),
|
|
626
|
+
/*#__PURE__*/ _jsx(Chip, {
|
|
627
|
+
label: "Sale",
|
|
628
|
+
size: "small",
|
|
629
|
+
color: "primary"
|
|
630
|
+
})
|
|
631
|
+
]
|
|
632
|
+
}) : null,
|
|
633
|
+
(variant == null ? void 0 : variant.soldOut) ? /*#__PURE__*/ _jsx(Chip, {
|
|
634
|
+
label: "Sold out",
|
|
635
|
+
size: "small",
|
|
636
|
+
variant: "outlined"
|
|
637
|
+
}) : null,
|
|
638
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
639
|
+
size: "small",
|
|
640
|
+
onClick: async ()=>{
|
|
641
|
+
if (hostId && resolved.id !== 'sample') {
|
|
642
|
+
setWishlisted(await toggleWishlist(hostId, resolved.id, siteFetch));
|
|
643
|
+
}
|
|
644
|
+
},
|
|
645
|
+
children: wishlisted ? '♥ Saved' : '♡ Save'
|
|
646
|
+
})
|
|
647
|
+
]
|
|
648
|
+
}),
|
|
649
|
+
subscription && resolved.subscriptionOptional ? /*#__PURE__*/ _jsxs(ToggleButtonGroup, {
|
|
650
|
+
value: billing,
|
|
651
|
+
exclusive: true,
|
|
652
|
+
size: "small",
|
|
653
|
+
onChange: (_event, value)=>{
|
|
654
|
+
if (value === 'once' || value === 'subscribe') {
|
|
655
|
+
setBilling(value);
|
|
656
|
+
}
|
|
657
|
+
},
|
|
658
|
+
sx: {
|
|
659
|
+
mb: 2
|
|
660
|
+
},
|
|
661
|
+
children: [
|
|
662
|
+
/*#__PURE__*/ _jsx(ToggleButton, {
|
|
663
|
+
value: "once",
|
|
664
|
+
children: `One-time $${(_ref4 = variant == null ? void 0 : variant.priceUsd) != null ? _ref4 : 0}`
|
|
665
|
+
}),
|
|
666
|
+
/*#__PURE__*/ _jsx(ToggleButton, {
|
|
667
|
+
value: "subscribe",
|
|
668
|
+
children: `Subscribe $${(_ref5 = variant == null ? void 0 : variant.priceUsd) != null ? _ref5 : 0}${intervalSuffix}`
|
|
669
|
+
})
|
|
670
|
+
]
|
|
671
|
+
}) : null,
|
|
672
|
+
resolved.options.map((option)=>{
|
|
673
|
+
var _selections_option_name;
|
|
674
|
+
return /*#__PURE__*/ _jsx(TextField, {
|
|
675
|
+
label: option.name,
|
|
676
|
+
value: (_selections_option_name = selections[option.name]) != null ? _selections_option_name : '',
|
|
677
|
+
onChange: (event)=>setSelections((prev)=>_extends({}, prev, {
|
|
678
|
+
[option.name]: event.target.value
|
|
679
|
+
})),
|
|
680
|
+
size: "small",
|
|
681
|
+
select: true,
|
|
682
|
+
fullWidth: true,
|
|
683
|
+
sx: {
|
|
684
|
+
mb: 1.5
|
|
685
|
+
},
|
|
686
|
+
children: option.values.map((value)=>/*#__PURE__*/ _jsx(MenuItem, {
|
|
687
|
+
value: value,
|
|
688
|
+
children: value
|
|
689
|
+
}, value))
|
|
690
|
+
}, option.name);
|
|
691
|
+
}),
|
|
692
|
+
showCoupon ? /*#__PURE__*/ _jsx(TextField, {
|
|
693
|
+
label: "Discount code",
|
|
694
|
+
value: coupon,
|
|
695
|
+
onChange: (event)=>setCoupon(event.target.value),
|
|
696
|
+
size: "small",
|
|
697
|
+
sx: {
|
|
698
|
+
mb: 2,
|
|
699
|
+
display: 'block'
|
|
700
|
+
}
|
|
701
|
+
}) : null,
|
|
702
|
+
/*#__PURE__*/ _jsxs(Box, {
|
|
703
|
+
sx: {
|
|
704
|
+
display: 'flex',
|
|
705
|
+
gap: 1.5,
|
|
706
|
+
alignItems: 'center',
|
|
707
|
+
mb: 2
|
|
708
|
+
},
|
|
709
|
+
children: [
|
|
710
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
711
|
+
label: "Qty",
|
|
712
|
+
value: quantity,
|
|
713
|
+
onChange: (event)=>setQuantity(Math.max(1, Math.min(99, Math.round(Number(event.target.value)) || 1))),
|
|
714
|
+
size: "small",
|
|
715
|
+
sx: {
|
|
716
|
+
width: 80
|
|
717
|
+
},
|
|
718
|
+
slotProps: {
|
|
719
|
+
htmlInput: {
|
|
720
|
+
inputMode: 'numeric'
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
}),
|
|
724
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
725
|
+
variant: "outlined",
|
|
726
|
+
color: "primary",
|
|
727
|
+
size: "large",
|
|
728
|
+
disabled: !hostId || (variant == null ? void 0 : variant.soldOut),
|
|
729
|
+
onClick: handleAddToCart,
|
|
730
|
+
children: added ? 'Added ✓' : 'Add to cart'
|
|
731
|
+
}),
|
|
732
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
733
|
+
variant: "contained",
|
|
734
|
+
color: "primary",
|
|
735
|
+
size: "large",
|
|
736
|
+
disabled: !hostId || status === 'sending' || (variant == null ? void 0 : variant.soldOut) || // No payments on this deployment: the same 501 every time, so
|
|
737
|
+
// the control latches off rather than inviting a retry that
|
|
738
|
+
// cannot succeed (AGL-2019).
|
|
739
|
+
status === 'unconfigured' || // Asked but unanswered: the server would only refuse again.
|
|
740
|
+
shipCountries !== null && !shipTo,
|
|
741
|
+
onClick: handleBuy,
|
|
742
|
+
sx: {
|
|
743
|
+
flex: 1
|
|
744
|
+
},
|
|
745
|
+
children: (variant == null ? void 0 : variant.soldOut) ? 'Sold out' : status === 'sending' ? // it is the shopper's only clue about what is about to
|
|
746
|
+
// happen to their page (AGL-1944).
|
|
747
|
+
nativeCheckout ? 'Opening…' : 'Redirecting…' : buyLabel || (subscribing ? 'Subscribe' : 'Buy now')
|
|
748
|
+
})
|
|
749
|
+
]
|
|
750
|
+
}),
|
|
751
|
+
nativeCheckout ? /*#__PURE__*/ _jsx(Suspense, {
|
|
752
|
+
fallback: /*#__PURE__*/ _jsx(StorefrontPaymentElementFallback, {}),
|
|
753
|
+
children: /*#__PURE__*/ _jsx(StorefrontPaymentElement, {
|
|
754
|
+
clientSecret: nativeCheckout.clientSecret,
|
|
755
|
+
publishableKey: nativeCheckout.publishableKey,
|
|
756
|
+
payLabel: buyLabel || (subscribing ? 'Subscribe' : 'Pay now'),
|
|
757
|
+
// Cancelling drops the form and leaves the session open —
|
|
758
|
+
// deliberately. The shopper may come back to the same
|
|
759
|
+
// attempt key, and an abandoned session is what the AGL-323
|
|
760
|
+
// recovery emails are built on. Nothing is expired from the
|
|
761
|
+
// browser: that is a write against the merchant's account.
|
|
762
|
+
onCancel: ()=>setNativeCheckout(null)
|
|
763
|
+
})
|
|
764
|
+
}) : null,
|
|
765
|
+
shipCountries ? /*#__PURE__*/ _jsx(TextField, {
|
|
766
|
+
select: true,
|
|
767
|
+
label: "Ship to",
|
|
768
|
+
value: shipTo,
|
|
769
|
+
onChange: (event)=>setShipTo(event.target.value),
|
|
770
|
+
size: "small",
|
|
771
|
+
fullWidth: true,
|
|
772
|
+
helperText: "Shipping rates depend on where this is going",
|
|
773
|
+
sx: {
|
|
774
|
+
mb: 2
|
|
775
|
+
},
|
|
776
|
+
children: shipCountries.map((code)=>{
|
|
777
|
+
var _CommerceModel_CHECKOUT_SHIPPING_COUNTRY_NAMES_code;
|
|
778
|
+
return /*#__PURE__*/ _jsx(MenuItem, {
|
|
779
|
+
value: code,
|
|
780
|
+
children: (_CommerceModel_CHECKOUT_SHIPPING_COUNTRY_NAMES_code = CommerceModel.CHECKOUT_SHIPPING_COUNTRY_NAMES[code]) != null ? _CommerceModel_CHECKOUT_SHIPPING_COUNTRY_NAMES_code : code
|
|
781
|
+
}, code);
|
|
782
|
+
})
|
|
783
|
+
}) : null,
|
|
784
|
+
status === 'ask' || status === 'unconfigured' ? /*#__PURE__*/ _jsx(Alert, {
|
|
785
|
+
severity: "info",
|
|
786
|
+
sx: {
|
|
787
|
+
mb: 2
|
|
788
|
+
},
|
|
789
|
+
children: message
|
|
790
|
+
}) : null,
|
|
791
|
+
status === 'error' ? /*#__PURE__*/ _jsx(Alert, {
|
|
792
|
+
severity: "error",
|
|
793
|
+
sx: {
|
|
794
|
+
mb: 2
|
|
795
|
+
},
|
|
796
|
+
children: message || 'Checkout is unavailable right now.'
|
|
797
|
+
}) : null,
|
|
798
|
+
(variant == null ? void 0 : variant.soldOut) && hostId ? notifyState === 'done' ? /*#__PURE__*/ _jsx(Alert, {
|
|
799
|
+
severity: "success",
|
|
800
|
+
sx: {
|
|
801
|
+
mb: 2
|
|
802
|
+
},
|
|
803
|
+
children: 'We will email you when it is back.'
|
|
804
|
+
}) : /*#__PURE__*/ _jsxs(Box, {
|
|
805
|
+
sx: {
|
|
806
|
+
display: 'flex',
|
|
807
|
+
gap: 1,
|
|
808
|
+
mb: 2
|
|
809
|
+
},
|
|
810
|
+
children: [
|
|
811
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
812
|
+
placeholder: "you@example.com",
|
|
813
|
+
type: "email",
|
|
814
|
+
// Third instance of the nameless-input defect (AGL-2392).
|
|
815
|
+
// Named for its job rather than "Email address": this row
|
|
816
|
+
// appears inside a product page that may also carry the
|
|
817
|
+
// newsletter block, and two fields both announced as
|
|
818
|
+
// "Email address" is barely better than none.
|
|
819
|
+
slotProps: {
|
|
820
|
+
htmlInput: {
|
|
821
|
+
'aria-label': 'Email address for back-in-stock alert'
|
|
822
|
+
}
|
|
823
|
+
},
|
|
824
|
+
value: notifyEmail,
|
|
825
|
+
onChange: (event)=>setNotifyEmail(event.target.value),
|
|
826
|
+
size: "small",
|
|
827
|
+
sx: {
|
|
828
|
+
flex: 1
|
|
829
|
+
}
|
|
830
|
+
}),
|
|
831
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
832
|
+
size: "small",
|
|
833
|
+
variant: "outlined",
|
|
834
|
+
disabled: !notifyEmail.trim(),
|
|
835
|
+
onClick: async ()=>{
|
|
836
|
+
const response = await siteFetch('/api/commerce/notify-restock', {
|
|
837
|
+
method: 'POST',
|
|
838
|
+
headers: {
|
|
839
|
+
'Content-Type': 'application/json'
|
|
840
|
+
},
|
|
841
|
+
body: JSON.stringify({
|
|
842
|
+
hostId,
|
|
843
|
+
productId: resolved.id,
|
|
844
|
+
email: notifyEmail
|
|
845
|
+
})
|
|
846
|
+
}).catch(()=>null);
|
|
847
|
+
if (response == null ? void 0 : response.ok) setNotifyState('done');
|
|
848
|
+
},
|
|
849
|
+
children: 'Notify me'
|
|
850
|
+
})
|
|
851
|
+
]
|
|
852
|
+
}) : null,
|
|
853
|
+
!hideDescription && resolved.description ? /*#__PURE__*/ _jsx(Typography, {
|
|
854
|
+
variant: "body1",
|
|
855
|
+
color: "text.secondary",
|
|
856
|
+
children: resolved.description
|
|
857
|
+
}) : null
|
|
858
|
+
]
|
|
859
|
+
})
|
|
860
|
+
]
|
|
861
|
+
}));
|
|
862
|
+
});
|
|
863
|
+
ProductDetail.displayName = 'AglynProductDetail';
|
|
864
|
+
export const schema = {
|
|
865
|
+
$id: ID,
|
|
866
|
+
pluginId: BUNDLE_ID,
|
|
867
|
+
displayName: 'Product detail',
|
|
868
|
+
description: "One product's gallery, options and buy button.",
|
|
869
|
+
category: Aglyn.ComponentCategory.COMMERCE,
|
|
870
|
+
icon: {
|
|
871
|
+
path: mdiTagOutline.path,
|
|
872
|
+
sx: {
|
|
873
|
+
color: '#2e7d32'
|
|
874
|
+
}
|
|
875
|
+
},
|
|
876
|
+
flags: {
|
|
877
|
+
selfClosing: Aglyn.FEATURE_FLAG.ENABLED
|
|
878
|
+
},
|
|
879
|
+
attributes: [
|
|
880
|
+
{
|
|
881
|
+
name: 'slug',
|
|
882
|
+
label: 'Product slug',
|
|
883
|
+
description: 'Pin to one product; blank follows the /products/{slug} URL ' + '(product page template).',
|
|
884
|
+
component: Aglyn.FieldComponentType.TEXT_FIELD
|
|
885
|
+
},
|
|
886
|
+
{
|
|
887
|
+
name: 'buyLabel',
|
|
888
|
+
label: 'Buy button label',
|
|
889
|
+
description: 'Defaults to "Buy now".',
|
|
890
|
+
component: Aglyn.FieldComponentType.TEXT_FIELD
|
|
891
|
+
},
|
|
892
|
+
{
|
|
893
|
+
name: 'hideDescription',
|
|
894
|
+
label: 'Hide description',
|
|
895
|
+
description: 'Design the description separately with tokens.',
|
|
896
|
+
component: Aglyn.FieldComponentType.CHECKBOX
|
|
897
|
+
},
|
|
898
|
+
{
|
|
899
|
+
// Off by default, so no existing page changes shape on deploy. The cart
|
|
900
|
+
// has carried this field all along and the product page had none, so a
|
|
901
|
+
// shopper buying the same goods through Buy now had nowhere to enter a
|
|
902
|
+
// code the merchant had advertised.
|
|
903
|
+
name: 'showCoupon',
|
|
904
|
+
label: 'Show discount code field',
|
|
905
|
+
description: 'Lets a buyer enter a discount or coupon code before buying.',
|
|
906
|
+
component: Aglyn.FieldComponentType.CHECKBOX
|
|
907
|
+
}
|
|
908
|
+
]
|
|
909
|
+
};
|
|
910
|
+
export const presets = [
|
|
911
|
+
{
|
|
912
|
+
$id: generatePresetId(ID),
|
|
913
|
+
type: Aglyn.NodeType.PRESET,
|
|
914
|
+
displayName: 'Product detail',
|
|
915
|
+
pluginId: BUNDLE_ID,
|
|
916
|
+
description: 'Gallery, variant picker, and buy button for one product',
|
|
917
|
+
category: Aglyn.ComponentCategory.COMMERCE,
|
|
918
|
+
icon: {
|
|
919
|
+
path: mdiTagOutline.path,
|
|
920
|
+
sx: {
|
|
921
|
+
color: '#2e7d32'
|
|
922
|
+
}
|
|
923
|
+
},
|
|
924
|
+
data: {
|
|
925
|
+
$id: null,
|
|
926
|
+
componentId: ID,
|
|
927
|
+
pluginId: BUNDLE_ID,
|
|
928
|
+
props: {}
|
|
929
|
+
}
|
|
930
|
+
},
|
|
931
|
+
{
|
|
932
|
+
// Product page (AGL-561): the commerce-standard PDP subtree —
|
|
933
|
+
// breadcrumb, detail, related products, reviews — for the product
|
|
934
|
+
// page template screen. `{{product.name}}` resolves there via the
|
|
935
|
+
// site page resolver's token pass (AGL-292); node shapes follow
|
|
936
|
+
// the Sections & Blocks convention (AGL-539) and reference only
|
|
937
|
+
// persisted component ids.
|
|
938
|
+
$id: generatePresetId(ID, 'page'),
|
|
939
|
+
type: Aglyn.NodeType.PRESET,
|
|
940
|
+
displayName: 'Product page',
|
|
941
|
+
pluginId: BUNDLE_ID,
|
|
942
|
+
description: 'Breadcrumb, product detail, related products, and reviews',
|
|
943
|
+
category: Aglyn.ComponentCategory.COMMERCE,
|
|
944
|
+
icon: {
|
|
945
|
+
path: mdiTagOutline.path,
|
|
946
|
+
sx: {
|
|
947
|
+
color: '#2e7d32'
|
|
948
|
+
}
|
|
949
|
+
},
|
|
950
|
+
data: {
|
|
951
|
+
$id: null,
|
|
952
|
+
componentId: 'muiStack',
|
|
953
|
+
pluginId: Aglyn.MUI_BUNDLE_ID,
|
|
954
|
+
props: {
|
|
955
|
+
spacing: 4
|
|
956
|
+
},
|
|
957
|
+
// Styling on the node's own sx, never in props (AGL-1346): both
|
|
958
|
+
// records render, but only `node.sx` is the one the Styles panel can
|
|
959
|
+
// read, edit or clear.
|
|
960
|
+
sx: {
|
|
961
|
+
paddingTop: 2,
|
|
962
|
+
paddingBottom: 2
|
|
963
|
+
},
|
|
964
|
+
nodes: [
|
|
965
|
+
{
|
|
966
|
+
$id: null,
|
|
967
|
+
componentId: 'muiStack',
|
|
968
|
+
pluginId: Aglyn.MUI_BUNDLE_ID,
|
|
969
|
+
props: {
|
|
970
|
+
direction: 'row',
|
|
971
|
+
spacing: 1
|
|
972
|
+
},
|
|
973
|
+
sx: {
|
|
974
|
+
alignItems: 'center'
|
|
975
|
+
},
|
|
976
|
+
nodes: [
|
|
977
|
+
{
|
|
978
|
+
$id: null,
|
|
979
|
+
componentId: 'muiScreenLink',
|
|
980
|
+
pluginId: Aglyn.MUI_BUNDLE_ID,
|
|
981
|
+
props: {
|
|
982
|
+
children: 'Shop',
|
|
983
|
+
size: 'small',
|
|
984
|
+
color: 'inherit'
|
|
985
|
+
}
|
|
986
|
+
},
|
|
987
|
+
{
|
|
988
|
+
$id: null,
|
|
989
|
+
componentId: 'muiTypography',
|
|
990
|
+
pluginId: Aglyn.MUI_BUNDLE_ID,
|
|
991
|
+
props: {
|
|
992
|
+
variant: 'body2',
|
|
993
|
+
children: '/ {{product.name}}'
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
]
|
|
997
|
+
},
|
|
998
|
+
{
|
|
999
|
+
$id: null,
|
|
1000
|
+
componentId: ID,
|
|
1001
|
+
pluginId: BUNDLE_ID,
|
|
1002
|
+
props: {}
|
|
1003
|
+
},
|
|
1004
|
+
{
|
|
1005
|
+
$id: null,
|
|
1006
|
+
componentId: RELATED_PRODUCTS_ID,
|
|
1007
|
+
pluginId: BUNDLE_ID,
|
|
1008
|
+
props: {}
|
|
1009
|
+
},
|
|
1010
|
+
{
|
|
1011
|
+
$id: null,
|
|
1012
|
+
componentId: PRODUCT_REVIEWS_ID,
|
|
1013
|
+
pluginId: BUNDLE_ID,
|
|
1014
|
+
props: {}
|
|
1015
|
+
}
|
|
1016
|
+
]
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
];
|
|
1020
|
+
export default ProductDetail;
|
|
1021
|
+
|
|
1022
|
+
//# sourceMappingURL=product-detail.js.map
|