@medusajs/draft-order 2.21.1 → 2.21.2-snapshot-20260925150426
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/admin/index.js +848 -848
- package/.medusa/server/src/admin/index.mjs +848 -848
- package/package.json +18 -18
|
@@ -3032,7 +3032,7 @@ const LoadingState = () => {
|
|
|
3032
3032
|
};
|
|
3033
3033
|
const CustomerInfo = ({ customer }) => {
|
|
3034
3034
|
const name = [customer.first_name, customer.last_name].filter(Boolean).join(" ");
|
|
3035
|
-
const fallback = name ? name[0] : customer.email[0];
|
|
3035
|
+
const fallback = name ? name[0] : customer.email?.[0] || "-";
|
|
3036
3036
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 flex-1", children: [
|
|
3037
3037
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Avatar, { size: "small", fallback, className: "w-6 h-6" }),
|
|
3038
3038
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col flex-1 overflow-hidden", children: [
|
|
@@ -6168,27 +6168,6 @@ const BillingAddressForm = ({ order }) => {
|
|
|
6168
6168
|
) });
|
|
6169
6169
|
};
|
|
6170
6170
|
const schema$5 = addressSchema;
|
|
6171
|
-
const CustomItems = () => {
|
|
6172
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
|
|
6173
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
|
|
6174
|
-
/* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
|
|
6175
|
-
] });
|
|
6176
|
-
};
|
|
6177
|
-
const CustomItemsForm = () => {
|
|
6178
|
-
const form = reactHookForm.useForm({
|
|
6179
|
-
resolver: zod$1.zodResolver(schema$4)
|
|
6180
|
-
});
|
|
6181
|
-
return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
|
|
6182
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
|
|
6183
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
6184
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
|
|
6185
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
|
|
6186
|
-
] }) })
|
|
6187
|
-
] }) });
|
|
6188
|
-
};
|
|
6189
|
-
const schema$4 = zod.z.object({
|
|
6190
|
-
email: zod.z.string().email()
|
|
6191
|
-
});
|
|
6192
6171
|
const Email = () => {
|
|
6193
6172
|
const { id } = reactRouterDom.useParams();
|
|
6194
6173
|
const { order, isPending, isError, error } = useOrder(id, {
|
|
@@ -6211,7 +6190,7 @@ const EmailForm = ({ order }) => {
|
|
|
6211
6190
|
defaultValues: {
|
|
6212
6191
|
email: order.email ?? ""
|
|
6213
6192
|
},
|
|
6214
|
-
resolver: zod$1.zodResolver(schema$
|
|
6193
|
+
resolver: zod$1.zodResolver(schema$4)
|
|
6215
6194
|
});
|
|
6216
6195
|
const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
|
|
6217
6196
|
const { handleSuccess } = useRouteModal();
|
|
@@ -6254,7 +6233,7 @@ const EmailForm = ({ order }) => {
|
|
|
6254
6233
|
}
|
|
6255
6234
|
) });
|
|
6256
6235
|
};
|
|
6257
|
-
const schema$
|
|
6236
|
+
const schema$4 = zod.z.object({
|
|
6258
6237
|
email: zod.z.string().email()
|
|
6259
6238
|
});
|
|
6260
6239
|
const NumberInput = React.forwardRef(
|
|
@@ -7276,88 +7255,67 @@ const customItemSchema = zod.z.object({
|
|
|
7276
7255
|
quantity: zod.z.number(),
|
|
7277
7256
|
unit_price: zod.z.union([zod.z.number(), zod.z.string()])
|
|
7278
7257
|
});
|
|
7279
|
-
const
|
|
7280
|
-
|
|
7281
|
-
|
|
7282
|
-
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
|
|
7288
|
-
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
|
|
7293
|
-
|
|
7294
|
-
|
|
7295
|
-
|
|
7296
|
-
|
|
7297
|
-
|
|
7298
|
-
|
|
7299
|
-
}
|
|
7300
|
-
),
|
|
7301
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
|
|
7302
|
-
/* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
|
|
7303
|
-
labelValue,
|
|
7304
|
-
":"
|
|
7305
|
-
] }),
|
|
7306
|
-
" ",
|
|
7307
|
-
children
|
|
7308
|
-
] })
|
|
7309
|
-
]
|
|
7310
|
-
}
|
|
7311
|
-
);
|
|
7312
|
-
}
|
|
7313
|
-
);
|
|
7314
|
-
InlineTip.displayName = "InlineTip";
|
|
7315
|
-
const MetadataFieldSchema = zod.z.object({
|
|
7316
|
-
key: zod.z.string(),
|
|
7317
|
-
disabled: zod.z.boolean().optional(),
|
|
7318
|
-
value: zod.z.any()
|
|
7319
|
-
});
|
|
7320
|
-
const MetadataSchema = zod.z.object({
|
|
7321
|
-
metadata: zod.z.array(MetadataFieldSchema)
|
|
7258
|
+
const CustomItems = () => {
|
|
7259
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
|
|
7260
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
|
|
7261
|
+
/* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
|
|
7262
|
+
] });
|
|
7263
|
+
};
|
|
7264
|
+
const CustomItemsForm = () => {
|
|
7265
|
+
const form = reactHookForm.useForm({
|
|
7266
|
+
resolver: zod$1.zodResolver(schema$3)
|
|
7267
|
+
});
|
|
7268
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
|
|
7269
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
|
|
7270
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
7271
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
|
|
7272
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
|
|
7273
|
+
] }) })
|
|
7274
|
+
] }) });
|
|
7275
|
+
};
|
|
7276
|
+
const schema$3 = zod.z.object({
|
|
7277
|
+
email: zod.z.string().email()
|
|
7322
7278
|
});
|
|
7323
|
-
const
|
|
7279
|
+
const SalesChannel = () => {
|
|
7324
7280
|
const { id } = reactRouterDom.useParams();
|
|
7325
|
-
const {
|
|
7326
|
-
|
|
7327
|
-
|
|
7281
|
+
const { draft_order, isPending, isError, error } = useDraftOrder(
|
|
7282
|
+
id,
|
|
7283
|
+
{
|
|
7284
|
+
fields: "+sales_channel_id"
|
|
7285
|
+
},
|
|
7286
|
+
{
|
|
7287
|
+
enabled: !!id
|
|
7288
|
+
}
|
|
7289
|
+
);
|
|
7328
7290
|
if (isError) {
|
|
7329
7291
|
throw error;
|
|
7330
7292
|
}
|
|
7331
|
-
const
|
|
7293
|
+
const ISrEADY = !!draft_order && !isPending;
|
|
7332
7294
|
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
|
|
7333
7295
|
/* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
|
|
7334
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "
|
|
7335
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "
|
|
7296
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
|
|
7297
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
|
|
7336
7298
|
] }),
|
|
7337
|
-
|
|
7299
|
+
ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
|
|
7338
7300
|
] });
|
|
7339
7301
|
};
|
|
7340
|
-
const
|
|
7341
|
-
const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
|
|
7342
|
-
const MetadataForm = ({ orderId, metadata }) => {
|
|
7343
|
-
const { handleSuccess } = useRouteModal();
|
|
7344
|
-
const hasUneditableRows = getHasUneditableRows(metadata);
|
|
7345
|
-
const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
|
|
7302
|
+
const SalesChannelForm = ({ order }) => {
|
|
7346
7303
|
const form = reactHookForm.useForm({
|
|
7347
7304
|
defaultValues: {
|
|
7348
|
-
|
|
7305
|
+
sales_channel_id: order.sales_channel_id || ""
|
|
7349
7306
|
},
|
|
7350
|
-
resolver: zod$1.zodResolver(
|
|
7307
|
+
resolver: zod$1.zodResolver(schema$2)
|
|
7351
7308
|
});
|
|
7352
|
-
const
|
|
7353
|
-
|
|
7309
|
+
const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
|
|
7310
|
+
const { handleSuccess } = useRouteModal();
|
|
7311
|
+
const onSubmit = form.handleSubmit(async (data) => {
|
|
7354
7312
|
await mutateAsync(
|
|
7355
7313
|
{
|
|
7356
|
-
|
|
7314
|
+
sales_channel_id: data.sales_channel_id
|
|
7357
7315
|
},
|
|
7358
7316
|
{
|
|
7359
7317
|
onSuccess: () => {
|
|
7360
|
-
ui.toast.success("
|
|
7318
|
+
ui.toast.success("Sales channel updated");
|
|
7361
7319
|
handleSuccess();
|
|
7362
7320
|
},
|
|
7363
7321
|
onError: (error) => {
|
|
@@ -7366,365 +7324,133 @@ const MetadataForm = ({ orderId, metadata }) => {
|
|
|
7366
7324
|
}
|
|
7367
7325
|
);
|
|
7368
7326
|
});
|
|
7369
|
-
const { fields, insert, remove } = reactHookForm.useFieldArray({
|
|
7370
|
-
control: form.control,
|
|
7371
|
-
name: "metadata"
|
|
7372
|
-
});
|
|
7373
|
-
function deleteRow(index) {
|
|
7374
|
-
remove(index);
|
|
7375
|
-
if (fields.length === 1) {
|
|
7376
|
-
insert(0, {
|
|
7377
|
-
key: "",
|
|
7378
|
-
value: "",
|
|
7379
|
-
disabled: false
|
|
7380
|
-
});
|
|
7381
|
-
}
|
|
7382
|
-
}
|
|
7383
|
-
function insertRow(index, position) {
|
|
7384
|
-
insert(index + (position === "above" ? 0 : 1), {
|
|
7385
|
-
key: "",
|
|
7386
|
-
value: "",
|
|
7387
|
-
disabled: false
|
|
7388
|
-
});
|
|
7389
|
-
}
|
|
7390
7327
|
return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7391
7328
|
KeyboundForm,
|
|
7392
7329
|
{
|
|
7393
|
-
onSubmit: handleSubmit,
|
|
7394
7330
|
className: "flex flex-1 flex-col overflow-hidden",
|
|
7331
|
+
onSubmit,
|
|
7395
7332
|
children: [
|
|
7396
|
-
/* @__PURE__ */ jsxRuntime.
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
|
|
7400
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
|
|
7401
|
-
] }),
|
|
7402
|
-
fields.map((field, index) => {
|
|
7403
|
-
const isDisabled = field.disabled || false;
|
|
7404
|
-
let placeholder = "-";
|
|
7405
|
-
if (typeof field.value === "object") {
|
|
7406
|
-
placeholder = "{ ... }";
|
|
7407
|
-
}
|
|
7408
|
-
if (Array.isArray(field.value)) {
|
|
7409
|
-
placeholder = "[ ... ]";
|
|
7410
|
-
}
|
|
7411
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7412
|
-
ConditionalTooltip,
|
|
7413
|
-
{
|
|
7414
|
-
showTooltip: isDisabled,
|
|
7415
|
-
content: "This row is disabled because it contains non-primitive data.",
|
|
7416
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
|
|
7417
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7418
|
-
"div",
|
|
7419
|
-
{
|
|
7420
|
-
className: ui.clx("grid grid-cols-2 divide-x", {
|
|
7421
|
-
"overflow-hidden rounded-b-lg": index === fields.length - 1
|
|
7422
|
-
}),
|
|
7423
|
-
children: [
|
|
7424
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7425
|
-
Form$2.Field,
|
|
7426
|
-
{
|
|
7427
|
-
control: form.control,
|
|
7428
|
-
name: `metadata.${index}.key`,
|
|
7429
|
-
render: ({ field: field2 }) => {
|
|
7430
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7431
|
-
GridInput,
|
|
7432
|
-
{
|
|
7433
|
-
"aria-labelledby": METADATA_KEY_LABEL_ID,
|
|
7434
|
-
...field2,
|
|
7435
|
-
disabled: isDisabled,
|
|
7436
|
-
placeholder: "Key"
|
|
7437
|
-
}
|
|
7438
|
-
) }) });
|
|
7439
|
-
}
|
|
7440
|
-
}
|
|
7441
|
-
),
|
|
7442
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7443
|
-
Form$2.Field,
|
|
7444
|
-
{
|
|
7445
|
-
control: form.control,
|
|
7446
|
-
name: `metadata.${index}.value`,
|
|
7447
|
-
render: ({ field: { value, ...field2 } }) => {
|
|
7448
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7449
|
-
GridInput,
|
|
7450
|
-
{
|
|
7451
|
-
"aria-labelledby": METADATA_VALUE_LABEL_ID,
|
|
7452
|
-
...field2,
|
|
7453
|
-
value: isDisabled ? placeholder : value,
|
|
7454
|
-
disabled: isDisabled,
|
|
7455
|
-
placeholder: "Value"
|
|
7456
|
-
}
|
|
7457
|
-
) }) });
|
|
7458
|
-
}
|
|
7459
|
-
}
|
|
7460
|
-
)
|
|
7461
|
-
]
|
|
7462
|
-
}
|
|
7463
|
-
),
|
|
7464
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
|
|
7465
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7466
|
-
ui.DropdownMenu.Trigger,
|
|
7467
|
-
{
|
|
7468
|
-
className: ui.clx(
|
|
7469
|
-
"invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
|
|
7470
|
-
{
|
|
7471
|
-
hidden: isDisabled
|
|
7472
|
-
}
|
|
7473
|
-
),
|
|
7474
|
-
disabled: isDisabled,
|
|
7475
|
-
asChild: true,
|
|
7476
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
|
|
7477
|
-
}
|
|
7478
|
-
),
|
|
7479
|
-
/* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
|
|
7480
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7481
|
-
ui.DropdownMenu.Item,
|
|
7482
|
-
{
|
|
7483
|
-
className: "gap-x-2",
|
|
7484
|
-
onClick: () => insertRow(index, "above"),
|
|
7485
|
-
children: [
|
|
7486
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
|
|
7487
|
-
"Insert row above"
|
|
7488
|
-
]
|
|
7489
|
-
}
|
|
7490
|
-
),
|
|
7491
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7492
|
-
ui.DropdownMenu.Item,
|
|
7493
|
-
{
|
|
7494
|
-
className: "gap-x-2",
|
|
7495
|
-
onClick: () => insertRow(index, "below"),
|
|
7496
|
-
children: [
|
|
7497
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
|
|
7498
|
-
"Insert row below"
|
|
7499
|
-
]
|
|
7500
|
-
}
|
|
7501
|
-
),
|
|
7502
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
|
|
7503
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7504
|
-
ui.DropdownMenu.Item,
|
|
7505
|
-
{
|
|
7506
|
-
className: "gap-x-2",
|
|
7507
|
-
onClick: () => deleteRow(index),
|
|
7508
|
-
children: [
|
|
7509
|
-
/* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
|
|
7510
|
-
"Delete row"
|
|
7511
|
-
]
|
|
7512
|
-
}
|
|
7513
|
-
)
|
|
7514
|
-
] })
|
|
7515
|
-
] })
|
|
7516
|
-
] })
|
|
7517
|
-
},
|
|
7518
|
-
field.id
|
|
7519
|
-
);
|
|
7520
|
-
})
|
|
7521
|
-
] }),
|
|
7522
|
-
hasUneditableRows && /* @__PURE__ */ jsxRuntime.jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
|
|
7523
|
-
] }),
|
|
7524
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
|
|
7525
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
|
|
7333
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
|
|
7334
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
7335
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
|
|
7526
7336
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
|
|
7527
7337
|
] }) })
|
|
7528
7338
|
]
|
|
7529
7339
|
}
|
|
7530
7340
|
) });
|
|
7531
7341
|
};
|
|
7532
|
-
const
|
|
7342
|
+
const SalesChannelField = ({ control, order }) => {
|
|
7343
|
+
const salesChannels = useComboboxData({
|
|
7344
|
+
queryFn: async (params) => {
|
|
7345
|
+
return await sdk.admin.salesChannel.list(params);
|
|
7346
|
+
},
|
|
7347
|
+
queryKey: ["sales-channels"],
|
|
7348
|
+
getOptions: (data) => {
|
|
7349
|
+
return data.sales_channels.map((salesChannel) => ({
|
|
7350
|
+
label: salesChannel.name,
|
|
7351
|
+
value: salesChannel.id
|
|
7352
|
+
}));
|
|
7353
|
+
},
|
|
7354
|
+
defaultValue: order.sales_channel_id || void 0
|
|
7355
|
+
});
|
|
7533
7356
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7534
|
-
|
|
7357
|
+
Form$2.Field,
|
|
7535
7358
|
{
|
|
7536
|
-
|
|
7537
|
-
|
|
7538
|
-
|
|
7539
|
-
|
|
7540
|
-
|
|
7541
|
-
|
|
7542
|
-
|
|
7543
|
-
|
|
7544
|
-
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
|
|
7552
|
-
|
|
7553
|
-
|
|
7554
|
-
|
|
7555
|
-
};
|
|
7556
|
-
const EDITABLE_TYPES = ["string", "number", "boolean"];
|
|
7557
|
-
function getDefaultValues(metadata) {
|
|
7558
|
-
if (!metadata || !Object.keys(metadata).length) {
|
|
7559
|
-
return [
|
|
7560
|
-
{
|
|
7561
|
-
key: "",
|
|
7562
|
-
value: "",
|
|
7563
|
-
disabled: false
|
|
7564
|
-
}
|
|
7565
|
-
];
|
|
7566
|
-
}
|
|
7567
|
-
return Object.entries(metadata).map(([key, value]) => {
|
|
7568
|
-
if (!EDITABLE_TYPES.includes(typeof value)) {
|
|
7569
|
-
return {
|
|
7570
|
-
key,
|
|
7571
|
-
value,
|
|
7572
|
-
disabled: true
|
|
7573
|
-
};
|
|
7574
|
-
}
|
|
7575
|
-
let stringValue = value;
|
|
7576
|
-
if (typeof value !== "string") {
|
|
7577
|
-
stringValue = JSON.stringify(value);
|
|
7578
|
-
}
|
|
7579
|
-
return {
|
|
7580
|
-
key,
|
|
7581
|
-
value: stringValue,
|
|
7582
|
-
original_key: key
|
|
7583
|
-
};
|
|
7584
|
-
});
|
|
7585
|
-
}
|
|
7586
|
-
function parseValues(values) {
|
|
7587
|
-
const metadata = values.metadata;
|
|
7588
|
-
const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
|
|
7589
|
-
if (isEmpty) {
|
|
7590
|
-
return null;
|
|
7591
|
-
}
|
|
7592
|
-
const update = {};
|
|
7593
|
-
metadata.forEach((field) => {
|
|
7594
|
-
let key = field.key;
|
|
7595
|
-
let value = field.value;
|
|
7596
|
-
const disabled = field.disabled;
|
|
7597
|
-
if (!key || !value) {
|
|
7598
|
-
return;
|
|
7599
|
-
}
|
|
7600
|
-
if (disabled) {
|
|
7601
|
-
update[key] = value;
|
|
7602
|
-
return;
|
|
7603
|
-
}
|
|
7604
|
-
key = key.trim();
|
|
7605
|
-
value = value.trim();
|
|
7606
|
-
if (value === "true") {
|
|
7607
|
-
update[key] = true;
|
|
7608
|
-
} else if (value === "false") {
|
|
7609
|
-
update[key] = false;
|
|
7610
|
-
} else {
|
|
7611
|
-
const parsedNumber = parseFloat(value);
|
|
7612
|
-
if (!isNaN(parsedNumber)) {
|
|
7613
|
-
update[key] = parsedNumber;
|
|
7614
|
-
} else {
|
|
7615
|
-
update[key] = value;
|
|
7359
|
+
control,
|
|
7360
|
+
name: "sales_channel_id",
|
|
7361
|
+
render: ({ field }) => {
|
|
7362
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
|
|
7363
|
+
/* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
|
|
7364
|
+
/* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7365
|
+
Combobox,
|
|
7366
|
+
{
|
|
7367
|
+
options: salesChannels.options,
|
|
7368
|
+
fetchNextPage: salesChannels.fetchNextPage,
|
|
7369
|
+
isFetchingNextPage: salesChannels.isFetchingNextPage,
|
|
7370
|
+
searchValue: salesChannels.searchValue,
|
|
7371
|
+
onSearchValueChange: salesChannels.onSearchValueChange,
|
|
7372
|
+
placeholder: "Select sales channel",
|
|
7373
|
+
...field
|
|
7374
|
+
}
|
|
7375
|
+
) }),
|
|
7376
|
+
/* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
|
|
7377
|
+
] });
|
|
7616
7378
|
}
|
|
7617
7379
|
}
|
|
7618
|
-
});
|
|
7619
|
-
return update;
|
|
7620
|
-
}
|
|
7621
|
-
function getHasUneditableRows(metadata) {
|
|
7622
|
-
if (!metadata) {
|
|
7623
|
-
return false;
|
|
7624
|
-
}
|
|
7625
|
-
return Object.values(metadata).some(
|
|
7626
|
-
(value) => !EDITABLE_TYPES.includes(typeof value)
|
|
7627
7380
|
);
|
|
7628
|
-
}
|
|
7629
|
-
const PROMOTION_QUERY_KEY = "promotions";
|
|
7630
|
-
const promotionsQueryKeys = {
|
|
7631
|
-
list: (query2) => [
|
|
7632
|
-
PROMOTION_QUERY_KEY,
|
|
7633
|
-
query2 ? query2 : void 0
|
|
7634
|
-
],
|
|
7635
|
-
detail: (id, query2) => [
|
|
7636
|
-
PROMOTION_QUERY_KEY,
|
|
7637
|
-
id,
|
|
7638
|
-
query2 ? query2 : void 0
|
|
7639
|
-
]
|
|
7640
|
-
};
|
|
7641
|
-
const usePromotions = (query2, options) => {
|
|
7642
|
-
const { data, ...rest } = reactQuery.useQuery({
|
|
7643
|
-
queryKey: promotionsQueryKeys.list(query2),
|
|
7644
|
-
queryFn: async () => sdk.admin.promotion.list(query2),
|
|
7645
|
-
...options
|
|
7646
|
-
});
|
|
7647
|
-
return { ...data, ...rest };
|
|
7648
7381
|
};
|
|
7649
|
-
const
|
|
7382
|
+
const schema$2 = zod.z.object({
|
|
7383
|
+
sales_channel_id: zod.z.string().min(1)
|
|
7384
|
+
});
|
|
7385
|
+
const STACKED_FOCUS_MODAL_ID = "shipping-form";
|
|
7386
|
+
const Shipping = () => {
|
|
7650
7387
|
const { id } = reactRouterDom.useParams();
|
|
7388
|
+
const { order, isPending, isError, error } = useOrder(id, {
|
|
7389
|
+
fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
|
|
7390
|
+
});
|
|
7651
7391
|
const {
|
|
7652
7392
|
order: preview,
|
|
7393
|
+
isPending: isPreviewPending,
|
|
7653
7394
|
isError: isPreviewError,
|
|
7654
7395
|
error: previewError
|
|
7655
|
-
} = useOrderPreview(id
|
|
7396
|
+
} = useOrderPreview(id);
|
|
7656
7397
|
useInitiateOrderEdit({ preview });
|
|
7657
7398
|
const { onCancel } = useCancelOrderEdit({ preview });
|
|
7399
|
+
if (isError) {
|
|
7400
|
+
throw error;
|
|
7401
|
+
}
|
|
7658
7402
|
if (isPreviewError) {
|
|
7659
7403
|
throw previewError;
|
|
7660
7404
|
}
|
|
7661
|
-
const
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
7405
|
+
const orderHasItems = (order?.items?.length || 0) > 0;
|
|
7406
|
+
const isReady = preview && !isPreviewPending && order && !isPending;
|
|
7407
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
|
|
7408
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
|
|
7409
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-6 py-16", children: [
|
|
7410
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
|
|
7411
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This draft order currently has no items. Add items to the order before adding shipping." }) })
|
|
7412
|
+
] }) }) }),
|
|
7413
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }) })
|
|
7414
|
+
] }) : isReady ? /* @__PURE__ */ jsxRuntime.jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
7415
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
|
|
7416
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
|
|
7417
|
+
] }) });
|
|
7666
7418
|
};
|
|
7667
|
-
const
|
|
7668
|
-
const {
|
|
7419
|
+
const ShippingForm = ({ preview, order }) => {
|
|
7420
|
+
const { setIsOpen } = useStackedModal();
|
|
7669
7421
|
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
7670
|
-
const [
|
|
7671
|
-
const
|
|
7672
|
-
const {
|
|
7673
|
-
const promoIds = getPromotionIds(items, shipping_methods);
|
|
7674
|
-
const { promotions, isPending, isError, error } = usePromotions(
|
|
7422
|
+
const [data, setData] = React.useState(null);
|
|
7423
|
+
const appliedShippingOptionIds = preview.shipping_methods?.map((method) => method.shipping_option_id).filter(Boolean);
|
|
7424
|
+
const { shipping_options } = useShippingOptions(
|
|
7675
7425
|
{
|
|
7676
|
-
id:
|
|
7426
|
+
id: appliedShippingOptionIds,
|
|
7427
|
+
fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
|
|
7677
7428
|
},
|
|
7678
7429
|
{
|
|
7679
|
-
enabled:
|
|
7430
|
+
enabled: appliedShippingOptionIds.length > 0
|
|
7680
7431
|
}
|
|
7681
7432
|
);
|
|
7682
|
-
const
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
return data.promotions.map((promotion) => ({
|
|
7694
|
-
label: promotion.code,
|
|
7695
|
-
value: promotion.code
|
|
7696
|
-
}));
|
|
7697
|
-
}
|
|
7698
|
-
});
|
|
7699
|
-
const add = async (value) => {
|
|
7700
|
-
if (!value) {
|
|
7701
|
-
return;
|
|
7702
|
-
}
|
|
7703
|
-
addPromotions(
|
|
7704
|
-
{
|
|
7705
|
-
promo_codes: [value]
|
|
7706
|
-
},
|
|
7707
|
-
{
|
|
7708
|
-
onError: (e) => {
|
|
7709
|
-
ui.toast.error(e.message);
|
|
7710
|
-
comboboxData.onSearchValueChange("");
|
|
7711
|
-
setComboboxValue("");
|
|
7712
|
-
},
|
|
7713
|
-
onSuccess: () => {
|
|
7714
|
-
comboboxData.onSearchValueChange("");
|
|
7715
|
-
setComboboxValue("");
|
|
7716
|
-
}
|
|
7717
|
-
}
|
|
7718
|
-
);
|
|
7719
|
-
};
|
|
7433
|
+
const uniqueShippingProfiles = React.useMemo(() => {
|
|
7434
|
+
const profiles = /* @__PURE__ */ new Map();
|
|
7435
|
+
getUniqueShippingProfiles(order.items).forEach((profile) => {
|
|
7436
|
+
profiles.set(profile.id, profile);
|
|
7437
|
+
});
|
|
7438
|
+
shipping_options?.forEach((option) => {
|
|
7439
|
+
profiles.set(option.shipping_profile_id, option.shipping_profile);
|
|
7440
|
+
});
|
|
7441
|
+
return Array.from(profiles.values());
|
|
7442
|
+
}, [order.items, shipping_options]);
|
|
7443
|
+
const { handleSuccess } = useRouteModal();
|
|
7720
7444
|
const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
|
|
7721
|
-
const { mutateAsync: requestOrderEdit } =
|
|
7445
|
+
const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
|
|
7446
|
+
const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
|
|
7447
|
+
const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
|
|
7722
7448
|
const onSubmit = async () => {
|
|
7723
7449
|
setIsSubmitting(true);
|
|
7724
7450
|
let requestSucceeded = false;
|
|
7725
7451
|
await requestOrderEdit(void 0, {
|
|
7726
7452
|
onError: (e) => {
|
|
7727
|
-
ui.toast.error(e.message);
|
|
7453
|
+
ui.toast.error(`Failed to request order edit: ${e.message}`);
|
|
7728
7454
|
},
|
|
7729
7455
|
onSuccess: () => {
|
|
7730
7456
|
requestSucceeded = true;
|
|
@@ -7736,7 +7462,7 @@ const PromotionForm = ({ preview }) => {
|
|
|
7736
7462
|
}
|
|
7737
7463
|
await confirmOrderEdit(void 0, {
|
|
7738
7464
|
onError: (e) => {
|
|
7739
|
-
ui.toast.error(e.message);
|
|
7465
|
+
ui.toast.error(`Failed to confirm order edit: ${e.message}`);
|
|
7740
7466
|
},
|
|
7741
7467
|
onSuccess: () => {
|
|
7742
7468
|
handleSuccess();
|
|
@@ -7746,367 +7472,16 @@ const PromotionForm = ({ preview }) => {
|
|
|
7746
7472
|
}
|
|
7747
7473
|
});
|
|
7748
7474
|
};
|
|
7749
|
-
|
|
7750
|
-
|
|
7751
|
-
|
|
7752
|
-
|
|
7753
|
-
|
|
7754
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
7755
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
7756
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
|
|
7757
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
|
|
7758
|
-
] }),
|
|
7759
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7760
|
-
Combobox,
|
|
7761
|
-
{
|
|
7762
|
-
id: "promotion-combobox",
|
|
7763
|
-
"aria-describedby": "promotion-combobox-hint",
|
|
7764
|
-
isFetchingNextPage: comboboxData.isFetchingNextPage,
|
|
7765
|
-
fetchNextPage: comboboxData.fetchNextPage,
|
|
7766
|
-
options: comboboxData.options,
|
|
7767
|
-
onSearchValueChange: comboboxData.onSearchValueChange,
|
|
7768
|
-
searchValue: comboboxData.searchValue,
|
|
7769
|
-
disabled: comboboxData.disabled || isAddingPromotions,
|
|
7770
|
-
onChange: add,
|
|
7771
|
-
value: comboboxValue
|
|
7772
|
-
}
|
|
7773
|
-
)
|
|
7774
|
-
] }),
|
|
7775
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
|
|
7776
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions?.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
7777
|
-
PromotionItem,
|
|
7778
|
-
{
|
|
7779
|
-
promotion,
|
|
7780
|
-
orderId: preview.id,
|
|
7781
|
-
isLoading: isPending
|
|
7782
|
-
},
|
|
7783
|
-
promotion.id
|
|
7784
|
-
)) })
|
|
7785
|
-
] }) }),
|
|
7786
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
7787
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
|
|
7788
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7789
|
-
ui.Button,
|
|
7790
|
-
{
|
|
7791
|
-
size: "small",
|
|
7792
|
-
type: "submit",
|
|
7793
|
-
isLoading: isSubmitting || isAddingPromotions,
|
|
7794
|
-
children: "Save"
|
|
7795
|
-
}
|
|
7796
|
-
)
|
|
7797
|
-
] }) })
|
|
7798
|
-
] });
|
|
7799
|
-
};
|
|
7800
|
-
const PromotionItem = ({
|
|
7801
|
-
promotion,
|
|
7802
|
-
orderId,
|
|
7803
|
-
isLoading
|
|
7804
|
-
}) => {
|
|
7805
|
-
const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
|
|
7806
|
-
const onRemove = async () => {
|
|
7807
|
-
removePromotions(
|
|
7808
|
-
{
|
|
7809
|
-
promo_codes: [promotion.code]
|
|
7810
|
-
},
|
|
7811
|
-
{
|
|
7812
|
-
onError: (e) => {
|
|
7813
|
-
ui.toast.error(e.message);
|
|
7814
|
-
}
|
|
7815
|
-
}
|
|
7816
|
-
);
|
|
7817
|
-
};
|
|
7818
|
-
const displayValue = getDisplayValue(promotion);
|
|
7819
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7820
|
-
"div",
|
|
7821
|
-
{
|
|
7822
|
-
className: ui.clx(
|
|
7823
|
-
"bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
|
|
7824
|
-
{
|
|
7825
|
-
"animate-pulse": isLoading
|
|
7826
|
-
}
|
|
7827
|
-
),
|
|
7828
|
-
children: [
|
|
7829
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
7830
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
|
|
7831
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
|
|
7832
|
-
displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
7833
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
|
|
7834
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
|
|
7835
|
-
] }),
|
|
7836
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: promotion.application_method?.allocation })
|
|
7837
|
-
] })
|
|
7838
|
-
] }),
|
|
7839
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7840
|
-
ui.IconButton,
|
|
7841
|
-
{
|
|
7842
|
-
size: "small",
|
|
7843
|
-
type: "button",
|
|
7844
|
-
variant: "transparent",
|
|
7845
|
-
onClick: onRemove,
|
|
7846
|
-
isLoading: isPending || isLoading,
|
|
7847
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
|
|
7848
|
-
}
|
|
7849
|
-
)
|
|
7850
|
-
]
|
|
7851
|
-
},
|
|
7852
|
-
promotion.id
|
|
7853
|
-
);
|
|
7854
|
-
};
|
|
7855
|
-
function getDisplayValue(promotion) {
|
|
7856
|
-
const value = promotion.application_method?.value;
|
|
7857
|
-
if (!value) {
|
|
7858
|
-
return null;
|
|
7859
|
-
}
|
|
7860
|
-
if (promotion.application_method?.type === "fixed") {
|
|
7861
|
-
const currency = promotion.application_method?.currency_code;
|
|
7862
|
-
if (!currency) {
|
|
7863
|
-
return null;
|
|
7864
|
-
}
|
|
7865
|
-
return getLocaleAmount(value, currency);
|
|
7866
|
-
} else if (promotion.application_method?.type === "percentage") {
|
|
7867
|
-
return formatPercentage(value);
|
|
7868
|
-
}
|
|
7869
|
-
return null;
|
|
7870
|
-
}
|
|
7871
|
-
const formatter = new Intl.NumberFormat([], {
|
|
7872
|
-
style: "percent",
|
|
7873
|
-
minimumFractionDigits: 2
|
|
7874
|
-
});
|
|
7875
|
-
const formatPercentage = (value, isPercentageValue = false) => {
|
|
7876
|
-
let val = value || 0;
|
|
7877
|
-
if (!isPercentageValue) {
|
|
7878
|
-
val = val / 100;
|
|
7879
|
-
}
|
|
7880
|
-
return formatter.format(val);
|
|
7881
|
-
};
|
|
7882
|
-
function getPromotionIds(items, shippingMethods) {
|
|
7883
|
-
const promotionIds = /* @__PURE__ */ new Set();
|
|
7884
|
-
for (const item of items) {
|
|
7885
|
-
if (item.adjustments) {
|
|
7886
|
-
for (const adjustment of item.adjustments) {
|
|
7887
|
-
if (adjustment.promotion_id) {
|
|
7888
|
-
promotionIds.add(adjustment.promotion_id);
|
|
7889
|
-
}
|
|
7890
|
-
}
|
|
7891
|
-
}
|
|
7892
|
-
}
|
|
7893
|
-
for (const shippingMethod of shippingMethods) {
|
|
7894
|
-
if (shippingMethod.adjustments) {
|
|
7895
|
-
for (const adjustment of shippingMethod.adjustments) {
|
|
7896
|
-
if (adjustment.promotion_id) {
|
|
7897
|
-
promotionIds.add(adjustment.promotion_id);
|
|
7475
|
+
const onKeydown = React.useCallback(
|
|
7476
|
+
(e) => {
|
|
7477
|
+
if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
|
|
7478
|
+
if (data || isSubmitting) {
|
|
7479
|
+
return;
|
|
7898
7480
|
}
|
|
7481
|
+
onSubmit();
|
|
7899
7482
|
}
|
|
7900
|
-
}
|
|
7901
|
-
}
|
|
7902
|
-
return Array.from(promotionIds);
|
|
7903
|
-
}
|
|
7904
|
-
const SalesChannel = () => {
|
|
7905
|
-
const { id } = reactRouterDom.useParams();
|
|
7906
|
-
const { draft_order, isPending, isError, error } = useDraftOrder(
|
|
7907
|
-
id,
|
|
7908
|
-
{
|
|
7909
|
-
fields: "+sales_channel_id"
|
|
7910
7483
|
},
|
|
7911
|
-
|
|
7912
|
-
enabled: !!id
|
|
7913
|
-
}
|
|
7914
|
-
);
|
|
7915
|
-
if (isError) {
|
|
7916
|
-
throw error;
|
|
7917
|
-
}
|
|
7918
|
-
const ISrEADY = !!draft_order && !isPending;
|
|
7919
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
|
|
7920
|
-
/* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
|
|
7921
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
|
|
7922
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
|
|
7923
|
-
] }),
|
|
7924
|
-
ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
|
|
7925
|
-
] });
|
|
7926
|
-
};
|
|
7927
|
-
const SalesChannelForm = ({ order }) => {
|
|
7928
|
-
const form = reactHookForm.useForm({
|
|
7929
|
-
defaultValues: {
|
|
7930
|
-
sales_channel_id: order.sales_channel_id || ""
|
|
7931
|
-
},
|
|
7932
|
-
resolver: zod$1.zodResolver(schema$2)
|
|
7933
|
-
});
|
|
7934
|
-
const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
|
|
7935
|
-
const { handleSuccess } = useRouteModal();
|
|
7936
|
-
const onSubmit = form.handleSubmit(async (data) => {
|
|
7937
|
-
await mutateAsync(
|
|
7938
|
-
{
|
|
7939
|
-
sales_channel_id: data.sales_channel_id
|
|
7940
|
-
},
|
|
7941
|
-
{
|
|
7942
|
-
onSuccess: () => {
|
|
7943
|
-
ui.toast.success("Sales channel updated");
|
|
7944
|
-
handleSuccess();
|
|
7945
|
-
},
|
|
7946
|
-
onError: (error) => {
|
|
7947
|
-
ui.toast.error(error.message);
|
|
7948
|
-
}
|
|
7949
|
-
}
|
|
7950
|
-
);
|
|
7951
|
-
});
|
|
7952
|
-
return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7953
|
-
KeyboundForm,
|
|
7954
|
-
{
|
|
7955
|
-
className: "flex flex-1 flex-col overflow-hidden",
|
|
7956
|
-
onSubmit,
|
|
7957
|
-
children: [
|
|
7958
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
|
|
7959
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
7960
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
|
|
7961
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
|
|
7962
|
-
] }) })
|
|
7963
|
-
]
|
|
7964
|
-
}
|
|
7965
|
-
) });
|
|
7966
|
-
};
|
|
7967
|
-
const SalesChannelField = ({ control, order }) => {
|
|
7968
|
-
const salesChannels = useComboboxData({
|
|
7969
|
-
queryFn: async (params) => {
|
|
7970
|
-
return await sdk.admin.salesChannel.list(params);
|
|
7971
|
-
},
|
|
7972
|
-
queryKey: ["sales-channels"],
|
|
7973
|
-
getOptions: (data) => {
|
|
7974
|
-
return data.sales_channels.map((salesChannel) => ({
|
|
7975
|
-
label: salesChannel.name,
|
|
7976
|
-
value: salesChannel.id
|
|
7977
|
-
}));
|
|
7978
|
-
},
|
|
7979
|
-
defaultValue: order.sales_channel_id || void 0
|
|
7980
|
-
});
|
|
7981
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7982
|
-
Form$2.Field,
|
|
7983
|
-
{
|
|
7984
|
-
control,
|
|
7985
|
-
name: "sales_channel_id",
|
|
7986
|
-
render: ({ field }) => {
|
|
7987
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
|
|
7988
|
-
/* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
|
|
7989
|
-
/* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7990
|
-
Combobox,
|
|
7991
|
-
{
|
|
7992
|
-
options: salesChannels.options,
|
|
7993
|
-
fetchNextPage: salesChannels.fetchNextPage,
|
|
7994
|
-
isFetchingNextPage: salesChannels.isFetchingNextPage,
|
|
7995
|
-
searchValue: salesChannels.searchValue,
|
|
7996
|
-
onSearchValueChange: salesChannels.onSearchValueChange,
|
|
7997
|
-
placeholder: "Select sales channel",
|
|
7998
|
-
...field
|
|
7999
|
-
}
|
|
8000
|
-
) }),
|
|
8001
|
-
/* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
|
|
8002
|
-
] });
|
|
8003
|
-
}
|
|
8004
|
-
}
|
|
8005
|
-
);
|
|
8006
|
-
};
|
|
8007
|
-
const schema$2 = zod.z.object({
|
|
8008
|
-
sales_channel_id: zod.z.string().min(1)
|
|
8009
|
-
});
|
|
8010
|
-
const STACKED_FOCUS_MODAL_ID = "shipping-form";
|
|
8011
|
-
const Shipping = () => {
|
|
8012
|
-
const { id } = reactRouterDom.useParams();
|
|
8013
|
-
const { order, isPending, isError, error } = useOrder(id, {
|
|
8014
|
-
fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
|
|
8015
|
-
});
|
|
8016
|
-
const {
|
|
8017
|
-
order: preview,
|
|
8018
|
-
isPending: isPreviewPending,
|
|
8019
|
-
isError: isPreviewError,
|
|
8020
|
-
error: previewError
|
|
8021
|
-
} = useOrderPreview(id);
|
|
8022
|
-
useInitiateOrderEdit({ preview });
|
|
8023
|
-
const { onCancel } = useCancelOrderEdit({ preview });
|
|
8024
|
-
if (isError) {
|
|
8025
|
-
throw error;
|
|
8026
|
-
}
|
|
8027
|
-
if (isPreviewError) {
|
|
8028
|
-
throw previewError;
|
|
8029
|
-
}
|
|
8030
|
-
const orderHasItems = (order?.items?.length || 0) > 0;
|
|
8031
|
-
const isReady = preview && !isPreviewPending && order && !isPending;
|
|
8032
|
-
return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
|
|
8033
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
|
|
8034
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-6 py-16", children: [
|
|
8035
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
|
|
8036
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This draft order currently has no items. Add items to the order before adding shipping." }) })
|
|
8037
|
-
] }) }) }),
|
|
8038
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }) })
|
|
8039
|
-
] }) : isReady ? /* @__PURE__ */ jsxRuntime.jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
8040
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
|
|
8041
|
-
/* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
|
|
8042
|
-
] }) });
|
|
8043
|
-
};
|
|
8044
|
-
const ShippingForm = ({ preview, order }) => {
|
|
8045
|
-
const { setIsOpen } = useStackedModal();
|
|
8046
|
-
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
8047
|
-
const [data, setData] = React.useState(null);
|
|
8048
|
-
const appliedShippingOptionIds = preview.shipping_methods?.map((method) => method.shipping_option_id).filter(Boolean);
|
|
8049
|
-
const { shipping_options } = useShippingOptions(
|
|
8050
|
-
{
|
|
8051
|
-
id: appliedShippingOptionIds,
|
|
8052
|
-
fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
|
|
8053
|
-
},
|
|
8054
|
-
{
|
|
8055
|
-
enabled: appliedShippingOptionIds.length > 0
|
|
8056
|
-
}
|
|
8057
|
-
);
|
|
8058
|
-
const uniqueShippingProfiles = React.useMemo(() => {
|
|
8059
|
-
const profiles = /* @__PURE__ */ new Map();
|
|
8060
|
-
getUniqueShippingProfiles(order.items).forEach((profile) => {
|
|
8061
|
-
profiles.set(profile.id, profile);
|
|
8062
|
-
});
|
|
8063
|
-
shipping_options?.forEach((option) => {
|
|
8064
|
-
profiles.set(option.shipping_profile_id, option.shipping_profile);
|
|
8065
|
-
});
|
|
8066
|
-
return Array.from(profiles.values());
|
|
8067
|
-
}, [order.items, shipping_options]);
|
|
8068
|
-
const { handleSuccess } = useRouteModal();
|
|
8069
|
-
const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
|
|
8070
|
-
const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
|
|
8071
|
-
const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
|
|
8072
|
-
const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
|
|
8073
|
-
const onSubmit = async () => {
|
|
8074
|
-
setIsSubmitting(true);
|
|
8075
|
-
let requestSucceeded = false;
|
|
8076
|
-
await requestOrderEdit(void 0, {
|
|
8077
|
-
onError: (e) => {
|
|
8078
|
-
ui.toast.error(`Failed to request order edit: ${e.message}`);
|
|
8079
|
-
},
|
|
8080
|
-
onSuccess: () => {
|
|
8081
|
-
requestSucceeded = true;
|
|
8082
|
-
}
|
|
8083
|
-
});
|
|
8084
|
-
if (!requestSucceeded) {
|
|
8085
|
-
setIsSubmitting(false);
|
|
8086
|
-
return;
|
|
8087
|
-
}
|
|
8088
|
-
await confirmOrderEdit(void 0, {
|
|
8089
|
-
onError: (e) => {
|
|
8090
|
-
ui.toast.error(`Failed to confirm order edit: ${e.message}`);
|
|
8091
|
-
},
|
|
8092
|
-
onSuccess: () => {
|
|
8093
|
-
handleSuccess();
|
|
8094
|
-
},
|
|
8095
|
-
onSettled: () => {
|
|
8096
|
-
setIsSubmitting(false);
|
|
8097
|
-
}
|
|
8098
|
-
});
|
|
8099
|
-
};
|
|
8100
|
-
const onKeydown = React.useCallback(
|
|
8101
|
-
(e) => {
|
|
8102
|
-
if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
|
|
8103
|
-
if (data || isSubmitting) {
|
|
8104
|
-
return;
|
|
8105
|
-
}
|
|
8106
|
-
onSubmit();
|
|
8107
|
-
}
|
|
8108
|
-
},
|
|
8109
|
-
[data, isSubmitting, onSubmit]
|
|
7484
|
+
[data, isSubmitting, onSubmit]
|
|
8110
7485
|
);
|
|
8111
7486
|
React.useEffect(() => {
|
|
8112
7487
|
document.addEventListener("keydown", onKeydown);
|
|
@@ -9398,86 +8773,711 @@ const Illustration = () => {
|
|
|
9398
8773
|
/* @__PURE__ */ jsxRuntime.jsx("g", { clipPath: "url(#clip4_20915_38670)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9399
8774
|
"path",
|
|
9400
8775
|
{
|
|
9401
|
-
d: "M136.504 95.1945L129.12 95.1519L129.095 99.3617",
|
|
9402
|
-
stroke: "#A1A1AA",
|
|
9403
|
-
strokeWidth: "1.5",
|
|
9404
|
-
strokeLinecap: "round",
|
|
9405
|
-
strokeLinejoin: "round"
|
|
8776
|
+
d: "M136.504 95.1945L129.12 95.1519L129.095 99.3617",
|
|
8777
|
+
stroke: "#A1A1AA",
|
|
8778
|
+
strokeWidth: "1.5",
|
|
8779
|
+
strokeLinecap: "round",
|
|
8780
|
+
strokeLinejoin: "round"
|
|
8781
|
+
}
|
|
8782
|
+
) }),
|
|
8783
|
+
/* @__PURE__ */ jsxRuntime.jsx("g", { clipPath: "url(#clip5_20915_38670)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8784
|
+
"path",
|
|
8785
|
+
{
|
|
8786
|
+
d: "M146.894 101.198L139.51 101.155L139.486 105.365",
|
|
8787
|
+
stroke: "#A1A1AA",
|
|
8788
|
+
strokeWidth: "1.5",
|
|
8789
|
+
strokeLinecap: "round",
|
|
8790
|
+
strokeLinejoin: "round"
|
|
8791
|
+
}
|
|
8792
|
+
) }),
|
|
8793
|
+
/* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
|
|
8794
|
+
/* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip0_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8795
|
+
"rect",
|
|
8796
|
+
{
|
|
8797
|
+
width: "12",
|
|
8798
|
+
height: "12",
|
|
8799
|
+
fill: "white",
|
|
8800
|
+
transform: "matrix(0.865865 0.500278 -0.871576 0.490261 138.36 74.6508)"
|
|
8801
|
+
}
|
|
8802
|
+
) }),
|
|
8803
|
+
/* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip1_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8804
|
+
"rect",
|
|
8805
|
+
{
|
|
8806
|
+
width: "12",
|
|
8807
|
+
height: "12",
|
|
8808
|
+
fill: "white",
|
|
8809
|
+
transform: "matrix(0.865865 0.500278 -0.871576 0.490261 148.75 80.6541)"
|
|
8810
|
+
}
|
|
8811
|
+
) }),
|
|
8812
|
+
/* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip2_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8813
|
+
"rect",
|
|
8814
|
+
{
|
|
8815
|
+
width: "12",
|
|
8816
|
+
height: "12",
|
|
8817
|
+
fill: "white",
|
|
8818
|
+
transform: "matrix(0.865865 0.500278 -0.871576 0.490261 159.141 86.6575)"
|
|
8819
|
+
}
|
|
8820
|
+
) }),
|
|
8821
|
+
/* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip3_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8822
|
+
"rect",
|
|
8823
|
+
{
|
|
8824
|
+
width: "12",
|
|
8825
|
+
height: "12",
|
|
8826
|
+
fill: "white",
|
|
8827
|
+
transform: "matrix(0.865865 0.500278 -0.871576 0.490261 120.928 84.4561)"
|
|
8828
|
+
}
|
|
8829
|
+
) }),
|
|
8830
|
+
/* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip4_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8831
|
+
"rect",
|
|
8832
|
+
{
|
|
8833
|
+
width: "12",
|
|
8834
|
+
height: "12",
|
|
8835
|
+
fill: "white",
|
|
8836
|
+
transform: "matrix(0.865865 0.500278 -0.871576 0.490261 131.318 90.4594)"
|
|
8837
|
+
}
|
|
8838
|
+
) }),
|
|
8839
|
+
/* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip5_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8840
|
+
"rect",
|
|
8841
|
+
{
|
|
8842
|
+
width: "12",
|
|
8843
|
+
height: "12",
|
|
8844
|
+
fill: "white",
|
|
8845
|
+
transform: "matrix(0.865865 0.500278 -0.871576 0.490261 141.709 96.4627)"
|
|
8846
|
+
}
|
|
8847
|
+
) })
|
|
8848
|
+
] })
|
|
8849
|
+
]
|
|
8850
|
+
}
|
|
8851
|
+
);
|
|
8852
|
+
};
|
|
8853
|
+
const schema = zod.z.object({
|
|
8854
|
+
customer_id: zod.z.string().min(1)
|
|
8855
|
+
});
|
|
8856
|
+
const InlineTip = React.forwardRef(
|
|
8857
|
+
({ variant = "tip", label, className, children, ...props }, ref) => {
|
|
8858
|
+
const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
|
|
8859
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8860
|
+
"div",
|
|
8861
|
+
{
|
|
8862
|
+
ref,
|
|
8863
|
+
className: ui.clx(
|
|
8864
|
+
"bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
|
|
8865
|
+
className
|
|
8866
|
+
),
|
|
8867
|
+
...props,
|
|
8868
|
+
children: [
|
|
8869
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8870
|
+
"div",
|
|
8871
|
+
{
|
|
8872
|
+
role: "presentation",
|
|
8873
|
+
className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
|
|
8874
|
+
"bg-ui-tag-orange-icon": variant === "warning"
|
|
8875
|
+
})
|
|
8876
|
+
}
|
|
8877
|
+
),
|
|
8878
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
|
|
8879
|
+
/* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
|
|
8880
|
+
labelValue,
|
|
8881
|
+
":"
|
|
8882
|
+
] }),
|
|
8883
|
+
" ",
|
|
8884
|
+
children
|
|
8885
|
+
] })
|
|
8886
|
+
]
|
|
8887
|
+
}
|
|
8888
|
+
);
|
|
8889
|
+
}
|
|
8890
|
+
);
|
|
8891
|
+
InlineTip.displayName = "InlineTip";
|
|
8892
|
+
const MetadataFieldSchema = zod.z.object({
|
|
8893
|
+
key: zod.z.string(),
|
|
8894
|
+
disabled: zod.z.boolean().optional(),
|
|
8895
|
+
value: zod.z.any()
|
|
8896
|
+
});
|
|
8897
|
+
const MetadataSchema = zod.z.object({
|
|
8898
|
+
metadata: zod.z.array(MetadataFieldSchema)
|
|
8899
|
+
});
|
|
8900
|
+
const Metadata = () => {
|
|
8901
|
+
const { id } = reactRouterDom.useParams();
|
|
8902
|
+
const { order, isPending, isError, error } = useOrder(id, {
|
|
8903
|
+
fields: "metadata"
|
|
8904
|
+
});
|
|
8905
|
+
if (isError) {
|
|
8906
|
+
throw error;
|
|
8907
|
+
}
|
|
8908
|
+
const isReady = !isPending && !!order;
|
|
8909
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
|
|
8910
|
+
/* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
|
|
8911
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
|
|
8912
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
|
|
8913
|
+
] }),
|
|
8914
|
+
!isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order?.metadata })
|
|
8915
|
+
] });
|
|
8916
|
+
};
|
|
8917
|
+
const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
|
|
8918
|
+
const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
|
|
8919
|
+
const MetadataForm = ({ orderId, metadata }) => {
|
|
8920
|
+
const { handleSuccess } = useRouteModal();
|
|
8921
|
+
const hasUneditableRows = getHasUneditableRows(metadata);
|
|
8922
|
+
const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
|
|
8923
|
+
const form = reactHookForm.useForm({
|
|
8924
|
+
defaultValues: {
|
|
8925
|
+
metadata: getDefaultValues(metadata)
|
|
8926
|
+
},
|
|
8927
|
+
resolver: zod$1.zodResolver(MetadataSchema)
|
|
8928
|
+
});
|
|
8929
|
+
const handleSubmit = form.handleSubmit(async (data) => {
|
|
8930
|
+
const parsedData = parseValues(data);
|
|
8931
|
+
await mutateAsync(
|
|
8932
|
+
{
|
|
8933
|
+
metadata: parsedData
|
|
8934
|
+
},
|
|
8935
|
+
{
|
|
8936
|
+
onSuccess: () => {
|
|
8937
|
+
ui.toast.success("Metadata updated");
|
|
8938
|
+
handleSuccess();
|
|
8939
|
+
},
|
|
8940
|
+
onError: (error) => {
|
|
8941
|
+
ui.toast.error(error.message);
|
|
8942
|
+
}
|
|
8943
|
+
}
|
|
8944
|
+
);
|
|
8945
|
+
});
|
|
8946
|
+
const { fields, insert, remove } = reactHookForm.useFieldArray({
|
|
8947
|
+
control: form.control,
|
|
8948
|
+
name: "metadata"
|
|
8949
|
+
});
|
|
8950
|
+
function deleteRow(index) {
|
|
8951
|
+
remove(index);
|
|
8952
|
+
if (fields.length === 1) {
|
|
8953
|
+
insert(0, {
|
|
8954
|
+
key: "",
|
|
8955
|
+
value: "",
|
|
8956
|
+
disabled: false
|
|
8957
|
+
});
|
|
8958
|
+
}
|
|
8959
|
+
}
|
|
8960
|
+
function insertRow(index, position) {
|
|
8961
|
+
insert(index + (position === "above" ? 0 : 1), {
|
|
8962
|
+
key: "",
|
|
8963
|
+
value: "",
|
|
8964
|
+
disabled: false
|
|
8965
|
+
});
|
|
8966
|
+
}
|
|
8967
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8968
|
+
KeyboundForm,
|
|
8969
|
+
{
|
|
8970
|
+
onSubmit: handleSubmit,
|
|
8971
|
+
className: "flex flex-1 flex-col overflow-hidden",
|
|
8972
|
+
children: [
|
|
8973
|
+
/* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
|
|
8974
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
|
|
8975
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
|
|
8976
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
|
|
8977
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
|
|
8978
|
+
] }),
|
|
8979
|
+
fields.map((field, index) => {
|
|
8980
|
+
const isDisabled = field.disabled || false;
|
|
8981
|
+
let placeholder = "-";
|
|
8982
|
+
if (typeof field.value === "object") {
|
|
8983
|
+
placeholder = "{ ... }";
|
|
8984
|
+
}
|
|
8985
|
+
if (Array.isArray(field.value)) {
|
|
8986
|
+
placeholder = "[ ... ]";
|
|
8987
|
+
}
|
|
8988
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8989
|
+
ConditionalTooltip,
|
|
8990
|
+
{
|
|
8991
|
+
showTooltip: isDisabled,
|
|
8992
|
+
content: "This row is disabled because it contains non-primitive data.",
|
|
8993
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
|
|
8994
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
8995
|
+
"div",
|
|
8996
|
+
{
|
|
8997
|
+
className: ui.clx("grid grid-cols-2 divide-x", {
|
|
8998
|
+
"overflow-hidden rounded-b-lg": index === fields.length - 1
|
|
8999
|
+
}),
|
|
9000
|
+
children: [
|
|
9001
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9002
|
+
Form$2.Field,
|
|
9003
|
+
{
|
|
9004
|
+
control: form.control,
|
|
9005
|
+
name: `metadata.${index}.key`,
|
|
9006
|
+
render: ({ field: field2 }) => {
|
|
9007
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9008
|
+
GridInput,
|
|
9009
|
+
{
|
|
9010
|
+
"aria-labelledby": METADATA_KEY_LABEL_ID,
|
|
9011
|
+
...field2,
|
|
9012
|
+
disabled: isDisabled,
|
|
9013
|
+
placeholder: "Key"
|
|
9014
|
+
}
|
|
9015
|
+
) }) });
|
|
9016
|
+
}
|
|
9017
|
+
}
|
|
9018
|
+
),
|
|
9019
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9020
|
+
Form$2.Field,
|
|
9021
|
+
{
|
|
9022
|
+
control: form.control,
|
|
9023
|
+
name: `metadata.${index}.value`,
|
|
9024
|
+
render: ({ field: { value, ...field2 } }) => {
|
|
9025
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9026
|
+
GridInput,
|
|
9027
|
+
{
|
|
9028
|
+
"aria-labelledby": METADATA_VALUE_LABEL_ID,
|
|
9029
|
+
...field2,
|
|
9030
|
+
value: isDisabled ? placeholder : value,
|
|
9031
|
+
disabled: isDisabled,
|
|
9032
|
+
placeholder: "Value"
|
|
9033
|
+
}
|
|
9034
|
+
) }) });
|
|
9035
|
+
}
|
|
9036
|
+
}
|
|
9037
|
+
)
|
|
9038
|
+
]
|
|
9039
|
+
}
|
|
9040
|
+
),
|
|
9041
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
|
|
9042
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9043
|
+
ui.DropdownMenu.Trigger,
|
|
9044
|
+
{
|
|
9045
|
+
className: ui.clx(
|
|
9046
|
+
"invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
|
|
9047
|
+
{
|
|
9048
|
+
hidden: isDisabled
|
|
9049
|
+
}
|
|
9050
|
+
),
|
|
9051
|
+
disabled: isDisabled,
|
|
9052
|
+
asChild: true,
|
|
9053
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
|
|
9054
|
+
}
|
|
9055
|
+
),
|
|
9056
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
|
|
9057
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
9058
|
+
ui.DropdownMenu.Item,
|
|
9059
|
+
{
|
|
9060
|
+
className: "gap-x-2",
|
|
9061
|
+
onClick: () => insertRow(index, "above"),
|
|
9062
|
+
children: [
|
|
9063
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
|
|
9064
|
+
"Insert row above"
|
|
9065
|
+
]
|
|
9066
|
+
}
|
|
9067
|
+
),
|
|
9068
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
9069
|
+
ui.DropdownMenu.Item,
|
|
9070
|
+
{
|
|
9071
|
+
className: "gap-x-2",
|
|
9072
|
+
onClick: () => insertRow(index, "below"),
|
|
9073
|
+
children: [
|
|
9074
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
|
|
9075
|
+
"Insert row below"
|
|
9076
|
+
]
|
|
9077
|
+
}
|
|
9078
|
+
),
|
|
9079
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
|
|
9080
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
9081
|
+
ui.DropdownMenu.Item,
|
|
9082
|
+
{
|
|
9083
|
+
className: "gap-x-2",
|
|
9084
|
+
onClick: () => deleteRow(index),
|
|
9085
|
+
children: [
|
|
9086
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
|
|
9087
|
+
"Delete row"
|
|
9088
|
+
]
|
|
9089
|
+
}
|
|
9090
|
+
)
|
|
9091
|
+
] })
|
|
9092
|
+
] })
|
|
9093
|
+
] })
|
|
9094
|
+
},
|
|
9095
|
+
field.id
|
|
9096
|
+
);
|
|
9097
|
+
})
|
|
9098
|
+
] }),
|
|
9099
|
+
hasUneditableRows && /* @__PURE__ */ jsxRuntime.jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
|
|
9100
|
+
] }),
|
|
9101
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
|
|
9102
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
|
|
9103
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
|
|
9104
|
+
] }) })
|
|
9105
|
+
]
|
|
9106
|
+
}
|
|
9107
|
+
) });
|
|
9108
|
+
};
|
|
9109
|
+
const GridInput = React.forwardRef(({ className, ...props }, ref) => {
|
|
9110
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9111
|
+
"input",
|
|
9112
|
+
{
|
|
9113
|
+
ref,
|
|
9114
|
+
...props,
|
|
9115
|
+
autoComplete: "off",
|
|
9116
|
+
className: ui.clx(
|
|
9117
|
+
"txt-compact-small text-ui-fg-base placeholder:text-ui-fg-muted disabled:text-ui-fg-disabled disabled:bg-ui-bg-base bg-transparent px-2 py-1.5 outline-none",
|
|
9118
|
+
className
|
|
9119
|
+
)
|
|
9120
|
+
}
|
|
9121
|
+
);
|
|
9122
|
+
});
|
|
9123
|
+
GridInput.displayName = "MetadataForm.GridInput";
|
|
9124
|
+
const PlaceholderInner = () => {
|
|
9125
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
|
|
9126
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
|
|
9127
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
|
|
9128
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
|
|
9129
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
|
|
9130
|
+
] }) })
|
|
9131
|
+
] });
|
|
9132
|
+
};
|
|
9133
|
+
const EDITABLE_TYPES = ["string", "number", "boolean"];
|
|
9134
|
+
function getDefaultValues(metadata) {
|
|
9135
|
+
if (!metadata || !Object.keys(metadata).length) {
|
|
9136
|
+
return [
|
|
9137
|
+
{
|
|
9138
|
+
key: "",
|
|
9139
|
+
value: "",
|
|
9140
|
+
disabled: false
|
|
9141
|
+
}
|
|
9142
|
+
];
|
|
9143
|
+
}
|
|
9144
|
+
return Object.entries(metadata).map(([key, value]) => {
|
|
9145
|
+
if (!EDITABLE_TYPES.includes(typeof value)) {
|
|
9146
|
+
return {
|
|
9147
|
+
key,
|
|
9148
|
+
value,
|
|
9149
|
+
disabled: true
|
|
9150
|
+
};
|
|
9151
|
+
}
|
|
9152
|
+
let stringValue = value;
|
|
9153
|
+
if (typeof value !== "string") {
|
|
9154
|
+
stringValue = JSON.stringify(value);
|
|
9155
|
+
}
|
|
9156
|
+
return {
|
|
9157
|
+
key,
|
|
9158
|
+
value: stringValue,
|
|
9159
|
+
original_key: key
|
|
9160
|
+
};
|
|
9161
|
+
});
|
|
9162
|
+
}
|
|
9163
|
+
function parseValues(values) {
|
|
9164
|
+
const metadata = values.metadata;
|
|
9165
|
+
const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
|
|
9166
|
+
if (isEmpty) {
|
|
9167
|
+
return null;
|
|
9168
|
+
}
|
|
9169
|
+
const update = {};
|
|
9170
|
+
metadata.forEach((field) => {
|
|
9171
|
+
let key = field.key;
|
|
9172
|
+
let value = field.value;
|
|
9173
|
+
const disabled = field.disabled;
|
|
9174
|
+
if (!key || !value) {
|
|
9175
|
+
return;
|
|
9176
|
+
}
|
|
9177
|
+
if (disabled) {
|
|
9178
|
+
update[key] = value;
|
|
9179
|
+
return;
|
|
9180
|
+
}
|
|
9181
|
+
key = key.trim();
|
|
9182
|
+
value = value.trim();
|
|
9183
|
+
if (value === "true") {
|
|
9184
|
+
update[key] = true;
|
|
9185
|
+
} else if (value === "false") {
|
|
9186
|
+
update[key] = false;
|
|
9187
|
+
} else {
|
|
9188
|
+
const parsedNumber = parseFloat(value);
|
|
9189
|
+
if (!isNaN(parsedNumber)) {
|
|
9190
|
+
update[key] = parsedNumber;
|
|
9191
|
+
} else {
|
|
9192
|
+
update[key] = value;
|
|
9193
|
+
}
|
|
9194
|
+
}
|
|
9195
|
+
});
|
|
9196
|
+
return update;
|
|
9197
|
+
}
|
|
9198
|
+
function getHasUneditableRows(metadata) {
|
|
9199
|
+
if (!metadata) {
|
|
9200
|
+
return false;
|
|
9201
|
+
}
|
|
9202
|
+
return Object.values(metadata).some(
|
|
9203
|
+
(value) => !EDITABLE_TYPES.includes(typeof value)
|
|
9204
|
+
);
|
|
9205
|
+
}
|
|
9206
|
+
const PROMOTION_QUERY_KEY = "promotions";
|
|
9207
|
+
const promotionsQueryKeys = {
|
|
9208
|
+
list: (query2) => [
|
|
9209
|
+
PROMOTION_QUERY_KEY,
|
|
9210
|
+
query2 ? query2 : void 0
|
|
9211
|
+
],
|
|
9212
|
+
detail: (id, query2) => [
|
|
9213
|
+
PROMOTION_QUERY_KEY,
|
|
9214
|
+
id,
|
|
9215
|
+
query2 ? query2 : void 0
|
|
9216
|
+
]
|
|
9217
|
+
};
|
|
9218
|
+
const usePromotions = (query2, options) => {
|
|
9219
|
+
const { data, ...rest } = reactQuery.useQuery({
|
|
9220
|
+
queryKey: promotionsQueryKeys.list(query2),
|
|
9221
|
+
queryFn: async () => sdk.admin.promotion.list(query2),
|
|
9222
|
+
...options
|
|
9223
|
+
});
|
|
9224
|
+
return { ...data, ...rest };
|
|
9225
|
+
};
|
|
9226
|
+
const Promotions = () => {
|
|
9227
|
+
const { id } = reactRouterDom.useParams();
|
|
9228
|
+
const {
|
|
9229
|
+
order: preview,
|
|
9230
|
+
isError: isPreviewError,
|
|
9231
|
+
error: previewError
|
|
9232
|
+
} = useOrderPreview(id, void 0);
|
|
9233
|
+
useInitiateOrderEdit({ preview });
|
|
9234
|
+
const { onCancel } = useCancelOrderEdit({ preview });
|
|
9235
|
+
if (isPreviewError) {
|
|
9236
|
+
throw previewError;
|
|
9237
|
+
}
|
|
9238
|
+
const isReady = !!preview;
|
|
9239
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
|
|
9240
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
|
|
9241
|
+
isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
|
|
9242
|
+
] });
|
|
9243
|
+
};
|
|
9244
|
+
const PromotionForm = ({ preview }) => {
|
|
9245
|
+
const { items, shipping_methods } = preview;
|
|
9246
|
+
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
9247
|
+
const [comboboxValue, setComboboxValue] = React.useState("");
|
|
9248
|
+
const { handleSuccess } = useRouteModal();
|
|
9249
|
+
const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
|
|
9250
|
+
const promoIds = getPromotionIds(items, shipping_methods);
|
|
9251
|
+
const { promotions, isPending, isError, error } = usePromotions(
|
|
9252
|
+
{
|
|
9253
|
+
id: promoIds
|
|
9254
|
+
},
|
|
9255
|
+
{
|
|
9256
|
+
enabled: !!promoIds.length
|
|
9257
|
+
}
|
|
9258
|
+
);
|
|
9259
|
+
const comboboxData = useComboboxData({
|
|
9260
|
+
queryKey: ["promotions", "combobox", promoIds],
|
|
9261
|
+
queryFn: async (params) => {
|
|
9262
|
+
return await sdk.admin.promotion.list({
|
|
9263
|
+
...params,
|
|
9264
|
+
id: {
|
|
9265
|
+
$nin: promoIds
|
|
9266
|
+
}
|
|
9267
|
+
});
|
|
9268
|
+
},
|
|
9269
|
+
getOptions: (data) => {
|
|
9270
|
+
return data.promotions.map((promotion) => ({
|
|
9271
|
+
label: promotion.code,
|
|
9272
|
+
value: promotion.code
|
|
9273
|
+
}));
|
|
9274
|
+
}
|
|
9275
|
+
});
|
|
9276
|
+
const add = async (value) => {
|
|
9277
|
+
if (!value) {
|
|
9278
|
+
return;
|
|
9279
|
+
}
|
|
9280
|
+
addPromotions(
|
|
9281
|
+
{
|
|
9282
|
+
promo_codes: [value]
|
|
9283
|
+
},
|
|
9284
|
+
{
|
|
9285
|
+
onError: (e) => {
|
|
9286
|
+
ui.toast.error(e.message);
|
|
9287
|
+
comboboxData.onSearchValueChange("");
|
|
9288
|
+
setComboboxValue("");
|
|
9289
|
+
},
|
|
9290
|
+
onSuccess: () => {
|
|
9291
|
+
comboboxData.onSearchValueChange("");
|
|
9292
|
+
setComboboxValue("");
|
|
9293
|
+
}
|
|
9294
|
+
}
|
|
9295
|
+
);
|
|
9296
|
+
};
|
|
9297
|
+
const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
|
|
9298
|
+
const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
|
|
9299
|
+
const onSubmit = async () => {
|
|
9300
|
+
setIsSubmitting(true);
|
|
9301
|
+
let requestSucceeded = false;
|
|
9302
|
+
await requestOrderEdit(void 0, {
|
|
9303
|
+
onError: (e) => {
|
|
9304
|
+
ui.toast.error(e.message);
|
|
9305
|
+
},
|
|
9306
|
+
onSuccess: () => {
|
|
9307
|
+
requestSucceeded = true;
|
|
9308
|
+
}
|
|
9309
|
+
});
|
|
9310
|
+
if (!requestSucceeded) {
|
|
9311
|
+
setIsSubmitting(false);
|
|
9312
|
+
return;
|
|
9313
|
+
}
|
|
9314
|
+
await confirmOrderEdit(void 0, {
|
|
9315
|
+
onError: (e) => {
|
|
9316
|
+
ui.toast.error(e.message);
|
|
9317
|
+
},
|
|
9318
|
+
onSuccess: () => {
|
|
9319
|
+
handleSuccess();
|
|
9320
|
+
},
|
|
9321
|
+
onSettled: () => {
|
|
9322
|
+
setIsSubmitting(false);
|
|
9323
|
+
}
|
|
9324
|
+
});
|
|
9325
|
+
};
|
|
9326
|
+
if (isError) {
|
|
9327
|
+
throw error;
|
|
9328
|
+
}
|
|
9329
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
|
|
9330
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
9331
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
9332
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
9333
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
|
|
9334
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
|
|
9335
|
+
] }),
|
|
9336
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9337
|
+
Combobox,
|
|
9338
|
+
{
|
|
9339
|
+
id: "promotion-combobox",
|
|
9340
|
+
"aria-describedby": "promotion-combobox-hint",
|
|
9341
|
+
isFetchingNextPage: comboboxData.isFetchingNextPage,
|
|
9342
|
+
fetchNextPage: comboboxData.fetchNextPage,
|
|
9343
|
+
options: comboboxData.options,
|
|
9344
|
+
onSearchValueChange: comboboxData.onSearchValueChange,
|
|
9345
|
+
searchValue: comboboxData.searchValue,
|
|
9346
|
+
disabled: comboboxData.disabled || isAddingPromotions,
|
|
9347
|
+
onChange: add,
|
|
9348
|
+
value: comboboxValue
|
|
9406
9349
|
}
|
|
9407
|
-
)
|
|
9408
|
-
|
|
9409
|
-
|
|
9350
|
+
)
|
|
9351
|
+
] }),
|
|
9352
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
|
|
9353
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions?.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
9354
|
+
PromotionItem,
|
|
9355
|
+
{
|
|
9356
|
+
promotion,
|
|
9357
|
+
orderId: preview.id,
|
|
9358
|
+
isLoading: isPending
|
|
9359
|
+
},
|
|
9360
|
+
promotion.id
|
|
9361
|
+
)) })
|
|
9362
|
+
] }) }),
|
|
9363
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
9364
|
+
/* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
|
|
9365
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9366
|
+
ui.Button,
|
|
9367
|
+
{
|
|
9368
|
+
size: "small",
|
|
9369
|
+
type: "submit",
|
|
9370
|
+
isLoading: isSubmitting || isAddingPromotions,
|
|
9371
|
+
children: "Save"
|
|
9372
|
+
}
|
|
9373
|
+
)
|
|
9374
|
+
] }) })
|
|
9375
|
+
] });
|
|
9376
|
+
};
|
|
9377
|
+
const PromotionItem = ({
|
|
9378
|
+
promotion,
|
|
9379
|
+
orderId,
|
|
9380
|
+
isLoading
|
|
9381
|
+
}) => {
|
|
9382
|
+
const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
|
|
9383
|
+
const onRemove = async () => {
|
|
9384
|
+
removePromotions(
|
|
9385
|
+
{
|
|
9386
|
+
promo_codes: [promotion.code]
|
|
9387
|
+
},
|
|
9388
|
+
{
|
|
9389
|
+
onError: (e) => {
|
|
9390
|
+
ui.toast.error(e.message);
|
|
9391
|
+
}
|
|
9392
|
+
}
|
|
9393
|
+
);
|
|
9394
|
+
};
|
|
9395
|
+
const displayValue = getDisplayValue(promotion);
|
|
9396
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9397
|
+
"div",
|
|
9398
|
+
{
|
|
9399
|
+
className: ui.clx(
|
|
9400
|
+
"bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
|
|
9401
|
+
{
|
|
9402
|
+
"animate-pulse": isLoading
|
|
9403
|
+
}
|
|
9404
|
+
),
|
|
9405
|
+
children: [
|
|
9406
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
9407
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
|
|
9408
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
|
|
9409
|
+
displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
9410
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
|
|
9411
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
|
|
9412
|
+
] }),
|
|
9413
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: promotion.application_method?.allocation })
|
|
9414
|
+
] })
|
|
9415
|
+
] }),
|
|
9416
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9417
|
+
ui.IconButton,
|
|
9410
9418
|
{
|
|
9411
|
-
|
|
9412
|
-
|
|
9413
|
-
|
|
9414
|
-
|
|
9415
|
-
|
|
9419
|
+
size: "small",
|
|
9420
|
+
type: "button",
|
|
9421
|
+
variant: "transparent",
|
|
9422
|
+
onClick: onRemove,
|
|
9423
|
+
isLoading: isPending || isLoading,
|
|
9424
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
|
|
9416
9425
|
}
|
|
9417
|
-
)
|
|
9418
|
-
/* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
|
|
9419
|
-
/* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip0_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9420
|
-
"rect",
|
|
9421
|
-
{
|
|
9422
|
-
width: "12",
|
|
9423
|
-
height: "12",
|
|
9424
|
-
fill: "white",
|
|
9425
|
-
transform: "matrix(0.865865 0.500278 -0.871576 0.490261 138.36 74.6508)"
|
|
9426
|
-
}
|
|
9427
|
-
) }),
|
|
9428
|
-
/* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip1_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9429
|
-
"rect",
|
|
9430
|
-
{
|
|
9431
|
-
width: "12",
|
|
9432
|
-
height: "12",
|
|
9433
|
-
fill: "white",
|
|
9434
|
-
transform: "matrix(0.865865 0.500278 -0.871576 0.490261 148.75 80.6541)"
|
|
9435
|
-
}
|
|
9436
|
-
) }),
|
|
9437
|
-
/* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip2_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9438
|
-
"rect",
|
|
9439
|
-
{
|
|
9440
|
-
width: "12",
|
|
9441
|
-
height: "12",
|
|
9442
|
-
fill: "white",
|
|
9443
|
-
transform: "matrix(0.865865 0.500278 -0.871576 0.490261 159.141 86.6575)"
|
|
9444
|
-
}
|
|
9445
|
-
) }),
|
|
9446
|
-
/* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip3_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9447
|
-
"rect",
|
|
9448
|
-
{
|
|
9449
|
-
width: "12",
|
|
9450
|
-
height: "12",
|
|
9451
|
-
fill: "white",
|
|
9452
|
-
transform: "matrix(0.865865 0.500278 -0.871576 0.490261 120.928 84.4561)"
|
|
9453
|
-
}
|
|
9454
|
-
) }),
|
|
9455
|
-
/* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip4_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9456
|
-
"rect",
|
|
9457
|
-
{
|
|
9458
|
-
width: "12",
|
|
9459
|
-
height: "12",
|
|
9460
|
-
fill: "white",
|
|
9461
|
-
transform: "matrix(0.865865 0.500278 -0.871576 0.490261 131.318 90.4594)"
|
|
9462
|
-
}
|
|
9463
|
-
) }),
|
|
9464
|
-
/* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip5_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9465
|
-
"rect",
|
|
9466
|
-
{
|
|
9467
|
-
width: "12",
|
|
9468
|
-
height: "12",
|
|
9469
|
-
fill: "white",
|
|
9470
|
-
transform: "matrix(0.865865 0.500278 -0.871576 0.490261 141.709 96.4627)"
|
|
9471
|
-
}
|
|
9472
|
-
) })
|
|
9473
|
-
] })
|
|
9426
|
+
)
|
|
9474
9427
|
]
|
|
9475
|
-
}
|
|
9428
|
+
},
|
|
9429
|
+
promotion.id
|
|
9476
9430
|
);
|
|
9477
9431
|
};
|
|
9478
|
-
|
|
9479
|
-
|
|
9432
|
+
function getDisplayValue(promotion) {
|
|
9433
|
+
const value = promotion.application_method?.value;
|
|
9434
|
+
if (!value) {
|
|
9435
|
+
return null;
|
|
9436
|
+
}
|
|
9437
|
+
if (promotion.application_method?.type === "fixed") {
|
|
9438
|
+
const currency = promotion.application_method?.currency_code;
|
|
9439
|
+
if (!currency) {
|
|
9440
|
+
return null;
|
|
9441
|
+
}
|
|
9442
|
+
return getLocaleAmount(value, currency);
|
|
9443
|
+
} else if (promotion.application_method?.type === "percentage") {
|
|
9444
|
+
return formatPercentage(value);
|
|
9445
|
+
}
|
|
9446
|
+
return null;
|
|
9447
|
+
}
|
|
9448
|
+
const formatter = new Intl.NumberFormat([], {
|
|
9449
|
+
style: "percent",
|
|
9450
|
+
minimumFractionDigits: 2
|
|
9480
9451
|
});
|
|
9452
|
+
const formatPercentage = (value, isPercentageValue = false) => {
|
|
9453
|
+
let val = value || 0;
|
|
9454
|
+
if (!isPercentageValue) {
|
|
9455
|
+
val = val / 100;
|
|
9456
|
+
}
|
|
9457
|
+
return formatter.format(val);
|
|
9458
|
+
};
|
|
9459
|
+
function getPromotionIds(items, shippingMethods) {
|
|
9460
|
+
const promotionIds = /* @__PURE__ */ new Set();
|
|
9461
|
+
for (const item of items) {
|
|
9462
|
+
if (item.adjustments) {
|
|
9463
|
+
for (const adjustment of item.adjustments) {
|
|
9464
|
+
if (adjustment.promotion_id) {
|
|
9465
|
+
promotionIds.add(adjustment.promotion_id);
|
|
9466
|
+
}
|
|
9467
|
+
}
|
|
9468
|
+
}
|
|
9469
|
+
}
|
|
9470
|
+
for (const shippingMethod of shippingMethods) {
|
|
9471
|
+
if (shippingMethod.adjustments) {
|
|
9472
|
+
for (const adjustment of shippingMethod.adjustments) {
|
|
9473
|
+
if (adjustment.promotion_id) {
|
|
9474
|
+
promotionIds.add(adjustment.promotion_id);
|
|
9475
|
+
}
|
|
9476
|
+
}
|
|
9477
|
+
}
|
|
9478
|
+
}
|
|
9479
|
+
return Array.from(promotionIds);
|
|
9480
|
+
}
|
|
9481
9481
|
const widgetModule = { widgets: [] };
|
|
9482
9482
|
const routeModule = {
|
|
9483
9483
|
routes: [
|
|
@@ -9502,10 +9502,6 @@ const routeModule = {
|
|
|
9502
9502
|
Component: BillingAddress,
|
|
9503
9503
|
path: "/draft-orders/:id/billing-address"
|
|
9504
9504
|
},
|
|
9505
|
-
{
|
|
9506
|
-
Component: CustomItems,
|
|
9507
|
-
path: "/draft-orders/:id/custom-items"
|
|
9508
|
-
},
|
|
9509
9505
|
{
|
|
9510
9506
|
Component: Email,
|
|
9511
9507
|
path: "/draft-orders/:id/email"
|
|
@@ -9515,12 +9511,8 @@ const routeModule = {
|
|
|
9515
9511
|
path: "/draft-orders/:id/items"
|
|
9516
9512
|
},
|
|
9517
9513
|
{
|
|
9518
|
-
Component:
|
|
9519
|
-
path: "/draft-orders/:id/
|
|
9520
|
-
},
|
|
9521
|
-
{
|
|
9522
|
-
Component: Promotions,
|
|
9523
|
-
path: "/draft-orders/:id/promotions"
|
|
9514
|
+
Component: CustomItems,
|
|
9515
|
+
path: "/draft-orders/:id/custom-items"
|
|
9524
9516
|
},
|
|
9525
9517
|
{
|
|
9526
9518
|
Component: SalesChannel,
|
|
@@ -9537,6 +9529,14 @@ const routeModule = {
|
|
|
9537
9529
|
{
|
|
9538
9530
|
Component: TransferOwnership,
|
|
9539
9531
|
path: "/draft-orders/:id/transfer-ownership"
|
|
9532
|
+
},
|
|
9533
|
+
{
|
|
9534
|
+
Component: Metadata,
|
|
9535
|
+
path: "/draft-orders/:id/metadata"
|
|
9536
|
+
},
|
|
9537
|
+
{
|
|
9538
|
+
Component: Promotions,
|
|
9539
|
+
path: "/draft-orders/:id/promotions"
|
|
9540
9540
|
}
|
|
9541
9541
|
]
|
|
9542
9542
|
}
|