@storepecker/storefront-core 2.3.6 → 2.4.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.
Files changed (91) hide show
  1. package/dist/api/index.cjs +28 -24
  2. package/dist/api/index.d.cts +8 -5
  3. package/dist/api/index.d.ts +8 -5
  4. package/dist/api/index.js +1 -1
  5. package/dist/{booking-CG6tul9l.d.ts → booking-BVWe8HHh.d.ts} +1 -1
  6. package/dist/{booking-DNVf5ZAS.d.cts → booking-DX9SU_qm.d.cts} +1 -1
  7. package/dist/cart-kJoawc_Z.d.cts +126 -0
  8. package/dist/cart-y-7RPmnQ.d.ts +126 -0
  9. package/dist/checkout/index.cjs +22 -22
  10. package/dist/checkout/index.d.cts +3 -1
  11. package/dist/checkout/index.d.ts +3 -1
  12. package/dist/checkout/index.js +2 -2
  13. package/dist/{chunk-BTT3XQ32.cjs → chunk-33TWVRZE.cjs} +6 -6
  14. package/dist/chunk-3YRSHPM6.cjs +34 -0
  15. package/dist/{chunk-ILVGYHNI.js → chunk-6Q7QMPOQ.js} +2 -1
  16. package/dist/{chunk-HTFVROIV.cjs → chunk-7UK3E7SL.cjs} +6 -0
  17. package/dist/chunk-B3BXKMQA.cjs +271 -0
  18. package/dist/chunk-BTR3HLL4.js +14 -0
  19. package/dist/chunk-EGFOTJPC.js +22 -0
  20. package/dist/{chunk-YUPBTD4M.js → chunk-F45S7UWC.js} +1 -139
  21. package/dist/chunk-HAQWCNDY.cjs +24 -0
  22. package/dist/{chunk-Y4NGR42Z.js → chunk-HUIT4JCR.js} +1 -1
  23. package/dist/{chunk-TF2KMTB6.js → chunk-JRYWZMNT.js} +1 -1
  24. package/dist/{chunk-JCOOINQF.cjs → chunk-KLNKIQQM.cjs} +4 -3
  25. package/dist/chunk-L43KF3AC.js +269 -0
  26. package/dist/chunk-LHF5BSWO.cjs +16 -0
  27. package/dist/chunk-LJUGNSQQ.cjs +149 -0
  28. package/dist/chunk-NA5GT4D3.js +75 -0
  29. package/dist/chunk-OSM73ETC.js +139 -0
  30. package/dist/{chunk-4CVKE6CC.cjs → chunk-OTMTHA5C.cjs} +0 -147
  31. package/dist/{chunk-JH4JJBXE.cjs → chunk-TTIQRDHX.cjs} +2 -2
  32. package/dist/chunk-U7EXLQCT.js +32 -0
  33. package/dist/{chunk-LW3V53WJ.js → chunk-UVU7H4E6.js} +6 -1
  34. package/dist/chunk-V447PVRV.cjs +308 -0
  35. package/dist/chunk-VWQR3A7V.cjs +81 -0
  36. package/dist/chunk-YK4M3SFP.js +301 -0
  37. package/dist/{collections-Bz9KD7Na.d.cts → collections-BDSVfRNo.d.ts} +1 -1
  38. package/dist/{collections-CkEUi3BR.d.ts → collections-WzvTO0OQ.d.cts} +1 -1
  39. package/dist/components/address-form.cjs +17 -0
  40. package/dist/components/address-form.css +329 -0
  41. package/dist/components/address-form.d.cts +33 -0
  42. package/dist/components/address-form.d.ts +33 -0
  43. package/dist/components/address-form.js +11 -0
  44. package/dist/components/digital-product-download-modal.cjs +8 -0
  45. package/dist/components/digital-product-download-modal.d.cts +15 -0
  46. package/dist/components/digital-product-download-modal.d.ts +15 -0
  47. package/dist/components/digital-product-download-modal.js +2 -0
  48. package/dist/components/index.cjs +35 -695
  49. package/dist/components/index.d.cts +14 -87
  50. package/dist/components/index.d.ts +14 -87
  51. package/dist/components/index.js +11 -688
  52. package/dist/components/search-dropdown.cjs +7 -0
  53. package/dist/components/search-dropdown.css +200 -0
  54. package/dist/components/search-dropdown.d.cts +28 -0
  55. package/dist/components/search-dropdown.d.ts +28 -0
  56. package/dist/components/search-dropdown.js +1 -0
  57. package/dist/components/share-button.cjs +9 -0
  58. package/dist/components/share-button.d.cts +11 -0
  59. package/dist/components/share-button.d.ts +11 -0
  60. package/dist/components/share-button.js +3 -0
  61. package/dist/components/share-icon.cjs +7 -0
  62. package/dist/components/share-icon.d.cts +9 -0
  63. package/dist/components/share-icon.d.ts +9 -0
  64. package/dist/components/share-icon.js +1 -0
  65. package/dist/components/theme-data-initializer.cjs +8 -0
  66. package/dist/components/theme-data-initializer.d.cts +12 -0
  67. package/dist/components/theme-data-initializer.d.ts +12 -0
  68. package/dist/components/theme-data-initializer.js +2 -0
  69. package/dist/hooks/index.cjs +18 -17
  70. package/dist/hooks/index.d.cts +4 -2
  71. package/dist/hooks/index.d.ts +4 -2
  72. package/dist/hooks/index.js +6 -5
  73. package/dist/models/index.d.cts +6 -4
  74. package/dist/models/index.d.ts +6 -4
  75. package/dist/orders-CjNmCY5I.d.cts +144 -0
  76. package/dist/orders-L_8eIkUS.d.ts +144 -0
  77. package/dist/{pixelEvents-OVIkPw-J.d.ts → pixelEvents-Bo-VjAx8.d.ts} +4 -2
  78. package/dist/{pixelEvents-DYkiTkb2.d.cts → pixelEvents-C1rFPOwb.d.cts} +4 -2
  79. package/dist/{orders-fIdANHSl.d.ts → product-DJMdi4D4.d.cts} +1 -265
  80. package/dist/{orders-fIdANHSl.d.cts → product-DJMdi4D4.d.ts} +1 -265
  81. package/dist/store/index.cjs +5 -5
  82. package/dist/store/index.d.cts +6 -4
  83. package/dist/store/index.d.ts +6 -4
  84. package/dist/store/index.js +2 -2
  85. package/dist/utils/index.cjs +44 -43
  86. package/dist/utils/index.d.cts +7 -5
  87. package/dist/utils/index.d.ts +7 -5
  88. package/dist/utils/index.js +3 -2
  89. package/dist/{wishlist-stNzfvIP.d.cts → wishlist-CUuCTSVJ.d.cts} +1 -1
  90. package/dist/{wishlist-_bd4gLyQ.d.ts → wishlist-DKYFZR0s.d.ts} +1 -1
  91. package/package.json +49 -1
