@medusajs/draft-order 0.0.2 → 0.0.3

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.
@@ -7395,18 +7395,7 @@ const CreateForm = () => {
7395
7395
  company: ""
7396
7396
  },
7397
7397
  billing_address_id: "",
7398
- billing_address: {
7399
- country_code: "",
7400
- first_name: "",
7401
- last_name: "",
7402
- address_1: "",
7403
- address_2: "",
7404
- city: "",
7405
- province: "",
7406
- company: "",
7407
- postal_code: "",
7408
- phone: ""
7409
- },
7398
+ billing_address: void 0,
7410
7399
  same_as_shipping: true
7411
7400
  },
7412
7401
  resolver: zod.zodResolver(schema$8)
@@ -7976,7 +7965,7 @@ const schema$8 = z.object({
7976
7965
  shipping_address_id: z.string().optional(),
7977
7966
  shipping_address: addressSchema.optional(),
7978
7967
  billing_address_id: z.string().optional(),
7979
- billing_address: addressSchema.nullish(),
7968
+ billing_address: z.any().optional(),
7980
7969
  same_as_shipping: z.boolean().optional()
7981
7970
  }).superRefine((data, ctx) => {
7982
7971
  if (!data.customer_id && !data.email) {
@@ -8907,20 +8896,6 @@ const SummarySection = ({ order }) => {
8907
8896
  label: "Edit items",
8908
8897
  icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
8909
8898
  to: "items"
8910
- },
8911
- {
8912
- label: "Edit custom items",
8913
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
8914
- to: "custom-items"
8915
- }
8916
- ]
8917
- },
8918
- {
8919
- actions: [
8920
- {
8921
- label: "Edit promotions",
8922
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ReceiptPercent, {}),
8923
- to: "promotions"
8924
8899
  }
8925
8900
  ]
8926
8901
  }
@@ -9085,95 +9060,6 @@ const ID = () => {
9085
9060
  /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Outlet, {})
9086
9061
  ] });
9087
9062
  };
9088
- const Email = () => {
9089
- const { id } = reactRouterDom.useParams();
9090
- const { order, isPending, isError, error } = useOrder(id, {
9091
- fields: "+email"
9092
- });
9093
- if (isError) {
9094
- throw error;
9095
- }
9096
- const isReady = !isPending && !!order;
9097
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9098
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
9099
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Email" }) }),
9100
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
9101
- ] }),
9102
- isReady && /* @__PURE__ */ jsxRuntime.jsx(EmailForm, { order })
9103
- ] });
9104
- };
9105
- const EmailForm = ({ order }) => {
9106
- const form = reactHookForm.useForm({
9107
- defaultValues: {
9108
- email: order.email ?? ""
9109
- },
9110
- resolver: zod.zodResolver(schema$7)
9111
- });
9112
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9113
- const { handleSuccess } = useRouteModal();
9114
- const onSubmit = form.handleSubmit(async (data) => {
9115
- await mutateAsync(
9116
- { email: data.email },
9117
- {
9118
- onSuccess: () => {
9119
- handleSuccess();
9120
- },
9121
- onError: (error) => {
9122
- ui.toast.error(error.message);
9123
- }
9124
- }
9125
- );
9126
- });
9127
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
9128
- KeyboundForm,
9129
- {
9130
- className: "flex flex-1 flex-col overflow-hidden",
9131
- onSubmit,
9132
- children: [
9133
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
9134
- Form$2.Field,
9135
- {
9136
- control: form.control,
9137
- name: "email",
9138
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9139
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Email" }),
9140
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9141
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9142
- ] })
9143
- }
9144
- ) }),
9145
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9146
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9147
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
9148
- ] }) })
9149
- ]
9150
- }
9151
- ) });
9152
- };
9153
- const schema$7 = z.object({
9154
- email: z.string().email()
9155
- });
9156
- const CustomItems = () => {
9157
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9158
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9159
- /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9160
- ] });
9161
- };
9162
- const CustomItemsForm = () => {
9163
- const form = reactHookForm.useForm({
9164
- resolver: zod.zodResolver(schema$6)
9165
- });
9166
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9167
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9168
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9169
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9170
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9171
- ] }) })
9172
- ] }) });
9173
- };
9174
- const schema$6 = z.object({
9175
- email: z.string().email()
9176
- });
9177
9063
  const SwitchBlock = (props) => {
9178
9064
  return /* @__PURE__ */ jsxRuntime.jsx(
9179
9065
  Form$2.Field,
@@ -9231,7 +9117,7 @@ const BillingAddressForm = ({ order }) => {
9231
9117
  phone: ((_j = order.billing_address) == null ? void 0 : _j.phone) ?? "",
9232
9118
  notify: false
9233
9119
  },
9234
- resolver: zod.zodResolver(schema$5)
9120
+ resolver: zod.zodResolver(schema$7)
9235
9121
  });
9236
9122
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9237
9123
  const { handleSuccess } = useRouteModal();
@@ -9399,57 +9285,34 @@ const BillingAddressForm = ({ order }) => {
9399
9285
  }
9400
9286
  ) });
9401
9287
  };
9402
- const schema$5 = addressSchema.extend({
9288
+ const schema$7 = addressSchema.extend({
9403
9289
  notify: z.boolean().optional()
9404
9290
  });
9405
- const InlineTip = React.forwardRef(
9406
- ({ variant = "tip", label, className, children, ...props }, ref) => {
9407
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
9408
- return /* @__PURE__ */ jsxRuntime.jsxs(
9409
- "div",
9410
- {
9411
- ref,
9412
- className: ui.clx(
9413
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
9414
- className
9415
- ),
9416
- ...props,
9417
- children: [
9418
- /* @__PURE__ */ jsxRuntime.jsx(
9419
- "div",
9420
- {
9421
- role: "presentation",
9422
- className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
9423
- "bg-ui-tag-orange-icon": variant === "warning"
9424
- })
9425
- }
9426
- ),
9427
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
9428
- /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
9429
- labelValue,
9430
- ":"
9431
- ] }),
9432
- " ",
9433
- children
9434
- ] })
9435
- ]
9436
- }
9437
- );
9438
- }
9439
- );
9440
- InlineTip.displayName = "InlineTip";
9441
- const MetadataFieldSchema = z.object({
9442
- key: z.string(),
9443
- disabled: z.boolean().optional(),
9444
- value: z.any()
9445
- });
9446
- const MetadataSchema = z.object({
9447
- metadata: z.array(MetadataFieldSchema)
9291
+ const CustomItems = () => {
9292
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9293
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9294
+ /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9295
+ ] });
9296
+ };
9297
+ const CustomItemsForm = () => {
9298
+ const form = reactHookForm.useForm({
9299
+ resolver: zod.zodResolver(schema$6)
9300
+ });
9301
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9302
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9303
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9304
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9305
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9306
+ ] }) })
9307
+ ] }) });
9308
+ };
9309
+ const schema$6 = z.object({
9310
+ email: z.string().email()
9448
9311
  });
9449
- const Metadata = () => {
9312
+ const Email = () => {
9450
9313
  const { id } = reactRouterDom.useParams();
9451
9314
  const { order, isPending, isError, error } = useOrder(id, {
9452
- fields: "metadata"
9315
+ fields: "+email"
9453
9316
  });
9454
9317
  if (isError) {
9455
9318
  throw error;
@@ -9457,33 +9320,26 @@ const Metadata = () => {
9457
9320
  const isReady = !isPending && !!order;
9458
9321
  return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9459
9322
  /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
9460
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
9461
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
9323
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Email" }) }),
9324
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
9462
9325
  ] }),
9463
- !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
9326
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(EmailForm, { order })
9464
9327
  ] });
9465
9328
  };
9466
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
9467
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
9468
- const MetadataForm = ({ orderId, metadata }) => {
9469
- const { handleSuccess } = useRouteModal();
9470
- const hasUneditableRows = getHasUneditableRows(metadata);
9471
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
9329
+ const EmailForm = ({ order }) => {
9472
9330
  const form = reactHookForm.useForm({
9473
9331
  defaultValues: {
9474
- metadata: getDefaultValues(metadata)
9332
+ email: order.email ?? ""
9475
9333
  },
9476
- resolver: zod.zodResolver(MetadataSchema)
9334
+ resolver: zod.zodResolver(schema$5)
9477
9335
  });
9478
- const handleSubmit = form.handleSubmit(async (data) => {
9479
- const parsedData = parseValues(data);
9336
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9337
+ const { handleSuccess } = useRouteModal();
9338
+ const onSubmit = form.handleSubmit(async (data) => {
9480
9339
  await mutateAsync(
9481
- {
9482
- metadata: parsedData
9483
- },
9340
+ { email: data.email },
9484
9341
  {
9485
9342
  onSuccess: () => {
9486
- ui.toast.success("Metadata updated");
9487
9343
  handleSuccess();
9488
9344
  },
9489
9345
  onError: (error) => {
@@ -9492,266 +9348,35 @@ const MetadataForm = ({ orderId, metadata }) => {
9492
9348
  }
9493
9349
  );
9494
9350
  });
9495
- const { fields, insert, remove } = reactHookForm.useFieldArray({
9496
- control: form.control,
9497
- name: "metadata"
9498
- });
9499
- function deleteRow(index) {
9500
- remove(index);
9501
- if (fields.length === 1) {
9502
- insert(0, {
9503
- key: "",
9504
- value: "",
9505
- disabled: false
9506
- });
9507
- }
9508
- }
9509
- function insertRow(index, position) {
9510
- insert(index + (position === "above" ? 0 : 1), {
9511
- key: "",
9512
- value: "",
9513
- disabled: false
9514
- });
9515
- }
9516
9351
  return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
9517
9352
  KeyboundForm,
9518
9353
  {
9519
- onSubmit: handleSubmit,
9520
9354
  className: "flex flex-1 flex-col overflow-hidden",
9355
+ onSubmit,
9521
9356
  children: [
9522
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
9523
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
9524
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
9525
- /* @__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" }) }),
9526
- /* @__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" }) })
9527
- ] }),
9528
- fields.map((field, index) => {
9529
- const isDisabled = field.disabled || false;
9530
- let placeholder = "-";
9531
- if (typeof field.value === "object") {
9532
- placeholder = "{ ... }";
9533
- }
9534
- if (Array.isArray(field.value)) {
9535
- placeholder = "[ ... ]";
9536
- }
9537
- return /* @__PURE__ */ jsxRuntime.jsx(
9538
- ConditionalTooltip,
9539
- {
9540
- showTooltip: isDisabled,
9541
- content: "This row is disabled because it contains non-primitive data.",
9542
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
9543
- /* @__PURE__ */ jsxRuntime.jsxs(
9544
- "div",
9545
- {
9546
- className: ui.clx("grid grid-cols-2 divide-x", {
9547
- "overflow-hidden rounded-b-lg": index === fields.length - 1
9548
- }),
9549
- children: [
9550
- /* @__PURE__ */ jsxRuntime.jsx(
9551
- Form$2.Field,
9552
- {
9553
- control: form.control,
9554
- name: `metadata.${index}.key`,
9555
- render: ({ field: field2 }) => {
9556
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
9557
- GridInput,
9558
- {
9559
- "aria-labelledby": METADATA_KEY_LABEL_ID,
9560
- ...field2,
9561
- disabled: isDisabled,
9562
- placeholder: "Key"
9563
- }
9564
- ) }) });
9565
- }
9566
- }
9567
- ),
9568
- /* @__PURE__ */ jsxRuntime.jsx(
9569
- Form$2.Field,
9570
- {
9571
- control: form.control,
9572
- name: `metadata.${index}.value`,
9573
- render: ({ field: { value, ...field2 } }) => {
9574
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
9575
- GridInput,
9576
- {
9577
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
9578
- ...field2,
9579
- value: isDisabled ? placeholder : value,
9580
- disabled: isDisabled,
9581
- placeholder: "Value"
9582
- }
9583
- ) }) });
9584
- }
9585
- }
9586
- )
9587
- ]
9588
- }
9589
- ),
9590
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
9591
- /* @__PURE__ */ jsxRuntime.jsx(
9592
- ui.DropdownMenu.Trigger,
9593
- {
9594
- className: ui.clx(
9595
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
9596
- {
9597
- hidden: isDisabled
9598
- }
9599
- ),
9600
- disabled: isDisabled,
9601
- asChild: true,
9602
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
9603
- }
9604
- ),
9605
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
9606
- /* @__PURE__ */ jsxRuntime.jsxs(
9607
- ui.DropdownMenu.Item,
9608
- {
9609
- className: "gap-x-2",
9610
- onClick: () => insertRow(index, "above"),
9611
- children: [
9612
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
9613
- "Insert row above"
9614
- ]
9615
- }
9616
- ),
9617
- /* @__PURE__ */ jsxRuntime.jsxs(
9618
- ui.DropdownMenu.Item,
9619
- {
9620
- className: "gap-x-2",
9621
- onClick: () => insertRow(index, "below"),
9622
- children: [
9623
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
9624
- "Insert row below"
9625
- ]
9626
- }
9627
- ),
9628
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
9629
- /* @__PURE__ */ jsxRuntime.jsxs(
9630
- ui.DropdownMenu.Item,
9631
- {
9632
- className: "gap-x-2",
9633
- onClick: () => deleteRow(index),
9634
- children: [
9635
- /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
9636
- "Delete row"
9637
- ]
9638
- }
9639
- )
9640
- ] })
9641
- ] })
9642
- ] })
9643
- },
9644
- field.id
9645
- );
9646
- })
9647
- ] }),
9648
- 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." })
9649
- ] }),
9650
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
9651
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
9357
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
9358
+ Form$2.Field,
9359
+ {
9360
+ control: form.control,
9361
+ name: "email",
9362
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9363
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Email" }),
9364
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9365
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9366
+ ] })
9367
+ }
9368
+ ) }),
9369
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9370
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9652
9371
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
9653
9372
  ] }) })
9654
9373
  ]
9655
9374
  }
9656
9375
  ) });
9657
9376
  };
