@infuro/cms-core 1.0.50 → 1.0.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin.cjs +843 -402
- package/dist/admin.d.cts +13 -1
- package/dist/admin.d.ts +13 -1
- package/dist/admin.js +843 -402
- package/dist/api.cjs +33 -33
- package/dist/api.js +2 -2
- package/dist/{chunk-IPDHT2UV.js → chunk-CTXBYO2J.js} +94 -104
- package/dist/{chunk-UUWAUHUW.cjs → chunk-JN4AFHZ4.cjs} +94 -105
- package/dist/{chunk-JE22VP6S.js → chunk-MXIWUFBP.js} +1 -1
- package/dist/{chunk-LT2WOPKA.js → chunk-NUXR7BUG.js} +179 -59
- package/dist/{chunk-KOTXDSQB.cjs → chunk-UQWZUZ5X.cjs} +1 -1
- package/dist/{chunk-JCMOOPNX.cjs → chunk-YOW457RA.cjs} +208 -88
- package/dist/{emit-order-notification-trigger-6XX7LSC4.js → emit-order-notification-trigger-HZQPPSFB.js} +1 -1
- package/dist/{emit-order-notification-trigger-NASG7ZEO.cjs → emit-order-notification-trigger-NR3VN6C6.cjs} +3 -3
- package/dist/index.cjs +280 -246
- package/dist/index.d.cts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +54 -20
- package/dist/{order-notification-dispatcher-3TA4ETYJ.js → order-notification-dispatcher-AT4IFAGL.js} +1 -1
- package/dist/{order-notification-dispatcher-ZEAZ5SHV.cjs → order-notification-dispatcher-YBAWDOIO.cjs} +4 -4
- package/package.json +1 -1
package/dist/admin.js
CHANGED
|
@@ -26,10 +26,10 @@ import 'jodit/es2021/jodit.min.css';
|
|
|
26
26
|
import { Chart, ArcElement, Tooltip, Legend, CategoryScale, LinearScale, PointElement, LineElement, Title, Filler, BarElement } from 'chart.js';
|
|
27
27
|
import { Line, Doughnut, Bar } from 'react-chartjs-2';
|
|
28
28
|
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
|
29
|
+
import { Country, State, City } from 'country-state-city';
|
|
29
30
|
import { QRCode } from 'react-qr-code';
|
|
30
31
|
import 'typeorm';
|
|
31
32
|
import { Editor, Frame, Element as Element$1, useEditor, useNode } from '@craftjs/core';
|
|
32
|
-
import { Country, State, City } from 'country-state-city';
|
|
33
33
|
import { ThemeProvider } from 'next-themes';
|
|
34
34
|
|
|
35
35
|
var __defProp = Object.defineProperty;
|
|
@@ -230,11 +230,20 @@ var init_infuro_favicon = __esm({
|
|
|
230
230
|
function isSuperAdminGroupName(name) {
|
|
231
231
|
return name === ADMIN_GROUP_NAME;
|
|
232
232
|
}
|
|
233
|
+
function hasEntityPermission(record, entity, action) {
|
|
234
|
+
const p = record?.[entity];
|
|
235
|
+
if (!p) return false;
|
|
236
|
+
if (action === "create") return p.c;
|
|
237
|
+
if (action === "read") return p.r;
|
|
238
|
+
if (action === "update") return p.u;
|
|
239
|
+
return p.d;
|
|
240
|
+
}
|
|
233
241
|
var ADMIN_GROUP_NAME;
|
|
234
242
|
var init_permission_entities = __esm({
|
|
235
243
|
"src/auth/permission-entities.ts"() {
|
|
236
244
|
ADMIN_GROUP_NAME = "Administrator";
|
|
237
245
|
__name(isSuperAdminGroupName, "isSuperAdminGroupName");
|
|
246
|
+
__name(hasEntityPermission, "hasEntityPermission");
|
|
238
247
|
}
|
|
239
248
|
});
|
|
240
249
|
|
|
@@ -436,6 +445,395 @@ var init_Header = __esm({
|
|
|
436
445
|
__name(AdminHeader, "AdminHeader");
|
|
437
446
|
}
|
|
438
447
|
});
|
|
448
|
+
|
|
449
|
+
// src/lib/vendor-role-defaults.ts
|
|
450
|
+
function full() {
|
|
451
|
+
return {
|
|
452
|
+
canCreate: true,
|
|
453
|
+
canRead: true,
|
|
454
|
+
canUpdate: true,
|
|
455
|
+
canDelete: true
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
function read() {
|
|
459
|
+
return {
|
|
460
|
+
canCreate: false,
|
|
461
|
+
canRead: true,
|
|
462
|
+
canUpdate: false,
|
|
463
|
+
canDelete: false
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
function none() {
|
|
467
|
+
return {
|
|
468
|
+
canCreate: false,
|
|
469
|
+
canRead: false,
|
|
470
|
+
canUpdate: false,
|
|
471
|
+
canDelete: false
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
function readUpdate() {
|
|
475
|
+
return {
|
|
476
|
+
canCreate: false,
|
|
477
|
+
canRead: true,
|
|
478
|
+
canUpdate: true,
|
|
479
|
+
canDelete: false
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
function storePerms(spec) {
|
|
483
|
+
const resolve = /* @__PURE__ */ __name((v) => {
|
|
484
|
+
if (v === "full") return full();
|
|
485
|
+
if (v === "read") return read();
|
|
486
|
+
if (v === "none") return none();
|
|
487
|
+
return v;
|
|
488
|
+
}, "resolve");
|
|
489
|
+
const out = {};
|
|
490
|
+
for (const entity of STORE_ENTITIES) {
|
|
491
|
+
out[entity] = resolve(spec[entity] ?? "none");
|
|
492
|
+
}
|
|
493
|
+
return out;
|
|
494
|
+
}
|
|
495
|
+
var VENDOR_RBAC_ENTITIES, STORE_ENTITIES;
|
|
496
|
+
var init_vendor_role_defaults = __esm({
|
|
497
|
+
"src/lib/vendor-role-defaults.ts"() {
|
|
498
|
+
init_vendor_scope();
|
|
499
|
+
VENDOR_RBAC_ENTITIES = [
|
|
500
|
+
...VENDOR_STORE_RBAC_ENTITIES,
|
|
501
|
+
"dashboard",
|
|
502
|
+
"settings",
|
|
503
|
+
"team",
|
|
504
|
+
"roles"
|
|
505
|
+
];
|
|
506
|
+
STORE_ENTITIES = [
|
|
507
|
+
...VENDOR_STORE_RBAC_ENTITIES
|
|
508
|
+
];
|
|
509
|
+
__name(full, "full");
|
|
510
|
+
__name(read, "read");
|
|
511
|
+
__name(none, "none");
|
|
512
|
+
__name(readUpdate, "readUpdate");
|
|
513
|
+
__name(storePerms, "storePerms");
|
|
514
|
+
[
|
|
515
|
+
{
|
|
516
|
+
name: "Owner",
|
|
517
|
+
description: "Full store access and team/role management",
|
|
518
|
+
isSystem: true,
|
|
519
|
+
isOwnerRole: true,
|
|
520
|
+
permissions: {
|
|
521
|
+
...storePerms(Object.fromEntries(STORE_ENTITIES.map((e) => [
|
|
522
|
+
e,
|
|
523
|
+
"full"
|
|
524
|
+
]))),
|
|
525
|
+
dashboard: read(),
|
|
526
|
+
settings: readUpdate(),
|
|
527
|
+
team: full(),
|
|
528
|
+
roles: full()
|
|
529
|
+
}
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
name: "Manager",
|
|
533
|
+
description: "Day-to-day store operations",
|
|
534
|
+
isSystem: true,
|
|
535
|
+
isOwnerRole: false,
|
|
536
|
+
permissions: {
|
|
537
|
+
...storePerms({
|
|
538
|
+
products: "full",
|
|
539
|
+
collections: "full",
|
|
540
|
+
brands: "full",
|
|
541
|
+
product_categories: "full",
|
|
542
|
+
orders: "full",
|
|
543
|
+
vendor_customers: "full",
|
|
544
|
+
discounts: "full",
|
|
545
|
+
order_discounts: "full",
|
|
546
|
+
order_addresses: "full",
|
|
547
|
+
payments: "read",
|
|
548
|
+
taxes: "read",
|
|
549
|
+
attributes: "read"
|
|
550
|
+
}),
|
|
551
|
+
dashboard: read(),
|
|
552
|
+
settings: read(),
|
|
553
|
+
team: none(),
|
|
554
|
+
roles: none()
|
|
555
|
+
}
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
name: "Catalog Staff",
|
|
559
|
+
description: "Manage products and catalog content",
|
|
560
|
+
isSystem: true,
|
|
561
|
+
isOwnerRole: false,
|
|
562
|
+
permissions: {
|
|
563
|
+
...storePerms({
|
|
564
|
+
products: "full",
|
|
565
|
+
collections: "full",
|
|
566
|
+
brands: "full",
|
|
567
|
+
product_categories: "full",
|
|
568
|
+
attributes: "full",
|
|
569
|
+
orders: "read",
|
|
570
|
+
vendor_customers: "read"
|
|
571
|
+
}),
|
|
572
|
+
dashboard: read(),
|
|
573
|
+
settings: none(),
|
|
574
|
+
team: none(),
|
|
575
|
+
roles: none()
|
|
576
|
+
}
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
name: "Fulfillment",
|
|
580
|
+
description: "Orders and fulfillment",
|
|
581
|
+
isSystem: true,
|
|
582
|
+
isOwnerRole: false,
|
|
583
|
+
permissions: {
|
|
584
|
+
...storePerms({
|
|
585
|
+
products: "read",
|
|
586
|
+
orders: "full",
|
|
587
|
+
order_addresses: "full",
|
|
588
|
+
order_discounts: "read",
|
|
589
|
+
vendor_customers: "read"
|
|
590
|
+
}),
|
|
591
|
+
dashboard: read(),
|
|
592
|
+
settings: none(),
|
|
593
|
+
team: none(),
|
|
594
|
+
roles: none()
|
|
595
|
+
}
|
|
596
|
+
},
|
|
597
|
+
{
|
|
598
|
+
name: "Viewer",
|
|
599
|
+
description: "Read-only access to store data",
|
|
600
|
+
isSystem: true,
|
|
601
|
+
isOwnerRole: false,
|
|
602
|
+
permissions: {
|
|
603
|
+
...storePerms(Object.fromEntries(STORE_ENTITIES.map((e) => [
|
|
604
|
+
e,
|
|
605
|
+
"read"
|
|
606
|
+
]))),
|
|
607
|
+
dashboard: read(),
|
|
608
|
+
settings: none(),
|
|
609
|
+
team: none(),
|
|
610
|
+
roles: none()
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
];
|
|
614
|
+
}
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
// src/auth/rbac-debug.ts
|
|
618
|
+
function summarizeEntityPerms(entityPerms) {
|
|
619
|
+
const out = {};
|
|
620
|
+
if (!entityPerms) return out;
|
|
621
|
+
for (const [entity, p] of Object.entries(entityPerms)) {
|
|
622
|
+
out[entity] = {
|
|
623
|
+
c: p.c,
|
|
624
|
+
r: p.r,
|
|
625
|
+
u: p.u,
|
|
626
|
+
d: p.d
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
return out;
|
|
630
|
+
}
|
|
631
|
+
function vendorPortalFallbackReason(user, entity, action) {
|
|
632
|
+
if (!isVendorPortalUser(user)) return null;
|
|
633
|
+
if (entity === "dashboard" && action === "read") return "vendor_portal_dashboard_fallback";
|
|
634
|
+
if (entity === "analytics" && action === "read") return "vendor_portal_analytics_fallback";
|
|
635
|
+
if (entity === "settings" && action === "read") return "vendor_portal_settings_read_fallback";
|
|
636
|
+
if (entity === "upload" && (action === "create" || action === "read")) {
|
|
637
|
+
return "vendor_portal_upload_fallback";
|
|
638
|
+
}
|
|
639
|
+
if (VENDOR_STORE_RBAC_ENTITIES.has(entity) && action === "read") return "vendor_portal_store_read_fallback";
|
|
640
|
+
return null;
|
|
641
|
+
}
|
|
642
|
+
function explainSessionEntityAccess(user, entity, action) {
|
|
643
|
+
const userSnapshot = {
|
|
644
|
+
email: user?.email ?? null,
|
|
645
|
+
id: user?.id ?? null,
|
|
646
|
+
groupId: user?.groupId ?? null,
|
|
647
|
+
groupName: user?.groupName ?? null,
|
|
648
|
+
isRBACAdmin: user?.isRBACAdmin ?? false,
|
|
649
|
+
adminAccess: user?.adminAccess ?? null,
|
|
650
|
+
vendorIds: user?.vendorIds ?? [],
|
|
651
|
+
activeVendorId: user?.activeVendorId ?? null,
|
|
652
|
+
vendorRole: user?.vendorRole ?? null,
|
|
653
|
+
vendorRoleId: user?.vendorRoleId ?? null,
|
|
654
|
+
vendorRoleName: user?.vendorRoleName ?? null,
|
|
655
|
+
isVendorRoleOwner: user?.isVendorRoleOwner ?? false,
|
|
656
|
+
vendorEntityPerms: summarizeEntityPerms(user?.vendorEntityPerms),
|
|
657
|
+
isVendorPortal: user?.isVendorPortal ?? false,
|
|
658
|
+
isVendorOwner: user?.isVendorOwner ?? false,
|
|
659
|
+
isVendorPortalComputed: isVendorPortalUser(user),
|
|
660
|
+
isVendorOwnerComputed: isVendorOwner(user),
|
|
661
|
+
jwtEntityPerms: summarizeEntityPerms(user?.entityPerms),
|
|
662
|
+
jwtEntityPermForTarget: user?.entityPerms?.[entity] ?? null
|
|
663
|
+
};
|
|
664
|
+
if (!user?.email) {
|
|
665
|
+
return {
|
|
666
|
+
allowed: false,
|
|
667
|
+
reason: "no_session_email",
|
|
668
|
+
userSnapshot
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
if (user.isRBACAdmin) {
|
|
672
|
+
return {
|
|
673
|
+
allowed: true,
|
|
674
|
+
reason: "platform_administrator",
|
|
675
|
+
userSnapshot
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
if ((isVendorPortalUser(user) || (user.vendorIds?.length ?? 0) > 0) && entity === "upload" && (action === "create" || action === "read")) {
|
|
679
|
+
return {
|
|
680
|
+
allowed: true,
|
|
681
|
+
reason: "vendor_portal_upload",
|
|
682
|
+
userSnapshot
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
const vendorIds = user.vendorIds ?? [];
|
|
686
|
+
const isStaff = user.vendorRole === "staff";
|
|
687
|
+
const vendorPerms = user.vendorEntityPerms;
|
|
688
|
+
const hasVendorRolePerms = vendorPerms != null && Object.keys(vendorPerms).length > 0;
|
|
689
|
+
const enforceVendorRoleMatrix = vendorIds.length > 0 && (hasVendorRolePerms || user.vendorRoleId != null);
|
|
690
|
+
if (enforceVendorRoleMatrix) {
|
|
691
|
+
const vendorRbacSet = new Set(VENDOR_RBAC_ENTITIES);
|
|
692
|
+
if (vendorRbacSet.has(entity) || entity === "analytics") {
|
|
693
|
+
if (entity === "analytics" && action === "read") {
|
|
694
|
+
const allowed3 = hasEntityPermission(vendorPerms, "dashboard", "read");
|
|
695
|
+
return {
|
|
696
|
+
allowed: allowed3,
|
|
697
|
+
reason: allowed3 ? "vendor_role_analytics_via_dashboard" : "vendor_role_analytics_denied",
|
|
698
|
+
userSnapshot
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
if (user.isVendorRoleOwner === true) {
|
|
702
|
+
return {
|
|
703
|
+
allowed: true,
|
|
704
|
+
reason: "vendor_owner_role_full",
|
|
705
|
+
userSnapshot
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
const allowed2 = hasEntityPermission(vendorPerms, entity, action);
|
|
709
|
+
return {
|
|
710
|
+
allowed: allowed2,
|
|
711
|
+
reason: allowed2 ? "vendor_role_permissions_allow" : "vendor_role_permissions_deny",
|
|
712
|
+
userSnapshot
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
if (vendorIds.length > 0) {
|
|
717
|
+
if (entity === "dashboard" && action === "read") {
|
|
718
|
+
return {
|
|
719
|
+
allowed: true,
|
|
720
|
+
reason: "vendor_link_dashboard_read",
|
|
721
|
+
userSnapshot
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
if (entity === "analytics" && action === "read") {
|
|
725
|
+
return {
|
|
726
|
+
allowed: true,
|
|
727
|
+
reason: "vendor_link_analytics_read",
|
|
728
|
+
userSnapshot
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
if (entity === "settings") {
|
|
732
|
+
if (action === "read") {
|
|
733
|
+
return {
|
|
734
|
+
allowed: true,
|
|
735
|
+
reason: "vendor_link_settings_read",
|
|
736
|
+
userSnapshot
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
if (action === "update" && !isStaff) {
|
|
740
|
+
return {
|
|
741
|
+
allowed: true,
|
|
742
|
+
reason: "vendor_link_settings_update",
|
|
743
|
+
userSnapshot
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
if (VENDOR_STORE_RBAC_ENTITIES.has(entity)) {
|
|
748
|
+
if (isStaff && action === "read") {
|
|
749
|
+
return {
|
|
750
|
+
allowed: true,
|
|
751
|
+
reason: "vendor_staff_store_read",
|
|
752
|
+
userSnapshot
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
if (!isStaff) {
|
|
756
|
+
return {
|
|
757
|
+
allowed: true,
|
|
758
|
+
reason: "vendor_link_store_full",
|
|
759
|
+
userSnapshot
|
|
760
|
+
};
|
|
761
|
+
}
|
|
762
|
+
return {
|
|
763
|
+
allowed: false,
|
|
764
|
+
reason: "vendor_staff_store_write_denied",
|
|
765
|
+
userSnapshot
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
if (isVendorPortalUser(user) && isVendorOwner(user)) {
|
|
770
|
+
if (entity === "dashboard" && action === "read") {
|
|
771
|
+
return {
|
|
772
|
+
allowed: true,
|
|
773
|
+
reason: "vendor_owner_group_dashboard",
|
|
774
|
+
userSnapshot
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
if (entity === "analytics" && action === "read") {
|
|
778
|
+
return {
|
|
779
|
+
allowed: true,
|
|
780
|
+
reason: "vendor_owner_group_analytics",
|
|
781
|
+
userSnapshot
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
if (entity === "settings" && (action === "read" || action === "update")) {
|
|
785
|
+
return {
|
|
786
|
+
allowed: true,
|
|
787
|
+
reason: "vendor_owner_group_settings",
|
|
788
|
+
userSnapshot
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
if (VENDOR_STORE_RBAC_ENTITIES.has(entity)) {
|
|
792
|
+
return {
|
|
793
|
+
allowed: true,
|
|
794
|
+
reason: "vendor_owner_group_store",
|
|
795
|
+
userSnapshot
|
|
796
|
+
};
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
const vendorPortalReason = vendorPortalFallbackReason(user, entity, action);
|
|
800
|
+
if (vendorPortalReason) {
|
|
801
|
+
return {
|
|
802
|
+
allowed: true,
|
|
803
|
+
reason: vendorPortalReason,
|
|
804
|
+
userSnapshot
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
const explicit = user.entityPerms?.[entity];
|
|
808
|
+
if (explicit !== void 0) {
|
|
809
|
+
const allowed2 = hasEntityPermission(user.entityPerms, entity, action);
|
|
810
|
+
return {
|
|
811
|
+
allowed: allowed2,
|
|
812
|
+
reason: allowed2 ? "jwt_entity_perms_allow" : "jwt_entity_perms_deny",
|
|
813
|
+
userSnapshot
|
|
814
|
+
};
|
|
815
|
+
}
|
|
816
|
+
const allowed = hasEntityPermission(user.entityPerms, entity, action);
|
|
817
|
+
return {
|
|
818
|
+
allowed,
|
|
819
|
+
reason: allowed ? "entity_perms_fallback_allow" : "no_matching_rule",
|
|
820
|
+
userSnapshot
|
|
821
|
+
};
|
|
822
|
+
}
|
|
823
|
+
function sessionHasEntityAccessFromExplanation(user, entity, action) {
|
|
824
|
+
return explainSessionEntityAccess(user, entity, action).allowed;
|
|
825
|
+
}
|
|
826
|
+
var init_rbac_debug = __esm({
|
|
827
|
+
"src/auth/rbac-debug.ts"() {
|
|
828
|
+
init_permission_entities();
|
|
829
|
+
init_vendor_role_defaults();
|
|
830
|
+
init_vendor_scope();
|
|
831
|
+
__name(summarizeEntityPerms, "summarizeEntityPerms");
|
|
832
|
+
__name(vendorPortalFallbackReason, "vendorPortalFallbackReason");
|
|
833
|
+
__name(explainSessionEntityAccess, "explainSessionEntityAccess");
|
|
834
|
+
__name(sessionHasEntityAccessFromExplanation, "sessionHasEntityAccessFromExplanation");
|
|
835
|
+
}
|
|
836
|
+
});
|
|
439
837
|
var defaultValue, AdminConfigContext;
|
|
440
838
|
var init_admin_config_context = __esm({
|
|
441
839
|
"src/admin/admin-config-context.tsx"() {
|
|
@@ -455,7 +853,7 @@ var init_admin_config_context = __esm({
|
|
|
455
853
|
var CMS_VERSION;
|
|
456
854
|
var init_cms_version = __esm({
|
|
457
855
|
"src/lib/cms-version.ts"() {
|
|
458
|
-
CMS_VERSION = "1.0.
|
|
856
|
+
CMS_VERSION = "1.0.51" ;
|
|
459
857
|
}
|
|
460
858
|
});
|
|
461
859
|
function useCatalogCategories(enabled = true) {
|
|
@@ -590,6 +988,10 @@ function AdminSidebar({ variant = "sidebar" }) {
|
|
|
590
988
|
const sectionCls7 = "mb-5";
|
|
591
989
|
const headingCls = "text-[11px] font-semibold text-gray-400 uppercase tracking-wider px-2.5 mb-1.5";
|
|
592
990
|
const asideCls = isDrawer ? "w-full h-full min-h-0 bg-white flex flex-col overflow-hidden" : "w-52 h-full min-h-0 bg-white border-r border-gray-200 flex-shrink-0 flex flex-col overflow-hidden";
|
|
991
|
+
const canReadEntity = /* @__PURE__ */ __name((entity) => {
|
|
992
|
+
if (!sessionUser) return true;
|
|
993
|
+
return sessionHasEntityAccessFromExplanation(sessionUser, entity, "read");
|
|
994
|
+
}, "canReadEntity");
|
|
593
995
|
return /* @__PURE__ */ React.createElement("aside", {
|
|
594
996
|
className: asideCls
|
|
595
997
|
}, /* @__PURE__ */ React.createElement("div", {
|
|
@@ -607,30 +1009,40 @@ function AdminSidebar({ variant = "sidebar" }) {
|
|
|
607
1009
|
className: `${linkCls} ${isActive("/admin/dashboard") ? linkActive : linkInactive}`
|
|
608
1010
|
}, /* @__PURE__ */ React.createElement(LayoutDashboard, {
|
|
609
1011
|
className: `h-4 w-4 mr-2 ${isActive("/admin/dashboard") ? iconActive : iconInactive}`
|
|
610
|
-
}), "Dashboard")))), showPlatformNav && customNavSections.length > 0 && customNavSections.map((section) =>
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
}, /* @__PURE__ */ React.createElement(
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
1012
|
+
}), "Dashboard")))), showPlatformNav && customNavSections.length > 0 && customNavSections.map((section) => {
|
|
1013
|
+
const filteredItems = section.items.filter((item) => {
|
|
1014
|
+
const entity = item.href.replace("/admin/", "").split("/")[0];
|
|
1015
|
+
return canReadEntity(entity);
|
|
1016
|
+
});
|
|
1017
|
+
if (filteredItems.length === 0) return null;
|
|
1018
|
+
return /* @__PURE__ */ React.createElement("div", {
|
|
1019
|
+
key: section.title,
|
|
1020
|
+
className: sectionCls7
|
|
1021
|
+
}, /* @__PURE__ */ React.createElement("h3", {
|
|
1022
|
+
className: headingCls
|
|
1023
|
+
}, section.title), /* @__PURE__ */ React.createElement("ul", {
|
|
1024
|
+
className: "space-y-0.5"
|
|
1025
|
+
}, filteredItems.map((item) => {
|
|
1026
|
+
const Icon2 = getIconForItem(item.icon);
|
|
1027
|
+
return /* @__PURE__ */ React.createElement("li", {
|
|
1028
|
+
key: item.href
|
|
1029
|
+
}, /* @__PURE__ */ React.createElement(Link2, {
|
|
1030
|
+
href: item.href,
|
|
1031
|
+
className: `${linkCls} ${isActive(item.href) ? linkActive : linkInactive}`
|
|
1032
|
+
}, /* @__PURE__ */ React.createElement(Icon2, {
|
|
1033
|
+
className: `h-4 w-4 mr-2 ${isActive(item.href) ? iconActive : iconInactive}`
|
|
1034
|
+
}), item.label));
|
|
1035
|
+
})));
|
|
1036
|
+
}), showPlatformNav && customNavSections.length === 0 && customNavItems.length > 0 && /* @__PURE__ */ React.createElement("div", {
|
|
628
1037
|
className: sectionCls7
|
|
629
1038
|
}, /* @__PURE__ */ React.createElement("h3", {
|
|
630
1039
|
className: headingCls
|
|
631
1040
|
}, "Custom"), /* @__PURE__ */ React.createElement("ul", {
|
|
632
1041
|
className: "space-y-0.5"
|
|
633
|
-
}, customNavItems.
|
|
1042
|
+
}, customNavItems.filter((item) => {
|
|
1043
|
+
const entity = item.href.replace("/admin/", "").split("/")[0];
|
|
1044
|
+
return canReadEntity(entity);
|
|
1045
|
+
}).map((item) => {
|
|
634
1046
|
const Icon2 = getIconForItem(item.icon);
|
|
635
1047
|
return /* @__PURE__ */ React.createElement("li", {
|
|
636
1048
|
key: item.href
|
|
@@ -651,85 +1063,92 @@ function AdminSidebar({ variant = "sidebar" }) {
|
|
|
651
1063
|
className: `${linkCls} ${isActive("/admin/dashboard") ? linkActive : linkInactive}`
|
|
652
1064
|
}, /* @__PURE__ */ React.createElement(LayoutDashboard, {
|
|
653
1065
|
className: `h-4 w-4 mr-2 ${isActive("/admin/dashboard") ? iconActive : iconInactive}`
|
|
654
|
-
}), "Dashboard")))), vendorPortal && customNavSections.length > 0 && customNavSections.map((section) =>
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
}, /* @__PURE__ */ React.createElement(
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
1066
|
+
}), "Dashboard")))), vendorPortal && customNavSections.length > 0 && customNavSections.map((section) => {
|
|
1067
|
+
const filteredItems = section.items.filter((item) => {
|
|
1068
|
+
const entity = item.href.replace("/admin/", "").split("/")[0];
|
|
1069
|
+
return canReadEntity(entity);
|
|
1070
|
+
});
|
|
1071
|
+
if (filteredItems.length === 0) return null;
|
|
1072
|
+
return /* @__PURE__ */ React.createElement("div", {
|
|
1073
|
+
key: section.title,
|
|
1074
|
+
className: sectionCls7
|
|
1075
|
+
}, /* @__PURE__ */ React.createElement("h3", {
|
|
1076
|
+
className: headingCls
|
|
1077
|
+
}, section.title), /* @__PURE__ */ React.createElement("ul", {
|
|
1078
|
+
className: "space-y-0.5"
|
|
1079
|
+
}, filteredItems.map((item) => {
|
|
1080
|
+
const Icon2 = getIconForItem(item.icon);
|
|
1081
|
+
return /* @__PURE__ */ React.createElement("li", {
|
|
1082
|
+
key: item.href
|
|
1083
|
+
}, /* @__PURE__ */ React.createElement(Link2, {
|
|
1084
|
+
href: item.href,
|
|
1085
|
+
className: `${linkCls} ${isActive(item.href) ? linkActive : linkInactive}`
|
|
1086
|
+
}, /* @__PURE__ */ React.createElement(Icon2, {
|
|
1087
|
+
className: `h-4 w-4 mr-2 ${isActive(item.href) ? iconActive : iconInactive}`
|
|
1088
|
+
}), item.label));
|
|
1089
|
+
})));
|
|
1090
|
+
}), showStoreNav && /* @__PURE__ */ React.createElement("div", {
|
|
672
1091
|
className: sectionCls7
|
|
673
1092
|
}, /* @__PURE__ */ React.createElement("h3", {
|
|
674
1093
|
className: headingCls
|
|
675
1094
|
}, "Store"), /* @__PURE__ */ React.createElement("ul", {
|
|
676
1095
|
className: "space-y-0.5"
|
|
677
|
-
}, showVendorOnboard && multiVendorEnabled !== false && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1096
|
+
}, showVendorOnboard && multiVendorEnabled !== false && canReadEntity("vendors") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
678
1097
|
href: "/admin/vendors",
|
|
679
1098
|
className: `${linkCls} ${isActive("/admin/vendors") ? linkActive : linkInactive}`
|
|
680
1099
|
}, /* @__PURE__ */ React.createElement(Store, {
|
|
681
1100
|
className: `h-4 w-4 mr-2 ${isActive("/admin/vendors") ? iconActive : iconInactive}`
|
|
682
|
-
}), "Vendors")), showVendorCategories && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1101
|
+
}), "Vendors")), showVendorCategories && canReadEntity("product_categories") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
683
1102
|
href: "/admin/product_categories",
|
|
684
1103
|
className: `${linkCls} ${isActive("/admin/product_categories") ? linkActive : linkInactive}`
|
|
685
1104
|
}, /* @__PURE__ */ React.createElement(FolderTree, {
|
|
686
1105
|
className: `h-4 w-4 mr-2 ${isActive("/admin/product_categories") ? iconActive : iconInactive}`
|
|
687
|
-
}), "Categories")), showVendorCollections && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1106
|
+
}), "Categories")), showVendorCollections && canReadEntity("collections") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
688
1107
|
href: "/admin/collections",
|
|
689
1108
|
className: `${linkCls} ${isActive("/admin/collections") ? linkActive : linkInactive}`
|
|
690
1109
|
}, /* @__PURE__ */ React.createElement(Layers, {
|
|
691
1110
|
className: `h-4 w-4 mr-2 ${isActive("/admin/collections") ? iconActive : iconInactive}`
|
|
692
|
-
}), "Collections")), showVendorBrands && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1111
|
+
}), "Collections")), showVendorBrands && canReadEntity("brands") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
693
1112
|
href: "/admin/brands",
|
|
694
1113
|
className: `${linkCls} ${isActive("/admin/brands") ? linkActive : linkInactive}`
|
|
695
1114
|
}, /* @__PURE__ */ React.createElement(Building2, {
|
|
696
1115
|
className: `h-4 w-4 mr-2 ${isActive("/admin/brands") ? iconActive : iconInactive}`
|
|
697
|
-
}), "Brands")), !hasCustomEventsNav && eventsEnabled !== false ? /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1116
|
+
}), "Brands")), !hasCustomEventsNav && eventsEnabled !== false && canReadEntity("events") ? /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
698
1117
|
href: "/admin/events",
|
|
699
1118
|
className: `${linkCls} ${isActive("/admin/events") ? linkActive : linkInactive}`
|
|
700
1119
|
}, /* @__PURE__ */ React.createElement(CalendarDays, {
|
|
701
1120
|
className: `h-4 w-4 mr-2 ${isActive("/admin/events") ? iconActive : iconInactive}`
|
|
702
|
-
}), "Events")) : null, /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1121
|
+
}), "Events")) : null, canReadEntity("products") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
703
1122
|
href: "/admin/products",
|
|
704
1123
|
className: `${linkCls} ${isActive("/admin/products") ? linkActive : linkInactive}`
|
|
705
1124
|
}, /* @__PURE__ */ React.createElement(ShoppingBag, {
|
|
706
1125
|
className: `h-4 w-4 mr-2 ${isActive("/admin/products") ? iconActive : iconInactive}`
|
|
707
|
-
}), "Products")), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1126
|
+
}), "Products")), canReadEntity("combos") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
708
1127
|
href: "/admin/combos",
|
|
709
1128
|
className: `${linkCls} ${isActive("/admin/combos") ? linkActive : linkInactive}`
|
|
710
1129
|
}, /* @__PURE__ */ React.createElement(Package, {
|
|
711
1130
|
className: `h-4 w-4 mr-2 ${isActive("/admin/combos") ? iconActive : iconInactive}`
|
|
712
|
-
}), "Combos")), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1131
|
+
}), "Combos")), canReadEntity("taxes") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
713
1132
|
href: "/admin/taxes",
|
|
714
1133
|
className: `${linkCls} ${isActive("/admin/taxes") ? linkActive : linkInactive}`
|
|
715
1134
|
}, /* @__PURE__ */ React.createElement(Receipt, {
|
|
716
1135
|
className: `h-4 w-4 mr-2 ${isActive("/admin/taxes") ? iconActive : iconInactive}`
|
|
717
|
-
}), "Taxes")), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1136
|
+
}), "Taxes")), canReadEntity("discounts") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
718
1137
|
href: "/admin/discounts",
|
|
719
1138
|
className: `${linkCls} ${isActive("/admin/discounts") ? linkActive : linkInactive}`
|
|
720
1139
|
}, /* @__PURE__ */ React.createElement(BadgePercent, {
|
|
721
1140
|
className: `h-4 w-4 mr-2 ${isActive("/admin/discounts") ? iconActive : iconInactive}`
|
|
722
|
-
}), "Discounts")), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1141
|
+
}), "Discounts")), canReadEntity("orders") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
723
1142
|
href: "/admin/orders",
|
|
724
1143
|
className: `${linkCls} ${isActive("/admin/orders") ? linkActive : linkInactive}`
|
|
725
1144
|
}, /* @__PURE__ */ React.createElement(ShoppingCart, {
|
|
726
1145
|
className: `h-4 w-4 mr-2 ${isActive("/admin/orders") ? iconActive : iconInactive}`
|
|
727
|
-
}), "Orders")), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1146
|
+
}), "Orders")), canReadEntity("payments") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
728
1147
|
href: "/admin/payments",
|
|
729
1148
|
className: `${linkCls} ${isActive("/admin/payments") ? linkActive : linkInactive}`
|
|
730
1149
|
}, /* @__PURE__ */ React.createElement(CreditCard, {
|
|
731
1150
|
className: `h-4 w-4 mr-2 ${isActive("/admin/payments") ? iconActive : iconInactive}`
|
|
732
|
-
}), "Payments")), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1151
|
+
}), "Payments")), canReadEntity("vendor_customers") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
733
1152
|
href: "/admin/vendor_customers",
|
|
734
1153
|
className: `${linkCls} ${isActive("/admin/vendor_customers") ? linkActive : linkInactive}`
|
|
735
1154
|
}, /* @__PURE__ */ React.createElement(Users, {
|
|
@@ -740,32 +1159,32 @@ function AdminSidebar({ variant = "sidebar" }) {
|
|
|
740
1159
|
className: headingCls
|
|
741
1160
|
}, "Management"), /* @__PURE__ */ React.createElement("ul", {
|
|
742
1161
|
className: "space-y-0.5"
|
|
743
|
-
}, /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1162
|
+
}, canReadEntity("contacts") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
744
1163
|
href: "/admin/contacts",
|
|
745
1164
|
className: `${linkCls} ${isActive("/admin/contacts") ? linkActive : linkInactive}`
|
|
746
1165
|
}, /* @__PURE__ */ React.createElement(Inbox, {
|
|
747
1166
|
className: `h-4 w-4 mr-2 ${isActive("/admin/contacts") ? iconActive : iconInactive}`
|
|
748
|
-
}), "Contacts")), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1167
|
+
}), "Contacts")), canReadEntity("blogs") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
749
1168
|
href: "/admin/blogs",
|
|
750
1169
|
className: `${linkCls} ${isActive("/admin/blogs") ? linkActive : linkInactive}`
|
|
751
1170
|
}, /* @__PURE__ */ React.createElement(File, {
|
|
752
1171
|
className: `h-4 w-4 mr-2 ${isActive("/admin/blogs") ? iconActive : iconInactive}`
|
|
753
|
-
}), "Blogs")), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1172
|
+
}), "Blogs")), canReadEntity("pages") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
754
1173
|
href: "/admin/pages",
|
|
755
1174
|
className: `${linkCls} ${isActive("/admin/pages") ? linkActive : linkInactive}`
|
|
756
1175
|
}, /* @__PURE__ */ React.createElement(LinkIcon, {
|
|
757
1176
|
className: `h-4 w-4 mr-2 ${isActive("/admin/pages") ? iconActive : iconInactive}`
|
|
758
|
-
}), "Pages")), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1177
|
+
}), "Pages")), canReadEntity("forms") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
759
1178
|
href: "/admin/forms",
|
|
760
1179
|
className: `${linkCls} ${isActive("/admin/forms") ? linkActive : linkInactive}`
|
|
761
1180
|
}, /* @__PURE__ */ React.createElement(ClipboardList, {
|
|
762
1181
|
className: `h-4 w-4 mr-2 ${isActive("/admin/forms") ? iconActive : iconInactive}`
|
|
763
|
-
}), "Forms")), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1182
|
+
}), "Forms")), canReadEntity("form_submissions") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
764
1183
|
href: "/admin/submissions",
|
|
765
1184
|
className: `${linkCls} ${isActive("/admin/submissions") ? linkActive : linkInactive}`
|
|
766
1185
|
}, /* @__PURE__ */ React.createElement(MessageSquare, {
|
|
767
1186
|
className: `h-4 w-4 mr-2 ${isActive("/admin/submissions") ? iconActive : iconInactive}`
|
|
768
|
-
}), "Submissions")), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1187
|
+
}), "Submissions")), canReadEntity("upload") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
769
1188
|
href: "/admin/media",
|
|
770
1189
|
className: `${linkCls} ${isActive("/admin/media") ? linkActive : linkInactive}`
|
|
771
1190
|
}, /* @__PURE__ */ React.createElement(Image$1, {
|
|
@@ -802,12 +1221,12 @@ function AdminSidebar({ variant = "sidebar" }) {
|
|
|
802
1221
|
className: headingCls
|
|
803
1222
|
}, "System"), /* @__PURE__ */ React.createElement("ul", {
|
|
804
1223
|
className: "space-y-0.5"
|
|
805
|
-
}, /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1224
|
+
}, canReadEntity("users") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
806
1225
|
href: "/admin/users",
|
|
807
1226
|
className: `${linkCls} ${isActive("/admin/users") ? linkActive : linkInactive}`
|
|
808
1227
|
}, /* @__PURE__ */ React.createElement(Users, {
|
|
809
1228
|
className: `h-4 w-4 mr-2 ${isActive("/admin/users") ? iconActive : iconInactive}`
|
|
810
|
-
}), "Users")), /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
1229
|
+
}), "Users")), canReadEntity("roles") && /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement(Link2, {
|
|
811
1230
|
href: "/admin/roles",
|
|
812
1231
|
className: `${linkCls} ${isActive("/admin/roles") ? linkActive : linkInactive}`
|
|
813
1232
|
}, /* @__PURE__ */ React.createElement(Shield, {
|
|
@@ -854,6 +1273,7 @@ var init_Sidebar = __esm({
|
|
|
854
1273
|
"src/components/Admin/Sidebar.tsx"() {
|
|
855
1274
|
"use client";
|
|
856
1275
|
init_vendor_scope();
|
|
1276
|
+
init_rbac_debug();
|
|
857
1277
|
init_admin_config_context();
|
|
858
1278
|
init_infuro_favicon();
|
|
859
1279
|
init_cms_version();
|
|
@@ -1480,7 +1900,15 @@ function useEventsSettings() {
|
|
|
1480
1900
|
requireEventApproval
|
|
1481
1901
|
};
|
|
1482
1902
|
}
|
|
1483
|
-
function AdminLayout({ children, customNavItems = [], customNavSections = [], customCrudConfigs = {}, categoryRelatedProductLabels = {}, renderOrderDetailFooter, theme, themeRegistry, pluginDescriptors = [] }) {
|
|
1903
|
+
function AdminLayout({ children, customNavItems = [], customNavSections = [], customCrudConfigs = {}, categoryRelatedProductLabels = {}, renderOrderDetailFooter, extraNotificationVariables, theme, themeRegistry, pluginDescriptors = [] }) {
|
|
1904
|
+
useEffect(() => {
|
|
1905
|
+
document.documentElement.style.overflow = "hidden";
|
|
1906
|
+
document.body.style.overflow = "hidden";
|
|
1907
|
+
return () => {
|
|
1908
|
+
document.documentElement.style.overflow = "";
|
|
1909
|
+
document.body.style.overflow = "";
|
|
1910
|
+
};
|
|
1911
|
+
}, []);
|
|
1484
1912
|
const resolvedTheme = useResolvedTheme(theme, themeRegistry);
|
|
1485
1913
|
const { storeEnabled, currency } = useStoreEnabled();
|
|
1486
1914
|
const { multiVendorEnabled, vendorCanCreateCategories, vendorCanCreateCollections, vendorCanCreateBrands, requireProductApproval } = useMultiVendorSettings();
|
|
@@ -1501,6 +1929,7 @@ function AdminLayout({ children, customNavItems = [], customNavSections = [], cu
|
|
|
1501
1929
|
customCrudConfigs,
|
|
1502
1930
|
categoryRelatedProductLabels,
|
|
1503
1931
|
renderOrderDetailFooter,
|
|
1932
|
+
extraNotificationVariables,
|
|
1504
1933
|
theme: resolvedTheme,
|
|
1505
1934
|
themeRegistry,
|
|
1506
1935
|
pluginDescriptors: mergedPluginDescriptors,
|
|
@@ -1519,6 +1948,7 @@ function AdminLayout({ children, customNavItems = [], customNavSections = [], cu
|
|
|
1519
1948
|
customCrudConfigs,
|
|
1520
1949
|
categoryRelatedProductLabels,
|
|
1521
1950
|
renderOrderDetailFooter,
|
|
1951
|
+
extraNotificationVariables,
|
|
1522
1952
|
resolvedTheme,
|
|
1523
1953
|
themeRegistry,
|
|
1524
1954
|
mergedPluginDescriptors,
|
|
@@ -4375,6 +4805,8 @@ function AdminCRUD({ title, apiEndpoint, columns, addEditPageUrl, customViewPage
|
|
|
4375
4805
|
const hasLoadedRef = useRef(false);
|
|
4376
4806
|
const isMobile = useIsMobile();
|
|
4377
4807
|
const showGroupColumn = !!manageUserGroups && roleOptions.length > 0;
|
|
4808
|
+
const { data: session } = useSession();
|
|
4809
|
+
const sessionUser = session?.user;
|
|
4378
4810
|
const listColumns = useMemo(() => Array.isArray(columns) ? columns.filter((c) => !c.hideInTable) : [], [
|
|
4379
4811
|
columns
|
|
4380
4812
|
]);
|
|
@@ -4915,6 +5347,9 @@ function AdminCRUD({ title, apiEndpoint, columns, addEditPageUrl, customViewPage
|
|
|
4915
5347
|
withListFrom
|
|
4916
5348
|
]);
|
|
4917
5349
|
const resourceName = apiEndpoint.replace("/api/", "");
|
|
5350
|
+
const canCreate = !sessionUser || sessionHasEntityAccessFromExplanation(sessionUser, resourceName, "create");
|
|
5351
|
+
const canUpdate = !sessionUser || sessionHasEntityAccessFromExplanation(sessionUser, resourceName, "update");
|
|
5352
|
+
const canDelete = !sessionUser || sessionHasEntityAccessFromExplanation(sessionUser, resourceName, "delete");
|
|
4918
5353
|
const dedicatedRecordEditHref = /* @__PURE__ */ __name((recordId) => addEditPage && (resourceName === "orders" || resourceName === "events") ? withListFrom(`${addEditPageUrl}/${recordId}/edit`) : addEditPage ? withListFrom(`${addEditPageUrl}/${recordId}`) : "", "dedicatedRecordEditHref");
|
|
4919
5354
|
const showDedicatedDuplicate = addEditPage && !CRUD_NO_DUPLICATE_RESOURCES.has(resourceName);
|
|
4920
5355
|
const hasCustomView = customViewPageUrl && customViewPageUrl.length > 0;
|
|
@@ -5074,15 +5509,15 @@ function AdminCRUD({ title, apiEndpoint, columns, addEditPageUrl, customViewPage
|
|
|
5074
5509
|
onClick: /* @__PURE__ */ __name(() => setBulkDialogOpen(true), "onClick"),
|
|
5075
5510
|
variant: "outline",
|
|
5076
5511
|
className: "bg-transparent text-white border-gray-600 hover:bg-gray-700 text-xs h-8"
|
|
5077
|
-
}, /* @__PURE__ */ React.createElement(
|
|
5512
|
+
}, /* @__PURE__ */ React.createElement(Download, {
|
|
5078
5513
|
className: "h-3.5 w-3.5 mr-1"
|
|
5079
5514
|
}), "Import"), /* @__PURE__ */ React.createElement(Button, {
|
|
5080
5515
|
onClick: handleExport,
|
|
5081
5516
|
variant: "outline",
|
|
5082
5517
|
className: "bg-transparent text-white border-gray-600 hover:bg-gray-700 text-xs h-8"
|
|
5083
|
-
}, /* @__PURE__ */ React.createElement(
|
|
5518
|
+
}, /* @__PURE__ */ React.createElement(Upload, {
|
|
5084
5519
|
className: "h-3.5 w-3.5 mr-1"
|
|
5085
|
-
}), "Export"), !addEditPage && /* @__PURE__ */ React.createElement(Button, {
|
|
5520
|
+
}), "Export"), canCreate && !addEditPage && /* @__PURE__ */ React.createElement(Button, {
|
|
5086
5521
|
onClick: /* @__PURE__ */ __name(() => {
|
|
5087
5522
|
setEditingItem(null);
|
|
5088
5523
|
setDuplicateSeed(null);
|
|
@@ -5091,7 +5526,7 @@ function AdminCRUD({ title, apiEndpoint, columns, addEditPageUrl, customViewPage
|
|
|
5091
5526
|
className: "bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs h-8"
|
|
5092
5527
|
}, /* @__PURE__ */ React.createElement(Plus, {
|
|
5093
5528
|
className: "h-3.5 w-3.5"
|
|
5094
|
-
}), "Add"), addEditPage && dedicatedCreateHref && /* @__PURE__ */ React.createElement(Link2, {
|
|
5529
|
+
}), "Add"), canCreate && addEditPage && dedicatedCreateHref && /* @__PURE__ */ React.createElement(Link2, {
|
|
5095
5530
|
href: dedicatedCreateHref,
|
|
5096
5531
|
className: "inline-flex items-center gap-1 bg-white text-gray-800 hover:bg-gray-100 border-0 text-xs h-8 px-3 rounded-md font-medium"
|
|
5097
5532
|
}, /* @__PURE__ */ React.createElement(Plus, {
|
|
@@ -5250,7 +5685,7 @@ function AdminCRUD({ title, apiEndpoint, columns, addEditPageUrl, customViewPage
|
|
|
5250
5685
|
onClick: /* @__PURE__ */ __name((e) => e.stopPropagation(), "onClick")
|
|
5251
5686
|
}, /* @__PURE__ */ React.createElement("div", {
|
|
5252
5687
|
className: "flex items-center justify-center gap-1"
|
|
5253
|
-
}, customRowActions ? customRowActions(item) : /* @__PURE__ */ React.createElement(React.Fragment, null, !addEditPage && /* @__PURE__ */ React.createElement(Button, {
|
|
5688
|
+
}, customRowActions ? customRowActions(item) : /* @__PURE__ */ React.createElement(React.Fragment, null, canUpdate && !addEditPage && /* @__PURE__ */ React.createElement(Button, {
|
|
5254
5689
|
variant: "outline",
|
|
5255
5690
|
size: "icon",
|
|
5256
5691
|
className: "h-7 w-7",
|
|
@@ -5260,7 +5695,7 @@ function AdminCRUD({ title, apiEndpoint, columns, addEditPageUrl, customViewPage
|
|
|
5260
5695
|
className: "h-3.5 w-3.5"
|
|
5261
5696
|
}), /* @__PURE__ */ React.createElement("span", {
|
|
5262
5697
|
className: "sr-only"
|
|
5263
|
-
}, "Edit")), addEditPage && /* @__PURE__ */ React.createElement(Button, {
|
|
5698
|
+
}, "Edit")), canUpdate && addEditPage && /* @__PURE__ */ React.createElement(Button, {
|
|
5264
5699
|
variant: "outline",
|
|
5265
5700
|
size: "icon",
|
|
5266
5701
|
className: "h-7 w-7",
|
|
@@ -5270,7 +5705,7 @@ function AdminCRUD({ title, apiEndpoint, columns, addEditPageUrl, customViewPage
|
|
|
5270
5705
|
className: "h-3.5 w-3.5"
|
|
5271
5706
|
}), /* @__PURE__ */ React.createElement("span", {
|
|
5272
5707
|
className: "sr-only"
|
|
5273
|
-
}, "Edit")), showDuplicateEntry && /* @__PURE__ */ React.createElement(Button, {
|
|
5708
|
+
}, "Edit")), canCreate && showDuplicateEntry && /* @__PURE__ */ React.createElement(Button, {
|
|
5274
5709
|
variant: "outline",
|
|
5275
5710
|
size: "icon",
|
|
5276
5711
|
className: "h-7 w-7",
|
|
@@ -5296,7 +5731,7 @@ function AdminCRUD({ title, apiEndpoint, columns, addEditPageUrl, customViewPage
|
|
|
5296
5731
|
className: "h-3.5 w-3.5"
|
|
5297
5732
|
}), /* @__PURE__ */ React.createElement("span", {
|
|
5298
5733
|
className: "sr-only"
|
|
5299
|
-
}, "Resend invite")), /* @__PURE__ */ React.createElement(Button, {
|
|
5734
|
+
}, "Resend invite")), canDelete && /* @__PURE__ */ React.createElement(Button, {
|
|
5300
5735
|
variant: "outline",
|
|
5301
5736
|
size: "icon",
|
|
5302
5737
|
className: "h-7 w-7 border-red-300 text-red-600 hover:text-red-700",
|
|
@@ -5434,6 +5869,7 @@ var init_CRUD = __esm({
|
|
|
5434
5869
|
init_dropdown_menu();
|
|
5435
5870
|
init_utils();
|
|
5436
5871
|
init_use_mobile();
|
|
5872
|
+
init_rbac_debug();
|
|
5437
5873
|
init_BulkUploadDialog();
|
|
5438
5874
|
init_admin_list_return_url();
|
|
5439
5875
|
init_build_crud_list_filters_from_columns();
|
|
@@ -15502,6 +15938,18 @@ var init_email_recipients = __esm({
|
|
|
15502
15938
|
__name(serializeEmailRecipients, "serializeEmailRecipients");
|
|
15503
15939
|
}
|
|
15504
15940
|
});
|
|
15941
|
+
function useNotificationVariables() {
|
|
15942
|
+
const config = useContext(AdminConfigContext);
|
|
15943
|
+
const extra = config?.extraNotificationVariables ?? [];
|
|
15944
|
+
const vars = [
|
|
15945
|
+
...KNOWN_VARS,
|
|
15946
|
+
...extra.map((e) => e.name)
|
|
15947
|
+
];
|
|
15948
|
+
return {
|
|
15949
|
+
vars,
|
|
15950
|
+
extra
|
|
15951
|
+
};
|
|
15952
|
+
}
|
|
15505
15953
|
function getEmailTriggerDefaults(triggerKey, audience = "customer") {
|
|
15506
15954
|
if (audience === "vendor") {
|
|
15507
15955
|
return VENDOR_EMAIL_TRIGGER_DEFAULTS[triggerKey] ?? {
|
|
@@ -15645,6 +16093,7 @@ var KNOWN_VARS, EMAIL_TRIGGER_DEFAULTS, VENDOR_EMAIL_TRIGGER_DEFAULTS, ADMIN_EMA
|
|
|
15645
16093
|
var init_order_notification_bindings_shared = __esm({
|
|
15646
16094
|
"src/admin/components/order-notification-bindings-shared.ts"() {
|
|
15647
16095
|
"use client";
|
|
16096
|
+
init_admin_config_context();
|
|
15648
16097
|
KNOWN_VARS = [
|
|
15649
16098
|
"orderId",
|
|
15650
16099
|
"orderNumber",
|
|
@@ -15659,6 +16108,7 @@ var init_order_notification_bindings_shared = __esm({
|
|
|
15659
16108
|
"invoiceNumber",
|
|
15660
16109
|
"invoiceUrl"
|
|
15661
16110
|
];
|
|
16111
|
+
__name(useNotificationVariables, "useNotificationVariables");
|
|
15662
16112
|
EMAIL_TRIGGER_DEFAULTS = {
|
|
15663
16113
|
order_placed: {
|
|
15664
16114
|
subject: "Your order {{orderNumber}} is confirmed",
|
|
@@ -16362,16 +16812,23 @@ function TriggerEmailEditor({ triggerKey, label, description, audience = "custom
|
|
|
16362
16812
|
cancelled = true;
|
|
16363
16813
|
};
|
|
16364
16814
|
}, []);
|
|
16815
|
+
const { vars: availableVars, extra: extraVars } = useNotificationVariables();
|
|
16365
16816
|
const visibleVars = useMemo(() => {
|
|
16366
|
-
return
|
|
16817
|
+
return availableVars.filter((v) => {
|
|
16367
16818
|
if (v === "vendorName" || v === "vendorId") return multiVendorOn;
|
|
16368
16819
|
if (v === "eventName") return eventsOn;
|
|
16369
16820
|
return true;
|
|
16370
16821
|
});
|
|
16371
16822
|
}, [
|
|
16823
|
+
availableVars,
|
|
16372
16824
|
multiVendorOn,
|
|
16373
16825
|
eventsOn
|
|
16374
16826
|
]);
|
|
16827
|
+
const getVarHint = /* @__PURE__ */ __name((v) => {
|
|
16828
|
+
if (v in VAR_HINTS) return VAR_HINTS[v];
|
|
16829
|
+
const match = extraVars.find((e) => e.name === v);
|
|
16830
|
+
return match?.hint || match?.label || v;
|
|
16831
|
+
}, "getVarHint");
|
|
16375
16832
|
return /* @__PURE__ */ React.createElement("div", {
|
|
16376
16833
|
className: "space-y-3 border-t border-gray-100 pt-4 first:border-t-0 first:pt-0 dark:border-gray-700"
|
|
16377
16834
|
}, /* @__PURE__ */ React.createElement("div", {
|
|
@@ -16434,7 +16891,7 @@ function TriggerEmailEditor({ triggerKey, label, description, audience = "custom
|
|
|
16434
16891
|
}, visibleVars.map((v) => /* @__PURE__ */ React.createElement("button", {
|
|
16435
16892
|
key: v,
|
|
16436
16893
|
type: "button",
|
|
16437
|
-
title:
|
|
16894
|
+
title: getVarHint(v),
|
|
16438
16895
|
onClick: /* @__PURE__ */ __name(() => insertVariable(v), "onClick"),
|
|
16439
16896
|
className: "rounded border border-gray-200 bg-white px-2 py-1 font-mono text-[11px] text-gray-700 hover:border-blue-300 hover:bg-blue-50 dark:border-gray-600 dark:bg-gray-900 dark:text-gray-300 dark:hover:border-blue-700 dark:hover:bg-blue-950/40"
|
|
16440
16897
|
}, `{{${v}}}`))), /* @__PURE__ */ React.createElement("p", {
|
|
@@ -16480,6 +16937,12 @@ function PushTriggerBindings({ audience = "customer" }) {
|
|
|
16480
16937
|
const bodyRef = useRef(null);
|
|
16481
16938
|
const subjectRef = useRef(null);
|
|
16482
16939
|
const lastFocused = useRef("body");
|
|
16940
|
+
const { vars: availableVars, extra: extraVars } = useNotificationVariables();
|
|
16941
|
+
const getVarHint = /* @__PURE__ */ __name((v) => {
|
|
16942
|
+
if (v in VAR_HINTS2) return VAR_HINTS2[v];
|
|
16943
|
+
const match = extraVars.find((e) => e.name === v);
|
|
16944
|
+
return match?.hint || match?.label || v;
|
|
16945
|
+
}, "getVarHint");
|
|
16483
16946
|
useEffect(() => {
|
|
16484
16947
|
let cancelled = false;
|
|
16485
16948
|
(async () => {
|
|
@@ -16701,11 +17164,11 @@ function PushTriggerBindings({ audience = "customer" }) {
|
|
|
16701
17164
|
className: "text-xs font-medium text-gray-700 dark:text-gray-300"
|
|
16702
17165
|
}, "Insert Variables"), /* @__PURE__ */ React.createElement("div", {
|
|
16703
17166
|
className: "flex flex-wrap gap-1.5"
|
|
16704
|
-
},
|
|
17167
|
+
}, availableVars.map((v) => /* @__PURE__ */ React.createElement("button", {
|
|
16705
17168
|
key: v,
|
|
16706
17169
|
type: "button",
|
|
16707
17170
|
onClick: /* @__PURE__ */ __name(() => insertVariable(v), "onClick"),
|
|
16708
|
-
title:
|
|
17171
|
+
title: getVarHint(v),
|
|
16709
17172
|
className: "px-2 py-1 bg-gray-100 hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300 rounded text-xs font-mono border border-gray-200 dark:border-gray-700 transition-colors"
|
|
16710
17173
|
}, `{{${v}}}`)))), /* @__PURE__ */ React.createElement("div", {
|
|
16711
17174
|
className: "space-y-1.5"
|
|
@@ -20811,183 +21274,6 @@ var init_PluginsPage = __esm({
|
|
|
20811
21274
|
}
|
|
20812
21275
|
});
|
|
20813
21276
|
|
|
20814
|
-
// src/lib/vendor-role-defaults.ts
|
|
20815
|
-
function full() {
|
|
20816
|
-
return {
|
|
20817
|
-
canCreate: true,
|
|
20818
|
-
canRead: true,
|
|
20819
|
-
canUpdate: true,
|
|
20820
|
-
canDelete: true
|
|
20821
|
-
};
|
|
20822
|
-
}
|
|
20823
|
-
function read() {
|
|
20824
|
-
return {
|
|
20825
|
-
canCreate: false,
|
|
20826
|
-
canRead: true,
|
|
20827
|
-
canUpdate: false,
|
|
20828
|
-
canDelete: false
|
|
20829
|
-
};
|
|
20830
|
-
}
|
|
20831
|
-
function none() {
|
|
20832
|
-
return {
|
|
20833
|
-
canCreate: false,
|
|
20834
|
-
canRead: false,
|
|
20835
|
-
canUpdate: false,
|
|
20836
|
-
canDelete: false
|
|
20837
|
-
};
|
|
20838
|
-
}
|
|
20839
|
-
function readUpdate() {
|
|
20840
|
-
return {
|
|
20841
|
-
canCreate: false,
|
|
20842
|
-
canRead: true,
|
|
20843
|
-
canUpdate: true,
|
|
20844
|
-
canDelete: false
|
|
20845
|
-
};
|
|
20846
|
-
}
|
|
20847
|
-
function storePerms(spec) {
|
|
20848
|
-
const resolve = /* @__PURE__ */ __name((v) => {
|
|
20849
|
-
if (v === "full") return full();
|
|
20850
|
-
if (v === "read") return read();
|
|
20851
|
-
if (v === "none") return none();
|
|
20852
|
-
return v;
|
|
20853
|
-
}, "resolve");
|
|
20854
|
-
const out = {};
|
|
20855
|
-
for (const entity of STORE_ENTITIES) {
|
|
20856
|
-
out[entity] = resolve(spec[entity] ?? "none");
|
|
20857
|
-
}
|
|
20858
|
-
return out;
|
|
20859
|
-
}
|
|
20860
|
-
var STORE_ENTITIES;
|
|
20861
|
-
var init_vendor_role_defaults = __esm({
|
|
20862
|
-
"src/lib/vendor-role-defaults.ts"() {
|
|
20863
|
-
init_vendor_scope();
|
|
20864
|
-
[
|
|
20865
|
-
...VENDOR_STORE_RBAC_ENTITIES,
|
|
20866
|
-
"dashboard",
|
|
20867
|
-
"settings",
|
|
20868
|
-
"team",
|
|
20869
|
-
"roles"
|
|
20870
|
-
];
|
|
20871
|
-
STORE_ENTITIES = [
|
|
20872
|
-
...VENDOR_STORE_RBAC_ENTITIES
|
|
20873
|
-
];
|
|
20874
|
-
__name(full, "full");
|
|
20875
|
-
__name(read, "read");
|
|
20876
|
-
__name(none, "none");
|
|
20877
|
-
__name(readUpdate, "readUpdate");
|
|
20878
|
-
__name(storePerms, "storePerms");
|
|
20879
|
-
[
|
|
20880
|
-
{
|
|
20881
|
-
name: "Owner",
|
|
20882
|
-
description: "Full store access and team/role management",
|
|
20883
|
-
isSystem: true,
|
|
20884
|
-
isOwnerRole: true,
|
|
20885
|
-
permissions: {
|
|
20886
|
-
...storePerms(Object.fromEntries(STORE_ENTITIES.map((e) => [
|
|
20887
|
-
e,
|
|
20888
|
-
"full"
|
|
20889
|
-
]))),
|
|
20890
|
-
dashboard: read(),
|
|
20891
|
-
settings: readUpdate(),
|
|
20892
|
-
team: full(),
|
|
20893
|
-
roles: full()
|
|
20894
|
-
}
|
|
20895
|
-
},
|
|
20896
|
-
{
|
|
20897
|
-
name: "Manager",
|
|
20898
|
-
description: "Day-to-day store operations",
|
|
20899
|
-
isSystem: true,
|
|
20900
|
-
isOwnerRole: false,
|
|
20901
|
-
permissions: {
|
|
20902
|
-
...storePerms({
|
|
20903
|
-
products: "full",
|
|
20904
|
-
collections: "full",
|
|
20905
|
-
brands: "full",
|
|
20906
|
-
product_categories: "full",
|
|
20907
|
-
orders: "full",
|
|
20908
|
-
vendor_customers: "full",
|
|
20909
|
-
discounts: "full",
|
|
20910
|
-
order_discounts: "full",
|
|
20911
|
-
order_addresses: "full",
|
|
20912
|
-
payments: "read",
|
|
20913
|
-
taxes: "read",
|
|
20914
|
-
attributes: "read"
|
|
20915
|
-
}),
|
|
20916
|
-
dashboard: read(),
|
|
20917
|
-
settings: read(),
|
|
20918
|
-
team: none(),
|
|
20919
|
-
roles: none()
|
|
20920
|
-
}
|
|
20921
|
-
},
|
|
20922
|
-
{
|
|
20923
|
-
name: "Catalog Staff",
|
|
20924
|
-
description: "Manage products and catalog content",
|
|
20925
|
-
isSystem: true,
|
|
20926
|
-
isOwnerRole: false,
|
|
20927
|
-
permissions: {
|
|
20928
|
-
...storePerms({
|
|
20929
|
-
products: "full",
|
|
20930
|
-
collections: "full",
|
|
20931
|
-
brands: "full",
|
|
20932
|
-
product_categories: "full",
|
|
20933
|
-
attributes: "full",
|
|
20934
|
-
orders: "read",
|
|
20935
|
-
vendor_customers: "read"
|
|
20936
|
-
}),
|
|
20937
|
-
dashboard: read(),
|
|
20938
|
-
settings: none(),
|
|
20939
|
-
team: none(),
|
|
20940
|
-
roles: none()
|
|
20941
|
-
}
|
|
20942
|
-
},
|
|
20943
|
-
{
|
|
20944
|
-
name: "Fulfillment",
|
|
20945
|
-
description: "Orders and fulfillment",
|
|
20946
|
-
isSystem: true,
|
|
20947
|
-
isOwnerRole: false,
|
|
20948
|
-
permissions: {
|
|
20949
|
-
...storePerms({
|
|
20950
|
-
products: "read",
|
|
20951
|
-
orders: "full",
|
|
20952
|
-
order_addresses: "full",
|
|
20953
|
-
order_discounts: "read",
|
|
20954
|
-
vendor_customers: "read"
|
|
20955
|
-
}),
|
|
20956
|
-
dashboard: read(),
|
|
20957
|
-
settings: none(),
|
|
20958
|
-
team: none(),
|
|
20959
|
-
roles: none()
|
|
20960
|
-
}
|
|
20961
|
-
},
|
|
20962
|
-
{
|
|
20963
|
-
name: "Viewer",
|
|
20964
|
-
description: "Read-only access to store data",
|
|
20965
|
-
isSystem: true,
|
|
20966
|
-
isOwnerRole: false,
|
|
20967
|
-
permissions: {
|
|
20968
|
-
...storePerms(Object.fromEntries(STORE_ENTITIES.map((e) => [
|
|
20969
|
-
e,
|
|
20970
|
-
"read"
|
|
20971
|
-
]))),
|
|
20972
|
-
dashboard: read(),
|
|
20973
|
-
settings: none(),
|
|
20974
|
-
team: none(),
|
|
20975
|
-
roles: none()
|
|
20976
|
-
}
|
|
20977
|
-
}
|
|
20978
|
-
];
|
|
20979
|
-
}
|
|
20980
|
-
});
|
|
20981
|
-
|
|
20982
|
-
// src/auth/rbac-debug.ts
|
|
20983
|
-
var init_rbac_debug = __esm({
|
|
20984
|
-
"src/auth/rbac-debug.ts"() {
|
|
20985
|
-
init_permission_entities();
|
|
20986
|
-
init_vendor_role_defaults();
|
|
20987
|
-
init_vendor_scope();
|
|
20988
|
-
}
|
|
20989
|
-
});
|
|
20990
|
-
|
|
20991
21277
|
// src/auth/helpers.ts
|
|
20992
21278
|
function canManageRoles(user) {
|
|
20993
21279
|
return !!(user?.email && user.isRBACAdmin);
|
|
@@ -21145,23 +21431,6 @@ function VendorRolesPage() {
|
|
|
21145
21431
|
return next;
|
|
21146
21432
|
});
|
|
21147
21433
|
}, "setAllRows");
|
|
21148
|
-
const toggleEntityRow = /* @__PURE__ */ __name((entity) => {
|
|
21149
|
-
const isOwnerOnlyEntity = entity === "team" || entity === "roles";
|
|
21150
|
-
setMatrix((prev) => {
|
|
21151
|
-
const current = prev[entity];
|
|
21152
|
-
const isAllChecked = current?.canRead && (isOwnerOnlyEntity || current.canCreate && current.canUpdate && current.canDelete);
|
|
21153
|
-
return {
|
|
21154
|
-
...prev,
|
|
21155
|
-
[entity]: {
|
|
21156
|
-
entity,
|
|
21157
|
-
canRead: !isAllChecked,
|
|
21158
|
-
canCreate: isOwnerOnlyEntity ? false : !isAllChecked,
|
|
21159
|
-
canUpdate: isOwnerOnlyEntity ? false : !isAllChecked,
|
|
21160
|
-
canDelete: isOwnerOnlyEntity ? false : !isAllChecked
|
|
21161
|
-
}
|
|
21162
|
-
};
|
|
21163
|
-
});
|
|
21164
|
-
}, "toggleEntityRow");
|
|
21165
21434
|
const saveMatrix = /* @__PURE__ */ __name(async () => {
|
|
21166
21435
|
if (!selectedId) return;
|
|
21167
21436
|
setSaving(true);
|
|
@@ -21355,31 +21624,35 @@ function VendorRolesPage() {
|
|
|
21355
21624
|
}), " Clear All"))), /* @__PURE__ */ React25__default.createElement("div", {
|
|
21356
21625
|
className: "overflow-x-auto rounded-lg border border-gray-200 dark:border-gray-700"
|
|
21357
21626
|
}, /* @__PURE__ */ React25__default.createElement("table", {
|
|
21358
|
-
className: "min-w-full text-
|
|
21627
|
+
className: "min-w-full text-sm"
|
|
21359
21628
|
}, /* @__PURE__ */ React25__default.createElement("thead", {
|
|
21360
|
-
className: "bg-
|
|
21361
|
-
}, /* @__PURE__ */ React25__default.createElement("tr",
|
|
21362
|
-
className: "
|
|
21363
|
-
},
|
|
21364
|
-
className: "px-3 py-2 font-
|
|
21629
|
+
className: "bg-white dark:bg-gray-800"
|
|
21630
|
+
}, /* @__PURE__ */ React25__default.createElement("tr", {
|
|
21631
|
+
className: "border-b border-gray-200 dark:border-gray-700"
|
|
21632
|
+
}, /* @__PURE__ */ React25__default.createElement("th", {
|
|
21633
|
+
className: "px-3 py-2.5 text-left font-semibold text-gray-700 dark:text-gray-300"
|
|
21634
|
+
}, /* @__PURE__ */ React25__default.createElement("div", {
|
|
21635
|
+
className: "flex items-center gap-2"
|
|
21636
|
+
}, /* @__PURE__ */ React25__default.createElement("span", null, "Entity"))), /* @__PURE__ */ React25__default.createElement("th", {
|
|
21637
|
+
className: "px-3 py-2.5 text-center font-semibold text-gray-700 dark:text-gray-300"
|
|
21365
21638
|
}, "Create"), /* @__PURE__ */ React25__default.createElement("th", {
|
|
21366
|
-
className: "px-3 py-2 font-
|
|
21639
|
+
className: "px-3 py-2.5 text-center font-semibold text-gray-700 dark:text-gray-300"
|
|
21367
21640
|
}, "Read"), /* @__PURE__ */ React25__default.createElement("th", {
|
|
21368
|
-
className: "px-3 py-2 font-
|
|
21641
|
+
className: "px-3 py-2.5 text-center font-semibold text-gray-700 dark:text-gray-300"
|
|
21369
21642
|
}, "Update"), /* @__PURE__ */ React25__default.createElement("th", {
|
|
21370
|
-
className: "px-3 py-2 font-
|
|
21371
|
-
}, "Delete"), /* @__PURE__ */ React25__default.createElement("
|
|
21372
|
-
className: "px-3 py-2 font-medium text-right"
|
|
21373
|
-
}, "Row Actions"))), /* @__PURE__ */ React25__default.createElement("tbody", null, entities.map((entity) => {
|
|
21643
|
+
className: "px-3 py-2.5 text-center font-semibold text-gray-700 dark:text-gray-300"
|
|
21644
|
+
}, "Delete"))), /* @__PURE__ */ React25__default.createElement("tbody", null, entities.map((entity) => {
|
|
21374
21645
|
const isOwnerOnlyEntity = entity === "team" || entity === "roles";
|
|
21375
21646
|
return /* @__PURE__ */ React25__default.createElement("tr", {
|
|
21376
21647
|
key: entity,
|
|
21377
|
-
className: "border-
|
|
21648
|
+
className: "border-b border-gray-100 last:border-b-0 hover:bg-gray-50 dark:border-gray-700 dark:hover:bg-gray-800/50"
|
|
21378
21649
|
}, /* @__PURE__ */ React25__default.createElement("td", {
|
|
21379
|
-
className: "px-3 py-2 font-mono text-gray-800 dark:text-gray-200
|
|
21380
|
-
},
|
|
21381
|
-
className: "
|
|
21382
|
-
}, "
|
|
21650
|
+
className: "px-3 py-2.5 font-mono text-sm text-gray-800 dark:text-gray-200"
|
|
21651
|
+
}, /* @__PURE__ */ React25__default.createElement("div", {
|
|
21652
|
+
className: "flex items-center gap-2"
|
|
21653
|
+
}, /* @__PURE__ */ React25__default.createElement("span", null, entity), isOwnerOnlyEntity && /* @__PURE__ */ React25__default.createElement("span", {
|
|
21654
|
+
className: "text-[10px] text-amber-600 dark:text-amber-400"
|
|
21655
|
+
}, "(Owner managed)"))), [
|
|
21383
21656
|
"canCreate",
|
|
21384
21657
|
"canRead",
|
|
21385
21658
|
"canUpdate",
|
|
@@ -21388,21 +21661,15 @@ function VendorRolesPage() {
|
|
|
21388
21661
|
const disabled = isOwnerOnlyEntity && key !== "canRead";
|
|
21389
21662
|
return /* @__PURE__ */ React25__default.createElement("td", {
|
|
21390
21663
|
key,
|
|
21391
|
-
className: "px-3 py-2"
|
|
21664
|
+
className: "px-3 py-2.5 text-center"
|
|
21392
21665
|
}, /* @__PURE__ */ React25__default.createElement("input", {
|
|
21393
21666
|
type: "checkbox",
|
|
21394
21667
|
checked: disabled ? false : !!matrix[entity]?.[key],
|
|
21395
21668
|
disabled,
|
|
21396
21669
|
onChange: /* @__PURE__ */ __name(() => toggle(entity, key), "onChange"),
|
|
21397
|
-
className: disabled ? "cursor-not-allowed opacity-40" : "cursor-pointer"
|
|
21670
|
+
className: disabled ? "h-4 w-4 cursor-not-allowed opacity-40" : "h-4 w-4 cursor-pointer"
|
|
21398
21671
|
}));
|
|
21399
|
-
})
|
|
21400
|
-
className: "px-3 py-2 text-right"
|
|
21401
|
-
}, /* @__PURE__ */ React25__default.createElement("button", {
|
|
21402
|
-
type: "button",
|
|
21403
|
-
onClick: /* @__PURE__ */ __name(() => toggleEntityRow(entity), "onClick"),
|
|
21404
|
-
className: "text-[11px] text-blue-600 hover:underline dark:text-blue-400"
|
|
21405
|
-
}, "Toggle")));
|
|
21672
|
+
}));
|
|
21406
21673
|
})))))))), /* @__PURE__ */ React25__default.createElement(Dialog, {
|
|
21407
21674
|
open: deleteOpen,
|
|
21408
21675
|
onOpenChange: setDeleteOpen
|
|
@@ -22280,39 +22547,90 @@ var init_VendorTeamPage = __esm({
|
|
|
22280
22547
|
__name(VendorTeamPage, "VendorTeamPage");
|
|
22281
22548
|
}
|
|
22282
22549
|
});
|
|
22283
|
-
|
|
22284
|
-
|
|
22285
|
-
|
|
22286
|
-
|
|
22287
|
-
|
|
22550
|
+
function splitPhoneAndCountryCode(rawPhone, defaultCode = "+91") {
|
|
22551
|
+
if (!rawPhone || !rawPhone.trim()) {
|
|
22552
|
+
return {
|
|
22553
|
+
countryCode: defaultCode,
|
|
22554
|
+
phoneNumber: ""
|
|
22555
|
+
};
|
|
22288
22556
|
}
|
|
22289
|
-
|
|
22557
|
+
const trimmed = rawPhone.trim();
|
|
22558
|
+
const match = COUNTRY_PHONE_CODES.find((c) => trimmed.startsWith(c.code));
|
|
22559
|
+
if (match) {
|
|
22560
|
+
return {
|
|
22561
|
+
countryCode: match.code,
|
|
22562
|
+
phoneNumber: trimmed.slice(match.code.length).replace(/\s+/g, "")
|
|
22563
|
+
};
|
|
22564
|
+
}
|
|
22565
|
+
if (trimmed.startsWith("+")) {
|
|
22566
|
+
const spaceIdx = trimmed.indexOf(" ");
|
|
22567
|
+
if (spaceIdx > 0) {
|
|
22568
|
+
return {
|
|
22569
|
+
countryCode: trimmed.slice(0, spaceIdx),
|
|
22570
|
+
phoneNumber: trimmed.slice(spaceIdx + 1).replace(/\s+/g, "")
|
|
22571
|
+
};
|
|
22572
|
+
}
|
|
22573
|
+
}
|
|
22574
|
+
return {
|
|
22575
|
+
countryCode: defaultCode,
|
|
22576
|
+
phoneNumber: trimmed.replace(/\D/g, "")
|
|
22577
|
+
};
|
|
22578
|
+
}
|
|
22579
|
+
function formatPhoneWithCountryCode(countryCode, phoneNumber) {
|
|
22580
|
+
const cleanNum = phoneNumber.replace(/\D/g, "");
|
|
22581
|
+
if (!cleanNum) return null;
|
|
22582
|
+
const cleanCode = countryCode.trim() || "+91";
|
|
22583
|
+
return `${cleanCode}${cleanNum}`;
|
|
22584
|
+
}
|
|
22585
|
+
function validateGstin(gstin, options) {
|
|
22586
|
+
const required = options?.required === true;
|
|
22587
|
+
if (!gstin || !gstin.trim()) {
|
|
22588
|
+
if (required) return "GSTIN number is required";
|
|
22589
|
+
return null;
|
|
22590
|
+
}
|
|
22591
|
+
if (!/^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z][1-9A-Z]Z[0-9A-Z]$/i.test(gstin.trim())) {
|
|
22592
|
+
return "Invalid GSTIN number (15 characters, e.g. 22AAAAA0000A1Z5)";
|
|
22593
|
+
}
|
|
22594
|
+
return null;
|
|
22595
|
+
}
|
|
22596
|
+
function validateIndiaTaxIds(gstin, pan, options) {
|
|
22597
|
+
const gstinErr = validateGstin(gstin, {
|
|
22598
|
+
required: options?.requiredGstin
|
|
22599
|
+
});
|
|
22600
|
+
if (gstinErr) return gstinErr;
|
|
22601
|
+
if (options?.requiredPan && (!pan || !pan.trim())) {
|
|
22602
|
+
return "PAN is required";
|
|
22603
|
+
}
|
|
22604
|
+
if (pan && !/^[A-Z]{5}[0-9]{4}[A-Z]$/i.test(pan.trim())) {
|
|
22290
22605
|
return "Invalid PAN format (e.g. ABCDE1234F)";
|
|
22291
22606
|
}
|
|
22292
22607
|
return null;
|
|
22293
22608
|
}
|
|
22294
22609
|
function validateAadhaar(aadhaar) {
|
|
22295
22610
|
if (!aadhaar) return null;
|
|
22296
|
-
if (!/^[0-9]{12}$/.test(aadhaar)) {
|
|
22611
|
+
if (!/^[0-9]{12}$/.test(aadhaar.replace(/\s+/g, ""))) {
|
|
22297
22612
|
return "Invalid Aadhaar number (12 digits)";
|
|
22298
22613
|
}
|
|
22299
22614
|
return null;
|
|
22300
22615
|
}
|
|
22301
22616
|
function validatePersonKyc(person, options) {
|
|
22302
22617
|
const required = options?.required === true;
|
|
22303
|
-
if (required && !person.aadhaarNo) return "Aadhaar number is required";
|
|
22304
|
-
if (required && !person.panNo) return "PAN is required";
|
|
22618
|
+
if (required && (!person.aadhaarNo || !person.aadhaarNo.trim())) return "Aadhaar number is required";
|
|
22619
|
+
if (required && (!person.panNo || !person.panNo.trim())) return "PAN is required";
|
|
22305
22620
|
const aadhaarErr = validateAadhaar(person.aadhaarNo ?? null);
|
|
22306
22621
|
if (aadhaarErr) return aadhaarErr;
|
|
22307
|
-
const panErr = validateIndiaTaxIds(null, person.panNo ?? null
|
|
22622
|
+
const panErr = validateIndiaTaxIds(null, person.panNo ?? null, {
|
|
22623
|
+
requiredPan: required
|
|
22624
|
+
});
|
|
22308
22625
|
if (panErr) return panErr;
|
|
22309
22626
|
return null;
|
|
22310
22627
|
}
|
|
22311
22628
|
function readOwnerDesignation(metadata) {
|
|
22312
|
-
|
|
22313
|
-
|
|
22629
|
+
if (!metadata || typeof metadata !== "object") return "";
|
|
22630
|
+
const d = metadata.ownerDesignation;
|
|
22631
|
+
return typeof d === "string" ? d.trim() : "";
|
|
22314
22632
|
}
|
|
22315
|
-
var VENDOR_REGISTRATION_STATUSES, VENDOR_BUSINESS_TYPES;
|
|
22633
|
+
var VENDOR_REGISTRATION_STATUSES, VENDOR_BUSINESS_TYPES, COUNTRY_PHONE_CODES;
|
|
22316
22634
|
var init_vendor_profile = __esm({
|
|
22317
22635
|
"src/lib/vendor-profile.ts"() {
|
|
22318
22636
|
VENDOR_REGISTRATION_STATUSES = [
|
|
@@ -22359,7 +22677,34 @@ var init_vendor_profile = __esm({
|
|
|
22359
22677
|
label: "Other"
|
|
22360
22678
|
}
|
|
22361
22679
|
];
|
|
22680
|
+
COUNTRY_PHONE_CODES = (() => {
|
|
22681
|
+
const list = [];
|
|
22682
|
+
const seenCodes = /* @__PURE__ */ new Set();
|
|
22683
|
+
for (const c of Country.getAllCountries()) {
|
|
22684
|
+
if (!c.phonecode) continue;
|
|
22685
|
+
const rawCode = c.phonecode.replace(/^\+/, "").trim();
|
|
22686
|
+
if (!rawCode) continue;
|
|
22687
|
+
const code = `+${rawCode}`;
|
|
22688
|
+
const key = `${code}-${c.name}`;
|
|
22689
|
+
if (seenCodes.has(key)) continue;
|
|
22690
|
+
seenCodes.add(key);
|
|
22691
|
+
list.push({
|
|
22692
|
+
code,
|
|
22693
|
+
country: c.name,
|
|
22694
|
+
isoCode: c.isoCode,
|
|
22695
|
+
label: `${code} (${c.name})`
|
|
22696
|
+
});
|
|
22697
|
+
}
|
|
22698
|
+
return list.sort((a, b) => {
|
|
22699
|
+
if (a.code === "+91" && b.code !== "+91") return -1;
|
|
22700
|
+
if (b.code === "+91" && a.code !== "+91") return 1;
|
|
22701
|
+
return a.country.localeCompare(b.country);
|
|
22702
|
+
});
|
|
22703
|
+
})();
|
|
22704
|
+
__name(splitPhoneAndCountryCode, "splitPhoneAndCountryCode");
|
|
22705
|
+
__name(formatPhoneWithCountryCode, "formatPhoneWithCountryCode");
|
|
22362
22706
|
new Set(VENDOR_REGISTRATION_STATUSES.map((s) => s.value));
|
|
22707
|
+
__name(validateGstin, "validateGstin");
|
|
22363
22708
|
__name(validateIndiaTaxIds, "validateIndiaTaxIds");
|
|
22364
22709
|
__name(validateAadhaar, "validateAadhaar");
|
|
22365
22710
|
__name(validatePersonKyc, "validatePersonKyc");
|
|
@@ -22962,10 +23307,26 @@ function SubmissionDetailPage({ submissionId }) {
|
|
|
22962
23307
|
}
|
|
22963
23308
|
const formName = submission.form?.name ?? `Form #${submission.formId}`;
|
|
22964
23309
|
const contact = submission.contact;
|
|
22965
|
-
const
|
|
22966
|
-
|
|
22967
|
-
|
|
22968
|
-
|
|
23310
|
+
const resolveFieldLabel = /* @__PURE__ */ __name((key) => {
|
|
23311
|
+
if (!key) return "\u2014";
|
|
23312
|
+
const rawKey = key.trim();
|
|
23313
|
+
const numericIdMatch = rawKey.match(/^(?:field_)?(\d+)$/i);
|
|
23314
|
+
const fieldIdStr = numericIdMatch ? numericIdMatch[1] : null;
|
|
23315
|
+
const fields = submission?.form?.fields ?? [];
|
|
23316
|
+
const field = fields.find((f) => fieldIdStr !== null && String(f.id) === fieldIdStr || String(f.id) === rawKey || f.name && f.name.trim().toLowerCase() === rawKey.toLowerCase() || f.label && f.label.trim().toLowerCase() === rawKey.toLowerCase());
|
|
23317
|
+
if (field) {
|
|
23318
|
+
if (field.label && field.label.trim() && !/^\d+$/.test(field.label.trim())) {
|
|
23319
|
+
return field.label.trim();
|
|
23320
|
+
}
|
|
23321
|
+
if (field.name && field.name.trim() && !/^\d+$/.test(field.name.trim())) {
|
|
23322
|
+
return field.name.trim().replace(/_/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
23323
|
+
}
|
|
23324
|
+
}
|
|
23325
|
+
if (fieldIdStr !== null) {
|
|
23326
|
+
return `Field #${fieldIdStr}`;
|
|
23327
|
+
}
|
|
23328
|
+
return rawKey.replace(/_/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
23329
|
+
}, "resolveFieldLabel");
|
|
22969
23330
|
return /* @__PURE__ */ React.createElement("div", {
|
|
22970
23331
|
className: "rounded-lg bg-white shadow-md"
|
|
22971
23332
|
}, /* @__PURE__ */ React.createElement(DetailPageHeader, {
|
|
@@ -23024,7 +23385,7 @@ function SubmissionDetailPage({ submissionId }) {
|
|
|
23024
23385
|
key
|
|
23025
23386
|
}, /* @__PURE__ */ React.createElement("td", {
|
|
23026
23387
|
className: "py-2 px-3 text-gray-600 font-medium"
|
|
23027
|
-
},
|
|
23388
|
+
}, resolveFieldLabel(key)), /* @__PURE__ */ React.createElement("td", {
|
|
23028
23389
|
className: "py-2 px-3 text-gray-900 break-words min-w-0"
|
|
23029
23390
|
}, value === null || value === void 0 ? "\u2014" : typeof value === "object" ? JSON.stringify(value) : String(value)))))))), /* @__PURE__ */ React.createElement("section", null, /* @__PURE__ */ React.createElement("h2", {
|
|
23030
23391
|
className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2"
|
|
@@ -24679,7 +25040,7 @@ function OrderPlacementPage({ editOrderId }) {
|
|
|
24679
25040
|
productQuery
|
|
24680
25041
|
]);
|
|
24681
25042
|
const recalcPreview = useCallback(async () => {
|
|
24682
|
-
const orderLines = lines.filter((l) => !
|
|
25043
|
+
const orderLines = lines.filter((l) => !l.key.startsWith("reward-")).map((l) => ({
|
|
24683
25044
|
productId: l.productId,
|
|
24684
25045
|
quantity: l.quantity
|
|
24685
25046
|
}));
|
|
@@ -24703,19 +25064,22 @@ function OrderPlacementPage({ editOrderId }) {
|
|
|
24703
25064
|
body: JSON.stringify({
|
|
24704
25065
|
orderLines,
|
|
24705
25066
|
currency,
|
|
24706
|
-
discountId: coupons[0]?.discountId ?? null
|
|
25067
|
+
discountId: coupons[0]?.discountId ?? null,
|
|
25068
|
+
discountIds: coupons.map((c) => c.discountId)
|
|
24707
25069
|
})
|
|
24708
25070
|
});
|
|
24709
25071
|
if (!res.ok) throw new Error("Calculate failed");
|
|
24710
25072
|
const data = await res.json();
|
|
24711
25073
|
const correctedLines = data.lines.map((cl) => {
|
|
24712
25074
|
if (cl.productId == null) return cl;
|
|
24713
|
-
const
|
|
25075
|
+
const pid = Number(cl.productId);
|
|
25076
|
+
const cached = productCache.current.get(pid);
|
|
24714
25077
|
if (!cl.found && cached) {
|
|
24715
|
-
const unitPrice2 = cached.price;
|
|
25078
|
+
const unitPrice2 = Number(cached.price ?? 0);
|
|
24716
25079
|
const subtotal3 = unitPrice2 * cl.quantity;
|
|
24717
25080
|
return {
|
|
24718
25081
|
...cl,
|
|
25082
|
+
productId: pid,
|
|
24719
25083
|
found: true,
|
|
24720
25084
|
unitPrice: unitPrice2,
|
|
24721
25085
|
subtotal: subtotal3,
|
|
@@ -24723,15 +25087,16 @@ function OrderPlacementPage({ editOrderId }) {
|
|
|
24723
25087
|
total: subtotal3
|
|
24724
25088
|
};
|
|
24725
25089
|
}
|
|
24726
|
-
const unitPrice = cached?.price ?? cl.unitPrice;
|
|
25090
|
+
const unitPrice = Number(cached?.price ?? cl.unitPrice ?? 0);
|
|
24727
25091
|
const subtotal2 = unitPrice * cl.quantity;
|
|
24728
|
-
const taxRate = cl.taxRate ?? (cl.subtotal > 0 && cl.tax > 0 ? cl.tax / cl.subtotal : 0);
|
|
24729
|
-
const lineDiscount = cl.
|
|
25092
|
+
const taxRate = Number(cl.taxRate ?? (cl.subtotal > 0 && cl.tax > 0 ? cl.tax / cl.subtotal * 100 : 0));
|
|
25093
|
+
const lineDiscount = Number(cl.discount ?? 0);
|
|
24730
25094
|
const discountedBase = Math.max(0, subtotal2 - lineDiscount);
|
|
24731
25095
|
const tax2 = discountedBase * taxRate / 100;
|
|
24732
25096
|
const total2 = discountedBase + tax2;
|
|
24733
25097
|
return {
|
|
24734
25098
|
...cl,
|
|
25099
|
+
productId: pid,
|
|
24735
25100
|
unitPrice,
|
|
24736
25101
|
subtotal: subtotal2,
|
|
24737
25102
|
taxRate,
|
|
@@ -24739,13 +25104,14 @@ function OrderPlacementPage({ editOrderId }) {
|
|
|
24739
25104
|
total: total2
|
|
24740
25105
|
};
|
|
24741
25106
|
});
|
|
24742
|
-
const rewardDisplayLines = lines.filter((l) =>
|
|
24743
|
-
const
|
|
25107
|
+
const rewardDisplayLines = lines.filter((l) => l.key.startsWith("reward-")).map((l) => {
|
|
25108
|
+
const pid = Number(l.productId);
|
|
25109
|
+
const cached = productCache.current.get(pid);
|
|
24744
25110
|
return {
|
|
24745
|
-
productId:
|
|
25111
|
+
productId: pid,
|
|
24746
25112
|
productName: l.label,
|
|
24747
25113
|
found: true,
|
|
24748
|
-
unitPrice: cached?.price ?? 0,
|
|
25114
|
+
unitPrice: Number(cached?.price ?? 0),
|
|
24749
25115
|
quantity: l.quantity,
|
|
24750
25116
|
subtotal: 0,
|
|
24751
25117
|
tax: 0,
|
|
@@ -24787,7 +25153,7 @@ function OrderPlacementPage({ editOrderId }) {
|
|
|
24787
25153
|
useEffect(() => {
|
|
24788
25154
|
const automaticCoupons = coupons.filter((c) => c.isAutomatic);
|
|
24789
25155
|
if (automaticCoupons.length === 0) return;
|
|
24790
|
-
const nonRewardLines = lines.filter((l) => !
|
|
25156
|
+
const nonRewardLines = lines.filter((l) => !l.key.startsWith("reward-"));
|
|
24791
25157
|
if (nonRewardLines.length === 0) {
|
|
24792
25158
|
const autoIds = new Set(automaticCoupons.map((c) => c.discountId));
|
|
24793
25159
|
const rewardPids = new Set(automaticCoupons.flatMap((c) => c.rewardLines.map((r) => r.productId)));
|
|
@@ -24867,7 +25233,7 @@ function OrderPlacementPage({ editOrderId }) {
|
|
|
24867
25233
|
cancelled = true;
|
|
24868
25234
|
};
|
|
24869
25235
|
}, [
|
|
24870
|
-
lines.filter((l) => !
|
|
25236
|
+
lines.filter((l) => !l.key.startsWith("reward-")).map((l) => `${l.productId}:${l.quantity}`).join(","),
|
|
24871
25237
|
coupons.filter((c) => c.isAutomatic).map((c) => c.discountId).join(",")
|
|
24872
25238
|
]);
|
|
24873
25239
|
function handleRemoveCoupon(couponCode) {
|
|
@@ -24989,7 +25355,10 @@ function OrderPlacementPage({ editOrderId }) {
|
|
|
24989
25355
|
const calcByProductId = useMemo(() => {
|
|
24990
25356
|
const m = /* @__PURE__ */ new Map();
|
|
24991
25357
|
for (const l of preview?.lines ?? []) {
|
|
24992
|
-
if (l.productId != null && l.found)
|
|
25358
|
+
if (l.productId != null && l.found) {
|
|
25359
|
+
const pid = Number(l.productId);
|
|
25360
|
+
if (Number.isFinite(pid)) m.set(pid, l);
|
|
25361
|
+
}
|
|
24993
25362
|
}
|
|
24994
25363
|
return m;
|
|
24995
25364
|
}, [
|
|
@@ -25011,13 +25380,13 @@ function OrderPlacementPage({ editOrderId }) {
|
|
|
25011
25380
|
}
|
|
25012
25381
|
const unknown = preview?.lines.filter((l) => !l.found) ?? [];
|
|
25013
25382
|
if (unknown.length > 0) {
|
|
25014
|
-
toast.error(
|
|
25383
|
+
toast.error(`One or more items could not be validated: ${unknown.map((u) => u.productName).join(", ")}`);
|
|
25015
25384
|
return;
|
|
25016
25385
|
}
|
|
25017
25386
|
setSubmitting(true);
|
|
25387
|
+
let resolvedContactId = effectiveContactId;
|
|
25018
25388
|
try {
|
|
25019
|
-
|
|
25020
|
-
if (!resolvedContactId && effectiveEmail) {
|
|
25389
|
+
if (resolvedContactId == null && effectiveEmail) {
|
|
25021
25390
|
try {
|
|
25022
25391
|
const res2 = await fetch(`/api/contacts?search=${encodeURIComponent(effectiveEmail)}&limit=1`);
|
|
25023
25392
|
if (res2.ok) {
|
|
@@ -25039,12 +25408,12 @@ function OrderPlacementPage({ editOrderId }) {
|
|
|
25039
25408
|
billingAddress,
|
|
25040
25409
|
shippingAddress: sameAsBilling ? billingAddress : shippingAddress,
|
|
25041
25410
|
orderLines: lines.map((l) => {
|
|
25042
|
-
const isReward =
|
|
25043
|
-
const calc = preview?.lines.find((pl) => pl.productId === l.productId);
|
|
25411
|
+
const isReward = l.key.startsWith("reward-");
|
|
25412
|
+
const calc = preview?.lines.find((pl) => Number(pl.productId) === Number(l.productId));
|
|
25044
25413
|
return {
|
|
25045
25414
|
productId: l.productId,
|
|
25046
25415
|
quantity: l.quantity,
|
|
25047
|
-
unitPrice: isReward ? 0 : calc?.unitPrice ?? productCache.current.get(l.productId)?.price ?? 0
|
|
25416
|
+
unitPrice: isReward ? 0 : calc?.unitPrice ?? Number(productCache.current.get(l.productId)?.price ?? 0)
|
|
25048
25417
|
};
|
|
25049
25418
|
})
|
|
25050
25419
|
};
|
|
@@ -30020,8 +30389,8 @@ function ProductEditPage({ productId }) {
|
|
|
30020
30389
|
const [price, setPrice] = useState(0);
|
|
30021
30390
|
const [defaultPriceStr, setDefaultPriceStr] = useState("");
|
|
30022
30391
|
const [pricingConfig, setPricingConfig] = useState(DEFAULT_PRICING_CONFIG);
|
|
30023
|
-
const [compareAtPrice, setCompareAtPrice] = useState(
|
|
30024
|
-
const [quantity, setQuantity] = useState(1);
|
|
30392
|
+
const [compareAtPrice, setCompareAtPrice] = useState("");
|
|
30393
|
+
const [quantity, setQuantity] = useState("1");
|
|
30025
30394
|
const [status, setStatus] = useState("draft");
|
|
30026
30395
|
const [approvalStatus, setApprovalStatus] = useState("pending");
|
|
30027
30396
|
const [rejectionReason, setRejectionReason] = useState("");
|
|
@@ -30242,8 +30611,8 @@ function ProductEditPage({ productId }) {
|
|
|
30242
30611
|
setDefaultPriceStr(product.price != null && Number.isFinite(Number(product.price)) ? String(product.price) : "");
|
|
30243
30612
|
setPrice(product.price != null ? Number(product.price) : 0);
|
|
30244
30613
|
const rawCompare = product.compareAtPrice != null ? Number(product.compareAtPrice) : 0;
|
|
30245
|
-
setCompareAtPrice(Number.isFinite(rawCompare) ? rawCompare :
|
|
30246
|
-
setQuantity(product.quantity
|
|
30614
|
+
setCompareAtPrice(rawCompare != null && Number.isFinite(rawCompare) ? String(rawCompare) : "");
|
|
30615
|
+
setQuantity(product.quantity != null ? String(product.quantity) : "1");
|
|
30247
30616
|
setStatus(product.status ?? "draft");
|
|
30248
30617
|
setApprovalStatus(typeof product.approvalStatus === "string" && product.approvalStatus ? product.approvalStatus : "pending");
|
|
30249
30618
|
setRejectionReason(typeof product.rejectionReason === "string" ? product.rejectionReason : "");
|
|
@@ -30410,22 +30779,6 @@ function ProductEditPage({ productId }) {
|
|
|
30410
30779
|
return pricingConfig.defaultCurrency || "INR";
|
|
30411
30780
|
}
|
|
30412
30781
|
})();
|
|
30413
|
-
const handleNumberChange = /* @__PURE__ */ __name((setter, options) => (e) => {
|
|
30414
|
-
const value = e.target.value;
|
|
30415
|
-
if (value === "") {
|
|
30416
|
-
setter(0);
|
|
30417
|
-
return;
|
|
30418
|
-
}
|
|
30419
|
-
let num = options?.integer ? Number.parseInt(value, 10) : Number(value);
|
|
30420
|
-
if (Number.isNaN(num)) {
|
|
30421
|
-
setter(0);
|
|
30422
|
-
return;
|
|
30423
|
-
}
|
|
30424
|
-
if (options?.min !== void 0) {
|
|
30425
|
-
num = Math.max(options.min, num);
|
|
30426
|
-
}
|
|
30427
|
-
setter(num);
|
|
30428
|
-
}, "handleNumberChange");
|
|
30429
30782
|
const openRejectModal = /* @__PURE__ */ __name((fromStatus) => {
|
|
30430
30783
|
approvalBeforeRejectRef.current = fromStatus === "rejected" ? "pending" : fromStatus;
|
|
30431
30784
|
setRejectDraft(rejectionReason);
|
|
@@ -30498,12 +30851,13 @@ function ProductEditPage({ productId }) {
|
|
|
30498
30851
|
return;
|
|
30499
30852
|
}
|
|
30500
30853
|
}
|
|
30501
|
-
const
|
|
30854
|
+
const quantityValue = quantity === "" ? 0 : Number(quantity);
|
|
30855
|
+
const quantityErrors = validateProductQuantity(quantityValue, hasVariants, parsedVariants);
|
|
30502
30856
|
if (quantityErrors.length) {
|
|
30503
30857
|
setErrors(quantityErrors);
|
|
30504
30858
|
return;
|
|
30505
30859
|
}
|
|
30506
|
-
const resolvedQuantity = hasVariants ? productQuantityFromVariants(parsedVariants) :
|
|
30860
|
+
const resolvedQuantity = hasVariants ? productQuantityFromVariants(parsedVariants) : quantityValue;
|
|
30507
30861
|
setSaving(true);
|
|
30508
30862
|
try {
|
|
30509
30863
|
const compareAtPriceValue = compareAtPrice ? Math.round(Number(compareAtPrice) * 100) / 100 : null;
|
|
@@ -31117,9 +31471,8 @@ function ProductEditPage({ productId }) {
|
|
|
31117
31471
|
type: "number",
|
|
31118
31472
|
value: compareAtPrice,
|
|
31119
31473
|
className: inputCls3,
|
|
31120
|
-
|
|
31121
|
-
|
|
31122
|
-
})
|
|
31474
|
+
min: 0,
|
|
31475
|
+
onChange: /* @__PURE__ */ __name((e) => setCompareAtPrice(e.target.value), "onChange")
|
|
31123
31476
|
})), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("label", {
|
|
31124
31477
|
className: labelCls3
|
|
31125
31478
|
}, "Contact form"), /* @__PURE__ */ React.createElement("select", {
|
|
@@ -31142,10 +31495,7 @@ function ProductEditPage({ productId }) {
|
|
|
31142
31495
|
min: 0,
|
|
31143
31496
|
step: 1,
|
|
31144
31497
|
value: hasVariants ? productQuantityFromVariants(variantsFromForm(variantRows, pricingConfig.defaultCurrency)) : quantity,
|
|
31145
|
-
onChange:
|
|
31146
|
-
min: 0,
|
|
31147
|
-
integer: true
|
|
31148
|
-
}),
|
|
31498
|
+
onChange: /* @__PURE__ */ __name((e) => setQuantity(e.target.value), "onChange"),
|
|
31149
31499
|
className: `${inputCls3}${hasVariants ? " bg-gray-100" : ""}`,
|
|
31150
31500
|
required: !hasVariants,
|
|
31151
31501
|
readOnly: hasVariants,
|
|
@@ -31222,8 +31572,18 @@ function ProductEditPage({ productId }) {
|
|
|
31222
31572
|
value: row.taxId === "" ? "" : String(row.taxId),
|
|
31223
31573
|
onChange: /* @__PURE__ */ __name((e) => {
|
|
31224
31574
|
const v = e.target.value;
|
|
31575
|
+
if (v === "") {
|
|
31576
|
+
setTaxRow(i, {
|
|
31577
|
+
taxId: "",
|
|
31578
|
+
rate: ""
|
|
31579
|
+
});
|
|
31580
|
+
return;
|
|
31581
|
+
}
|
|
31582
|
+
const taxId = Number(v);
|
|
31583
|
+
const selectedTax = taxMasterList.find((t) => t.id === taxId);
|
|
31225
31584
|
setTaxRow(i, {
|
|
31226
|
-
taxId
|
|
31585
|
+
taxId,
|
|
31586
|
+
rate: selectedTax?.rate != null ? String(selectedTax.rate) : ""
|
|
31227
31587
|
});
|
|
31228
31588
|
}, "onChange"),
|
|
31229
31589
|
className: inputCls3
|
|
@@ -33048,6 +33408,35 @@ function EventEditPage({ eventId }) {
|
|
|
33048
33408
|
const [saving, setSaving] = useState(false);
|
|
33049
33409
|
const [errors, setErrors] = useState([]);
|
|
33050
33410
|
const [activeTab, setActiveTab] = useState("basic");
|
|
33411
|
+
const eventTabs = [
|
|
33412
|
+
{
|
|
33413
|
+
key: "basic",
|
|
33414
|
+
label: "Basic info"
|
|
33415
|
+
},
|
|
33416
|
+
{
|
|
33417
|
+
key: "venue",
|
|
33418
|
+
label: "Venue"
|
|
33419
|
+
},
|
|
33420
|
+
{
|
|
33421
|
+
key: "datetime",
|
|
33422
|
+
label: "Date & time"
|
|
33423
|
+
},
|
|
33424
|
+
{
|
|
33425
|
+
key: "settings",
|
|
33426
|
+
label: "Settings"
|
|
33427
|
+
}
|
|
33428
|
+
];
|
|
33429
|
+
const activeTabIndex = eventTabs.findIndex((tab) => tab.key === activeTab);
|
|
33430
|
+
const goToPreviousTab = /* @__PURE__ */ __name(() => {
|
|
33431
|
+
if (activeTabIndex > 0) {
|
|
33432
|
+
setActiveTab(eventTabs[activeTabIndex - 1].key);
|
|
33433
|
+
}
|
|
33434
|
+
}, "goToPreviousTab");
|
|
33435
|
+
const goToNextTab = /* @__PURE__ */ __name(() => {
|
|
33436
|
+
if (activeTabIndex < eventTabs.length - 1) {
|
|
33437
|
+
setActiveTab(eventTabs[activeTabIndex + 1].key);
|
|
33438
|
+
}
|
|
33439
|
+
}, "goToNextTab");
|
|
33051
33440
|
const [name, setName] = useState("");
|
|
33052
33441
|
const [slug, setSlug] = useState("");
|
|
33053
33442
|
const [description, setDescription] = useState("");
|
|
@@ -33867,7 +34256,19 @@ function EventEditPage({ eventId }) {
|
|
|
33867
34256
|
[key]: value
|
|
33868
34257
|
})), "onChange")
|
|
33869
34258
|
}))))
|
|
33870
|
-
}),
|
|
34259
|
+
}), /* @__PURE__ */ React.createElement("div", {
|
|
34260
|
+
className: "flex items-center justify-between border-t border-gray-200 px-4 py-4 sm:px-6"
|
|
34261
|
+
}, /* @__PURE__ */ React.createElement("button", {
|
|
34262
|
+
type: "button",
|
|
34263
|
+
onClick: goToPreviousTab,
|
|
34264
|
+
disabled: activeTabIndex === 0,
|
|
34265
|
+
className: "rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-40"
|
|
34266
|
+
}, "Previous"), /* @__PURE__ */ React.createElement("button", {
|
|
34267
|
+
type: "button",
|
|
34268
|
+
onClick: goToNextTab,
|
|
34269
|
+
disabled: activeTabIndex === eventTabs.length - 1,
|
|
34270
|
+
className: "rounded-md bg-gray-900 px-4 py-2 text-sm font-medium text-white hover:bg-gray-800 disabled:cursor-not-allowed disabled:opacity-40"
|
|
34271
|
+
}, "Next")), showEventProducts ? /* @__PURE__ */ React.createElement("div", {
|
|
33871
34272
|
className: "border-t border-gray-200 px-4 py-4 sm:px-6"
|
|
33872
34273
|
}, /* @__PURE__ */ React.createElement(EventProductsSection, {
|
|
33873
34274
|
eventId: eventRecordId,
|
|
@@ -34212,6 +34613,18 @@ function ComboEditPage({ comboId }) {
|
|
|
34212
34613
|
]);
|
|
34213
34614
|
return;
|
|
34214
34615
|
}
|
|
34616
|
+
if (!startsAt) {
|
|
34617
|
+
setErrors([
|
|
34618
|
+
"Starts at is required"
|
|
34619
|
+
]);
|
|
34620
|
+
return;
|
|
34621
|
+
}
|
|
34622
|
+
if (!endsAt) {
|
|
34623
|
+
setErrors([
|
|
34624
|
+
"Ends at is required"
|
|
34625
|
+
]);
|
|
34626
|
+
return;
|
|
34627
|
+
}
|
|
34215
34628
|
if (!priceStr.trim()) {
|
|
34216
34629
|
setErrors([
|
|
34217
34630
|
`Price (${defaultCurrency}) is required`
|
|
@@ -34501,18 +34914,20 @@ function ComboEditPage({ comboId }) {
|
|
|
34501
34914
|
className: "grid grid-cols-2 gap-4"
|
|
34502
34915
|
}, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("label", {
|
|
34503
34916
|
className: "block text-xs font-medium text-gray-600 mb-1"
|
|
34504
|
-
}, "Starts at"), /* @__PURE__ */ React.createElement("input", {
|
|
34917
|
+
}, "Starts at *"), /* @__PURE__ */ React.createElement("input", {
|
|
34505
34918
|
type: "datetime-local",
|
|
34506
34919
|
value: startsAt,
|
|
34507
34920
|
onChange: /* @__PURE__ */ __name((e) => setStartsAt(e.target.value), "onChange"),
|
|
34508
|
-
className: "w-full rounded-md border border-gray-300 px-3 py-2 text-sm"
|
|
34921
|
+
className: "w-full rounded-md border border-gray-300 px-3 py-2 text-sm",
|
|
34922
|
+
required: true
|
|
34509
34923
|
})), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("label", {
|
|
34510
34924
|
className: "block text-xs font-medium text-gray-600 mb-1"
|
|
34511
|
-
}, "Ends at"), /* @__PURE__ */ React.createElement("input", {
|
|
34925
|
+
}, "Ends at *"), /* @__PURE__ */ React.createElement("input", {
|
|
34512
34926
|
type: "datetime-local",
|
|
34513
34927
|
value: endsAt,
|
|
34514
34928
|
onChange: /* @__PURE__ */ __name((e) => setEndsAt(e.target.value), "onChange"),
|
|
34515
|
-
className: "w-full rounded-md border border-gray-300 px-3 py-2 text-sm"
|
|
34929
|
+
className: "w-full rounded-md border border-gray-300 px-3 py-2 text-sm",
|
|
34930
|
+
required: true
|
|
34516
34931
|
})))))),
|
|
34517
34932
|
sidebar: /* @__PURE__ */ React.createElement(React.Fragment, null)
|
|
34518
34933
|
}));
|
|
@@ -34598,7 +35013,8 @@ function VendorEditPage({ vendorId }) {
|
|
|
34598
35013
|
const [website, setWebsite] = useState("");
|
|
34599
35014
|
const [logo, setLogo] = useState("");
|
|
34600
35015
|
const [email, setEmail] = useState("");
|
|
34601
|
-
const [
|
|
35016
|
+
const [storePhoneCode, setStorePhoneCode] = useState("+91");
|
|
35017
|
+
const [storePhoneNum, setStorePhoneNum] = useState("");
|
|
34602
35018
|
const [addressLine1, setAddressLine1] = useState("");
|
|
34603
35019
|
const [addressLine2, setAddressLine2] = useState("");
|
|
34604
35020
|
const [city, setCity] = useState("");
|
|
@@ -34612,7 +35028,8 @@ function VendorEditPage({ vendorId }) {
|
|
|
34612
35028
|
const [metadata, setMetadata] = useState(null);
|
|
34613
35029
|
const [ownerName, setOwnerName] = useState("");
|
|
34614
35030
|
const [ownerEmail, setOwnerEmail] = useState("");
|
|
34615
|
-
const [
|
|
35031
|
+
const [ownerPhoneCode, setOwnerPhoneCode] = useState("+91");
|
|
35032
|
+
const [ownerPhoneNum, setOwnerPhoneNum] = useState("");
|
|
34616
35033
|
const [ownerDesignation, setOwnerDesignation] = useState("");
|
|
34617
35034
|
const [ownerAadhaarNo, setOwnerAadhaarNo] = useState("");
|
|
34618
35035
|
const [ownerPanNo, setOwnerPanNo] = useState("");
|
|
@@ -34636,7 +35053,7 @@ function VendorEditPage({ vendorId }) {
|
|
|
34636
35053
|
website: website.trim() || null,
|
|
34637
35054
|
logo: logo.trim() || null,
|
|
34638
35055
|
email: email.trim() || null,
|
|
34639
|
-
phone:
|
|
35056
|
+
phone: formatPhoneWithCountryCode(storePhoneCode, storePhoneNum),
|
|
34640
35057
|
addressLine1: addressLine1.trim() || null,
|
|
34641
35058
|
addressLine2: addressLine2.trim() || null,
|
|
34642
35059
|
city: city.trim() || null,
|
|
@@ -34664,7 +35081,9 @@ function VendorEditPage({ vendorId }) {
|
|
|
34664
35081
|
setWebsite(data.website ?? "");
|
|
34665
35082
|
setLogo(data.logo ?? "");
|
|
34666
35083
|
setEmail(data.email ?? "");
|
|
34667
|
-
|
|
35084
|
+
const sPhone = splitPhoneAndCountryCode(data.phone);
|
|
35085
|
+
setStorePhoneCode(sPhone.countryCode);
|
|
35086
|
+
setStorePhoneNum(sPhone.phoneNumber);
|
|
34668
35087
|
setAddressLine1(data.addressLine1 ?? "");
|
|
34669
35088
|
setAddressLine2(data.addressLine2 ?? "");
|
|
34670
35089
|
setCity(data.city ?? "");
|
|
@@ -34686,7 +35105,9 @@ function VendorEditPage({ vendorId }) {
|
|
|
34686
35105
|
if (!cancelled) {
|
|
34687
35106
|
setOwnerName(user.name ?? "");
|
|
34688
35107
|
setOwnerEmail(user.email ?? "");
|
|
34689
|
-
|
|
35108
|
+
const oPhone = splitPhoneAndCountryCode(user.phone);
|
|
35109
|
+
setOwnerPhoneCode(oPhone.countryCode);
|
|
35110
|
+
setOwnerPhoneNum(oPhone.phoneNumber);
|
|
34690
35111
|
}
|
|
34691
35112
|
}
|
|
34692
35113
|
} else if (!cancelled) {
|
|
@@ -34833,7 +35254,10 @@ function VendorEditPage({ vendorId }) {
|
|
|
34833
35254
|
setSaving(false);
|
|
34834
35255
|
return;
|
|
34835
35256
|
}
|
|
34836
|
-
const
|
|
35257
|
+
const formattedOwnerPhone = formatPhoneWithCountryCode(ownerPhoneCode, ownerPhoneNum);
|
|
35258
|
+
const taxError = validateGstin(gstin.trim().toUpperCase() || null, {
|
|
35259
|
+
required: true
|
|
35260
|
+
});
|
|
34837
35261
|
if (taxError) {
|
|
34838
35262
|
setErrors([
|
|
34839
35263
|
taxError
|
|
@@ -34875,7 +35299,7 @@ function VendorEditPage({ vendorId }) {
|
|
|
34875
35299
|
user: {
|
|
34876
35300
|
name: ownerName.trim(),
|
|
34877
35301
|
email: ownerEmail.trim(),
|
|
34878
|
-
phone:
|
|
35302
|
+
phone: formattedOwnerPhone || void 0,
|
|
34879
35303
|
designation: ownerDesignation.trim() || void 0,
|
|
34880
35304
|
aadhaarNo: ownerAadhaarNo.trim(),
|
|
34881
35305
|
panNo: ownerPanNo.trim().toUpperCase(),
|
|
@@ -34939,7 +35363,9 @@ function VendorEditPage({ vendorId }) {
|
|
|
34939
35363
|
setSaving(false);
|
|
34940
35364
|
return;
|
|
34941
35365
|
}
|
|
34942
|
-
const taxError =
|
|
35366
|
+
const taxError = validateGstin(gstin.trim().toUpperCase() || null, {
|
|
35367
|
+
required: false
|
|
35368
|
+
});
|
|
34943
35369
|
if (taxError) {
|
|
34944
35370
|
setErrors([
|
|
34945
35371
|
taxError
|
|
@@ -34975,6 +35401,7 @@ function VendorEditPage({ vendorId }) {
|
|
|
34975
35401
|
return;
|
|
34976
35402
|
}
|
|
34977
35403
|
if (ownerUserId != null) {
|
|
35404
|
+
const formattedOwnerPhone = formatPhoneWithCountryCode(ownerPhoneCode, ownerPhoneNum);
|
|
34978
35405
|
const userRes = await fetch(`/api/users/${ownerUserId}`, {
|
|
34979
35406
|
method: "PUT",
|
|
34980
35407
|
headers: {
|
|
@@ -34983,7 +35410,7 @@ function VendorEditPage({ vendorId }) {
|
|
|
34983
35410
|
body: JSON.stringify({
|
|
34984
35411
|
name: ownerName.trim(),
|
|
34985
35412
|
email: ownerEmail.trim(),
|
|
34986
|
-
phone:
|
|
35413
|
+
phone: formattedOwnerPhone || null
|
|
34987
35414
|
})
|
|
34988
35415
|
});
|
|
34989
35416
|
if (!userRes.ok) {
|
|
@@ -35117,12 +35544,23 @@ function VendorEditPage({ vendorId }) {
|
|
|
35117
35544
|
className: `mt-1 ${fieldClass}`
|
|
35118
35545
|
})), /* @__PURE__ */ React25__default.createElement("div", null, /* @__PURE__ */ React25__default.createElement(FieldLabel, {
|
|
35119
35546
|
htmlFor: "vendorPhone"
|
|
35120
|
-
}, "Store phone"), /* @__PURE__ */ React25__default.createElement(
|
|
35547
|
+
}, "Store phone"), /* @__PURE__ */ React25__default.createElement("div", {
|
|
35548
|
+
className: "flex gap-2 mt-1"
|
|
35549
|
+
}, /* @__PURE__ */ React25__default.createElement("select", {
|
|
35550
|
+
value: storePhoneCode,
|
|
35551
|
+
onChange: /* @__PURE__ */ __name((e) => setStorePhoneCode(e.target.value), "onChange"),
|
|
35552
|
+
className: "w-36 rounded-md border border-gray-300 px-3 py-2 text-sm bg-white focus:outline-none focus:ring-1 focus:ring-black"
|
|
35553
|
+
}, COUNTRY_PHONE_CODES.map((c) => /* @__PURE__ */ React25__default.createElement("option", {
|
|
35554
|
+
key: c.code,
|
|
35555
|
+
value: c.code
|
|
35556
|
+
}, c.label))), /* @__PURE__ */ React25__default.createElement(Input, {
|
|
35121
35557
|
id: "vendorPhone",
|
|
35122
|
-
|
|
35123
|
-
|
|
35124
|
-
|
|
35125
|
-
|
|
35558
|
+
type: "tel",
|
|
35559
|
+
placeholder: "9876543210",
|
|
35560
|
+
value: storePhoneNum,
|
|
35561
|
+
onChange: /* @__PURE__ */ __name((e) => setStorePhoneNum(e.target.value.replace(/\D/g, "")), "onChange"),
|
|
35562
|
+
className: `flex-1 ${fieldClass}`
|
|
35563
|
+
}))))), /* @__PURE__ */ React25__default.createElement("section", null, /* @__PURE__ */ React25__default.createElement("h2", {
|
|
35126
35564
|
className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2"
|
|
35127
35565
|
}, "Store address"), /* @__PURE__ */ React25__default.createElement("div", {
|
|
35128
35566
|
className: sectionCls5
|
|
@@ -35175,12 +35613,15 @@ function VendorEditPage({ vendorId }) {
|
|
|
35175
35613
|
className: `mt-1 ${fieldClass}`
|
|
35176
35614
|
}))))), /* @__PURE__ */ React25__default.createElement("section", null, /* @__PURE__ */ React25__default.createElement("h2", {
|
|
35177
35615
|
className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2"
|
|
35178
|
-
}, "Tax
|
|
35616
|
+
}, "Tax"), /* @__PURE__ */ React25__default.createElement("div", {
|
|
35179
35617
|
className: sectionCls5
|
|
35180
35618
|
}, /* @__PURE__ */ React25__default.createElement("div", null, /* @__PURE__ */ React25__default.createElement(FieldLabel, {
|
|
35181
|
-
htmlFor: "gstin"
|
|
35619
|
+
htmlFor: "gstin",
|
|
35620
|
+
required: create
|
|
35182
35621
|
}, "GSTIN"), /* @__PURE__ */ React25__default.createElement(Input, {
|
|
35183
35622
|
id: "gstin",
|
|
35623
|
+
required: create,
|
|
35624
|
+
maxLength: 15,
|
|
35184
35625
|
value: gstin,
|
|
35185
35626
|
onChange: /* @__PURE__ */ __name((e) => setGstin(e.target.value.toUpperCase()), "onChange"),
|
|
35186
35627
|
placeholder: "22AAAAA0000A1Z5",
|
|
@@ -35210,12 +35651,23 @@ function VendorEditPage({ vendorId }) {
|
|
|
35210
35651
|
className: `mt-1 ${fieldClass}`
|
|
35211
35652
|
})), /* @__PURE__ */ React25__default.createElement("div", null, /* @__PURE__ */ React25__default.createElement(FieldLabel, {
|
|
35212
35653
|
htmlFor: "ownerPhone"
|
|
35213
|
-
}, "Phone"), /* @__PURE__ */ React25__default.createElement(
|
|
35654
|
+
}, "Phone"), /* @__PURE__ */ React25__default.createElement("div", {
|
|
35655
|
+
className: "flex gap-2 mt-1"
|
|
35656
|
+
}, /* @__PURE__ */ React25__default.createElement("select", {
|
|
35657
|
+
value: ownerPhoneCode,
|
|
35658
|
+
onChange: /* @__PURE__ */ __name((e) => setOwnerPhoneCode(e.target.value), "onChange"),
|
|
35659
|
+
className: "w-36 rounded-md border border-gray-300 px-3 py-2 text-sm bg-white focus:outline-none focus:ring-1 focus:ring-black"
|
|
35660
|
+
}, COUNTRY_PHONE_CODES.map((c) => /* @__PURE__ */ React25__default.createElement("option", {
|
|
35661
|
+
key: c.code,
|
|
35662
|
+
value: c.code
|
|
35663
|
+
}, c.label))), /* @__PURE__ */ React25__default.createElement(Input, {
|
|
35214
35664
|
id: "ownerPhone",
|
|
35215
|
-
|
|
35216
|
-
|
|
35217
|
-
|
|
35218
|
-
|
|
35665
|
+
type: "tel",
|
|
35666
|
+
placeholder: "9876543210",
|
|
35667
|
+
value: ownerPhoneNum,
|
|
35668
|
+
onChange: /* @__PURE__ */ __name((e) => setOwnerPhoneNum(e.target.value.replace(/\D/g, "")), "onChange"),
|
|
35669
|
+
className: `flex-1 ${fieldClass}`
|
|
35670
|
+
}))), /* @__PURE__ */ React25__default.createElement("div", null, /* @__PURE__ */ React25__default.createElement(FieldLabel, {
|
|
35219
35671
|
htmlFor: "ownerDesignation"
|
|
35220
35672
|
}, "Designation"), /* @__PURE__ */ React25__default.createElement(Input, {
|
|
35221
35673
|
id: "ownerDesignation",
|
|
@@ -35300,7 +35752,7 @@ function VendorEditPage({ vendorId }) {
|
|
|
35300
35752
|
htmlFor: "termsAccepted",
|
|
35301
35753
|
className: "font-normal cursor-pointer text-sm leading-snug"
|
|
35302
35754
|
}, "I confirm I have read and accepted the terms and conditions for selling on this platform."))))),
|
|
35303
|
-
sidebar:
|
|
35755
|
+
sidebar: create ? void 0 : /* @__PURE__ */ React25__default.createElement("section", null, /* @__PURE__ */ React25__default.createElement("h2", {
|
|
35304
35756
|
className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2"
|
|
35305
35757
|
}, "Status"), /* @__PURE__ */ React25__default.createElement("div", {
|
|
35306
35758
|
className: sectionCls5
|
|
@@ -35335,18 +35787,7 @@ function VendorEditPage({ vendorId }) {
|
|
|
35335
35787
|
readOnly: true,
|
|
35336
35788
|
value: active ? "Yes" : "No",
|
|
35337
35789
|
className: `mt-1 ${fieldClass} bg-gray-100`
|
|
35338
|
-
}))))
|
|
35339
|
-
className: "text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2"
|
|
35340
|
-
}, "Owner access"), /* @__PURE__ */ React25__default.createElement("div", {
|
|
35341
|
-
className: sectionCls5
|
|
35342
|
-
}, /* @__PURE__ */ React25__default.createElement("p", {
|
|
35343
|
-
className: "text-sm text-gray-600"
|
|
35344
|
-
}, "Creates the vendor and an invite for the owner. After create, you can send the invite email or copy the invite link."), /* @__PURE__ */ React25__default.createElement(Button, {
|
|
35345
|
-
type: "button",
|
|
35346
|
-
disabled: saving,
|
|
35347
|
-
onClick: handleCreate,
|
|
35348
|
-
className: "w-full"
|
|
35349
|
-
}, saving ? "Creating\u2026" : "Create vendor"))) : void 0)
|
|
35790
|
+
}))))
|
|
35350
35791
|
}), /* @__PURE__ */ React25__default.createElement(Dialog, {
|
|
35351
35792
|
open: inviteDialog != null,
|
|
35352
35793
|
onOpenChange: /* @__PURE__ */ __name((open) => {
|
|
@@ -36941,7 +37382,7 @@ function ConditionCard({ condition, onChange, onRemove, eventsOn }) {
|
|
|
36941
37382
|
value: "minAmount"
|
|
36942
37383
|
}, "Minimum order amount"), /* @__PURE__ */ React.createElement(SelectItem, {
|
|
36943
37384
|
value: "minQuantity"
|
|
36944
|
-
}, "Minimum
|
|
37385
|
+
}, "Minimum Cart Quantity"), /* @__PURE__ */ React.createElement(SelectItem, {
|
|
36945
37386
|
value: "productMinQuantity"
|
|
36946
37387
|
}, "Product"), (eventsOn || condition.kind === "events") && /* @__PURE__ */ React.createElement(SelectItem, {
|
|
36947
37388
|
value: "events"
|
|
@@ -38396,8 +38837,8 @@ function ContactDetailPage({ contactId }) {
|
|
|
38396
38837
|
setAddAddressError("Select country, state, and city from the lists.");
|
|
38397
38838
|
return;
|
|
38398
38839
|
}
|
|
38399
|
-
const { Country:
|
|
38400
|
-
const countryName =
|
|
38840
|
+
const { Country: Country3, State: State2 } = await import('country-state-city');
|
|
38841
|
+
const countryName = Country3.getCountryByCode(addressGeo.countryIso)?.name ?? "";
|
|
38401
38842
|
const stateName = State2.getStatesOfCountry(addressGeo.countryIso).find((s) => s.isoCode === addressGeo.stateIso)?.name ?? "";
|
|
38402
38843
|
const payload = {
|
|
38403
38844
|
contactId: Number(contactId),
|