@salla.sa/twilight-theme-engine 1.0.118 → 1.0.120

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/dist/{AddToCartForm-QYSEYGYJ.js → AddToCartForm-3JMN4PL4.js} +3 -3
  2. package/dist/{AddToCartForm-QYSEYGYJ.js.map → AddToCartForm-3JMN4PL4.js.map} +1 -1
  3. package/dist/{BlogAuthorPage-ZDQE2AZX.js → BlogAuthorPage-HRPTZ6KW.js} +8 -8
  4. package/dist/{BlogAuthorPage-ZDQE2AZX.js.map → BlogAuthorPage-HRPTZ6KW.js.map} +1 -1
  5. package/dist/{BlogCategoryPage-2F5MARO5.js → BlogCategoryPage-2NNWTOTW.js} +8 -8
  6. package/dist/{BlogCategoryPage-2F5MARO5.js.map → BlogCategoryPage-2NNWTOTW.js.map} +1 -1
  7. package/dist/{BlogPage-CAVVNZ4W.js → BlogPage-JMVHQBYK.js} +7 -7
  8. package/dist/{BlogPage-CAVVNZ4W.js.map → BlogPage-JMVHQBYK.js.map} +1 -1
  9. package/dist/{BlogSinglePage-Z2HIKZNQ.js → BlogSinglePage-Y6V66JG6.js} +7 -7
  10. package/dist/{BlogSinglePage-Z2HIKZNQ.js.map → BlogSinglePage-Y6V66JG6.js.map} +1 -1
  11. package/dist/{BlogTagPage-2ULPCKZI.js → BlogTagPage-B4NJLSQ7.js} +8 -8
  12. package/dist/{BlogTagPage-2ULPCKZI.js.map → BlogTagPage-B4NJLSQ7.js.map} +1 -1
  13. package/dist/{BrandsPage-TWEXYBHF.js → BrandsPage-NBVF64JF.js} +7 -7
  14. package/dist/{BrandsPage-TWEXYBHF.js.map → BrandsPage-NBVF64JF.js.map} +1 -1
  15. package/dist/{Breadcrumb-EWUPYS3P.js → Breadcrumb-JYGYQJLB.js} +7 -7
  16. package/dist/{Breadcrumb-EWUPYS3P.js.map → Breadcrumb-JYGYQJLB.js.map} +1 -1
  17. package/dist/{CartItem-WREXJVPL.js → CartItem-B3GIVKO6.js} +7 -7
  18. package/dist/{CartItem-WREXJVPL.js.map → CartItem-B3GIVKO6.js.map} +1 -1
  19. package/dist/{CartSummary-UOQRTFXF.js → CartSummary-KYDOZM5M.js} +7 -7
  20. package/dist/{CartSummary-UOQRTFXF.js.map → CartSummary-KYDOZM5M.js.map} +1 -1
  21. package/dist/{Copyright-THOU54OW.js → Copyright-EODCFCIG.js} +3 -3
  22. package/dist/{Copyright-THOU54OW.js.map → Copyright-EODCFCIG.js.map} +1 -1
  23. package/dist/{CustomerLayout-52HRHKMR.js → CustomerLayout-76NGJTMK.js} +7 -7
  24. package/dist/{CustomerLayout-52HRHKMR.js.map → CustomerLayout-76NGJTMK.js.map} +1 -1
  25. package/dist/{Footer-J22W5XIY.js → Footer-JKHEL74P.js} +4 -4
  26. package/dist/{Footer-J22W5XIY.js.map → Footer-JKHEL74P.js.map} +1 -1
  27. package/dist/{Header-YTBXJUWG.js → Header-WJAMZDMT.js} +4 -4
  28. package/dist/{Header-YTBXJUWG.js.map → Header-WJAMZDMT.js.map} +1 -1
  29. package/dist/{LoyaltyPage-VYRO57M7.js → LoyaltyPage-JPZEXI2N.js} +7 -7
  30. package/dist/{LoyaltyPage-VYRO57M7.js.map → LoyaltyPage-JPZEXI2N.js.map} +1 -1
  31. package/dist/{LoyaltyPointsPage-EBXM7KN3.js → LoyaltyPointsPage-C4IZPAOG.js} +3 -3
  32. package/dist/{LoyaltyPointsPage-EBXM7KN3.js.map → LoyaltyPointsPage-C4IZPAOG.js.map} +1 -1
  33. package/dist/{MainMenu-ESHMVSQT.js → MainMenu-EIK6QDPF.js} +3 -3
  34. package/dist/{MainMenu-ESHMVSQT.js.map → MainMenu-EIK6QDPF.js.map} +1 -1
  35. package/dist/{MasterLayout-GPOW75JW.js → MasterLayout-IVOF3YTF.js} +7 -7
  36. package/dist/{MasterLayout-GPOW75JW.js.map → MasterLayout-IVOF3YTF.js.map} +1 -1
  37. package/dist/{MobileMenu-YRIGGD3A.js → MobileMenu-5PNZNRXJ.js} +7 -7
  38. package/dist/{MobileMenu-YRIGGD3A.js.map → MobileMenu-5PNZNRXJ.js.map} +1 -1
  39. package/dist/{NotificationsPage-YWA3WHKP.js → NotificationsPage-LO74N5F7.js} +7 -7
  40. package/dist/{NotificationsPage-YWA3WHKP.js.map → NotificationsPage-LO74N5F7.js.map} +1 -1
  41. package/dist/{OrderSinglePage-FIJTEFHJ.js → OrderSinglePage-6PYW65SG.js} +7 -7
  42. package/dist/{OrderSinglePage-FIJTEFHJ.js.map → OrderSinglePage-6PYW65SG.js.map} +1 -1
  43. package/dist/{OrdersPage-CSQPJ3A2.js → OrdersPage-KTZJCAXM.js} +7 -7
  44. package/dist/{OrdersPage-CSQPJ3A2.js.map → OrdersPage-KTZJCAXM.js.map} +1 -1
  45. package/dist/{PageSingle-UIJ3USK4.js → PageSingle-2IY5TNSQ.js} +3 -3
  46. package/dist/{PageSingle-UIJ3USK4.js.map → PageSingle-2IY5TNSQ.js.map} +1 -1
  47. package/dist/{ProductDetails-F5CTHGCT.js → ProductDetails-EXHNDRRN.js} +3 -3
  48. package/dist/{ProductDetails-F5CTHGCT.js.map → ProductDetails-EXHNDRRN.js.map} +1 -1
  49. package/dist/{ProfilePage-P2FZ4KCI.js → ProfilePage-4W6ZGYOE.js} +7 -7
  50. package/dist/{ProfilePage-P2FZ4KCI.js.map → ProfilePage-4W6ZGYOE.js.map} +1 -1
  51. package/dist/{ReviewsPage-X37ZSSWG.js → ReviewsPage-P6UX4LHI.js} +3 -3
  52. package/dist/{ReviewsPage-X37ZSSWG.js.map → ReviewsPage-P6UX4LHI.js.map} +1 -1
  53. package/dist/{SeoCartWidget-ZDYIBND6.js → SeoCartWidget-2WHHI6QF.js} +7 -7
  54. package/dist/{SeoCartWidget-ZDYIBND6.js.map → SeoCartWidget-2WHHI6QF.js.map} +1 -1
  55. package/dist/{SettingsPage-R6G63QP4.js → SettingsPage-U2B5JI5K.js} +7 -7
  56. package/dist/{SettingsPage-R6G63QP4.js.map → SettingsPage-U2B5JI5K.js.map} +1 -1
  57. package/dist/{StoreClosedNotification-Q7TMNZEX.js → StoreClosedNotification-MJQT66GR.js} +8 -8
  58. package/dist/{StoreClosedNotification-Q7TMNZEX.js.map → StoreClosedNotification-MJQT66GR.js.map} +1 -1
  59. package/dist/{TestimonialsPage-RZ77X7BG.js → TestimonialsPage-BGJND2VC.js} +3 -3
  60. package/dist/{TestimonialsPage-RZ77X7BG.js.map → TestimonialsPage-BGJND2VC.js.map} +1 -1
  61. package/dist/{ThankYouPage-WDABLHMH.js → ThankYouPage-B3KOZKMZ.js} +7 -7
  62. package/dist/{ThankYouPage-WDABLHMH.js.map → ThankYouPage-B3KOZKMZ.js.map} +1 -1
  63. package/dist/{WalletPage-SGB23HK3.js → WalletPage-KVG6MYQ4.js} +7 -7
  64. package/dist/{WalletPage-SGB23HK3.js.map → WalletPage-KVG6MYQ4.js.map} +1 -1
  65. package/dist/{WishlistPage-QZADACKT.js → WishlistPage-ZAXYF5WP.js} +7 -7
  66. package/dist/{WishlistPage-QZADACKT.js.map → WishlistPage-ZAXYF5WP.js.map} +1 -1
  67. package/dist/api/store.d.ts +15 -0
  68. package/dist/api/store.d.ts.map +1 -1
  69. package/dist/api/store.js +1 -1
  70. package/dist/{chunk-MQTO6I7W.js → chunk-25MXTMV4.js} +4 -4
  71. package/dist/{chunk-MQTO6I7W.js.map → chunk-25MXTMV4.js.map} +1 -1
  72. package/dist/{chunk-MKDS22Q3.js → chunk-4GWHDLUF.js} +6 -6
  73. package/dist/{chunk-MKDS22Q3.js.map → chunk-4GWHDLUF.js.map} +1 -1
  74. package/dist/{chunk-CVBRA2LE.js → chunk-5QYNHHPE.js} +3 -3
  75. package/dist/{chunk-CVBRA2LE.js.map → chunk-5QYNHHPE.js.map} +1 -1
  76. package/dist/{chunk-HUQU5NB5.js → chunk-5YXJC35L.js} +10 -10
  77. package/dist/{chunk-HUQU5NB5.js.map → chunk-5YXJC35L.js.map} +1 -1
  78. package/dist/{chunk-TDOVEDHH.js → chunk-D6XHL6VQ.js} +69 -46
  79. package/dist/chunk-D6XHL6VQ.js.map +1 -0
  80. package/dist/{chunk-4FUSNRFO.js → chunk-FIDNPYLL.js} +3 -3
  81. package/dist/{chunk-4FUSNRFO.js.map → chunk-FIDNPYLL.js.map} +1 -1
  82. package/dist/{chunk-LPCNDH4F.js → chunk-IRQJBRKV.js} +23 -5
  83. package/dist/chunk-IRQJBRKV.js.map +1 -0
  84. package/dist/{chunk-BSJPKSKE.js → chunk-NHEMVF3B.js} +5 -5
  85. package/dist/{chunk-BSJPKSKE.js.map → chunk-NHEMVF3B.js.map} +1 -1
  86. package/dist/{chunk-QXYSINUS.js → chunk-TI6S5KW3.js} +3 -3
  87. package/dist/{chunk-QXYSINUS.js.map → chunk-TI6S5KW3.js.map} +1 -1
  88. package/dist/chunk-TM5MVVTX.js +14 -0
  89. package/dist/{chunk-JJ7VOYWQ.js.map → chunk-TM5MVVTX.js.map} +1 -1
  90. package/dist/{chunk-TYYXLAOZ.js → chunk-ULPH6647.js} +5 -5
  91. package/dist/{chunk-TYYXLAOZ.js.map → chunk-ULPH6647.js.map} +1 -1
  92. package/dist/{chunk-XSJ3YUSS.js → chunk-UNLQTOEN.js} +4 -4
  93. package/dist/{chunk-XSJ3YUSS.js.map → chunk-UNLQTOEN.js.map} +1 -1
  94. package/dist/{chunk-B3QDJK2B.js → chunk-UVQ3QASG.js} +7 -7
  95. package/dist/{chunk-B3QDJK2B.js.map → chunk-UVQ3QASG.js.map} +1 -1
  96. package/dist/{chunk-6KCK7SG7.js → chunk-Y5ZHBECO.js} +4 -4
  97. package/dist/{chunk-6KCK7SG7.js.map → chunk-Y5ZHBECO.js.map} +1 -1
  98. package/dist/{chunk-YAVIABRR.js → chunk-Y6VKKGXJ.js} +3 -3
  99. package/dist/{chunk-YAVIABRR.js.map → chunk-Y6VKKGXJ.js.map} +1 -1
  100. package/dist/components/cart/index.js +1 -1
  101. package/dist/components/common/index.js +1 -1
  102. package/dist/components/drawer/index.js +5 -5
  103. package/dist/components/home/index.js +7 -7
  104. package/dist/components/layout/index.js +1 -1
  105. package/dist/components/product/index.js +6 -6
  106. package/dist/components/store/index.js +6 -6
  107. package/dist/{document-class-HCJFZSJ2.js → document-class-OSMTFGJJ.js} +5 -5
  108. package/dist/{document-class-HCJFZSJ2.js.map → document-class-OSMTFGJJ.js.map} +1 -1
  109. package/dist/hooks/index.js +5 -5
  110. package/dist/hooks/useGtm.js +5 -5
  111. package/dist/hooks/useMoney.js +5 -5
  112. package/dist/hooks/useStore.js +5 -5
  113. package/dist/index.js +5 -5
  114. package/dist/{not-found-ZJ64R3RS.js → not-found-ZX6EJRVW.js} +7 -7
  115. package/dist/{not-found-ZJ64R3RS.js.map → not-found-ZX6EJRVW.js.map} +1 -1
  116. package/dist/providers/index.js +5 -5
  117. package/dist/routes/account/orders.js +1 -1
  118. package/dist/routes/account.js +6 -6
  119. package/dist/routes/blog.js +5 -5
  120. package/dist/routes/brands.js +1 -1
  121. package/dist/routes/cart.js +9 -9
  122. package/dist/routes/home.js +8 -8
  123. package/dist/routes/loyalty.js +2 -2
  124. package/dist/routes/page.js +1 -1
  125. package/dist/routes/product-listing.js +7 -7
  126. package/dist/routes/product.js +7 -7
  127. package/dist/routes/testimonials.js +2 -2
  128. package/dist/routes/thank-you.js +1 -1
  129. package/dist/skeleton.js +8 -8
  130. package/dist/tanstack/middleware/twilight.d.ts.map +1 -1
  131. package/dist/tanstack.js +20 -3
  132. package/dist/tanstack.js.map +1 -1
  133. package/dist/utils/fast-checkout.d.ts +1 -1
  134. package/dist/utils/fast-checkout.d.ts.map +1 -1
  135. package/dist/utils/maintenance.d.ts +17 -0
  136. package/dist/utils/maintenance.d.ts.map +1 -1
  137. package/package.json +1 -1
  138. package/dist/chunk-JJ7VOYWQ.js +0 -14
  139. package/dist/chunk-LPCNDH4F.js.map +0 -1
  140. package/dist/chunk-TDOVEDHH.js.map +0 -1
