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