@medusajs/draft-order 2.11.3-preview-20251031120214 → 2.11.3-preview-20251031150158

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.
@@ -9586,6 +9586,74 @@ const CustomItemsForm = () => {
9586
9586
  const schema$5 = objectType({
9587
9587
  email: stringType().email()
9588
9588
  });
9589
+ const Email = () => {
9590
+ const { id } = useParams();
9591
+ const { order, isPending, isError, error } = useOrder(id, {
9592
+ fields: "+email"
9593
+ });
9594
+ if (isError) {
9595
+ throw error;
9596
+ }
9597
+ const isReady = !isPending && !!order;
9598
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9599
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
9600
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Email" }) }),
9601
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
9602
+ ] }),
9603
+ isReady && /* @__PURE__ */ jsx(EmailForm, { order })
9604
+ ] });
9605
+ };
9606
+ const EmailForm = ({ order }) => {
9607
+ const form = useForm({
9608
+ defaultValues: {
9609
+ email: order.email ?? ""
9610
+ },
9611
+ resolver: zodResolver(schema$4)
9612
+ });
9613
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9614
+ const { handleSuccess } = useRouteModal();
9615
+ const onSubmit = form.handleSubmit(async (data) => {
9616
+ await mutateAsync(
9617
+ { email: data.email },
9618
+ {
9619
+ onSuccess: () => {
9620
+ handleSuccess();
9621
+ },
9622
+ onError: (error) => {
9623
+ toast.error(error.message);
9624
+ }
9625
+ }
9626
+ );
9627
+ });
9628
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
9629
+ KeyboundForm,
9630
+ {
9631
+ className: "flex flex-1 flex-col overflow-hidden",
9632
+ onSubmit,
9633
+ children: [
9634
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(
9635
+ Form$2.Field,
9636
+ {
9637
+ control: form.control,
9638
+ name: "email",
9639
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
9640
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Email" }),
9641
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
9642
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
9643
+ ] })
9644
+ }
9645
+ ) }),
9646
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
9647
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9648
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
9649
+ ] }) })
9650
+ ]
9651
+ }
9652
+ ) });
9653
+ };
9654
+ const schema$4 = objectType({
9655
+ email: stringType().email()
9656
+ });
9589
9657
  const NumberInput = forwardRef(
9590
9658
  ({
9591
9659
  value,
@@ -10560,632 +10628,632 @@ const customItemSchema = objectType({
10560
10628
  quantity: numberType(),
10561
10629
  unit_price: unionType([numberType(), stringType()])
10562
10630
  });
10563
- const PROMOTION_QUERY_KEY = "promotions";
10564
- const promotionsQueryKeys = {
10565
- list: (query2) => [
10566
- PROMOTION_QUERY_KEY,
10567
- query2 ? query2 : void 0
10568
- ],
10569
- detail: (id, query2) => [
10570
- PROMOTION_QUERY_KEY,
10571
- id,
10572
- query2 ? query2 : void 0
10573
- ]
10574
- };
10575
- const usePromotions = (query2, options) => {
10576
- const { data, ...rest } = useQuery({
10577
- queryKey: promotionsQueryKeys.list(query2),
10578
- queryFn: async () => sdk.admin.promotion.list(query2),
10579
- ...options
10580
- });
10581
- return { ...data, ...rest };
10582
- };
10583
- const Promotions = () => {
10631
+ const InlineTip = forwardRef(
10632
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
10633
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10634
+ return /* @__PURE__ */ jsxs(
10635
+ "div",
10636
+ {
10637
+ ref,
10638
+ className: clx(
10639
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10640
+ className
10641
+ ),
10642
+ ...props,
10643
+ children: [
10644
+ /* @__PURE__ */ jsx(
10645
+ "div",
10646
+ {
10647
+ role: "presentation",
10648
+ className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10649
+ "bg-ui-tag-orange-icon": variant === "warning"
10650
+ })
10651
+ }
10652
+ ),
10653
+ /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
10654
+ /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10655
+ labelValue,
10656
+ ":"
10657
+ ] }),
10658
+ " ",
10659
+ children
10660
+ ] })
10661
+ ]
10662
+ }
10663
+ );
10664
+ }
10665
+ );
10666
+ InlineTip.displayName = "InlineTip";
10667
+ const MetadataFieldSchema = objectType({
10668
+ key: stringType(),
10669
+ disabled: booleanType().optional(),
10670
+ value: anyType()
10671
+ });
10672
+ const MetadataSchema = objectType({
10673
+ metadata: arrayType(MetadataFieldSchema)
10674
+ });
10675
+ const Metadata = () => {
10584
10676
  const { id } = useParams();
10585
- const {
10586
- order: preview,
10587
- isError: isPreviewError,
10588
- error: previewError
10589
- } = useOrderPreview(id, void 0);
10590
- useInitiateOrderEdit({ preview });
10591
- const { onCancel } = useCancelOrderEdit({ preview });
10592
- if (isPreviewError) {
10593
- throw previewError;
10677
+ const { order, isPending, isError, error } = useOrder(id, {
10678
+ fields: "metadata"
10679
+ });
10680
+ if (isError) {
10681
+ throw error;
10594
10682
  }
10595
- const isReady = !!preview;
10596
- return /* @__PURE__ */ jsxs(RouteDrawer, { onClose: onCancel, children: [
10597
- /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Promotions" }) }) }),
10598
- isReady && /* @__PURE__ */ jsx(PromotionForm, { preview })
10683
+ const isReady = !isPending && !!order;
10684
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
10685
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
10686
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
10687
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10688
+ ] }),
10689
+ !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10599
10690
  ] });
10600
10691
  };
10601
- const PromotionForm = ({ preview }) => {
10602
- const { items, shipping_methods } = preview;
10603
- const [isSubmitting, setIsSubmitting] = useState(false);
10604
- const [comboboxValue, setComboboxValue] = useState("");
10692
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10693
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10694
+ const MetadataForm = ({ orderId, metadata }) => {
10605
10695
  const { handleSuccess } = useRouteModal();
10606
- const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
10607
- const promoIds = getPromotionIds(items, shipping_methods);
10608
- const { promotions, isPending, isError, error } = usePromotions(
10609
- {
10610
- id: promoIds
10611
- },
10612
- {
10613
- enabled: !!promoIds.length
10614
- }
10615
- );
10616
- const comboboxData = useComboboxData({
10617
- queryKey: ["promotions", "combobox", promoIds],
10618
- queryFn: async (params) => {
10619
- return await sdk.admin.promotion.list({
10620
- ...params,
10621
- id: {
10622
- $nin: promoIds
10623
- }
10624
- });
10696
+ const hasUneditableRows = getHasUneditableRows(metadata);
10697
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10698
+ const form = useForm({
10699
+ defaultValues: {
10700
+ metadata: getDefaultValues(metadata)
10625
10701
  },
10626
- getOptions: (data) => {
10627
- return data.promotions.map((promotion) => ({
10628
- label: promotion.code,
10629
- value: promotion.code
10630
- }));
10631
- }
10702
+ resolver: zodResolver(MetadataSchema)
10632
10703
  });
10633
- const add = async (value) => {
10634
- if (!value) {
10635
- return;
10636
- }
10637
- addPromotions(
10704
+ const handleSubmit = form.handleSubmit(async (data) => {
10705
+ const parsedData = parseValues(data);
10706
+ await mutateAsync(
10638
10707
  {
10639
- promo_codes: [value]
10708
+ metadata: parsedData
10640
10709
  },
10641
10710
  {
10642
- onError: (e) => {
10643
- toast.error(e.message);
10644
- comboboxData.onSearchValueChange("");
10645
- setComboboxValue("");
10646
- },
10647
10711
  onSuccess: () => {
10648
- comboboxData.onSearchValueChange("");
10649
- setComboboxValue("");
10712
+ toast.success("Metadata updated");
10713
+ handleSuccess();
10714
+ },
10715
+ onError: (error) => {
10716
+ toast.error(error.message);
10650
10717
  }
10651
10718
  }
10652
10719
  );
10653
- };
10654
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10655
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
10656
- const onSubmit = async () => {
10657
- setIsSubmitting(true);
10658
- let requestSucceeded = false;
10659
- await requestOrderEdit(void 0, {
10660
- onError: (e) => {
10661
- toast.error(e.message);
10662
- },
10663
- onSuccess: () => {
10664
- requestSucceeded = true;
10665
- }
10666
- });
10667
- if (!requestSucceeded) {
10668
- setIsSubmitting(false);
10669
- return;
10720
+ });
10721
+ const { fields, insert, remove } = useFieldArray({
10722
+ control: form.control,
10723
+ name: "metadata"
10724
+ });
10725
+ function deleteRow(index) {
10726
+ remove(index);
10727
+ if (fields.length === 1) {
10728
+ insert(0, {
10729
+ key: "",
10730
+ value: "",
10731
+ disabled: false
10732
+ });
10670
10733
  }
10671
- await confirmOrderEdit(void 0, {
10672
- onError: (e) => {
10673
- toast.error(e.message);
10674
- },
10675
- onSuccess: () => {
10676
- handleSuccess();
10677
- },
10678
- onSettled: () => {
10679
- setIsSubmitting(false);
10680
- }
10734
+ }
10735
+ function insertRow(index, position) {
10736
+ insert(index + (position === "above" ? 0 : 1), {
10737
+ key: "",
10738
+ value: "",
10739
+ disabled: false
10681
10740
  });
10682
- };
10683
- if (isError) {
10684
- throw error;
10685
10741
  }
10686
- return /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
10687
- /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
10688
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
10689
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
10690
- /* @__PURE__ */ jsx(Label$1, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
10691
- /* @__PURE__ */ jsx(Hint$1, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
10742
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
10743
+ KeyboundForm,
10744
+ {
10745
+ onSubmit: handleSubmit,
10746
+ className: "flex flex-1 flex-col overflow-hidden",
10747
+ children: [
10748
+ /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10749
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10750
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10751
+ /* @__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" }) }),
10752
+ /* @__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" }) })
10753
+ ] }),
10754
+ fields.map((field, index) => {
10755
+ const isDisabled = field.disabled || false;
10756
+ let placeholder = "-";
10757
+ if (typeof field.value === "object") {
10758
+ placeholder = "{ ... }";
10759
+ }
10760
+ if (Array.isArray(field.value)) {
10761
+ placeholder = "[ ... ]";
10762
+ }
10763
+ return /* @__PURE__ */ jsx(
10764
+ ConditionalTooltip,
10765
+ {
10766
+ showTooltip: isDisabled,
10767
+ content: "This row is disabled because it contains non-primitive data.",
10768
+ children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
10769
+ /* @__PURE__ */ jsxs(
10770
+ "div",
10771
+ {
10772
+ className: clx("grid grid-cols-2 divide-x", {
10773
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
10774
+ }),
10775
+ children: [
10776
+ /* @__PURE__ */ jsx(
10777
+ Form$2.Field,
10778
+ {
10779
+ control: form.control,
10780
+ name: `metadata.${index}.key`,
10781
+ render: ({ field: field2 }) => {
10782
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10783
+ GridInput,
10784
+ {
10785
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
10786
+ ...field2,
10787
+ disabled: isDisabled,
10788
+ placeholder: "Key"
10789
+ }
10790
+ ) }) });
10791
+ }
10792
+ }
10793
+ ),
10794
+ /* @__PURE__ */ jsx(
10795
+ Form$2.Field,
10796
+ {
10797
+ control: form.control,
10798
+ name: `metadata.${index}.value`,
10799
+ render: ({ field: { value, ...field2 } }) => {
10800
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10801
+ GridInput,
10802
+ {
10803
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
10804
+ ...field2,
10805
+ value: isDisabled ? placeholder : value,
10806
+ disabled: isDisabled,
10807
+ placeholder: "Value"
10808
+ }
10809
+ ) }) });
10810
+ }
10811
+ }
10812
+ )
10813
+ ]
10814
+ }
10815
+ ),
10816
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10817
+ /* @__PURE__ */ jsx(
10818
+ DropdownMenu.Trigger,
10819
+ {
10820
+ className: clx(
10821
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
10822
+ {
10823
+ hidden: isDisabled
10824
+ }
10825
+ ),
10826
+ disabled: isDisabled,
10827
+ asChild: true,
10828
+ children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
10829
+ }
10830
+ ),
10831
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
10832
+ /* @__PURE__ */ jsxs(
10833
+ DropdownMenu.Item,
10834
+ {
10835
+ className: "gap-x-2",
10836
+ onClick: () => insertRow(index, "above"),
10837
+ children: [
10838
+ /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
10839
+ "Insert row above"
10840
+ ]
10841
+ }
10842
+ ),
10843
+ /* @__PURE__ */ jsxs(
10844
+ DropdownMenu.Item,
10845
+ {
10846
+ className: "gap-x-2",
10847
+ onClick: () => insertRow(index, "below"),
10848
+ children: [
10849
+ /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
10850
+ "Insert row below"
10851
+ ]
10852
+ }
10853
+ ),
10854
+ /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
10855
+ /* @__PURE__ */ jsxs(
10856
+ DropdownMenu.Item,
10857
+ {
10858
+ className: "gap-x-2",
10859
+ onClick: () => deleteRow(index),
10860
+ children: [
10861
+ /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
10862
+ "Delete row"
10863
+ ]
10864
+ }
10865
+ )
10866
+ ] })
10867
+ ] })
10868
+ ] })
10869
+ },
10870
+ field.id
10871
+ );
10872
+ })
10873
+ ] }),
10874
+ 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." })
10692
10875
  ] }),