@@ -2,10 +2,75 @@ import { ensureTwilightContextFromMatches } from './chunk-JYV25VNZ.js';
2
2
  import { renderThemeHookSlotsScript, renderAppScopeInstallScript } from './chunk-5FJFN3IW.js';
3
3
  import { resolveHead, mergeHead } from './chunk-GD26FI4J.js';
4
4
  import { buildBaseHead } from './chunk-OM2GRPDH.js';
5
- import { readEnv, renderRuntimeEnvScript, escapeForInlineScript, extractTokenFromCookies } from './chunk-FHU2MXZA.js';
5
+ import { extractTokenFromCookies, readEnv, renderRuntimeEnvScript, escapeForInlineScript } from './chunk-FHU2MXZA.js';
6
6
  import { getTwilightContext, SettingsError } from './chunk-7VNVCHID.js';
7
7
  import { FALLBACK_LOCALE } from './chunk-T72DAX7R.js';
8
8
 
9
+ // src/utils/maintenance.ts
10
+ var VIEW_AS_OWNER_COOKIE_NAME = "salla_view_as";
11
+ var OWNER_SOURCES = ["dashboard", "portal"];
12
+ function storeIdOf(settings) {
13
+ const id = settings?.store?.id;
14
+ return id == null ? null : String(id);
15
+ }
16
+ function ownerLinkMatches(href, settings) {
17
+ const storeId = storeIdOf(settings);
18
+ if (!storeId) return false;
19
+ let params;
20
+ try {
21
+ params = new URL(href, "http://localhost").searchParams;
22
+ } catch {
23
+ return false;
24
+ }
25
+ const source = params.get("utm_source");
26
+ return source != null && OWNER_SOURCES.includes(source) && params.get("identifier") === storeId;
27
+ }
28
+ function ownerCookieMatches(cookieHeader, settings) {
29
+ const storeId = storeIdOf(settings);
30
+ return !!storeId && extractTokenFromCookies(cookieHeader, VIEW_AS_OWNER_COOKIE_NAME) === storeId;
31
+ }
32
+ function showsMaintenancePage(settings, viewAsOwner) {
33
+ return settings?.maintenance === true && !viewAsOwner && settings.theme?.mode !== "preview";
34
+ }
35
+ var MAINTENANCE_EVIDENCE_HEADER = "x-twilight-maintenance";
36
+ function maintenanceEvidence(settings) {
37
+ const evidence = {};
38
+ if (!settings) return evidence;
39
+ for (const [key, read] of EVIDENCE) {
40
+ const value = read(settings);
41
+ if (value != null && value !== "") evidence[key] = String(value);
42
+ }
43
+ return evidence;
44
+ }
45
+ var EVIDENCE = [
46
+ ["store", (s) => s.store?.id],
47
+ ["scope", (s) => s.store?.scope?.id],
48
+ ["requested-scope", (s) => s.requestedScopeId],
49
+ ["mode", (s) => s.theme?.mode],
50
+ ["request-id", (s) => s.answer?.requestId],
51
+ ["trace", (s) => s.answer?.traceId],
52
+ ["cache", (s) => s.answer?.cacheStatus],
53
+ ["age", (s) => s.answer?.age]
54
+ ];
55
+ function maintenanceEvidenceHeader(evidence) {
56
+ return Object.entries(evidence).map(([key, value]) => `${key}=${value.replace(/[^\x21-\x7e]/g, "")}`).join("; ");
57
+ }
58
+ var DASHBOARD_URL = "https://s.salla.sa";
59
+ var MAINTENANCE_SETTINGS_URL = `${DASHBOARD_URL}/channel/settings?legacy=0#maintenance-mode`;
60
+ function withOwnerMaintenanceButton(settings, buttonTitle) {
61
+ const details = settings.maintenance_details;
62
+ if (settings.maintenance !== true || details?.button_title) return settings;
63
+ return {
64
+ ...settings,
65
+ maintenance_details: {
66
+ ...details,
67
+ button_title: buttonTitle,
68
+ button_full_title: buttonTitle,
69
+ button_url: MAINTENANCE_SETTINGS_URL
70
+ }
71
+ };
72
+ }
73
+
9
74
  // src/routes/root/head.ts
10
75
  var SALLA_ICONS_CSS_URL = "https://cdn.assets.salla.network/static/fonts/sallaicons.css?v=2.0.5";
11
76
  var LIT_VERSION = "3.3.3";
@@ -295,48 +360,6 @@ function buildCustomJsScript(customJs, isUrl) {
295
360
  };
296
361
  }
297
362
 