9658
- const GridInput = React.forwardRef(({ className, ...props }, ref) => {
9659
- return /* @__PURE__ */ jsxRuntime.jsx(
9660
- "input",
9661
- {
9662
- ref,
9663
- ...props,
9664
- autoComplete: "off",
9665
- className: ui.clx(
9666
- "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",
9667
- className
9668
- )
9669
- }
9670
- );
9377
+ const schema$5 = z.object({
9378
+ email: z.string().email()
9671
9379
  });
9672
- GridInput.displayName = "MetadataForm.GridInput";
9673
- const PlaceholderInner = () => {
9674
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
9675
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
9676
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
9677
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
9678
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
9679
- ] }) })
9680
- ] });
9681
- };
9682
- const EDITABLE_TYPES = ["string", "number", "boolean"];
9683
- function getDefaultValues(metadata) {
9684
- if (!metadata || !Object.keys(metadata).length) {
9685
- return [
9686
- {
9687
- key: "",
9688
- value: "",
9689
- disabled: false
9690
- }
9691
- ];
9692
- }
9693
- return Object.entries(metadata).map(([key, value]) => {
9694
- if (!EDITABLE_TYPES.includes(typeof value)) {
9695
- return {
9696
- key,
9697
- value,
9698
- disabled: true
9699
- };
9700
- }
9701
- let stringValue = value;
9702
- if (typeof value !== "string") {
9703
- stringValue = JSON.stringify(value);
9704
- }
9705
- return {
9706
- key,
9707
- value: stringValue,
9708
- original_key: key
9709
- };
9710
- });
9711
- }
9712
- function parseValues(values) {
9713
- const metadata = values.metadata;
9714
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
9715
- if (isEmpty) {
9716
- return null;
9717
- }
9718
- const update = {};
9719
- metadata.forEach((field) => {
9720
- let key = field.key;
9721
- let value = field.value;
9722
- const disabled = field.disabled;
9723
- if (!key || !value) {
9724
- return;
9725
- }
9726
- if (disabled) {
9727
- update[key] = value;
9728
- return;
9729
- }
9730
- key = key.trim();
9731
- value = value.trim();
9732
- if (value === "true") {
9733
- update[key] = true;
9734
- } else if (value === "false") {
9735
- update[key] = false;
9736
- } else {
9737
- const parsedNumber = parseFloat(value);
9738
- if (!isNaN(parsedNumber)) {
9739
- update[key] = parsedNumber;
9740
- } else {
9741
- update[key] = value;
9742
- }
9743
- }
9744
- });
9745
- return update;
9746
- }
9747
- function getHasUneditableRows(metadata) {
9748
- if (!metadata) {
9749
- return false;
9750
- }
9751
- return Object.values(metadata).some(
9752
- (value) => !EDITABLE_TYPES.includes(typeof value)
9753
- );
9754
- }
9755
9380
  const Promotions = () => {
9756
9381
  return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9757
9382
  /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
@@ -9802,911 +9427,804 @@ const PromotionForm = () => {
9802
9427
  const schema$4 = z.object({
9803
9428
  promo_codes: z.string().optional()
9804
9429
  });
9805
- const SalesChannel = () => {
9806
- const { id } = reactRouterDom.useParams();
9807
- const { draft_order, isPending, isError, error } = useDraftOrder(
9808
- id,
9809
- {
9810
- fields: "+sales_channel_id"
9811
- },
9812
- {
9813
- enabled: !!id
9430
+ function NumberInput({
9431
+ value,
9432
+ onChange,
9433
+ min = 0,
9434
+ max = 100,
9435
+ step = 1,
9436
+ className,
9437
+ disabled,
9438
+ ...props
9439
+ }) {
9440
+ const handleChange = (event) => {
9441
+ const newValue = event.target.value === "" ? min : Number(event.target.value);
9442
+ if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
9443
+ onChange(newValue);
9814
9444
  }
9815
- );
9816
- if (isError) {
9817
- throw error;
9818
- }
9819
- const ready = draft_order && !isPending;
9820
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9821
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
9822
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
9823
- /* @__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" }) })
9824
- ] }),
9825
- ready && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
9826
- ] });
9827
- };
9828
- const SalesChannelForm = ({ order }) => {
9829
- const form = reactHookForm.useForm({
9830
- defaultValues: {
9831
- sales_channel_id: order.sales_channel_id || void 0,
9832
- notify: false
9833
- },
9834
- resolver: zod.zodResolver(schema$3)
9835
- });
9836
- const salesChannels = useComboboxData({
9837
- queryFn: async (params) => {
9838
- return await sdk.admin.salesChannel.list(params);
9839
- },
9840
- queryKey: ["sales-channels"],
9841
- getOptions: (data) => {
9842
- return data.sales_channels.map((salesChannel) => ({
9843
- label: salesChannel.name,
9844
- value: salesChannel.id
9845
- }));
9846
- },
9847
- defaultValue: order.sales_channel_id || void 0
9445
+ };
9446
+ const handleIncrement = () => {
9447
+ const newValue = value + step;
9448
+ if (max === void 0 || newValue <= max) {
9449
+ onChange(newValue);
9450
+ }
9451
+ };
9452
+ const handleDecrement = () => {
9453
+ const newValue = value - step;
9454
+ if (min === void 0 || newValue >= min) {
9455
+ onChange(newValue);
9456
+ }
9457
+ };
9458
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9459
+ "div",
9460
+ {
9461
+ className: ui.clx(
9462
+ "inline-flex h-7 rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
9463
+ "[&:has(input:focus)]:shadow-borders-interactive-with-active",
9464
+ className
9465
+ ),
9466
+ children: [
9467
+ /* @__PURE__ */ jsxRuntime.jsx(
9468
+ "input",
9469
+ {
9470
+ type: "number",
9471
+ value,
9472
+ onChange: handleChange,
9473
+ min,
9474
+ max,
9475
+ step,
9476
+ className: ui.clx(
9477
+ "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
9478
+ "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
9479
+ "placeholder:text-ui-fg-muted"
9480
+ ),
9481
+ ...props
9482
+ }
9483
+ ),
9484
+ /* @__PURE__ */ jsxRuntime.jsxs(
9485
+ "button",
9486
+ {
9487
+ className: ui.clx(
9488
+ "size-7 flex items-center justify-center outline-none transition-fg",
9489
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9490
+ "focus:bg-ui-bg-field-component-hover",
9491
+ "hover:bg-ui-bg-field-component-hover"
9492
+ ),
9493
+ type: "button",
9494
+ onClick: handleDecrement,
9495
+ disabled: min !== void 0 && value <= min || disabled,
9496
+ children: [
9497
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Minus, {}),
9498
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
9499
+ ]
9500
+ }
9501
+ ),
9502
+ /* @__PURE__ */ jsxRuntime.jsxs(
9503
+ "button",
9504
+ {
9505
+ className: ui.clx(
9506
+ "size-7 flex items-center justify-center outline-none transition-fg",
9507
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9508
+ "focus:bg-ui-bg-field-hover",
9509
+ "hover:bg-ui-bg-field-hover"
9510
+ ),
9511
+ type: "button",
9512
+ onClick: handleIncrement,
9513
+ disabled: max !== void 0 && value >= max || disabled,
9514
+ children: [
9515
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
9516
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Increase by ${step}` })
9517
+ ]
9518
+ }
9519
+ )
9520
+ ]
9521
+ }
9522
+ );
9523
+ }
9524
+ const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
9525
+ const productVariantsQueryKeys = {
9526
+ list: (query) => [
9527
+ PRODUCT_VARIANTS_QUERY_KEY,
9528
+ query ? query : void 0
9529
+ ]
9530
+ };
9531
+ const useProductVariants = (query, options) => {
9532
+ const { data, ...rest } = reactQuery.useQuery({
9533
+ queryKey: productVariantsQueryKeys.list(query),
9534
+ queryFn: async () => await sdk.admin.productVariant.list(query),
9535
+ ...options
9848
9536
  });
9849
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9850
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-6", children: [
9851
- /* @__PURE__ */ jsxRuntime.jsx(
9852
- Form$2.Field,
9537
+ return { ...data, ...rest };
9538
+ };
9539
+ const useCancelOrderEdit = ({ preview }) => {
9540
+ const { mutateAsync: cancelOrderEdit } = useOrderEditCancel(preview == null ? void 0 : preview.id);
9541
+ const onCancel = React.useCallback(async () => {
9542
+ if (!preview) {
9543
+ return true;
9544
+ }
9545
+ let res = false;
9546
+ await cancelOrderEdit(void 0, {
9547
+ onError: (e) => {
9548
+ ui.toast.error(e.message);
9549
+ },
9550
+ onSuccess: () => {
9551
+ res = true;
9552
+ }
9553
+ });
9554
+ return res;
9555
+ }, [preview, cancelOrderEdit]);
9556
+ return { onCancel };
9557
+ };
9558
+ let IS_REQUEST_RUNNING = false;
9559
+ const useInitiateOrderEdit = ({
9560
+ preview
9561
+ }) => {
9562
+ const navigate = reactRouterDom.useNavigate();
9563
+ const { mutateAsync } = useOrderEditCreate(preview == null ? void 0 : preview.id);
9564
+ React.useEffect(() => {
9565
+ async function run() {
9566
+ if (IS_REQUEST_RUNNING || !preview) {
9567
+ return;
9568
+ }
9569
+ if (preview.order_change) {
9570
+ return;
9571
+ }
9572
+ IS_REQUEST_RUNNING = true;
9573
+ await mutateAsync(
9853
9574
  {
9854
- control: form.control,
9855
- name: "sales_channel_id",
9856
- render: ({ field }) => {
9857
- return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9858
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
9859
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
9860
- Combobox,
9861
- {
9862
- options: salesChannels.options,
9863
- fetchNextPage: salesChannels.fetchNextPage,
9864
- isFetchingNextPage: salesChannels.isFetchingNextPage,
9865
- searchValue: salesChannels.searchValue,
9866
- onSearchValueChange: salesChannels.onSearchValueChange,
9867
- placeholder: "Select sales channel",
9868
- ...field
9869
- }
9870
- ) })
9871
- ] });
9872
- }
9873
- }
9874
- ),
9875
- /* @__PURE__ */ jsxRuntime.jsx(
9876
- SwitchBlock,
9575
+ order_id: preview.id
9576
+ },
9877
9577
  {
9878
- label: "Send notification",
9879
- description: "Notify the customer that the sales channel has been updated.",
9880
- control: form.control,
9881
- name: "notify"
9578
+ onError: (e) => {
9579
+ ui.toast.error(e.message);
9580
+ navigate(`/draft-orders/${preview.id}`, { replace: true });
9581
+ return;
9582
+ }
9882
9583
  }
9883
- )
9884
- ] }),
9885
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9886
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9887
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9888
- ] }) })
9889
- ] }) });
9584
+ );
9585
+ IS_REQUEST_RUNNING = false;
9586
+ }
9587
+ run();
9588
+ }, [preview, navigate, mutateAsync]);
9890
9589
  };
9891
- const schema$3 = z.object({
9892
- sales_channel_id: z.string().min(1),
9893
- notify: z.boolean().optional()
9894
- });
9895
- const ShippingAddress = () => {
9590
+ const STACKED_MODAL_ID = "items_stacked_modal";
9591
+ const Items = () => {
9896
9592
  const { id } = reactRouterDom.useParams();
9897
- const { order, isPending, isError, error } = useOrder(id, {
9898
- fields: "+shipping_address"
9899
- });
9593
+ const {
9594
+ order: preview,
9595
+ isPending: isPreviewPending,
9596
+ isError: isPreviewError,
9597
+ error: previewError
9598
+ } = useOrderPreview(id);
9599
+ useInitiateOrderEdit({ preview });
9600
+ const { draft_order, isPending, isError, error } = useDraftOrder(
9601
+ id,
9602
+ {
9603
+ fields: "currency_code"
9604
+ },
9605
+ {
9606
+ enabled: !!id
9607
+ }
9608
+ );
9609
+ const { onCancel } = useCancelOrderEdit({ preview });
9900
9610
  if (isError) {
9901
9611
  throw error;
9902
9612
  }
9903
- const isReady = !isPending && !!order;
9904
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9905
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
9906
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Shipping Address" }) }),
9907
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
9908
- ] }),
9909
- isReady && /* @__PURE__ */ jsxRuntime.jsx(ShippingAddressForm, { order })
9910
- ] });
9613
+ if (isPreviewError) {
9614
+ throw previewError;
9615
+ }
9616
+ const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
9617
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: ready && /* @__PURE__ */ jsxRuntime.jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) });
9911
9618
  };
9912
- const ShippingAddressForm = ({ order }) => {
9913
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
9619
+ const ItemsForm = ({ preview, currencyCode }) => {
9620
+ var _a;
9621
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
9622
+ const { handleSuccess } = useRouteModal();
9623
+ const { searchValue, onSearchValueChange, query } = useDebouncedSearch();
9914
9624
  const form = reactHookForm.useForm({
9915
9625
  defaultValues: {
9916
- first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
9917
- last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
9918
- company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
9919
- address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
9920
- address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
9921
- city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
9922
- province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
9923
- country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
9924
- postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
9925
- phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? "",
9926
9626
  notify: false
9927
9627
  },
9928
- resolver: zod.zodResolver(schema$2)
9628
+ resolver: zod.zodResolver(schema$3)
9929
9629
  });
9930
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9931
- const { handleSuccess } = useRouteModal();
9932
- const onSubmit = form.handleSubmit(async (data) => {
9933
- await mutateAsync(
9934
- {
9935
- shipping_address: {
9936
- first_name: data.first_name,
9937
- last_name: data.last_name,
9938
- company: data.company,
9939
- address_1: data.address_1,
9940
- address_2: data.address_2,
9941
- city: data.city,
9942
- province: data.province,
9943
- country_code: data.country_code,
9944
- postal_code: data.postal_code,
9945
- phone: data.phone
9946
- }
9630
+ const { mutateAsync: confirmOrderEdit } = useOrderEditConfirm(preview.id);
9631
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
9632
+ const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
9633
+ const matches = React.useMemo(() => {
9634
+ return matchSorter.matchSorter(preview.items, query, {
9635
+ keys: ["product_title", "variant_title", "variant_sku"]
9636
+ });
9637
+ }, [preview.items, query]);
9638
+ const onSubmit = form.handleSubmit(async (_data) => {
9639
+ setIsSubmitting(true);
9640
+ let requestSucceeded = false;
9641
+ await requestOrderEdit(void 0, {
9642
+ onError: (e) => {
9643
+ ui.toast.error(`Failed to request order edit: ${e.message}`);
9947
9644
  },
9948
- {
9949
- onSuccess: () => {
9950
- handleSuccess();
9951
- },
9952
- onError: (error) => {
9953
- ui.toast.error(error.message);
9954
- }
9645
+ onSuccess: () => {
9646
+ requestSucceeded = true;
9955
9647
  }
9956
- );
9648
+ });
9649
+ if (!requestSucceeded) {
9650
+ setIsSubmitting(false);
9651
+ return;
9652
+ }
9653
+ await confirmOrderEdit(void 0, {
9654
+ onError: (e) => {
9655
+ ui.toast.error(`Failed to confirm order edit: ${e.message}`);
9656
+ },
9657
+ onSuccess: () => {
9658
+ handleSuccess();
9659
+ },
9660
+ onSettled: () => {
9661
+ setIsSubmitting(false);
9662
+ }
9663
+ });
9957
9664
  });
9958
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
9665
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
9959
9666
  KeyboundForm,
9960
9667
  {
9961
- className: "flex flex-1 flex-col overflow-hidden",
9668
+ className: "flex h-full flex-col overflow-hidden",
9962
9669
  onSubmit,
9963
9670
  children: [
9964
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: [
9965
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-4", children: [
9966
- /* @__PURE__ */ jsxRuntime.jsx(
9967
- Form$2.Field,
9968
- {
9969
- control: form.control,
9970
- name: "country_code",
9971
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9972
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Country" }),
9973
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(CountrySelect, { ...field }) }),
9974
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9671
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
9672
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal, { id: STACKED_MODAL_ID, children: [
9673
+ /* @__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: [
9674
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9675
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Items" }) }),
9676
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Edit the items in the draft order." }) })
9677
+ ] }),
9678
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
9679
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
9680
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
9681
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
9682
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
9683
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
9684
+ ] }),
9685
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9686
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
9687
+ ui.Input,
9688
+ {
9689
+ type: "search",
9690
+ placeholder: "Search items",
9691
+ value: searchValue,
9692
+ onChange: (e) => onSearchValueChange(e.target.value)
9693
+ }
9694
+ ) }),
9695
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { type: "button", variant: "secondary", children: "Add items" }) })
9975
9696
  ] })
9976
- }
9977
- ),
9978
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
9979
- /* @__PURE__ */ jsxRuntime.jsx(
9980
- Form$2.Field,
9981
- {
9982
- control: form.control,
9983
- name: "first_name",
9984
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9985
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "First name" }),
9986
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9987
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9697
+ ] }),
9698
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
9699
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3 px-4 py-2 text-ui-fg-muted", children: [
9700
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
9701
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) }),
9702
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Price" }) })
9703
+ ] }),
9704
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
9705
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
9706
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
9707
+ ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
9708
+ "div",
9709
+ {
9710
+ className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center",
9711
+ children: [
9712
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
9713
+ /* @__PURE__ */ jsxRuntime.jsx(
9714
+ Thumbnail,
9715
+ {
9716
+ thumbnail: item.thumbnail,
9717
+ alt: item.product_title ?? void 0
9718
+ }
9719
+ ),
9720
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
9721
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
9722
+ /* @__PURE__ */ jsxRuntime.jsx(
9723
+ ui.Text,
9724
+ {
9725
+ size: "small",
9726
+ weight: "plus",
9727
+ leading: "compact",
9728
+ children: item.product_title
9729
+ }
9730
+ ),
9731
+ /* @__PURE__ */ jsxRuntime.jsxs(
9732
+ ui.Text,
9733
+ {
9734
+ size: "small",
9735
+ leading: "compact",
9736
+ className: "text-ui-fg-subtle",
9737
+ children: [
9738
+ "(",
9739
+ item.variant_title,
9740
+ ")"
9741
+ ]
9742
+ }
9743
+ )
9744
+ ] }),
9745
+ /* @__PURE__ */ jsxRuntime.jsx(
9746
+ ui.Text,
9747
+ {
9748
+ size: "small",
9749
+ leading: "compact",
9750
+ className: "text-ui-fg-subtle",
9751
+ children: item.variant_sku
9752
+ }
9753
+ )
9754
+ ] })
9755
+ ] }),
9756
+ /* @__PURE__ */ jsxRuntime.jsx(QuantityInput, { orderId: preview.id, item }),
9757
+ /* @__PURE__ */ jsxRuntime.jsx(
9758
+ UnitPriceInput,
9759
+ {
9760
+ orderId: preview.id,
9761
+ item,
9762
+ currencyCode
9763
+ }
9764
+ )
9765
+ ]
9766
+ },
9767
+ item.id
9768
+ )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
9769
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
9770
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
9771
+ 'No items found for "',
9772
+ query,
9773
+ '".'
9988
9774
  ] })
9989
- }
9990
- ),
9991
- /* @__PURE__ */ jsxRuntime.jsx(
9992
- Form$2.Field,
9775
+ ] }) })
9776
+ ] })
9777
+ ] }),
9778
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
9779
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
9780
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
9781
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(
9782
+ ui.Text,
9993
9783
  {
9994
- control: form.control,
9995
- name: "last_name",
9996
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9997
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Last name" }),
9998
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9999
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10000
- ] })
9784
+ size: "small",
9785
+ leading: "compact",
9786
+ className: "text-ui-fg-subtle",
9787
+ children: [
9788
+ itemCount,
9789
+ " ",
9790
+ itemCount === 1 ? "item" : "items"
9791
+ ]
10001
9792
  }
10002
- )
9793
+ ) }),
9794
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10003
9795
  ] }),
9796
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10004
9797
  /* @__PURE__ */ jsxRuntime.jsx(
10005
- Form$2.Field,
10006
- {
10007
- control: form.control,
10008
- name: "company",
10009
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10010
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Company" }),
10011
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10012
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10013
- ] })
10014
- }
10015
- ),
10016
- /* @__PURE__ */ jsxRuntime.jsx(
10017
- Form$2.Field,
10018
- {
10019
- control: form.control,
10020
- name: "address_1",
10021
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10022
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Address" }),
10023
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10024
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10025
- ] })
10026
- }
10027
- ),
10028
- /* @__PURE__ */ jsxRuntime.jsx(
10029
- Form$2.Field,
9798
+ SwitchBlock,
10030
9799
  {
9800
+ label: "Send notification",
9801
+ description: "Notify the customer that the items have been updated.",
10031
9802
  control: form.control,
10032
- name: "address_2",
10033
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10034
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
10035
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10036
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10037
- ] })
10038
- }
10039
- ),
10040
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
10041
- /* @__PURE__ */ jsxRuntime.jsx(
10042
- Form$2.Field,
10043
- {
10044
- control: form.control,
10045
- name: "postal_code",
10046
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10047
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Postal code" }),
10048
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10049
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10050
- ] })
10051
- }
10052
- ),
10053
- /* @__PURE__ */ jsxRuntime.jsx(
10054
- Form$2.Field,
10055
- {
10056
- control: form.control,
10057
- name: "city",
10058
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10059
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "City" }),
10060
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10061
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10062
- ] })
10063
- }
10064
- )
10065
- ] }),
10066
- /* @__PURE__ */ jsxRuntime.jsx(
10067
- Form$2.Field,
10068
- {
10069
- control: form.control,
10070
- name: "province",
10071
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10072
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Province / State" }),
10073
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10074
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10075
- ] })
10076
- }
10077
- ),
10078
- /* @__PURE__ */ jsxRuntime.jsx(
10079
- Form$2.Field,
10080
- {
10081
- control: form.control,
10082
- name: "phone",
10083
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10084
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Phone" }),
10085
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10086
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10087
- ] })
9803
+ name: "notify"
10088
9804
  }
10089
9805
  )
10090
- ] }),
10091
- /* @__PURE__ */ jsxRuntime.jsx(
10092
- SwitchBlock,
10093
- {
10094
- control: form.control,
10095
- name: "notify",
10096
- label: "Notify customer",
10097
- description: "Notify the customer of the new shipping address."
10098
- }
10099
- )
10100
- ] }),
10101
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
10102
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10103
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
9806
+ ] }) }),
9807
+ /* @__PURE__ */ jsxRuntime.jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items })
9808
+ ] }) }),
9809
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
9810
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
9811
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isSubmitting, children: "Save" })
10104
9812
  ] }) })
10105
9813
  ]
10106
9814
  }
10107
9815
  ) });
10108
9816
  };
10109
- const schema$2 = addressSchema.extend({
10110
- notify: z.boolean().optional()
10111
- });
10112
- const useCancelOrderEdit = ({ preview }) => {
10113
- const { mutateAsync: cancelOrderEdit } = useOrderEditCancel(preview == null ? void 0 : preview.id);
10114
- const onCancel = React.useCallback(async () => {
10115
- if (!preview) {
10116
- return true;
9817
+ const UnitPriceInput = ({
9818
+ orderId,
9819
+ item,
9820
+ currencyCode
9821
+ }) => {
9822
+ const [unitPrice, setUnitPrice] = React.useState(item.unit_price);
9823
+ const [isEditing, setIsEditing] = React.useState(false);
9824
+ const actionId = React.useMemo(() => {
9825
+ var _a, _b;
9826
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
9827
+ }, [item]);
9828
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useOrderEditUpdateActionItem(orderId);
9829
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useOrderEditUpdateOriginalItem(orderId);
9830
+ const onSubmit = React.useCallback(async () => {
9831
+ if (unitPrice === item.unit_price) {
9832
+ setIsEditing(false);
9833
+ return;
10117
9834
  }
10118
- let res = false;
10119
- await cancelOrderEdit(void 0, {
10120
- onError: (e) => {
10121
- ui.toast.error(e.message);
9835
+ if (!actionId) {
9836
+ await updateOriginalItem(
9837
+ {
9838
+ item_id: item.id,
9839
+ quantity: item.quantity,
9840
+ unit_price: unitPrice
9841
+ },
9842
+ {
9843
+ onSuccess: () => {
9844
+ setIsEditing(false);
9845
+ },
9846
+ onError: (e) => {
9847
+ ui.toast.error(e.message);
9848
+ }
9849
+ }
9850
+ );
9851
+ return;
9852
+ }
9853
+ await updateActionItem(
9854
+ {
9855
+ action_id: actionId,
9856
+ unit_price: unitPrice
10122
9857
  },
10123
- onSuccess: () => {
10124
- res = true;
9858
+ {
9859
+ onSuccess: () => {
9860
+ setIsEditing(false);
9861
+ },
9862
+ onError: (e) => {
9863
+ ui.toast.error(e.message);
9864
+ }
10125
9865
  }
10126
- });
10127
- return res;
10128
- }, [preview, cancelOrderEdit]);
10129
- return { onCancel };
9866
+ );
9867
+ }, [item, actionId, updateActionItem, updateOriginalItem, unitPrice]);
9868
+ const onChange = React.useCallback((e) => {
9869
+ const value = e.target.value;
9870
+ if (value === "") {
9871
+ setUnitPrice(null);
9872
+ }
9873
+ const unitPrice2 = parseFloat(value);
9874
+ if (isNaN(unitPrice2)) {
9875
+ return;
9876
+ }
9877
+ setUnitPrice(unitPrice2);
9878
+ }, []);
9879
+ const isLoading = isUpdatingActionItem || isUpdatingOriginalItem;
9880
+ return isEditing ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-3", children: [
9881
+ /* @__PURE__ */ jsxRuntime.jsx(
9882
+ ui.Input,
9883
+ {
9884
+ size: "small",
9885
+ type: "number",
9886
+ value: unitPrice || "",
9887
+ onChange
9888
+ }
9889
+ ),
9890
+ /* @__PURE__ */ jsxRuntime.jsx(
9891
+ ui.IconButton,
9892
+ {
9893
+ className: "shrink-0",
9894
+ type: "button",
9895
+ size: "small",
9896
+ onClick: onSubmit,
9897
+ isLoading,
9898
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {})
9899
+ }
9900
+ )
9901
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-3", children: [
9902
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }),
9903
+ /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { type: "button", size: "small", onClick: () => setIsEditing(true), children: /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {}) })
9904
+ ] });
10130
9905
  };
10131
- let IS_REQUEST_RUNNING = false;
10132
- const useInitiateOrderEdit = ({
10133
- preview
10134
- }) => {
10135
- const navigate = reactRouterDom.useNavigate();
10136
- const { mutateAsync } = useOrderEditCreate(preview == null ? void 0 : preview.id);
10137
- React.useEffect(() => {
10138
- async function run() {
10139
- if (IS_REQUEST_RUNNING || !preview) {
9906
+ const QuantityInput = ({ orderId, item }) => {
9907
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useOrderEditUpdateActionItem(orderId);
9908
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useOrderEditUpdateOriginalItem(orderId);
9909
+ const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useOrderEditRemoveActionItem(orderId);
9910
+ const onChange = React.useCallback(
9911
+ async (quantity) => {
9912
+ var _a, _b;
9913
+ if (quantity === item.quantity) {
10140
9914
  return;
10141
9915
  }
10142
- if (preview.order_change) {
9916
+ const actionId = (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
9917
+ if (actionId) {
9918
+ if (quantity === 0) {
9919
+ await removeActionItem(actionId, {
9920
+ onError: (e) => {
9921
+ ui.toast.error(e.message);
9922
+ }
9923
+ });
9924
+ return;
9925
+ }
9926
+ await updateActionItem(
9927
+ {
9928
+ action_id: actionId,
9929
+ quantity
9930
+ },
9931
+ {
9932
+ onError: (e) => {
9933
+ ui.toast.error(e.message);
9934
+ }
9935
+ }
9936
+ );
10143
9937
  return;
10144
9938
  }
10145
- IS_REQUEST_RUNNING = true;
10146
- await mutateAsync(
9939
+ await updateOriginalItem(
10147
9940
  {
10148
- order_id: preview.id
9941
+ item_id: item.id,
9942
+ quantity
10149
9943
  },
10150
9944
  {
10151
9945
  onError: (e) => {
10152
9946
  ui.toast.error(e.message);
10153
- navigate(`/draft-orders/${preview.id}`, { replace: true });
10154
- return;
10155
9947
  }
10156
9948
  }
10157
9949
  );
10158
- IS_REQUEST_RUNNING = false;
10159
- }
10160
- run();
10161
- }, [preview, navigate, mutateAsync]);
10162
- };
10163
- const Shipping = () => {
10164
- const { id } = reactRouterDom.useParams();
10165
- const [searchParams] = reactRouterDom.useSearchParams();
10166
- const shippingProfileId = searchParams.get("shipping_profile_id");
10167
- const { order, isPending, isError, error } = useOrder(id, {
10168
- fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+items.variant.options.*,+currency_code"
10169
- });
10170
- const {
10171
- order: preview,
10172
- isPending: isPreviewPending,
10173
- isError: isPreviewError,
10174
- error: previewError
10175
- } = useOrderPreview(id);
10176
- useInitiateOrderEdit({ preview });
10177
- const { onCancel } = useCancelOrderEdit({ preview });
10178
- const onClose = async () => {
10179
- const res = await onCancel();
10180
- if (res) {
10181
- clearLocalStorageShippingInformation();
10182
- }
10183
- return res;
10184
- };
10185
- if (isError) {
10186
- throw error;
10187
- }
10188
- if (isPreviewError) {
10189
- throw previewError;
10190
- }
10191
- const ready = order && !isPending && preview && !isPreviewPending;
10192
- return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose, children: ready && /* @__PURE__ */ jsxRuntime.jsx(
10193
- ShippingForm,
9950
+ },
9951
+ [item, updateActionItem, updateOriginalItem, removeActionItem]
9952
+ );
9953
+ return /* @__PURE__ */ jsxRuntime.jsx(
9954
+ NumberInput,
10194
9955
  {
10195
- order,
10196
- preview,
10197
- selectedShippingProfileId: shippingProfileId
9956
+ value: item.quantity,
9957
+ onChange,
9958
+ disabled: isUpdatingActionItem || isUpdatingOriginalItem || isRemovingActionItem
10198
9959
  }
10199
- ) });
9960
+ );
10200
9961
  };
10201
- const ShippingForm = ({
10202
- order,
10203
- preview,
10204
- selectedShippingProfileId
10205
- }) => {
10206
- const [isSubmitting, setIsSubmitting] = React.useState(false);
10207
- const { searchValue, onSearchValueChange, query } = useDebouncedSearch();
10208
- const uniqueShippingProfiles = getUniqueShippingProfiles(order.items);
10209
- const navigate = reactRouterDom.useNavigate();
10210
- const { handleSuccess } = useRouteModal();
10211
- const { mutateAsync: confirmOrderEdit } = useOrderEditConfirm(preview.id);
10212
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
10213
- const shippingInformation = getLocalStorageShippingInformation();
10214
- const form = reactHookForm.useForm({
10215
- defaultValues: {
10216
- shipping_profile_id: selectedShippingProfileId ? selectedShippingProfileId : uniqueShippingProfiles.length <= 1 ? uniqueShippingProfiles[0].id : (shippingInformation == null ? void 0 : shippingInformation.shipping_profile_id) || "",
10217
- location_id: (shippingInformation == null ? void 0 : shippingInformation.location_id) || ""
10218
- },
10219
- resolver: zod.zodResolver(schema$1)
10220
- });
10221
- const shippingProfileId = reactHookForm.useWatch({
10222
- control: form.control,
10223
- name: "shipping_profile_id"
10224
- });
10225
- const locationId = reactHookForm.useWatch({
10226
- control: form.control,
10227
- name: "location_id"
10228
- });
9962
+ const VARIANT_PREFIX = "items";
9963
+ const LIMIT = 50;
9964
+ const ExistingItemsForm = ({ orderId, items }) => {
9965
+ const { setIsOpen } = useStackedModal();
9966
+ const [rowSelection, setRowSelection] = React.useState(
9967
+ items.reduce((acc, item) => {
9968
+ acc[item.variant_id] = true;
9969
+ return acc;
9970
+ }, {})
9971
+ );
10229
9972
  React.useEffect(() => {
10230
- updateLocalStorageShippingInformation({
10231
- shipping_profile_id: shippingProfileId,
10232
- location_id: locationId
10233
- });
10234
- }, [shippingProfileId, locationId]);
10235
- const items = React.useMemo(() => {
10236
- var _a;
10237
- return (_a = order.items) == null ? void 0 : _a.filter(
10238
- (item) => {
10239
- var _a2, _b, _c;
10240
- return ((_c = (_b = (_a2 = item.variant) == null ? void 0 : _a2.product) == null ? void 0 : _b.shipping_profile) == null ? void 0 : _c.id) === shippingProfileId;
10241
- }
10242
- );
10243
- }, [order.items, shippingProfileId]);
10244
- const itemCount = (items == null ? void 0 : items.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10245
- const matches = React.useMemo(() => {
10246
- return matchSorter.matchSorter(items, query, {
10247
- keys: ["product_title", "variant_title", "variant_sku"]
10248
- });
10249
- }, [items, query]);
10250
- if (selectedShippingProfileId && !uniqueShippingProfiles.find(
10251
- (profile) => profile.id === selectedShippingProfileId
10252
- )) {
10253
- ui.toast.error(
10254
- `Unable to find a shipping profile with the provided ID: ${selectedShippingProfileId}`
9973
+ setRowSelection(
9974
+ items.reduce((acc, item) => {
9975
+ acc[item.variant_id] = true;
9976
+ return acc;
9977
+ }, {})
10255
9978
  );
10256
- navigate("..");
10257
- }
10258
- const onSubmit = form.handleSubmit(async (_data) => {
10259
- setIsSubmitting(true);
10260
- let requestSucceeded = false;
10261
- await requestOrderEdit(void 0, {
10262
- onError: (e) => {
10263
- ui.toast.error(`Failed to request order edit: ${e.message}`);
10264
- },
10265
- onSuccess: () => {
10266
- requestSucceeded = true;
10267
- }
10268
- });
10269
- if (!requestSucceeded) {
10270
- setIsSubmitting(false);
10271
- return;
9979
+ }, [items]);
9980
+ const queryParams = useQueryParams(["q", "order"], VARIANT_PREFIX);
9981
+ const { variants, count, isPending, isError, error } = useProductVariants(
9982
+ {
9983
+ ...queryParams,
9984
+ limit: LIMIT
9985
+ },
9986
+ {
9987
+ placeholderData: reactQuery.keepPreviousData
10272
9988
  }
10273
- await confirmOrderEdit(void 0, {
10274
- onError: (e) => {
10275
- ui.toast.error(`Failed to confirm order edit: ${e.message}`);
10276
- },
10277
- onSuccess: () => {
10278
- handleSuccess();
9989
+ );
9990
+ const columns = useColumns();
9991
+ const { mutateAsync } = useOrderEditAddItems(orderId);
9992
+ const onSubmit = async () => {
9993
+ const ids = Object.keys(rowSelection).filter(
9994
+ (id) => !items.find((i) => i.variant_id === id)
9995
+ );
9996
+ await mutateAsync(
9997
+ {
9998
+ items: ids.map((id) => ({
9999
+ variant_id: id,
10000
+ quantity: 1
10001
+ }))
10279
10002
  },
10280
- onSettled: () => {
10281
- setIsSubmitting(false);
10003
+ {
10004
+ onSuccess: () => {
10005
+ setRowSelection({});
10006
+ setIsOpen(STACKED_MODAL_ID, false);
10007
+ },
10008
+ onError: (e) => {
10009
+ ui.toast.error(e.message);
10010
+ }
10282
10011
  }
10283
- });
10284
- });
10285
- return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
10286
- KeyboundForm,
10012
+ );
10013
+ };
10014
+ if (isError) {
10015
+ throw error;
10016
+ }
10017
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10018
+ StackedFocusModal.Content,
10287
10019
  {
10288
- className: "flex h-full flex-col overflow-hidden",
10289
- onSubmit,
10020
+ onOpenAutoFocus: (e) => {
10021
+ e.preventDefault();
10022
+ const searchInput = document.querySelector(
10023
+ "[data-modal-id='modal-search-input']"
10024
+ );
10025
+ if (searchInput) {
10026
+ searchInput.focus();
10027
+ }
10028
+ },
10290
10029
  children: [
10291
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
10292
- /* @__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 py-16 px-6", children: [
10293
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10294
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
10295
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose which shipping method(s) to use for this order." }) })
10296
- ] }),
10297
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10298
- /* @__PURE__ */ jsxRuntime.jsx(
10299
- ShippingProfileField,
10030
+ /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Header, { children: [
10031
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10032
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Choose which product variants to add to the order." }) })
10033
+ ] }),
10034
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
10035
+ DataTable,
10036
+ {
10037
+ data: variants,
10038
+ columns,
10039
+ isLoading: isPending,
10040
+ getRowId: (row) => row.id,
10041
+ rowCount: count,
10042
+ prefix: VARIANT_PREFIX,
10043
+ layout: "fill",
10044
+ rowSelection: {
10045
+ state: rowSelection,
10046
+ onRowSelectionChange: setRowSelection,
10047
+ enableRowSelection: (row) => {
10048
+ return !items.find((i) => i.variant_id === row.original.id);
10049
+ }
10050
+ },
10051
+ autoFocusSearch: true
10052
+ }
10053
+ ) }),
10054
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
10055
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10056
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
10057
+ ] }) })
10058
+ ]
10059
+ }
10060
+ );
10061
+ };
10062
+ const columnHelper = ui.createDataTableColumnHelper();
10063
+ const useColumns = () => {
10064
+ return React.useMemo(() => {
10065
+ return [
10066
+ columnHelper.select(),
10067
+ columnHelper.accessor("product.title", {
10068
+ header: "Product",
10069
+ cell: ({ row }) => {
10070
+ var _a, _b, _c;
10071
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
10072
+ /* @__PURE__ */ jsxRuntime.jsx(
10073
+ Thumbnail,
10074
+ {
10075
+ thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
10076
+ alt: (_b = row.original.product) == null ? void 0 : _b.title
10077
+ }
10078
+ ),
10079
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
10080
+ ] });
10081
+ },
10082
+ enableSorting: true
10083
+ }),
10084
+ columnHelper.accessor("title", {
10085
+ header: "Variant",
10086
+ enableSorting: true
10087
+ }),
10088
+ columnHelper.accessor("sku", {
10089
+ header: "SKU",
10090
+ cell: ({ getValue }) => {
10091
+ return getValue() ?? "-";
10092
+ },
10093
+ enableSorting: true
10094
+ }),
10095
+ columnHelper.accessor("updated_at", {
10096
+ header: "Updated",
10097
+ cell: ({ getValue }) => {
10098
+ return /* @__PURE__ */ jsxRuntime.jsx(
10099
+ ui.Tooltip,
10300
10100
  {
10301
- control: form.control,
10302
- shippingProfiles: uniqueShippingProfiles
10101
+ content: getFullDate({ date: getValue(), includeTime: true }),
10102
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
10303
10103
  }
10304
- ),
10305
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10306
- /* @__PURE__ */ jsxRuntime.jsx(LocationField, { control: form.control }),
10307
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10308
- /* @__PURE__ */ jsxRuntime.jsx(
10309
- ShippingOptionField,
10104
+ );
10105
+ },
10106
+ enableSorting: true,
10107
+ sortAscLabel: "Oldest first",
10108
+ sortDescLabel: "Newest first"
10109
+ }),
10110
+ columnHelper.accessor("created_at", {
10111
+ header: "Created",
10112
+ cell: ({ getValue }) => {
10113
+ return /* @__PURE__ */ jsxRuntime.jsx(
10114
+ ui.Tooltip,
10310
10115
  {
10311
- control: form.control,
10312
- orderId: preview.id,
10313
- preview
10116
+ content: getFullDate({ date: getValue(), includeTime: true }),
10117
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
10314
10118
  }
10315
- ),
10316
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10317
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
10318
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10319
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10320
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items to ship" }),
10321
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Items with the selected shipping profile." })
10322
- ] }),
10323
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10324
- ui.Input,
10325
- {
10326
- type: "search",
10327
- placeholder: "Search items",
10328
- value: searchValue,
10329
- onChange: (e) => onSearchValueChange(e.target.value)
10330
- }
10331
- ) }) })
10332
- ] }),
10333
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10334
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 px-4 py-2 text-ui-fg-muted", children: [
10335
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
10336
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) })
10337
- ] }),
10338
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
10339
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Choose a shipping profile" }),
10340
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Items with the selected shipping profile will be shown here." })
10341
- ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
10342
- "div",
10343
- {
10344
- className: "grid grid-cols-2 gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center",
10345
- children: [
10346
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
10347
- /* @__PURE__ */ jsxRuntime.jsx(
10348
- Thumbnail,
10349
- {
10350
- thumbnail: item.thumbnail,
10351
- alt: item.product_title ?? void 0
10352
- }
10353
- ),
10354
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10355
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
10356
- /* @__PURE__ */ jsxRuntime.jsx(
10357
- ui.Text,
10358
- {
10359
- size: "small",
10360
- weight: "plus",
10361
- leading: "compact",
10362
- children: item.product_title
10363
- }
10364
- ),
10365
- /* @__PURE__ */ jsxRuntime.jsxs(
10366
- ui.Text,
10367
- {
10368
- size: "small",
10369
- leading: "compact",
10370
- className: "text-ui-fg-subtle",
10371
- children: [
10372
- "(",
10373
- item.variant_title,
10374
- ")"
10375
- ]
10376
- }
10377
- )
10378
- ] }),
10379
- /* @__PURE__ */ jsxRuntime.jsx(
10380
- ui.Text,
10381
- {
10382
- size: "small",
10383
- leading: "compact",
10384
- className: "text-ui-fg-subtle",
10385
- children: item.variant_sku
10386
- }
10387
- )
10388
- ] })
10389
- ] }),
10390
- /* @__PURE__ */ jsxRuntime.jsxs(
10391
- ui.Text,
10392
- {
10393
- size: "small",
10394
- leading: "compact",
10395
- className: "text-ui-fg-subtle",
10396
- children: [
10397
- item.quantity,
10398
- "x"
10399
- ]
10400
- }
10401
- )
10402
- ]
10403
- },
10404
- item.id
10405
- )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
10406
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10407
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
10408
- 'No items found for "',
10409
- query,
10410
- '".'
10411
- ] })
10412
- ] }) })
10413
- ] })
10414
- ] })
10415
- ] }) }) }),
10416
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-x-2", children: [
10417
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10418
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isSubmitting, children: "Save" })
10419
- ] }) })
10420
- ]
10421
- }
10422
- ) });
10119
+ );
10120
+ },
10121
+ enableSorting: true,
10122
+ sortAscLabel: "Oldest first",
10123
+ sortDescLabel: "Newest first"
10124
+ })
10125
+ ];
10126
+ }, []);
10423
10127
  };
10424
- const ShippingProfileField = ({
10425
- control,
10426
- shippingProfiles
10427
- }) => {
10428
- const shippingProfileOptions = shippingProfiles.map((profile) => ({
10429
- label: profile.name,
10430
- value: profile.id
10431
- }));
10432
- return /* @__PURE__ */ jsxRuntime.jsx(
10433
- Form$2.Field,
10128
+ const schema$3 = z.object({
10129
+ notify: z.boolean()
10130
+ });
10131
+ const SalesChannel = () => {
10132
+ const { id } = reactRouterDom.useParams();
10133
+ const { draft_order, isPending, isError, error } = useDraftOrder(
10134
+ id,
10434
10135
  {
10435
- control,
10436
- name: "shipping_profile_id",
10437
- render: ({ field: { onChange, ref, ...field } }) => {
10438
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10439
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10440
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Shipping Profile" }),
10441
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose the shipping profile to add shipping for." })
10442
- ] }),
10443
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsxs(
10444
- ui.Select,
10445
- {
10446
- ...field,
10447
- onValueChange: onChange,
10448
- disabled: shippingProfileOptions.length <= 1,
10449
- children: [
10450
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { ref, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, { placeholder: "Select a shipping profile" }) }),
10451
- /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Content, { children: shippingProfileOptions.map((option) => /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: option.value, children: option.label }, option.value)) })
10452
- ]
10453
- }
10454
- ) })
10455
- ] }) });
10456
- }
10457
- }
10458
- );
10459
- };
10460
- const LocationField = ({ control }) => {
10461
- const locations = useComboboxData({
10462
- queryKey: ["locations"],
10463
- queryFn: async (params) => {
10464
- return await sdk.admin.stockLocation.list(params);
10136
+ fields: "+sales_channel_id"
10465
10137
  },
10466
- getOptions: (data) => {
10467
- return data.stock_locations.map((location) => ({
10468
- label: location.name,
10469
- value: location.id
10470
- }));
10471
- }
10472
- });
10473
- return /* @__PURE__ */ jsxRuntime.jsx(
10474
- Form$2.Field,
10475
10138
  {
10476
- control,
10477
- name: "location_id",
10478
- render: ({ field }) => {
10479
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10480
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10481
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Location" }),
10482
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose where you want to ship the items from." })
10483
- ] }),
10484
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10485
- Combobox,
10486
- {
10487
- options: locations.options,
10488
- fetchNextPage: locations.fetchNextPage,
10489
- isFetchingNextPage: locations.isFetchingNextPage,
10490
- searchValue: locations.searchValue,
10491
- onSearchValueChange: locations.onSearchValueChange,
10492
- placeholder: "Select location",
10493
- ...field
10494
- }
10495
- ) })
10496
- ] }) });
10497
- }
10139
+ enabled: !!id
10498
10140
  }
10499
10141
  );
10142
+ if (isError) {
10143
+ throw error;
10144
+ }
10145
+ const ready = draft_order && !isPending;
10146
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10147
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10148
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
10149
+ /* @__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" }) })
10150
+ ] }),
10151
+ ready && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
10152
+ ] });
10500
10153
  };
10501
- const ShippingOptionField = ({
10502
- orderId,
10503
- preview,
10504
- control
10505
- }) => {
10506
- var _a, _b;
10507
- const locationId = reactHookForm.useWatch({ control, name: "location_id" });
10508
- const shippingProfileId = reactHookForm.useWatch({ control, name: "shipping_profile_id" });
10509
- const shippingOptions = useComboboxData({
10510
- queryKey: ["shipping_options"],
10154
+ const SalesChannelForm = ({ order }) => {
10155
+ const form = reactHookForm.useForm({
10156
+ defaultValues: {
10157
+ sales_channel_id: order.sales_channel_id || void 0,
10158
+ notify: false
10159
+ },
10160
+ resolver: zod.zodResolver(schema$2)
10161
+ });
10162
+ const salesChannels = useComboboxData({
10511
10163
  queryFn: async (params) => {
10512
- return await sdk.admin.shippingOption.list({
10513
- ...params,
10514
- stock_location_id: locationId,
10515
- shipping_profile_id: shippingProfileId
10516
- });
10164
+ return await sdk.admin.salesChannel.list(params);
10517
10165
  },
10166
+ queryKey: ["sales-channels"],
10518
10167
  getOptions: (data) => {
10519
- return data.shipping_options.map((option) => ({
10520
- label: option.name,
10521
- value: option.id
10168
+ return data.sales_channels.map((salesChannel) => ({
10169
+ label: salesChannel.name,
10170
+ value: salesChannel.id
10522
10171
  }));
10523
10172
  },
10524
- enabled: !!locationId && !!shippingProfileId,
10525
- defaultValue: ((_a = preview.shipping_methods[0]) == null ? void 0 : _a.shipping_option_id) || void 0
10173
+ defaultValue: order.sales_channel_id || void 0
10526
10174
  });
10527
- const { mutateAsync: addShippingMethod, isPending } = useOrderEditAddShippingMethod(orderId);
10528
- const onShippingOptionChange = async (value) => {
10529
- if (!value) {
10530
- return;
10531
- }
10532
- await addShippingMethod(
10533
- {
10534
- shipping_option_id: value
10535
- },
10536
- {
10537
- onError: (e) => {
10538
- ui.toast.error(e.message);
10539
- }
10540
- }
10541
- );
10542
- };
10543
- const tooltipContent = !locationId && !shippingProfileId ? "Choose a location and shipping profile first." : !locationId ? "Choose a location first." : "Choose a shipping profile first.";
10544
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10545
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10546
- /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", children: "Shipping option" }),
10547
- /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { children: "Choose the shipping option to use." })
10548
- ] }),
10549
- /* @__PURE__ */ jsxRuntime.jsx(
10550
- ConditionalTooltip,
10551
- {
10552
- content: tooltipContent,
10553
- showTooltip: !locationId || !shippingProfileId,
10554
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
10555
- Combobox,
10556
- {
10557
- options: shippingOptions.options,
10558
- fetchNextPage: shippingOptions.fetchNextPage,
10559
- isFetchingNextPage: shippingOptions.isFetchingNextPage,
10560
- searchValue: shippingOptions.searchValue,
10561
- onSearchValueChange: shippingOptions.onSearchValueChange,
10562
- placeholder: "Select shipping option",
10563
- onChange: onShippingOptionChange,
10564
- value: ((_b = preview.shipping_methods[0]) == null ? void 0 : _b.shipping_option_id) || void 0,
10565
- disabled: !locationId || !shippingProfileId || isPending
10175
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
10176
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-6", children: [
10177
+ /* @__PURE__ */ jsxRuntime.jsx(
10178
+ Form$2.Field,
10179
+ {
10180
+ control: form.control,
10181
+ name: "sales_channel_id",
10182
+ render: ({ field }) => {
10183
+ return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10184
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
10185
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10186
+ Combobox,
10187
+ {
10188
+ options: salesChannels.options,
10189
+ fetchNextPage: salesChannels.fetchNextPage,
10190
+ isFetchingNextPage: salesChannels.isFetchingNextPage,
10191
+ searchValue: salesChannels.searchValue,
10192
+ onSearchValueChange: salesChannels.onSearchValueChange,
10193
+ placeholder: "Select sales channel",
10194
+ ...field
10195
+ }
10196
+ ) })
10197
+ ] });
10566
10198
  }
10567
- ) })
10568
- }
10569
- )
10570
- ] });
10571
- };
10572
- const LOCAL_STORAGE_KEY = "draft_order_shipping";
10573
- const getLocalStorageShippingInformation = () => {
10574
- const shippingInformation = localStorage.getItem(LOCAL_STORAGE_KEY);
10575
- return shippingInformation ? JSON.parse(shippingInformation) : null;
10576
- };
10577
- const updateLocalStorageShippingInformation = (shipping) => {
10578
- const shippingInformation = getLocalStorageShippingInformation();
10579
- if (!shippingInformation) {
10580
- localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(shipping));
10581
- return;
10582
- }
10583
- localStorage.setItem(
10584
- LOCAL_STORAGE_KEY,
10585
- JSON.stringify({
10586
- ...shippingInformation,
10587
- ...shipping
10588
- })
10589
- );
10590
- };
10591
- function clearLocalStorageShippingInformation() {
10592
- localStorage.removeItem(LOCAL_STORAGE_KEY);
10593
- }
10594
- const schema$1 = z.object({
10595
- shipping_profile_id: z.string(),
10596
- location_id: z.string()
10597
- });
10598
- function NumberInput({
10599
- value,
10600
- onChange,
10601
- min = 0,
10602
- max = 100,
10603
- step = 1,
10604
- className,
10605
- disabled,
10606
- ...props
10607
- }) {
10608
- const handleChange = (event) => {
10609
- const newValue = event.target.value === "" ? min : Number(event.target.value);
10610
- if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
10611
- onChange(newValue);
10612
- }
10613
- };
10614
- const handleIncrement = () => {
10615
- const newValue = value + step;
10616
- if (max === void 0 || newValue <= max) {
10617
- onChange(newValue);
10618
- }
10619
- };
10620
- const handleDecrement = () => {
10621
- const newValue = value - step;
10622
- if (min === void 0 || newValue >= min) {
10623
- onChange(newValue);
10624
- }
10625
- };
10626
- return /* @__PURE__ */ jsxRuntime.jsxs(
10627
- "div",
10628
- {
10629
- className: ui.clx(
10630
- "inline-flex h-7 rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
10631
- "[&:has(input:focus)]:shadow-borders-interactive-with-active",
10632
- className
10199
+ }
10633
10200
  ),
10634
- children: [
10635
- /* @__PURE__ */ jsxRuntime.jsx(
10636
- "input",
10637
- {
10638
- type: "number",
10639
- value,
10640
- onChange: handleChange,
10641
- min,
10642
- max,
10643
- step,
10644
- className: ui.clx(
10645
- "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
10646
- "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
10647
- "placeholder:text-ui-fg-muted"
10648
- ),
10649
- ...props
10650
- }
10651
- ),
10652
- /* @__PURE__ */ jsxRuntime.jsxs(
10653
- "button",
10654
- {
10655
- className: ui.clx(
10656
- "size-7 flex items-center justify-center outline-none transition-fg",
10657
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10658
- "focus:bg-ui-bg-field-component-hover",
10659
- "hover:bg-ui-bg-field-component-hover"
10660
- ),
10661
- type: "button",
10662
- onClick: handleDecrement,
10663
- disabled: min !== void 0 && value <= min || disabled,
10664
- children: [
10665
- /* @__PURE__ */ jsxRuntime.jsx(icons.Minus, {}),
10666
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
10667
- ]
10668
- }
10669
- ),
10670
- /* @__PURE__ */ jsxRuntime.jsxs(
10671
- "button",
10672
- {
10673
- className: ui.clx(
10674
- "size-7 flex items-center justify-center outline-none transition-fg",
10675
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10676
- "focus:bg-ui-bg-field-hover",
10677
- "hover:bg-ui-bg-field-hover"
10678
- ),
10679
- type: "button",
10680
- onClick: handleIncrement,
10681
- disabled: max !== void 0 && value >= max || disabled,
10682
- children: [
10683
- /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
10684
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Increase by ${step}` })
10685
- ]
10686
- }
10687
- )
10688
- ]
10689
- }
10690
- );
10691
- }
10692
- const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
10693
- const productVariantsQueryKeys = {
10694
- list: (query) => [
10695
- PRODUCT_VARIANTS_QUERY_KEY,
10696
- query ? query : void 0
10697
- ]
10698
- };
10699
- const useProductVariants = (query, options) => {
10700
- const { data, ...rest } = reactQuery.useQuery({
10701
- queryKey: productVariantsQueryKeys.list(query),
10702
- queryFn: async () => await sdk.admin.productVariant.list(query),
10703
- ...options
10704
- });
10705
- return { ...data, ...rest };
10201
+ /* @__PURE__ */ jsxRuntime.jsx(
10202
+ SwitchBlock,
10203
+ {
10204
+ label: "Send notification",
10205
+ description: "Notify the customer that the sales channel has been updated.",
10206
+ control: form.control,
10207
+ name: "notify"
10208
+ }
10209
+ )
10210
+ ] }),
10211
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
10212
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10213
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
10214
+ ] }) })
10215
+ ] }) });
10706
10216
  };