10693
- /* @__PURE__ */ jsx(
10694
- Combobox,
10695
- {
10696
- id: "promotion-combobox",
10697
- "aria-describedby": "promotion-combobox-hint",
10698
- isFetchingNextPage: comboboxData.isFetchingNextPage,
10699
- fetchNextPage: comboboxData.fetchNextPage,
10700
- options: comboboxData.options,
10701
- onSearchValueChange: comboboxData.onSearchValueChange,
10702
- searchValue: comboboxData.searchValue,
10703
- disabled: comboboxData.disabled || isAddingPromotions,
10704
- onChange: add,
10705
- value: comboboxValue
10706
- }
10707
- )
10708
- ] }),
10709
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10710
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsx(
10711
- PromotionItem,
10712
- {
10713
- promotion,
10714
- orderId: preview.id,
10715
- isLoading: isPending
10716
- },
10717
- promotion.id
10718
- )) })
10719
- ] }) }),
10720
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
10721
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10722
- /* @__PURE__ */ jsx(
10723
- Button,
10724
- {
10725
- size: "small",
10726
- type: "submit",
10727
- isLoading: isSubmitting || isAddingPromotions,
10728
- children: "Save"
10729
- }
10876
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10877
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10878
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10879
+ ] }) })
10880
+ ]
10881
+ }
10882
+ ) });
10883
+ };
10884
+ const GridInput = forwardRef(({ className, ...props }, ref) => {
10885
+ return /* @__PURE__ */ jsx(
10886
+ "input",
10887
+ {
10888
+ ref,
10889
+ ...props,
10890
+ autoComplete: "off",
10891
+ className: clx(
10892
+ "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",
10893
+ className
10730
10894
  )
10895
+ }
10896
+ );
10897
+ });
10898
+ GridInput.displayName = "MetadataForm.GridInput";
10899
+ const PlaceholderInner = () => {
10900
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
10901
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
10902
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10903
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
10904
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
10731
10905
  ] }) })
10732
10906
  ] });
10733
10907
  };
10734
- const PromotionItem = ({
10735
- promotion,
10736
- orderId,
10737
- isLoading
10738
- }) => {
10739
- var _a;
10740
- const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
10741
- const onRemove = async () => {
10742
- removePromotions(
10743
- {
10744
- promo_codes: [promotion.code]
10745
- },
10908
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
10909
+ function getDefaultValues(metadata) {
10910
+ if (!metadata || !Object.keys(metadata).length) {
10911
+ return [
10746
10912
  {
10747
- onError: (e) => {
10748
- toast.error(e.message);
10749
- }
10913
+ key: "",
10914
+ value: "",
10915
+ disabled: false
10750
10916
  }
10751
- );
10752
- };
10753
- const displayValue = getDisplayValue(promotion);
10754
- return /* @__PURE__ */ jsxs(
10755
- "div",
10756
- {
10757
- className: clx(
10758
- "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
10759
- {
10760
- "animate-pulse": isLoading
10761
- }
10762
- ),
10763
- children: [
10764
- /* @__PURE__ */ jsxs("div", { children: [
10765
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
10766
- /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
10767
- displayValue && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
10768
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: displayValue }),
10769
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: "·" })
10770
- ] }),
10771
- /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
10772
- ] })
10773
- ] }),
10774
- /* @__PURE__ */ jsx(
10775
- IconButton,
10776
- {
10777
- size: "small",
10778
- type: "button",
10779
- variant: "transparent",
10780
- onClick: onRemove,
10781
- isLoading: isPending || isLoading,
10782
- children: /* @__PURE__ */ jsx(XMark, {})
10783
- }
10784
- )
10785
- ]
10786
- },
10787
- promotion.id
10788
- );
10789
- };
10790
- function getDisplayValue(promotion) {
10791
- var _a, _b, _c, _d;
10792
- const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
10793
- if (!value) {
10794
- return null;
10917
+ ];
10795
10918
  }
10796
- if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
10797
- const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
10798
- if (!currency) {
10799
- return null;
10919
+ return Object.entries(metadata).map(([key, value]) => {
10920
+ if (!EDITABLE_TYPES.includes(typeof value)) {
10921
+ return {
10922
+ key,
10923
+ value,
10924
+ disabled: true
10925
+ };
10800
10926
  }
10801
- return getLocaleAmount(value, currency);
10802
- } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
10803
- return formatPercentage(value);
10804
- }
10805
- return null;
10927
+ let stringValue = value;
10928
+ if (typeof value !== "string") {
10929
+ stringValue = JSON.stringify(value);
10930
+ }
10931
+ return {
10932
+ key,
10933
+ value: stringValue,
10934
+ original_key: key
10935
+ };
10936
+ });
10806
10937
  }
10807
- const formatter = new Intl.NumberFormat([], {
10808
- style: "percent",
10809
- minimumFractionDigits: 2
10810
- });
10811
- const formatPercentage = (value, isPercentageValue = false) => {
10812
- let val = value || 0;
10813
- if (!isPercentageValue) {
10814
- val = val / 100;
10938
+ function parseValues(values) {
10939
+ const metadata = values.metadata;
10940
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
10941
+ if (isEmpty) {
10942
+ return null;
10815
10943
  }
10816
- return formatter.format(val);
10817
- };
10818
- function getPromotionIds(items, shippingMethods) {
10819
- const promotionIds = /* @__PURE__ */ new Set();
10820
- for (const item of items) {
10821
- if (item.adjustments) {
10822
- for (const adjustment of item.adjustments) {
10823
- if (adjustment.promotion_id) {
10824
- promotionIds.add(adjustment.promotion_id);
10825
- }
10826
- }
10944
+ const update = {};
10945
+ metadata.forEach((field) => {
10946
+ let key = field.key;
10947
+ let value = field.value;
10948
+ const disabled = field.disabled;
10949
+ if (!key || !value) {
10950
+ return;
10827
10951
  }
10828
- }
10829
- for (const shippingMethod of shippingMethods) {
10830
- if (shippingMethod.adjustments) {
10831
- for (const adjustment of shippingMethod.adjustments) {
10832
- if (adjustment.promotion_id) {
10833
- promotionIds.add(adjustment.promotion_id);
10834
- }
10952
+ if (disabled) {
10953
+ update[key] = value;
10954
+ return;
10955
+ }
10956
+ key = key.trim();
10957
+ value = value.trim();
10958
+ if (value === "true") {
10959
+ update[key] = true;
10960
+ } else if (value === "false") {
10961
+ update[key] = false;
10962
+ } else {
10963
+ const parsedNumber = parseFloat(value);
10964
+ if (!isNaN(parsedNumber)) {
10965
+ update[key] = parsedNumber;
10966
+ } else {
10967
+ update[key] = value;
10835
10968
  }
10836
10969
  }
10837
- }
10838
- return Array.from(promotionIds);
10970
+ });
10971
+ return update;
10839
10972
  }
10840
- const InlineTip = forwardRef(
10841
- ({ variant = "tip", label, className, children, ...props }, ref) => {
10842
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10843
- return /* @__PURE__ */ jsxs(
10844
- "div",
10845
- {
10846
- ref,
10847
- className: clx(
10848
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10849
- className
10850
- ),
10851
- ...props,
10852
- children: [
10853
- /* @__PURE__ */ jsx(
10854
- "div",
10855
- {
10856
- role: "presentation",
10857
- className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10858
- "bg-ui-tag-orange-icon": variant === "warning"
10859
- })
10860
- }
10861
- ),
10862
- /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
10863
- /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10864
- labelValue,
10865
- ":"
10866
- ] }),
10867
- " ",
10868
- children
10869
- ] })
10870
- ]
10871
- }
10872
- );
10973
+ function getHasUneditableRows(metadata) {
10974
+ if (!metadata) {
10975
+ return false;
10873
10976
  }
10874
- );
10875
- InlineTip.displayName = "InlineTip";
10876
- const MetadataFieldSchema = objectType({
10877
- key: stringType(),
10878
- disabled: booleanType().optional(),
10879
- value: anyType()
10880
- });
10881
- const MetadataSchema = objectType({
10882
- metadata: arrayType(MetadataFieldSchema)
10883
- });
10884
- const Metadata = () => {
10885
- const { id } = useParams();
10886
- const { order, isPending, isError, error } = useOrder(id, {
10887
- fields: "metadata"
10977
+ return Object.values(metadata).some(
10978
+ (value) => !EDITABLE_TYPES.includes(typeof value)
10979
+ );
10980
+ }
10981
+ const PROMOTION_QUERY_KEY = "promotions";
10982
+ const promotionsQueryKeys = {
10983
+ list: (query2) => [
10984
+ PROMOTION_QUERY_KEY,
10985
+ query2 ? query2 : void 0
10986
+ ],
10987
+ detail: (id, query2) => [
10988
+ PROMOTION_QUERY_KEY,
10989
+ id,
10990
+ query2 ? query2 : void 0
10991
+ ]
10992
+ };
10993
+ const usePromotions = (query2, options) => {
10994
+ const { data, ...rest } = useQuery({
10995
+ queryKey: promotionsQueryKeys.list(query2),
10996
+ queryFn: async () => sdk.admin.promotion.list(query2),
10997
+ ...options
10888
10998
  });
10889
- if (isError) {
10890
- throw error;
10999
+ return { ...data, ...rest };
11000
+ };
11001
+ const Promotions = () => {
11002
+ const { id } = useParams();
11003
+ const {
11004
+ order: preview,
11005
+ isError: isPreviewError,
11006
+ error: previewError
11007
+ } = useOrderPreview(id, void 0);
11008
+ useInitiateOrderEdit({ preview });
11009
+ const { onCancel } = useCancelOrderEdit({ preview });
11010
+ if (isPreviewError) {
11011
+ throw previewError;
10891
11012
  }
10892
- const isReady = !isPending && !!order;
10893
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
10894
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
10895
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
10896
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10897
- ] }),
10898
- !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
11013
+ const isReady = !!preview;
11014
+ return /* @__PURE__ */ jsxs(RouteDrawer, { onClose: onCancel, children: [
11015
+ /* @__PURE__ */ jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Promotions" }) }) }),
11016
+ isReady && /* @__PURE__ */ jsx(PromotionForm, { preview })
10899
11017
  ] });
10900
11018
  };