298
- // src/utils/maintenance.ts
299
- var VIEW_AS_OWNER_COOKIE_NAME = "salla_view_as";
300
- var OWNER_SOURCES = ["dashboard", "portal"];
301
- function storeIdOf(settings) {
302
- const id = settings?.store?.id;
303
- return id == null ? null : String(id);
304
- }
305
- function ownerLinkMatches(href, settings) {
306
- const storeId = storeIdOf(settings);
307
- if (!storeId) return false;
308
- let params;
309
- try {
310
- params = new URL(href, "http://localhost").searchParams;
311
- } catch {
312
- return false;
313
- }
314
- const source = params.get("utm_source");
315
- return source != null && OWNER_SOURCES.includes(source) && params.get("identifier") === storeId;
316
- }
317
- function ownerCookieMatches(cookieHeader, settings) {
318
- const storeId = storeIdOf(settings);
319
- return !!storeId && extractTokenFromCookies(cookieHeader, VIEW_AS_OWNER_COOKIE_NAME) === storeId;
320
- }
321
- function showsMaintenancePage(settings, viewAsOwner) {
322
- return settings?.maintenance === true && !viewAsOwner && settings.theme?.mode !== "preview";
323
- }
324
- var DASHBOARD_URL = "https://s.salla.sa";
325
- var MAINTENANCE_SETTINGS_URL = `${DASHBOARD_URL}/channel/settings?legacy=0#maintenance-mode`;
326
- function withOwnerMaintenanceButton(settings, buttonTitle) {
327
- const details = settings.maintenance_details;
328
- if (settings.maintenance !== true || details?.button_title) return settings;
329
- return {
330
- ...settings,
331
- maintenance_details: {
332
- ...details,
333
- button_title: buttonTitle,
334
- button_full_title: buttonTitle,
335
- button_url: MAINTENANCE_SETTINGS_URL
336
- }
337
- };
338
- }
339
-
340
- export { TICKETING_SCRIPT_URL, VIEW_AS_OWNER_COOKIE_NAME, ownerCookieMatches, ownerLinkMatches, resolveTwilightSdkUrl, rootHead, showsMaintenancePage, withOwnerMaintenanceButton };
341
- //# sourceMappingURL=chunk-TDOVEDHH.js.map
342
- //# sourceMappingURL=chunk-TDOVEDHH.js.map
363
+ export { MAINTENANCE_EVIDENCE_HEADER, TICKETING_SCRIPT_URL, VIEW_AS_OWNER_COOKIE_NAME, maintenanceEvidence, maintenanceEvidenceHeader, ownerCookieMatches, ownerLinkMatches, resolveTwilightSdkUrl, rootHead, showsMaintenancePage, withOwnerMaintenanceButton };
364
+ //# sourceMappingURL=chunk-D6XHL6VQ.js.map
365
+ //# sourceMappingURL=chunk-D6XHL6VQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/maintenance.ts","../src/routes/root/head.ts"],"names":[],"mappings":"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","file":"chunk-D6XHL6VQ.js","sourcesContent":["import type { StoreContext } from '../api/store';\nimport { extractTokenFromCookies } from './cookies';\n\n/**\n * Remembers that this browser is the merchant looking at their own closed store.\n *\n * The dashboard's \"view store\" link carries `?utm_source=dashboard&identifier=<store id>`\n * (`portal` for the partners portal). Twig's backend checks that once, keeps\n * `view-as: owner` in the PHP session and lets every later request through; this\n * cookie is that session entry. No `max-age`: a session cookie, as the PHP session\n * was, so closing the browser ends the owner view.\n *\n * The value is the store id the bypass was granted for, checked against the store\n * the settings answer about, so one store's cookie opens no other store.\n */\nexport const VIEW_AS_OWNER_COOKIE_NAME = 'salla_view_as';\n\nconst OWNER_SOURCES = ['dashboard', 'portal'];\n\n/** The id as the URL and the cookie spell it, or null when the settings name none. */\nfunction storeIdOf(settings: StoreContext | null | undefined): string | null {\n const id = settings?.store?.id;\n return id == null ? null : String(id);\n}\n\n/**\n * Whether `href` is the dashboard's link into the merchant's own store:\n * `utm_source` is `dashboard` or `portal`, and `identifier` is this store's id.\n * The backend's own rule, translated.\n */\nexport function ownerLinkMatches(href: string, settings: StoreContext | null | undefined): boolean {\n const storeId = storeIdOf(settings);\n if (!storeId) return false;\n let params: URLSearchParams;\n try {\n params = new URL(href, 'http://localhost').searchParams;\n } catch {\n return false;\n }\n const source = params.get('utm_source');\n return source != null && OWNER_SOURCES.includes(source) && params.get('identifier') === storeId;\n}\n\n/** Whether the cookie remembers an owner view of this store. */\nexport function ownerCookieMatches(\n cookieHeader: string | null,\n settings: StoreContext | null | undefined\n): boolean {\n const storeId = storeIdOf(settings);\n return !!storeId && extractTokenFromCookies(cookieHeader, VIEW_AS_OWNER_COOKIE_NAME) === storeId;\n}\n\n/**\n * Whether this visitor gets the maintenance page instead of the store.\n *\n * True only when the settings say the store is closed and nothing lets the visitor\n * through: neither an owner view (the link or the cookie) nor the theme editor's\n * preview, which the backend also always lets in.\n */\nexport function showsMaintenancePage(\n settings: StoreContext | null | undefined,\n viewAsOwner: boolean\n): boolean {\n return settings?.maintenance === true && !viewAsOwner && settings.theme?.mode !== 'preview';\n}\n\n/**\n * The response header a maintenance 503 carries saying which settings decided it.\n *\n * Theme workers write no logs, and the dispatcher's line for a 5xx records the\n * answer's own `x-trace-id` and this header, so the evidence travels on the answer.\n * The backend sets `maintenance` from store-wide state alone (closed, not launched,\n * or the market in maintenance), so `request-id` and `trace` find the settings\n * request it logged, and `cache`/`age` say whether this was a cached copy of one.\n */\nexport const MAINTENANCE_EVIDENCE_HEADER = 'x-twilight-maintenance';\n\n/**\n * What the maintenance decision rested on, as `key=value` pairs. Ids and the API's\n * own header values only: nothing a visitor typed, nothing that identifies them.\n */\nexport function maintenanceEvidence(\n settings: StoreContext | null | undefined\n): Record<string, string> {\n const evidence: Record<string, string> = {};\n if (!settings) return evidence;\n for (const [key, read] of EVIDENCE) {\n const value = read(settings);\n if (value != null && value !== '') evidence[key] = String(value);\n }\n return evidence;\n}\n\nconst EVIDENCE: [string, (settings: StoreContext) => unknown][] = [\n ['store', (s) => s.store?.id],\n ['scope', (s) => s.store?.scope?.id],\n ['requested-scope', (s) => s.requestedScopeId],\n ['mode', (s) => s.theme?.mode],\n ['request-id', (s) => s.answer?.requestId],\n ['trace', (s) => s.answer?.traceId],\n ['cache', (s) => s.answer?.cacheStatus],\n ['age', (s) => s.answer?.age],\n];\n\n/** {@link maintenanceEvidence} as one header value: `store=1; scope=2; cache=HIT`. */\nexport function maintenanceEvidenceHeader(evidence: Record<string, string>): string {\n return Object.entries(evidence)\n .map(([key, value]) => `${key}=${value.replace(/[^\\x21-\\x7e]/g, '')}`)\n .join('; ');\n}\n\n// todo:: drop both once the backend sends `dashboard_url` (or the filled `button_*`) in the\n// settings; until then this mirrors `config('salla.app.dashboard_url')` and the path Twig's\n// `StoreStatusAlertWidget` appends for the owner.\nconst DASHBOARD_URL = 'https://s.salla.sa';\n\n/** The dashboard page where the merchant turns maintenance mode off, as the backend links it. */\nexport const MAINTENANCE_SETTINGS_URL = `${DASHBOARD_URL}/channel/settings?legacy=0#maintenance-mode`;\n\n/**\n * The button on the SDK's merchant maintenance bar. The API fills the `button_*`\n * fields only inside Twig's owner session, which the engine's settings request has\n * none of, so the SDK, handed the settings as they are, draws an empty button. The\n * SDK renders only in the store view, so `maintenance: true` there means the owner\n * (or the preview, where the SDK mounts no bar): the three fields get what Twig's\n * owner branch gives them. The merchant's own title and message stay as they are.\n */\nexport function withOwnerMaintenanceButton<\n T extends Pick<StoreContext, 'maintenance' | 'maintenance_details'>,\n>(settings: T, buttonTitle: string): T {\n const details = settings.maintenance_details;\n if (settings.maintenance !== true || details?.button_title) return settings;\n return {\n ...settings,\n maintenance_details: {\n ...details,\n button_title: buttonTitle,\n button_full_title: buttonTitle,\n button_url: MAINTENANCE_SETTINGS_URL,\n },\n };\n}\n","import type { HeadDescriptor, HeadResult } from '../../utils/head';\nimport { mergeHead, resolveHead } from '../../utils/head';\nimport { buildBaseHead } from '../../utils/baseHead';\nimport { FALLBACK_LOCALE } from '../../providers/locale-constants';\nimport { getTwilightContext } from '../../twilight/context';\nimport type { TwilightContextMatch } from '../../twilight/ensure-context';\nimport { ensureTwilightContextFromMatches } from '../../twilight/ensure-context';\nimport type { StoreContext } from '../../api/store';\nimport type { AppSnippet } from '../../api/apps';\nimport { SettingsError } from '../../utils/errors';\nimport { renderAppScopeInstallScript } from '../../utils/app-scope';\nimport { renderThemeHookSlotsScript } from '../../utils/theme-hook-slots';\nimport { escapeForInlineScript } from '../../utils/inline-script';\nimport { readEnv, renderRuntimeEnvScript } from '../../utils/runtime-env';\n\nconst SALLA_ICONS_CSS_URL = 'https://cdn.assets.salla.network/static/fonts/sallaicons.css?v=2.0.5';\nconst LIT_VERSION = '3.3.3';\nconst LIT_CDN_BASE = `https://cdn.assets.salla.network/static/lit/${LIT_VERSION}`;\n\n/** Bare-specifier map for the lit build the engine's `<salla-*>` web components resolve against. */\nconst LIT_IMPORTS: Record<string, string> = {\n lit: `${LIT_CDN_BASE}/lit.js`,\n 'lit/': `${LIT_CDN_BASE}/`,\n 'lit-html': `${LIT_CDN_BASE}/lit-html/lit-html.js`,\n 'lit-html/': `${LIT_CDN_BASE}/lit-html/`,\n 'lit-element': `${LIT_CDN_BASE}/lit-element/lit-element.js`,\n 'lit-element/': `${LIT_CDN_BASE}/lit-element/`,\n '@lit/reactive-element': `${LIT_CDN_BASE}/reactive-element/reactive-element.js`,\n '@lit/reactive-element/': `${LIT_CDN_BASE}/reactive-element/`,\n};\n\nexport const TICKETING_SCRIPT_URL =\n 'https://cdn.assets.salla.network/latest/@salla.sa/ui-store-ticketing-system/ticketing-system.es.js';\n\nconst TWILIGHT_RELEASE_CDN = 'https://cdn.salla.network/js/twilight';\nconst TWILIGHT_DEV_CDN = 'https://cdn.assets.salla.network/dev/@salla.sa/twilight';\n// The oldest Twilight release this engine works with. Raise it whenever the engine\n// starts relying on something newer; the reason lives in that commit. Today's floor:\n// components ship their own CSS, which themes no longer compile (SallaApp/twilight#2107).\nconst MIN_TWILIGHT_VERSION = '2.14.538';\n// Last resort when no override and no platform pin, and the substitute for a pin below the floor.\nconst DEFAULT_TWILIGHT_VERSION = '2.14.584';\nconst releaseUrl = (version: string): string =>\n `${TWILIGHT_RELEASE_CDN}/${version}/twilight.esm.js`;\n// The head is built more than once per request (early hints, then the page); say it once.\nconst warnedPins = new Set<string>();\n\n/** `x.y.z` release pins only; dev shas and other strings are loaded as given. */\nfunction belowMinimum(version: string): boolean {\n return (\n /^\\d+\\.\\d+\\.\\d+$/.test(version) &&\n version.localeCompare(MIN_TWILIGHT_VERSION, undefined, { numeric: true }) < 0\n );\n}\n\n/** The `x.y.z` release segment of a release-CDN `.../twilight.esm.js` URL, if present. */\nfunction releaseVersionInUrl(url: string): string | null {\n const match = url.match(/\\/(\\d+\\.\\d+\\.\\d+)\\/twilight\\.esm\\.js(?:[?#]|$)/);\n return match ? match[1] : null;\n}\n\n/**\n * `VITE_TWILIGHT_URL`/`VITE_TWILIGHT_VERSION` outrank everything below, including\n * `theme.twilight.version`'s own `belowMinimum` guard — a stale override wins\n * silently otherwise (TD-16375: a scaffold-time pin outlived the engine raising\n * MIN_TWILIGHT_VERSION, so every new theme rendered without component CSS and\n * nothing said why). Only a dev-mode nudge, not a swap: an env override is a\n * deliberate choice, so unlike the settings-pin path below this never substitutes\n * the engine default underneath the developer.\n */\nfunction warnIfOverrideBelowMinimum(source: string, version: string): void {\n // Worker logs in production should stay quiet -- this is a developer-directed nudge,\n // not a user-facing or production-monitored signal. import.meta.env.DEV is a static\n // false in production builds, so this branch (and the console.warn below) is\n // tree-shaken out entirely, same as DevSettingsWidget / dev-settings-store.ts.\n if (!import.meta.env.DEV) return;\n if (!belowMinimum(version)) return;\n const key = `${source}:${version}`;\n if (warnedPins.has(key)) return;\n warnedPins.add(key);\n console.warn(\n `[twilight] ${source}=${version} is below the engine minimum ${MIN_TWILIGHT_VERSION} — components may load without their CSS (SallaApp/twilight#2107). Unset it or bump it to ${MIN_TWILIGHT_VERSION}+.`\n );\n}\n\n/**\n * Which twilight.esm.js the storefront loads, in priority order:\n * 1. `VITE_TWILIGHT_URL` — full local/deployment override.\n * 2. `VITE_TWILIGHT_VERSION` — dev-CDN build override.\n * 3. `theme.twilight.version` from the settings endpoint — the platform-pinned\n * release used when no environment override is configured.\n * 4. The engine's default release, also used when the pin is below the engine minimum.\n */\nexport function resolveTwilightSdkUrl(settings?: StoreContext): string {\n const urlOverride = readEnv('VITE_TWILIGHT_URL');\n if (urlOverride) {\n const version = releaseVersionInUrl(urlOverride);\n if (version) warnIfOverrideBelowMinimum('VITE_TWILIGHT_URL', version);\n return urlOverride;\n }\n\n const versionOverride = readEnv('VITE_TWILIGHT_VERSION');\n if (versionOverride) {\n warnIfOverrideBelowMinimum('VITE_TWILIGHT_VERSION', versionOverride);\n return `${TWILIGHT_DEV_CDN}/${versionOverride}/twilight.esm.js`;\n }\n\n const pinnedVersion = settings?.theme?.twilight?.version;\n if (pinnedVersion && belowMinimum(pinnedVersion)) {\n if (!warnedPins.has(pinnedVersion)) {\n warnedPins.add(pinnedVersion);\n console.warn(\n `[twilight] theme.twilight.version ${pinnedVersion} is below the engine minimum ${MIN_TWILIGHT_VERSION}; loading ${DEFAULT_TWILIGHT_VERSION} instead`\n );\n }\n return releaseUrl(DEFAULT_TWILIGHT_VERSION);\n }\n if (pinnedVersion) return releaseUrl(pinnedVersion);\n\n return releaseUrl(DEFAULT_TWILIGHT_VERSION);\n}\n\n// On a page that preloads its LCP image, the icon font (~270 KB) applies once the first screen's\n// priority images have painted, so it doesn't compete with them; other pages swap on load.\nconst MEDIA_SWAP_SCRIPT = `\n(function(){var d=document,s=function(l){if(l.sheet||\"all\"===l.media)l.media=\"all\";else l.onload=function(){this.media=\"all\"}},f=d.getElementById(\"salla-theme-font\"),i=d.getElementById(\"salla-icons-css\");f&&s(f);if(!i)return;if(!d.querySelector('link[rel=\"preload\"][as=\"image\"]'))return s(i);var g=function(){g=function(){};s(i)},p=function(){requestAnimationFrame(function(){setTimeout(function(){g()})});setTimeout(function(){g()},100)};d.addEventListener(\"DOMContentLoaded\",function(){var m=[].filter.call(d.querySelectorAll('img[fetchpriority=\"high\"]'),function(x){return!x.complete}),n=m.length;if(!n)return p();m.forEach(function(x){var o=function(){--n||p()};x.addEventListener(\"load\",o,{once:!0});x.addEventListener(\"error\",o,{once:!0})});setTimeout(function(){g()},2500)})})();\n`.trim();\n\nconst LOADING_CSS = `\n.loading-overlay{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:#fff;z-index:9999}\n.loading-spinner{animation:spin 1s linear infinite;border-radius:9999px;height:3rem;width:3rem;border-bottom:2px solid var(--color-primary,#000)}\n@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}\nhtml,body{margin:0;padding:0;height:100%}\n`.trim();\n\nconst SALLA_INIT_SCRIPT = `\nwindow.salla = window.Salla = window.Salla || window.salla || {};\nwindow.Salla.onReady = window.Salla.onReady || function(callback) {\n return new Promise(function(resolve) {\n if (window.Salla.status === 'ready') {\n var config = window.salla && window.salla.config && window.salla.config.all();\n resolve(callback ? callback(config) : config);\n } else {\n window.addEventListener('twilight::initiated', function(event) {\n resolve(callback ? callback(event.detail) : event.detail);\n }, { once: true });\n }\n });\n};\n`.trim();\n\n/**\n * Distinct snippet-host origins to `preconnect` (warm DNS/TCP/TLS during parse). From the real\n * URLs (dev/prod-correct), deduped and capped at 4. No `crossOrigin`: snippets are no-cors fetches.\n */\nexport function snippetPreconnectOrigins(snippets: readonly AppSnippet[] | undefined): string[] {\n if (!snippets?.length) return [];\n const origins = new Set<string>();\n for (const app of snippets) {\n if (app.status !== 'enabled') continue;\n for (const s of app.snippets) {\n if (!s.url) continue;\n try {\n origins.add(new URL(s.url).origin);\n } catch {\n /* skip a malformed snippet url rather than breaking the head */\n }\n if (origins.size >= 4) return [...origins];\n }\n }\n return [...origins];\n}\n\nexport function rootHead(ctx: {\n params: Record<string, string>;\n matches?: readonly TwilightContextMatch[];\n}): HeadResult {\n // Re-run on the client during hydration, where the twilight module store may\n // still be empty. Recover it from the resolved match context so the head is\n // built from real settings instead of falling through to 'Store Unavailable'.\n ensureTwilightContextFromMatches(ctx.matches);\n\n let settings: StoreContext | undefined;\n try {\n settings = getTwilightContext().settings;\n } catch (e) {\n if (e instanceof SettingsError) {\n return resolveHead({\n title: 'Store Unavailable',\n });\n }\n throw e;\n }\n const locale = ctx.params.locale || FALLBACK_LOCALE;\n const parts = deriveHeadParts(settings);\n\n return resolveHead(\n mergeHead(buildBaseHead(settings, locale), {\n meta: buildRootMeta(parts),\n links: buildRootLinks(parts),\n styles: buildRootStyles(parts),\n importMap: [{ imports: LIT_IMPORTS }],\n scripts: buildRootScripts(parts),\n })\n );\n}\n\n/** Everything the root head's tag builders read, derived once from the store settings. */\ninterface RootHeadParts {\n store: StoreContext['store'] | undefined;\n favicon?: string;\n primaryColor?: string;\n fontUrl?: string;\n fontUrlWithDisplay?: string;\n isGoogleFont?: boolean;\n fontFamilyName?: string;\n customJs?: string;\n customCss?: string;\n isCustomCssUrl?: boolean;\n isCustomJsUrl?: boolean;\n twilightSdkUrl: string;\n /** The visitor gets the maintenance page, which loads no SDK and no app snippets. */\n maintenance: boolean;\n snippetPreconnects: Array<{ rel: 'preconnect'; href: string }>;\n appScopeInstallScript: string;\n themeHookSlotsScript: string | null;\n runtimeEnvScript: string | null;\n}\n\n/** Google Fonts only honours `display=swap` as a query param; other hosts get the @font-face\n * override instead (see buildRootStyles). */\nfunction deriveFontParts(theme?: StoreContext['theme']) {\n const font = theme?.font;\n const fontUrl = font?.url || font?.path;\n const isGoogleFont = fontUrl?.includes('fonts.googleapis.com');\n const needsDisplay = Boolean(isGoogleFont && fontUrl && !fontUrl.includes('display='));\n const separator = fontUrl?.includes('?') ? '&' : '?';\n\n return {\n fontUrl,\n isGoogleFont,\n fontFamilyName: font?.family_name,\n fontUrlWithDisplay: needsDisplay ? `${fontUrl}${separator}display=swap` : fontUrl,\n };\n}\n\n/** Theme customization JS/CSS, each either a URL to load or an inline blob to embed. */\nfunction deriveCustomizationParts(theme?: StoreContext['theme']) {\n const customization = theme?.customization;\n const customJs = customization?.js?.trim();\n const customCss = customization?.css?.trim();\n const isUrl = (value?: string): boolean =>\n Boolean(value?.startsWith('http') || value?.startsWith('//'));\n\n return {\n customJs,\n customCss,\n isCustomCssUrl: isUrl(customCss),\n isCustomJsUrl: isUrl(customJs),\n };\n}\n\nfunction deriveHeadParts(settings?: StoreContext): RootHeadParts {\n const store = settings?.store;\n\n return {\n store,\n favicon: store?.icon,\n primaryColor: settings?.theme?.color?.primary,\n ...deriveFontParts(settings?.theme),\n ...deriveCustomizationParts(settings?.theme),\n twilightSdkUrl: resolveTwilightSdkUrl(settings),\n maintenance: getTwilightContext().maintenance,\n // Warm the connection to the snippet host(s) during head parse, so the body's deferred\n // `<script src>` snippet tags fetch off an already-open socket instead of DNS+TCP+TLS.\n snippetPreconnects: snippetPreconnectOrigins(getTwilightContext().appsSnippets).map((href) => ({\n rel: 'preconnect' as const,\n href,\n })),\n // Install `Salla.appScope` inline at parse time, before the SDK is ready — else a snippet's\n // onReady callback calls it too early and throws. Always emitted, even when the settings\n // prefetch failed: the CDN snippet tags ship regardless (they come from the *snippets*\n // endpoint), so the factory has to exist for them. `installAppScope` then seeds the real\n // buckets into this install once the client query resolves.\n appScopeInstallScript: renderAppScopeInstallScript(\n getTwilightContext().appsSettings ?? { apps: {} }\n ),\n // Whitelist the theme's own hook slots at parse time too, for the same reason: apps register\n // their `onReady` callbacks from parser-inserted snippet tags, long before React hydrates.\n themeHookSlotsScript: renderThemeHookSlotsScript(),\n // Env this render resolved (worker `vars` live in server-only `process.env`), handed to the\n // client so it doesn't silently fall back to the production defaults. Re-rendered on the\n // client during hydration, where it resolves to the same values or to nothing.\n runtimeEnvScript: renderRuntimeEnvScript(),\n };\n}\n\nfunction buildRootMeta(p: RootHeadParts): NonNullable<HeadDescriptor['meta']> {\n return [\n { name: 'robots', content: 'index, follow' },\n { name: 'msapplication-TileColor', content: '#ffffff' },\n ...(p.favicon ? [{ name: 'msapplication-TileImage', content: p.favicon }] : []),\n ...(p.primaryColor\n ? [\n { name: 'theme-color', content: p.primaryColor },\n { name: 'msapplication-navbutton-color', content: p.primaryColor },\n { name: 'apple-mobile-web-app-status-bar-style', content: p.primaryColor },\n ]\n : []),\n ];\n}\n\nfunction buildRootLinks(p: RootHeadParts): NonNullable<HeadDescriptor['links']> {\n return [\n { rel: 'preconnect', href: 'https://api.salla.dev' },\n { rel: 'preconnect', href: 'https://cdn.salla.sa' },\n { rel: 'preconnect', href: 'https://cdn.assets.salla.network', crossOrigin: 'anonymous' },\n // Warm the installed apps' CDN snippet host(s) — see snippetPreconnectOrigins.\n // Not on the maintenance page: it renders neither the snippets nor the SDK.\n ...(p.maintenance ? [] : p.snippetPreconnects),\n ...(p.isGoogleFont\n ? [\n {\n rel: 'preconnect' as const,\n href: 'https://fonts.gstatic.com',\n crossOrigin: 'anonymous' as const,\n },\n ]\n : []),\n ...(p.maintenance ? [] : [{ rel: 'modulepreload' as const, href: p.twilightSdkUrl }]),\n ...(p.fontUrlWithDisplay\n ? [\n {\n id: 'salla-theme-font',\n rel: 'stylesheet',\n href: p.fontUrlWithDisplay,\n media: 'print',\n },\n ]\n : []),\n ...(p.fontUrlWithDisplay && !p.isGoogleFont && p.fontFamilyName\n ? [\n {\n id: 'salla-font-display-override',\n rel: 'preload',\n as: 'style',\n href: p.fontUrlWithDisplay,\n },\n ]\n : []),\n ...(p.favicon ? [{ rel: 'icon', href: p.favicon }] : []),\n ...(p.favicon\n ? [{ id: 'salla-apple-icon', rel: 'apple-touch-icon-precomposed', href: p.favicon }]\n : []),\n ...(p.isCustomCssUrl && p.customCss\n ? [{ id: 'salla-custom-css', rel: 'stylesheet', href: p.customCss }]\n : []),\n {\n id: 'salla-icons-css',\n rel: 'stylesheet',\n href: SALLA_ICONS_CSS_URL,\n media: 'print',\n },\n // {\n // id: 'intl-tel-input-css',\n // rel: 'stylesheet',\n // href: 'https://cdn.jsdelivr.net/npm/intl-tel-input@26.8.0/build/css/intlTelInput.css',\n // },\n ...(p.isCustomJsUrl && p.customJs\n ? [{ id: 'salla-custom-js-preload', rel: 'preload', as: 'script', href: p.customJs }]\n : []),\n ];\n}\n\n// Hoistable (href + precedence): the web components insert their own <style> near the top of\n// <head> before hydration, which a positionally hydrated <style> would be matched against.\nconst hoisted = (id: string, children: string) => ({\n id,\n href: id,\n precedence: 'default',\n children,\n});\n\nfunction buildRootStyles(p: RootHeadParts): NonNullable<HeadDescriptor['styles']> {\n return [\n hoisted('twilight-loading', LOADING_CSS),\n ...(!p.isGoogleFont && p.fontFamilyName\n ? [\n hoisted(\n 'salla-font-display-swap',\n `@font-face{font-family:\"${p.fontFamilyName}\";font-display:swap;src:local(\"${p.fontFamilyName}\")}`\n ),\n ]\n : []),\n ...(!p.isCustomCssUrl && p.customCss ? [hoisted('salla-custom-css', p.customCss)] : []),\n ];\n}\n\nfunction buildRootScripts(p: RootHeadParts): NonNullable<HeadDescriptor['scripts']> {\n return [\n // First: the API base / store identifier this render used, so the hydrated client\n // resolves the same ones (worker `vars` never reach the browser bundle on their own).\n ...(p.runtimeEnvScript ? [{ id: 'salla-runtime-env', children: p.runtimeEnvScript }] : []),\n { id: 'twilight-init', children: SALLA_INIT_SCRIPT },\n // After twilight-init (which defines window.Salla) and before the SDK module, so the\n // appScope factory exists ahead of any snippet's onReady callback firing.\n { id: 'salla-app-scope', children: p.appScopeInstallScript },\n // Arms the hook-slot whitelist push here, so its `twilight::initiated` listener is\n // registered before any app snippet's — listeners fire in registration order.\n ...(p.themeHookSlotsScript\n ? [{ id: 'salla-theme-hook-slots', children: p.themeHookSlotsScript }]\n : []),\n { id: 'salla-async-css', children: MEDIA_SWAP_SCRIPT },\n // The SDK and ticketing modules are rendered at the end of <body> (SallaSdkScripts).\n ...(p.customJs ? [buildCustomJsScript(p.customJs, Boolean(p.isCustomJsUrl))] : []),\n ];\n}\n\n/** A URL customization is loaded after SDK init; an inline one is wrapped so a syntax/runtime\n * error in partner JS warns instead of taking the page down. */\nfunction buildCustomJsScript(customJs: string, isUrl: boolean) {\n return {\n id: 'salla-custom-js',\n children: isUrl\n ? `window.addEventListener('twilight::initiated',function(){var s=document.createElement('script');s.src=${escapeForInlineScript(JSON.stringify(customJs))};s.async=true;document.head.appendChild(s)},{once:true});`\n : `try { ${customJs} } catch(e) { console.warn(\"[ThemeCustomization] Custom JS error:\", e); }`,\n };\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { MadeWithSalla } from './chunk-OQIIJRAS.js';
2
2
  import { HookSlot, useIsClient } from './chunk-5XDPAKF5.js';