10707
- const STACKED_MODAL_ID = "items_stacked_modal";
10708
- const Items = () => {
10217
+ const schema$2 = z.object({
10218
+ sales_channel_id: z.string().min(1),
10219
+ notify: z.boolean().optional()
10220
+ });
10221
+ const Shipping = () => {
10709
10222
  const { id } = reactRouterDom.useParams();
10223
+ const [searchParams] = reactRouterDom.useSearchParams();
10224
+ const shippingProfileId = searchParams.get("shipping_profile_id");
10225
+ const { order, isPending, isError, error } = useOrder(id, {
10226
+ fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+items.variant.options.*,+currency_code"
10227
+ });
10710
10228
  const {
10711
10229
  order: preview,
10712
10230
  isPending: isPreviewPending,
@@ -10714,44 +10232,87 @@ const Items = () => {
10714
10232
  error: previewError
10715
10233
  } = useOrderPreview(id);
10716
10234
  useInitiateOrderEdit({ preview });
10717
- const { draft_order, isPending, isError, error } = useDraftOrder(
10718
- id,
10719
- {
10720
- fields: "currency_code"
10721
- },
10722
- {
10723
- enabled: !!id
10724
- }
10725
- );
10726
10235
  const { onCancel } = useCancelOrderEdit({ preview });
10236
+ const onClose = async () => {
10237
+ const res = await onCancel();
10238
+ if (res) {
10239
+ clearLocalStorageShippingInformation();
10240
+ }
10241
+ return res;
10242
+ };
10727
10243
  if (isError) {
10728
10244
  throw error;
10729
10245
  }
10730
10246
  if (isPreviewError) {
10731
10247
  throw previewError;
10732
10248
  }
10733
- const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10734
- return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: ready && /* @__PURE__ */ jsxRuntime.jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) });
10249
+ const ready = order && !isPending && preview && !isPreviewPending;
10250
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose, children: ready && /* @__PURE__ */ jsxRuntime.jsx(
10251
+ ShippingForm,
10252
+ {
10253
+ order,
10254
+ preview,
10255
+ selectedShippingProfileId: shippingProfileId
10256
+ }
10257
+ ) });
10735
10258
  };
