@nevios/storefront-kit 1.0.0 → 1.3.0

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/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React10 = require('react');
3
+ var React19 = require('react');
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var storefrontJs = require('@nevios/storefront-js');
6
6
 
@@ -22,15 +22,15 @@ function _interopNamespace(e) {
22
22
  return Object.freeze(n);
23
23
  }
24
24
 
25
- var React10__namespace = /*#__PURE__*/_interopNamespace(React10);
25
+ var React19__namespace = /*#__PURE__*/_interopNamespace(React19);
26
26
 
27
27
  // src/provider.tsx
28
- var StorefrontContext = React10__namespace.createContext(null);
28
+ var StorefrontContext = React19__namespace.createContext(null);
29
29
  function NeviosProvider({ client, children }) {
30
30
  return /* @__PURE__ */ jsxRuntime.jsx(StorefrontContext.Provider, { value: client, children });
31
31
  }
32
32
  function useStorefront() {
33
- const client = React10__namespace.useContext(StorefrontContext);
33
+ const client = React19__namespace.useContext(StorefrontContext);
34
34
  if (!client) {
35
35
  throw new Error(
36
36
  "useStorefront must be used inside <NeviosProvider>. Wrap your app root with it."
@@ -39,7 +39,7 @@ function useStorefront() {
39
39
  return client;
40
40
  }
41
41
  function useStorefrontOptional() {
42
- return React10__namespace.useContext(StorefrontContext);
42
+ return React19__namespace.useContext(StorefrontContext);
43
43
  }
44
44
  var DEFAULTS = {
45
45
  brand: "#111111",
@@ -75,7 +75,7 @@ function ThemeProvider({
75
75
  as: Tag = "div"
76
76
  }) {
77
77
  const style = themeToCssVars(theme);
78
- return React10__namespace.createElement(
78
+ return React19__namespace.createElement(
79
79
  Tag,
80
80
  { "data-nevios-theme": "", style },
81
81
  children
@@ -201,6 +201,37 @@ var en = {
201
201
  "order.terminal.cancelled": "This order was cancelled.",
202
202
  "order.terminal.refunded": "This order was refunded.",
203
203
  "order.terminal.returned": "This order was returned.",
204
+ // payment page — the four situations it can be in
205
+ "payment.title": "Pay for order {order}",
206
+ "payment.amountDue": "Amount due",
207
+ "payment.methodLabel": "Payment method",
208
+ "payment.payNow": "Pay now",
209
+ "payment.finish": "Finish payment",
210
+ "payment.loading": "Loading payment\u2026",
211
+ "payment.loadError": "Couldn't load this payment.",
212
+ "payment.actionError": "That didn't go through. Please try again.",
213
+ // …paid
214
+ "payment.paidTitle": "Paid",
215
+ "payment.paidBody": "Order {order} is paid. Nothing further is needed.",
216
+ "payment.paidAmount": "Paid",
217
+ // …returning from a gateway, callback still in flight
218
+ "payment.verifyingTitle": "Checking your payment\u2026",
219
+ "payment.verifyingBody": "This takes a few seconds. Don't pay again \u2014 we'll update this page.",
220
+ // …locked, one sentence per reason
221
+ "payment.blockedTitle": "This order can't be paid",
222
+ "payment.blocked.orderCancelled": "This order was cancelled, so there is nothing to pay.",
223
+ "payment.blocked.alreadyPaid": "This order is already paid.",
224
+ "payment.blocked.authorizationHeld": "Your bank is holding the funds for this order. Once the payment settles this page will show it as paid.",
225
+ "payment.blocked.documentIssued": "An invoice has been issued for this order, so the amount is fixed. Contact us to change how you pay.",
226
+ // …bank transfer
227
+ "payment.account": "Account",
228
+ "payment.beneficiary": "Beneficiary",
229
+ "payment.variableSymbol": "Variable symbol",
230
+ "payment.amount": "Amount",
231
+ "payment.copy": "Copy",
232
+ "payment.copied": "Copied",
233
+ "payment.qrAlt": "QR code for the payment",
234
+ "payment.qrCaption": "Scan in your banking app",
204
235
  // error pages
205
236
  "error.notFound.title": "Page not found",
206
237
  "error.notFound.body": "This page doesn't exist or isn't available in your region.",
@@ -217,6 +248,20 @@ var en = {
217
248
  "account.signOut": "Sign out",
218
249
  "account.greeting": "Signed in as {email}",
219
250
  "account.orders": "Your orders",
251
+ "account.loadError": "Could not load your account. Please try again.",
252
+ "account.retry": "Try again",
253
+ "account.loadMore": "Load more",
254
+ "account.signInError": "Could not request a sign-in link. Please try again shortly.",
255
+ "account.security": "Account security",
256
+ "account.newEmail": "New email",
257
+ "account.changeEmail": "Verify new email",
258
+ "account.recentLogin": "Sign in again by email before making this change.",
259
+ "account.sessions": "Sessions",
260
+ "account.currentSession": "Current session",
261
+ "account.revokeSession": "Sign out",
262
+ "account.closeAccount": "Close account",
263
+ "account.closeWarning": "Closing your account signs out all devices and disables account access. Orders and invoices are retained. Contact the shop to restore access.",
264
+ "account.confirmClose": "Confirm account closure",
220
265
  "account.noOrders": "No orders yet.",
221
266
  "account.addresses": "Saved addresses",
222
267
  "account.noAddresses": "No saved addresses yet.",
@@ -357,6 +402,33 @@ var cs = {
357
402
  "order.terminal.cancelled": "Tato objedn\xE1vka byla zru\u0161ena.",
358
403
  "order.terminal.refunded": "Tato objedn\xE1vka byla refundov\xE1na.",
359
404
  "order.terminal.returned": "Tato objedn\xE1vka byla vr\xE1cena.",
405
+ // platební stránka — čtyři situace, ve kterých může být
406
+ "payment.title": "Zaplatit objedn\xE1vku {order}",
407
+ "payment.amountDue": "K \xFAhrad\u011B",
408
+ "payment.methodLabel": "Zp\u016Fsob platby",
409
+ "payment.payNow": "Zaplatit",
410
+ "payment.finish": "Dokon\u010Dit platbu",
411
+ "payment.loading": "Na\u010D\xEDt\xE1n\xED platby\u2026",
412
+ "payment.loadError": "Platbu se nepoda\u0159ilo na\u010D\xEDst.",
413
+ "payment.actionError": "Nepovedlo se to. Zkuste to pros\xEDm znovu.",
414
+ "payment.paidTitle": "Zaplaceno",
415
+ "payment.paidBody": "Objedn\xE1vka {order} je zaplacen\xE1. Nic dal\u0161\xEDho d\u011Blat nemus\xEDte.",
416
+ "payment.paidAmount": "Uhrazeno",
417
+ "payment.verifyingTitle": "Ov\u011B\u0159ujeme platbu\u2026",
418
+ "payment.verifyingBody": "Chvilku to trv\xE1. Nepla\u0165te pros\xEDm znovu \u2014 str\xE1nka se sama aktualizuje.",
419
+ "payment.blockedTitle": "Tuhle objedn\xE1vku te\u010F zaplatit nejde",
420
+ "payment.blocked.orderCancelled": "Objedn\xE1vka byla zru\u0161en\xE1, tak\u017Ee nen\xED co platit.",
421
+ "payment.blocked.alreadyPaid": "Objedn\xE1vka je u\u017E zaplacen\xE1.",
422
+ "payment.blocked.authorizationHeld": "Banka na tuhle objedn\xE1vku dr\u017E\xED pen\xEDze. Jakmile se platba dokon\u010D\xED, uvid\xEDte to tady.",
423
+ "payment.blocked.documentIssued": "K objedn\xE1vce je vystaven\xE1 faktura, tak\u017Ee je \u010D\xE1stka pevn\xE1. Pokud chcete platit jinak, ozv\u011Bte se n\xE1m.",
424
+ "payment.account": "\xDA\u010Det",
425
+ "payment.beneficiary": "P\u0159\xEDjemce",
426
+ "payment.variableSymbol": "Variabiln\xED symbol",
427
+ "payment.amount": "\u010C\xE1stka",
428
+ "payment.copy": "Kop\xEDrovat",
429
+ "payment.copied": "Zkop\xEDrov\xE1no",
430
+ "payment.qrAlt": "QR k\xF3d k platb\u011B",
431
+ "payment.qrCaption": "Na\u010Dt\u011Bte v bankovn\xED aplikaci",
360
432
  "error.notFound.title": "Str\xE1nka nenalezena",
361
433
  "error.notFound.body": "Tato str\xE1nka neexistuje nebo nen\xED ve va\u0161em regionu dostupn\xE1.",
362
434
  "error.generic.title": "N\u011Bco se pokazilo",
@@ -371,6 +443,20 @@ var cs = {
371
443
  "account.signOut": "Odhl\xE1sit se",
372
444
  "account.greeting": "P\u0159ihl\xE1\u0161en jako {email}",
373
445
  "account.orders": "Va\u0161e objedn\xE1vky",
446
+ "account.loadError": "\xDAdaje se nepoda\u0159ilo na\u010D\xEDst. Zkuste to znovu.",
447
+ "account.retry": "Zkusit znovu",
448
+ "account.loadMore": "Na\u010D\xEDst dal\u0161\xED",
449
+ "account.signInError": "P\u0159ihl\xE1\u0161en\xED se nepoda\u0159ilo zah\xE1jit. Zkuste to za chv\xEDli znovu.",
450
+ "account.security": "Zabezpe\u010Den\xED \xFA\u010Dtu",
451
+ "account.newEmail": "Nov\xFD e-mail",
452
+ "account.changeEmail": "Ov\u011B\u0159it nov\xFD e-mail",
453
+ "account.recentLogin": "Pro tuto zm\u011Bnu se nejprve znovu p\u0159ihlaste p\u0159es e-mail.",
454
+ "account.sessions": "P\u0159ihl\xE1\u0161en\xED",
455
+ "account.currentSession": "Toto p\u0159ihl\xE1\u0161en\xED",
456
+ "account.revokeSession": "Odhl\xE1sit",
457
+ "account.closeAccount": "Uzav\u0159\xEDt \xFA\u010Det",
458
+ "account.closeWarning": "Uzav\u0159en\xEDm \xFA\u010Dtu ukon\u010D\xEDte p\u0159\xEDstup a odhl\xE1s\xEDte v\u0161echna za\u0159\xEDzen\xED. Objedn\xE1vky a doklady z\u016Fstanou zachov\xE1ny. Obnoven\xED p\u0159\xEDstupu \u0159e\u0161\xED podpora obchodu.",
459
+ "account.confirmClose": "Potvrdit uzav\u0159en\xED \xFA\u010Dtu",
374
460
  "account.noOrders": "Zat\xEDm \u017E\xE1dn\xE9 objedn\xE1vky.",
375
461
  "account.addresses": "Ulo\u017Een\xE9 adresy",
376
462
  "account.noAddresses": "Zat\xEDm \u017E\xE1dn\xE9 ulo\u017Een\xE9 adresy.",
@@ -455,13 +541,13 @@ function makeI18n(locale, messages) {
455
541
  return { locale, messages, t };
456
542
  }
457
543
  var DEFAULT_I18N = makeI18n("en", en);
458
- var I18nContext = React10__namespace.createContext(null);
544
+ var I18nContext = React19__namespace.createContext(null);
459
545
  function I18nProvider({
460
546
  locale,
461
547
  messages,
462
548
  children
463
549
  }) {
464
- const value = React10__namespace.useMemo(() => {
550
+ const value = React19__namespace.useMemo(() => {
465
551
  const lang = langOf(locale);
466
552
  if (locale && !(lang in BUNDLED) && !messages) {
467
553
  devWarn(
@@ -475,7 +561,7 @@ function I18nProvider({
475
561
  return /* @__PURE__ */ jsxRuntime.jsx(I18nContext.Provider, { value, children });
476
562
  }
477
563
  function useI18n() {
478
- return React10__namespace.useContext(I18nContext) ?? DEFAULT_I18N;
564
+ return React19__namespace.useContext(I18nContext) ?? DEFAULT_I18N;
479
565
  }
480
566
  function useT() {
481
567
  return useI18n().t;
@@ -599,7 +685,7 @@ function ProductCard({ product, href, locale }) {
599
685
  var MAIN_WIDTHS = [600, 800, 1e3];
600
686
  var THUMB_WIDTHS = [56, 112];
601
687
  function ProductGallery({ media, alt }) {
602
- const [active, setActive] = React10__namespace.useState(0);
688
+ const [active, setActive] = React19__namespace.useState(0);
603
689
  const imageBase = useStorefrontOptional()?.imageBase;
604
690
  if (media.length === 0) {
605
691
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -687,10 +773,10 @@ function matchVariant(product, selected) {
687
773
  ) ?? null;
688
774
  }
689
775
  function VariantPicker({ product, onChange }) {
690
- const [selected, setSelected] = React10__namespace.useState(
776
+ const [selected, setSelected] = React19__namespace.useState(
691
777
  () => product.variants[0]?.options ?? []
692
778
  );
693
- React10__namespace.useEffect(() => {
779
+ React19__namespace.useEffect(() => {
694
780
  onChange?.(matchVariant(product, selected));
695
781
  }, [product, selected]);
696
782
  if (product.options.length === 0) return null;
@@ -731,8 +817,8 @@ function BackInStockForm({
731
817
  }) {
732
818
  const t = useT();
733
819
  const client = useStorefront();
734
- const [email, setEmail] = React10__namespace.useState(defaultEmail);
735
- const [state, setState] = React10__namespace.useState("idle");
820
+ const [email, setEmail] = React19__namespace.useState(defaultEmail);
821
+ const [state, setState] = React19__namespace.useState("idle");
736
822
  if (!variant || variant.availability?.status !== "out_of_stock") return null;
737
823
  async function submit(e) {
738
824
  e.preventDefault();
@@ -832,7 +918,7 @@ function ProductDetailPage({
832
918
  locale,
833
919
  addToCart
834
920
  }) {
835
- const [variant, setVariant] = React10__namespace.useState(
921
+ const [variant, setVariant] = React19__namespace.useState(
836
922
  product.variants[0] ?? null
837
923
  );
838
924
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -1064,12 +1150,12 @@ function TagFilter({ tags, selected = [], onChange }) {
1064
1150
  }) })
1065
1151
  ] });
1066
1152
  }
1067
- var CartContext = React10__namespace.createContext(null);
1153
+ var CartContext = React19__namespace.createContext(null);
1068
1154
  function CartProvider({ children }) {
1069
1155
  const client = useStorefront();
1070
- const [cart, setCart] = React10__namespace.useState(null);
1071
- const [loading, setLoading] = React10__namespace.useState(false);
1072
- const run = React10__namespace.useCallback(
1156
+ const [cart, setCart] = React19__namespace.useState(null);
1157
+ const [loading, setLoading] = React19__namespace.useState(false);
1158
+ const run = React19__namespace.useCallback(
1073
1159
  async (op) => {
1074
1160
  setLoading(true);
1075
1161
  try {
@@ -1082,7 +1168,7 @@ function CartProvider({ children }) {
1082
1168
  },
1083
1169
  []
1084
1170
  );
1085
- const refresh = React10__namespace.useCallback(async () => {
1171
+ const refresh = React19__namespace.useCallback(async () => {
1086
1172
  setLoading(true);
1087
1173
  try {
1088
1174
  setCart(await client.cart.get());
@@ -1090,10 +1176,10 @@ function CartProvider({ children }) {
1090
1176
  setLoading(false);
1091
1177
  }
1092
1178
  }, [client]);
1093
- React10__namespace.useEffect(() => {
1179
+ React19__namespace.useEffect(() => {
1094
1180
  void refresh();
1095
1181
  }, [refresh]);
1096
- const value = React10__namespace.useMemo(
1182
+ const value = React19__namespace.useMemo(
1097
1183
  () => ({
1098
1184
  cart,
1099
1185
  loading,
@@ -1108,7 +1194,7 @@ function CartProvider({ children }) {
1108
1194
  return /* @__PURE__ */ jsxRuntime.jsx(CartContext.Provider, { value, children });
1109
1195
  }
1110
1196
  function useCart() {
1111
- const ctx = React10__namespace.useContext(CartContext);
1197
+ const ctx = React19__namespace.useContext(CartContext);
1112
1198
  if (!ctx) {
1113
1199
  throw new Error("useCart must be used inside <CartProvider>.");
1114
1200
  }
@@ -1122,8 +1208,8 @@ function AddToCart({
1122
1208
  }) {
1123
1209
  const t = useT();
1124
1210
  const { addLine } = useCart();
1125
- const [busy, setBusy] = React10__namespace.useState(false);
1126
- const [error, setError] = React10__namespace.useState(null);
1211
+ const [busy, setBusy] = React19__namespace.useState(false);
1212
+ const [error, setError] = React19__namespace.useState(null);
1127
1213
  const disabled = variant == null || busy;
1128
1214
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
1129
1215
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1164,6 +1250,7 @@ function AddToCart({
1164
1250
  }
1165
1251
  function CartLineItem({ line, locale }) {
1166
1252
  const t = useT();
1253
+ const loc = useFormatLocale(locale);
1167
1254
  const { updateLine, removeLine } = useCart();
1168
1255
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "0.85rem", alignItems: "flex-start", padding: "0.75rem 0" }, children: [
1169
1256
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1235,7 +1322,7 @@ function CartLineItem({ line, locale }) {
1235
1322
  )
1236
1323
  ] })
1237
1324
  ] }),
1238
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontWeight: 500, whiteSpace: "nowrap" }, children: formatCents(line.line_total_cents, line.unit_price.currency, locale) })
1325
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontWeight: 500, whiteSpace: "nowrap" }, children: formatCents(line.line_total_cents, line.unit_price.currency, loc) })
1239
1326
  ] });
1240
1327
  }
1241
1328
  function StepBtn({ label, onClick }) {
@@ -1267,6 +1354,7 @@ function CartSummary({
1267
1354
  locale
1268
1355
  }) {
1269
1356
  const tr = useT();
1357
+ const loc = useFormatLocale(locale);
1270
1358
  const { cart } = useCart();
1271
1359
  if (cart == null) return null;
1272
1360
  const t = cart.totals;
@@ -1287,10 +1375,10 @@ function CartSummary({
1287
1375
  opacity: empty ? 0.55 : 1
1288
1376
  };
1289
1377
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
1290
- /* @__PURE__ */ jsxRuntime.jsx(Row, { label: tr("cart.subtotal"), value: formatCents(t.subtotal_with_tax_cents, t.currency, locale) }),
1291
- t.tax_cents > 0 ? /* @__PURE__ */ jsxRuntime.jsx(Row, { label: tr("cart.tax"), value: formatCents(t.tax_cents, t.currency, locale), muted: true }) : null,
1378
+ /* @__PURE__ */ jsxRuntime.jsx(Row, { label: tr("cart.subtotal"), value: formatCents(t.subtotal_with_tax_cents, t.currency, loc) }),
1379
+ t.tax_cents > 0 ? /* @__PURE__ */ jsxRuntime.jsx(Row, { label: tr("cart.tax"), value: formatCents(t.tax_cents, t.currency, loc), muted: true }) : null,
1292
1380
  /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: 1, background: "var(--nv-border)" } }),
1293
- /* @__PURE__ */ jsxRuntime.jsx(Row, { label: tr("cart.total"), value: formatCents(t.total_cents, t.currency, locale), strong: true }),
1381
+ /* @__PURE__ */ jsxRuntime.jsx(Row, { label: tr("cart.total"), value: formatCents(t.total_cents, t.currency, loc), strong: true }),
1294
1382
  checkoutHref && !empty ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: checkoutHref, style: ctaStyle, children: cta }) : /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", disabled: empty, onClick: onCheckout, style: ctaStyle, children: cta })
1295
1383
  ] });
1296
1384
  }
@@ -1397,15 +1485,15 @@ function CartDrawer({
1397
1485
  }
1398
1486
  );
1399
1487
  }
1400
- var CheckoutContext = React10__namespace.createContext(null);
1488
+ var CheckoutContext = React19__namespace.createContext(null);
1401
1489
  function CheckoutProvider({
1402
1490
  children
1403
1491
  }) {
1404
1492
  const client = useStorefront();
1405
- const [checkout, setCheckout] = React10__namespace.useState(null);
1406
- const [loading, setLoading] = React10__namespace.useState(false);
1407
- const [error, setError] = React10__namespace.useState(null);
1408
- const run = React10__namespace.useCallback(
1493
+ const [checkout, setCheckout] = React19__namespace.useState(null);
1494
+ const [loading, setLoading] = React19__namespace.useState(false);
1495
+ const [error, setError] = React19__namespace.useState(null);
1496
+ const run = React19__namespace.useCallback(
1409
1497
  async (op, store) => {
1410
1498
  setLoading(true);
1411
1499
  try {
@@ -1423,7 +1511,7 @@ function CheckoutProvider({
1423
1511
  },
1424
1512
  []
1425
1513
  );
1426
- const refresh = React10__namespace.useCallback(async () => {
1514
+ const refresh = React19__namespace.useCallback(async () => {
1427
1515
  setLoading(true);
1428
1516
  try {
1429
1517
  setCheckout(await client.checkout.get());
@@ -1432,10 +1520,10 @@ function CheckoutProvider({
1432
1520
  setLoading(false);
1433
1521
  }
1434
1522
  }, [client]);
1435
- React10__namespace.useEffect(() => {
1523
+ React19__namespace.useEffect(() => {
1436
1524
  void refresh();
1437
1525
  }, [refresh]);
1438
- const pay = React10__namespace.useCallback(
1526
+ const pay = React19__namespace.useCallback(
1439
1527
  async (opts = {}) => {
1440
1528
  const co = checkout;
1441
1529
  if (!co) throw new Error("pay() called before a checkout exists");
@@ -1458,7 +1546,7 @@ function CheckoutProvider({
1458
1546
  },
1459
1547
  [checkout, client, run]
1460
1548
  );
1461
- const value = React10__namespace.useMemo(
1549
+ const value = React19__namespace.useMemo(
1462
1550
  () => ({
1463
1551
  checkout,
1464
1552
  loading,
@@ -1483,7 +1571,7 @@ function CheckoutProvider({
1483
1571
  return /* @__PURE__ */ jsxRuntime.jsx(CheckoutContext.Provider, { value, children });
1484
1572
  }
1485
1573
  function useCheckout() {
1486
- const ctx = React10__namespace.useContext(CheckoutContext);
1574
+ const ctx = React19__namespace.useContext(CheckoutContext);
1487
1575
  if (!ctx) {
1488
1576
  throw new Error("useCheckout must be used inside <CheckoutProvider>.");
1489
1577
  }
@@ -1642,10 +1730,25 @@ function AddressForm({
1642
1730
  }) {
1643
1731
  const t = useT();
1644
1732
  const { checkout, setAddress, loading } = useCheckout();
1645
- const [form, setForm] = React10__namespace.useState(
1733
+ const [form, setForm] = React19__namespace.useState(
1646
1734
  () => seed(checkout?.email ?? null, checkout?.shipping_address ?? null)
1647
1735
  );
1648
- const set = (key) => (e) => setForm((f) => ({ ...f, [key]: e.target.value }));
1736
+ const touched = React19__namespace.useRef(/* @__PURE__ */ new Set());
1737
+ React19__namespace.useEffect(() => {
1738
+ const prefill = checkout?.customer_prefill;
1739
+ const addresses = prefill?.addresses.filter((a) => !a.is_pickup);
1740
+ const saved = addresses?.find((a) => a.is_default) ?? addresses?.[0];
1741
+ const address = checkout?.shipping_address ?? (saved ? { ...saved, postal_code: saved.zip } : null);
1742
+ const defaults = seed(checkout?.email ?? prefill?.email ?? null, address);
1743
+ defaults.first_name || (defaults.first_name = prefill?.first_name ?? "");
1744
+ defaults.last_name || (defaults.last_name = prefill?.last_name ?? "");
1745
+ defaults.phone || (defaults.phone = prefill?.phone ?? "");
1746
+ setForm((current) => Object.fromEntries(Object.entries(current).map(([key, value]) => [key, touched.current.has(key) ? value : value || defaults[key]])));
1747
+ }, [checkout?.token]);
1748
+ const set = (key) => (e) => {
1749
+ touched.current.add(key);
1750
+ setForm((f) => ({ ...f, [key]: e.target.value }));
1751
+ };
1649
1752
  async function submit(e) {
1650
1753
  e.preventDefault();
1651
1754
  const { email, ...rest } = form;
@@ -1693,13 +1796,14 @@ function ShippingPicker({
1693
1796
  locale
1694
1797
  }) {
1695
1798
  const t = useT();
1799
+ const loc = useFormatLocale(locale);
1696
1800
  const { checkout, shippingQuotes, setShippingMethod, loading } = useCheckout();
1697
1801
  const heading = title ?? t("checkout.shippingMethod");
1698
- const [quotes, setQuotes] = React10__namespace.useState(null);
1699
- const [selected, setSelected] = React10__namespace.useState(null);
1700
- const [fetching, setFetching] = React10__namespace.useState(true);
1802
+ const [quotes, setQuotes] = React19__namespace.useState(null);
1803
+ const [selected, setSelected] = React19__namespace.useState(null);
1804
+ const [fetching, setFetching] = React19__namespace.useState(true);
1701
1805
  const addressKey = checkout?.shipping_address ? `${checkout.shipping_address.country_code}:${checkout.shipping_address.postal_code}` : null;
1702
- React10__namespace.useEffect(() => {
1806
+ React19__namespace.useEffect(() => {
1703
1807
  let live = true;
1704
1808
  setFetching(true);
1705
1809
  shippingQuotes().then((qs) => {
@@ -1727,17 +1831,13 @@ function ShippingPicker({
1727
1831
  }
1728
1832
  return /* @__PURE__ */ jsxRuntime.jsxs(Section, { title: heading, children: [
1729
1833
  /* @__PURE__ */ jsxRuntime.jsx("div", { role: "radiogroup", style: { display: "flex", flexDirection: "column", gap: "0.6rem" }, children: quotes.map((q) => {
1730
- const days = estDays(q, t);
1731
1834
  return /* @__PURE__ */ jsxRuntime.jsx(
1732
1835
  SelectRow,
1733
1836
  {
1734
1837
  selected: selected === q.rate_id,
1735
1838
  onSelect: () => setSelected(q.rate_id),
1736
- trailing: q.is_free ? t("common.free") : formatCents(q.price_cents, q.currency, locale),
1737
- children: /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", flexDirection: "column" }, children: [
1738
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 500 }, children: q.label }),
1739
- days ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.8125rem", color: "var(--nv-muted)" }, children: days }) : null
1740
- ] })
1839
+ trailing: q.is_free ? t("common.free") : formatCents(q.price_cents, q.currency, loc),
1840
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { display: "flex", flexDirection: "column" }, children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 500 }, children: q.label }) })
1741
1841
  },
1742
1842
  q.rate_id
1743
1843
  );
@@ -1745,14 +1845,38 @@ function ShippingPicker({
1745
1845
  /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: submit, busy: loading, disabled: selected == null, children: submitLabel ?? t("checkout.continueToPayment") }) })
1746
1846
  ] });
1747
1847
  }
1748
- function estDays(q, t) {
1749
- const { estimated_days_min: lo, estimated_days_max: hi } = q;
1750
- if (lo == null && hi == null) return null;
1751
- if (lo != null && hi != null) {
1752
- return lo === hi ? t("shipping.days", { count: lo }) : t("shipping.daysRange", { min: lo, max: hi });
1753
- }
1754
- const n = lo ?? hi;
1755
- return t("shipping.days", { count: n });
1848
+ function PaymentMethodPicker({
1849
+ methods,
1850
+ value,
1851
+ onSelect,
1852
+ currency,
1853
+ locale,
1854
+ disabled,
1855
+ label
1856
+ }) {
1857
+ const loc = useFormatLocale(locale);
1858
+ return /* @__PURE__ */ jsxRuntime.jsx(
1859
+ "div",
1860
+ {
1861
+ role: "radiogroup",
1862
+ "aria-label": label,
1863
+ style: { display: "flex", flexDirection: "column", gap: "0.6rem" },
1864
+ children: methods.map((m) => /* @__PURE__ */ jsxRuntime.jsx(
1865
+ SelectRow,
1866
+ {
1867
+ selected: value === m.method,
1868
+ disabled,
1869
+ onSelect: () => onSelect(m.method),
1870
+ trailing: m.surcharge_cents > 0 ? `+${formatCents(m.surcharge_cents, currency, loc)}` : void 0,
1871
+ children: /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", flexDirection: "column" }, children: [
1872
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 500 }, children: m.display_label }),
1873
+ m.display_description ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.8125rem", color: "var(--nv-muted)" }, children: m.display_description }) : null
1874
+ ] })
1875
+ },
1876
+ m.method
1877
+ ))
1878
+ }
1879
+ );
1756
1880
  }
1757
1881
  function PaymentSection({
1758
1882
  title,
@@ -1764,10 +1888,10 @@ function PaymentSection({
1764
1888
  const t = useT();
1765
1889
  const heading = title ?? t("checkout.payment");
1766
1890
  const { checkout, paymentMethods, setPaymentMethod, pay, loading } = useCheckout();
1767
- const [methods, setMethods] = React10__namespace.useState(null);
1768
- const [fetching, setFetching] = React10__namespace.useState(true);
1891
+ const [methods, setMethods] = React19__namespace.useState(null);
1892
+ const [fetching, setFetching] = React19__namespace.useState(true);
1769
1893
  const selected = checkout?.payment_method ?? null;
1770
- React10__namespace.useEffect(() => {
1894
+ React19__namespace.useEffect(() => {
1771
1895
  let live = true;
1772
1896
  setFetching(true);
1773
1897
  paymentMethods().then((ms) => {
@@ -1794,19 +1918,17 @@ function PaymentSection({
1794
1918
  return /* @__PURE__ */ jsxRuntime.jsx(Section, { title: heading, children: /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "var(--nv-muted)", margin: 0 }, children: t("checkout.noPayment") }) });
1795
1919
  }
1796
1920
  return /* @__PURE__ */ jsxRuntime.jsxs(Section, { title: heading, children: [
1797
- /* @__PURE__ */ jsxRuntime.jsx("div", { role: "radiogroup", style: { display: "flex", flexDirection: "column", gap: "0.6rem" }, children: methods.map((m) => /* @__PURE__ */ jsxRuntime.jsx(
1798
- SelectRow,
1921
+ /* @__PURE__ */ jsxRuntime.jsx(
1922
+ PaymentMethodPicker,
1799
1923
  {
1800
- selected: selected === m.method,
1801
- onSelect: () => void setPaymentMethod(m.method),
1802
- trailing: m.surcharge_cents > 0 && checkout ? `+${formatCents(m.surcharge_cents, checkout.totals.currency, locale)}` : void 0,
1803
- children: /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", flexDirection: "column" }, children: [
1804
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 500 }, children: m.display_label }),
1805
- m.display_description ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.8125rem", color: "var(--nv-muted)" }, children: m.display_description }) : null
1806
- ] })
1807
- },
1808
- m.method
1809
- )) }),
1924
+ methods,
1925
+ value: selected,
1926
+ onSelect: (method) => void setPaymentMethod(method),
1927
+ currency: checkout?.totals.currency ?? "CZK",
1928
+ locale,
1929
+ label: heading
1930
+ }
1931
+ ),
1810
1932
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1811
1933
  /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: placeOrder, busy: loading, disabled: selected == null, children: isGateway ? t("checkout.payNow") : t("checkout.placeOrder") }),
1812
1934
  isGateway ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.8125rem", color: "var(--nv-muted)", marginTop: "0.6rem" }, children: t("checkout.gatewayRedirectNote") }) : null
@@ -1819,12 +1941,13 @@ function OrderSummary({
1819
1941
  locale
1820
1942
  }) {
1821
1943
  const tr = useT();
1944
+ const loc = useFormatLocale(locale);
1822
1945
  const ctx = useCheckout();
1823
1946
  const checkout = override ?? ctx.checkout;
1824
1947
  if (checkout == null) return null;
1825
1948
  const t = checkout.totals;
1826
1949
  const c = t.currency;
1827
- const money = (cents) => formatCents(cents, c, locale);
1950
+ const money = (cents) => formatCents(cents, c, loc);
1828
1951
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
1829
1952
  !totalsOnly && checkout.line_items.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("ul", { style: { listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: "0.75rem" }, children: checkout.line_items.map((li) => /* @__PURE__ */ jsxRuntime.jsxs("li", { style: { display: "flex", gap: "0.75rem", alignItems: "center" }, children: [
1830
1953
  li.image_url ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -1905,16 +2028,16 @@ function CheckoutFlow({
1905
2028
  }) {
1906
2029
  const t = useT();
1907
2030
  const { checkout, loading, create } = useCheckout();
1908
- const [step, setStep] = React10__namespace.useState("address");
1909
- const [bootstrapped, setBootstrapped] = React10__namespace.useState(false);
1910
- React10__namespace.useEffect(() => {
2031
+ const [step, setStep] = React19__namespace.useState("address");
2032
+ const [bootstrapped, setBootstrapped] = React19__namespace.useState(false);
2033
+ React19__namespace.useEffect(() => {
1911
2034
  if (checkout || !cartToken || bootstrapped) return;
1912
2035
  setBootstrapped(true);
1913
2036
  void create(cartToken).catch(() => {
1914
2037
  });
1915
2038
  }, [checkout, cartToken, bootstrapped, create]);
1916
2039
  const serverStep = reachedStep(checkout);
1917
- React10__namespace.useEffect(() => {
2040
+ React19__namespace.useEffect(() => {
1918
2041
  setStep((cur) => rank(serverStep) > rank(cur) ? serverStep : cur);
1919
2042
  }, [serverStep]);
1920
2043
  if (checkout?.order_id) {
@@ -2035,10 +2158,10 @@ function DefaultConfirmation({ checkout }) {
2035
2158
  }
2036
2159
  function useOrderStatus(statusToken, initial) {
2037
2160
  const client = useStorefront();
2038
- const [order, setOrder] = React10__namespace.useState(initial ?? null);
2039
- const [loading, setLoading] = React10__namespace.useState(false);
2040
- const [error, setError] = React10__namespace.useState(null);
2041
- const load = React10__namespace.useCallback(async () => {
2161
+ const [order, setOrder] = React19__namespace.useState(initial ?? null);
2162
+ const [loading, setLoading] = React19__namespace.useState(false);
2163
+ const [error, setError] = React19__namespace.useState(null);
2164
+ const load = React19__namespace.useCallback(async () => {
2042
2165
  if (!statusToken) return;
2043
2166
  setLoading(true);
2044
2167
  try {
@@ -2050,12 +2173,85 @@ function useOrderStatus(statusToken, initial) {
2050
2173
  setLoading(false);
2051
2174
  }
2052
2175
  }, [client, statusToken]);
2053
- React10__namespace.useEffect(() => {
2176
+ React19__namespace.useEffect(() => {
2054
2177
  if (initial) return;
2055
2178
  void load();
2056
2179
  }, [load, initial]);
2057
2180
  return { order, loading, error, reload: () => void load() };
2058
2181
  }
2182
+ function usePayment(token, initial) {
2183
+ const client = useStorefront();
2184
+ const [payment, setPayment] = React19__namespace.useState(initial ?? null);
2185
+ const [methods, setMethods] = React19__namespace.useState([]);
2186
+ const [loading, setLoading] = React19__namespace.useState(false);
2187
+ const [busy, setBusy] = React19__namespace.useState(false);
2188
+ const [error, setError] = React19__namespace.useState(null);
2189
+ const load = React19__namespace.useCallback(async () => {
2190
+ if (!token) return;
2191
+ setLoading(true);
2192
+ try {
2193
+ const [state, list] = await Promise.all([
2194
+ client.payment.get(token),
2195
+ client.payment.methods(token)
2196
+ ]);
2197
+ setPayment(state);
2198
+ setMethods(list);
2199
+ setError(null);
2200
+ } catch (e) {
2201
+ setError(e instanceof Error ? e : new Error(String(e)));
2202
+ } finally {
2203
+ setLoading(false);
2204
+ }
2205
+ }, [client, token]);
2206
+ React19__namespace.useEffect(() => {
2207
+ if (!token) return;
2208
+ if (initial && initial.token === token) {
2209
+ setPayment(initial);
2210
+ client.payment.methods(token).then(setMethods).catch(() => setMethods([]));
2211
+ return;
2212
+ }
2213
+ void load();
2214
+ }, [token, load]);
2215
+ const selectMethod = React19__namespace.useCallback(
2216
+ async (method) => {
2217
+ if (!token) return null;
2218
+ setBusy(true);
2219
+ try {
2220
+ const next = await client.payment.selectMethod(token, method);
2221
+ setPayment(next);
2222
+ setError(null);
2223
+ return next;
2224
+ } catch (e) {
2225
+ setError(e instanceof Error ? e : new Error(String(e)));
2226
+ return null;
2227
+ } finally {
2228
+ setBusy(false);
2229
+ }
2230
+ },
2231
+ [client, token]
2232
+ );
2233
+ const startPayment = React19__namespace.useCallback(
2234
+ async (input) => {
2235
+ if (!token) return null;
2236
+ setBusy(true);
2237
+ try {
2238
+ const result = await client.payment.start(token, {
2239
+ return_url: input?.returnUrl,
2240
+ cancel_url: input?.cancelUrl
2241
+ });
2242
+ setError(null);
2243
+ return result.redirect_url;
2244
+ } catch (e) {
2245
+ setError(e instanceof Error ? e : new Error(String(e)));
2246
+ return null;
2247
+ } finally {
2248
+ setBusy(false);
2249
+ }
2250
+ },
2251
+ [client, token]
2252
+ );
2253
+ return { payment, methods, loading, busy, error, reload: load, selectMethod, startPayment };
2254
+ }
2059
2255
  var PHASE_RANK = {
2060
2256
  placed: 0,
2061
2257
  paid: 1,
@@ -2151,6 +2347,7 @@ function OrderLines({
2151
2347
  order,
2152
2348
  locale
2153
2349
  }) {
2350
+ const loc = useFormatLocale(locale);
2154
2351
  return /* @__PURE__ */ jsxRuntime.jsxs("ul", { style: { listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
2155
2352
  order.line_items.map((li) => /* @__PURE__ */ jsxRuntime.jsxs("li", { style: { display: "flex", gap: "0.75rem", alignItems: "center" }, children: [
2156
2353
  li.image_url ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -2171,11 +2368,11 @@ function OrderLines({
2171
2368
  li.quantity
2172
2369
  ] })
2173
2370
  ] }),
2174
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontVariantNumeric: "tabular-nums" }, children: formatCents(li.total_with_tax_cents, order.currency, locale) })
2371
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontVariantNumeric: "tabular-nums" }, children: formatCents(li.total_with_tax_cents, order.currency, loc) })
2175
2372
  ] }, li.id)),
2176
2373
  order.fee_lines.map((f, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { style: { display: "flex", gap: "0.75rem", alignItems: "center" }, children: [
2177
2374
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { display: "block", fontWeight: 500 }, children: f.title }) }),
2178
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontVariantNumeric: "tabular-nums" }, children: formatCents(f.total_with_tax_cents, order.currency, locale) })
2375
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontVariantNumeric: "tabular-nums" }, children: formatCents(f.total_with_tax_cents, order.currency, loc) })
2179
2376
  ] }, `fee-${i}`))
2180
2377
  ] });
2181
2378
  }
@@ -2184,9 +2381,10 @@ function OrderTotals({
2184
2381
  locale
2185
2382
  }) {
2186
2383
  const tr = useT();
2384
+ const loc = useFormatLocale(locale);
2187
2385
  const t = order.totals;
2188
2386
  const c = order.currency;
2189
- const money = (cents) => formatCents(cents, c, locale);
2387
+ const money = (cents) => formatCents(cents, c, loc);
2190
2388
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
2191
2389
  /* @__PURE__ */ jsxRuntime.jsx(Row3, { label: tr("totals.subtotal"), value: money(t.subtotal_cents) }),
2192
2390
  t.discount_cents > 0 ? /* @__PURE__ */ jsxRuntime.jsx(Row3, { label: tr("totals.discount"), value: `\u2212${money(t.discount_cents)}`, muted: true }) : null,
@@ -2292,6 +2490,7 @@ function OrderStatusPage({
2292
2490
  statusToken,
2293
2491
  order: initial,
2294
2492
  onContactSupport,
2493
+ payHref,
2295
2494
  locale
2296
2495
  }) {
2297
2496
  const t = useT();
@@ -2343,6 +2542,7 @@ function OrderStatusPage({
2343
2542
  /* @__PURE__ */ jsxRuntime.jsxs(Card, { title: t("order.payment"), children: [
2344
2543
  /* @__PURE__ */ jsxRuntime.jsx(Line, { label: t("order.method"), value: order.payment.method ?? "\u2014" }),
2345
2544
  /* @__PURE__ */ jsxRuntime.jsx(Line, { label: t("order.status"), value: order.payment.status }),
2545
+ order.payment.token && payHref ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: payHref(order.payment.token), style: { color: "var(--nv-brand)", fontWeight: 500 }, children: t("payment.finish") }) : null,
2346
2546
  order.payment.invoice_available && order.payment.invoice_url ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: order.payment.invoice_url, style: { color: "var(--nv-brand)" }, children: t("order.downloadInvoice") }) : null
2347
2547
  ] }),
2348
2548
  order.actions.can_contact_support && onContactSupport ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -2394,27 +2594,291 @@ function Line({ label, value }) {
2394
2594
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { textAlign: "right" }, children: value })
2395
2595
  ] });
2396
2596
  }
2397
- var AccountContext = React10__namespace.createContext(null);
2597
+ function TransferInstructions({
2598
+ instructions: i,
2599
+ locale
2600
+ }) {
2601
+ const t = useT();
2602
+ const loc = useFormatLocale(locale);
2603
+ const account = i.iban || i.account_number;
2604
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2605
+ "div",
2606
+ {
2607
+ style: {
2608
+ display: "flex",
2609
+ flexWrap: "wrap",
2610
+ gap: "1.25rem",
2611
+ alignItems: "flex-start",
2612
+ padding: "1rem",
2613
+ borderRadius: "var(--nv-radius)",
2614
+ border: "1px solid var(--nv-border)"
2615
+ },
2616
+ children: [
2617
+ /* @__PURE__ */ jsxRuntime.jsxs("dl", { style: { flex: "1 1 15rem", margin: 0, display: "flex", flexDirection: "column", gap: "0.7rem" }, children: [
2618
+ account ? /* @__PURE__ */ jsxRuntime.jsx(CopyRow, { label: t("payment.account"), value: account }) : null,
2619
+ i.beneficiary_name ? /* @__PURE__ */ jsxRuntime.jsx(Row4, { label: t("payment.beneficiary"), value: i.beneficiary_name }) : null,
2620
+ /* @__PURE__ */ jsxRuntime.jsx(CopyRow, { label: t("payment.variableSymbol"), value: i.variable_symbol }),
2621
+ /* @__PURE__ */ jsxRuntime.jsx(
2622
+ Row4,
2623
+ {
2624
+ label: t("payment.amount"),
2625
+ value: formatCents(i.amount_cents, i.currency, loc),
2626
+ strong: true
2627
+ }
2628
+ )
2629
+ ] }),
2630
+ i.qr_svg_data_uri ? /* @__PURE__ */ jsxRuntime.jsxs("figure", { style: { margin: 0, textAlign: "center" }, children: [
2631
+ /* @__PURE__ */ jsxRuntime.jsx(
2632
+ "img",
2633
+ {
2634
+ src: i.qr_svg_data_uri,
2635
+ alt: t("payment.qrAlt"),
2636
+ width: 148,
2637
+ height: 148,
2638
+ style: { display: "block", borderRadius: "var(--nv-radius)" }
2639
+ }
2640
+ ),
2641
+ /* @__PURE__ */ jsxRuntime.jsx("figcaption", { style: { fontSize: "0.75rem", color: "var(--nv-muted)", marginTop: "0.4rem" }, children: t("payment.qrCaption") })
2642
+ ] }) : null,
2643
+ i.instructions ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { flexBasis: "100%", margin: 0, fontSize: "0.8125rem", color: "var(--nv-muted)" }, children: i.instructions }) : null
2644
+ ]
2645
+ }
2646
+ );
2647
+ }
2648
+ function Row4({
2649
+ label,
2650
+ value,
2651
+ strong
2652
+ }) {
2653
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.1rem" }, children: [
2654
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { style: { fontSize: "0.75rem", color: "var(--nv-muted)" }, children: label }),
2655
+ /* @__PURE__ */ jsxRuntime.jsx(
2656
+ "dd",
2657
+ {
2658
+ style: {
2659
+ margin: 0,
2660
+ fontWeight: strong ? 600 : 500,
2661
+ fontVariantNumeric: "tabular-nums"
2662
+ },
2663
+ children: value
2664
+ }
2665
+ )
2666
+ ] });
2667
+ }
2668
+ function CopyRow({ label, value }) {
2669
+ const t = useT();
2670
+ const [copied, setCopied] = React19__namespace.useState(false);
2671
+ React19__namespace.useEffect(() => {
2672
+ if (!copied) return;
2673
+ const id = setTimeout(() => setCopied(false), 1800);
2674
+ return () => clearTimeout(id);
2675
+ }, [copied]);
2676
+ async function copy() {
2677
+ try {
2678
+ await navigator.clipboard.writeText(value);
2679
+ setCopied(true);
2680
+ } catch {
2681
+ }
2682
+ }
2683
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.1rem" }, children: [
2684
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { style: { fontSize: "0.75rem", color: "var(--nv-muted)" }, children: label }),
2685
+ /* @__PURE__ */ jsxRuntime.jsxs("dd", { style: { margin: 0, display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
2686
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 500, fontVariantNumeric: "tabular-nums" }, children: value }),
2687
+ /* @__PURE__ */ jsxRuntime.jsx(
2688
+ "button",
2689
+ {
2690
+ type: "button",
2691
+ onClick: () => void copy(),
2692
+ style: {
2693
+ font: "inherit",
2694
+ fontSize: "0.75rem",
2695
+ cursor: "pointer",
2696
+ padding: "0.15rem 0.5rem",
2697
+ borderRadius: "var(--nv-radius)",
2698
+ border: "1px solid var(--nv-border)",
2699
+ background: "transparent",
2700
+ color: "var(--nv-muted)"
2701
+ },
2702
+ children: copied ? t("payment.copied") : t("payment.copy")
2703
+ }
2704
+ )
2705
+ ] })
2706
+ ] });
2707
+ }
2708
+ var HANDOFF_TTL_MS = 30 * 60 * 1e3;
2709
+ var POLL_MS = 2e3;
2710
+ var POLL_ATTEMPTS = 6;
2711
+ var BLOCKED_MESSAGE = {
2712
+ order_cancelled: "payment.blocked.orderCancelled",
2713
+ already_paid: "payment.blocked.alreadyPaid",
2714
+ authorization_held: "payment.blocked.authorizationHeld",
2715
+ document_issued: "payment.blocked.documentIssued"
2716
+ };
2717
+ function handoffKey(token) {
2718
+ return `nv_payment_handoff_${token}`;
2719
+ }
2720
+ function rememberHandoff(token) {
2721
+ try {
2722
+ sessionStorage.setItem(handoffKey(token), String(Date.now()));
2723
+ } catch {
2724
+ }
2725
+ }
2726
+ function consumeHandoff(token) {
2727
+ try {
2728
+ const raw = sessionStorage.getItem(handoffKey(token));
2729
+ if (!raw) return false;
2730
+ const fresh = Date.now() - Number(raw) < HANDOFF_TTL_MS;
2731
+ if (!fresh) sessionStorage.removeItem(handoffKey(token));
2732
+ return fresh;
2733
+ } catch {
2734
+ return false;
2735
+ }
2736
+ }
2737
+ function forgetHandoff(token) {
2738
+ try {
2739
+ sessionStorage.removeItem(handoffKey(token));
2740
+ } catch {
2741
+ }
2742
+ }
2743
+ function PaymentPage({
2744
+ token,
2745
+ payment: initial,
2746
+ returnUrl,
2747
+ cancelUrl,
2748
+ statusHref,
2749
+ locale,
2750
+ onPaid
2751
+ }) {
2752
+ const t = useT();
2753
+ const loc = useFormatLocale(locale);
2754
+ const { payment, methods, loading, busy, error, reload, selectMethod, startPayment } = usePayment(token, initial);
2755
+ const [verifying, setVerifying] = React19__namespace.useState(false);
2756
+ React19__namespace.useEffect(() => {
2757
+ if (token) setVerifying(consumeHandoff(token));
2758
+ }, [token]);
2759
+ const settled = payment != null && !payment.can_pay && payment.blocked_reason === "already_paid";
2760
+ React19__namespace.useEffect(() => {
2761
+ if (!verifying || !token || settled) return;
2762
+ let attempts = 0;
2763
+ const id = setInterval(() => {
2764
+ attempts += 1;
2765
+ if (attempts > POLL_ATTEMPTS) {
2766
+ setVerifying(false);
2767
+ forgetHandoff(token);
2768
+ clearInterval(id);
2769
+ return;
2770
+ }
2771
+ void reload();
2772
+ }, POLL_MS);
2773
+ return () => clearInterval(id);
2774
+ }, [verifying, token, settled, reload]);
2775
+ React19__namespace.useEffect(() => {
2776
+ if (!settled || !token || !payment) return;
2777
+ setVerifying(false);
2778
+ forgetHandoff(token);
2779
+ onPaid?.(payment);
2780
+ }, [settled, token, payment, onPaid]);
2781
+ if (!token) return null;
2782
+ if (payment == null) {
2783
+ return /* @__PURE__ */ jsxRuntime.jsx(Shell2, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, color: "var(--nv-muted)" }, children: loading ? t("payment.loading") : t("payment.loadError") }) });
2784
+ }
2785
+ const money = (cents) => formatCents(cents, payment.currency, loc);
2786
+ if (settled) {
2787
+ return /* @__PURE__ */ jsxRuntime.jsxs(Shell2, { title: t("payment.paidTitle"), children: [
2788
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0 }, children: t("payment.paidBody", { order: payment.order_name ?? payment.order_number }) }),
2789
+ /* @__PURE__ */ jsxRuntime.jsx(Amount, { label: t("payment.paidAmount"), value: money(payment.total_cents) }),
2790
+ statusHref ? /* @__PURE__ */ jsxRuntime.jsx(Link, { href: statusHref, children: t("order.trackOrder") }) : null
2791
+ ] });
2792
+ }
2793
+ if (payment.blocked_reason) {
2794
+ return /* @__PURE__ */ jsxRuntime.jsxs(Shell2, { title: t("payment.blockedTitle"), children: [
2795
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0 }, children: t(BLOCKED_MESSAGE[payment.blocked_reason]) }),
2796
+ statusHref ? /* @__PURE__ */ jsxRuntime.jsx(Link, { href: statusHref, children: t("order.trackOrder") }) : null
2797
+ ] });
2798
+ }
2799
+ if (verifying) {
2800
+ return /* @__PURE__ */ jsxRuntime.jsx(Shell2, { title: t("payment.verifyingTitle"), children: /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, color: "var(--nv-muted)" }, children: t("payment.verifyingBody") }) });
2801
+ }
2802
+ const isBank = payment.category === "bank";
2803
+ const isGateway = payment.category === "gateway";
2804
+ async function pay() {
2805
+ if (!token) return;
2806
+ rememberHandoff(token);
2807
+ const url = await startPayment({ returnUrl, cancelUrl });
2808
+ if (url) {
2809
+ window.location.assign(url);
2810
+ return;
2811
+ }
2812
+ forgetHandoff(token);
2813
+ await reload();
2814
+ }
2815
+ return /* @__PURE__ */ jsxRuntime.jsxs(Shell2, { title: t("payment.title", { order: payment.order_name ?? payment.order_number }), children: [
2816
+ /* @__PURE__ */ jsxRuntime.jsx(Amount, { label: t("payment.amountDue"), value: money(payment.amount_due_cents) }),
2817
+ methods.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
2818
+ PaymentMethodPicker,
2819
+ {
2820
+ methods,
2821
+ value: payment.method,
2822
+ onSelect: (method) => void selectMethod(method),
2823
+ currency: payment.currency,
2824
+ locale: loc,
2825
+ disabled: busy,
2826
+ label: t("payment.methodLabel")
2827
+ }
2828
+ ) : null,
2829
+ isBank && payment.instructions ? /* @__PURE__ */ jsxRuntime.jsx(TransferInstructions, { instructions: payment.instructions, locale: loc }) : null,
2830
+ !isBank ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
2831
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => void pay(), busy, children: t("payment.payNow") }),
2832
+ isGateway ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.8125rem", color: "var(--nv-muted)", marginTop: "0.6rem" }, children: t("checkout.gatewayRedirectNote") }) : null
2833
+ ] }) : null,
2834
+ error ? /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", style: { margin: 0, color: "var(--nv-danger, #b3261e)" }, children: t("payment.actionError") }) : null,
2835
+ statusHref ? /* @__PURE__ */ jsxRuntime.jsx(Link, { href: statusHref, children: t("order.trackOrder") }) : null
2836
+ ] });
2837
+ }
2838
+ function Shell2({
2839
+ title,
2840
+ children
2841
+ }) {
2842
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { style: { display: "flex", flexDirection: "column", gap: "1rem", maxWidth: "34rem" }, children: [
2843
+ title ? /* @__PURE__ */ jsxRuntime.jsx("h1", { style: { margin: 0, fontSize: "1.25rem", fontWeight: 600 }, children: title }) : null,
2844
+ children
2845
+ ] });
2846
+ }
2847
+ function Amount({ label, value }) {
2848
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "baseline" }, children: [
2849
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--nv-muted)" }, children: label }),
2850
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { style: { fontSize: "1.35rem", fontVariantNumeric: "tabular-nums" }, children: value })
2851
+ ] });
2852
+ }
2853
+ function Link({ href, children }) {
2854
+ return /* @__PURE__ */ jsxRuntime.jsx("a", { href, style: { color: "var(--nv-brand)", fontSize: "0.875rem" }, children });
2855
+ }
2856
+ var AccountContext = React19__namespace.createContext(null);
2398
2857
  function AccountProvider({ children }) {
2399
2858
  const client = useStorefront();
2400
- const [customer, setCustomer] = React10__namespace.useState(null);
2401
- const [loading, setLoading] = React10__namespace.useState(true);
2402
- const refresh = React10__namespace.useCallback(async () => {
2859
+ const [customer, setCustomer] = React19__namespace.useState(null);
2860
+ const [loading, setLoading] = React19__namespace.useState(true);
2861
+ const [error, setError] = React19__namespace.useState(false);
2862
+ const refresh = React19__namespace.useCallback(async () => {
2403
2863
  setLoading(true);
2864
+ setError(false);
2404
2865
  try {
2405
2866
  setCustomer(await client.account.me());
2867
+ } catch {
2868
+ setError(true);
2406
2869
  } finally {
2407
2870
  setLoading(false);
2408
2871
  }
2409
2872
  }, [client]);
2410
- React10__namespace.useEffect(() => {
2873
+ React19__namespace.useEffect(() => {
2411
2874
  void refresh();
2412
2875
  }, [refresh]);
2413
- const value = React10__namespace.useMemo(
2876
+ const value = React19__namespace.useMemo(
2414
2877
  () => ({
2415
2878
  customer,
2416
2879
  signedIn: customer != null,
2417
2880
  loading,
2881
+ error,
2418
2882
  requestMagicLink: (email) => client.account.requestMagicLink(email),
2419
2883
  verify: async (token) => {
2420
2884
  const c = await client.account.verify(token);
@@ -2427,12 +2891,12 @@ function AccountProvider({ children }) {
2427
2891
  },
2428
2892
  refresh
2429
2893
  }),
2430
- [customer, loading, client, refresh]
2894
+ [customer, loading, error, client, refresh]
2431
2895
  );
2432
2896
  return /* @__PURE__ */ jsxRuntime.jsx(AccountContext.Provider, { value, children });
2433
2897
  }
2434
2898
  function useAccount() {
2435
- const ctx = React10__namespace.useContext(AccountContext);
2899
+ const ctx = React19__namespace.useContext(AccountContext);
2436
2900
  if (!ctx) {
2437
2901
  throw new Error("useAccount must be used inside <AccountProvider>.");
2438
2902
  }
@@ -2440,9 +2904,9 @@ function useAccount() {
2440
2904
  }
2441
2905
  function useMagicLinkVerify(token) {
2442
2906
  const { verify } = useAccount();
2443
- const [status, setStatus] = React10__namespace.useState("idle");
2444
- const done = React10__namespace.useRef(false);
2445
- React10__namespace.useEffect(() => {
2907
+ const [status, setStatus] = React19__namespace.useState("idle");
2908
+ const done = React19__namespace.useRef(false);
2909
+ React19__namespace.useEffect(() => {
2446
2910
  if (!token || done.current) return;
2447
2911
  done.current = true;
2448
2912
  setStatus("verifying");
@@ -2453,18 +2917,22 @@ function useMagicLinkVerify(token) {
2453
2917
  function LoginForm({ verifyPath = "/account/verify", onSent }) {
2454
2918
  const t = useT();
2455
2919
  const { requestMagicLink } = useAccount();
2456
- const [email, setEmail] = React10__namespace.useState("");
2457
- const [busy, setBusy] = React10__namespace.useState(false);
2458
- const [sent, setSent] = React10__namespace.useState(false);
2459
- const [devLink, setDevLink] = React10__namespace.useState(null);
2920
+ const [email, setEmail] = React19__namespace.useState("");
2921
+ const [busy, setBusy] = React19__namespace.useState(false);
2922
+ const [sent, setSent] = React19__namespace.useState(false);
2923
+ const [error, setError] = React19__namespace.useState(false);
2924
+ const [devLink, setDevLink] = React19__namespace.useState(null);
2460
2925
  async function submit(e) {
2461
2926
  e.preventDefault();
2462
2927
  setBusy(true);
2928
+ setError(false);
2463
2929
  try {
2464
2930
  const r = await requestMagicLink(email);
2465
2931
  setSent(true);
2466
2932
  if (r.devToken) setDevLink(`${verifyPath}?token=${encodeURIComponent(r.devToken)}`);
2467
2933
  onSent?.(email);
2934
+ } catch {
2935
+ setError(true);
2468
2936
  } finally {
2469
2937
  setBusy(false);
2470
2938
  }
@@ -2503,6 +2971,7 @@ function LoginForm({ verifyPath = "/account/verify", onSent }) {
2503
2971
  }
2504
2972
  )
2505
2973
  ] }),
2974
+ error ? /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", children: t("account.signInError") }) : null,
2506
2975
  /* @__PURE__ */ jsxRuntime.jsx(
2507
2976
  "button",
2508
2977
  {
@@ -2564,20 +3033,47 @@ function OrderHistory({
2564
3033
  const loc = useFormatLocale(locale);
2565
3034
  const { signedIn } = useAccount();
2566
3035
  const client = useStorefront();
2567
- const [orders, setOrders] = React10__namespace.useState(null);
2568
- const [reordering, setReordering] = React10__namespace.useState(null);
2569
- const [notice, setNotice] = React10__namespace.useState(null);
2570
- React10__namespace.useEffect(() => {
3036
+ const [orders, setOrders] = React19__namespace.useState(null);
3037
+ const [error, setError] = React19__namespace.useState(false);
3038
+ const [nextCursor, setNextCursor] = React19__namespace.useState(null);
3039
+ const [pageLoading, setPageLoading] = React19__namespace.useState(false);
3040
+ const [reload, setReload] = React19__namespace.useState(0);
3041
+ const [reordering, setReordering] = React19__namespace.useState(null);
3042
+ const [notice, setNotice] = React19__namespace.useState(null);
3043
+ React19__namespace.useEffect(() => {
2571
3044
  let live = true;
2572
3045
  if (!signedIn) {
2573
3046
  setOrders([]);
2574
3047
  return;
2575
3048
  }
2576
- client.account.orders().then((o) => live && setOrders(o)).catch(() => live && setOrders([]));
3049
+ setError(false);
3050
+ setOrders(null);
3051
+ client.account.ordersPage().then((page) => {
3052
+ if (live) {
3053
+ setOrders(page.orders);
3054
+ setNextCursor(page.nextCursor);
3055
+ }
3056
+ }).catch(() => {
3057
+ if (live) setError(true);
3058
+ });
2577
3059
  return () => {
2578
3060
  live = false;
2579
3061
  };
2580
- }, [signedIn, client]);
3062
+ }, [signedIn, client, reload]);
3063
+ async function loadMore() {
3064
+ if (!nextCursor || pageLoading) return;
3065
+ setPageLoading(true);
3066
+ setError(false);
3067
+ try {
3068
+ const page = await client.account.ordersPage({ beforeId: nextCursor });
3069
+ setOrders((previous) => [...previous ?? [], ...page.orders]);
3070
+ setNextCursor(page.nextCursor);
3071
+ } catch {
3072
+ setError(true);
3073
+ } finally {
3074
+ setPageLoading(false);
3075
+ }
3076
+ }
2581
3077
  async function reorder(statusToken) {
2582
3078
  setReordering(statusToken);
2583
3079
  setNotice(null);
@@ -2598,7 +3094,11 @@ function OrderHistory({
2598
3094
  }
2599
3095
  return /* @__PURE__ */ jsxRuntime.jsxs("section", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
2600
3096
  /* @__PURE__ */ jsxRuntime.jsx("h2", { style: { margin: 0, fontSize: "1.1rem", fontWeight: 600 }, children: t("account.orders") }),
2601
- orders == null ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "var(--nv-muted)", margin: 0 }, children: t("common.loadingShort") }) : orders.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "var(--nv-muted)", margin: 0 }, children: t("account.noOrders") }) : /* @__PURE__ */ jsxRuntime.jsx("ul", { style: { listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: "0.5rem" }, children: orders.map((o) => /* @__PURE__ */ jsxRuntime.jsxs(
3097
+ error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "alert", children: [
3098
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: t("account.loadError") }),
3099
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => orders ? void loadMore() : setReload((x) => x + 1), children: t("account.retry") })
3100
+ ] }) : null,
3101
+ orders == null ? error ? null : /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "var(--nv-muted)", margin: 0 }, children: t("common.loadingShort") }) : orders.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "var(--nv-muted)", margin: 0 }, children: t("account.noOrders") }) : /* @__PURE__ */ jsxRuntime.jsx("ul", { style: { listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: "0.5rem" }, children: orders.map((o) => /* @__PURE__ */ jsxRuntime.jsxs(
2602
3102
  "li",
2603
3103
  {
2604
3104
  style: {
@@ -2645,12 +3145,13 @@ function OrderHistory({
2645
3145
  ]
2646
3146
  },
2647
3147
  o.status_token
2648
- )) })
3148
+ )) }),
3149
+ nextCursor ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", disabled: pageLoading, onClick: () => void loadMore(), children: pageLoading ? t("common.loadingShort") : t("account.loadMore") }) : null
2649
3150
  ] });
