@lodashventure/medusa-membership 0.4.9 → 0.4.10

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.
@@ -1,1103 +0,0 @@
1
- "use strict";
2
- const jsxRuntime = require("react/jsx-runtime");
3
- const adminSdk = require("@medusajs/admin-sdk");
4
- const ui = require("@medusajs/ui");
5
- const axios = require("axios");
6
- const react = require("react");
7
- const Medusa = require("@medusajs/js-sdk");
8
- const icons = require("@medusajs/icons");
9
- const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
10
- const axios__default = /* @__PURE__ */ _interopDefault(axios);
11
- const Medusa__default = /* @__PURE__ */ _interopDefault(Medusa);
12
- const useMembershipConfig = (storeId, options) => {
13
- const [data, setData] = react.useState(void 0);
14
- const [isLoading, setIsLoading] = react.useState(true);
15
- const [error, setError] = react.useState(null);
16
- const fetchConfig = async () => {
17
- if (!storeId) {
18
- setError(new Error("No store id found"));
19
- setIsLoading(false);
20
- return;
21
- }
22
- try {
23
- setIsLoading(true);
24
- setError(null);
25
- const { data: config2 } = await axios__default.default.get(
26
- `/admin/membership/config/${storeId}`
27
- );
28
- setData(config2);
29
- } catch (err) {
30
- setError(
31
- err instanceof Error ? err : new Error("Failed to fetch config")
32
- );
33
- } finally {
34
- setIsLoading(false);
35
- }
36
- };
37
- react.useEffect(() => {
38
- fetchConfig();
39
- }, [storeId, options == null ? void 0 : options.enabled]);
40
- return {
41
- data,
42
- isLoading,
43
- error,
44
- refetch: fetchConfig
45
- };
46
- };
47
- const sdk = new Medusa__default.default({
48
- baseUrl: "/",
49
- debug: false,
50
- auth: {
51
- type: "session"
52
- }
53
- });
54
- const useStore = () => {
55
- const [data, setData] = react.useState(void 0);
56
- const [isLoading, setIsLoading] = react.useState(true);
57
- const [error, setError] = react.useState(null);
58
- const fetchStore = async () => {
59
- var _a;
60
- try {
61
- setIsLoading(true);
62
- setError(null);
63
- const response = await sdk.admin.store.list();
64
- const activeStore = (_a = response.stores) == null ? void 0 : _a[0];
65
- if (!activeStore) {
66
- throw new Error("No active store found");
67
- }
68
- setData(activeStore);
69
- } catch (err) {
70
- setError(err instanceof Error ? err : new Error("Failed to fetch store"));
71
- } finally {
72
- setIsLoading(false);
73
- }
74
- };
75
- react.useEffect(() => {
76
- fetchStore();
77
- }, []);
78
- return {
79
- data,
80
- isLoading,
81
- error,
82
- refetch: fetchStore
83
- };
84
- };
85
- const usePromotionCollectable = (id) => {
86
- const [data, setData] = react.useState(void 0);
87
- const [isLoading, setIsLoading] = react.useState(true);
88
- const [error, setError] = react.useState(null);
89
- const fetchCollectable = async () => {
90
- try {
91
- setIsLoading(true);
92
- setError(null);
93
- const response = await axios__default.default.get(
94
- `/admin/promotions/${id}/update-collectable`
95
- );
96
- setData(response);
97
- } catch (err) {
98
- setError(
99
- err instanceof Error ? err : new Error("Failed to fetch collectable")
100
- );
101
- } finally {
102
- setIsLoading(false);
103
- }
104
- };
105
- react.useEffect(() => {
106
- fetchCollectable();
107
- }, [id]);
108
- return {
109
- data,
110
- isLoading,
111
- error,
112
- refetch: fetchCollectable
113
- };
114
- };
115
- const useUpdatePromotionCollectable = (id) => {
116
- const [isPending, setIsPending] = react.useState(false);
117
- const [error, setError] = react.useState(null);
118
- const mutate = async (data, { onSuccess } = {}) => {
119
- try {
120
- setIsPending(true);
121
- setError(null);
122
- const response = await axios__default.default.patch(
123
- `/admin/promotions/${id}/update-collectable`,
124
- data
125
- );
126
- ui.toast.success("Coupon collection updated successfully", {
127
- dismissable: true,
128
- duration: 2500
129
- });
130
- if (onSuccess) {
131
- onSuccess();
132
- }
133
- return response.data;
134
- } catch (err) {
135
- const error2 = err instanceof Error ? err : new Error("Failed to update coupon collection");
136
- setError(error2);
137
- ui.toast.error("Failed to update coupon collection", {
138
- dismissable: true,
139
- duration: 2500
140
- });
141
- throw error2;
142
- } finally {
143
- setIsPending(false);
144
- }
145
- };
146
- return {
147
- mutate,
148
- isPending,
149
- error
150
- };
151
- };
152
- const PromotionWidget = ({ data }) => {
153
- const { id } = data;
154
- const { data: collectable } = usePromotionCollectable(id);
155
- const { data: store } = useStore();
156
- const { data: config2 } = useMembershipConfig(store == null ? void 0 : store.id);
157
- const { mutate: updateCollectable } = useUpdatePromotionCollectable(id);
158
- const handleToggleCollectable = async (checked) => {
159
- try {
160
- updateCollectable({
161
- enabled: checked
162
- });
163
- ui.toast.success("Coupon collection updated successfully", {
164
- dismissable: true,
165
- duration: 2500
166
- });
167
- } catch (error) {
168
- ui.toast.error("Failed to update coupon collection", {
169
- dismissable: true,
170
- duration: 2500
171
- });
172
- }
173
- };
174
- if (!(config2 == null ? void 0 : config2.enable_promotion_collection)) {
175
- return null;
176
- }
177
- if (data.is_automatic) {
178
- return null;
179
- }
180
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-6 gap-4", children: [
181
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Coupon Collection" }) }),
182
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 py-2", children: [
183
- /* @__PURE__ */ jsxRuntime.jsx(
184
- ui.Switch,
185
- {
186
- checked: collectable == null ? void 0 : collectable.data.enabled,
187
- onCheckedChange: handleToggleCollectable
188
- }
189
- ),
190
- /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { children: "Can be collected by customer" })
191
- ] })
192
- ] });
193
- };
194
- adminSdk.defineWidgetConfig({
195
- zone: "promotion.details.side.after"
196
- });
197
- const useUpdateMembershipConfig = () => {
198
- const [isPending, setIsPending] = react.useState(false);
199
- const [error, setError] = react.useState(null);
200
- const mutate = async ({ storeId, config: config2 }, {
201
- onSuccess
202
- } = {}) => {
203
- if (!storeId) {
204
- throw new Error("No store id found");
205
- }
206
- try {
207
- setIsPending(true);
208
- setError(null);
209
- const response = await axios__default.default.patch(
210
- `/admin/membership/config/${storeId}`,
211
- config2
212
- );
213
- if (onSuccess) {
214
- onSuccess(response.data);
215
- }
216
- return response.data;
217
- } catch (err) {
218
- const error2 = err instanceof Error ? err : new Error("Failed to update config");
219
- setError(error2);
220
- throw error2;
221
- } finally {
222
- setIsPending(false);
223
- }
224
- };
225
- return {
226
- mutate,
227
- isPending,
228
- error
229
- };
230
- };
231
- const MembershipPage = () => {
232
- const { data: store } = useStore();
233
- const [config2, setConfig] = react.useState({
234
- enable_membership: false,
235
- membership_points_multiplier: 1,
236
- enable_membership_notification: false,
237
- enable_wishlist: true,
238
- enable_promotion_collection: true
239
- });
240
- const { data: curConfig, error, refetch } = useMembershipConfig(store == null ? void 0 : store.id);
241
- const { mutate: saveConfig, isPending } = useUpdateMembershipConfig();
242
- const [spendingAmount, setSpendingAmount] = react.useState(
243
- 1 / config2.membership_points_multiplier
244
- );
245
- react.useEffect(() => {
246
- if (curConfig) {
247
- setConfig(curConfig);
248
- setSpendingAmount(1 / curConfig.membership_points_multiplier);
249
- }
250
- }, [curConfig]);
251
- const handleSave = async () => {
252
- var _a, _b;
253
- try {
254
- await saveConfig({
255
- storeId: store == null ? void 0 : store.id,
256
- config: config2
257
- });
258
- ui.toast.success("Settings saved successfully", {
259
- dismissable: true,
260
- duration: 2500
261
- });
262
- await refetch();
263
- } catch (error2) {
264
- if (axios__default.default.isAxiosError(error2)) {
265
- ui.toast.error("Error saving settings", {
266
- description: (_b = (_a = error2.response) == null ? void 0 : _a.data) == null ? void 0 : _b.message,
267
- dismissable: true,
268
- duration: 2500
269
- });
270
- } else {
271
- ui.toast.error("Error saving settings", {
272
- dismissable: true,
273
- duration: 2500
274
- });
275
- }
276
- }
277
- };
278
- if (error || !config2) {
279
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
280
- "Error: ",
281
- error == null ? void 0 : error.message
282
- ] });
283
- }
284
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-8 rounded-lg", children: [
285
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold mb-4", children: "Membership Settings" }),
286
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
287
- /* @__PURE__ */ jsxRuntime.jsx(
288
- ui.Switch,
289
- {
290
- checked: config2.enable_membership,
291
- onCheckedChange: (checked) => setConfig((prev) => ({ ...prev, enable_membership: checked }))
292
- }
293
- ),
294
- "Enable Membership points"
295
- ] }),
296
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 mt-4", children: [
297
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Spending" }),
298
- /* @__PURE__ */ jsxRuntime.jsx(
299
- ui.Input,
300
- {
301
- className: "w-32",
302
- type: "number",
303
- value: spendingAmount,
304
- onChange: (e) => {
305
- const value = Number(e.target.value) || 0;
306
- const ratio = 1 / value;
307
- setConfig((prev) => ({
308
- ...prev,
309
- membership_points_multiplier: ratio
310
- }));
311
- setSpendingAmount(value);
312
- }
313
- }
314
- ),
315
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "To get 1 point" })
316
- ] }),
317
- /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "my-4" }),
318
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 my-2", children: [
319
- /* @__PURE__ */ jsxRuntime.jsx(
320
- ui.Switch,
321
- {
322
- checked: config2.enable_membership_notification,
323
- onCheckedChange: (checked) => setConfig((prev) => ({
324
- ...prev,
325
- enable_membership_notification: checked
326
- }))
327
- }
328
- ),
329
- "Enable Membership Notification"
330
- ] }),
331
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 my-2", children: [
332
- /* @__PURE__ */ jsxRuntime.jsx(
333
- ui.Switch,
334
- {
335
- checked: config2.enable_wishlist,
336
- onCheckedChange: (checked) => setConfig((prev) => ({
337
- ...prev,
338
- enable_wishlist: checked
339
- }))
340
- }
341
- ),
342
- "Enable Membership Wishlist"
343
- ] }),
344
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 my-2", children: [
345
- /* @__PURE__ */ jsxRuntime.jsx(
346
- ui.Switch,
347
- {
348
- checked: config2.enable_promotion_collection,
349
- onCheckedChange: (checked) => setConfig((prev) => ({
350
- ...prev,
351
- enable_promotion_collection: checked
352
- }))
353
- }
354
- ),
355
- "Enable Promotion Collection"
356
- ] }),
357
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: handleSave, disabled: isPending, className: "mt-5", children: isPending ? "Saving..." : "Save Settings" })
358
- ] });
359
- };
360
- const BannerUpload = () => {
361
- return /* @__PURE__ */ jsxRuntime.jsx(MembershipPage, {});
362
- };
363
- const config$2 = adminSdk.defineRouteConfig({
364
- label: "Membership",
365
- icon: icons.Users
366
- });
367
- const useCreateMembershipConsent = () => {
368
- const [isPending, setIsPending] = react.useState(false);
369
- const [error, setError] = react.useState(null);
370
- const mutate = async (data, { onSuccess } = {}) => {
371
- try {
372
- setIsPending(true);
373
- setError(null);
374
- const response = await axios__default.default.post("/admin/membership-consents", data);
375
- if (onSuccess) {
376
- onSuccess();
377
- }
378
- return response.data;
379
- } catch (err) {
380
- const error2 = err instanceof Error ? err : new Error("Failed to create consent");
381
- setError(error2);
382
- throw error2;
383
- } finally {
384
- setIsPending(false);
385
- }
386
- };
387
- return {
388
- mutate,
389
- isPending,
390
- error
391
- };
392
- };
393
- const useDeleteMembershipConsent = () => {
394
- const [isPending, setIsPending] = react.useState(false);
395
- const [error, setError] = react.useState(null);
396
- const mutate = async (id, { onSuccess } = {}) => {
397
- try {
398
- setIsPending(true);
399
- setError(null);
400
- await axios__default.default.delete(`/admin/membership-consents/${id}`);
401
- if (onSuccess) {
402
- onSuccess();
403
- }
404
- } catch (err) {
405
- const error2 = err instanceof Error ? err : new Error("Failed to delete consent");
406
- setError(error2);
407
- throw error2;
408
- } finally {
409
- setIsPending(false);
410
- }
411
- };
412
- return {
413
- mutate,
414
- isPending,
415
- error
416
- };
417
- };
418
- const useMembershipConsents = () => {
419
- const [data, setData] = react.useState(void 0);
420
- const [isLoading, setIsLoading] = react.useState(true);
421
- const [error, setError] = react.useState(null);
422
- const fetchConsents = async () => {
423
- try {
424
- setIsLoading(true);
425
- setError(null);
426
- const response = await axios__default.default.get("/admin/membership-consents");
427
- setData(
428
- response.data
429
- );
430
- } catch (err) {
431
- setError(
432
- err instanceof Error ? err : new Error("Failed to fetch consents")
433
- );
434
- } finally {
435
- setIsLoading(false);
436
- }
437
- };
438
- react.useEffect(() => {
439
- fetchConsents();
440
- }, []);
441
- return {
442
- data,
443
- isLoading,
444
- error,
445
- refetch: fetchConsents
446
- };
447
- };
448
- const useUpdateMembershipConsent = () => {
449
- const [isPending, setIsPending] = react.useState(false);
450
- const [error, setError] = react.useState(null);
451
- const mutate = async (consentKey, { onSuccess } = {}) => {
452
- try {
453
- setIsPending(true);
454
- setError(null);
455
- const response = await axios__default.default.patch(
456
- `/admin/membership-consents/${consentKey.id}`,
457
- {
458
- name: consentKey.name,
459
- description: consentKey.description
460
- }
461
- );
462
- if (onSuccess) {
463
- onSuccess();
464
- }
465
- return response.data;
466
- } catch (err) {
467
- const error2 = err instanceof Error ? err : new Error("Failed to update consent");
468
- setError(error2);
469
- throw error2;
470
- } finally {
471
- setIsPending(false);
472
- }
473
- };
474
- return {
475
- mutate,
476
- isPending,
477
- error
478
- };
479
- };
480
- const columnHelper$1 = ui.createDataTableColumnHelper();
481
- const columns$1 = [
482
- columnHelper$1.accessor("name", {
483
- header: "Name"
484
- }),
485
- columnHelper$1.accessor("description", {
486
- header: "Description",
487
- maxSize: 250
488
- })
489
- ];
490
- const MembershipConsentsRenderer = () => {
491
- const dialog = ui.usePrompt();
492
- const [pagination, setPagination] = react.useState({
493
- pageSize: 1e3,
494
- pageIndex: 0
495
- });
496
- const [isDrawerOpen, setIsDrawerOpen] = react.useState(false);
497
- const [editingConsent, setEditingConsent] = react.useState(null);
498
- const [formData, setFormData] = react.useState({
499
- name: "",
500
- description: ""
501
- });
502
- const { data, isLoading, refetch } = useMembershipConsents();
503
- const createConsent = useCreateMembershipConsent();
504
- const updateConsent = useUpdateMembershipConsent();
505
- const deleteConsent = useDeleteMembershipConsent();
506
- const table = ui.useDataTable({
507
- columns: columns$1,
508
- data: (data == null ? void 0 : data.consent_keys) || [],
509
- getRowId: (consent) => consent.id,
510
- rowCount: (data == null ? void 0 : data.count) || 0,
511
- isLoading,
512
- pagination: {
513
- state: pagination,
514
- onPaginationChange: setPagination
515
- },
516
- onRowClick: (_, row) => {
517
- openDrawer(row.original);
518
- }
519
- });
520
- const handleInputChange = (e) => {
521
- const { name, value } = e.target;
522
- setFormData((prev) => ({
523
- ...prev,
524
- [name]: name === "min_points" ? Number(value) : value
525
- }));
526
- };
527
- const handleTextAreaChange = (e) => {
528
- const { name, value } = e.target;
529
- setFormData((prev) => ({
530
- ...prev,
531
- [name]: value
532
- }));
533
- };
534
- const handleReset = () => {
535
- setFormData({
536
- name: "",
537
- description: ""
538
- });
539
- };
540
- const openDrawer = (consentKey) => {
541
- if (consentKey) {
542
- setEditingConsent(consentKey);
543
- setFormData({
544
- name: consentKey.name,
545
- description: consentKey.description
546
- });
547
- } else {
548
- setEditingConsent(null);
549
- handleReset();
550
- }
551
- setIsDrawerOpen(true);
552
- };
553
- const closeDrawer = () => {
554
- setIsDrawerOpen(false);
555
- setEditingConsent(null);
556
- handleReset();
557
- refetch();
558
- };
559
- const handleSubmit = async () => {
560
- var _a, _b;
561
- try {
562
- if (!formData.name) {
563
- ui.toast.error("Name is required", { dismissable: true, duration: 2500 });
564
- return;
565
- }
566
- if (editingConsent) {
567
- await updateConsent.mutateAsync({ id: editingConsent.id, ...formData });
568
- ui.toast.success("Consent updated successfully", {
569
- dismissable: true,
570
- duration: 2500
571
- });
572
- } else {
573
- await createConsent.mutateAsync(formData);
574
- ui.toast.success("Consent created successfully", {
575
- dismissable: true,
576
- duration: 2500
577
- });
578
- }
579
- closeDrawer();
580
- } catch (error) {
581
- if (axios__default.default.isAxiosError(error)) {
582
- ui.toast.error("Error saving consent", {
583
- description: (_b = (_a = error.response) == null ? void 0 : _a.data) == null ? void 0 : _b.message,
584
- dismissable: true,
585
- duration: 2500
586
- });
587
- } else {
588
- ui.toast.error("Error saving consent", {
589
- dismissable: true,
590
- duration: 2500
591
- });
592
- }
593
- }
594
- };
595
- const handleDelete = async (id) => {
596
- var _a, _b;
597
- try {
598
- const confirmed = await dialog({
599
- title: "Delete Membership Consent",
600
- description: `Are you sure you want to delete the \`${editingConsent == null ? void 0 : editingConsent.name}\` consent?`
601
- });
602
- if (!confirmed) {
603
- return;
604
- }
605
- await deleteConsent.mutateAsync(id);
606
- ui.toast.success("Consent deleted successfully", {
607
- dismissable: true,
608
- duration: 2500
609
- });
610
- closeDrawer();
611
- } catch (error) {
612
- if (axios__default.default.isAxiosError(error)) {
613
- ui.toast.error("Error deleting consent", {
614
- description: (_b = (_a = error.response) == null ? void 0 : _a.data) == null ? void 0 : _b.message,
615
- dismissable: true,
616
- duration: 2500
617
- });
618
- } else {
619
- ui.toast.error("Error deleting consent", {
620
- dismissable: true,
621
- duration: 2500
622
- });
623
- }
624
- }
625
- };
626
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
627
- /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "flex flex-col p-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.DataTable, { instance: table, children: [
628
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DataTable.Toolbar, { className: "flex flex-col items-start justify-between gap-2 md:flex-row md:items-center", children: [
629
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Membership Consents" }),
630
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: () => openDrawer(), children: "Add Consent" })
631
- ] }),
632
- /* @__PURE__ */ jsxRuntime.jsx(ui.DataTable.Table, {})
633
- ] }) }),
634
- /* @__PURE__ */ jsxRuntime.jsx(ui.Drawer, { open: isDrawerOpen, onOpenChange: setIsDrawerOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Drawer.Content, { children: [
635
- /* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Title, { children: editingConsent ? "Edit Consent" : "Add Consent" }) }),
636
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Drawer.Body, { "aria-description": "Membership Consent Form", children: [
637
- /* @__PURE__ */ jsxRuntime.jsxs(
638
- "div",
639
- {
640
- className: "space-y-4",
641
- "aria-description": "Membership Consent Form",
642
- children: [
643
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Name" }),
644
- /* @__PURE__ */ jsxRuntime.jsx(
645
- ui.Input,
646
- {
647
- name: "name",
648
- value: formData.name,
649
- onChange: handleInputChange
650
- }
651
- ),
652
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Description" }),
653
- /* @__PURE__ */ jsxRuntime.jsx(
654
- ui.Textarea,
655
- {
656
- className: "truncate",
657
- name: "description",
658
- value: formData.description,
659
- onChange: handleTextAreaChange
660
- }
661
- )
662
- ]
663
- }
664
- ),
665
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2 mt-6", children: [
666
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: closeDrawer, children: "Cancel" }),
667
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: handleSubmit, children: editingConsent ? "Update" : "Create" })
668
- ] })
669
- ] }),
670
- /* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Footer, { className: "flex justify-start", children: editingConsent && /* @__PURE__ */ jsxRuntime.jsx(
671
- ui.Button,
672
- {
673
- variant: "danger",
674
- onClick: () => {
675
- handleDelete(editingConsent.id);
676
- },
677
- children: "Delete"
678
- }
679
- ) })
680
- ] }) })
681
- ] });
682
- };
683
- const MembershipConsentPage = () => {
684
- return /* @__PURE__ */ jsxRuntime.jsx(MembershipConsentsRenderer, {});
685
- };
686
- const config$1 = adminSdk.defineRouteConfig({
687
- label: "Membership Consents"
688
- });
689
- const useCreateMembershipTier = () => {
690
- const [isPending, setIsPending] = react.useState(false);
691
- const [error, setError] = react.useState(null);
692
- const mutate = async (data, { onSuccess } = {}) => {
693
- try {
694
- setIsPending(true);
695
- setError(null);
696
- const response = await axios__default.default.post("/admin/member-tiers", data);
697
- if (onSuccess) {
698
- onSuccess();
699
- }
700
- return response.data;
701
- } catch (err) {
702
- const error2 = err instanceof Error ? err : new Error("Failed to create tier");
703
- setError(error2);
704
- throw error2;
705
- } finally {
706
- setIsPending(false);
707
- }
708
- };
709
- return {
710
- mutate,
711
- isPending,
712
- error
713
- };
714
- };
715
- const useDeleteMembershipTier = () => {
716
- const [isPending, setIsPending] = react.useState(false);
717
- const [error, setError] = react.useState(null);
718
- const mutate = async (id, { onSuccess } = {}) => {
719
- try {
720
- setIsPending(true);
721
- setError(null);
722
- await axios__default.default.delete(`/admin/member-tiers/${id}`);
723
- if (onSuccess) {
724
- onSuccess();
725
- }
726
- } catch (err) {
727
- const error2 = err instanceof Error ? err : new Error("Failed to delete tier");
728
- setError(error2);
729
- throw error2;
730
- } finally {
731
- setIsPending(false);
732
- }
733
- };
734
- return {
735
- mutate,
736
- isPending,
737
- error
738
- };
739
- };
740
- const useMembershipTiers = (params = {
741
- limit: 15,
742
- offset: 0,
743
- order: {
744
- min_points: "ASC"
745
- }
746
- }) => {
747
- var _a;
748
- const [data, setData] = react.useState(void 0);
749
- const [isLoading, setIsLoading] = react.useState(true);
750
- const [error, setError] = react.useState(null);
751
- const fetchTiers = async () => {
752
- try {
753
- setIsLoading(true);
754
- setError(null);
755
- const response = await axios__default.default.get("/admin/member-tiers", {
756
- params
757
- });
758
- setData(
759
- response.data
760
- );
761
- } catch (err) {
762
- setError(err instanceof Error ? err : new Error("Failed to fetch tiers"));
763
- } finally {
764
- setIsLoading(false);
765
- }
766
- };
767
- react.useEffect(() => {
768
- fetchTiers();
769
- }, [params.limit, params.offset, (_a = params.order) == null ? void 0 : _a.min_points]);
770
- return {
771
- data,
772
- isLoading,
773
- error,
774
- refetch: fetchTiers
775
- };
776
- };
777
- const useUpdateMembershipTier = () => {
778
- const [isPending, setIsPending] = react.useState(false);
779
- const [error, setError] = react.useState(null);
780
- const mutate = async (tier, { onSuccess } = {}) => {
781
- try {
782
- setIsPending(true);
783
- setError(null);
784
- const response = await axios__default.default.patch(`/admin/member-tiers/${tier.id}`, {
785
- name: tier.name,
786
- description: tier.description,
787
- privilege_description: tier.privilege_description,
788
- min_points: tier.min_points
789
- });
790
- if (onSuccess) {
791
- onSuccess();
792
- }
793
- return response.data;
794
- } catch (err) {
795
- const error2 = err instanceof Error ? err : new Error("Failed to update tier");
796
- setError(error2);
797
- throw error2;
798
- } finally {
799
- setIsPending(false);
800
- }
801
- };
802
- return {
803
- mutate,
804
- isPending,
805
- error
806
- };
807
- };
808
- const columnHelper = ui.createDataTableColumnHelper();
809
- const columns = [
810
- columnHelper.accessor("min_points", {
811
- header: "Min Points"
812
- }),
813
- columnHelper.accessor("name", {
814
- header: "Name"
815
- }),
816
- columnHelper.accessor("description", {
817
- header: "Description",
818
- maxSize: 250
819
- }),
820
- columnHelper.accessor("privilege_description", {
821
- header: "Privilege Description",
822
- maxSize: 250
823
- })
824
- ];
825
- const MembershipTierRenderer = () => {
826
- const dialog = ui.usePrompt();
827
- const [pagination, setPagination] = react.useState({
828
- pageSize: 1e3,
829
- pageIndex: 0
830
- });
831
- const [isDrawerOpen, setIsDrawerOpen] = react.useState(false);
832
- const [editingTier, setEditingTier] = react.useState(null);
833
- const [formData, setFormData] = react.useState({
834
- name: "",
835
- description: "",
836
- privilege_description: "",
837
- min_points: 0
838
- });
839
- const { data, isLoading, refetch } = useMembershipTiers({
840
- limit: pagination.pageSize,
841
- offset: pagination.pageIndex * pagination.pageSize
842
- });
843
- const createTier = useCreateMembershipTier();
844
- const updateTier = useUpdateMembershipTier();
845
- const deleteTier = useDeleteMembershipTier();
846
- const table = ui.useDataTable({
847
- columns,
848
- data: (data == null ? void 0 : data.tiers) || [],
849
- getRowId: (tier) => tier.id,
850
- rowCount: (data == null ? void 0 : data.count) || 0,
851
- isLoading,
852
- pagination: {
853
- state: pagination,
854
- onPaginationChange: setPagination
855
- },
856
- onRowClick: (_, row) => {
857
- openDrawer(row.original);
858
- }
859
- });
860
- const handleInputChange = (e) => {
861
- const { name, value } = e.target;
862
- setFormData((prev) => ({
863
- ...prev,
864
- [name]: name === "min_points" ? Number(value) : value
865
- }));
866
- };
867
- const handleTextAreaChange = (e) => {
868
- const { name, value } = e.target;
869
- setFormData((prev) => ({
870
- ...prev,
871
- [name]: value
872
- }));
873
- };
874
- const handleReset = () => {
875
- setFormData({
876
- name: "",
877
- description: "",
878
- privilege_description: "",
879
- min_points: 0
880
- });
881
- };
882
- const openDrawer = (tier) => {
883
- if (tier) {
884
- setEditingTier(tier);
885
- setFormData({
886
- name: tier.name,
887
- description: tier.description,
888
- privilege_description: tier.privilege_description,
889
- min_points: tier.min_points
890
- });
891
- } else {
892
- setEditingTier(null);
893
- handleReset();
894
- }
895
- setIsDrawerOpen(true);
896
- };
897
- const closeDrawer = () => {
898
- setIsDrawerOpen(false);
899
- setEditingTier(null);
900
- handleReset();
901
- refetch();
902
- };
903
- const handleSubmit = async () => {
904
- var _a, _b;
905
- try {
906
- if (!formData.name) {
907
- ui.toast.error("Name is required", { dismissable: true, duration: 2500 });
908
- return;
909
- }
910
- if (editingTier) {
911
- await updateTier.mutateAsync({ id: editingTier.id, ...formData });
912
- ui.toast.success("Tier updated successfully", {
913
- dismissable: true,
914
- duration: 2500
915
- });
916
- } else {
917
- await createTier.mutateAsync(formData);
918
- ui.toast.success("Tier created successfully", {
919
- dismissable: true,
920
- duration: 2500
921
- });
922
- }
923
- closeDrawer();
924
- } catch (error) {
925
- if (axios__default.default.isAxiosError(error)) {
926
- ui.toast.error("Error saving tier", {
927
- description: (_b = (_a = error.response) == null ? void 0 : _a.data) == null ? void 0 : _b.message,
928
- dismissable: true,
929
- duration: 2500
930
- });
931
- } else {
932
- ui.toast.error("Error saving tier", {
933
- dismissable: true,
934
- duration: 2500
935
- });
936
- }
937
- }
938
- };
939
- const handleDelete = async (id) => {
940
- var _a, _b;
941
- try {
942
- const confirmed = await dialog({
943
- title: "Delete Membership Tier",
944
- description: `Are you sure you want to delete the \`${editingTier == null ? void 0 : editingTier.name}\` tier?`
945
- });
946
- if (!confirmed) {
947
- return;
948
- }
949
- await deleteTier.mutateAsync(id);
950
- ui.toast.success("Tier deleted successfully", {
951
- dismissable: true,
952
- duration: 2500
953
- });
954
- closeDrawer();
955
- } catch (error) {
956
- if (axios__default.default.isAxiosError(error)) {
957
- ui.toast.error("Error deleting tier", {
958
- description: (_b = (_a = error.response) == null ? void 0 : _a.data) == null ? void 0 : _b.message,
959
- dismissable: true,
960
- duration: 2500
961
- });
962
- } else {
963
- ui.toast.error("Error deleting tier", {
964
- dismissable: true,
965
- duration: 2500
966
- });
967
- }
968
- }
969
- };
970
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
971
- /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "flex flex-col p-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.DataTable, { instance: table, children: [
972
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DataTable.Toolbar, { className: "flex flex-col items-start justify-between gap-2 md:flex-row md:items-center", children: [
973
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Membership Tiers" }),
974
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: () => openDrawer(), children: "Add Tier" })
975
- ] }),
976
- /* @__PURE__ */ jsxRuntime.jsx(ui.DataTable.Table, {})
977
- ] }) }),
978
- /* @__PURE__ */ jsxRuntime.jsx(ui.Drawer, { open: isDrawerOpen, onOpenChange: setIsDrawerOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Drawer.Content, { children: [
979
- /* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Title, { children: editingTier ? "Edit Tier" : "Add Tier" }) }),
980
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Drawer.Body, { "aria-description": "Membership Tier Form", children: [
981
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", "aria-description": "Membership Tier Form", children: [
982
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Name" }),
983
- /* @__PURE__ */ jsxRuntime.jsx(
984
- ui.Input,
985
- {
986
- name: "name",
987
- value: formData.name,
988
- onChange: handleInputChange
989
- }
990
- ),
991
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Description" }),
992
- /* @__PURE__ */ jsxRuntime.jsx(
993
- ui.Textarea,
994
- {
995
- className: "truncate",
996
- name: "description",
997
- value: formData.description,
998
- onChange: handleTextAreaChange
999
- }
1000
- ),
1001
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Privilege Description" }),
1002
- /* @__PURE__ */ jsxRuntime.jsx(
1003
- ui.Textarea,
1004
- {
1005
- className: "truncate",
1006
- name: "privilege_description",
1007
- value: formData.privilege_description,
1008
- onChange: handleTextAreaChange
1009
- }
1010
- ),
1011
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { children: "Points" }),
1012
- /* @__PURE__ */ jsxRuntime.jsx(
1013
- ui.Input,
1014
- {
1015
- name: "min_points",
1016
- type: "number",
1017
- value: formData.min_points,
1018
- onChange: handleInputChange
1019
- }
1020
- )
1021
- ] }),
1022
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2 mt-6", children: [
1023
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", onClick: closeDrawer, children: "Cancel" }),
1024
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: handleSubmit, children: editingTier ? "Update" : "Create" })
1025
- ] })
1026
- ] }),
1027
- /* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Footer, { className: "flex justify-start", children: editingTier && /* @__PURE__ */ jsxRuntime.jsx(
1028
- ui.Button,
1029
- {
1030
- variant: "danger",
1031
- onClick: () => {
1032
- handleDelete(editingTier.id);
1033
- },
1034
- children: "Delete"
1035
- }
1036
- ) })
1037
- ] }) })
1038
- ] });
1039
- };
1040
- const MembershipTierPage = () => {
1041
- return /* @__PURE__ */ jsxRuntime.jsx(MembershipTierRenderer, {});
1042
- };
1043
- const config = adminSdk.defineRouteConfig({
1044
- label: "Membership Tiers"
1045
- });
1046
- const widgetModule = { widgets: [
1047
- {
1048
- Component: PromotionWidget,
1049
- zone: ["promotion.details.side.after"]
1050
- }
1051
- ] };
1052
- const routeModule = {
1053
- routes: [
1054
- {
1055
- Component: BannerUpload,
1056
- path: "/membership"
1057
- },
1058
- {
1059
- Component: MembershipConsentPage,
1060
- path: "/membership/member-consents"
1061
- },
1062
- {
1063
- Component: MembershipTierPage,
1064
- path: "/membership/membertier"
1065
- }
1066
- ]
1067
- };
1068
- const menuItemModule = {
1069
- menuItems: [
1070
- {
1071
- label: config$2.label,
1072
- icon: config$2.icon,
1073
- path: "/membership",
1074
- nested: void 0
1075
- },
1076
- {
1077
- label: config$1.label,
1078
- icon: void 0,
1079
- path: "/membership/member-consents",
1080
- nested: void 0
1081
- },
1082
- {
1083
- label: config.label,
1084
- icon: void 0,
1085
- path: "/membership/membertier",
1086
- nested: void 0
1087
- }
1088
- ]
1089
- };
1090
- const formModule = { customFields: {} };
1091
- const displayModule = {
1092
- displays: {}
1093
- };
1094
- const i18nModule = { resources: {} };
1095
- const plugin = {
1096
- widgetModule,
1097
- routeModule,
1098
- menuItemModule,
1099
- formModule,
1100
- displayModule,
1101
- i18nModule
1102
- };
1103
- module.exports = plugin;