10736
- const ItemsForm = ({ preview, currencyCode }) => {
10737
- var _a;
10259
+ const ShippingForm = ({
10260
+ order,
10261
+ preview,
10262
+ selectedShippingProfileId
10263
+ }) => {
10738
10264
  const [isSubmitting, setIsSubmitting] = React.useState(false);
10739
- const { handleSuccess } = useRouteModal();
10740
10265
  const { searchValue, onSearchValueChange, query } = useDebouncedSearch();
10266
+ const uniqueShippingProfiles = getUniqueShippingProfiles(order.items);
10267
+ const navigate = reactRouterDom.useNavigate();
10268
+ const { handleSuccess } = useRouteModal();
10269
+ const { mutateAsync: confirmOrderEdit } = useOrderEditConfirm(preview.id);
10270
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
10271
+ const shippingInformation = getLocalStorageShippingInformation();
10741
10272
  const form = reactHookForm.useForm({
10742
10273
  defaultValues: {
10743
- notify: false
10274
+ shipping_profile_id: selectedShippingProfileId ? selectedShippingProfileId : uniqueShippingProfiles.length <= 1 ? uniqueShippingProfiles[0].id : (shippingInformation == null ? void 0 : shippingInformation.shipping_profile_id) || "",
10275
+ location_id: (shippingInformation == null ? void 0 : shippingInformation.location_id) || ""
10744
10276
  },
10745
- resolver: zod.zodResolver(schema)
10277
+ resolver: zod.zodResolver(schema$1)
10746
10278
  });
10747
- const { mutateAsync: confirmOrderEdit } = useOrderEditConfirm(preview.id);
10748
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
10749
- const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10750
- const matches = React.useMemo(() => {
10751
- return matchSorter.matchSorter(preview.items, query, {
10279
+ const shippingProfileId = reactHookForm.useWatch({
10280
+ control: form.control,
10281
+ name: "shipping_profile_id"
10282
+ });
10283
+ const locationId = reactHookForm.useWatch({
10284
+ control: form.control,
10285
+ name: "location_id"
10286
+ });
10287
+ React.useEffect(() => {
10288
+ updateLocalStorageShippingInformation({
10289
+ shipping_profile_id: shippingProfileId,
10290
+ location_id: locationId
10291
+ });
10292
+ }, [shippingProfileId, locationId]);
10293
+ const items = React.useMemo(() => {
10294
+ var _a;
10295
+ return (_a = order.items) == null ? void 0 : _a.filter(
10296
+ (item) => {
10297
+ var _a2, _b, _c;
10298
+ return ((_c = (_b = (_a2 = item.variant) == null ? void 0 : _a2.product) == null ? void 0 : _b.shipping_profile) == null ? void 0 : _c.id) === shippingProfileId;
10299
+ }
10300
+ );
10301
+ }, [order.items, shippingProfileId]);
10302
+ const itemCount = (items == null ? void 0 : items.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10303
+ const matches = React.useMemo(() => {
10304
+ return matchSorter.matchSorter(items, query, {
10752
10305
  keys: ["product_title", "variant_title", "variant_sku"]
10753
10306
  });
10754
- }, [preview.items, query]);
10307
+ }, [items, query]);
10308
+ if (selectedShippingProfileId && !uniqueShippingProfiles.find(
10309
+ (profile) => profile.id === selectedShippingProfileId
10310
+ )) {
10311
+ ui.toast.error(
10312
+ `Unable to find a shipping profile with the provided ID: ${selectedShippingProfileId}`
10313
+ );
10314
+ navigate("..");
10315
+ }
10755
10316
  const onSubmit = form.handleSubmit(async (_data) => {
10756
10317
  setIsSubmitting(true);
10757
10318
  let requestSucceeded = false;
@@ -10786,144 +10347,131 @@ const ItemsForm = ({ preview, currencyCode }) => {
10786
10347
  onSubmit,
10787
10348
  children: [
10788
10349
  /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
10789
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal, { id: STACKED_MODAL_ID, children: [
10790
- /* @__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: [
10791
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10792
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Items" }) }),
10793
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Edit the items in the draft order." }) })
10350
+ /* @__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 py-16 px-6", children: [
10351
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10352
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
10353
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose which shipping method(s) to use for this order." }) })
10354
+ ] }),
10355
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10356
+ /* @__PURE__ */ jsxRuntime.jsx(
10357
+ ShippingProfileField,
10358
+ {
10359
+ control: form.control,
10360
+ shippingProfiles: uniqueShippingProfiles
10361
+ }
10362
+ ),
10363
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10364
+ /* @__PURE__ */ jsxRuntime.jsx(LocationField, { control: form.control }),
10365
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10366
+ /* @__PURE__ */ jsxRuntime.jsx(
10367
+ ShippingOptionField,
10368
+ {
10369
+ control: form.control,
10370
+ orderId: preview.id,
10371
+ preview
10372
+ }
10373
+ ),
10374
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10375
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
10376
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10377
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10378
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items to ship" }),
10379
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Items with the selected shipping profile." })
10380
+ ] }),
10381
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10382
+ ui.Input,
10383
+ {
10384
+ type: "search",
10385
+ placeholder: "Search items",
10386
+ value: searchValue,
10387
+ onChange: (e) => onSearchValueChange(e.target.value)
10388
+ }
10389
+ ) }) })
10794
10390
  ] }),