10901
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10902
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10903
- const MetadataForm = ({ orderId, metadata }) => {
11019
+ const PromotionForm = ({ preview }) => {
11020
+ const { items, shipping_methods } = preview;
11021
+ const [isSubmitting, setIsSubmitting] = useState(false);
11022
+ const [comboboxValue, setComboboxValue] = useState("");
10904
11023
  const { handleSuccess } = useRouteModal();
10905
- const hasUneditableRows = getHasUneditableRows(metadata);
10906
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10907
- const form = useForm({
10908
- defaultValues: {
10909
- metadata: getDefaultValues(metadata)
11024
+ const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
11025
+ const promoIds = getPromotionIds(items, shipping_methods);
11026
+ const { promotions, isPending, isError, error } = usePromotions(
11027
+ {
11028
+ id: promoIds
10910
11029
  },
10911
- resolver: zodResolver(MetadataSchema)
11030
+ {
11031
+ enabled: !!promoIds.length
11032
+ }
11033
+ );
11034
+ const comboboxData = useComboboxData({
11035
+ queryKey: ["promotions", "combobox", promoIds],
11036
+ queryFn: async (params) => {
11037
+ return await sdk.admin.promotion.list({
11038
+ ...params,
11039
+ id: {
11040
+ $nin: promoIds
11041
+ }
11042
+ });
11043
+ },
11044
+ getOptions: (data) => {
11045
+ return data.promotions.map((promotion) => ({
11046
+ label: promotion.code,
11047
+ value: promotion.code
11048
+ }));
11049
+ }
10912
11050
  });
10913
- const handleSubmit = form.handleSubmit(async (data) => {
10914
- const parsedData = parseValues(data);
10915
- await mutateAsync(
11051
+ const add = async (value) => {
11052
+ if (!value) {
11053
+ return;
11054
+ }
11055
+ addPromotions(
10916
11056
  {
10917
- metadata: parsedData
11057
+ promo_codes: [value]
10918
11058
  },
10919
11059
  {
10920
- onSuccess: () => {
10921
- toast.success("Metadata updated");
10922
- handleSuccess();
11060
+ onError: (e) => {
11061
+ toast.error(e.message);
11062
+ comboboxData.onSearchValueChange("");
11063
+ setComboboxValue("");
10923
11064
  },
10924
- onError: (error) => {
10925
- toast.error(error.message);
11065
+ onSuccess: () => {
11066
+ comboboxData.onSearchValueChange("");
11067
+ setComboboxValue("");
10926
11068
  }
10927
11069
  }
10928
11070
  );
10929
- });
10930
- const { fields, insert, remove } = useFieldArray({
10931
- control: form.control,
10932
- name: "metadata"
10933
- });
10934
- function deleteRow(index) {
10935
- remove(index);
10936
- if (fields.length === 1) {
10937
- insert(0, {
10938
- key: "",
10939
- value: "",
10940
- disabled: false
10941
- });
11071
+ };
11072
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11073
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
11074
+ const onSubmit = async () => {
11075
+ setIsSubmitting(true);
11076
+ let requestSucceeded = false;
11077
+ await requestOrderEdit(void 0, {
11078
+ onError: (e) => {
11079
+ toast.error(e.message);
11080
+ },
11081
+ onSuccess: () => {
11082
+ requestSucceeded = true;
11083
+ }
11084
+ });
11085
+ if (!requestSucceeded) {
11086
+ setIsSubmitting(false);
11087
+ return;
10942
11088
  }
10943
- }
10944
- function insertRow(index, position) {
10945
- insert(index + (position === "above" ? 0 : 1), {
10946
- key: "",
10947
- value: "",
10948
- disabled: false
11089
+ await confirmOrderEdit(void 0, {
11090
+ onError: (e) => {
11091
+ toast.error(e.message);
11092
+ },
11093
+ onSuccess: () => {
11094
+ handleSuccess();
11095
+ },
11096
+ onSettled: () => {
11097
+ setIsSubmitting(false);
11098
+ }
10949
11099
  });
11100
+ };
11101
+ if (isError) {
11102
+ throw error;
10950
11103
  }
10951
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
10952
- KeyboundForm,
11104
+ return /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
11105
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
11106
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
11107
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
11108
+ /* @__PURE__ */ jsx(Label$1, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
11109
+ /* @__PURE__ */ jsx(Hint$1, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
11110
+ ] }),
11111
+ /* @__PURE__ */ jsx(
11112
+ Combobox,
11113
+ {
11114
+ id: "promotion-combobox",
11115
+ "aria-describedby": "promotion-combobox-hint",
11116
+ isFetchingNextPage: comboboxData.isFetchingNextPage,
11117
+ fetchNextPage: comboboxData.fetchNextPage,
11118
+ options: comboboxData.options,
11119
+ onSearchValueChange: comboboxData.onSearchValueChange,
11120
+ searchValue: comboboxData.searchValue,
11121
+ disabled: comboboxData.disabled || isAddingPromotions,
11122
+ onChange: add,
11123
+ value: comboboxValue
11124
+ }
11125
+ )
11126
+ ] }),
11127
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11128
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsx(
11129
+ PromotionItem,
11130
+ {
11131
+ promotion,
11132
+ orderId: preview.id,
11133
+ isLoading: isPending
11134
+ },
11135
+ promotion.id
11136
+ )) })
11137
+ ] }) }),
11138
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
11139
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11140
+ /* @__PURE__ */ jsx(
11141
+ Button,
11142
+ {
11143
+ size: "small",
11144
+ type: "submit",
11145
+ isLoading: isSubmitting || isAddingPromotions,
11146
+ children: "Save"
11147
+ }
11148
+ )
11149
+ ] }) })
11150
+ ] });
11151
+ };
11152
+ const PromotionItem = ({
11153
+ promotion,
11154
+ orderId,
11155
+ isLoading
11156
+ }) => {
11157
+ var _a;
11158
+ const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
11159
+ const onRemove = async () => {
11160
+ removePromotions(
11161
+ {
11162
+ promo_codes: [promotion.code]
11163
+ },
11164
+ {
11165
+ onError: (e) => {
11166
+ toast.error(e.message);
11167
+ }
11168
+ }
11169
+ );
11170
+ };
11171
+ const displayValue = getDisplayValue(promotion);
11172
+ return /* @__PURE__ */ jsxs(
11173
+ "div",
10953
11174
  {
10954
- onSubmit: handleSubmit,
10955
- className: "flex flex-1 flex-col overflow-hidden",
11175
+ className: clx(
11176
+ "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
11177
+ {
11178
+ "animate-pulse": isLoading
11179
+ }
11180
+ ),
10956
11181
  children: [
10957
- /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10958
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10959
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10960
- /* @__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" }) }),
10961
- /* @__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" }) })
11182
+ /* @__PURE__ */ jsxs("div", { children: [
11183
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11184
+ /* @__PURE__ */ jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
11185
+ displayValue && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
11186
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: displayValue }),
11187
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", children: "·" })
10962
11188
  ] }),
10963
- fields.map((field, index) => {
10964
- const isDisabled = field.disabled || false;
10965
- let placeholder = "-";
10966
- if (typeof field.value === "object") {
10967
- placeholder = "{ ... }";
10968
- }
10969
- if (Array.isArray(field.value)) {
10970
- placeholder = "[ ... ]";
10971
- }
10972
- return /* @__PURE__ */ jsx(
10973
- ConditionalTooltip,
10974
- {
10975
- showTooltip: isDisabled,
10976
- content: "This row is disabled because it contains non-primitive data.",
10977
- children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
10978
- /* @__PURE__ */ jsxs(
10979
- "div",
10980
- {
10981
- className: clx("grid grid-cols-2 divide-x", {
10982
- "overflow-hidden rounded-b-lg": index === fields.length - 1
10983
- }),
10984
- children: [
10985
- /* @__PURE__ */ jsx(
10986
- Form$2.Field,
10987
- {
10988
- control: form.control,
10989
- name: `metadata.${index}.key`,
10990
- render: ({ field: field2 }) => {
10991
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10992
- GridInput,
10993
- {
10994
- "aria-labelledby": METADATA_KEY_LABEL_ID,
10995
- ...field2,
10996
- disabled: isDisabled,
10997
- placeholder: "Key"
10998
- }
10999
- ) }) });
11000
- }
11001
- }
11002
- ),
11003
- /* @__PURE__ */ jsx(
11004
- Form$2.Field,
11005
- {
11006
- control: form.control,
11007
- name: `metadata.${index}.value`,
11008
- render: ({ field: { value, ...field2 } }) => {
11009
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11010
- GridInput,
11011
- {
11012
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
11013
- ...field2,
11014
- value: isDisabled ? placeholder : value,
11015
- disabled: isDisabled,
11016
- placeholder: "Value"
11017
- }
11018
- ) }) });
11019
- }
11020
- }
11021
- )
11022
- ]
11023
- }
11024
- ),
11025
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
11026
- /* @__PURE__ */ jsx(
11027
- DropdownMenu.Trigger,
11028
- {
11029
- className: clx(
11030
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11031
- {
11032
- hidden: isDisabled
11033
- }
11034
- ),
11035
- disabled: isDisabled,
11036
- asChild: true,
11037
- children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
11038
- }
11039
- ),
11040
- /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
11041
- /* @__PURE__ */ jsxs(
11042
- DropdownMenu.Item,
11043
- {
11044
- className: "gap-x-2",
11045
- onClick: () => insertRow(index, "above"),
11046
- children: [
11047
- /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
11048
- "Insert row above"
11049
- ]
11050
- }
11051
- ),
11052
- /* @__PURE__ */ jsxs(
11053
- DropdownMenu.Item,
11054
- {
11055
- className: "gap-x-2",
11056
- onClick: () => insertRow(index, "below"),
11057
- children: [
11058
- /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
11059
- "Insert row below"
11060
- ]
11061
- }
11062
- ),
11063
- /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
11064
- /* @__PURE__ */ jsxs(
11065
- DropdownMenu.Item,
11066
- {
11067
- className: "gap-x-2",
11068
- onClick: () => deleteRow(index),
11069
- children: [
11070
- /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
11071
- "Delete row"
11072
- ]
11073
- }
11074
- )
11075
- ] })
11076
- ] })
11077
- ] })
11078
- },
11079
- field.id
11080
- );
11081
- })
11082
- ] }),
11083
- 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." })
11189
+ /* @__PURE__ */ jsx(Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11190
+ ] })
11084
11191
  ] }),
