@jytextiles/medusa-plugin-faire-store-sync 0.2.5 → 0.2.7
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/.medusa/server/src/__tests__/faire-client.spec.js +124 -7
- package/.medusa/server/src/__tests__/ingest-faire-order-support.spec.js +61 -1
- package/.medusa/server/src/admin/index.js +167 -137
- package/.medusa/server/src/admin/index.mjs +168 -138
- package/.medusa/server/src/api/admin/faire/status/route.js +4 -2
- package/.medusa/server/src/api/admin/faire/taxonomy/route.js +12 -0
- package/.medusa/server/src/lib/faire-client.js +120 -18
- package/.medusa/server/src/lib/types.js +6 -2
- package/.medusa/server/src/modules/faire-sync/service.js +18 -3
- package/.medusa/server/src/workflows/ingest-faire-order-support.js +81 -28
- package/.medusa/server/src/workflows/sync-product-to-faire.js +108 -37
- package/package.json +1 -1
- package/src/__tests__/faire-client.spec.ts +135 -6
- package/src/__tests__/ingest-faire-order-support.spec.ts +63 -0
- package/src/admin/lib/api.ts +4 -0
- package/src/admin/routes/settings/faire/[id]/page.tsx +56 -61
- package/src/admin/routes/settings/faire/settings/page.tsx +62 -13
- package/src/api/admin/faire/status/route.ts +3 -1
- package/src/api/admin/faire/taxonomy/route.ts +10 -0
- package/src/lib/faire-client.ts +139 -16
- package/src/lib/types.ts +57 -18
- package/src/modules/faire-sync/service.ts +23 -2
- package/src/workflows/ingest-faire-order-support.ts +96 -29
- package/src/workflows/sync-product-to-faire.ts +146 -42
|
@@ -63,6 +63,9 @@ const faireApi = {
|
|
|
63
63
|
getSync: (id) => sdk.client.fetch(`/admin/faire/syncs/${id}`),
|
|
64
64
|
retrySync: (id) => sdk.client.fetch(`/admin/faire/syncs/${id}`, { method: "POST" }),
|
|
65
65
|
brand: () => sdk.client.fetch("/admin/faire/brand"),
|
|
66
|
+
taxonomy: () => sdk.client.fetch(
|
|
67
|
+
"/admin/faire/taxonomy"
|
|
68
|
+
),
|
|
66
69
|
products: (opts = {}) => {
|
|
67
70
|
const query = {};
|
|
68
71
|
if (opts.limit !== void 0) query.limit = String(opts.limit);
|
|
@@ -481,124 +484,6 @@ const config = adminSdk.defineRouteConfig({
|
|
|
481
484
|
const handle$3 = {
|
|
482
485
|
breadcrumb: () => "Faire Sync"
|
|
483
486
|
};
|
|
484
|
-
const STATUS_COLORS = {
|
|
485
|
-
success: "green",
|
|
486
|
-
failed: "red",
|
|
487
|
-
draft: "orange",
|
|
488
|
-
pending: "grey",
|
|
489
|
-
syncing: "grey"
|
|
490
|
-
};
|
|
491
|
-
const FaireSyncDetailPage = () => {
|
|
492
|
-
const { id } = reactRouterDom.useParams();
|
|
493
|
-
const navigate = reactRouterDom.useNavigate();
|
|
494
|
-
const [record, setRecord] = react.useState(null);
|
|
495
|
-
const [loading, setLoading] = react.useState(true);
|
|
496
|
-
const [retrying, setRetrying] = react.useState(false);
|
|
497
|
-
const [error, setError] = react.useState(null);
|
|
498
|
-
react.useEffect(() => {
|
|
499
|
-
if (!id) return;
|
|
500
|
-
setLoading(true);
|
|
501
|
-
faireApi.getSync(id).then((res) => {
|
|
502
|
-
setRecord(res.sync || res);
|
|
503
|
-
}).catch((err) => setError(err.message || "Failed to load sync record")).finally(() => setLoading(false));
|
|
504
|
-
}, [id]);
|
|
505
|
-
const handleRetry = async () => {
|
|
506
|
-
if (!record) return;
|
|
507
|
-
setRetrying(true);
|
|
508
|
-
setError(null);
|
|
509
|
-
try {
|
|
510
|
-
await faireApi.retrySync(record.id);
|
|
511
|
-
const updated = await faireApi.getSync(record.id).catch(() => null);
|
|
512
|
-
if (updated) setRecord(updated.sync || updated);
|
|
513
|
-
} catch (err) {
|
|
514
|
-
setError(err.message || "Retry failed");
|
|
515
|
-
} finally {
|
|
516
|
-
setRetrying(false);
|
|
517
|
-
}
|
|
518
|
-
};
|
|
519
|
-
if (loading) {
|
|
520
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "p-6", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }) });
|
|
521
|
-
}
|
|
522
|
-
if (!record) {
|
|
523
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "p-6 flex flex-col gap-4", children: [
|
|
524
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Sync record not found" }),
|
|
525
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", onClick: () => navigate("/settings/faire"), children: "Back to Faire settings" })
|
|
526
|
-
] });
|
|
527
|
-
}
|
|
528
|
-
const warnings = record.error_message ? record.error_message.split(" | ") : [];
|
|
529
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
530
|
-
error && /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-tag-red-text", children: error }) }),
|
|
531
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
|
|
532
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-6 py-4", children: [
|
|
533
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
534
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Sync record" }),
|
|
535
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle font-mono text-xs", children: record.id })
|
|
536
|
-
] }),
|
|
537
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
538
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.StatusBadge, { color: STATUS_COLORS[record.status] || "grey", children: record.status }),
|
|
539
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
|
|
540
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "small", variant: "transparent", disabled: retrying, children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisHorizontal, {}) }) }),
|
|
541
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { align: "end", children: [
|
|
542
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
543
|
-
ui.DropdownMenu.Item,
|
|
544
|
-
{
|
|
545
|
-
className: "gap-x-2",
|
|
546
|
-
onClick: handleRetry,
|
|
547
|
-
disabled: retrying,
|
|
548
|
-
children: [
|
|
549
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowPath, { className: "text-ui-fg-subtle" }),
|
|
550
|
-
retrying ? "Re-syncing…" : "Re-sync product"
|
|
551
|
-
]
|
|
552
|
-
}
|
|
553
|
-
),
|
|
554
|
-
record.product_url && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
555
|
-
ui.DropdownMenu.Item,
|
|
556
|
-
{
|
|
557
|
-
className: "gap-x-2",
|
|
558
|
-
onClick: () => window.open(record.product_url, "_blank"),
|
|
559
|
-
children: [
|
|
560
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpRightOnBox, { className: "text-ui-fg-subtle" }),
|
|
561
|
-
"Open on Faire"
|
|
562
|
-
]
|
|
563
|
-
}
|
|
564
|
-
)
|
|
565
|
-
] })
|
|
566
|
-
] })
|
|
567
|
-
] })
|
|
568
|
-
] }),
|
|
569
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-4 grid grid-cols-2 gap-4", children: [
|
|
570
|
-
/* @__PURE__ */ jsxRuntime.jsx(Detail, { label: "Product", value: record.product_id, mono: true }),
|
|
571
|
-
/* @__PURE__ */ jsxRuntime.jsx(Detail, { label: "Action", value: record.action }),
|
|
572
|
-
/* @__PURE__ */ jsxRuntime.jsx(Detail, { label: "Faire product token", value: record.product_token || "—", mono: true }),
|
|
573
|
-
/* @__PURE__ */ jsxRuntime.jsx(Detail, { label: "State", value: record.product_state || "—" }),
|
|
574
|
-
/* @__PURE__ */ jsxRuntime.jsx(Detail, { label: "Published", value: record.published ? "Yes" : "No" }),
|
|
575
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
576
|
-
Detail,
|
|
577
|
-
{
|
|
578
|
-
label: "Synced at",
|
|
579
|
-
value: record.synced_at ? new Date(record.synced_at).toLocaleString() : "—"
|
|
580
|
-
}
|
|
581
|
-
)
|
|
582
|
-
] })
|
|
583
|
-
] }),
|
|
584
|
-
warnings.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
|
|
585
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Issues" }) }),
|
|
586
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4 flex flex-col gap-2", children: warnings.map((w, i) => /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-tag-red-text text-sm", children: w }, i)) })
|
|
587
|
-
] }),
|
|
588
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Toaster, {})
|
|
589
|
-
] });
|
|
590
|
-
};
|
|
591
|
-
const Detail = ({
|
|
592
|
-
label,
|
|
593
|
-
value,
|
|
594
|
-
mono
|
|
595
|
-
}) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
596
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { children: label }),
|
|
597
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: mono ? "font-mono text-xs" : "", children: value })
|
|
598
|
-
] });
|
|
599
|
-
const handle$2 = {
|
|
600
|
-
breadcrumb: () => "Sync record"
|
|
601
|
-
};
|
|
602
487
|
const Root = ({ prev = "..", children }) => {
|
|
603
488
|
const navigate = reactRouterDom.useNavigate();
|
|
604
489
|
const [open, setOpen] = react.useState(false);
|
|
@@ -895,10 +780,124 @@ const FaireBulkPage = () => {
|
|
|
895
780
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Toaster, {})
|
|
896
781
|
] });
|
|
897
782
|
};
|
|
898
|
-
const handle$
|
|
783
|
+
const handle$2 = {
|
|
899
784
|
breadcrumb: () => "Bulk sync"
|
|
900
785
|
};
|
|
786
|
+
const PARENT$1 = "/settings/faire";
|
|
787
|
+
const STATUS_COLORS = {
|
|
788
|
+
success: "green",
|
|
789
|
+
failed: "red",
|
|
790
|
+
draft: "orange",
|
|
791
|
+
pending: "grey",
|
|
792
|
+
syncing: "grey"
|
|
793
|
+
};
|
|
794
|
+
const FaireSyncDetailPage = () => {
|
|
795
|
+
const { id } = reactRouterDom.useParams();
|
|
796
|
+
const navigate = reactRouterDom.useNavigate();
|
|
797
|
+
const [record, setRecord] = react.useState(null);
|
|
798
|
+
const [loading, setLoading] = react.useState(true);
|
|
799
|
+
const [retrying, setRetrying] = react.useState(false);
|
|
800
|
+
const [error, setError] = react.useState(null);
|
|
801
|
+
react.useEffect(() => {
|
|
802
|
+
if (!id) return;
|
|
803
|
+
setLoading(true);
|
|
804
|
+
faireApi.getSync(id).then((res) => {
|
|
805
|
+
setRecord(res.sync || res);
|
|
806
|
+
}).catch((err) => setError(err.message || "Failed to load sync record")).finally(() => setLoading(false));
|
|
807
|
+
}, [id]);
|
|
808
|
+
const handleRetry = async () => {
|
|
809
|
+
if (!record) return;
|
|
810
|
+
setRetrying(true);
|
|
811
|
+
setError(null);
|
|
812
|
+
try {
|
|
813
|
+
await faireApi.retrySync(record.id);
|
|
814
|
+
const updated = await faireApi.getSync(record.id).catch(() => null);
|
|
815
|
+
if (updated) setRecord(updated.sync || updated);
|
|
816
|
+
} catch (err) {
|
|
817
|
+
setError(err.message || "Retry failed");
|
|
818
|
+
} finally {
|
|
819
|
+
setRetrying(false);
|
|
820
|
+
}
|
|
821
|
+
};
|
|
822
|
+
const warnings = (record == null ? void 0 : record.error_message) ? record.error_message.split(" | ") : [];
|
|
823
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(RouteFocusModal, { prev: PARENT$1, children: [
|
|
824
|
+
/* @__PURE__ */ jsxRuntime.jsxs(RouteFocusModal.Header, { children: [
|
|
825
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
826
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h1", children: "Sync record" }),
|
|
827
|
+
record && /* @__PURE__ */ jsxRuntime.jsx(ui.StatusBadge, { color: STATUS_COLORS[record.status] || "grey", children: record.status })
|
|
828
|
+
] }),
|
|
829
|
+
record && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
|
|
830
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "small", variant: "transparent", disabled: retrying, children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisHorizontal, {}) }) }),
|
|
831
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { align: "end", children: [
|
|
832
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
833
|
+
ui.DropdownMenu.Item,
|
|
834
|
+
{
|
|
835
|
+
className: "gap-x-2",
|
|
836
|
+
onClick: handleRetry,
|
|
837
|
+
disabled: retrying,
|
|
838
|
+
children: [
|
|
839
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowPath, { className: "text-ui-fg-subtle" }),
|
|
840
|
+
retrying ? "Re-syncing…" : "Re-sync product"
|
|
841
|
+
]
|
|
842
|
+
}
|
|
843
|
+
),
|
|
844
|
+
record.product_url && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
845
|
+
ui.DropdownMenu.Item,
|
|
846
|
+
{
|
|
847
|
+
className: "gap-x-2",
|
|
848
|
+
onClick: () => window.open(record.product_url, "_blank"),
|
|
849
|
+
children: [
|
|
850
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpRightOnBox, { className: "text-ui-fg-subtle" }),
|
|
851
|
+
"Open on Faire"
|
|
852
|
+
]
|
|
853
|
+
}
|
|
854
|
+
)
|
|
855
|
+
] })
|
|
856
|
+
] }) })
|
|
857
|
+
] }),
|
|
858
|
+
/* @__PURE__ */ jsxRuntime.jsxs(RouteFocusModal.Body, { className: "flex flex-col gap-4 overflow-y-auto p-6", children: [
|
|
859
|
+
error && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-tag-red-text", children: error }),
|
|
860
|
+
loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-3", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-10 w-full" }, i)) }) : !record ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start gap-4", children: [
|
|
861
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Sync record not found" }),
|
|
862
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", onClick: () => navigate(PARENT$1), children: "Back to Faire settings" })
|
|
863
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
864
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-ui-border-base grid grid-cols-2 gap-4 rounded-lg border p-4", children: [
|
|
865
|
+
/* @__PURE__ */ jsxRuntime.jsx(Detail, { label: "Record id", value: record.id, mono: true }),
|
|
866
|
+
/* @__PURE__ */ jsxRuntime.jsx(Detail, { label: "Product", value: record.product_id, mono: true }),
|
|
867
|
+
/* @__PURE__ */ jsxRuntime.jsx(Detail, { label: "Action", value: record.action }),
|
|
868
|
+
/* @__PURE__ */ jsxRuntime.jsx(Detail, { label: "Faire product token", value: record.product_token || "—", mono: true }),
|
|
869
|
+
/* @__PURE__ */ jsxRuntime.jsx(Detail, { label: "State", value: record.product_state || "—" }),
|
|
870
|
+
/* @__PURE__ */ jsxRuntime.jsx(Detail, { label: "Published", value: record.published ? "Yes" : "No" }),
|
|
871
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
872
|
+
Detail,
|
|
873
|
+
{
|
|
874
|
+
label: "Synced at",
|
|
875
|
+
value: record.synced_at ? new Date(record.synced_at).toLocaleString() : "—"
|
|
876
|
+
}
|
|
877
|
+
)
|
|
878
|
+
] }),
|
|
879
|
+
warnings.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-ui-border-base flex flex-col gap-2 rounded-lg border p-4", children: [
|
|
880
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Issues" }),
|
|
881
|
+
warnings.map((w, i) => /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-tag-red-text text-sm", children: w }, i))
|
|
882
|
+
] })
|
|
883
|
+
] })
|
|
884
|
+
] }),
|
|
885
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Toaster, {})
|
|
886
|
+
] });
|
|
887
|
+
};
|
|
888
|
+
const Detail = ({
|
|
889
|
+
label,
|
|
890
|
+
value,
|
|
891
|
+
mono
|
|
892
|
+
}) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
893
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { children: label }),
|
|
894
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: mono ? "font-mono text-xs" : "", children: value })
|
|
895
|
+
] });
|
|
896
|
+
const handle$1 = {
|
|
897
|
+
breadcrumb: () => "Sync record"
|
|
898
|
+
};
|
|
901
899
|
const STATUS_KEY = ["faire", "status"];
|
|
900
|
+
const TAXONOMY_KEY = ["faire", "taxonomy"];
|
|
902
901
|
const PARENT = "/settings/faire";
|
|
903
902
|
const NONE = "__none__";
|
|
904
903
|
const cleanSettings = (form) => {
|
|
@@ -933,6 +932,11 @@ const FaireSyncSettingsDrawer = () => {
|
|
|
933
932
|
});
|
|
934
933
|
const status = statusQuery.data;
|
|
935
934
|
const connected = !!(status == null ? void 0 : status.connected);
|
|
935
|
+
const taxonomyQuery = reactQuery.useQuery({
|
|
936
|
+
queryKey: TAXONOMY_KEY,
|
|
937
|
+
queryFn: async () => (await faireApi.taxonomy().catch(() => ({ taxonomy: [] }))).taxonomy || []
|
|
938
|
+
});
|
|
939
|
+
const taxonomy = taxonomyQuery.data ?? [];
|
|
936
940
|
react.useEffect(() => {
|
|
937
941
|
if (status == null ? void 0 : status.settings) setForm(status.settings);
|
|
938
942
|
}, [status == null ? void 0 : status.settings]);
|
|
@@ -961,7 +965,8 @@ const FaireSyncSettingsDrawer = () => {
|
|
|
961
965
|
/* @__PURE__ */ jsxRuntime.jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.connected, label: "Faire connected" }),
|
|
962
966
|
/* @__PURE__ */ jsxRuntime.jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.brand, label: "Brand configured" }),
|
|
963
967
|
/* @__PURE__ */ jsxRuntime.jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.wholesale_pricing, label: "Wholesale pricing" }),
|
|
964
|
-
/* @__PURE__ */ jsxRuntime.jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.shipping_policy, label: "Shipping policy" })
|
|
968
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.shipping_policy, label: "Shipping policy" }),
|
|
969
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChecklistItem, { ok: status == null ? void 0 : status.readiness.taxonomy, label: "Default category" })
|
|
965
970
|
] })
|
|
966
971
|
] }),
|
|
967
972
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
@@ -971,9 +976,8 @@ const FaireSyncSettingsDrawer = () => {
|
|
|
971
976
|
] }),
|
|
972
977
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4", children: [
|
|
973
978
|
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Brand ID", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
974
|
-
|
|
979
|
+
ui.Input,
|
|
975
980
|
{
|
|
976
|
-
className: "border-ui-border-base rounded-lg border px-3 py-2 text-sm",
|
|
977
981
|
value: String(form.default_brand_id ?? ""),
|
|
978
982
|
onChange: (e) => setForm({ ...form, default_brand_id: e.target.value || null }),
|
|
979
983
|
disabled: !connected,
|
|
@@ -981,10 +985,9 @@ const FaireSyncSettingsDrawer = () => {
|
|
|
981
985
|
}
|
|
982
986
|
) }),
|
|
983
987
|
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Wholesale markup % (off retail)", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: "Wholesale price = retail × (100 − markup%) / 100. E.g. 50 → half of retail.", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
984
|
-
|
|
988
|
+
ui.Input,
|
|
985
989
|
{
|
|
986
990
|
type: "number",
|
|
987
|
-
className: "border-ui-border-base rounded-lg border px-3 py-2 text-sm",
|
|
988
991
|
value: String(form.default_wholesale_markup_percent ?? ""),
|
|
989
992
|
onChange: (e) => setForm({
|
|
990
993
|
...form,
|
|
@@ -995,10 +998,9 @@ const FaireSyncSettingsDrawer = () => {
|
|
|
995
998
|
}
|
|
996
999
|
) }) }),
|
|
997
1000
|
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Default min order quantity", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
998
|
-
|
|
1001
|
+
ui.Input,
|
|
999
1002
|
{
|
|
1000
1003
|
type: "number",
|
|
1001
|
-
className: "border-ui-border-base rounded-lg border px-3 py-2 text-sm",
|
|
1002
1004
|
value: String(form.default_min_order_quantity ?? 1),
|
|
1003
1005
|
onChange: (e) => setForm({
|
|
1004
1006
|
...form,
|
|
@@ -1008,10 +1010,9 @@ const FaireSyncSettingsDrawer = () => {
|
|
|
1008
1010
|
}
|
|
1009
1011
|
) }),
|
|
1010
1012
|
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Default lead time (days)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1011
|
-
|
|
1013
|
+
ui.Input,
|
|
1012
1014
|
{
|
|
1013
1015
|
type: "number",
|
|
1014
|
-
className: "border-ui-border-base rounded-lg border px-3 py-2 text-sm",
|
|
1015
1016
|
value: String(form.default_lead_time_days ?? ""),
|
|
1016
1017
|
onChange: (e) => setForm({
|
|
1017
1018
|
...form,
|
|
@@ -1021,14 +1022,22 @@ const FaireSyncSettingsDrawer = () => {
|
|
|
1021
1022
|
placeholder: "e.g. 14"
|
|
1022
1023
|
}
|
|
1023
1024
|
) }),
|
|
1024
|
-
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Default category", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1025
|
-
|
|
1025
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Default category (taxonomy)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1026
|
+
SelectField,
|
|
1026
1027
|
{
|
|
1027
|
-
className: "border-ui-border-base rounded-lg border px-3 py-2 text-sm",
|
|
1028
1028
|
value: String(form.default_category ?? ""),
|
|
1029
|
-
|
|
1029
|
+
onValueChange: (v) => setForm({ ...form, default_category: v || null }),
|
|
1030
1030
|
disabled: !connected,
|
|
1031
|
-
|
|
1031
|
+
options: taxonomy.map((t) => ({ value: t.id, label: t.name }))
|
|
1032
|
+
}
|
|
1033
|
+
) }),
|
|
1034
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Shipping policy ID", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1035
|
+
ui.Input,
|
|
1036
|
+
{
|
|
1037
|
+
value: String(form.default_shipping_policy_id ?? ""),
|
|
1038
|
+
onChange: (e) => setForm({ ...form, default_shipping_policy_id: e.target.value || null }),
|
|
1039
|
+
disabled: !connected,
|
|
1040
|
+
placeholder: "sp_..."
|
|
1032
1041
|
}
|
|
1033
1042
|
) }),
|
|
1034
1043
|
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Follow product status", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: "If on, published Medusa products are published on Faire; draft products sync as drafts.", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1068,6 +1077,27 @@ const Field = ({ label, children }) => /* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
|
1068
1077
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { children: label }),
|
|
1069
1078
|
children
|
|
1070
1079
|
] });
|
|
1080
|
+
const SelectField = ({
|
|
1081
|
+
value,
|
|
1082
|
+
onValueChange,
|
|
1083
|
+
options,
|
|
1084
|
+
disabled
|
|
1085
|
+
}) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1086
|
+
ui.Select,
|
|
1087
|
+
{
|
|
1088
|
+
value: value ? value : NONE,
|
|
1089
|
+
onValueChange: (v) => onValueChange(v === NONE ? "" : v),
|
|
1090
|
+
disabled,
|
|
1091
|
+
size: "small",
|
|
1092
|
+
children: [
|
|
1093
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, { placeholder: "Not set" }) }),
|
|
1094
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Select.Content, { children: [
|
|
1095
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: NONE, children: "Not set" }),
|
|
1096
|
+
options.map((o) => /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: o.value, children: o.label }, o.value))
|
|
1097
|
+
] })
|
|
1098
|
+
]
|
|
1099
|
+
}
|
|
1100
|
+
);
|
|
1071
1101
|
const ChecklistItem = ({ ok, label }) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1072
1102
|
"div",
|
|
1073
1103
|
{
|
|
@@ -1165,13 +1195,13 @@ const routeModule = {
|
|
|
1165
1195
|
handle: handle$3
|
|
1166
1196
|
},
|
|
1167
1197
|
{
|
|
1168
|
-
Component:
|
|
1169
|
-
path: "/settings/faire
|
|
1198
|
+
Component: FaireBulkPage,
|
|
1199
|
+
path: "/settings/faire/bulk",
|
|
1170
1200
|
handle: handle$2
|
|
1171
1201
|
},
|
|
1172
1202
|
{
|
|
1173
|
-
Component:
|
|
1174
|
-
path: "/settings/faire
|
|
1203
|
+
Component: FaireSyncDetailPage,
|
|
1204
|
+
path: "/settings/faire/:id",
|
|
1175
1205
|
handle: handle$1
|
|
1176
1206
|
},
|
|
1177
1207
|
{
|