10795
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10796
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
10797
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10798
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10799
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10800
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10801
- ] }),
10802
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10803
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10804
- ui.Input,
10805
- {
10806
- type: "search",
10807
- placeholder: "Search items",
10808
- value: searchValue,
10809
- onChange: (e) => onSearchValueChange(e.target.value)
10810
- }
10811
- ) }),
10812
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { type: "button", variant: "secondary", children: "Add items" }) })
10813
- ] })
10391
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10392
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 px-4 py-2 text-ui-fg-muted", children: [
10393
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
10394
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) })
10814
10395
  ] }),
10815
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10816
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3 px-4 py-2 text-ui-fg-muted", children: [
10817
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
10818
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10819
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Price" }) })
10820
- ] }),
10821
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
10822
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10823
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10824
- ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
10825
- "div",
10826
- {
10827
- className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center",
10828
- children: [
10829
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
10830
- /* @__PURE__ */ jsxRuntime.jsx(
10831
- Thumbnail,
10832
- {
10833
- thumbnail: item.thumbnail,
10834
- alt: item.product_title ?? void 0
10835
- }
10836
- ),
10837
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10838
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
10839
- /* @__PURE__ */ jsxRuntime.jsx(
10840
- ui.Text,
10841
- {
10842
- size: "small",
10843
- weight: "plus",
10844
- leading: "compact",
10845
- children: item.product_title
10846
- }
10847
- ),
10848
- /* @__PURE__ */ jsxRuntime.jsxs(
10849
- ui.Text,
10850
- {
10851
- size: "small",
10852
- leading: "compact",
10853
- className: "text-ui-fg-subtle",
10854
- children: [
10855
- "(",
10856
- item.variant_title,
10857
- ")"
10858
- ]
10859
- }
10860
- )
10861
- ] }),
10396
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
10397
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Choose a shipping profile" }),
10398
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Items with the selected shipping profile will be shown here." })
10399
+ ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
10400
+ "div",
10401
+ {
10402
+ className: "grid grid-cols-2 gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center",
10403
+ children: [
10404
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
10405
+ /* @__PURE__ */ jsxRuntime.jsx(
10406
+ Thumbnail,
10407
+ {
10408
+ thumbnail: item.thumbnail,
10409
+ alt: item.product_title ?? void 0
10410
+ }
10411
+ ),
10412
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10413
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
10862
10414
  /* @__PURE__ */ jsxRuntime.jsx(
10415
+ ui.Text,
10416
+ {
10417
+ size: "small",
10418
+ weight: "plus",
10419
+ leading: "compact",
10420
+ children: item.product_title
10421
+ }
10422
+ ),
10423
+ /* @__PURE__ */ jsxRuntime.jsxs(
10863
10424
  ui.Text,
10864
10425
  {
10865
10426
  size: "small",
10866
10427
  leading: "compact",
10867
10428
  className: "text-ui-fg-subtle",
10868
- children: item.variant_sku
10429
+ children: [
10430
+ "(",
10431
+ item.variant_title,
10432
+ ")"
10433
+ ]
10869
10434
  }
10870
10435
  )
10871
- ] })
10872
- ] }),
10873
- /* @__PURE__ */ jsxRuntime.jsx(QuantityInput, { orderId: preview.id, item }),
10874
- /* @__PURE__ */ jsxRuntime.jsx(
10875
- UnitPriceInput,
10876
- {
10877
- orderId: preview.id,
10878
- item,
10879
- currencyCode
10880
- }
10881
- )
10882
- ]
10883
- },
10884
- item.id
10885
- )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
10886
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10887
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
10888
- 'No items found for "',
10889
- query,
10890
- '".'
10891
- ] })
10892
- ] }) })
10893
- ] })
10894
- ] }),
10895
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10896
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10897
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10898
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(
10899
- ui.Text,
10900
- {
10901
- size: "small",
10902
- leading: "compact",
10903
- className: "text-ui-fg-subtle",
10904
- children: [
10905
- itemCount,
10906
- " ",
10907
- itemCount === 1 ? "item" : "items"
10436
+ ] }),
10437
+ /* @__PURE__ */ jsxRuntime.jsx(
10438
+ ui.Text,
10439
+ {
10440
+ size: "small",
10441
+ leading: "compact",
10442
+ className: "text-ui-fg-subtle",
10443
+ children: item.variant_sku
10444
+ }
10445
+ )
10446
+ ] })
10447
+ ] }),
10448
+ /* @__PURE__ */ jsxRuntime.jsxs(
10449
+ ui.Text,
10450
+ {
10451
+ size: "small",
10452
+ leading: "compact",
10453
+ className: "text-ui-fg-subtle",
10454
+ children: [
10455
+ item.quantity,
10456
+ "x"
10457
+ ]
10458
+ }
10459
+ )
10908
10460
  ]