11085
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11086
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11087
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11088
- ] }) })
11192
+ /* @__PURE__ */ jsx(
11193
+ IconButton,
11194
+ {
11195
+ size: "small",
11196
+ type: "button",
11197
+ variant: "transparent",
11198
+ onClick: onRemove,
11199
+ isLoading: isPending || isLoading,
11200
+ children: /* @__PURE__ */ jsx(XMark, {})
11201
+ }
11202
+ )
11089
11203
  ]
11090
- }
11091
- ) });
11092
- };
11093
- const GridInput = forwardRef(({ className, ...props }, ref) => {
11094
- return /* @__PURE__ */ jsx(
11095
- "input",
11096
- {
11097
- ref,
11098
- ...props,
11099
- autoComplete: "off",
11100
- className: clx(
11101
- "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",
11102
- className
11103
- )
11104
- }
11204
+ },
11205
+ promotion.id
11105
11206
  );
11106
- });
11107
- GridInput.displayName = "MetadataForm.GridInput";
11108
- const PlaceholderInner = () => {
11109
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11110
- /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11111
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11112
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
11113
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
11114
- ] }) })
11115
- ] });
11116
11207
  };
11117
- const EDITABLE_TYPES = ["string", "number", "boolean"];
11118
- function getDefaultValues(metadata) {
11119
- if (!metadata || !Object.keys(metadata).length) {
11120
- return [
11121
- {
11122
- key: "",
11123
- value: "",
11124
- disabled: false
11125
- }
11126
- ];
11208
+ function getDisplayValue(promotion) {
11209
+ var _a, _b, _c, _d;
11210
+ const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11211
+ if (!value) {
11212
+ return null;
11127
11213
  }
11128
- return Object.entries(metadata).map(([key, value]) => {
11129
- if (!EDITABLE_TYPES.includes(typeof value)) {
11130
- return {
11131
- key,
11132
- value,
11133
- disabled: true
11134
- };
11135
- }
11136
- let stringValue = value;
11137
- if (typeof value !== "string") {
11138
- stringValue = JSON.stringify(value);
11214
+ if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11215
+ const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11216
+ if (!currency) {
11217
+ return null;
11139
11218
  }
11140
- return {
11141
- key,
11142
- value: stringValue,
11143
- original_key: key
11144
- };
11145
- });
11219
+ return getLocaleAmount(value, currency);
11220
+ } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11221
+ return formatPercentage(value);
11222
+ }
11223
+ return null;
11146
11224
  }
11147
- function parseValues(values) {
11148
- const metadata = values.metadata;
11149
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11150
- if (isEmpty) {
11151
- return null;
11225
+ const formatter = new Intl.NumberFormat([], {
11226
+ style: "percent",
11227
+ minimumFractionDigits: 2
11228
+ });
11229
+ const formatPercentage = (value, isPercentageValue = false) => {
11230
+ let val = value || 0;
11231
+ if (!isPercentageValue) {
11232
+ val = val / 100;
11152
11233
  }
11153
- const update = {};
11154
- metadata.forEach((field) => {
11155
- let key = field.key;
11156
- let value = field.value;
11157
- const disabled = field.disabled;
11158
- if (!key || !value) {
11159
- return;
11160
- }
11161
- if (disabled) {
11162
- update[key] = value;
11163
- return;
11234
+ return formatter.format(val);
11235
+ };
11236
+ function getPromotionIds(items, shippingMethods) {
11237
+ const promotionIds = /* @__PURE__ */ new Set();
11238
+ for (const item of items) {
11239
+ if (item.adjustments) {
11240
+ for (const adjustment of item.adjustments) {
11241
+ if (adjustment.promotion_id) {
11242
+ promotionIds.add(adjustment.promotion_id);
11243
+ }
11244
+ }
11164
11245
  }
11165
- key = key.trim();
11166
- value = value.trim();
11167
- if (value === "true") {
11168
- update[key] = true;
11169
- } else if (value === "false") {
11170
- update[key] = false;
11171
- } else {
11172
- const parsedNumber = parseFloat(value);
11173
- if (!isNaN(parsedNumber)) {
11174
- update[key] = parsedNumber;
11175
- } else {
11176
- update[key] = value;
11246
+ }
11247
+ for (const shippingMethod of shippingMethods) {
11248
+ if (shippingMethod.adjustments) {
11249
+ for (const adjustment of shippingMethod.adjustments) {
11250
+ if (adjustment.promotion_id) {
11251
+ promotionIds.add(adjustment.promotion_id);
11252
+ }
11177
11253
  }
11178
11254
  }
11179
- });
11180
- return update;
11181
- }
11182
- function getHasUneditableRows(metadata) {
11183
- if (!metadata) {
11184
- return false;
11185
11255
  }
11186
- return Object.values(metadata).some(
11187
- (value) => !EDITABLE_TYPES.includes(typeof value)
11188
- );
11256
+ return Array.from(promotionIds);
11189
11257
  }
11190
11258
  const SalesChannel = () => {
11191
11259
  const { id } = useParams();
@@ -11215,7 +11283,7 @@ const SalesChannelForm = ({ order }) => {
11215
11283
  defaultValues: {
11216
11284
  sales_channel_id: order.sales_channel_id || ""
11217
11285
  },
11218
- resolver: zodResolver(schema$4)
11286
+ resolver: zodResolver(schema$3)
11219
11287
  });
11220
11288
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11221
11289
  const { handleSuccess } = useRouteModal();
@@ -11290,78 +11358,281 @@ const SalesChannelField = ({ control, order }) => {
11290
11358
  }
11291
11359
  );
11292
11360
  };
11293
- const schema$4 = objectType({
11361
+ const schema$3 = objectType({
11294
11362
  sales_channel_id: stringType().min(1)
11295
11363
  });
11296
- const STACKED_FOCUS_MODAL_ID = "shipping-form";
11297
- const Shipping = () => {
11298
- var _a;
11364
+ const ShippingAddress = () => {
11299
11365
  const { id } = useParams();
11300
11366
  const { order, isPending, isError, error } = useOrder(id, {
11301
- fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
11367
+ fields: "+shipping_address"
11302
11368
  });
11303
- const {
11304
- order: preview,
11305
- isPending: isPreviewPending,
11306
- isError: isPreviewError,
11307
- error: previewError
11308
- } = useOrderPreview(id);
11309
- useInitiateOrderEdit({ preview });
11310
- const { onCancel } = useCancelOrderEdit({ preview });
11311
11369
  if (isError) {
11312
11370
  throw error;
11313
11371
  }
11314
- if (isPreviewError) {
11315
- throw previewError;
11316
- }
11317
- const orderHasItems = (((_a = order == null ? void 0 : order.items) == null ? void 0 : _a.length) || 0) > 0;
11318
- const isReady = preview && !isPreviewPending && order && !isPending;
11319
- return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
11320
- /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
11321
- /* @__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: [
11322
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Shipping" }) }),
11323
- /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "This draft order currently has no items. Add items to the order before adding shipping." }) })
11324
- ] }) }) }),
11325
- /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }) })
11326
- ] }) : isReady ? /* @__PURE__ */ jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxs("div", { children: [
11327
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
11328
- /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
11329
- ] }) });
11372
+ const isReady = !isPending && !!order;
11373
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
11374
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
11375
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Shipping Address" }) }),
11376
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
11377
+ ] }),
11378
+ isReady && /* @__PURE__ */ jsx(ShippingAddressForm, { order })
11379
+ ] });
11330
11380
  };
