@sazito/checkout 0.4.13 → 0.4.15

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.
@@ -3,8 +3,8 @@
3
3
 
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var react = require('react');
6
- var useCheckout = require('../chunks/use-checkout-CYsNFiM6.cjs');
7
- var labels = require('../chunks/labels-BfqHC6_h.cjs');
6
+ var useCheckout = require('../chunks/use-checkout-XcQVjeL0.cjs');
7
+ var labels = require('../chunks/labels-Cb5obEcJ.cjs');
8
8
  var next_paymentReturn = require('./payment-return.cjs');
9
9
  require('@sazito/client-sdk');
10
10
 
@@ -518,7 +518,7 @@ function ShippingRateIcon({ rate }) {
518
518
  case 'delivery-man':
519
519
  return jsxRuntime.jsx(DeliveryManIcon, {});
520
520
  default:
521
- return rate.icon && isImageUrl(rate.icon) ? jsxRuntime.jsx("img", { src: rate.icon, alt: "" }) : jsxRuntime.jsx(TruckIcon, {});
521
+ return rate.icon && isImageUrl$1(rate.icon) ? jsxRuntime.jsx("img", { src: rate.icon, alt: "" }) : jsxRuntime.jsx(TruckIcon, {});
522
522
  }
523
523
  }
524
524
  function shippingRateIconKey(rate) {
@@ -617,7 +617,7 @@ function parseColorChannels(value) {
617
617
  return [Number(channels[1]), Number(channels[2]), Number(channels[3])];
618
618
  return null;
619
619
  }
620
- function isImageUrl(value) {
620
+ function isImageUrl$1(value) {
621
621
  return /^(https?:)?\/\//i.test(value) || value.startsWith('/') || value.startsWith('data:');
622
622
  }
623
623
  function PostIcon() {
@@ -710,8 +710,36 @@ function PaymentIcon({ kind }) {
710
710
  }
711
711
  }
712
712
 
713
+ function groupResultItemsByShipping(invoiceItems, shippingItems) {
714
+ const itemById = new Map();
715
+ const assignedItems = new Set();
716
+ invoiceItems.forEach((item) => {
717
+ if (item.id !== undefined)
718
+ itemById.set(String(item.id), item);
719
+ });
720
+ const shipmentGroups = shippingItems.map((shipping) => {
721
+ const items = shipping.invoiceItemIds.flatMap((itemId) => {
722
+ const item = itemById.get(String(itemId));
723
+ if (!item || assignedItems.has(item))
724
+ return [];
725
+ assignedItems.add(item);
726
+ return [item];
727
+ });
728
+ return { shipping, items };
729
+ });
730
+ // Older payment responses did not expose invoice-line IDs. A single shipping
731
+ // method is still unambiguous, so keep those orders grouped correctly.
732
+ if (shipmentGroups.length === 1 && shipmentGroups[0].items.length === 0) {
733
+ shipmentGroups[0].items = [...invoiceItems];
734
+ invoiceItems.forEach((item) => assignedItems.add(item));
735
+ }
736
+ return {
737
+ shipmentGroups: shipmentGroups.filter((group) => group.items.length > 0),
738
+ unassignedItems: invoiceItems.filter((item) => !assignedItems.has(item))
739
+ };
740
+ }
713
741
  function ResultStep({ continueShoppingUrl }) {
714
- const { state, actions, money, price, t } = useCheckout.useCheckout();
742
+ const { state, actions, money, t } = useCheckout.useCheckout();
715
743
  const result = state.result;
716
744
  const status = result?.status ?? 'pending';
717
745
  const order = result?.order;
@@ -719,21 +747,42 @@ function ResultStep({ continueShoppingUrl }) {
719
747
  const showDetails = Boolean(order && (status === 'success' || status === 'pending'));
720
748
  const showSummary = invoice?.netTotal != null || invoice?.finalTotal != null;
721
749
  const isFailure = status === 'failed' || status === 'stock_violated';
750
+ const orderDetailsUrl = order
751
+ ? buildOrderDetailsUrl(order.id, order.orderIdentifier, continueShoppingUrl)
752
+ : null;
753
+ const groupedItems = invoice
754
+ ? groupResultItemsByShipping(invoice.invoiceItems, invoice.shippingItems)
755
+ : { shipmentGroups: [], unassignedItems: [] };
756
+ const renderItems = (items) => (jsxRuntime.jsx("ul", { className: "szc-result-items", children: items.map((item, index) => (jsxRuntime.jsxs("li", { className: "szc-result-item", children: [jsxRuntime.jsxs("span", { className: "szc-result-item__product", children: [item.image?.url ? (jsxRuntime.jsx("img", { className: "szc-result-item__thumb", src: item.image.url, alt: "" })) : (jsxRuntime.jsx(ProductPlaceholder, { className: "szc-result-item__thumb" })), jsxRuntime.jsxs("span", { children: [jsxRuntime.jsx("strong", { children: item.name }), item.variantAttributes.length ? (jsxRuntime.jsx("small", { children: item.variantAttributes.map(formatAttribute).join(' · ') })) : null] })] }), jsxRuntime.jsxs("span", { className: "szc-result-item__quantity", children: [jsxRuntime.jsx("span", { className: "szc-result-item__mobile-label", children: t.quantity }), jsxRuntime.jsx("strong", { children: labels.formatNumber(item.noOfItems, state.locale) })] }), jsxRuntime.jsxs("span", { className: "szc-result-item__total", children: [jsxRuntime.jsx("span", { className: "szc-result-item__mobile-label", children: t.lineTotal }), jsxRuntime.jsx("strong", { children: money(item.totalItemsPrice) })] })] }, `${String(item.id ?? item.productVariantId)}-${index}`))) }));
722
757
  const titleMap = {
723
758
  success: t.paymentSuccess,
724
759
  failed: t.paymentFailed,
725
760
  pending: t.paymentPending,
726
761
  stock_violated: t.paymentFailed
727
762
  };
728
- return (jsxRuntime.jsxs("section", { className: `szc-result szc-result--${status}${showDetails ? '' : ' szc-result--compact'}`, children: [jsxRuntime.jsxs("div", { className: "szc-result__hero", role: isFailure ? 'alert' : 'status', "aria-live": isFailure ? 'assertive' : 'polite', children: [jsxRuntime.jsx("div", { className: "szc-result__icon", children: jsxRuntime.jsx("span", { className: "szc-result__icon-mark", children: status === 'success' ? (jsxRuntime.jsx(CheckCircle, {})) : status === 'pending' ? (jsxRuntime.jsx(Spinner, {})) : (jsxRuntime.jsx(CrossCircle, {})) }) }), jsxRuntime.jsxs("div", { className: "szc-result__copy", children: [jsxRuntime.jsx("h2", { className: "szc-result__title", children: titleMap[status] }), status === 'pending' ? jsxRuntime.jsx("p", { className: "szc-result__hint", children: t.paymentPendingHint }) : null, result?.message ? (jsxRuntime.jsx("p", { className: "szc-result__message", dir: "auto", children: result.message })) : null, status === 'success' && order ? (jsxRuntime.jsx("p", { className: "szc-result__hint", children: t.orderConfirmedHint })) : null] }), order ? (jsxRuntime.jsxs("dl", { className: "szc-result__reference", children: [jsxRuntime.jsxs("div", { className: "szc-result__reference-primary", children: [jsxRuntime.jsx("dt", { children: t.orderNumber }), jsxRuntime.jsx("dd", { children: formatPublicId(order.orderNumber, state.locale) })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("dt", { children: t.orderId }), jsxRuntime.jsx("dd", { children: formatPublicId(order.id, state.locale) })] })] })) : null, jsxRuntime.jsxs("div", { className: "szc-result__actions", children: [status === 'failed' || status === 'stock_violated' ? (jsxRuntime.jsx(Button, { onClick: () => actions.goToStep('payment'), children: t.tryAgain })) : null, continueShoppingUrl ? (jsxRuntime.jsx(Button, { variant: status === 'success' ? 'primary' : 'outline', asChild: true, children: jsxRuntime.jsx("a", { href: continueShoppingUrl, children: t.continueShopping }) })) : null] })] }), showDetails && order && invoice ? (jsxRuntime.jsxs("div", { className: "szc-result__details", children: [jsxRuntime.jsx("h3", { className: "szc-result__details-title", children: t.orderDetails }), invoice.shippingItems.length > 0 ? (jsxRuntime.jsxs("section", { className: "szc-result__section", "aria-labelledby": "szc-result-shipping-title", children: [jsxRuntime.jsx("h4", { id: "szc-result-shipping-title", className: "szc-result__section-title", children: t.shippingMethods }), jsxRuntime.jsx("div", { className: "szc-result-shipping-list", children: invoice.shippingItems.map((shipping) => (jsxRuntime.jsx("article", { className: "szc-result-group", children: jsxRuntime.jsxs("header", { className: "szc-result-group__head", children: [jsxRuntime.jsx("span", { className: "szc-result-group__mark", "aria-hidden": "true", children: shipping.rate.icon ? jsxRuntime.jsx("img", { src: shipping.rate.icon, alt: "" }) : jsxRuntime.jsx(DeliveryIcon, {}) }), jsxRuntime.jsx("span", { className: "szc-result-group__title", children: shipping.rate.name }), jsxRuntime.jsx("span", { className: "szc-result-group__price", children: price(shipping.rate.price) })] }) }, String(shipping.id)))) })] })) : null, invoice.invoiceItems.length > 0 ? (jsxRuntime.jsxs("section", { className: "szc-result-group", "aria-labelledby": "szc-result-items-title", children: [jsxRuntime.jsxs("header", { className: "szc-result-group__head", children: [jsxRuntime.jsx("span", { className: "szc-result-group__mark", "aria-hidden": "true", children: jsxRuntime.jsx(OrderItemsIcon, {}) }), jsxRuntime.jsx("h4", { id: "szc-result-items-title", className: "szc-result-group__title", children: t.orderItems })] }), jsxRuntime.jsxs("div", { className: "szc-result-items__head", "aria-hidden": "true", children: [jsxRuntime.jsx("span", { children: t.product }), jsxRuntime.jsx("span", { children: t.quantity }), jsxRuntime.jsx("span", { children: t.lineTotal })] }), jsxRuntime.jsx("ul", { className: "szc-result-items", children: invoice.invoiceItems.map((item, index) => (jsxRuntime.jsxs("li", { className: "szc-result-item", children: [jsxRuntime.jsxs("span", { className: "szc-result-item__product", children: [item.image?.url ? (jsxRuntime.jsx("img", { className: "szc-result-item__thumb", src: item.image.url, alt: "" })) : (jsxRuntime.jsx(ProductPlaceholder, { className: "szc-result-item__thumb" })), jsxRuntime.jsxs("span", { children: [jsxRuntime.jsx("strong", { children: item.name }), item.variantAttributes.length ? (jsxRuntime.jsx("small", { children: item.variantAttributes.map(formatAttribute).join(' · ') })) : null] })] }), jsxRuntime.jsxs("span", { className: "szc-result-item__quantity", children: [jsxRuntime.jsx("span", { className: "szc-result-item__mobile-label", children: t.quantity }), labels.formatNumber(item.noOfItems, state.locale)] }), jsxRuntime.jsxs("span", { className: "szc-result-item__total", children: [jsxRuntime.jsx("span", { className: "szc-result-item__mobile-label", children: t.lineTotal }), money(item.totalItemsPrice)] })] }, `${String(item.productVariantId)}-${index}`))) })] })) : null, showSummary ? jsxRuntime.jsxs("dl", { className: "szc-result-summary", children: [invoice.netTotal != null ? (jsxRuntime.jsx(SummaryRow, { label: t.subtotal, value: money(invoice.netTotal) })) : null, invoice.shippingTotal != null ? (jsxRuntime.jsx(SummaryRow, { label: t.shipping, value: money(invoice.shippingTotal) })) : null, invoice.discountTotal != null && invoice.discountTotal > 0 ? (jsxRuntime.jsx(SummaryRow, { label: t.discount, value: `−${money(invoice.discountTotal)}` })) : null, invoice.creditTotal != null && invoice.creditTotal > 0 ? (jsxRuntime.jsx(SummaryRow, { label: t.credit, value: `−${money(invoice.creditTotal)}` })) : null, invoice.vat != null && invoice.vat > 0 ? (jsxRuntime.jsx(SummaryRow, { label: t.vat, value: money(invoice.vat) })) : null, invoice.customerProfit != null && invoice.customerProfit > 0 ? (jsxRuntime.jsx(SummaryRow, { label: t.yourSavings, value: money(invoice.customerProfit), savings: true })) : null, invoice.finalTotal != null ? (jsxRuntime.jsx(SummaryRow, { label: t.total, value: money(invoice.finalTotal), total: true })) : null] }) : null] })) : null] }));
729
- }
730
- function formatPublicId(value, locale) {
731
- const text = String(value);
732
- return locale === 'fa' ? labels.toPersianDigits(text) : text;
763
+ return (jsxRuntime.jsxs("section", { className: `szc-result szc-result--${status}${showDetails ? '' : ' szc-result--compact'}`, children: [jsxRuntime.jsxs("div", { className: "szc-result__hero", role: isFailure ? 'alert' : 'status', "aria-live": isFailure ? 'assertive' : 'polite', children: [jsxRuntime.jsx("div", { className: "szc-result__icon", children: jsxRuntime.jsx("span", { className: "szc-result__icon-mark", children: status === 'success' ? (jsxRuntime.jsx(CheckCircle, {})) : status === 'pending' ? (jsxRuntime.jsx(Spinner, {})) : (jsxRuntime.jsx(CrossCircle, {})) }) }), jsxRuntime.jsxs("div", { className: "szc-result__copy", children: [jsxRuntime.jsx("h2", { className: "szc-result__title", children: titleMap[status] }), status === 'pending' ? jsxRuntime.jsx("p", { className: "szc-result__hint", children: t.paymentPendingHint }) : null, !isFailure && result?.message ? (jsxRuntime.jsx("p", { className: "szc-result__message", dir: "auto", children: result.message })) : null, status === 'success' && order ? (jsxRuntime.jsx("p", { className: "szc-result__hint", children: t.orderConfirmedHint })) : null] }), order ? (jsxRuntime.jsx("dl", { className: "szc-result__reference", children: jsxRuntime.jsxs("div", { className: "szc-result__reference-primary", children: [jsxRuntime.jsx("dt", { children: t.orderNumber }), jsxRuntime.jsx("dd", { dir: "ltr", children: String(order.orderNumber) })] }) })) : null, jsxRuntime.jsxs("div", { className: "szc-result__actions", children: [status === 'failed' || status === 'stock_violated' ? (jsxRuntime.jsx(Button, { onClick: () => void actions.retryPayment(), loading: state.flags.loadingPayments, children: t.tryAgain })) : null, orderDetailsUrl ? (jsxRuntime.jsx(Button, { asChild: true, children: jsxRuntime.jsx("a", { href: orderDetailsUrl, children: t.orderDetails }) })) : null, continueShoppingUrl ? (jsxRuntime.jsx(Button, { variant: "outline", asChild: true, children: jsxRuntime.jsx("a", { href: continueShoppingUrl, children: t.backToShop }) })) : null] })] }), showDetails && order && invoice ? (jsxRuntime.jsxs("div", { className: "szc-result__details", children: [groupedItems.shipmentGroups.map(({ shipping, items }, index) => {
764
+ const description = shipping.rate.description?.trim();
765
+ return (jsxRuntime.jsxs("section", { className: "szc-result__details-card szc-result-shipment", "aria-label": `${t.shippingMethod}: ${shipping.rate.name}`, children: [jsxRuntime.jsxs("header", { className: "szc-result-shipment__head", children: [jsxRuntime.jsx("span", { className: "szc-result-shipment__mark", "aria-hidden": "true", children: isImageUrl(shipping.rate.icon) ? (jsxRuntime.jsx("img", { src: shipping.rate.icon, alt: "" })) : (jsxRuntime.jsx(DeliveryIcon, {})) }), jsxRuntime.jsxs("span", { className: "szc-result-shipment__name", children: [jsxRuntime.jsx("small", { className: "szc-result-shipment__eyebrow", children: t.shippingMethod }), jsxRuntime.jsx("strong", { children: shipping.rate.name }), description ? (jsxRuntime.jsx("span", { className: "szc-result-shipment__description", children: description })) : null] }), shipping.rate.type !== 'free' ? (jsxRuntime.jsx("span", { className: "szc-result-shipment__price", children: money(shipping.rate.price) })) : null] }), renderItems(items)] }, `${String(shipping.id)}-${index}`));
766
+ }), groupedItems.unassignedItems.length > 0 ? (jsxRuntime.jsx("section", { className: "szc-result__details-card szc-result-unassigned-items", "aria-label": t.orderItems, children: renderItems(groupedItems.unassignedItems) })) : null, showSummary ? (jsxRuntime.jsxs("dl", { className: "szc-result-summary", children: [invoice.netTotal != null ? (jsxRuntime.jsx(SummaryRow, { label: t.subtotal, value: money(invoice.netTotal) })) : null, invoice.shippingTotal != null ? (jsxRuntime.jsx(SummaryRow, { label: t.shipping, value: money(invoice.shippingTotal) })) : null, invoice.discountTotal != null && invoice.discountTotal > 0 ? (jsxRuntime.jsx(SummaryRow, { label: t.discount, value: `−${money(invoice.discountTotal)}` })) : null, invoice.creditTotal != null && invoice.creditTotal > 0 ? (jsxRuntime.jsx(SummaryRow, { label: t.credit, value: `−${money(invoice.creditTotal)}` })) : null, invoice.vat != null && invoice.vat > 0 ? (jsxRuntime.jsx(SummaryRow, { label: t.vat, value: money(invoice.vat) })) : null, invoice.customerProfit != null && invoice.customerProfit > 0 ? (jsxRuntime.jsx(SummaryRow, { label: t.yourSavings, value: money(invoice.customerProfit), savings: true })) : null, invoice.finalTotal != null ? (jsxRuntime.jsx(SummaryRow, { label: t.total, value: money(invoice.finalTotal), total: true })) : null] })) : null] })) : null] }));
767
+ }
768
+ function buildOrderDetailsUrl(orderId, orderIdentifier, continueShoppingUrl) {
769
+ const path = `/orderinfo/${encodeURIComponent(String(orderId))}/${encodeURIComponent(orderIdentifier)}`;
770
+ if (!continueShoppingUrl)
771
+ return path;
772
+ try {
773
+ const storefrontUrl = new URL(continueShoppingUrl);
774
+ return new URL(path, storefrontUrl.origin).toString();
775
+ }
776
+ catch {
777
+ return path;
778
+ }
733
779
  }
734
780
  function formatAttribute(attribute) {
735
781
  return `${attribute.name}: ${attribute.value}`;
736
782
  }
783
+ function isImageUrl(value) {
784
+ return Boolean(value && (/^https?:\/\//i.test(value) || value.startsWith('/') || value.startsWith('data:image/')));
785
+ }
737
786
  function SummaryRow({ label, value, savings = false, total = false }) {
738
787
  return (jsxRuntime.jsxs("div", { className: `${total ? 'szc-result-summary__total' : ''} ${savings ? 'szc-result-summary__savings' : ''}`.trim(), children: [jsxRuntime.jsx("dt", { children: label }), jsxRuntime.jsx("dd", { children: value })] }));
739
788
  }
@@ -746,9 +795,6 @@ function CrossCircle() {
746
795
  function DeliveryIcon() {
747
796
  return (jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", width: "22", height: "22", fill: "none", "aria-hidden": "true", children: [jsxRuntime.jsx("path", { d: "M3 6.5h11v10H3zM14 10h3.5l3 3v3.5H14z", stroke: "currentColor", strokeWidth: "1.6", strokeLinejoin: "round" }), jsxRuntime.jsx("circle", { cx: "7", cy: "18", r: "1.75", stroke: "currentColor", strokeWidth: "1.6" }), jsxRuntime.jsx("circle", { cx: "17.5", cy: "18", r: "1.75", stroke: "currentColor", strokeWidth: "1.6" })] }));
748
797
  }
749
- function OrderItemsIcon() {
750
- return (jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", width: "22", height: "22", fill: "none", "aria-hidden": "true", children: [jsxRuntime.jsx("path", { d: "M5 7.5h14v11H5zM8 7.5V5h8v2.5", stroke: "currentColor", strokeWidth: "1.6", strokeLinejoin: "round" }), jsxRuntime.jsx("path", { d: "M8.5 12h7M8.5 15h5", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round" })] }));
751
- }
752
798
 
753
799
  function themeVars(theme) {
754
800
  const vars = {};
@@ -873,7 +919,7 @@ function SazitoCheckout({ theme, continueShoppingUrl, className, renderNextButto
873
919
  status: resultStatus,
874
920
  order: state.result?.order,
875
921
  continueShoppingUrl,
876
- onRetry: () => actions.goToStep('payment')
922
+ onRetry: () => void actions.retryPayment()
877
923
  })) : (jsxRuntime.jsx(ResultStep, { continueShoppingUrl: continueShoppingUrl })) })) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs("div", { className: `szc-layout${cartEmpty ? ' szc-layout--full' : ''}`, children: [jsxRuntime.jsxs("main", { className: "szc-main", children: [error && !emptyCartError ? jsxRuntime.jsx(ErrorBanner, { message: error.message }) : null, step === 'cart' ? (jsxRuntime.jsx(CartStep, { continueShoppingUrl: continueShoppingUrl, emptyCart: emptyCart, renderEmpty: renderEmptyCart })) : null, step === 'shipping' ? jsxRuntime.jsx(ShippingStep, {}) : null, step === 'payment' ? jsxRuntime.jsx(PaymentStep, {}) : null, actionsVisible && backButtonNode ? (jsxRuntime.jsx("div", { className: "szc-back-row", children: backButtonNode })) : null] }), !cartEmpty ? (jsxRuntime.jsxs("div", { className: "szc-side", children: [jsxRuntime.jsx(OrderSummary, {}), actionsVisible ? jsxRuntime.jsx("div", { className: "szc-side__cta", children: nextButtonNode }) : null] })) : null] }) })), actionsVisible ? (jsxRuntime.jsx("div", { className: "szc-footer-bar", children: jsxRuntime.jsxs("div", { className: "szc-footer", children: [jsxRuntime.jsxs("div", { className: "szc-footer__total", children: [jsxRuntime.jsx("span", { className: "szc-footer__total-label", children: t.total }), jsxRuntime.jsx("span", { className: "szc-footer__total-value", children: money(summary.total) })] }), jsxRuntime.jsx("div", { className: "szc-footer__actions", children: nextButtonNode })] }) })) : null] }));
878
924
  }
879
925