10909
- }
10910
- ) }),
10911
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10912
- ] }),
10913
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10914
- /* @__PURE__ */ jsxRuntime.jsx(
10915
- SwitchBlock,
10916
- {
10917
- label: "Send notification",
10918
- description: "Notify the customer that the items have been updated.",
10919
- control: form.control,
10920
- name: "notify"
10921
- }
10922
- )
10923
- ] }) }),
10924
- /* @__PURE__ */ jsxRuntime.jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items })
10925
- ] }) }),
10926
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
10461
+ },
10462
+ item.id
10463
+ )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
10464
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10465
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
10466
+ 'No items found for "',
10467
+ query,
10468
+ '".'
10469
+ ] })
10470
+ ] }) })
10471
+ ] })
10472
+ ] })
10473
+ ] }) }) }),
10474
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-x-2", children: [
10927
10475
  /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10928
10476
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isSubmitting, children: "Save" })
10929
10477
  ] }) })
@@ -10931,320 +10479,747 @@ const ItemsForm = ({ preview, currencyCode }) => {
10931
10479
  }
10932
10480
  ) });
10933
10481
  };
10934
- const UnitPriceInput = ({
10935
- orderId,
10936
- item,
10937
- currencyCode
10482
+ const ShippingProfileField = ({
10483
+ control,
10484
+ shippingProfiles
10938
10485
  }) => {
10939
- const [unitPrice, setUnitPrice] = React.useState(item.unit_price);
10940
- const [isEditing, setIsEditing] = React.useState(false);
10941
- const actionId = React.useMemo(() => {
10942
- var _a, _b;
10943
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10944
- }, [item]);
10945
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useOrderEditUpdateActionItem(orderId);
10946
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useOrderEditUpdateOriginalItem(orderId);
10947
- const onSubmit = React.useCallback(async () => {
10948
- if (unitPrice === item.unit_price) {
10949
- setIsEditing(false);
10950
- return;
10486
+ const shippingProfileOptions = shippingProfiles.map((profile) => ({
10487
+ label: profile.name,
10488
+ value: profile.id
10489
+ }));
10490
+ return /* @__PURE__ */ jsxRuntime.jsx(
10491
+ Form$2.Field,
10492
+ {
10493
+ control,
10494
+ name: "shipping_profile_id",
10495
+ render: ({ field: { onChange, ref, ...field } }) => {
10496
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10497
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10498
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Shipping Profile" }),
10499
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose the shipping profile to add shipping for." })
10500
+ ] }),
10501
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsxs(
10502
+ ui.Select,
10503
+ {
10504
+ ...field,
10505
+ onValueChange: onChange,
10506
+ disabled: shippingProfileOptions.length <= 1,
10507
+ children: [
10508
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Trigger, { ref, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Value, { placeholder: "Select a shipping profile" }) }),
10509
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Content, { children: shippingProfileOptions.map((option) => /* @__PURE__ */ jsxRuntime.jsx(ui.Select.Item, { value: option.value, children: option.label }, option.value)) })
10510
+ ]
10511
+ }
10512
+ ) })
10513
+ ] }) });
10514
+ }
10951
10515
  }