11331
- const ShippingForm = ({ preview, order }) => {
11332
- var _a;
11333
- const { setIsOpen } = useStackedModal();
11334
- const [isSubmitting, setIsSubmitting] = useState(false);
11335
- const [data, setData] = useState(null);
11336
- const appliedShippingOptionIds = (_a = preview.shipping_methods) == null ? void 0 : _a.map((method) => method.shipping_option_id).filter(Boolean);
11337
- const { shipping_options } = useShippingOptions(
11338
- {
11339
- id: appliedShippingOptionIds,
11340
- fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
11381
+ const ShippingAddressForm = ({ order }) => {
11382
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
11383
+ const form = useForm({
11384
+ defaultValues: {
11385
+ first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
11386
+ last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
11387
+ company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
11388
+ address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
11389
+ address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
11390
+ city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
11391
+ province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
11392
+ country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
11393
+ postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
11394
+ phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
11341
11395
  },
11342
- {
11343
- enabled: appliedShippingOptionIds.length > 0
11344
- }
11345
- );
11346
- const uniqueShippingProfiles = useMemo(() => {
11347
- const profiles = /* @__PURE__ */ new Map();
11348
- getUniqueShippingProfiles(order.items).forEach((profile) => {
11349
- profiles.set(profile.id, profile);
11350
- });
11351
- shipping_options == null ? void 0 : shipping_options.forEach((option) => {
11352
- profiles.set(option.shipping_profile_id, option.shipping_profile);
11353
- });
11354
- return Array.from(profiles.values());
11355
- }, [order.items, shipping_options]);
11396
+ resolver: zodResolver(schema$2)
11397
+ });
11398
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11356
11399
  const { handleSuccess } = useRouteModal();
11357
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11358
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
11359
- const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
11360
- const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
11361
- const onSubmit = async () => {
11362
- setIsSubmitting(true);
11363
- let requestSucceeded = false;
11364
- await requestOrderEdit(void 0, {
11400
+ const onSubmit = form.handleSubmit(async (data) => {
11401
+ await mutateAsync(
11402
+ {
11403
+ shipping_address: {
11404
+ first_name: data.first_name,
11405
+ last_name: data.last_name,
11406
+ company: data.company,
11407
+ address_1: data.address_1,
11408
+ address_2: data.address_2,
11409
+ city: data.city,
11410
+ province: data.province,
11411
+ country_code: data.country_code,
11412
+ postal_code: data.postal_code,
11413
+ phone: data.phone
11414
+ }
11415
+ },
11416
+ {
11417
+ onSuccess: () => {
11418
+ handleSuccess();
11419
+ },
11420
+ onError: (error) => {
11421
+ toast.error(error.message);
11422
+ }
11423
+ }
11424
+ );
11425
+ });
11426
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
11427
+ KeyboundForm,
11428
+ {
11429
+ className: "flex flex-1 flex-col overflow-hidden",
11430
+ onSubmit,
11431
+ children: [
11432
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-4", children: [
11433
+ /* @__PURE__ */ jsx(
11434
+ Form$2.Field,
11435
+ {
11436
+ control: form.control,
11437
+ name: "country_code",
11438
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11439
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
11440
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
11441
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11442
+ ] })
11443
+ }
11444
+ ),
11445
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11446
+ /* @__PURE__ */ jsx(
11447
+ Form$2.Field,
11448
+ {
11449
+ control: form.control,
11450
+ name: "first_name",
11451
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11452
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
11453
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11454
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11455
+ ] })
11456
+ }
11457
+ ),
11458
+ /* @__PURE__ */ jsx(
11459
+ Form$2.Field,
11460
+ {
11461
+ control: form.control,
11462
+ name: "last_name",
11463
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11464
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
11465
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11466
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11467
+ ] })
11468
+ }
11469
+ )
11470
+ ] }),
11471
+ /* @__PURE__ */ jsx(
11472
+ Form$2.Field,
11473
+ {
11474
+ control: form.control,
11475
+ name: "company",
11476
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11477
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
11478
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11479
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11480
+ ] })
11481
+ }
11482
+ ),
11483
+ /* @__PURE__ */ jsx(
11484
+ Form$2.Field,
11485
+ {
11486
+ control: form.control,
11487
+ name: "address_1",
11488
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11489
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
11490
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11491
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11492
+ ] })
11493
+ }
11494
+ ),
11495
+ /* @__PURE__ */ jsx(
11496
+ Form$2.Field,
11497
+ {
11498
+ control: form.control,
11499
+ name: "address_2",
11500
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11501
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
11502
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11503
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11504
+ ] })
11505
+ }
11506
+ ),
11507
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11508
+ /* @__PURE__ */ jsx(
11509
+ Form$2.Field,
11510
+ {
11511
+ control: form.control,
11512
+ name: "postal_code",
11513
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11514
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
11515
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11516
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11517
+ ] })
11518
+ }
11519
+ ),
11520
+ /* @__PURE__ */ jsx(
11521
+ Form$2.Field,
11522
+ {
11523
+ control: form.control,
11524
+ name: "city",
11525
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11526
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
11527
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11528
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11529
+ ] })
11530
+ }
11531
+ )
11532
+ ] }),
11533
+ /* @__PURE__ */ jsx(
11534
+ Form$2.Field,
11535
+ {
11536
+ control: form.control,
11537
+ name: "province",
11538
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11539
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
11540
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11541
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11542
+ ] })
11543
+ }
11544
+ ),
11545
+ /* @__PURE__ */ jsx(
11546
+ Form$2.Field,
11547
+ {
11548
+ control: form.control,
11549
+ name: "phone",
11550
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
11551
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
11552
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11553
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11554
+ ] })
11555
+ }
11556
+ )
11557
+ ] }) }),
11558
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
11559
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11560
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11561
+ ] }) })
11562
+ ]
11563
+ }
11564
+ ) });
11565
+ };
11566
+ const schema$2 = addressSchema;
11567
+ const STACKED_FOCUS_MODAL_ID = "shipping-form";
11568
+ const Shipping = () => {
11569
+ var _a;
11570
+ const { id } = useParams();
11571
+ const { order, isPending, isError, error } = useOrder(id, {
11572
+ fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
11573
+ });
11574
+ const {
11575
+ order: preview,
11576
+ isPending: isPreviewPending,
11577
+ isError: isPreviewError,
11578
+ error: previewError
11579
+ } = useOrderPreview(id);
11580
+ useInitiateOrderEdit({ preview });
11581
+ const { onCancel } = useCancelOrderEdit({ preview });
11582
+ if (isError) {
11583
+ throw error;
11584
+ }
11585
+ if (isPreviewError) {
11586
+ throw previewError;
11587
+ }
11588
+ const orderHasItems = (((_a = order == null ? void 0 : order.items) == null ? void 0 : _a.length) || 0) > 0;
11589
+ const isReady = preview && !isPreviewPending && order && !isPending;
11590
+ return /* @__PURE__ */ jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
11591
+ /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
11592
+ /* @__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: [
11593
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Shipping" }) }),
11594
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "This draft order currently has no items. Add items to the order before adding shipping." }) })
11595
+ ] }) }) }),
11596
+ /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }) })
11597
+ ] }) : isReady ? /* @__PURE__ */ jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxs("div", { children: [
11598
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
11599
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
11600
+ ] }) });
11601
+ };
11602
+ const ShippingForm = ({ preview, order }) => {
11603
+ var _a;
11604
+ const { setIsOpen } = useStackedModal();
11605
+ const [isSubmitting, setIsSubmitting] = useState(false);
11606
+ const [data, setData] = useState(null);
11607
+ const appliedShippingOptionIds = (_a = preview.shipping_methods) == null ? void 0 : _a.map((method) => method.shipping_option_id).filter(Boolean);
11608
+ const { shipping_options } = useShippingOptions(
11609
+ {
11610
+ id: appliedShippingOptionIds,
11611
+ fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
11612
+ },
11613
+ {
11614
+ enabled: appliedShippingOptionIds.length > 0
11615
+ }
11616
+ );
11617
+ const uniqueShippingProfiles = useMemo(() => {
11618
+ const profiles = /* @__PURE__ */ new Map();
11619
+ getUniqueShippingProfiles(order.items).forEach((profile) => {
11620
+ profiles.set(profile.id, profile);
11621
+ });
11622
+ shipping_options == null ? void 0 : shipping_options.forEach((option) => {
11623
+ profiles.set(option.shipping_profile_id, option.shipping_profile);
11624
+ });
11625
+ return Array.from(profiles.values());
11626
+ }, [order.items, shipping_options]);
11627
+ const { handleSuccess } = useRouteModal();
11628
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11629
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
11630
+ const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
11631
+ const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
11632
+ const onSubmit = async () => {
11633
+ setIsSubmitting(true);
11634
+ let requestSucceeded = false;
11635
+ await requestOrderEdit(void 0, {
11365
11636
  onError: (e) => {
11366
11637
  toast.error(`Failed to request order edit: ${e.message}`);
11367
11638
  },
@@ -11629,680 +11900,477 @@ const ShippingForm = ({ preview, order }) => {
11629
11900
  ) }),
11630
11901
  /* @__PURE__ */ jsxs("div", { className: "py-2 flex items-center gap-x-3", children: [
11631
11902
  /* @__PURE__ */ jsx("div", { className: "size-7 flex items-center justify-center tabular-nums", children: /* @__PURE__ */ jsxs(
11632
- Text,
11633
- {
11634
- size: "small",
11635
- leading: "compact",
11636
- className: "text-ui-fg-subtle",
11637
- children: [
11638
- item.quantity,
11639
- "x"
11640
- ]
11641
- }
11642
- ) }),
11643
- /* @__PURE__ */ jsx(Thumbnail, { thumbnail: item.thumbnail }),
11644
- /* @__PURE__ */ jsxs("div", { children: [
11645
- /* @__PURE__ */ jsxs(
11646
- Text,
11647
- {
11648
- size: "small",
11649
- leading: "compact",
11650
- weight: "plus",
11651
- children: [
11652
- (_b2 = (_a3 = item.variant) == null ? void 0 : _a3.product) == null ? void 0 : _b2.title,
11653
- " (",
11654
- (_c2 = item.variant) == null ? void 0 : _c2.title,
11655
- ")"
11656
- ]
11657
- }
11658
- ),
11659
- /* @__PURE__ */ jsx(
11660
- Text,
11661
- {
11662
- size: "small",
11663
- leading: "compact",
11664
- className: "text-ui-fg-subtle",
11665
- children: (_e2 = (_d2 = item.variant) == null ? void 0 : _d2.options) == null ? void 0 : _e2.map((option) => option.value).join(" · ")
11666
- }
11667
- )
11668
- ] })
11669
- ] })
11670
- ]
11671
- },
11672
- item.id
11673
- ),
11674
- idx !== items.length - 1 && /* @__PURE__ */ jsx(Divider, { variant: "dashed" })
11675
- ] }, item.id);
11676
- })
11677
- ] })
11678
- ]
11679
- },
11680
- profile.id
11681
- );
11682
- }) })
11683
- ] }) })
11684
- ] }) }),
11685
- /* @__PURE__ */ jsx(
11686
- StackedFocusModal,
11687
- {
11688
- id: STACKED_FOCUS_MODAL_ID,
11689
- onOpenChangeCallback: (open) => {
11690
- if (!open) {
11691
- setData(null);
11692
- }
11693
- return open;
11694
- },
11695
- children: data && /* @__PURE__ */ jsx(ShippingProfileForm, { data, order, preview })
11696
- }
11697
- )
11698
- ] }),
11699
- /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-x-2", children: [
11700
- /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11701
- /* @__PURE__ */ jsx(
11702
- Button,
11703
- {
11704
- size: "small",
11705
- type: "button",
11706
- isLoading: isSubmitting,
11707
- onClick: onSubmit,
11708
- children: "Save"
11709
- }
11710
- )
11711
- ] }) })
11712
- ] });
11713
- };
11714
- const StackedModalTrigger = ({
11715
- shippingProfileId,
11716
- shippingOption,
11717
- shippingMethod,
11718
- setData,
11719
- children
11720
- }) => {
11721
- const { setIsOpen, getIsOpen } = useStackedModal();
11722
- const isOpen = getIsOpen(STACKED_FOCUS_MODAL_ID);
11723
- const onToggle = () => {
11724
- if (isOpen) {
11725
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11726
- setData(null);
11727
- } else {
11728
- setIsOpen(STACKED_FOCUS_MODAL_ID, true);
11729
- setData({
11730
- shippingProfileId,
11731
- shippingOption,
11732
- shippingMethod
11733
- });
11734
- }
11735
- };
11736
- return /* @__PURE__ */ jsx(
11737
- Button,
11738
- {
11739
- size: "small",
11740
- variant: "secondary",
11741
- onClick: onToggle,
11742
- className: "text-ui-fg-primary shrink-0",
11743
- children
11744
- }
11745
- );
11746
- };
11747
- const ShippingProfileForm = ({
11748
- data,
11749
- order,
11750
- preview
11751
- }) => {
11752
- var _a, _b, _c, _d, _e, _f;
11753
- const { setIsOpen } = useStackedModal();
11754
- const form = useForm({
11755
- resolver: zodResolver(shippingMethodSchema),
11756
- defaultValues: {
11757
- location_id: (_d = (_c = (_b = (_a = data.shippingOption) == null ? void 0 : _a.service_zone) == null ? void 0 : _b.fulfillment_set) == null ? void 0 : _c.location) == null ? void 0 : _d.id,
11758
- shipping_option_id: (_e = data.shippingOption) == null ? void 0 : _e.id,
11759
- custom_amount: (_f = data.shippingMethod) == null ? void 0 : _f.amount
11760
- }
11761
- });
11762
- const { mutateAsync: addShippingMethod, isPending } = useDraftOrderAddShippingMethod(order.id);
11763
- const {
11764
- mutateAsync: updateShippingMethod,
11765
- isPending: isUpdatingShippingMethod
11766
- } = useDraftOrderUpdateShippingMethod(order.id);
11767
- const onSubmit = form.handleSubmit(async (values) => {
11768
- if (isEqual(values, form.formState.defaultValues)) {
11769
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11770
- return;
11771
- }
11772
- if (data.shippingMethod) {
11773
- await updateShippingMethod(
11774
- {
11775
- method_id: data.shippingMethod.id,
11776
- shipping_option_id: values.shipping_option_id,
11777
- custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
11778
- },
11779
- {
11780
- onError: (e) => {
11781
- toast.error(e.message);
11782
- },
11783
- onSuccess: () => {
11784
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11785
- }
11786
- }
11787
- );
11788
- return;
11789
- }
11790
- await addShippingMethod(
11791
- {
11792
- shipping_option_id: values.shipping_option_id,
11793
- custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
11794
- },
11795
- {
11796
- onError: (e) => {
11797
- toast.error(e.message);
11798
- },
11799
- onSuccess: () => {
11800
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11801
- }
11802
- }
11803
- );
11804
- });
11805
- return /* @__PURE__ */ jsx(StackedFocusModal.Content, { children: /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxs(
11806
- KeyboundForm,
11807
- {
11808
- className: "flex h-full flex-col overflow-hidden",
11809
- onSubmit,
11810
- children: [
11811
- /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
11812
- /* @__PURE__ */ jsx(StackedFocusModal.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: [
11813
- /* @__PURE__ */ jsxs("div", { children: [
11814
- /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Shipping" }) }),
11815
- /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a shipping method for the selected shipping profile. You can see the items that will be shipped using this method in the preview below." }) })
11816
- ] }),
11817
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11818
- /* @__PURE__ */ jsx(
11819
- LocationField,
11820
- {
11821
- control: form.control,
11822
- setValue: form.setValue
11823
- }
11824
- ),
11825
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11826
- /* @__PURE__ */ jsx(
11827
- ShippingOptionField,
11828
- {
11829
- shippingProfileId: data.shippingProfileId,
11830
- preview,
11831
- control: form.control
11832
- }
11833
- ),
11834
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11835
- /* @__PURE__ */ jsx(
11836
- CustomAmountField,
11837
- {
11838
- control: form.control,
11839
- currencyCode: order.currency_code
11840
- }
11841
- ),
11842
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11843
- /* @__PURE__ */ jsx(
11844
- ItemsPreview,
11845
- {
11846
- order,
11847
- shippingProfileId: data.shippingProfileId
11848
- }
11849
- )
11850
- ] }) }) }),
11851
- /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-x-2", children: [
11852
- /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11853
- /* @__PURE__ */ jsx(
11854
- Button,
11855
- {
11856
- size: "small",
11857
- type: "submit",
11858
- isLoading: isPending || isUpdatingShippingMethod,
11859
- children: data.shippingMethod ? "Update" : "Add"
11860
- }
11861
- )
11862
- ] }) })
11863
- ]
11864
- }
11865
- ) }) });
11866
- };
11867
- const shippingMethodSchema = objectType({
11868
- location_id: stringType(),
11869
- shipping_option_id: stringType(),
11870
- custom_amount: unionType([numberType(), stringType()]).optional()
11871
- });
11872
- const ItemsPreview = ({ order, shippingProfileId }) => {
11873
- const matches = order.items.filter(
11874
- (item) => {
11875
- var _a, _b, _c;
11876
- return ((_c = (_b = (_a = item.variant) == null ? void 0 : _a.product) == null ? void 0 : _b.shipping_profile) == null ? void 0 : _c.id) === shippingProfileId;
11877
- }
11878
- );
11879
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
11880
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 items-center gap-3", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
11881
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items to ship" }),
11882
- /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Items with the selected shipping profile." })
11883
- ] }) }),
11884
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
11885
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3 px-4 py-2 text-ui-fg-muted", children: [
11886
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
11887
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) })
11888
- ] }),
11889
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxs(
11890
- "div",
11891
- {
11892
- className: "grid grid-cols-2 gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center",
11893
- children: [
11894
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
11895
- /* @__PURE__ */ jsx(
11896
- Thumbnail,
11897
- {
11898
- thumbnail: item.thumbnail,
11899
- alt: item.product_title ?? void 0
11900
- }
11901
- ),
11902
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
11903
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
11904
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
11905
- /* @__PURE__ */ jsxs(
11906
- Text,
11907
- {
11908
- size: "small",
11909
- leading: "compact",
11910
- className: "text-ui-fg-subtle",
11911
- children: [
11912
- "(",
11913
- item.variant_title,
11914
- ")"
11915
- ]
11916
- }
11917
- )
11918
- ] }),
11919
- /* @__PURE__ */ jsx(
11920
- Text,
11921
- {
11922
- size: "small",
11923
- leading: "compact",
11924
- className: "text-ui-fg-subtle",
11925
- children: item.variant_sku
11926
- }
11927
- )
11928
- ] })
11929
- ] }),
11930
- /* @__PURE__ */ jsxs(
11931
- Text,
11932
- {
11933
- size: "small",
11934
- leading: "compact",
11935
- className: "text-ui-fg-subtle",
11936
- children: [
11937
- item.quantity,
11938
- "x"
11939
- ]
11940
- }
11941
- )
11942
- ]
11943
- },
11944
- item.id
11945
- )) : /* @__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: [
11946
- /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
11947
- /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
11948
- 'No items found for "',
11949
- query,
11950
- '".'
11951
- ] })
11952
- ] }) })
11953
- ] })
11954
- ] });
11955
- };
11956
- const LocationField = ({ control, setValue }) => {
11957
- const locations = useComboboxData({
11958
- queryKey: ["locations"],
11959
- queryFn: async (params) => {
11960
- return await sdk.admin.stockLocation.list(params);
11961
- },
11962
- getOptions: (data) => {
11963
- return data.stock_locations.map((location) => ({
11964
- label: location.name,
11965
- value: location.id
11966
- }));
11967
- }
11968
- });
11969
- return /* @__PURE__ */ jsx(
11970
- Form$2.Field,
11971
- {
11972
- control,
11973
- name: "location_id",
11974
- render: ({ field: { onChange, ...field } }) => {
11975
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11976
- /* @__PURE__ */ jsxs("div", { children: [
11977
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Location" }),
11978
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Choose where you want to ship the items from." })
11979
- ] }),
11980
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11981
- Combobox,
11982
- {
11983
- options: locations.options,
11984
- fetchNextPage: locations.fetchNextPage,
11985
- isFetchingNextPage: locations.isFetchingNextPage,
11986
- searchValue: locations.searchValue,
11987
- onSearchValueChange: locations.onSearchValueChange,
11988
- placeholder: "Select location",
11989
- onChange: (value) => {
11990
- setValue("shipping_option_id", "", {
11991
- shouldDirty: true,
11992
- shouldTouch: true
11993
- });
11994
- onChange(value);
11903
+ Text,
11904
+ {
11905
+ size: "small",
11906
+ leading: "compact",
11907
+ className: "text-ui-fg-subtle",
11908
+ children: [
11909
+ item.quantity,
11910
+ "x"
11911
+ ]
11912
+ }
11913
+ ) }),
11914
+ /* @__PURE__ */ jsx(Thumbnail, { thumbnail: item.thumbnail }),
11915
+ /* @__PURE__ */ jsxs("div", { children: [
11916
+ /* @__PURE__ */ jsxs(
11917
+ Text,
11918
+ {
11919
+ size: "small",
11920
+ leading: "compact",
11921
+ weight: "plus",
11922
+ children: [
11923
+ (_b2 = (_a3 = item.variant) == null ? void 0 : _a3.product) == null ? void 0 : _b2.title,
11924
+ " (",
11925
+ (_c2 = item.variant) == null ? void 0 : _c2.title,
11926
+ ")"
11927
+ ]
11928
+ }
11929
+ ),
11930
+ /* @__PURE__ */ jsx(
11931
+ Text,
11932
+ {
11933
+ size: "small",
11934
+ leading: "compact",
11935
+ className: "text-ui-fg-subtle",
11936
+ children: (_e2 = (_d2 = item.variant) == null ? void 0 : _d2.options) == null ? void 0 : _e2.map((option) => option.value).join(" · ")
11937
+ }
11938
+ )
11939
+ ] })
11940
+ ] })
11941
+ ]
11942
+ },
11943
+ item.id
11944
+ ),
11945
+ idx !== items.length - 1 && /* @__PURE__ */ jsx(Divider, { variant: "dashed" })
11946
+ ] }, item.id);
11947
+ })
11948
+ ] })
11949
+ ]
11995
11950
  },