@@ -0,0 +1,269 @@
1
+ import { search_dropdown_default, DownChevron } from './chunk-YK4M3SFP.js';
2
+ import { useAddressForm } from './chunk-6Q7QMPOQ.js';
3
+ import { forwardRef, useImperativeHandle, useEffect } from 'react';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ // src/components/address-form/address-form.module.css
7
+ var address_form_default = {};
8
+ var AddressForm = forwardRef(
9
+ ({
10
+ address,
11
+ onSuccess,
12
+ onError,
13
+ locationCacheKey,
14
+ defaultCountryId,
15
+ renderButton,
16
+ onFormikReady,
17
+ onCancel,
18
+ showCancel = true,
19
+ showDefaultCheckbox = true,
20
+ className,
21
+ submitLabel = "Save"
22
+ }, ref) => {
23
+ const {
24
+ formik,
25
+ states,
26
+ supportedCountries,
27
+ selectedCountry,
28
+ countryCodeOptions,
29
+ addressMeta,
30
+ handlePhoneCountryChange,
31
+ handleCountryCodeChange,
32
+ handlePhoneChange,
33
+ isSubmitting,
34
+ isEditing
35
+ } = useAddressForm({
36
+ address,
37
+ onSuccess,
38
+ onError,
39
+ locationCacheKey,
40
+ defaultCountryId
41
+ });
42
+ useImperativeHandle(
43
+ ref,
44
+ () => ({
45
+ formik,
46
+ resetForm: () => formik.resetForm()
47
+ }),
48
+ [formik]
49
+ );
50
+ useEffect(() => {
51
+ onFormikReady?.(formik);
52
+ }, [formik, onFormikReady]);
53
+ return /* @__PURE__ */ jsxs(
54
+ "form",
55
+ {
56
+ name: "address-form",
57
+ className: `${address_form_default.addressForm} ${className || ""}`,
58
+ onSubmit: formik.handleSubmit,
59
+ children: [
60
+ /* @__PURE__ */ jsxs("div", { className: address_form_default.formBody, children: [
61
+ /* @__PURE__ */ jsxs("div", { className: address_form_default.formGroup, children: [
62
+ /* @__PURE__ */ jsx("label", { children: "Name *" }),
63
+ /* @__PURE__ */ jsx(
64
+ "input",
65
+ {
66
+ className: address_form_default.formControl,
67
+ type: "text",
68
+ placeholder: "Name",
69
+ "aria-label": "name",
70
+ autoFocus: true,
71
+ ...formik.getFieldProps("customer_name")
72
+ }
73
+ ),
74
+ formik.touched.customer_name && formik.errors.customer_name && /* @__PURE__ */ jsx("span", { className: address_form_default.error, children: formik.errors.customer_name })
75
+ ] }),
76
+ /* @__PURE__ */ jsxs("div", { className: address_form_default.formGroup, children: [
77
+ /* @__PURE__ */ jsx("label", { children: "Email *" }),
78
+ /* @__PURE__ */ jsx(
79
+ "input",
80
+ {
81
+ className: address_form_default.formControl,
82
+ type: "email",
83
+ placeholder: "Email",
84
+ "aria-label": "email",
85
+ ...formik.getFieldProps("customer_email")
86
+ }
87
+ ),
88
+ formik.touched.customer_email && formik.errors.customer_email && /* @__PURE__ */ jsx("span", { className: address_form_default.error, children: formik.errors.customer_email })
89
+ ] }),
90
+ /* @__PURE__ */ jsxs("div", { className: address_form_default.formGroup, children: [
91
+ /* @__PURE__ */ jsx("label", { children: "Phone *" }),
92
+ /* @__PURE__ */ jsxs("div", { className: address_form_default.phoneRow, children: [
93
+ /* @__PURE__ */ jsx("div", { className: address_form_default.phoneCodeCol, children: /* @__PURE__ */ jsx(
94
+ search_dropdown_default,
95
+ {
96
+ options: countryCodeOptions,
97
+ value: formik.values.customer_country_code,
98
+ onChange: handlePhoneCountryChange,
99
+ placeholder: "Country",
100
+ searchPlaceholder: "Search country...",
101
+ maxHeight: "250px"
102
+ }
103
+ ) }),
104
+ /* @__PURE__ */ jsx("div", { className: address_form_default.phoneInputCol, children: /* @__PURE__ */ jsx(
105
+ "input",
106
+ {
107
+ className: address_form_default.formControl,
108
+ type: "tel",
109
+ placeholder: "Phone",
110
+ "aria-label": "phone",
111
+ name: "customer_phone",
112
+ value: formik.values.customer_phone,
113
+ onBlur: formik.handleBlur,
114
+ onChange: handlePhoneChange
115
+ }
116
+ ) })
117
+ ] }),
118
+ formik.touched.customer_phone && formik.errors.customer_phone && /* @__PURE__ */ jsx("span", { className: address_form_default.error, children: formik.errors.customer_phone })
119
+ ] }),
120
+ /* @__PURE__ */ jsx("hr", { className: address_form_default.divider }),
121
+ /* @__PURE__ */ jsxs("div", { className: address_form_default.formGroup, children: [
122
+ /* @__PURE__ */ jsx("label", { children: "Address (House No, Building, Street, Area) *" }),
123
+ /* @__PURE__ */ jsx(
124
+ "input",
125
+ {
126
+ className: address_form_default.formControl,
127
+ type: "text",
128
+ placeholder: "E.g. 1st Cross, 2nd Main, 3rd Stage",
129
+ "aria-label": "address",
130
+ ...formik.getFieldProps("address")
131
+ }
132
+ ),
133
+ formik.touched.address && formik.errors.address && /* @__PURE__ */ jsx("span", { className: address_form_default.error, children: formik.errors.address })
134
+ ] }),
135
+ /* @__PURE__ */ jsxs("div", { className: address_form_default.row, children: [
136
+ /* @__PURE__ */ jsx("div", { className: address_form_default.col, children: /* @__PURE__ */ jsxs("div", { className: address_form_default.formGroup, children: [
137
+ /* @__PURE__ */ jsx("label", { className: "text-capitalize", children: "Country *" }),
138
+ /* @__PURE__ */ jsx(
139
+ search_dropdown_default,
140
+ {
141
+ options: countryCodeOptions,
142
+ value: selectedCountry?.tld_code,
143
+ onChange: handleCountryCodeChange,
144
+ placeholder: "Select country",
145
+ searchPlaceholder: "Search country...",
146
+ maxHeight: "250px",
147
+ name: "country_obj"
148
+ }
149
+ )
150
+ ] }) }),
151
+ /* @__PURE__ */ jsx("div", { className: address_form_default.col, children: /* @__PURE__ */ jsxs("div", { className: address_form_default.formGroup, children: [
152
+ /* @__PURE__ */ jsxs("label", { style: { textTransform: "capitalize" }, children: [
153
+ addressMeta?.regionLabel || "State",
154
+ " *"
155
+ ] }),
156
+ /* @__PURE__ */ jsxs("div", { className: address_form_default.selectWrapper, children: [
157
+ /* @__PURE__ */ jsxs(
158
+ "select",
159
+ {
160
+ className: address_form_default.formControl,
161
+ "aria-label": "state",
162
+ "data-select": "",
163
+ ...formik.getFieldProps("state_obj"),
164
+ children: [
165
+ /* @__PURE__ */ jsxs("option", { value: "", children: [
166
+ "Select ",
167
+ addressMeta?.regionLabel || "State"
168
+ ] }),
169
+ states.map((state) => /* @__PURE__ */ jsx("option", { value: state.id, children: state.name }, state.id))
170
+ ]
171
+ }
172
+ ),
173
+ /* @__PURE__ */ jsx("span", { className: address_form_default.selectArrow, children: /* @__PURE__ */ jsx(DownChevron, { width: 12, height: 12 }) })
174
+ ] }),
175
+ formik.touched.state_obj && formik.errors.state_obj && /* @__PURE__ */ jsx("span", { className: address_form_default.error, children: formik.errors.state_obj })
176
+ ] }) })
177
+ ] }),
178
+ /* @__PURE__ */ jsxs("div", { className: address_form_default.row, children: [
179
+ addressMeta?.hasPostal && /* @__PURE__ */ jsx("div", { className: address_form_default.col, children: /* @__PURE__ */ jsxs("div", { className: address_form_default.formGroup, children: [
180
+ /* @__PURE__ */ jsxs("label", { children: [
181
+ addressMeta?.postalLabel || "Postal Code",
182
+ " *"
183
+ ] }),
184
+ /* @__PURE__ */ jsx(
185
+ "input",
186
+ {
187
+ className: address_form_default.formControl,
188
+ type: "tel",
189
+ placeholder: addressMeta?.postalLabel || "Postal Code",
190
+ "aria-label": "pincode",
191
+ ...formik.getFieldProps("pincode")
192
+ }
193
+ ),
194
+ formik.touched.pincode && formik.errors.pincode && /* @__PURE__ */ jsx("span", { className: address_form_default.error, children: formik.errors.pincode })
195
+ ] }) }),
196
+ /* @__PURE__ */ jsx("div", { className: address_form_default.col, children: /* @__PURE__ */ jsxs("div", { className: address_form_default.formGroup, children: [
197
+ /* @__PURE__ */ jsx("label", { children: "City/District *" }),
198
+ /* @__PURE__ */ jsx(
199
+ "input",
200
+ {
201
+ className: address_form_default.formControl,
202
+ type: "text",
203
+ placeholder: "E.g. Kochi, Bangalore",
204
+ "aria-label": "city",
205
+ ...formik.getFieldProps("city")
206
+ }
207
+ ),
208
+ formik.touched.city && formik.errors.city && /* @__PURE__ */ jsx("span", { className: address_form_default.error, children: formik.errors.city })
209
+ ] }) })
210
+ ] }),
211
+ /* @__PURE__ */ jsx("hr", { className: address_form_default.divider }),
212
+ showDefaultCheckbox && /* @__PURE__ */ jsx("div", { className: address_form_default.formGroup, children: /* @__PURE__ */ jsxs("label", { className: address_form_default.checkboxLabel, children: [
213
+ /* @__PURE__ */ jsx(
214
+ "input",
215
+ {
216
+ type: "checkbox",
217
+ className: address_form_default.checkboxInput,
218
+ checked: formik.values.is_default || false,
219
+ onChange: (e) => {
220
+ formik.setFieldValue("is_default", e.target.checked);
221
+ }
222
+ }
223
+ ),
224
+ "Make this your default address"
225
+ ] }) })
226
+ ] }),
227
+ /* @__PURE__ */ jsxs("div", { className: address_form_default.formFooter, children: [
228
+ showCancel && onCancel && /* @__PURE__ */ jsx(
229
+ "button",
230
+ {
231
+ type: "button",
232
+ className: address_form_default.cancelBtn,
233
+ onClick: onCancel,
234
+ children: "Cancel"
235
+ }
236
+ ),
237
+ renderButton ? renderButton({
238
+ type: "submit",
239
+ disabled: !formik.isValid || isSubmitting,
240
+ loading: isSubmitting,
241
+ children: isEditing ? submitLabel : submitLabel
242
+ }) : /* @__PURE__ */ jsx(
243
+ "button",
244
+ {
245
+ type: "submit",
246
+ disabled: !formik.isValid || isSubmitting,
247
+ className: address_form_default.formControl,
248
+ style: {
249
+ width: "auto",
250
+ cursor: !formik.isValid || isSubmitting ? "not-allowed" : "pointer",
251
+ backgroundColor: "var(--primary, #003d29)",
252
+ color: "var(--btn-text, #fff)",
253
+ border: "none",
254
+ padding: "0.5rem 1.5rem",
255
+ opacity: !formik.isValid || isSubmitting ? 0.6 : 1
256
+ },
257
+ children: isSubmitting ? "Saving..." : submitLabel
258
+ }
259
+ )
260
+ ] })
261
+ ]
262
+ }
263
+ );
264
+ }
265
+ );
266
+ AddressForm.displayName = "AddressForm";
267
+ var address_form_default2 = AddressForm;
268
+
269
+ export { address_form_default2 as address_form_default };
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ var chunkDODFO744_cjs = require('./chunk-DODFO744.cjs');
4
+ var react = require('react');
5
+
6
+ function ThemeDataInitializer({
7
+ themeData
8
+ }) {
9
+ const setThemeData = chunkDODFO744_cjs.useThemeData((state) => state.setThemeData);
10
+ react.useEffect(() => {
11
+ setThemeData(themeData);
12
+ }, [themeData]);
13
+ return null;
14
+ }
15
+
16
+ exports.ThemeDataInitializer = ThemeDataInitializer;
@@ -0,0 +1,149 @@
1
+ 'use strict';
2
+
3
+ // src/utils/cache.ts
4
+ var DEFAULT_EXPIRY_HOURS = 24;
5
+ var CacheManager = class _CacheManager {
6
+ constructor() {
7
+ this.cache = /* @__PURE__ */ new Map();
8
+ this.loadFromStorage();
9
+ }
10
+ static getInstance() {
11
+ if (!_CacheManager.instance) {
12
+ _CacheManager.instance = new _CacheManager();
13
+ }
14
+ return _CacheManager.instance;
15
+ }
16
+ loadFromStorage() {
17
+ if (typeof window === "undefined") return;
18
+ try {
19
+ const stored = localStorage.getItem("app_cache");
20
+ if (stored) {
21
+ const parsed = JSON.parse(stored);
22
+ this.cache = new Map(Object.entries(parsed));
23
+ this.cleanExpired();
24
+ }
25
+ } catch (error) {
26
+ console.warn("Failed to load cache from storage:", error);
27
+ }
28
+ }
29
+ saveToStorage() {
30
+ if (typeof window === "undefined") return;
31
+ try {
32
+ const cacheObject = Object.fromEntries(this.cache);
33
+ localStorage.setItem("app_cache", JSON.stringify(cacheObject));
34
+ } catch (error) {
35
+ console.warn("Failed to save cache to storage:", error);
36
+ }
37
+ }
38
+ cleanExpired() {
39
+ const now = Date.now();
40
+ const keysToDelete = [];
41
+ this.cache.forEach((item, key) => {
42
+ if (now > item.expiry) {
43
+ keysToDelete.push(key);
44
+ }
45
+ });
46
+ keysToDelete.forEach((key) => {
47
+ this.cache.delete(key);
48
+ });
49
+ this.saveToStorage();
50
+ }
51
+ set(key, data, options = {}) {
52
+ const expiryHours = options.expiryHours || DEFAULT_EXPIRY_HOURS;
53
+ const now = Date.now();
54
+ const expiry = now + expiryHours * 60 * 60 * 1e3;
55
+ const cacheItem = {
56
+ data,
57
+ timestamp: now,
58
+ expiry
59
+ };
60
+ this.cache.set(key, cacheItem);
61
+ this.saveToStorage();
62
+ }
63
+ get(key) {
64
+ this.cleanExpired();
65
+ const item = this.cache.get(key);
66
+ if (!item) return null;
67
+ const now = Date.now();
68
+ if (now > item.expiry) {
69
+ this.cache.delete(key);
70
+ this.saveToStorage();
71
+ return null;
72
+ }
73
+ return item.data;
74
+ }
75
+ has(key) {
76
+ this.cleanExpired();
77
+ return this.cache.has(key);
78
+ }
79
+ delete(key) {
80
+ this.cache.delete(key);
81
+ this.saveToStorage();
82
+ }
83
+ clear() {
84
+ this.cache.clear();
85
+ if (typeof window !== "undefined") {
86
+ localStorage.removeItem("app_cache");
87
+ }
88
+ }
89
+ getCacheInfo() {
90
+ this.cleanExpired();
91
+ return {
92
+ size: this.cache.size,
93
+ keys: Array.from(this.cache.keys())
94
+ };
95
+ }
96
+ invalidateCache(pattern) {
97
+ this.cleanExpired();
98
+ if (!pattern) {
99
+ this.clear();
100
+ return;
101
+ }
102
+ const keysToDelete = [];
103
+ this.cache.forEach((item, key) => {
104
+ if (key.includes(pattern)) {
105
+ keysToDelete.push(key);
106
+ }
107
+ });
108
+ keysToDelete.forEach((key) => {
109
+ this.cache.delete(key);
110
+ });
111
+ this.saveToStorage();
112
+ }
113
+ };
114
+ var cache = CacheManager.getInstance();
115
+ function setCache(key, data, options = {}) {
116
+ cache.set(key, data, options);
117
+ }
118
+ function getCache(key) {
119
+ return cache.get(key);
120
+ }
121
+ function hasCache(key) {
122
+ return cache.has(key);
123
+ }
124
+ function deleteCache(key) {
125
+ cache.delete(key);
126
+ }
127
+ function clearCache() {
128
+ cache.clear();
129
+ }
130
+ function invalidateCache(pattern) {
131
+ cache.invalidateCache(pattern);
132
+ }
133
+ function generateCacheKey(endpoint, params) {
134
+ const baseKey = endpoint.replace(/[^a-zA-Z0-9]/g, "_");
135
+ if (!params) return baseKey;
136
+ const paramString = JSON.stringify(params);
137
+ const hash = btoa(paramString).replace(/[^a-zA-Z0-9]/g, "");
138
+ return `${baseKey}_${hash}`;
139
+ }
140
+
141
+ exports.CacheManager = CacheManager;
142
+ exports.cache = cache;
143
+ exports.clearCache = clearCache;
144
+ exports.deleteCache = deleteCache;
145
+ exports.generateCacheKey = generateCacheKey;
146
+ exports.getCache = getCache;
147
+ exports.hasCache = hasCache;
148
+ exports.invalidateCache = invalidateCache;
149
+ exports.setCache = setCache;
@@ -0,0 +1,75 @@
1
+ import { timeFromNow, isExpired } from './chunk-HSF2D56O.js';
2
+ import Modal from 'react-responsive-modal';
3
+ import 'react-responsive-modal/styles.css';
4
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
+
6
+ var checkIfLimitReached = (attribute) => {
7
+ return isExpired(attribute.expiry_date) || attribute.download_count === 0;
8
+ };
9
+ var DigitalProductDownloadModal = ({ open, onClose, product, downloadAttribute, onDownload, loading }) => {
10
+ return /* @__PURE__ */ jsx(
11
+ Modal,
12
+ {
13
+ classNames: {
14
+ modal: "modal modal-lg modal-confirm",
15
+ closeButton: "modal-close"
16
+ },
17
+ open,
18
+ onClose,
19
+ center: true,
20
+ closeIcon: null,
21
+ children: /* @__PURE__ */ jsxs("div", { className: "modal-body px-4 py-2", children: [
22
+ /* @__PURE__ */ jsxs("span", { className: "text-2xl block mb-2 fw-regular", children: [
23
+ "Download links for ",
24
+ product?.product_name
25
+ ] }),
26
+ /* @__PURE__ */ jsx("hr", { className: "mb-4 mt-2" }),
27
+ /* @__PURE__ */ jsx("div", { className: "download-links", children: loading ? Array.from({ length: 3 }).map((_, index) => /* @__PURE__ */ jsx("div", { className: "w-100 rounded-1 mb-3", children: /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
28
+ /* @__PURE__ */ jsxs("div", { className: "w-100", children: [
29
+ /* @__PURE__ */ jsx("div", { className: "shine line w-75" }),
30
+ /* @__PURE__ */ jsx("div", { className: "shine line w-50 mt-2" })
31
+ ] }),
32
+ /* @__PURE__ */ jsx("div", { className: "shine w-160 h-32 rounded-1" })
33
+ ] }) }, index)) : downloadAttribute.map((attribute, index) => /* @__PURE__ */ jsxs(
34
+ "div",
35
+ {
36
+ className: "flex items-center justify-between mt-3",
37
+ children: [
38
+ /* @__PURE__ */ jsxs("div", { children: [
39
+ /* @__PURE__ */ jsxs("span", { className: "block text-md lh-1", children: [
40
+ "Download link ",
41
+ index + 1
42
+ ] }),
43
+ checkIfLimitReached(attribute) ? /* @__PURE__ */ jsx("span", { className: "text-danger text-sm lh-1", children: "Download link expired." }) : /* @__PURE__ */ jsxs("span", { className: "text-textSecondary text-sm lh-1", children: [
44
+ "Remaining tries: ",
45
+ attribute.download_count,
46
+ " ",
47
+ "\u2022\xA0 Expires",
48
+ " ",
49
+ timeFromNow(attribute.expiry_date)
50
+ ] })
51
+ ] }),
52
+ /* @__PURE__ */ jsx(
53
+ "button",
54
+ {
55
+ className: "btn btn-text btn-medium",
56
+ onClick: () => onDownload(attribute),
57
+ disabled: checkIfLimitReached(attribute),
58
+ children: "Download"
59
+ }
60
+ )
61
+ ]
62
+ },
63
+ `${attribute.download_link}-${index}`
64
+ )) }),
65
+ /* @__PURE__ */ jsxs("p", { className: "text-textSecondary text-sm fw-regular p-2 bg-warning-light rounded-2 mt-4", children: [
66
+ /* @__PURE__ */ jsx("strong", { className: "text-textSecondary", children: "Warning:" }),
67
+ " The download link is time-sensitive and will expire after a set period. You are limited to a specific number of download attempts, with each attempt reducing the remaining tries. To avoid any disruptions, please ensure a stable internet connection before proceeding with the download."
68
+ ] })
69
+ ] })
70
+ }
71
+ );
72
+ };
73
+ var digital_product_download_modal_default = DigitalProductDownloadModal;
74
+
75
+ export { digital_product_download_modal_default };
@@ -0,0 +1,139 @@
1
+ // src/utils/cache.ts
2
+ var DEFAULT_EXPIRY_HOURS = 24;
3
+ var CacheManager = class _CacheManager {
4
+ constructor() {
5
+ this.cache = /* @__PURE__ */ new Map();
6
+ this.loadFromStorage();
7
+ }
8
+ static getInstance() {
9
+ if (!_CacheManager.instance) {
10
+ _CacheManager.instance = new _CacheManager();
11
+ }
12
+ return _CacheManager.instance;
13
+ }
14
+ loadFromStorage() {
15
+ if (typeof window === "undefined") return;
16
+ try {
17
+ const stored = localStorage.getItem("app_cache");
18
+ if (stored) {
19
+ const parsed = JSON.parse(stored);
20
+ this.cache = new Map(Object.entries(parsed));
21
+ this.cleanExpired();
22
+ }
23
+ } catch (error) {
24
+ console.warn("Failed to load cache from storage:", error);
25
+ }
26
+ }
27
+ saveToStorage() {
28
+ if (typeof window === "undefined") return;
29
+ try {
30
+ const cacheObject = Object.fromEntries(this.cache);
31
+ localStorage.setItem("app_cache", JSON.stringify(cacheObject));
32
+ } catch (error) {
33
+ console.warn("Failed to save cache to storage:", error);
34
+ }
35
+ }
36
+ cleanExpired() {
37
+ const now = Date.now();
38
+ const keysToDelete = [];
39
+ this.cache.forEach((item, key) => {
40
+ if (now > item.expiry) {
41
+ keysToDelete.push(key);
42
+ }
43
+ });
44
+ keysToDelete.forEach((key) => {
45
+ this.cache.delete(key);
46
+ });
47
+ this.saveToStorage();
48
+ }
49
+ set(key, data, options = {}) {
50
+ const expiryHours = options.expiryHours || DEFAULT_EXPIRY_HOURS;
51
+ const now = Date.now();
52
+ const expiry = now + expiryHours * 60 * 60 * 1e3;
53
+ const cacheItem = {
54
+ data,
55
+ timestamp: now,
56
+ expiry
57
+ };
58
+ this.cache.set(key, cacheItem);
59
+ this.saveToStorage();
60
+ }
61
+ get(key) {
62
+ this.cleanExpired();
63
+ const item = this.cache.get(key);
64
+ if (!item) return null;
65
+ const now = Date.now();
66
+ if (now > item.expiry) {
67
+ this.cache.delete(key);
68
+ this.saveToStorage();
69
+ return null;
70
+ }
71
+ return item.data;
72
+ }
73
+ has(key) {
74
+ this.cleanExpired();
75
+ return this.cache.has(key);
76
+ }
77
+ delete(key) {
78
+ this.cache.delete(key);
79
+ this.saveToStorage();
80
+ }
81
+ clear() {
82
+ this.cache.clear();
83
+ if (typeof window !== "undefined") {
84
+ localStorage.removeItem("app_cache");
85
+ }
86
+ }
87
+ getCacheInfo() {
88
+ this.cleanExpired();
89
+ return {
90
+ size: this.cache.size,
91
+ keys: Array.from(this.cache.keys())
92
+ };
93
+ }
94
+ invalidateCache(pattern) {
95
+ this.cleanExpired();
96
+ if (!pattern) {
97
+ this.clear();
98
+ return;
99
+ }
100
+ const keysToDelete = [];
101
+ this.cache.forEach((item, key) => {
102
+ if (key.includes(pattern)) {
103
+ keysToDelete.push(key);
104
+ }
105
+ });
106
+ keysToDelete.forEach((key) => {
107
+ this.cache.delete(key);
108
+ });
109
+ this.saveToStorage();
110
+ }
111
+ };
112
+ var cache = CacheManager.getInstance();
113
+ function setCache(key, data, options = {}) {
114
+ cache.set(key, data, options);
115
+ }
116
+ function getCache(key) {
117
+ return cache.get(key);
118
+ }
119
+ function hasCache(key) {
120
+ return cache.has(key);
121
+ }
122
+ function deleteCache(key) {
123
+ cache.delete(key);
124
+ }
125
+ function clearCache() {
126
+ cache.clear();
127
+ }
128
+ function invalidateCache(pattern) {
129
+ cache.invalidateCache(pattern);
130
+ }
131
+ function generateCacheKey(endpoint, params) {
132
+ const baseKey = endpoint.replace(/[^a-zA-Z0-9]/g, "_");
133
+ if (!params) return baseKey;
134
+ const paramString = JSON.stringify(params);
135
+ const hash = btoa(paramString).replace(/[^a-zA-Z0-9]/g, "");
136
+ return `${baseKey}_${hash}`;
137
+ }
138
+
139
+ export { CacheManager, cache, clearCache, deleteCache, generateCacheKey, getCache, hasCache, invalidateCache, setCache };