10952
- if (!actionId) {
10953
- await updateOriginalItem(
10954
- {
10955
- item_id: item.id,
10956
- quantity: item.quantity,
10957
- unit_price: unitPrice
10958
- },
10959
- {
10960
- onSuccess: () => {
10961
- setIsEditing(false);
10962
- },
10963
- onError: (e) => {
10964
- ui.toast.error(e.message);
10965
- }
10966
- }
10967
- );
10516
+ );
10517
+ };
10518
+ const LocationField = ({ control }) => {
10519
+ const locations = useComboboxData({
10520
+ queryKey: ["locations"],
10521
+ queryFn: async (params) => {
10522
+ return await sdk.admin.stockLocation.list(params);
10523
+ },
10524
+ getOptions: (data) => {
10525
+ return data.stock_locations.map((location) => ({
10526
+ label: location.name,
10527
+ value: location.id
10528
+ }));
10529
+ }
10530
+ });
10531
+ return /* @__PURE__ */ jsxRuntime.jsx(
10532
+ Form$2.Field,
10533
+ {
10534
+ control,
10535
+ name: "location_id",
10536
+ render: ({ field }) => {
10537
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10538
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10539
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Location" }),
10540
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose where you want to ship the items from." })
10541
+ ] }),
10542
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10543
+ Combobox,
10544
+ {
10545
+ options: locations.options,
10546
+ fetchNextPage: locations.fetchNextPage,
10547
+ isFetchingNextPage: locations.isFetchingNextPage,
10548
+ searchValue: locations.searchValue,
10549
+ onSearchValueChange: locations.onSearchValueChange,
10550
+ placeholder: "Select location",
10551
+ ...field
10552
+ }
10553
+ ) })
10554
+ ] }) });
10555
+ }
10556
+ }
10557
+ );
10558
+ };
10559
+ const ShippingOptionField = ({
10560
+ orderId,
10561
+ preview,
10562
+ control
10563
+ }) => {
10564
+ var _a, _b;
10565
+ const locationId = reactHookForm.useWatch({ control, name: "location_id" });
10566
+ const shippingProfileId = reactHookForm.useWatch({ control, name: "shipping_profile_id" });
10567
+ const shippingOptions = useComboboxData({
10568
+ queryKey: ["shipping_options"],
10569
+ queryFn: async (params) => {
10570
+ return await sdk.admin.shippingOption.list({
10571
+ ...params,
10572
+ stock_location_id: locationId,
10573
+ shipping_profile_id: shippingProfileId
10574
+ });
10575
+ },
10576
+ getOptions: (data) => {
10577
+ return data.shipping_options.map((option) => ({
10578
+ label: option.name,
10579
+ value: option.id
10580
+ }));
10581
+ },
10582
+ enabled: !!locationId && !!shippingProfileId,
10583
+ defaultValue: ((_a = preview.shipping_methods[0]) == null ? void 0 : _a.shipping_option_id) || void 0
10584
+ });
10585
+ const { mutateAsync: addShippingMethod, isPending } = useOrderEditAddShippingMethod(orderId);
10586
+ const onShippingOptionChange = async (value) => {
10587
+ if (!value) {
10968
10588
  return;
10969
10589
  }
10970
- await updateActionItem(
10590
+ await addShippingMethod(
10971
10591
  {
10972
- action_id: actionId,
10973
- unit_price: unitPrice
10592
+ shipping_option_id: value
10974
10593
  },
10975
10594
  {
10976
- onSuccess: () => {
10977
- setIsEditing(false);
10978
- },
10979
10595
  onError: (e) => {
10980
10596
  ui.toast.error(e.message);
10981
10597
  }
10982
10598
  }
10983
10599
  );
10984
- }, [item, actionId, updateActionItem, updateOriginalItem, unitPrice]);
10985
- const onChange = React.useCallback((e) => {
10986
- const value = e.target.value;
10987
- if (value === "") {
10988
- setUnitPrice(null);
10989
- }
10990
- const unitPrice2 = parseFloat(value);
10991
- if (isNaN(unitPrice2)) {
10992
- return;
10993
- }
10994
- setUnitPrice(unitPrice2);
10995
- }, []);
10996
- const isLoading = isUpdatingActionItem || isUpdatingOriginalItem;
10997
- return isEditing ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-3", children: [
10998
- /* @__PURE__ */ jsxRuntime.jsx(
10999
- ui.Input,
11000
- {
11001
- size: "small",
11002
- type: "number",
11003
- value: unitPrice || "",
11004
- onChange
11005
- }
11006
- ),
10600
+ };
10601
+ const tooltipContent = !locationId && !shippingProfileId ? "Choose a location and shipping profile first." : !locationId ? "Choose a location first." : "Choose a shipping profile first.";
10602
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10603
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10604
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", children: "Shipping option" }),
10605
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { children: "Choose the shipping option to use." })
10606
+ ] }),
11007
10607
  /* @__PURE__ */ jsxRuntime.jsx(
11008
- ui.IconButton,
10608
+ ConditionalTooltip,
11009
10609
  {
11010
- className: "shrink-0",
11011
- type: "button",
11012
- size: "small",
11013
- onClick: onSubmit,
11014
- isLoading,
11015
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {})
10610
+ content: tooltipContent,
10611
+ showTooltip: !locationId || !shippingProfileId,
10612
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
10613
+ Combobox,
10614
+ {
10615
+ options: shippingOptions.options,
10616
+ fetchNextPage: shippingOptions.fetchNextPage,
10617
+ isFetchingNextPage: shippingOptions.isFetchingNextPage,
10618
+ searchValue: shippingOptions.searchValue,
10619
+ onSearchValueChange: shippingOptions.onSearchValueChange,
10620
+ placeholder: "Select shipping option",
10621
+ onChange: onShippingOptionChange,
10622
+ value: ((_b = preview.shipping_methods[0]) == null ? void 0 : _b.shipping_option_id) || void 0,
10623
+ disabled: !locationId || !shippingProfileId || isPending
10624
+ }
10625
+ ) })
11016
10626
  }
11017
10627
  )
11018
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-3", children: [
11019
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }),
11020
- /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { type: "button", size: "small", onClick: () => setIsEditing(true), children: /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {}) })
11021
10628
  ] });
11022
10629
  };
11023
- const QuantityInput = ({ orderId, item }) => {
11024
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useOrderEditUpdateActionItem(orderId);
11025
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useOrderEditUpdateOriginalItem(orderId);
11026
- const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useOrderEditRemoveActionItem(orderId);
11027
- const onChange = React.useCallback(
11028
- async (quantity) => {
11029
- var _a, _b;
11030
- if (quantity === item.quantity) {
11031
- return;
11032
- }
11033
- const actionId = (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
11034
- if (actionId) {
11035
- if (quantity === 0) {
11036
- await removeActionItem(actionId, {
11037
- onError: (e) => {
11038
- ui.toast.error(e.message);
11039
- }
11040
- });
11041
- return;
10630
+ const LOCAL_STORAGE_KEY = "draft_order_shipping";
10631
+ const getLocalStorageShippingInformation = () => {
10632
+ const shippingInformation = localStorage.getItem(LOCAL_STORAGE_KEY);
10633
+ return shippingInformation ? JSON.parse(shippingInformation) : null;
10634
+ };
10635
+ const updateLocalStorageShippingInformation = (shipping) => {
10636
+ const shippingInformation = getLocalStorageShippingInformation();
10637
+ if (!shippingInformation) {
10638
+ localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(shipping));
10639
+ return;
10640
+ }
10641
+ localStorage.setItem(
10642
+ LOCAL_STORAGE_KEY,
10643
+ JSON.stringify({
10644
+ ...shippingInformation,
10645
+ ...shipping
10646
+ })
10647
+ );
10648
+ };
10649
+ function clearLocalStorageShippingInformation() {
10650
+ localStorage.removeItem(LOCAL_STORAGE_KEY);
10651
+ }
10652
+ const schema$1 = z.object({
10653
+ shipping_profile_id: z.string(),
10654
+ location_id: z.string()
10655
+ });
10656
+ const ShippingAddress = () => {
10657
+ const { id } = reactRouterDom.useParams();
10658
+ const { order, isPending, isError, error } = useOrder(id, {
10659
+ fields: "+shipping_address"
10660
+ });
10661
+ if (isError) {
10662
+ throw error;
10663
+ }
10664
+ const isReady = !isPending && !!order;
10665
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10666
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10667
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Shipping Address" }) }),
10668
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
10669
+ ] }),
10670
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(ShippingAddressForm, { order })
10671
+ ] });
10672
+ };
10673
+ const ShippingAddressForm = ({ order }) => {
10674
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
10675
+ const form = reactHookForm.useForm({
10676
+ defaultValues: {
10677
+ first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
10678
+ last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
10679
+ company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
10680
+ address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
10681
+ address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
10682
+ city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
10683
+ province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
10684
+ country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
10685
+ postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
10686
+ phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? "",
10687
+ notify: false
10688
+ },
10689
+ resolver: zod.zodResolver(schema)
10690
+ });
10691
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
10692
+ const { handleSuccess } = useRouteModal();
10693
+ const onSubmit = form.handleSubmit(async (data) => {
10694
+ await mutateAsync(
10695
+ {
10696
+ shipping_address: {
10697
+ first_name: data.first_name,
10698
+ last_name: data.last_name,
10699
+ company: data.company,
10700
+ address_1: data.address_1,
10701
+ address_2: data.address_2,
10702
+ city: data.city,
10703
+ province: data.province,
10704
+ country_code: data.country_code,
10705
+ postal_code: data.postal_code,
10706
+ phone: data.phone
11042
10707
  }
11043
- await updateActionItem(
11044
- {
11045
- action_id: actionId,
11046
- quantity
11047
- },
11048
- {
11049
- onError: (e) => {
11050
- ui.toast.error(e.message);
11051
- }
11052
- }
11053
- );
11054
- return;
11055
- }
11056
- await updateOriginalItem(
11057
- {
11058
- item_id: item.id,
11059
- quantity
10708
+ },
10709
+ {
10710
+ onSuccess: () => {
10711
+ handleSuccess();
11060
10712
  },
11061
- {
11062
- onError: (e) => {
11063
- ui.toast.error(e.message);
11064
- }
10713
+ onError: (error) => {
10714
+ ui.toast.error(error.message);
11065
10715
  }
11066
- );
11067
- },
11068
- [item, updateActionItem, updateOriginalItem, removeActionItem]
11069
- );
11070
- return /* @__PURE__ */ jsxRuntime.jsx(
11071
- NumberInput,
10716
+ }
10717
+ );
10718
+ });
10719
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
10720
+ KeyboundForm,
11072
10721
  {
11073
- value: item.quantity,
11074
- onChange,
11075
- disabled: isUpdatingActionItem || isUpdatingOriginalItem || isRemovingActionItem
10722
+ className: "flex flex-1 flex-col overflow-hidden",
10723
+ onSubmit,
10724
+ children: [
10725
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: [
10726
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-4", children: [
10727
+ /* @__PURE__ */ jsxRuntime.jsx(
10728
+ Form$2.Field,
10729
+ {
10730
+ control: form.control,
10731
+ name: "country_code",
10732
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10733
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Country" }),
10734
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(CountrySelect, { ...field }) }),
10735
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10736
+ ] })
10737
+ }
10738
+ ),
10739
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
10740
+ /* @__PURE__ */ jsxRuntime.jsx(
10741
+ Form$2.Field,
10742
+ {
10743
+ control: form.control,
10744
+ name: "first_name",
10745
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10746
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "First name" }),
10747
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10748
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10749
+ ] })
10750
+ }
10751
+ ),
10752
+ /* @__PURE__ */ jsxRuntime.jsx(
10753
+ Form$2.Field,
10754
+ {
10755
+ control: form.control,
10756
+ name: "last_name",
10757
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10758
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Last name" }),
10759
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10760
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10761
+ ] })
10762
+ }
10763
+ )
10764
+ ] }),
10765
+ /* @__PURE__ */ jsxRuntime.jsx(
10766
+ Form$2.Field,
10767
+ {
10768
+ control: form.control,
10769
+ name: "company",
10770
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10771
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Company" }),
10772
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10773
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10774
+ ] })
10775
+ }
10776
+ ),
10777
+ /* @__PURE__ */ jsxRuntime.jsx(
10778
+ Form$2.Field,
10779
+ {
10780
+ control: form.control,
10781
+ name: "address_1",
10782
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10783
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Address" }),
10784
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10785
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10786
+ ] })
10787
+ }
10788
+ ),
10789
+ /* @__PURE__ */ jsxRuntime.jsx(
10790
+ Form$2.Field,
10791
+ {
10792
+ control: form.control,
10793
+ name: "address_2",
10794
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10795
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
10796
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10797
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10798
+ ] })
10799
+ }
10800
+ ),
10801
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
10802
+ /* @__PURE__ */ jsxRuntime.jsx(
10803
+ Form$2.Field,
10804
+ {
10805
+ control: form.control,
10806
+ name: "postal_code",
10807
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10808
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Postal code" }),
10809
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10810
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10811
+ ] })
10812
+ }
10813
+ ),
10814
+ /* @__PURE__ */ jsxRuntime.jsx(
10815
+ Form$2.Field,
10816
+ {
10817
+ control: form.control,
10818
+ name: "city",
10819
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10820
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "City" }),
10821
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10822
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10823
+ ] })
10824
+ }
10825
+ )
10826
+ ] }),
10827
+ /* @__PURE__ */ jsxRuntime.jsx(
10828
+ Form$2.Field,
10829
+ {
10830
+ control: form.control,
10831
+ name: "province",
10832
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10833
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Province / State" }),
10834
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10835
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10836
+ ] })
10837
+ }
10838
+ ),
10839
+ /* @__PURE__ */ jsxRuntime.jsx(
10840
+ Form$2.Field,
10841
+ {
10842
+ control: form.control,
10843
+ name: "phone",
10844
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10845
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Phone" }),
10846
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10847
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10848
+ ] })
10849
+ }
10850
+ )
10851
+ ] }),
10852
+ /* @__PURE__ */ jsxRuntime.jsx(
10853
+ SwitchBlock,
10854
+ {
10855
+ control: form.control,
10856
+ name: "notify",
10857
+ label: "Notify customer",
10858
+ description: "Notify the customer of the new shipping address."
10859
+ }
10860
+ )
10861
+ ] }),
10862
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
10863
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10864
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10865
+ ] }) })
10866
+ ]
11076
10867
  }
11077
- );
10868
+ ) });
11078
10869
  };
11079
- const VARIANT_PREFIX = "items";
11080
- const LIMIT = 50;
11081
- const ExistingItemsForm = ({ orderId, items }) => {
11082
- const { setIsOpen } = useStackedModal();
11083
- const [rowSelection, setRowSelection] = React.useState(
11084
- items.reduce((acc, item) => {
11085
- acc[item.variant_id] = true;
11086
- return acc;
11087
- }, {})
11088
- );
11089
- React.useEffect(() => {
11090
- setRowSelection(
11091
- items.reduce((acc, item) => {
11092
- acc[item.variant_id] = true;
11093
- return acc;
11094
- }, {})
10870
+ const schema = addressSchema.extend({
10871
+ notify: z.boolean().optional()
10872
+ });
10873
+ const InlineTip = React.forwardRef(
10874
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
10875
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10876
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10877
+ "div",
10878
+ {
10879
+ ref,
10880
+ className: ui.clx(
10881
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10882
+ className
10883
+ ),
10884
+ ...props,
10885
+ children: [
10886
+ /* @__PURE__ */ jsxRuntime.jsx(
10887
+ "div",
10888
+ {
10889
+ role: "presentation",
10890
+ className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10891
+ "bg-ui-tag-orange-icon": variant === "warning"
10892
+ })
10893
+ }
10894
+ ),
10895
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
10896
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10897
+ labelValue,
10898
+ ":"
10899
+ ] }),
10900
+ " ",
10901
+ children
10902
+ ] })
10903
+ ]
10904
+ }
11095
10905
  );