11996
- ...field
11951
+ profile.id
11952
+ );
11953
+ }) })
11954
+ ] }) })
11955
+ ] }) }),
11956
+ /* @__PURE__ */ jsx(
11957
+ StackedFocusModal,
11958
+ {
11959
+ id: STACKED_FOCUS_MODAL_ID,
11960
+ onOpenChangeCallback: (open) => {
11961
+ if (!open) {
11962
+ setData(null);
11997
11963
  }
11998
- ) })
11999
- ] }) });
12000
- }
12001
- }
12002
- );
11964
+ return open;
11965
+ },
11966
+ children: data && /* @__PURE__ */ jsx(ShippingProfileForm, { data, order, preview })
11967
+ }
11968
+ )
11969
+ ] }),
11970
+ /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-x-2", children: [
11971
+ /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11972
+ /* @__PURE__ */ jsx(
11973
+ Button,
11974
+ {
11975
+ size: "small",
11976
+ type: "button",
11977
+ isLoading: isSubmitting,
11978
+ onClick: onSubmit,
11979
+ children: "Save"
11980
+ }
11981
+ )
11982
+ ] }) })
11983
+ ] });
12003
11984
  };
12004
- const ShippingOptionField = ({
11985
+ const StackedModalTrigger = ({
12005
11986
  shippingProfileId,
12006
- preview,
12007
- control
11987
+ shippingOption,
11988
+ shippingMethod,
11989
+ setData,
11990
+ children
12008
11991
  }) => {
12009
- var _a;
12010
- const locationId = useWatch({ control, name: "location_id" });
12011
- const shippingOptions = useComboboxData({
12012
- queryKey: ["shipping_options", locationId, shippingProfileId],
12013
- queryFn: async (params) => {
12014
- return await sdk.admin.shippingOption.list({
12015
- ...params,
12016
- stock_location_id: locationId,
12017
- shipping_profile_id: shippingProfileId
11992
+ const { setIsOpen, getIsOpen } = useStackedModal();
11993
+ const isOpen = getIsOpen(STACKED_FOCUS_MODAL_ID);
11994
+ const onToggle = () => {
11995
+ if (isOpen) {
11996
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11997
+ setData(null);
11998
+ } else {
11999
+ setIsOpen(STACKED_FOCUS_MODAL_ID, true);
12000
+ setData({
12001
+ shippingProfileId,
12002
+ shippingOption,
12003
+ shippingMethod
12018
12004
  });
12019
- },
12020
- getOptions: (data) => {
12021
- return data.shipping_options.map((option) => {
12022
- var _a2;
12023
- if ((_a2 = option.rules) == null ? void 0 : _a2.find(
12024
- (r) => r.attribute === "is_return" && r.value === "true"
12025
- )) {
12026
- return void 0;
12027
- }
12028
- return {
12029
- label: option.name,
12030
- value: option.id
12031
- };
12032
- }).filter(Boolean);
12033
- },
12034
- enabled: !!locationId && !!shippingProfileId,
12035
- defaultValue: ((_a = preview.shipping_methods[0]) == null ? void 0 : _a.shipping_option_id) || void 0
12036
- });
12037
- const tooltipContent = !locationId && !shippingProfileId ? "Choose a location and shipping profile first." : !locationId ? "Choose a location first." : "Choose a shipping profile first.";
12038
- return /* @__PURE__ */ jsx(
12039
- Form$2.Field,
12040
- {
12041
- control,
12042
- name: "shipping_option_id",
12043
- render: ({ field }) => {
12044
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12045
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12046
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Shipping option" }),
12047
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Choose the shipping option to use." })
12048
- ] }),
12049
- /* @__PURE__ */ jsx(
12050
- ConditionalTooltip,
12051
- {
12052
- content: tooltipContent,
12053
- showTooltip: !locationId || !shippingProfileId,
12054
- children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12055
- Combobox,
12056
- {
12057
- options: shippingOptions.options,
12058
- fetchNextPage: shippingOptions.fetchNextPage,
12059
- isFetchingNextPage: shippingOptions.isFetchingNextPage,
12060
- searchValue: shippingOptions.searchValue,
12061
- onSearchValueChange: shippingOptions.onSearchValueChange,
12062
- placeholder: "Select shipping option",
12063
- ...field,
12064
- disabled: !locationId || !shippingProfileId
12065
- }
12066
- ) }) })
12067
- }
12068
- )
12069
- ] }) });
12070
- }
12071
12005
  }