3
3
  import { useTranslation } from './chunk-TYNZ5B2B.js';
4
- import { Image } from './chunk-CVBRA2LE.js';
4
+ import { Image } from './chunk-5QYNHHPE.js';
5
5
  import { Link } from './chunk-AXW67SY7.js';
6
6
  import { LazyImageModal } from './chunk-7V5HOZW4.js';
7
7
  import { useTwilight } from './chunk-DF6FBKDN.js';
@@ -281,5 +281,5 @@ function Footer({ inSheet = false } = {}) {
281
281
  }
282
282
 
283
283
  export { Footer };
284
- //# sourceMappingURL=chunk-4FUSNRFO.js.map
285
- //# sourceMappingURL=chunk-4FUSNRFO.js.map
284
+ //# sourceMappingURL=chunk-FIDNPYLL.js.map
285
+ //# sourceMappingURL=chunk-FIDNPYLL.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/layout/Footer.tsx"],"names":[],"mappings":"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","file":"chunk-4FUSNRFO.js","sourcesContent":["import { useState } from 'react';\nimport { SallaAppsIcons } from '@salla.sa/twilight-components-react/apps-icons';\nimport { SallaContacts } from '@salla.sa/twilight-components-react/contacts';\nimport { SallaSocial } from '@salla.sa/twilight-components-react/social';\nimport { SallaMenu } from '@salla.sa/twilight-components-react/menu';\nimport { SallaTrustBadges } from '@salla.sa/twilight-components-react/trust-badges';\nimport { SallaPayments } from '@salla.sa/twilight-components-react/payments';\nimport { useTwilight } from '../../providers/twilight-context';\nimport { useTranslation } from '../../providers/I18nProvider';\nimport { HookSlot } from '../../hooks/HookSlot';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport { Link, Image } from '../common';\nimport { ImageModal } from '../modal';\nimport { MadeWithSalla } from './MadeWithSalla';\n\n/** Salla's value-added-tax badge icon (70×70, CDN-resized) — a platform\n * asset shared by every store, not specific to any one theme. */\nconst TAX_ICON_URL =\n 'https://cdn.salla.network/cdn-cgi/image/fit=scale-down,width=70,height=70,onerror=redirect,format=auto/images/tax.png?v=2.0.5';\n\n/**\n * The store's value-added-tax registration: the tax number, plus the certificate as\n * the tax icon that opens the certificate image full size in a modal. Nothing shows\n * when the store has no tax number.\n */\nfunction FooterTax({ dark }: { dark: boolean }) {\n const { store } = useTwilight();\n const { t } = useTranslation();\n const [open, setOpen] = useState(false);\n const number = store.settings?.tax?.number;\n const certificate = store.settings?.tax?.certificate;\n if (!number) return null;\n\n return (\n <div\n data-testid=\"store-footer-tax\"\n className=\"store-footer__tax flex items-end gap-2 rtl:space-x-reverse\"\n >\n {certificate && (\n <>\n <button\n type=\"button\"\n data-testid=\"store-footer-tax-certificate\"\n className=\"store-footer__tax-cert shrink-0\"\n aria-label={t('common.elements.tax_certificate', 'Tax Certificate')}\n aria-haspopup=\"dialog\"\n onClick={() => setOpen(true)}\n >\n <img\n src={TAX_ICON_URL}\n alt={t('common.elements.tax_certificate', 'Tax Certificate')}\n width={40}\n height={50}\n loading=\"lazy\"\n decoding=\"async\"\n className=\"w-10 rounded-sm transition-opacity hover:opacity-80\"\n />\n </button>\n <ImageModal\n isOpen={open}\n onClose={() => setOpen(false)}\n src={certificate}\n alt={t('common.elements.tax_certificate', 'Tax Certificate')}\n title={t('common.elements.tax_certificate', 'Tax Certificate')}\n />\n </>\n )}\n <div>\n <p className={`mb-1 text-sm opacity-70 ${dark ? 'text-white' : ''}`}>\n {t('common.elements.tax_number', 'Tax Number')}\n </p>\n <b className=\"text-sm\">{number}</b>\n </div>\n </div>\n );\n}\n\n/** Saudi Business Center (SBC) logo, CDN-versioned like the tax icon -- also a\n * platform asset, not theme-specific. */\nconst SBC_ICON_URL = 'https://cdn.salla.network/images/sbc.png?v=2.0.5';\n\n/**\n * The store's Saudi Business Center certificate: a \"Trusted by Business Platform\" badge that\n * opens the certificate's page on the SBC site so visitors can verify the merchant. Nothing\n * shows when the store has no certificate.\n */\nfunction FooterSbc({ dark }: { dark: boolean }) {\n const { store } = useTwilight();\n const { t } = useTranslation();\n const id = store.settings?.certificate?.id;\n if (!id) return null;\n\n return (\n <a\n href={`https://eauthenticate.saudibusiness.gov.sa/certificate-details/${encodeURIComponent(id)}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-testid=\"store-footer-sbc\"\n className=\"store-footer__sbc flex items-center gap-2.5 transition-opacity hover:opacity-75\"\n >\n <img\n src={SBC_ICON_URL}\n alt={`SBC ${id}`}\n width={56}\n height={40}\n loading=\"lazy\"\n decoding=\"async\"\n className=\"h-10 w-14 rounded-sm\"\n />\n <div>\n <p className={`text-xs opacity-70 ${dark ? 'text-white' : ''}`}>\n {t('blocks.footer.sbc_trusted_by', 'Trusted by')}\n </p>\n <b className=\"text-sm\">{t('blocks.footer.sbc_platform', 'Business Platform')}</b>\n </div>\n </a>\n );\n}\n\n/** Trust badges, the tax registration and the SBC badge, side by side (wrapping on narrow columns). */\nfunction FooterTrust({ dark, centered }: { dark: boolean; centered: boolean }) {\n return (\n <div\n data-testid=\"store-footer-trust\"\n className={`store-footer__trust flex flex-wrap items-end gap-x-6 gap-y-3${centered ? ' justify-center' : ''}`}\n >\n <FooterTax dark={dark} />\n <FooterSbc dark={dark} />\n <SallaTrustBadges {...(dark ? { dark: true } : {})} />\n </div>\n );\n}\n\n/**\n * The footer's own menu of (\"important\") links -- skipped entirely when\n * `inSheet`, for a theme that opens it from somewhere else of its own (a\n * mobile account sheet, a dedicated links screen, …) instead; showing it\n * again down here would just be a redundant second copy. `heading` wraps it\n * in the grid layout's own `.store-footer__links` column; the centered\n * layout's inline row has none.\n */\nfunction FooterLinksMenu({\n inSheet,\n className,\n heading,\n dark,\n}: {\n inSheet: boolean;\n className: string;\n heading?: string;\n dark: boolean;\n}) {\n if (inSheet) return null;\n\n const menu = <SallaMenu source=\"footer\" className={className} suppressHydrationWarning />;\n if (!heading) return menu;\n\n return (\n <div className=\"store-footer__links\">\n <h3 className={`mb-3 text-lg font-bold lg:mb-5 ${dark ? 'text-white' : 'text-gray-900'}`}>\n {heading}\n </h3>\n {menu}\n </div>\n );\n}\n\n/** App-store / Google-Play buttons. Nothing shows -- not even the wrapping\n * div -- when the store has neither link set. */\nfunction FooterApps({ className }: { className: string }) {\n const { store } = useTwilight();\n const { t } = useTranslation();\n // The web component fills its light DOM before React hydrates the footer, a hydration error.\n const isClient = useIsClient();\n if (!store.apps?.appstore && !store.apps?.googleplay) return null;\n\n return (\n <div data-testid=\"store-footer-apps\" className={`store-footer__apps ${className}`}>\n {isClient && (\n <SallaAppsIcons\n apps={store.apps}\n appsTitle={t('blocks.footer.download_apps', 'Get our apps')}\n />\n )}\n </div>\n );\n}\n\n/** The logo link, same shape in both layouts -- only its own spacing differs. */\nfunction FooterLogo({ className }: { className: string }) {\n const { store } = useTwilight();\n return (\n <Link\n to=\"/\"\n className={`store-footer__logo inline-flex items-center m-0 transition-opacity hover:opacity-75 ${className}`}\n >\n <Image\n src={store.logo}\n alt={store.name || 'Store'}\n width={150}\n height={44}\n objectFit=\"contain\"\n className=\"h-11 w-auto max-w-[180px]\"\n />\n </Link>\n );\n}\n\n/** Merchant-authored description HTML -- mirrors the Twig theme's\n * `store.description|raw`. Renders nothing when the store has none set. */\nfunction FooterDescription({ className }: { className: string }) {\n const { store } = useTwilight();\n if (!store.description) return null;\n return (\n <div\n className={`store-footer__desc opacity-80 ${className}`}\n dangerouslySetInnerHTML={{ __html: store.description }}\n />\n );\n}\n\n/** The store's phone and email as one \"Contact us: …\" row under the description\n * (`<salla-contacts>`'s compact `isHeader` layout, which shows only those two).\n * Renders nothing when the store has neither. */\nfunction FooterContacts({ className }: { className: string }) {\n const { store } = useTwilight();\n const { t } = useTranslation();\n // The web component fills its light DOM once the SDK is ready, which can come before\n // React hydrates the footer's Suspense boundary: a hydration error (React #418).\n const isClient = useIsClient();\n if (!store.contacts?.phone && !store.contacts?.email) return null;\n return (\n <div className={`store-footer__contacts ${className}`}>\n {isClient && (\n <SallaContacts\n contacts={store.contacts}\n contactsTitle={t('blocks.footer.social', 'Contact us')}\n isHeader\n />\n )}\n </div>\n );\n}\n\n/** Centered layout: logo, description, contacts, social, footer menu, trust\n * badges and app buttons stacked as one centered column. */\nfunction FooterCenteredBody({ inSheet, isDark }: { inSheet: boolean; isDark: boolean }) {\n return (\n <div className=\"container mx-auto flex max-w-2xl flex-col items-center gap-6 text-center\">\n <FooterLogo className=\"\" />\n <FooterDescription className=\"\" />\n <FooterContacts className=\"\" />\n <SallaSocial />\n\n <FooterLinksMenu\n inSheet={inSheet}\n className=\"store-footer__menu store-footer__menu--inline\"\n dark={isDark}\n />\n\n <FooterTrust dark={isDark} centered />\n\n <FooterApps className=\"flex flex-col items-center gap-3\" />\n </div>\n );\n}\n\n/** Columns layout: brand (logo / description / contacts / social / trust) and app\n * buttons side by side, with the footer menu as its own labeled column. */\nfunction FooterColumnsBody({ inSheet, isDark }: { inSheet: boolean; isDark: boolean }) {\n const { t } = useTranslation();\n\n return (\n <div className=\"container grid grid-cols-1 gap-10 sm:grid-cols-2 lg:grid-cols-4 lg:gap-16\">\n <div className=\"store-footer__brand rtl:lg:pl-16 ltr:lg:pr-16 sm:col-span-2\">\n <FooterLogo className=\"mb-5\" />\n <FooterDescription className=\"max-w-sm leading-6 my-5\" />\n <FooterContacts className=\"mb-6\" />\n <SallaSocial className=\"block mb-6\" />\n <FooterTrust dark={isDark} centered={false} />\n </div>\n\n <FooterLinksMenu\n inSheet={inSheet}\n className=\"store-footer__menu store-footer__menu--stacked\"\n heading={t('blocks.footer.important_links', 'Important links')}\n dark={isDark}\n />\n\n <FooterApps className=\"\" />\n </div>\n );\n}\n\nexport interface FooterProps {\n /**\n * Renders as a plain `<div>` (no second `<footer>` landmark) with the\n * `footer:start` / `footer:end` hook slots skipped -- for a theme that\n * repeats these widgets somewhere other than the page's own footer (a\n * mobile sheet, for example) rather than rendering the real page footer a\n * second time.\n */\n inSheet?: boolean;\n}\n\n/**\n * Storefront footer.\n *\n * Two layouts, chosen by the `footer_layout` theme setting:\n * - **columns** (default): logo / description / social / trust badges, the\n * footer menu (\"important links\"), and app-store buttons, side by side.\n * - **centered**: the same pieces stacked as one centered column, with the\n * footer menu laid out as an inline, pipe-separated row.\n *\n * Styling for the handful of pieces rendered by web components this owns no\n * markup for (`<salla-social>`'s `.social-link` icons, `<salla-menu>`'s\n * `.s-menu-footer-item` rows, `<salla-payments>`'s `.s-payments-list-item`\n * icons) is the consuming theme's own responsibility, the same way\n * `inSheet`'s own presentation is -- this component owns structure and data,\n * not every pixel.\n */\nexport function Footer({ inSheet = false }: FooterProps = {}) {\n const { store, theme } = useTwilight();\n const { t } = useTranslation();\n const year = new Date().getFullYear();\n const isCentered = theme.settings?.footer_layout === 'centered';\n const isDark = !!theme.settings?.footer_is_dark;\n\n const Root = inSheet ? 'div' : 'footer';\n\n return (\n <Root\n className={`store-footer store-footer--${isCentered ? 'centered' : 'columns'}${\n inSheet ? ' store-footer--sheet' : ''\n } relative mt-8 sm:mt-16 ${isDark ? 'bg-[#0E0F0F] text-white' : 'bg-[#F4F7F2] text-gray-600'}`}\n suppressHydrationWarning\n >\n {!inSheet && <HookSlot name=\"footer:start\" />}\n\n <div\n aria-label=\"footer\"\n className={`store-footer__inner border-b py-8 lg:py-16 ${\n isDark ? 'bg-[#1D1F1F] border-dashed border-white/10' : 'bg-transparent border-gray-200'\n }`}\n >\n {isCentered ? (\n <FooterCenteredBody inSheet={inSheet} isDark={isDark} />\n ) : (\n <FooterColumnsBody inSheet={inSheet} isDark={isDark} />\n )}\n </div>\n\n <div className=\"store-footer__bottom container md:flex items-center justify-between gap-4 py-4 lg:py-7 text-center\">\n <span className={`text-sm copyright-text ${isDark ? 'text-gray-400' : 'text-gray-700'}`}>\n <HookSlot\n name=\"copyright\"\n context={{ storeName: store.name }}\n fallback={\n <>\n {t('blocks.footer.copyright', 'All rights reserved')}{' '}\n <Link to=\"/\" className=\"transition-opacity hover:opacity-75 hover:text-primary\">\n {store.name}\n </Link>{' '}\n © {year}\n <MadeWithSalla className=\"ms-2\" />\n </>\n }\n />\n </span>\n\n <SallaPayments />\n </div>\n\n {!inSheet && <HookSlot name=\"footer:end\" />}\n </Root>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/components/layout/Footer.tsx"],"names":[],"mappings":"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","file":"chunk-FIDNPYLL.js","sourcesContent":["import { useState } from 'react';\nimport { SallaAppsIcons } from '@salla.sa/twilight-components-react/apps-icons';\nimport { SallaContacts } from '@salla.sa/twilight-components-react/contacts';\nimport { SallaSocial } from '@salla.sa/twilight-components-react/social';\nimport { SallaMenu } from '@salla.sa/twilight-components-react/menu';\nimport { SallaTrustBadges } from '@salla.sa/twilight-components-react/trust-badges';\nimport { SallaPayments } from '@salla.sa/twilight-components-react/payments';\nimport { useTwilight } from '../../providers/twilight-context';\nimport { useTranslation } from '../../providers/I18nProvider';\nimport { HookSlot } from '../../hooks/HookSlot';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport { Link, Image } from '../common';\nimport { ImageModal } from '../modal';\nimport { MadeWithSalla } from './MadeWithSalla';\n\n/** Salla's value-added-tax badge icon (70×70, CDN-resized) — a platform\n * asset shared by every store, not specific to any one theme. */\nconst TAX_ICON_URL =\n 'https://cdn.salla.network/cdn-cgi/image/fit=scale-down,width=70,height=70,onerror=redirect,format=auto/images/tax.png?v=2.0.5';\n\n/**\n * The store's value-added-tax registration: the tax number, plus the certificate as\n * the tax icon that opens the certificate image full size in a modal. Nothing shows\n * when the store has no tax number.\n */\nfunction FooterTax({ dark }: { dark: boolean }) {\n const { store } = useTwilight();\n const { t } = useTranslation();\n const [open, setOpen] = useState(false);\n const number = store.settings?.tax?.number;\n const certificate = store.settings?.tax?.certificate;\n if (!number) return null;\n\n return (\n <div\n data-testid=\"store-footer-tax\"\n className=\"store-footer__tax flex items-end gap-2 rtl:space-x-reverse\"\n >\n {certificate && (\n <>\n <button\n type=\"button\"\n data-testid=\"store-footer-tax-certificate\"\n className=\"store-footer__tax-cert shrink-0\"\n aria-label={t('common.elements.tax_certificate', 'Tax Certificate')}\n aria-haspopup=\"dialog\"\n onClick={() => setOpen(true)}\n >\n <img\n src={TAX_ICON_URL}\n alt={t('common.elements.tax_certificate', 'Tax Certificate')}\n width={40}\n height={50}\n loading=\"lazy\"\n decoding=\"async\"\n className=\"w-10 rounded-sm transition-opacity hover:opacity-80\"\n />\n </button>\n <ImageModal\n isOpen={open}\n onClose={() => setOpen(false)}\n src={certificate}\n alt={t('common.elements.tax_certificate', 'Tax Certificate')}\n title={t('common.elements.tax_certificate', 'Tax Certificate')}\n />\n </>\n )}\n <div>\n <p className={`mb-1 text-sm opacity-70 ${dark ? 'text-white' : ''}`}>\n {t('common.elements.tax_number', 'Tax Number')}\n </p>\n <b className=\"text-sm\">{number}</b>\n </div>\n </div>\n );\n}\n\n/** Saudi Business Center (SBC) logo, CDN-versioned like the tax icon -- also a\n * platform asset, not theme-specific. */\nconst SBC_ICON_URL = 'https://cdn.salla.network/images/sbc.png?v=2.0.5';\n\n/**\n * The store's Saudi Business Center certificate: a \"Trusted by Business Platform\" badge that\n * opens the certificate's page on the SBC site so visitors can verify the merchant. Nothing\n * shows when the store has no certificate.\n */\nfunction FooterSbc({ dark }: { dark: boolean }) {\n const { store } = useTwilight();\n const { t } = useTranslation();\n const id = store.settings?.certificate?.id;\n if (!id) return null;\n\n return (\n <a\n href={`https://eauthenticate.saudibusiness.gov.sa/certificate-details/${encodeURIComponent(id)}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-testid=\"store-footer-sbc\"\n className=\"store-footer__sbc flex items-center gap-2.5 transition-opacity hover:opacity-75\"\n >\n <img\n src={SBC_ICON_URL}\n alt={`SBC ${id}`}\n width={56}\n height={40}\n loading=\"lazy\"\n decoding=\"async\"\n className=\"h-10 w-14 rounded-sm\"\n />\n <div>\n <p className={`text-xs opacity-70 ${dark ? 'text-white' : ''}`}>\n {t('blocks.footer.sbc_trusted_by', 'Trusted by')}\n </p>\n <b className=\"text-sm\">{t('blocks.footer.sbc_platform', 'Business Platform')}</b>\n </div>\n </a>\n );\n}\n\n/** Trust badges, the tax registration and the SBC badge, side by side (wrapping on narrow columns). */\nfunction FooterTrust({ dark, centered }: { dark: boolean; centered: boolean }) {\n return (\n <div\n data-testid=\"store-footer-trust\"\n className={`store-footer__trust flex flex-wrap items-end gap-x-6 gap-y-3${centered ? ' justify-center' : ''}`}\n >\n <FooterTax dark={dark} />\n <FooterSbc dark={dark} />\n <SallaTrustBadges {...(dark ? { dark: true } : {})} />\n </div>\n );\n}\n\n/**\n * The footer's own menu of (\"important\") links -- skipped entirely when\n * `inSheet`, for a theme that opens it from somewhere else of its own (a\n * mobile account sheet, a dedicated links screen, …) instead; showing it\n * again down here would just be a redundant second copy. `heading` wraps it\n * in the grid layout's own `.store-footer__links` column; the centered\n * layout's inline row has none.\n */\nfunction FooterLinksMenu({\n inSheet,\n className,\n heading,\n dark,\n}: {\n inSheet: boolean;\n className: string;\n heading?: string;\n dark: boolean;\n}) {\n if (inSheet) return null;\n\n const menu = <SallaMenu source=\"footer\" className={className} suppressHydrationWarning />;\n if (!heading) return menu;\n\n return (\n <div className=\"store-footer__links\">\n <h3 className={`mb-3 text-lg font-bold lg:mb-5 ${dark ? 'text-white' : 'text-gray-900'}`}>\n {heading}\n </h3>\n {menu}\n </div>\n );\n}\n\n/** App-store / Google-Play buttons. Nothing shows -- not even the wrapping\n * div -- when the store has neither link set. */\nfunction FooterApps({ className }: { className: string }) {\n const { store } = useTwilight();\n const { t } = useTranslation();\n // The web component fills its light DOM before React hydrates the footer, a hydration error.\n const isClient = useIsClient();\n if (!store.apps?.appstore && !store.apps?.googleplay) return null;\n\n return (\n <div data-testid=\"store-footer-apps\" className={`store-footer__apps ${className}`}>\n {isClient && (\n <SallaAppsIcons\n apps={store.apps}\n appsTitle={t('blocks.footer.download_apps', 'Get our apps')}\n />\n )}\n </div>\n );\n}\n\n/** The logo link, same shape in both layouts -- only its own spacing differs. */\nfunction FooterLogo({ className }: { className: string }) {\n const { store } = useTwilight();\n return (\n <Link\n to=\"/\"\n className={`store-footer__logo inline-flex items-center m-0 transition-opacity hover:opacity-75 ${className}`}\n >\n <Image\n src={store.logo}\n alt={store.name || 'Store'}\n width={150}\n height={44}\n objectFit=\"contain\"\n className=\"h-11 w-auto max-w-[180px]\"\n />\n </Link>\n );\n}\n\n/** Merchant-authored description HTML -- mirrors the Twig theme's\n * `store.description|raw`. Renders nothing when the store has none set. */\nfunction FooterDescription({ className }: { className: string }) {\n const { store } = useTwilight();\n if (!store.description) return null;\n return (\n <div\n className={`store-footer__desc opacity-80 ${className}`}\n dangerouslySetInnerHTML={{ __html: store.description }}\n />\n );\n}\n\n/** The store's phone and email as one \"Contact us: …\" row under the description\n * (`<salla-contacts>`'s compact `isHeader` layout, which shows only those two).\n * Renders nothing when the store has neither. */\nfunction FooterContacts({ className }: { className: string }) {\n const { store } = useTwilight();\n const { t } = useTranslation();\n // The web component fills its light DOM once the SDK is ready, which can come before\n // React hydrates the footer's Suspense boundary: a hydration error (React #418).\n const isClient = useIsClient();\n if (!store.contacts?.phone && !store.contacts?.email) return null;\n return (\n <div className={`store-footer__contacts ${className}`}>\n {isClient && (\n <SallaContacts\n contacts={store.contacts}\n contactsTitle={t('blocks.footer.social', 'Contact us')}\n isHeader\n />\n )}\n </div>\n );\n}\n\n/** Centered layout: logo, description, contacts, social, footer menu, trust\n * badges and app buttons stacked as one centered column. */\nfunction FooterCenteredBody({ inSheet, isDark }: { inSheet: boolean; isDark: boolean }) {\n return (\n <div className=\"container mx-auto flex max-w-2xl flex-col items-center gap-6 text-center\">\n <FooterLogo className=\"\" />\n <FooterDescription className=\"\" />\n <FooterContacts className=\"\" />\n <SallaSocial />\n\n <FooterLinksMenu\n inSheet={inSheet}\n className=\"store-footer__menu store-footer__menu--inline\"\n dark={isDark}\n />\n\n <FooterTrust dark={isDark} centered />\n\n <FooterApps className=\"flex flex-col items-center gap-3\" />\n </div>\n );\n}\n\n/** Columns layout: brand (logo / description / contacts / social / trust) and app\n * buttons side by side, with the footer menu as its own labeled column. */\nfunction FooterColumnsBody({ inSheet, isDark }: { inSheet: boolean; isDark: boolean }) {\n const { t } = useTranslation();\n\n return (\n <div className=\"container grid grid-cols-1 gap-10 sm:grid-cols-2 lg:grid-cols-4 lg:gap-16\">\n <div className=\"store-footer__brand rtl:lg:pl-16 ltr:lg:pr-16 sm:col-span-2\">\n <FooterLogo className=\"mb-5\" />\n <FooterDescription className=\"max-w-sm leading-6 my-5\" />\n <FooterContacts className=\"mb-6\" />\n <SallaSocial className=\"block mb-6\" />\n <FooterTrust dark={isDark} centered={false} />\n </div>\n\n <FooterLinksMenu\n inSheet={inSheet}\n className=\"store-footer__menu store-footer__menu--stacked\"\n heading={t('blocks.footer.important_links', 'Important links')}\n dark={isDark}\n />\n\n <FooterApps className=\"\" />\n </div>\n );\n}\n\nexport interface FooterProps {\n /**\n * Renders as a plain `<div>` (no second `<footer>` landmark) with the\n * `footer:start` / `footer:end` hook slots skipped -- for a theme that\n * repeats these widgets somewhere other than the page's own footer (a\n * mobile sheet, for example) rather than rendering the real page footer a\n * second time.\n */\n inSheet?: boolean;\n}\n\n/**\n * Storefront footer.\n *\n * Two layouts, chosen by the `footer_layout` theme setting:\n * - **columns** (default): logo / description / social / trust badges, the\n * footer menu (\"important links\"), and app-store buttons, side by side.\n * - **centered**: the same pieces stacked as one centered column, with the\n * footer menu laid out as an inline, pipe-separated row.\n *\n * Styling for the handful of pieces rendered by web components this owns no\n * markup for (`<salla-social>`'s `.social-link` icons, `<salla-menu>`'s\n * `.s-menu-footer-item` rows, `<salla-payments>`'s `.s-payments-list-item`\n * icons) is the consuming theme's own responsibility, the same way\n * `inSheet`'s own presentation is -- this component owns structure and data,\n * not every pixel.\n */\nexport function Footer({ inSheet = false }: FooterProps = {}) {\n const { store, theme } = useTwilight();\n const { t } = useTranslation();\n const year = new Date().getFullYear();\n const isCentered = theme.settings?.footer_layout === 'centered';\n const isDark = !!theme.settings?.footer_is_dark;\n\n const Root = inSheet ? 'div' : 'footer';\n\n return (\n <Root\n className={`store-footer store-footer--${isCentered ? 'centered' : 'columns'}${\n inSheet ? ' store-footer--sheet' : ''\n } relative mt-8 sm:mt-16 ${isDark ? 'bg-[#0E0F0F] text-white' : 'bg-[#F4F7F2] text-gray-600'}`}\n suppressHydrationWarning\n >\n {!inSheet && <HookSlot name=\"footer:start\" />}\n\n <div\n aria-label=\"footer\"\n className={`store-footer__inner border-b py-8 lg:py-16 ${\n isDark ? 'bg-[#1D1F1F] border-dashed border-white/10' : 'bg-transparent border-gray-200'\n }`}\n >\n {isCentered ? (\n <FooterCenteredBody inSheet={inSheet} isDark={isDark} />\n ) : (\n <FooterColumnsBody inSheet={inSheet} isDark={isDark} />\n )}\n </div>\n\n <div className=\"store-footer__bottom container md:flex items-center justify-between gap-4 py-4 lg:py-7 text-center\">\n <span className={`text-sm copyright-text ${isDark ? 'text-gray-400' : 'text-gray-700'}`}>\n <HookSlot\n name=\"copyright\"\n context={{ storeName: store.name }}\n fallback={\n <>\n {t('blocks.footer.copyright', 'All rights reserved')}{' '}\n <Link to=\"/\" className=\"transition-opacity hover:opacity-75 hover:text-primary\">\n {store.name}\n </Link>{' '}\n © {year}\n <MadeWithSalla className=\"ms-2\" />\n </>\n }\n />\n </span>\n\n <SallaPayments />\n </div>\n\n {!inSheet && <HookSlot name=\"footer:end\" />}\n </Root>\n );\n}\n"]}
@@ -38,6 +38,21 @@ var DEFAULT_INCLUDE_ITEMS = [
38
38
  "ratings",
39
39
  "user"
40
40
  ];