2650
3151
  }
2651
3152
  function AddressForm2({ initial, onSubmit, onCancel, busy }) {
2652
3153
  const t = useT();
2653
- const [form, setForm] = React10__namespace.useState(() => ({
3154
+ const [form, setForm] = React19__namespace.useState(() => ({
2654
3155
  first_name: initial?.first_name ?? "",
2655
3156
  last_name: initial?.last_name ?? "",
2656
3157
  company: initial?.company ?? "",
@@ -2748,17 +3249,17 @@ function AddressBook() {
2748
3249
  const t = useT();
2749
3250
  const { signedIn } = useAccount();
2750
3251
  const client = useStorefront();
2751
- const [addresses, setAddresses] = React10__namespace.useState(null);
2752
- const [mode, setMode] = React10__namespace.useState({ kind: "list" });
2753
- const [busy, setBusy] = React10__namespace.useState(false);
2754
- const load = React10__namespace.useCallback(() => {
3252
+ const [addresses, setAddresses] = React19__namespace.useState(null);
3253
+ const [mode, setMode] = React19__namespace.useState({ kind: "list" });
3254
+ const [busy, setBusy] = React19__namespace.useState(false);
3255
+ const load = React19__namespace.useCallback(() => {
2755
3256
  if (!signedIn) {
2756
3257
  setAddresses([]);
2757
3258
  return;
2758
3259
  }
2759
3260
  client.account.addresses().then(setAddresses).catch(() => setAddresses([]));
2760
3261
  }, [signedIn, client]);
2761
- React10__namespace.useEffect(() => {
3262
+ React19__namespace.useEffect(() => {
2762
3263
  load();
2763
3264
  }, [load]);
2764
3265
  async function run(fn) {
@@ -2812,10 +3313,10 @@ function ProfileEditor() {
2812
3313
  const t = useT();
2813
3314
  const client = useStorefront();
2814
3315
  const { customer, refresh } = useAccount();
2815
- const [editing, setEditing] = React10__namespace.useState(false);
2816
- const [busy, setBusy] = React10__namespace.useState(false);
2817
- const [error, setError] = React10__namespace.useState(false);
2818
- const [form, setForm] = React10__namespace.useState({});
3316
+ const [editing, setEditing] = React19__namespace.useState(false);
3317
+ const [busy, setBusy] = React19__namespace.useState(false);
3318
+ const [error, setError] = React19__namespace.useState(false);
3319
+ const [form, setForm] = React19__namespace.useState({});
2819
3320
  if (!customer) return null;
2820
3321
  function startEdit() {
2821
3322
  setForm({
@@ -2892,6 +3393,79 @@ function ProfileEditor() {
2892
3393
  ] })
2893
3394
  ] });
2894
3395
  }
3396
+ function AccountSecurity() {
3397
+ const client = useStorefront();
3398
+ const account = useAccount();
3399
+ const t = useT();
3400
+ const [sessions, setSessions] = React19__namespace.useState(null);
3401
+ const [email, setEmail] = React19__namespace.useState("");
3402
+ const [busy, setBusy] = React19__namespace.useState(false);
3403
+ const [notice, setNotice] = React19__namespace.useState(null);
3404
+ const [confirmClose, setConfirmClose] = React19__namespace.useState(false);
3405
+ const [retry, setRetry] = React19__namespace.useState(0);
3406
+ React19__namespace.useEffect(() => {
3407
+ let live = true;
3408
+ if (account.signedIn) client.account.sessions().then((s) => {
3409
+ if (live) setSessions(s);
3410
+ }).catch(() => {
3411
+ if (live) setNotice(t("account.loadError"));
3412
+ });
3413
+ return () => {
3414
+ live = false;
3415
+ };
3416
+ }, [client, account.signedIn, retry, t]);
3417
+ async function act(operation) {
3418
+ setBusy(true);
3419
+ setNotice(null);
3420
+ try {
3421
+ await operation();
3422
+ } catch (e) {
3423
+ setNotice(e instanceof storefrontJs.StorefrontError && e.status === 401 ? t("account.recentLogin") : t("account.loadError"));
3424
+ } finally {
3425
+ setBusy(false);
3426
+ }
3427
+ }
3428
+ if (!account.signedIn) return null;
3429
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { style: { display: "grid", gap: "0.75rem" }, children: [
3430
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: { margin: 0, fontSize: "1.1rem", fontWeight: 600 }, children: t("account.security") }),
3431
+ notice ? /* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", children: notice }) : null,
3432
+ /* @__PURE__ */ jsxRuntime.jsxs(
3433
+ "form",
3434
+ {
3435
+ style: { display: "flex", gap: "0.75rem", flexWrap: "wrap", alignItems: "end" },
3436
+ onSubmit: (e) => {
3437
+ e.preventDefault();
3438
+ void act(async () => {
3439
+ await client.account.requestEmailChange(email);
3440
+ setNotice(t("account.checkEmail"));
3441
+ });
3442
+ },
3443
+ children: [
3444
+ /* @__PURE__ */ jsxRuntime.jsx(Field, { label: t("account.newEmail"), type: "email", required: true, value: email, onChange: (e) => setEmail(e.target.value) }),
3445
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", busy, children: t("account.changeEmail") })
3446
+ ]
3447
+ }
3448
+ ),
3449
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { children: t("account.sessions") }),
3450
+ sessions ? sessions.map((s) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.75rem", justifyContent: "space-between" }, children: [
3451
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: s.current ? t("account.currentSession") : /* @__PURE__ */ jsxRuntime.jsx("time", { dateTime: s.created_at, children: s.created_at.slice(0, 10) }) }),
3452
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { busy, onClick: () => void act(async () => {
3453
+ await client.account.revokeSession(s.id);
3454
+ if (s.current) await account.logout();
3455
+ else setSessions((old) => old?.filter((row) => row.id !== s.id) ?? null);
3456
+ }), children: t("account.revokeSession") })
3457
+ ] }, s.id)) : /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: () => setRetry((x) => x + 1), children: t("account.retry") }),
3458
+ confirmClose ? /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3459
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: t("account.closeWarning") }),
3460
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { busy, onClick: () => void act(async () => {
3461
+ await client.account.close();
3462
+ await account.refresh();
3463
+ }), children: t("account.confirmClose") }),
3464
+ " ",
3465
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { disabled: busy, onClick: () => setConfirmClose(false), children: t("account.cancel") })
3466
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(Button, { disabled: busy, onClick: () => setConfirmClose(true), children: t("account.closeAccount") })
3467
+ ] });
3468
+ }
2895
3469
  function serializeJsonLd(data) {
2896
3470
  return JSON.stringify(data).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026");
2897
3471
  }