12072
- );
12073
- };
12074
- const CustomAmountField = ({
12075
- control,
12076
- currencyCode
12077
- }) => {
12006
+ };
12078
12007
  return /* @__PURE__ */ jsx(
12079
- Form$2.Field,
12008
+ Button,
12080
12009
  {
12081
- control,
12082
- name: "custom_amount",
12083
- render: ({ field: { onChange, ...field } }) => {
12084
- return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12085
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12086
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12087
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12088
- ] }),
12089
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12090
- CurrencyInput,
12091
- {
12092
- ...field,
12093
- onValueChange: (value) => onChange(value),
12094
- symbol: getNativeSymbol(currencyCode),
12095
- code: currencyCode
12096
- }
12097
- ) })
12098
- ] });
12099
- }
12010
+ size: "small",
12011
+ variant: "secondary",
12012
+ onClick: onToggle,
12013
+ className: "text-ui-fg-primary shrink-0",
12014
+ children
12100
12015
  }
12101
12016
  );
12102
12017
  };
12103
- const ShippingAddress = () => {
12104
- const { id } = useParams();
12105
- const { order, isPending, isError, error } = useOrder(id, {
12106
- fields: "+shipping_address"
12107
- });
12108
- if (isError) {
12109
- throw error;
12110
- }
12111
- const isReady = !isPending && !!order;
12112
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12113
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12114
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Shipping Address" }) }),
12115
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
12116
- ] }),
12117
- isReady && /* @__PURE__ */ jsx(ShippingAddressForm, { order })
12118
- ] });
12119
- };
12120
- const ShippingAddressForm = ({ order }) => {
12121
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12018
+ const ShippingProfileForm = ({
12019
+ data,
12020
+ order,
12021
+ preview
12022
+ }) => {
12023
+ var _a, _b, _c, _d, _e, _f;
12024
+ const { setIsOpen } = useStackedModal();
12122
12025
  const form = useForm({
12123
- defaultValues: {
12124
- first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
12125
- last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
12126
- company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
12127
- address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
12128
- address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
12129
- city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
12130
- province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
12131
- country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
12132
- postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12133
- phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12134
- },
12135
- resolver: zodResolver(schema$3)
12136
- });
12137
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12138
- const { handleSuccess } = useRouteModal();
12139
- const onSubmit = form.handleSubmit(async (data) => {
12140
- await mutateAsync(
12141
- {
12142
- shipping_address: {
12143
- first_name: data.first_name,
12144
- last_name: data.last_name,
12145
- company: data.company,
12146
- address_1: data.address_1,
12147
- address_2: data.address_2,
12148
- city: data.city,
12149
- province: data.province,
12150
- country_code: data.country_code,
12151
- postal_code: data.postal_code,
12152
- phone: data.phone
12026
+ resolver: zodResolver(shippingMethodSchema),
12027
+ defaultValues: {
12028
+ location_id: (_d = (_c = (_b = (_a = data.shippingOption) == null ? void 0 : _a.service_zone) == null ? void 0 : _b.fulfillment_set) == null ? void 0 : _c.location) == null ? void 0 : _d.id,
12029
+ shipping_option_id: (_e = data.shippingOption) == null ? void 0 : _e.id,
12030
+ custom_amount: (_f = data.shippingMethod) == null ? void 0 : _f.amount
12031
+ }
12032
+ });
12033
+ const { mutateAsync: addShippingMethod, isPending } = useDraftOrderAddShippingMethod(order.id);
12034
+ const {
12035
+ mutateAsync: updateShippingMethod,
12036
+ isPending: isUpdatingShippingMethod
12037
+ } = useDraftOrderUpdateShippingMethod(order.id);
12038
+ const onSubmit = form.handleSubmit(async (values) => {
12039
+ if (isEqual(values, form.formState.defaultValues)) {
12040
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12041
+ return;
12042
+ }
12043
+ if (data.shippingMethod) {
12044
+ await updateShippingMethod(
12045
+ {
12046
+ method_id: data.shippingMethod.id,
12047
+ shipping_option_id: values.shipping_option_id,
12048
+ custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
12049
+ },
12050
+ {
12051
+ onError: (e) => {
12052
+ toast.error(e.message);
12053
+ },
12054
+ onSuccess: () => {
12055
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12056
+ }
12153
12057
  }
12058
+ );
12059
+ return;
12060
+ }
12061
+ await addShippingMethod(
12062
+ {
12063
+ shipping_option_id: values.shipping_option_id,
12064
+ custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
12154
12065
  },
12155
12066
  {
12156
- onSuccess: () => {
12157
- handleSuccess();
12067
+ onError: (e) => {
12068
+ toast.error(e.message);
12158
12069
  },
12159
- onError: (error) => {
12160
- toast.error(error.message);
12070
+ onSuccess: () => {
12071
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12161
12072
  }
12162
12073
  }
12163
12074
  );
12164
12075
  });
12165
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
12076
+ return /* @__PURE__ */ jsx(StackedFocusModal.Content, { children: /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxs(
12166
12077
  KeyboundForm,
12167
12078
  {
12168
- className: "flex flex-1 flex-col overflow-hidden",
12079
+ className: "flex h-full flex-col overflow-hidden",
12169
12080
  onSubmit,
12170
12081
  children: [
12171
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-4", children: [
12082
+ /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
12083
+ /* @__PURE__ */ jsx(StackedFocusModal.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: [
12084
+ /* @__PURE__ */ jsxs("div", { children: [
12085
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Shipping" }) }),
12086
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a shipping method for the selected shipping profile. You can see the items that will be shipped using this method in the preview below." }) })
12087
+ ] }),
12088
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
12172
12089
  /* @__PURE__ */ jsx(
12173
- Form$2.Field,
12090
+ LocationField,
12174
12091
  {
12175
12092
  control: form.control,
12176
- name: "country_code",
12177
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12178
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Country" }),
12179
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
12180
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12181
- ] })
12093
+ setValue: form.setValue
12182
12094
  }
12183
12095
  ),
12184
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12185
- /* @__PURE__ */ jsx(
12186
- Form$2.Field,
12187
- {
12188
- control: form.control,
12189
- name: "first_name",
12190
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12191
- /* @__PURE__ */ jsx(Form$2.Label, { children: "First name" }),
12192
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12193
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12194
- ] })
12195
- }
12196
- ),
12197
- /* @__PURE__ */ jsx(
12198
- Form$2.Field,
12199
- {
12200
- control: form.control,
12201
- name: "last_name",
12202
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12203
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Last name" }),
12204
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12205
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12206
- ] })
12207
- }
12208
- )
12209
- ] }),
12096
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
12210
12097
  /* @__PURE__ */ jsx(
12211
- Form$2.Field,
12098
+ ShippingOptionField,
12212
12099
  {
12213
- control: form.control,
12214
- name: "company",
12215
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12216
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Company" }),
12217
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12218
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12219
- ] })
12100
+ shippingProfileId: data.shippingProfileId,
12101
+ preview,
12102
+ control: form.control
12220
12103
  }
12221
12104
  ),
12105
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
12222
12106
  /* @__PURE__ */ jsx(
12223
- Form$2.Field,
12107
+ CustomAmountField,
12224
12108
  {
12225
12109
  control: form.control,
12226
- name: "address_1",
12227
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12228
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Address" }),
12229
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12230
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12231
- ] })
12110
+ currencyCode: order.currency_code
12232
12111
  }
12233
12112
  ),
12113
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
12234
12114
  /* @__PURE__ */ jsx(
12235
- Form$2.Field,
12115
+ ItemsPreview,
12236
12116
  {
12237
- control: form.control,
12238
- name: "address_2",
12239
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12240
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12241
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12242
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12243
- ] })
12117
+ order,
12118
+ shippingProfileId: data.shippingProfileId
12244
12119
  }
12245
- ),
12246
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12247
- /* @__PURE__ */ jsx(
12248
- Form$2.Field,
12249
- {
12250
- control: form.control,
12251
- name: "postal_code",
12252
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12253
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Postal code" }),
12254
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12255
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12256
- ] })
12257
- }
12258
- ),
12259
- /* @__PURE__ */ jsx(
12260
- Form$2.Field,
12120
+ )
12121
+ ] }) }) }),
12122
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-x-2", children: [
12123
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12124
+ /* @__PURE__ */ jsx(
12125
+ Button,
12126
+ {
12127
+ size: "small",
12128
+ type: "submit",
12129
+ isLoading: isPending || isUpdatingShippingMethod,
12130
+ children: data.shippingMethod ? "Update" : "Add"
12131
+ }
12132
+ )
12133
+ ] }) })
12134
+ ]
12135
+ }
12136
+ ) }) });
12137
+ };
12138
+ const shippingMethodSchema = objectType({
12139
+ location_id: stringType(),
12140
+ shipping_option_id: stringType(),
12141
+ custom_amount: unionType([numberType(), stringType()]).optional()
12142
+ });
12143
+ const ItemsPreview = ({ order, shippingProfileId }) => {
12144
+ const matches = order.items.filter(
12145
+ (item) => {
12146
+ var _a, _b, _c;
12147
+ return ((_c = (_b = (_a = item.variant) == null ? void 0 : _a.product) == null ? void 0 : _b.shipping_profile) == null ? void 0 : _c.id) === shippingProfileId;
12148
+ }
12149
+ );
12150
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-6", children: [
12151
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 items-center gap-3", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12152
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "Items to ship" }),
12153
+ /* @__PURE__ */ jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: "Items with the selected shipping profile." })
12154
+ ] }) }),
12155
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
12156
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3 px-4 py-2 text-ui-fg-muted", children: [
12157
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Item" }) }),
12158
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", children: "Quantity" }) })
12159
+ ] }),
12160
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxs(
12161
+ "div",
12162
+ {
12163
+ className: "grid grid-cols-2 gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center",
12164
+ children: [
12165
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
12166
+ /* @__PURE__ */ jsx(
12167
+ Thumbnail,
12168
+ {
12169
+ thumbnail: item.thumbnail,
12170
+ alt: item.product_title ?? void 0
12171
+ }
12172
+ ),
12173
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12174
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-1", children: [
12175
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
12176
+ /* @__PURE__ */ jsxs(
12177
+ Text,
12178
+ {
12179
+ size: "small",
12180
+ leading: "compact",
12181
+ className: "text-ui-fg-subtle",
12182
+ children: [
12183
+ "(",
12184
+ item.variant_title,
12185
+ ")"
12186
+ ]
12187
+ }
12188
+ )
12189
+ ] }),
12190
+ /* @__PURE__ */ jsx(
12191
+ Text,
12192
+ {
12193
+ size: "small",
12194
+ leading: "compact",
12195
+ className: "text-ui-fg-subtle",
12196
+ children: item.variant_sku
12197
+ }
12198
+ )
12199
+ ] })
12200
+ ] }),
12201
+ /* @__PURE__ */ jsxs(
12202
+ Text,
12261
12203
  {
12262
- control: form.control,
12263
- name: "city",
12264
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12265
- /* @__PURE__ */ jsx(Form$2.Label, { children: "City" }),
12266
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12267
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12268
- ] })
12204
+ size: "small",
12205
+ leading: "compact",
12206
+ className: "text-ui-fg-subtle",
12207
+ children: [
12208
+ item.quantity,
12209
+ "x"
12210
+ ]
12269
12211
  }