41
+ var ANSWER_HEADERS = {
42
+ requestId: "s-request-id",
43
+ traceId: "x-trace-id",
44
+ cacheStatus: "cf-cache-status",
45
+ age: "age"
46
+ };
47
+ function settingsAnswerOf(headers) {
48
+ if (!headers) return void 0;
49
+ const answer = {};
50
+ for (const [field, name] of Object.entries(ANSWER_HEADERS)) {
51
+ const value = headers.get(name);
52
+ if (value) answer[field] = value;
53
+ }
54
+ return Object.keys(answer).length ? answer : void 0;
55
+ }
41
56
  function languagesToArray(languages) {
42
57
  if (!languages) return void 0;
43
58
  return Object.values(languages).map((lang) => ({ iso_code: lang.code, ...lang }));
@@ -67,10 +82,12 @@ async function requestSettings(identifier) {
67
82
  const includeParams = DEFAULT_INCLUDE_ITEMS.map((i) => `include[]=${i}`).join("&");
68
83
  const scope = getActiveScope();
69
84
  const params = scope != null ? `${includeParams}&scope=${scope.id}` : includeParams;
70
- const json = await api.get(`store/settings?${params}`, {
85
+ const request = api.get(`store/settings?${params}`, {
71
86
  timeout: SETTINGS_TIMEOUT_MS,
72
87
  headers: { [STORE_IDENTIFIER_HEADER]: identifier }
73
- }).json();
88
+ });
89
+ const json = await request.json();
90
+ const answer = settingsAnswerOf((await request)?.headers);
74
91
  const data = json?.data;
75
92
  if (!data) {
76
93
  throw new SettingsError(
@@ -94,7 +111,8 @@ async function requestSettings(identifier) {
94
111
  jitsu: withNativeAppHeaders(data.jitsu),
95
112
  maintenance: data.maintenance,
96
113
  maintenance_details: data.maintenance_details,
97
- ...scope && { requestedScopeId: scope.id }
114
+ ...scope && { requestedScopeId: scope.id },
115
+ ...answer && { answer }
98
116
  };
99
117
  }
100
118
  function apiErrorMessage(data) {
@@ -184,5 +202,5 @@ var store = {
184
202
  };
185
203
 
186
204
  export { readNativeAppHeaders, store };
187
- //# sourceMappingURL=chunk-LPCNDH4F.js.map
188
- //# sourceMappingURL=chunk-LPCNDH4F.js.map
205
+ //# sourceMappingURL=chunk-IRQJBRKV.js.map
206
+ //# sourceMappingURL=chunk-IRQJBRKV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/native-app-headers.ts","../src/api/store.ts"],"names":[],"mappings":"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","file":"chunk-IRQJBRKV.js","sourcesContent":["/** The headers the Salla native app sends with every page it loads in its webview. */\nexport const NATIVE_APP_HEADERS = [\n 's-app-os',\n 's-app-version',\n 's-app-full-version',\n 's-app-os-version',\n];\n\n/**\n * The native app's own headers on this request, or null when it is not the app.\n *\n * On a Twig theme Laravel copies them into the settings' `jitsu.context.extra.headers`,\n * where the SDK reads the app's platform and version from (`salla.config.isMobileApp()`).\n * A React theme asks for its settings from the server, through the API, so the app's\n * headers never reach that call: the request is the only place they are.\n */\nexport function readNativeAppHeaders(headers: Headers): Record<string, string> | null {\n const os = headers.get('s-app-os')?.toLowerCase();\n if (os !== 'ios' && os !== 'android') return null;\n const found: Record<string, string> = {};\n for (const name of NATIVE_APP_HEADERS) {\n const value = headers.get(name);\n if (value) found[name] = value;\n }\n return found;\n}\n","import { queryOptions } from '@tanstack/react-query';\nimport { isHTTPError, isNetworkError, isTimeoutError } from 'ky';\nimport { api, getActiveScope, STORE_IDENTIFIER_HEADER } from './client';\nimport { SettingsError } from '../utils/errors';\nimport type { Store, Theme, Language, JitsuConfig, MaintenanceDetails } from '../types';\nimport { getTwilightContext } from '../twilight/context';\nimport { resolveStoreIdentifier } from '../utils/store-identity';\nimport { parseStoreId } from '../utils/cookies';\nimport { requestedThemeVersionId } from '../utils/theme-version';\nimport { NATIVE_APP_HEADERS } from '../utils/native-app-headers';\n\nexport { resolveStoreIdentifier };\n\nconst DEFAULT_INCLUDE_ITEMS = [\n 'store',\n 'settings',\n 'theme',\n 'theme_settings',\n 'external_services',\n 'currencies',\n 'languages',\n 'payments',\n 'product_widgets',\n 'rating',\n 'ratings',\n 'user',\n];\n\n/** Twig's `salla.init({ user })` object; the endpoint ignores the token, so always the guest. */\nexport interface SettingsUser {\n type: 'guest' | 'user';\n id?: number | string | null;\n language_code?: string;\n currency_code?: string;\n country_code?: string;\n [key: string]: unknown;\n}\n\n/**\n * Raw API response for settings endpoint.\n * Languages come as object: { \"AR\": { code, name, ... }, \"EN\": {...} }\n */\ninterface SettingsApiResponse {\n store?: Store;\n theme?: Theme;\n languages?: Record<string, Language>;\n currencies?: Record<\n string,\n { code: string; name: string; symbol: string; amount: number; country_code: string }\n >;\n external_services?: Record<string, unknown>;\n headers?: Record<string, unknown>;\n login?: { url: string; turnstile_site_key: string };\n affiliate?: { utm_url: string; cta_enabled: boolean };\n debug?: boolean;\n trace_console?: boolean;\n policy_url?: string;\n user?: SettingsUser;\n swoole?: string[];\n jitsu?: JitsuConfig;\n maintenance?: boolean;\n maintenance_details?: MaintenanceDetails;\n}\n\n/**\n * Central settings context - single source of truth for all API data.\n * Contains everything from the settings endpoint response after processing.\n */\nexport interface StoreContext {\n store?: Store;\n theme?: Theme;\n /** Languages as array after conversion from API object format */\n languages?: Language[];\n currencies?: Record<\n string,\n { code: string; name: string; symbol: string; amount: number; country_code: string }\n >;\n external_services?: Record<string, unknown>;\n headers?: Record<string, unknown>;\n login?: { url: string; turnstile_site_key: string };\n affiliate?: { utm_url: string; cta_enabled: boolean };\n debug?: boolean;\n trace_console?: boolean; // todo:: remove it\n policy_url?: string;\n user?: SettingsUser;\n /** API paths the SDK sends with `s-store-api-version: swoole` */\n swoole?: string[];\n /** Where the SDK's analytics send events, and which ones; without it the SDK tracks nothing. */\n jitsu?: JitsuConfig;\n /**\n * The store is closed: by the merchant from the dashboard, by the platform, or\n * for the selected market only. The engine then renders the maintenance page\n * to everyone but the merchant; see `rootBeforeLoad`.\n */\n maintenance?: boolean;\n /** What the maintenance page says; sent beside `maintenance`. */\n maintenance_details?: MaintenanceDetails;\n /**\n * The scope these settings were requested with; absent when none was. Not from\n * the API: stamped by `store.settings`, so `resolveThemeVersionId` can tell\n * whether the version they name still answers the scope that is active now.\n */\n requestedScopeId?: string;\n /** Which answer of the API these settings are; see {@link SettingsAnswer}. */\n answer?: SettingsAnswer;\n}\n\n/**\n * Which answer of the settings API a set of settings came from, read off the\n * response rather than the body: the API's request id, the Store's trace, and\n * whether Cloudflare served it from its cache and how old it was. A decision the\n * settings drive for every visitor alike (the maintenance page) can then be\n * traced to the exact request the backend logged, or to a cached copy of it.\n */\nexport interface SettingsAnswer {\n requestId?: string;\n traceId?: string;\n cacheStatus?: string;\n age?: string;\n}\n\nconst ANSWER_HEADERS: Record<keyof SettingsAnswer, string> = {\n requestId: 's-request-id',\n traceId: 'x-trace-id',\n cacheStatus: 'cf-cache-status',\n age: 'age',\n};\n\nfunction settingsAnswerOf(headers: Headers | undefined): SettingsAnswer | undefined {\n if (!headers) return undefined;\n const answer: SettingsAnswer = {};\n for (const [field, name] of Object.entries(ANSWER_HEADERS) as [keyof SettingsAnswer, string][]) {\n const value = headers.get(name);\n if (value) answer[field] = value;\n }\n return Object.keys(answer).length ? answer : undefined;\n}\n\n/**\n * Converts languages object from API to array format.\n * API returns: { \"AR\": { code, name, ... }, \"EN\": { ... } }\n * We need: [{ code, name, ... }, { code, name, ... }]\n * todo:: return the languages as object from the APIs to avoid this\n */\nfunction languagesToArray(languages?: Record<string, Language>): Language[] | undefined {\n if (!languages) return undefined;\n // The SDK's localization modal reads `lang.iso_code` (not `code`) when a language is\n // selected — without it the switch navigates to `/undefined/...`.\n return Object.values(languages).map((lang) => ({ iso_code: lang.code, ...lang }));\n}\n\n/**\n * The settings' analytics context with the native app's headers in it, as Laravel\n * writes it for a Twig theme: the SDK reads the app's platform and version from there.\n * The API answers a server-side call with the engine's own headers, never the app's.\n */\nfunction withNativeAppHeaders(jitsu?: JitsuConfig): JitsuConfig | undefined {\n if (!jitsu || typeof window !== 'undefined') return jitsu;\n let appHeaders: Record<string, string> | null = null;\n try {\n appHeaders = getTwilightContext().nativeAppHeaders;\n } catch {\n return jitsu;\n }\n if (!appHeaders) return jitsu;\n const extra = jitsu.context?.extra;\n // The engine's own app headers go, so an app that sends no version doesn't get the engine's.\n const headers = { ...extra?.headers };\n for (const name of NATIVE_APP_HEADERS) delete headers[name];\n return {\n ...jitsu,\n context: {\n ...jitsu.context,\n extra: { ...extra, headers: { ...headers, ...appHeaders } },\n },\n };\n}\n\nconst SETTINGS_TIMEOUT_MS = 5000;\n\nasync function requestSettings(identifier: string): Promise<StoreContext> {\n const includeParams = DEFAULT_INCLUDE_ITEMS.map((i) => `include[]=${i}`).join('&');\n const scope = getActiveScope();\n const params = scope != null ? `${includeParams}&scope=${scope.id}` : includeParams;\n\n const request = api\n // Sent explicitly rather than left to the client's own resolution, so\n // the identifier this function checked is the identifier that travels.\n // They agree today; a caller passing one and being answered about\n // another is the failure this makes impossible rather than unlikely.\n .get(`store/settings?${params}`, {\n timeout: SETTINGS_TIMEOUT_MS,\n headers: { [STORE_IDENTIFIER_HEADER]: identifier },\n });\n const json = await request.json<{ data?: SettingsApiResponse }>();\n // The same response, already settled; only its headers are read.\n const answer = settingsAnswerOf((await request)?.headers);\n\n const data = json?.data;\n if (!data) {\n throw new SettingsError(\n `The Salla API answered the settings request for store \"${identifier}\" without settings.`,\n { reason: 'empty' }\n );\n }\n\n // Convert languages from object to array\n const languages = languagesToArray(data.languages);\n\n return {\n store: data.store,\n theme: data.theme,\n languages,\n currencies: data.currencies,\n external_services: data.external_services,\n headers: data.headers,\n login: data.login,\n affiliate: data.affiliate,\n policy_url: data.policy_url,\n user: data.user,\n swoole: data.swoole,\n jitsu: withNativeAppHeaders(data.jitsu),\n maintenance: data.maintenance,\n maintenance_details: data.maintenance_details,\n ...(scope && { requestedScopeId: scope.id }),\n ...(answer && { answer }),\n };\n}\n\n/** The message the API put in an error body, `{ error: { message } }`, when it sent one. */\nfunction apiErrorMessage(data: unknown): string | undefined {\n const message = (data as { error?: { message?: unknown } } | undefined)?.error?.message;\n return typeof message === 'string' && message.length > 0 && message.length <= 200\n ? message\n : undefined;\n}\n\n/**\n * What core's `CurrentStoreMiddleware` answers, with a 422, when no store has the\n * username or domain it was given (or the store's status is `deleted`). The lookup is\n * `loadUseUsernameOrDomain`, the same one Twig's `checkUsername` turns into its 410.\n * The literal is not translated: it reads the same whatever language was asked for.\n */\nconst STORE_NOT_FOUND_MESSAGE = 'المتجر غير موجود';\n\n/**\n * Whether the API answered that no store has this identifier. A numeric identifier\n * is looked up with `findOrFail`, which Store's exception handler answers with a 410;\n * a username or domain gets {@link STORE_NOT_FOUND_MESSAGE}. A 410 for a username is\n * not read as one: nothing on that path answers it, and a store that does exist must\n * never be told it does not.\n */\nfunction isStoreNotFound(identifier: string, status: number, said: string | undefined): boolean {\n if (status === 410) return parseStoreId(identifier) !== null;\n return status === 422 && said === STORE_NOT_FOUND_MESSAGE;\n}\n\n/**\n * Names what went wrong, because the page, the server log and Sentry all carry\n * this message. Every failure used to read \"Make sure VITE_STORE_DOMAIN is set\",\n * a local-development variable no deployed theme has, so a slow API looked like\n * a misconfigured theme.\n */\nfunction describeSettingsFailure(identifier: string, error: unknown): SettingsError {\n if (error instanceof SettingsError) return error;\n const request = `the settings request for store \"${identifier}\"`;\n if (isTimeoutError(error)) {\n return new SettingsError(\n `The Salla API did not answer ${request} within ${SETTINGS_TIMEOUT_MS} ms.`,\n { reason: 'timeout' }\n );\n }\n if (isHTTPError(error)) {\n const { status } = error.response;\n const said = apiErrorMessage(error.data);\n return new SettingsError(\n `The Salla API answered ${request} with HTTP ${status}${said ? `: ${said}` : ''}.`,\n { reason: isStoreNotFound(identifier, status, said) ? 'not-found' : 'http', status }\n );\n }\n if (isNetworkError(error)) {\n return new SettingsError(`The Salla API could not be reached for ${request}.`, {\n reason: 'network',\n });\n }\n const detail = error instanceof Error ? `: ${error.message}` : '';\n return new SettingsError(`The settings request for store \"${identifier}\" failed${detail}.`);\n}\n\n/**\n * The settings, or a {@link SettingsError} that says why there are none. The\n * query throws it so the root route can say why the store did not load;\n * `store.settings` keeps answering `null` for its own callers.\n */\nasync function fetchSettings(storeIdentifier?: string): Promise<StoreContext> {\n const identifier = storeIdentifier ?? resolveStoreIdentifier();\n\n if (!identifier) {\n const error = new SettingsError(\n 'No store is named for this request: add `?storeId=` on the preview host, or set VITE_STORE_DOMAIN in local development.',\n { reason: 'no-store' }\n );\n console.warn('[store.settings]', error.message);\n throw error;\n }\n\n try {\n return await requestSettings(identifier);\n } catch (cause) {\n const error = describeSettingsFailure(identifier, cause);\n console.error('[store.settings]', error.message, ...(cause === error ? [] : [cause]));\n throw error;\n }\n}\n\nexport const store = {\n settings: async (storeIdentifier?: string): Promise<StoreContext | null> => {\n try {\n return await fetchSettings(storeIdentifier);\n } catch {\n // Already logged, with the reason.\n return null;\n }\n },\n\n queries: {\n settings: (storeIdentifier?: string) =>\n queryOptions<StoreContext | null>({\n queryKey: [\n 'store',\n 'settings',\n storeIdentifier,\n getTwilightContext().locale,\n getActiveScope(),\n // Two versions of one store's settings are two different answers, and\n // this is the query whose answer decides what every other call is\n // pinned to. `requestedThemeVersionId` rather than the resolved one:\n // the resolved value falls back to what these settings report, so it\n // is not knowable until after this query has run — the key would be\n // one thing on the server and another on the client, and the hydrated\n // page would refetch the settings it was just handed.\n requestedThemeVersionId(),\n ],\n // Throws rather than resolving `null`, so the failure keeps its reason.\n queryFn: () => fetchSettings(storeIdentifier),\n // A null never retried, and the root route waits on this: the router's\n // default `retry: 1` would sit through the timeout twice.\n retry: 0,\n }),\n },\n};\n"]}
@@ -1,10 +1,10 @@
1
1
  import { ErrorPage } from './chunk-Z4Y55HWX.js';
2
2
  import { tanstackHeadAdapter } from './chunk-EHTLXK5F.js';
3
3
  import { dispatchRouteChanged, dispatchProductViewed } from './chunk-EFCIK5NI.js';
4
- import { store } from './chunk-LPCNDH4F.js';
4
+ import { store } from './chunk-IRQJBRKV.js';
5
5
  import { translations } from './chunk-E552K72T.js';
6
6
  import { shouldDehydrateQuery } from './chunk-MQALPNFL.js';
7
- import { VIEW_AS_OWNER_COOKIE_NAME, rootHead, ownerLinkMatches, ownerCookieMatches, showsMaintenancePage } from './chunk-TDOVEDHH.js';
7
+ import { VIEW_AS_OWNER_COOKIE_NAME, rootHead, ownerLinkMatches, ownerCookieMatches, showsMaintenancePage } from './chunk-D6XHL6VQ.js';
8
8
  import { apps } from './chunk-UMTMIMH7.js';
9
9
  import { setHeadAdapter } from './chunk-GD26FI4J.js';
10
10
  import { RedirectError, NotFoundError, UnauthorizedError, isMissingResource, responseStatusOf } from './chunk-T23HXVW5.js';
@@ -366,7 +366,7 @@ function resolveRouteId(tanstackId) {
366
366
  return TANSTACK_ROUTE_ID_MAP[tanstackId] ?? tanstackId;
367
367
  }
368
368
  var LazyNotFoundPage = lazy(
369
- () => import('./not-found-ZJ64R3RS.js').then((m) => ({ default: m.NotFoundPage }))
369
+ () => import('./not-found-ZX6EJRVW.js').then((m) => ({ default: m.NotFoundPage }))
370
370
  );
371
371
  function StoreUnavailablePage() {
372
372
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
@@ -752,5 +752,5 @@ function tanstackDocumentAdapter(descriptor) {
752
752
  }
753
753
 
754
754
  export { RouteDocumentSync, TanStackDocumentSync, createRouter, createTwilightRootRoute, tanstackDocumentAdapter, useTanstackDocumentAttrs };
755
- //# sourceMappingURL=chunk-BSJPKSKE.js.map
756
- //# sourceMappingURL=chunk-BSJPKSKE.js.map
755
+ //# sourceMappingURL=chunk-NHEMVF3B.js.map
756
+ //# sourceMappingURL=chunk-NHEMVF3B.js.map