@@ -2998,6 +3572,7 @@ function OrganizationJsonLd({
2998
3572
 
2999
3573
  exports.AccountDashboard = AccountDashboard;
3000
3574
  exports.AccountProvider = AccountProvider;
3575
+ exports.AccountSecurity = AccountSecurity;
3001
3576
  exports.AddToCart = AddToCart;
3002
3577
  exports.AddressBook = AddressBook;
3003
3578
  exports.AddressForm = AddressForm;
@@ -3018,10 +3593,15 @@ exports.MarketSwitcher = MarketSwitcher;
3018
3593
  exports.NeviosProvider = NeviosProvider;
3019
3594
  exports.OrderConfirmation = OrderConfirmation;
3020
3595
  exports.OrderHistory = OrderHistory;
3596
+ exports.OrderLines = OrderLines;
3021
3597
  exports.OrderStatusPage = OrderStatusPage;
3022
3598
  exports.OrderSummary = OrderSummary;
3599
+ exports.OrderTotals = OrderTotals;
3023
3600
  exports.OrganizationJsonLd = OrganizationJsonLd;
3601
+ exports.PaymentMethodPicker = PaymentMethodPicker;
3602
+ exports.PaymentPage = PaymentPage;
3024
3603
  exports.PaymentSection = PaymentSection;
3604
+ exports.PhaseTimeline = PhaseTimeline;
3025
3605
  exports.PriceMoney = PriceMoney;
3026
3606
  exports.PriceRangeFilter = PriceRangeFilter;
3027
3607
  exports.ProductCard = ProductCard;
@@ -3031,9 +3611,11 @@ exports.ProductJsonLd = ProductJsonLd;
3031
3611
  exports.ProfileEditor = ProfileEditor;
3032
3612
  exports.ShippingPicker = ShippingPicker;
3033
3613
  exports.SortSelect = SortSelect;
3614
+ exports.StatusBanner = StatusBanner;
3034
3615
  exports.StockBadge = StockBadge;
3035
3616
  exports.TagFilter = TagFilter;
3036
3617
  exports.ThemeProvider = ThemeProvider;
3618
+ exports.TransferInstructions = TransferInstructions;
3037
3619
  exports.VariantPicker = VariantPicker;
3038
3620
  exports.absoluteUrl = absoluteUrl;
3039
3621
  exports.bundledMessages = bundledMessages;
@@ -3041,6 +3623,7 @@ exports.cs = cs;
3041
3623
  exports.en = en;
3042
3624
  exports.formatCents = formatCents;
3043
3625
  exports.formatMoney = formatMoney;
3626
+ exports.isTerminal = isTerminal;
3044
3627
  exports.serializeJsonLd = serializeJsonLd;
3045
3628
  exports.stripHtml = stripHtml;
3046
3629
  exports.themeToCssVars = themeToCssVars;
@@ -3050,6 +3633,7 @@ exports.useCheckout = useCheckout;
3050
3633
  exports.useI18n = useI18n;
3051
3634
  exports.useMagicLinkVerify = useMagicLinkVerify;
3052
3635
  exports.useOrderStatus = useOrderStatus;
3636
+ exports.usePayment = usePayment;
3053
3637
  exports.useStorefront = useStorefront;
3054
3638
  exports.useStorefrontOptional = useStorefrontOptional;
3055
3639
  exports.useT = useT;