11096
- }, [items]);
11097
- const queryParams = useQueryParams(["q", "order"], VARIANT_PREFIX);
11098
- const { variants, count, isPending, isError, error } = useProductVariants(
11099
- {
11100
- ...queryParams,
11101
- limit: LIMIT
10906
+ }
10907
+ );
10908
+ InlineTip.displayName = "InlineTip";
10909
+ const MetadataFieldSchema = z.object({
10910
+ key: z.string(),
10911
+ disabled: z.boolean().optional(),
10912
+ value: z.any()
10913
+ });
10914
+ const MetadataSchema = z.object({
10915
+ metadata: z.array(MetadataFieldSchema)
10916
+ });
10917
+ const Metadata = () => {
10918
+ const { id } = reactRouterDom.useParams();
10919
+ const { order, isPending, isError, error } = useOrder(id, {
10920
+ fields: "metadata"
10921
+ });
10922
+ if (isError) {
10923
+ throw error;
10924
+ }
10925
+ const isReady = !isPending && !!order;
10926
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10927
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10928
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
10929
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10930
+ ] }),
10931
+ !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10932
+ ] });
10933
+ };
10934
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10935
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10936
+ const MetadataForm = ({ orderId, metadata }) => {
10937
+ const { handleSuccess } = useRouteModal();
10938
+ const hasUneditableRows = getHasUneditableRows(metadata);
10939
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10940
+ const form = reactHookForm.useForm({
10941
+ defaultValues: {
10942
+ metadata: getDefaultValues(metadata)
11102
10943
  },
11103
- {
11104
- placeholderData: reactQuery.keepPreviousData
11105
- }
11106
- );
11107
- const columns = useColumns();
11108
- const { mutateAsync } = useOrderEditAddItems(orderId);
11109
- const onSubmit = async () => {
11110
- const ids = Object.keys(rowSelection).filter(
11111
- (id) => !items.find((i) => i.variant_id === id)
11112
- );
10944
+ resolver: zod.zodResolver(MetadataSchema)
10945
+ });
10946
+ const handleSubmit = form.handleSubmit(async (data) => {
10947
+ const parsedData = parseValues(data);
11113
10948
  await mutateAsync(
11114
10949
  {
11115
- items: ids.map((id) => ({
11116
- variant_id: id,
11117
- quantity: 1
11118
- }))
10950
+ metadata: parsedData
11119
10951
  },
11120
10952
  {
11121
10953
  onSuccess: () => {
11122
- setRowSelection({});
11123
- setIsOpen(STACKED_MODAL_ID, false);
10954
+ ui.toast.success("Metadata updated");
10955
+ handleSuccess();
11124
10956
  },
11125
- onError: (e) => {
11126
- ui.toast.error(e.message);
10957
+ onError: (error) => {
10958
+ ui.toast.error(error.message);
11127
10959
  }
11128
10960
  }
11129
10961
  );
11130
- };
11131
- if (isError) {
11132
- throw error;
10962
+ });
10963
+ const { fields, insert, remove } = reactHookForm.useFieldArray({
10964
+ control: form.control,
10965
+ name: "metadata"
10966
+ });
10967
+ function deleteRow(index) {
10968
+ remove(index);
10969
+ if (fields.length === 1) {
10970
+ insert(0, {
10971
+ key: "",
10972
+ value: "",
10973
+ disabled: false
10974
+ });
10975
+ }
11133
10976
  }
11134
- return /* @__PURE__ */ jsxRuntime.jsxs(
11135
- StackedFocusModal.Content,
10977
+ function insertRow(index, position) {
10978
+ insert(index + (position === "above" ? 0 : 1), {
10979
+ key: "",
10980
+ value: "",
10981
+ disabled: false
10982
+ });
10983
+ }
10984
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
10985
+ KeyboundForm,
11136
10986
  {
11137
- onOpenAutoFocus: (e) => {
11138
- e.preventDefault();
11139
- const searchInput = document.querySelector(
11140
- "[data-modal-id='modal-search-input']"
11141
- );
11142
- if (searchInput) {
11143
- searchInput.focus();
11144
- }
11145
- },
10987
+ onSubmit: handleSubmit,
10988
+ className: "flex flex-1 flex-col overflow-hidden",
11146
10989
  children: [
11147
- /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Header, { children: [
11148
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Product Variants" }) }),
11149
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Choose which product variants to add to the order." }) })
10990
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10991
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10992
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10993
+ /* @__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" }) }),
10994
+ /* @__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" }) })
10995
+ ] }),
10996
+ fields.map((field, index) => {
10997
+ const isDisabled = field.disabled || false;
10998
+ let placeholder = "-";
10999
+ if (typeof field.value === "object") {
11000
+ placeholder = "{ ... }";
11001
+ }
11002
+ if (Array.isArray(field.value)) {
11003
+ placeholder = "[ ... ]";
11004
+ }
11005
+ return /* @__PURE__ */ jsxRuntime.jsx(
11006
+ ConditionalTooltip,
11007
+ {
11008
+ showTooltip: isDisabled,
11009
+ content: "This row is disabled because it contains non-primitive data.",
11010
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
11011
+ /* @__PURE__ */ jsxRuntime.jsxs(
11012
+ "div",
11013
+ {
11014
+ className: ui.clx("grid grid-cols-2 divide-x", {
11015
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
11016
+ }),
11017
+ children: [
11018
+ /* @__PURE__ */ jsxRuntime.jsx(
11019
+ Form$2.Field,
11020
+ {
11021
+ control: form.control,
11022
+ name: `metadata.${index}.key`,
11023
+ render: ({ field: field2 }) => {
11024
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11025
+ GridInput,
11026
+ {
11027
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
11028
+ ...field2,
11029
+ disabled: isDisabled,
11030
+ placeholder: "Key"
11031
+ }
11032
+ ) }) });
11033
+ }
11034
+ }
11035
+ ),
11036
+ /* @__PURE__ */ jsxRuntime.jsx(
11037
+ Form$2.Field,
11038
+ {
11039
+ control: form.control,
11040
+ name: `metadata.${index}.value`,
11041
+ render: ({ field: { value, ...field2 } }) => {
11042
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11043
+ GridInput,
11044
+ {
11045
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
11046
+ ...field2,
11047
+ value: isDisabled ? placeholder : value,
11048
+ disabled: isDisabled,
11049
+ placeholder: "Value"
11050
+ }
11051
+ ) }) });
11052
+ }
11053
+ }
11054
+ )
11055
+ ]
11056
+ }
11057
+ ),
11058
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
11059
+ /* @__PURE__ */ jsxRuntime.jsx(
11060
+ ui.DropdownMenu.Trigger,
11061
+ {
11062
+ className: ui.clx(
11063
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11064
+ {
11065
+ hidden: isDisabled
11066
+ }
11067
+ ),
11068
+ disabled: isDisabled,
11069
+ asChild: true,
11070
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
11071
+ }
11072
+ ),
11073
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
11074
+ /* @__PURE__ */ jsxRuntime.jsxs(
11075
+ ui.DropdownMenu.Item,
11076
+ {
11077
+ className: "gap-x-2",
11078
+ onClick: () => insertRow(index, "above"),
11079
+ children: [
11080
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
11081
+ "Insert row above"
11082
+ ]
11083
+ }
11084
+ ),
11085
+ /* @__PURE__ */ jsxRuntime.jsxs(
11086
+ ui.DropdownMenu.Item,
11087
+ {
11088
+ className: "gap-x-2",
11089
+ onClick: () => insertRow(index, "below"),
11090
+ children: [
11091
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
11092
+ "Insert row below"
11093
+ ]
11094
+ }
11095
+ ),
11096
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
11097
+ /* @__PURE__ */ jsxRuntime.jsxs(
11098
+ ui.DropdownMenu.Item,
11099
+ {
11100
+ className: "gap-x-2",
11101
+ onClick: () => deleteRow(index),
11102
+ children: [
11103
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
11104
+ "Delete row"
11105
+ ]
11106
+ }
11107
+ )
11108
+ ] })
11109
+ ] })
11110
+ ] })
11111
+ },
11112
+ field.id
11113
+ );
11114
+ })
11115
+ ] }),
11116
+ 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." })
11150
11117
  ] }),
11151
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
11152
- DataTable,
11153
- {
11154
- data: variants,
11155
- columns,
11156
- isLoading: isPending,
11157
- getRowId: (row) => row.id,
11158
- rowCount: count,
11159
- prefix: VARIANT_PREFIX,
11160
- layout: "fill",
11161
- rowSelection: {
11162
- state: rowSelection,
11163
- onRowSelectionChange: setRowSelection,
11164
- enableRowSelection: (row) => {
11165
- return !items.find((i) => i.variant_id === row.original.id);
11166
- }
11167
- },
11168
- autoFocusSearch: true
11169
- }
11170
- ) }),
11171
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
11172
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11173
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
11118
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11119
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11120
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11174
11121
  ] }) })
11175
11122
  ]
11176
11123
  }
11124
+ ) });
11125
+ };
11126
+ const GridInput = React.forwardRef(({ className, ...props }, ref) => {
11127
+ return /* @__PURE__ */ jsxRuntime.jsx(
11128
+ "input",
11129
+ {
11130
+ ref,
11131
+ ...props,
11132
+ autoComplete: "off",
11133
+ className: ui.clx(
11134
+ "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",
11135
+ className
11136
+ )
11137
+ }
11177
11138
  );
11139
+ });
11140
+ GridInput.displayName = "MetadataForm.GridInput";
11141
+ const PlaceholderInner = () => {
11142
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11143
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11144
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11145
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
11146
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
11147
+ ] }) })
11148
+ ] });
11178
11149
  };
11179
- const columnHelper = ui.createDataTableColumnHelper();
11180
- const useColumns = () => {
11181
- return React.useMemo(() => {
11150
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
11151
+ function getDefaultValues(metadata) {
11152
+ if (!metadata || !Object.keys(metadata).length) {
11182
11153
  return [
11183
- columnHelper.select(),
11184
- columnHelper.accessor("product.title", {
11185
- header: "Product",
11186
- cell: ({ row }) => {
11187
- var _a, _b, _c;
11188
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
11189
- /* @__PURE__ */ jsxRuntime.jsx(
11190
- Thumbnail,
11191
- {
11192
- thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
11193
- alt: (_b = row.original.product) == null ? void 0 : _b.title
11194
- }
11195
- ),
11196
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
11197
- ] });
11198
- },
11199
- enableSorting: true
11200
- }),
11201
- columnHelper.accessor("title", {
11202
- header: "Variant",
11203
- enableSorting: true
11204
- }),
11205
- columnHelper.accessor("sku", {
11206
- header: "SKU",
11207
- cell: ({ getValue }) => {
11208
- return getValue() ?? "-";
11209
- },
11210
- enableSorting: true
11211
- }),
11212
- columnHelper.accessor("updated_at", {
11213
- header: "Updated",
11214
- cell: ({ getValue }) => {
11215
- return /* @__PURE__ */ jsxRuntime.jsx(
11216
- ui.Tooltip,
11217
- {
11218
- content: getFullDate({ date: getValue(), includeTime: true }),
11219
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
11220
- }
11221
- );
11222
- },
11223
- enableSorting: true,
11224
- sortAscLabel: "Oldest first",
11225
- sortDescLabel: "Newest first"
11226
- }),
11227
- columnHelper.accessor("created_at", {
11228
- header: "Created",
11229
- cell: ({ getValue }) => {
11230
- return /* @__PURE__ */ jsxRuntime.jsx(
11231
- ui.Tooltip,
11232
- {
11233
- content: getFullDate({ date: getValue(), includeTime: true }),
11234
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
11235
- }
11236
- );
11237
- },
11238
- enableSorting: true,
11239
- sortAscLabel: "Oldest first",
11240
- sortDescLabel: "Newest first"
11241
- })
11154
+ {
11155
+ key: "",
11156
+ value: "",
11157
+ disabled: false
11158
+ }
11242
11159
  ];
11243
- }, []);
11244
- };
11245
- const schema = z.object({
11246
- notify: z.boolean()
11247
- });
11160
+ }
11161
+ return Object.entries(metadata).map(([key, value]) => {
11162
+ if (!EDITABLE_TYPES.includes(typeof value)) {
11163
+ return {
11164
+ key,
11165
+ value,
11166
+ disabled: true
11167
+ };
11168
+ }
11169
+ let stringValue = value;
11170
+ if (typeof value !== "string") {
11171
+ stringValue = JSON.stringify(value);
11172
+ }
11173
+ return {
11174
+ key,
11175
+ value: stringValue,
11176
+ original_key: key
11177
+ };
11178
+ });
11179
+ }
11180
+ function parseValues(values) {
11181
+ const metadata = values.metadata;
11182
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11183
+ if (isEmpty) {
11184
+ return null;
11185
+ }
11186
+ const update = {};
11187
+ metadata.forEach((field) => {
11188
+ let key = field.key;
11189
+ let value = field.value;
11190
+ const disabled = field.disabled;
11191
+ if (!key || !value) {
11192
+ return;
11193
+ }
11194
+ if (disabled) {
11195
+ update[key] = value;
11196
+ return;
11197
+ }
11198
+ key = key.trim();
11199
+ value = value.trim();
11200
+ if (value === "true") {
11201
+ update[key] = true;
11202
+ } else if (value === "false") {
11203
+ update[key] = false;
11204
+ } else {
11205
+ const parsedNumber = parseFloat(value);
11206
+ if (!isNaN(parsedNumber)) {
11207
+ update[key] = parsedNumber;
11208
+ } else {
11209
+ update[key] = value;
11210
+ }
11211
+ }
11212
+ });
11213
+ return update;
11214
+ }
11215
+ function getHasUneditableRows(metadata) {
11216
+ if (!metadata) {
11217
+ return false;
11218
+ }
11219
+ return Object.values(metadata).some(
11220
+ (value) => !EDITABLE_TYPES.includes(typeof value)
11221
+ );
11222
+ }
11248
11223
  const widgetModule = { widgets: [] };
11249
11224
  const routeModule = {
11250
11225
  routes: [
@@ -11263,40 +11238,40 @@ const routeModule = {
11263
11238
  path: "/draft-orders/:id",
11264
11239
  children: [
11265
11240
  {
11266
- Component: Email,
11267
- path: "/draft-orders/:id/email"
11241
+ Component: BillingAddress,
11242
+ path: "/draft-orders/:id/billing-address"
11268
11243
  },
11269
11244
  {
11270
11245
  Component: CustomItems,
11271
11246
  path: "/draft-orders/:id/custom-items"
11272
11247
  },
11273
11248
  {
11274
- Component: BillingAddress,
11275
- path: "/draft-orders/:id/billing-address"
11276
- },
11277
- {
11278
- Component: Metadata,
11279
- path: "/draft-orders/:id/metadata"
11249
+ Component: Email,
11250
+ path: "/draft-orders/:id/email"
11280
11251
  },
11281
11252
  {
11282
11253
  Component: Promotions,
11283
11254
  path: "/draft-orders/:id/promotions"
11284
11255
  },
11285
11256
  {
11286
- Component: SalesChannel,
11287
- path: "/draft-orders/:id/sales-channel"
11257
+ Component: Items,
11258
+ path: "/draft-orders/:id/items"
11288
11259
  },
11289
11260
  {
11290
- Component: ShippingAddress,
11291
- path: "/draft-orders/:id/shipping-address"
11261
+ Component: SalesChannel,
11262
+ path: "/draft-orders/:id/sales-channel"
11292
11263
  },
11293
11264
  {
11294
11265
  Component: Shipping,
11295
11266
  path: "/draft-orders/:id/shipping"
11296
11267
  },
11297
11268
  {
11298
- Component: Items,
11299
- path: "/draft-orders/:id/items"
11269
+ Component: ShippingAddress,
11270
+ path: "/draft-orders/:id/shipping-address"
11271
+ },
11272
+ {
11273
+ Component: Metadata,
11274
+ path: "/draft-orders/:id/metadata"
11300
11275
  }
11301
11276
  ]
11302
11277
  }