12270
12212
  )
12213
+ ]
12214
+ },
12215
+ item.id
12216
+ )) : /* @__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: [
12217
+ /* @__PURE__ */ jsx(Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
12218
+ /* @__PURE__ */ jsxs(Text, { size: "small", className: "text-ui-fg-subtle", children: [
12219
+ 'No items found for "',
12220
+ query,
12221
+ '".'
12222
+ ] })
12223
+ ] }) })
12224
+ ] })
12225
+ ] });
12226
+ };
12227
+ const LocationField = ({ control, setValue }) => {
12228
+ const locations = useComboboxData({
12229
+ queryKey: ["locations"],
12230
+ queryFn: async (params) => {
12231
+ return await sdk.admin.stockLocation.list(params);
12232
+ },
12233
+ getOptions: (data) => {
12234
+ return data.stock_locations.map((location) => ({
12235
+ label: location.name,
12236
+ value: location.id
12237
+ }));
12238
+ }
12239
+ });
12240
+ return /* @__PURE__ */ jsx(
12241
+ Form$2.Field,
12242
+ {
12243
+ control,
12244
+ name: "location_id",
12245
+ render: ({ field: { onChange, ...field } }) => {
12246
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12247
+ /* @__PURE__ */ jsxs("div", { children: [
12248
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Location" }),
12249
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Choose where you want to ship the items from." })
12271
12250
  ] }),
12272
- /* @__PURE__ */ jsx(
12273
- Form$2.Field,
12251
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12252
+ Combobox,
12274
12253
  {
12275
- control: form.control,
12276
- name: "province",
12277
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12278
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Province / State" }),
12279
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12280
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12281
- ] })
12254
+ options: locations.options,
12255
+ fetchNextPage: locations.fetchNextPage,
12256
+ isFetchingNextPage: locations.isFetchingNextPage,
12257
+ searchValue: locations.searchValue,
12258
+ onSearchValueChange: locations.onSearchValueChange,
12259
+ placeholder: "Select location",
12260
+ onChange: (value) => {
12261
+ setValue("shipping_option_id", "", {
12262
+ shouldDirty: true,
12263
+ shouldTouch: true
12264
+ });
12265
+ onChange(value);
12266
+ },
12267
+ ...field
12282
12268
  }
12283
- ),
12269
+ ) })
12270
+ ] }) });
12271
+ }
12272
+ }
12273
+ );
12274
+ };
12275
+ const ShippingOptionField = ({
12276
+ shippingProfileId,
12277
+ preview,
12278
+ control
12279
+ }) => {
12280
+ var _a;
12281
+ const locationId = useWatch({ control, name: "location_id" });
12282
+ const shippingOptions = useComboboxData({
12283
+ queryKey: ["shipping_options", locationId, shippingProfileId],
12284
+ queryFn: async (params) => {
12285
+ return await sdk.admin.shippingOption.list({
12286
+ ...params,
12287
+ stock_location_id: locationId,
12288
+ shipping_profile_id: shippingProfileId
12289
+ });
12290
+ },
12291
+ getOptions: (data) => {
12292
+ return data.shipping_options.map((option) => {
12293
+ var _a2;
12294
+ if ((_a2 = option.rules) == null ? void 0 : _a2.find(
12295
+ (r) => r.attribute === "is_return" && r.value === "true"
12296
+ )) {
12297
+ return void 0;
12298
+ }
12299
+ return {
12300
+ label: option.name,
12301
+ value: option.id
12302
+ };
12303
+ }).filter(Boolean);
12304
+ },
12305
+ enabled: !!locationId && !!shippingProfileId,
12306
+ defaultValue: ((_a = preview.shipping_methods[0]) == null ? void 0 : _a.shipping_option_id) || void 0
12307
+ });
12308
+ const tooltipContent = !locationId && !shippingProfileId ? "Choose a location and shipping profile first." : !locationId ? "Choose a location first." : "Choose a shipping profile first.";
12309
+ return /* @__PURE__ */ jsx(
12310
+ Form$2.Field,
12311
+ {
12312
+ control,
12313
+ name: "shipping_option_id",
12314
+ render: ({ field }) => {
12315
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12316
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12317
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Shipping option" }),
12318
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Choose the shipping option to use." })
12319
+ ] }),
12284
12320
  /* @__PURE__ */ jsx(
12285
- Form$2.Field,
12321
+ ConditionalTooltip,
12286
12322
  {
12287
- control: form.control,
12288
- name: "phone",
12289
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12290
- /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Phone" }),
12291
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12292
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12293
- ] })
12323
+ content: tooltipContent,
12324
+ showTooltip: !locationId || !shippingProfileId,
12325
+ children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12326
+ Combobox,
12327
+ {
12328
+ options: shippingOptions.options,
12329
+ fetchNextPage: shippingOptions.fetchNextPage,
12330
+ isFetchingNextPage: shippingOptions.isFetchingNextPage,
12331
+ searchValue: shippingOptions.searchValue,
12332
+ onSearchValueChange: shippingOptions.onSearchValueChange,
12333
+ placeholder: "Select shipping option",
12334
+ ...field,
12335
+ disabled: !locationId || !shippingProfileId
12336
+ }
12337
+ ) }) })
12294
12338
  }
12295
12339
  )
12296
- ] }) }),
12297
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
12298
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12299
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12300
- ] }) })
12301
- ]
12340
+ ] }) });
12341
+ }
12302
12342
  }
12303
- ) });
12343
+ );
12344
+ };
12345
+ const CustomAmountField = ({
12346
+ control,
12347
+ currencyCode
12348
+ }) => {
12349
+ return /* @__PURE__ */ jsx(
12350
+ Form$2.Field,
12351
+ {
12352
+ control,
12353
+ name: "custom_amount",
12354
+ render: ({ field: { onChange, ...field } }) => {
12355
+ return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12356
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
12357
+ /* @__PURE__ */ jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12358
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12359
+ ] }),
12360
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
12361
+ CurrencyInput,
12362
+ {
12363
+ ...field,
12364
+ onValueChange: (value) => onChange(value),
12365
+ symbol: getNativeSymbol(currencyCode),
12366
+ code: currencyCode
12367
+ }
12368
+ ) })
12369
+ ] });
12370
+ }
12371
+ }
12372
+ );
12304
12373
  };
12305
- const schema$3 = addressSchema;
12306
12374
  const TransferOwnership = () => {
12307
12375
  const { id } = useParams();
12308
12376
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -12326,7 +12394,7 @@ const TransferOwnershipForm = ({ order }) => {
12326
12394
  defaultValues: {
12327
12395
  customer_id: order.customer_id || ""
12328
12396
  },
12329
- resolver: zodResolver(schema$2)
12397
+ resolver: zodResolver(schema$1)
12330
12398
  });
12331
12399
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12332
12400
  const { handleSuccess } = useRouteModal();
@@ -12776,76 +12844,8 @@ const Illustration = () => {
12776
12844
  }
12777
12845
  );
12778
12846
  };
12779
- const schema$2 = objectType({
12780
- customer_id: stringType().min(1)
12781
- });
12782
- const Email = () => {
12783
- const { id } = useParams();
12784
- const { order, isPending, isError, error } = useOrder(id, {
12785
- fields: "+email"
12786
- });
12787
- if (isError) {
12788
- throw error;
12789
- }
12790
- const isReady = !isPending && !!order;
12791
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12792
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12793
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Email" }) }),
12794
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
12795
- ] }),
12796
- isReady && /* @__PURE__ */ jsx(EmailForm, { order })
12797
- ] });
12798
- };
12799
- const EmailForm = ({ order }) => {
12800
- const form = useForm({
12801
- defaultValues: {
12802
- email: order.email ?? ""
12803
- },
12804
- resolver: zodResolver(schema$1)
12805
- });
12806
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12807
- const { handleSuccess } = useRouteModal();
12808
- const onSubmit = form.handleSubmit(async (data) => {
12809
- await mutateAsync(
12810
- { email: data.email },
12811
- {
12812
- onSuccess: () => {
12813
- handleSuccess();
12814
- },
12815
- onError: (error) => {
12816
- toast.error(error.message);
12817
- }
12818
- }
12819
- );
12820
- });
12821
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
12822
- KeyboundForm,
12823
- {
12824
- className: "flex flex-1 flex-col overflow-hidden",
12825
- onSubmit,
12826
- children: [
12827
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(
12828
- Form$2.Field,
12829
- {
12830
- control: form.control,
12831
- name: "email",
12832
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
12833
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Email" }),
12834
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
12835
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
12836
- ] })
12837
- }
12838
- ) }),
12839
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
12840
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12841
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12842
- ] }) })
12843
- ]
12844
- }
12845
- ) });
12846
- };
12847
12847
  const schema$1 = objectType({
12848
- email: stringType().email()
12848
+ customer_id: stringType().min(1)
12849
12849
  });
12850
12850
  const BillingAddress = () => {
12851
12851
  const { id } = useParams();
@@ -13062,36 +13062,36 @@ const routeModule = {
13062
13062
  path: "/draft-orders/:id/custom-items"
13063
13063
  },
13064
13064
  {
13065
- Component: Items,
13066
- path: "/draft-orders/:id/items"
13065
+ Component: Email,
13066
+ path: "/draft-orders/:id/email"
13067
13067
  },
13068
13068
  {
13069
- Component: Promotions,
13070
- path: "/draft-orders/:id/promotions"
13069
+ Component: Items,
13070
+ path: "/draft-orders/:id/items"
13071
13071
  },
13072
13072
  {
13073
13073
  Component: Metadata,
13074
13074
  path: "/draft-orders/:id/metadata"
13075
13075
  },
13076
13076
  {
13077
- Component: SalesChannel,
13078
- path: "/draft-orders/:id/sales-channel"
13077
+ Component: Promotions,
13078
+ path: "/draft-orders/:id/promotions"
13079
13079
  },
13080
13080
  {
13081
- Component: Shipping,
13082
- path: "/draft-orders/:id/shipping"
13081
+ Component: SalesChannel,
13082
+ path: "/draft-orders/:id/sales-channel"
13083
13083
  },
13084
13084
  {
13085
13085
  Component: ShippingAddress,
13086
13086
  path: "/draft-orders/:id/shipping-address"
13087
13087
  },
13088
13088
  {
13089
- Component: TransferOwnership,
13090
- path: "/draft-orders/:id/transfer-ownership"
13089
+ Component: Shipping,
13090
+ path: "/draft-orders/:id/shipping"
13091
13091
  },
13092
13092
  {
13093
- Component: Email,
13094
- path: "/draft-orders/:id/email"
13093
+ Component: TransferOwnership,
13094
+ path: "/draft-orders/:id/transfer-ownership"
13095
13095
  },
13096
13096
  {
13097
13097
  Component: BillingAddress,