@medusajs/draft-order 2.11.0-preview-20251018060206 → 2.11.0-preview-20251018090155

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.
@@ -9573,6 +9573,27 @@ const ID = () => {
9573
9573
  /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Outlet, {})
9574
9574
  ] });
9575
9575
  };
9576
+ const CustomItems = () => {
9577
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9578
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9579
+ /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9580
+ ] });
9581
+ };
9582
+ const CustomItemsForm = () => {
9583
+ const form = reactHookForm.useForm({
9584
+ resolver: zod.zodResolver(schema$5)
9585
+ });
9586
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9587
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9588
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9589
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9590
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9591
+ ] }) })
9592
+ ] }) });
9593
+ };
9594
+ const schema$5 = objectType({
9595
+ email: stringType().email()
9596
+ });
9576
9597
  const BillingAddress = () => {
9577
9598
  const { id } = reactRouterDom.useParams();
9578
9599
  const { order, isPending, isError, error } = useOrder(id, {
@@ -9605,7 +9626,7 @@ const BillingAddressForm = ({ order }) => {
9605
9626
  postal_code: ((_i = order.billing_address) == null ? void 0 : _i.postal_code) ?? "",
9606
9627
  phone: ((_j = order.billing_address) == null ? void 0 : _j.phone) ?? ""
9607
9628
  },
9608
- resolver: zod.zodResolver(schema$5)
9629
+ resolver: zod.zodResolver(schema$4)
9609
9630
  });
9610
9631
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9611
9632
  const { handleSuccess } = useRouteModal();
@@ -9762,28 +9783,7 @@ const BillingAddressForm = ({ order }) => {
9762
9783
  }
9763
9784
  ) });
9764
9785
  };
9765
- const schema$5 = addressSchema;
9766
- const CustomItems = () => {
9767
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9768
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9769
- /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9770
- ] });
9771
- };
9772
- const CustomItemsForm = () => {
9773
- const form = reactHookForm.useForm({
9774
- resolver: zod.zodResolver(schema$4)
9775
- });
9776
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9777
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9778
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9779
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9780
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9781
- ] }) })
9782
- ] }) });
9783
- };
9784
- const schema$4 = objectType({
9785
- email: stringType().email()
9786
- });
9786
+ const schema$4 = addressSchema;
9787
9787
  const Email = () => {
9788
9788
  const { id } = reactRouterDom.useParams();
9789
9789
  const { order, isPending, isError, error } = useOrder(id, {
@@ -10826,478 +10826,128 @@ const customItemSchema = objectType({
10826
10826
  quantity: numberType(),
10827
10827
  unit_price: unionType([numberType(), stringType()])
10828
10828
  });
10829
- const InlineTip = React.forwardRef(
10830
- ({ variant = "tip", label, className, children, ...props }, ref) => {
10831
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10832
- return /* @__PURE__ */ jsxRuntime.jsxs(
10833
- "div",
10834
- {
10835
- ref,
10836
- className: ui.clx(
10837
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10838
- className
10839
- ),
10840
- ...props,
10841
- children: [
10842
- /* @__PURE__ */ jsxRuntime.jsx(
10843
- "div",
10844
- {
10845
- role: "presentation",
10846
- className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10847
- "bg-ui-tag-orange-icon": variant === "warning"
10848
- })
10849
- }
10850
- ),
10851
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
10852
- /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10853
- labelValue,
10854
- ":"
10855
- ] }),
10856
- " ",
10857
- children
10858
- ] })
10859
- ]
10860
- }
10861
- );
10862
- }
10863
- );
10864
- InlineTip.displayName = "InlineTip";
10865
- const MetadataFieldSchema = objectType({
10866
- key: stringType(),
10867
- disabled: booleanType().optional(),
10868
- value: anyType()
10869
- });
10870
- const MetadataSchema = objectType({
10871
- metadata: arrayType(MetadataFieldSchema)
10872
- });
10873
- const Metadata = () => {
10874
- const { id } = reactRouterDom.useParams();
10875
- const { order, isPending, isError, error } = useOrder(id, {
10876
- fields: "metadata"
10829
+ const PROMOTION_QUERY_KEY = "promotions";
10830
+ const promotionsQueryKeys = {
10831
+ list: (query2) => [
10832
+ PROMOTION_QUERY_KEY,
10833
+ query2 ? query2 : void 0
10834
+ ],
10835
+ detail: (id, query2) => [
10836
+ PROMOTION_QUERY_KEY,
10837
+ id,
10838
+ query2 ? query2 : void 0
10839
+ ]
10840
+ };
10841
+ const usePromotions = (query2, options) => {
10842
+ const { data, ...rest } = reactQuery.useQuery({
10843
+ queryKey: promotionsQueryKeys.list(query2),
10844
+ queryFn: async () => sdk.admin.promotion.list(query2),
10845
+ ...options
10877
10846
  });
10878
- if (isError) {
10879
- throw error;
10847
+ return { ...data, ...rest };
10848
+ };
10849
+ const Promotions = () => {
10850
+ const { id } = reactRouterDom.useParams();
10851
+ const {
10852
+ order: preview,
10853
+ isError: isPreviewError,
10854
+ error: previewError
10855
+ } = useOrderPreview(id, void 0);
10856
+ useInitiateOrderEdit({ preview });
10857
+ const { onCancel } = useCancelOrderEdit({ preview });
10858
+ if (isPreviewError) {
10859
+ throw previewError;
10880
10860
  }
10881
- const isReady = !isPending && !!order;
10882
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10883
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10884
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
10885
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10886
- ] }),
10887
- !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10861
+ const isReady = !!preview;
10862
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
10863
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
10864
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
10888
10865
  ] });
10889
10866
  };
10890
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10891
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10892
- const MetadataForm = ({ orderId, metadata }) => {
10867
+ const PromotionForm = ({ preview }) => {
10868
+ const { items, shipping_methods } = preview;
10869
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
10870
+ const [comboboxValue, setComboboxValue] = React.useState("");
10893
10871
  const { handleSuccess } = useRouteModal();
10894
- const hasUneditableRows = getHasUneditableRows(metadata);
10895
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10896
- const form = reactHookForm.useForm({
10897
- defaultValues: {
10898
- metadata: getDefaultValues(metadata)
10872
+ const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
10873
+ const promoIds = getPromotionIds(items, shipping_methods);
10874
+ const { promotions, isPending, isError, error } = usePromotions(
10875
+ {
10876
+ id: promoIds
10899
10877
  },
10900
- resolver: zod.zodResolver(MetadataSchema)
10878
+ {
10879
+ enabled: !!promoIds.length
10880
+ }
10881
+ );
10882
+ const comboboxData = useComboboxData({
10883
+ queryKey: ["promotions", "combobox", promoIds],
10884
+ queryFn: async (params) => {
10885
+ return await sdk.admin.promotion.list({
10886
+ ...params,
10887
+ id: {
10888
+ $nin: promoIds
10889
+ }
10890
+ });
10891
+ },
10892
+ getOptions: (data) => {
10893
+ return data.promotions.map((promotion) => ({
10894
+ label: promotion.code,
10895
+ value: promotion.code
10896
+ }));
10897
+ }
10901
10898
  });
10902
- const handleSubmit = form.handleSubmit(async (data) => {
10903
- const parsedData = parseValues(data);
10904
- await mutateAsync(
10899
+ const add = async (value) => {
10900
+ if (!value) {
10901
+ return;
10902
+ }
10903
+ addPromotions(
10905
10904
  {
10906
- metadata: parsedData
10905
+ promo_codes: [value]
10907
10906
  },
10908
10907
  {
10909
- onSuccess: () => {
10910
- ui.toast.success("Metadata updated");
10911
- handleSuccess();
10908
+ onError: (e) => {
10909
+ ui.toast.error(e.message);
10910
+ comboboxData.onSearchValueChange("");
10911
+ setComboboxValue("");
10912
10912
  },
10913
- onError: (error) => {
10914
- ui.toast.error(error.message);
10913
+ onSuccess: () => {
10914
+ comboboxData.onSearchValueChange("");
10915
+ setComboboxValue("");
10915
10916
  }
10916
10917
  }
10917
10918
  );
10918
- });
10919
- const { fields, insert, remove } = reactHookForm.useFieldArray({
10920
- control: form.control,
10921
- name: "metadata"
10922
- });
10923
- function deleteRow(index) {
10924
- remove(index);
10925
- if (fields.length === 1) {
10926
- insert(0, {
10927
- key: "",
10928
- value: "",
10929
- disabled: false
10930
- });
10919
+ };
10920
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10921
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
10922
+ const onSubmit = async () => {
10923
+ setIsSubmitting(true);
10924
+ let requestSucceeded = false;
10925
+ await requestOrderEdit(void 0, {
10926
+ onError: (e) => {
10927
+ ui.toast.error(e.message);
10928
+ },
10929
+ onSuccess: () => {
10930
+ requestSucceeded = true;
10931
+ }
10932
+ });
10933
+ if (!requestSucceeded) {
10934
+ setIsSubmitting(false);
10935
+ return;
10931
10936
  }
10932
- }
10933
- function insertRow(index, position) {
10934
- insert(index + (position === "above" ? 0 : 1), {
10935
- key: "",
10936
- value: "",
10937
- disabled: false
10937
+ await confirmOrderEdit(void 0, {
10938
+ onError: (e) => {
10939
+ ui.toast.error(e.message);
10940
+ },
10941
+ onSuccess: () => {
10942
+ handleSuccess();
10943
+ },
10944
+ onSettled: () => {
10945
+ setIsSubmitting(false);
10946
+ }
10938
10947
  });
10939
- }
10940
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
10941
- KeyboundForm,
10942
- {
10943
- onSubmit: handleSubmit,
10944
- className: "flex flex-1 flex-col overflow-hidden",
10945
- children: [
10946
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10947
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10948
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10949
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
10950
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
10951
- ] }),
10952
- fields.map((field, index) => {
10953
- const isDisabled = field.disabled || false;
10954
- let placeholder = "-";
10955
- if (typeof field.value === "object") {
10956
- placeholder = "{ ... }";
10957
- }
10958
- if (Array.isArray(field.value)) {
10959
- placeholder = "[ ... ]";
10960
- }
10961
- return /* @__PURE__ */ jsxRuntime.jsx(
10962
- ConditionalTooltip,
10963
- {
10964
- showTooltip: isDisabled,
10965
- content: "This row is disabled because it contains non-primitive data.",
10966
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
10967
- /* @__PURE__ */ jsxRuntime.jsxs(
10968
- "div",
10969
- {
10970
- className: ui.clx("grid grid-cols-2 divide-x", {
10971
- "overflow-hidden rounded-b-lg": index === fields.length - 1
10972
- }),
10973
- children: [
10974
- /* @__PURE__ */ jsxRuntime.jsx(
10975
- Form$2.Field,
10976
- {
10977
- control: form.control,
10978
- name: `metadata.${index}.key`,
10979
- render: ({ field: field2 }) => {
10980
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10981
- GridInput,
10982
- {
10983
- "aria-labelledby": METADATA_KEY_LABEL_ID,
10984
- ...field2,
10985
- disabled: isDisabled,
10986
- placeholder: "Key"
10987
- }
10988
- ) }) });
10989
- }
10990
- }
10991
- ),
10992
- /* @__PURE__ */ jsxRuntime.jsx(
10993
- Form$2.Field,
10994
- {
10995
- control: form.control,
10996
- name: `metadata.${index}.value`,
10997
- render: ({ field: { value, ...field2 } }) => {
10998
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10999
- GridInput,
11000
- {
11001
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
11002
- ...field2,
11003
- value: isDisabled ? placeholder : value,
11004
- disabled: isDisabled,
11005
- placeholder: "Value"
11006
- }
11007
- ) }) });
11008
- }
11009
- }
11010
- )
11011
- ]
11012
- }
11013
- ),
11014
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
11015
- /* @__PURE__ */ jsxRuntime.jsx(
11016
- ui.DropdownMenu.Trigger,
11017
- {
11018
- className: ui.clx(
11019
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11020
- {
11021
- hidden: isDisabled
11022
- }
11023
- ),
11024
- disabled: isDisabled,
11025
- asChild: true,
11026
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
11027
- }
11028
- ),
11029
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
11030
- /* @__PURE__ */ jsxRuntime.jsxs(
11031
- ui.DropdownMenu.Item,
11032
- {
11033
- className: "gap-x-2",
11034
- onClick: () => insertRow(index, "above"),
11035
- children: [
11036
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
11037
- "Insert row above"
11038
- ]
11039
- }
11040
- ),
11041
- /* @__PURE__ */ jsxRuntime.jsxs(
11042
- ui.DropdownMenu.Item,
11043
- {
11044
- className: "gap-x-2",
11045
- onClick: () => insertRow(index, "below"),
11046
- children: [
11047
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
11048
- "Insert row below"
11049
- ]
11050
- }
11051
- ),
11052
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
11053
- /* @__PURE__ */ jsxRuntime.jsxs(
11054
- ui.DropdownMenu.Item,
11055
- {
11056
- className: "gap-x-2",
11057
- onClick: () => deleteRow(index),
11058
- children: [
11059
- /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
11060
- "Delete row"
11061
- ]
11062
- }
11063
- )
11064
- ] })
11065
- ] })
11066
- ] })
11067
- },
11068
- field.id
11069
- );
11070
- })
11071
- ] }),
11072
- hasUneditableRows && /* @__PURE__ */ jsxRuntime.jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
11073
- ] }),
11074
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11075
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11076
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11077
- ] }) })
11078
- ]
11079
- }
11080
- ) });
11081
- };
11082
- const GridInput = React.forwardRef(({ className, ...props }, ref) => {
11083
- return /* @__PURE__ */ jsxRuntime.jsx(
11084
- "input",
11085
- {
11086
- ref,
11087
- ...props,
11088
- autoComplete: "off",
11089
- className: ui.clx(
11090
- "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",
11091
- className
11092
- )
11093
- }
11094
- );
11095
- });
11096
- GridInput.displayName = "MetadataForm.GridInput";
11097
- const PlaceholderInner = () => {
11098
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11099
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11100
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11101
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
11102
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
11103
- ] }) })
11104
- ] });
11105
- };
11106
- const EDITABLE_TYPES = ["string", "number", "boolean"];
11107
- function getDefaultValues(metadata) {
11108
- if (!metadata || !Object.keys(metadata).length) {
11109
- return [
11110
- {
11111
- key: "",
11112
- value: "",
11113
- disabled: false
11114
- }
11115
- ];
11116
- }
11117
- return Object.entries(metadata).map(([key, value]) => {
11118
- if (!EDITABLE_TYPES.includes(typeof value)) {
11119
- return {
11120
- key,
11121
- value,
11122
- disabled: true
11123
- };
11124
- }
11125
- let stringValue = value;
11126
- if (typeof value !== "string") {
11127
- stringValue = JSON.stringify(value);
11128
- }
11129
- return {
11130
- key,
11131
- value: stringValue,
11132
- original_key: key
11133
- };
11134
- });
11135
- }
11136
- function parseValues(values) {
11137
- const metadata = values.metadata;
11138
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11139
- if (isEmpty) {
11140
- return null;
11141
- }
11142
- const update = {};
11143
- metadata.forEach((field) => {
11144
- let key = field.key;
11145
- let value = field.value;
11146
- const disabled = field.disabled;
11147
- if (!key || !value) {
11148
- return;
11149
- }
11150
- if (disabled) {
11151
- update[key] = value;
11152
- return;
11153
- }
11154
- key = key.trim();
11155
- value = value.trim();
11156
- if (value === "true") {
11157
- update[key] = true;
11158
- } else if (value === "false") {
11159
- update[key] = false;
11160
- } else {
11161
- const parsedNumber = parseFloat(value);
11162
- if (!isNaN(parsedNumber)) {
11163
- update[key] = parsedNumber;
11164
- } else {
11165
- update[key] = value;
11166
- }
11167
- }
11168
- });
11169
- return update;
11170
- }
11171
- function getHasUneditableRows(metadata) {
11172
- if (!metadata) {
11173
- return false;
11174
- }
11175
- return Object.values(metadata).some(
11176
- (value) => !EDITABLE_TYPES.includes(typeof value)
11177
- );
11178
- }
11179
- const PROMOTION_QUERY_KEY = "promotions";
11180
- const promotionsQueryKeys = {
11181
- list: (query2) => [
11182
- PROMOTION_QUERY_KEY,
11183
- query2 ? query2 : void 0
11184
- ],
11185
- detail: (id, query2) => [
11186
- PROMOTION_QUERY_KEY,
11187
- id,
11188
- query2 ? query2 : void 0
11189
- ]
11190
- };
11191
- const usePromotions = (query2, options) => {
11192
- const { data, ...rest } = reactQuery.useQuery({
11193
- queryKey: promotionsQueryKeys.list(query2),
11194
- queryFn: async () => sdk.admin.promotion.list(query2),
11195
- ...options
11196
- });
11197
- return { ...data, ...rest };
11198
- };
11199
- const Promotions = () => {
11200
- const { id } = reactRouterDom.useParams();
11201
- const {
11202
- order: preview,
11203
- isError: isPreviewError,
11204
- error: previewError
11205
- } = useOrderPreview(id, void 0);
11206
- useInitiateOrderEdit({ preview });
11207
- const { onCancel } = useCancelOrderEdit({ preview });
11208
- if (isPreviewError) {
11209
- throw previewError;
11210
- }
11211
- const isReady = !!preview;
11212
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
11213
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
11214
- isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
11215
- ] });
11216
- };
11217
- const PromotionForm = ({ preview }) => {
11218
- const { items, shipping_methods } = preview;
11219
- const [isSubmitting, setIsSubmitting] = React.useState(false);
11220
- const [comboboxValue, setComboboxValue] = React.useState("");
11221
- const { handleSuccess } = useRouteModal();
11222
- const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
11223
- const promoIds = getPromotionIds(items, shipping_methods);
11224
- const { promotions, isPending, isError, error } = usePromotions(
11225
- {
11226
- id: promoIds
11227
- },
11228
- {
11229
- enabled: !!promoIds.length
11230
- }
11231
- );
11232
- const comboboxData = useComboboxData({
11233
- queryKey: ["promotions", "combobox", promoIds],
11234
- queryFn: async (params) => {
11235
- return await sdk.admin.promotion.list({
11236
- ...params,
11237
- id: {
11238
- $nin: promoIds
11239
- }
11240
- });
11241
- },
11242
- getOptions: (data) => {
11243
- return data.promotions.map((promotion) => ({
11244
- label: promotion.code,
11245
- value: promotion.code
11246
- }));
11247
- }
11248
- });
11249
- const add = async (value) => {
11250
- if (!value) {
11251
- return;
11252
- }
11253
- addPromotions(
11254
- {
11255
- promo_codes: [value]
11256
- },
11257
- {
11258
- onError: (e) => {
11259
- ui.toast.error(e.message);
11260
- comboboxData.onSearchValueChange("");
11261
- setComboboxValue("");
11262
- },
11263
- onSuccess: () => {
11264
- comboboxData.onSearchValueChange("");
11265
- setComboboxValue("");
11266
- }
11267
- }
11268
- );
11269
- };
11270
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11271
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
11272
- const onSubmit = async () => {
11273
- setIsSubmitting(true);
11274
- let requestSucceeded = false;
11275
- await requestOrderEdit(void 0, {
11276
- onError: (e) => {
11277
- ui.toast.error(e.message);
11278
- },
11279
- onSuccess: () => {
11280
- requestSucceeded = true;
11281
- }
11282
- });
11283
- if (!requestSucceeded) {
11284
- setIsSubmitting(false);
11285
- return;
11286
- }
11287
- await confirmOrderEdit(void 0, {
11288
- onError: (e) => {
11289
- ui.toast.error(e.message);
11290
- },
11291
- onSuccess: () => {
11292
- handleSuccess();
11293
- },
11294
- onSettled: () => {
11295
- setIsSubmitting(false);
11296
- }
11297
- });
11298
- };
11299
- if (isError) {
11300
- throw error;
10948
+ };
10949
+ if (isError) {
10950
+ throw error;
11301
10951
  }
11302
10952
  return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
11303
10953
  /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
@@ -11375,278 +11025,489 @@ const PromotionItem = ({
11375
11025
  {
11376
11026
  "animate-pulse": isLoading
11377
11027
  }
11378
- ),
11028
+ ),
11029
+ children: [
11030
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11031
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11032
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
11033
+ displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
11034
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
11035
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
11036
+ ] }),
11037
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11038
+ ] })
11039
+ ] }),
11040
+ /* @__PURE__ */ jsxRuntime.jsx(
11041
+ ui.IconButton,
11042
+ {
11043
+ size: "small",
11044
+ type: "button",
11045
+ variant: "transparent",
11046
+ onClick: onRemove,
11047
+ isLoading: isPending || isLoading,
11048
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
11049
+ }
11050
+ )
11051
+ ]
11052
+ },
11053
+ promotion.id
11054
+ );
11055
+ };
11056
+ function getDisplayValue(promotion) {
11057
+ var _a, _b, _c, _d;
11058
+ const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11059
+ if (!value) {
11060
+ return null;
11061
+ }
11062
+ if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11063
+ const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11064
+ if (!currency) {
11065
+ return null;
11066
+ }
11067
+ return getLocaleAmount(value, currency);
11068
+ } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11069
+ return formatPercentage(value);
11070
+ }
11071
+ return null;
11072
+ }
11073
+ const formatter = new Intl.NumberFormat([], {
11074
+ style: "percent",
11075
+ minimumFractionDigits: 2
11076
+ });
11077
+ const formatPercentage = (value, isPercentageValue = false) => {
11078
+ let val = value || 0;
11079
+ if (!isPercentageValue) {
11080
+ val = val / 100;
11081
+ }
11082
+ return formatter.format(val);
11083
+ };
11084
+ function getPromotionIds(items, shippingMethods) {
11085
+ const promotionIds = /* @__PURE__ */ new Set();
11086
+ for (const item of items) {
11087
+ if (item.adjustments) {
11088
+ for (const adjustment of item.adjustments) {
11089
+ if (adjustment.promotion_id) {
11090
+ promotionIds.add(adjustment.promotion_id);
11091
+ }
11092
+ }
11093
+ }
11094
+ }
11095
+ for (const shippingMethod of shippingMethods) {
11096
+ if (shippingMethod.adjustments) {
11097
+ for (const adjustment of shippingMethod.adjustments) {
11098
+ if (adjustment.promotion_id) {
11099
+ promotionIds.add(adjustment.promotion_id);
11100
+ }
11101
+ }
11102
+ }
11103
+ }
11104
+ return Array.from(promotionIds);
11105
+ }
11106
+ const InlineTip = React.forwardRef(
11107
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
11108
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
11109
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11110
+ "div",
11111
+ {
11112
+ ref,
11113
+ className: ui.clx(
11114
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
11115
+ className
11116
+ ),
11117
+ ...props,
11118
+ children: [
11119
+ /* @__PURE__ */ jsxRuntime.jsx(
11120
+ "div",
11121
+ {
11122
+ role: "presentation",
11123
+ className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
11124
+ "bg-ui-tag-orange-icon": variant === "warning"
11125
+ })
11126
+ }
11127
+ ),
11128
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
11129
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
11130
+ labelValue,
11131
+ ":"
11132
+ ] }),
11133
+ " ",
11134
+ children
11135
+ ] })
11136
+ ]
11137
+ }
11138
+ );
11139
+ }
11140
+ );
11141
+ InlineTip.displayName = "InlineTip";
11142
+ const MetadataFieldSchema = objectType({
11143
+ key: stringType(),
11144
+ disabled: booleanType().optional(),
11145
+ value: anyType()
11146
+ });
11147
+ const MetadataSchema = objectType({
11148
+ metadata: arrayType(MetadataFieldSchema)
11149
+ });
11150
+ const Metadata = () => {
11151
+ const { id } = reactRouterDom.useParams();
11152
+ const { order, isPending, isError, error } = useOrder(id, {
11153
+ fields: "metadata"
11154
+ });
11155
+ if (isError) {
11156
+ throw error;
11157
+ }
11158
+ const isReady = !isPending && !!order;
11159
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
11160
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11161
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
11162
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
11163
+ ] }),
11164
+ !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
11165
+ ] });
11166
+ };
11167
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
11168
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
11169
+ const MetadataForm = ({ orderId, metadata }) => {
11170
+ const { handleSuccess } = useRouteModal();
11171
+ const hasUneditableRows = getHasUneditableRows(metadata);
11172
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
11173
+ const form = reactHookForm.useForm({
11174
+ defaultValues: {
11175
+ metadata: getDefaultValues(metadata)
11176
+ },
11177
+ resolver: zod.zodResolver(MetadataSchema)
11178
+ });
11179
+ const handleSubmit = form.handleSubmit(async (data) => {
11180
+ const parsedData = parseValues(data);
11181
+ await mutateAsync(
11182
+ {
11183
+ metadata: parsedData
11184
+ },
11185
+ {
11186
+ onSuccess: () => {
11187
+ ui.toast.success("Metadata updated");
11188
+ handleSuccess();
11189
+ },
11190
+ onError: (error) => {
11191
+ ui.toast.error(error.message);
11192
+ }
11193
+ }
11194
+ );
11195
+ });
11196
+ const { fields, insert, remove } = reactHookForm.useFieldArray({
11197
+ control: form.control,
11198
+ name: "metadata"
11199
+ });
11200
+ function deleteRow(index) {
11201
+ remove(index);
11202
+ if (fields.length === 1) {
11203
+ insert(0, {
11204
+ key: "",
11205
+ value: "",
11206
+ disabled: false
11207
+ });
11208
+ }
11209
+ }
11210
+ function insertRow(index, position) {
11211
+ insert(index + (position === "above" ? 0 : 1), {
11212
+ key: "",
11213
+ value: "",
11214
+ disabled: false
11215
+ });
11216
+ }
11217
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11218
+ KeyboundForm,
11219
+ {
11220
+ onSubmit: handleSubmit,
11221
+ className: "flex flex-1 flex-col overflow-hidden",
11379
11222
  children: [
11380
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11381
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11382
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
11383
- displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
11384
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
11385
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
11223
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
11224
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
11225
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
11226
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
11227
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
11386
11228
  ] }),
11387
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11388
- ] })
11229
+ fields.map((field, index) => {
11230
+ const isDisabled = field.disabled || false;
11231
+ let placeholder = "-";
11232
+ if (typeof field.value === "object") {
11233
+ placeholder = "{ ... }";
11234
+ }
11235
+ if (Array.isArray(field.value)) {
11236
+ placeholder = "[ ... ]";
11237
+ }
11238
+ return /* @__PURE__ */ jsxRuntime.jsx(
11239
+ ConditionalTooltip,
11240
+ {
11241
+ showTooltip: isDisabled,
11242
+ content: "This row is disabled because it contains non-primitive data.",
11243
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
11244
+ /* @__PURE__ */ jsxRuntime.jsxs(
11245
+ "div",
11246
+ {
11247
+ className: ui.clx("grid grid-cols-2 divide-x", {
11248
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
11249
+ }),
11250
+ children: [
11251
+ /* @__PURE__ */ jsxRuntime.jsx(
11252
+ Form$2.Field,
11253
+ {
11254
+ control: form.control,
11255
+ name: `metadata.${index}.key`,
11256
+ render: ({ field: field2 }) => {
11257
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11258
+ GridInput,
11259
+ {
11260
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
11261
+ ...field2,
11262
+ disabled: isDisabled,
11263
+ placeholder: "Key"
11264
+ }
11265
+ ) }) });
11266
+ }
11267
+ }
11268
+ ),
11269
+ /* @__PURE__ */ jsxRuntime.jsx(
11270
+ Form$2.Field,
11271
+ {
11272
+ control: form.control,
11273
+ name: `metadata.${index}.value`,
11274
+ render: ({ field: { value, ...field2 } }) => {
11275
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11276
+ GridInput,
11277
+ {
11278
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
11279
+ ...field2,
11280
+ value: isDisabled ? placeholder : value,
11281
+ disabled: isDisabled,
11282
+ placeholder: "Value"
11283
+ }
11284
+ ) }) });
11285
+ }
11286
+ }
11287
+ )
11288
+ ]
11289
+ }
11290
+ ),
11291
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
11292
+ /* @__PURE__ */ jsxRuntime.jsx(
11293
+ ui.DropdownMenu.Trigger,
11294
+ {
11295
+ className: ui.clx(
11296
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11297
+ {
11298
+ hidden: isDisabled
11299
+ }
11300
+ ),
11301
+ disabled: isDisabled,
11302
+ asChild: true,
11303
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
11304
+ }
11305
+ ),
11306
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
11307
+ /* @__PURE__ */ jsxRuntime.jsxs(
11308
+ ui.DropdownMenu.Item,
11309
+ {
11310
+ className: "gap-x-2",
11311
+ onClick: () => insertRow(index, "above"),
11312
+ children: [
11313
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
11314
+ "Insert row above"
11315
+ ]
11316
+ }
11317
+ ),
11318
+ /* @__PURE__ */ jsxRuntime.jsxs(
11319
+ ui.DropdownMenu.Item,
11320
+ {
11321
+ className: "gap-x-2",
11322
+ onClick: () => insertRow(index, "below"),
11323
+ children: [
11324
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
11325
+ "Insert row below"
11326
+ ]
11327
+ }
11328
+ ),
11329
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
11330
+ /* @__PURE__ */ jsxRuntime.jsxs(
11331
+ ui.DropdownMenu.Item,
11332
+ {
11333
+ className: "gap-x-2",
11334
+ onClick: () => deleteRow(index),
11335
+ children: [
11336
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
11337
+ "Delete row"
11338
+ ]
11339
+ }
11340
+ )
11341
+ ] })
11342
+ ] })
11343
+ ] })
11344
+ },
11345
+ field.id
11346
+ );
11347
+ })
11348
+ ] }),
11349
+ hasUneditableRows && /* @__PURE__ */ jsxRuntime.jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
11389
11350
  ] }),
11390
- /* @__PURE__ */ jsxRuntime.jsx(
11391
- ui.IconButton,
11392
- {
11393
- size: "small",
11394
- type: "button",
11395
- variant: "transparent",
11396
- onClick: onRemove,
11397
- isLoading: isPending || isLoading,
11398
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
11399
- }
11400
- )
11351
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11352
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11353
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11354
+ ] }) })
11401
11355
  ]
11402
- },
11403
- promotion.id
11404
- );
11356
+ }
11357
+ ) });
11405
11358
  };
11406
- function getDisplayValue(promotion) {
11407
- var _a, _b, _c, _d;
11408
- const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11409
- if (!value) {
11410
- return null;
11411
- }
11412
- if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11413
- const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11414
- if (!currency) {
11415
- return null;
11359
+ const GridInput = React.forwardRef(({ className, ...props }, ref) => {
11360
+ return /* @__PURE__ */ jsxRuntime.jsx(
11361
+ "input",
11362
+ {
11363
+ ref,
11364
+ ...props,
11365
+ autoComplete: "off",
11366
+ className: ui.clx(
11367
+ "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",
11368
+ className
11369
+ )
11416
11370
  }
11417
- return getLocaleAmount(value, currency);
11418
- } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11419
- return formatPercentage(value);
11420
- }
11421
- return null;
11422
- }
11423
- const formatter = new Intl.NumberFormat([], {
11424
- style: "percent",
11425
- minimumFractionDigits: 2
11371
+ );
11426
11372
  });
11427
- const formatPercentage = (value, isPercentageValue = false) => {
11428
- let val = value || 0;
11429
- if (!isPercentageValue) {
11430
- val = val / 100;
11431
- }
11432
- return formatter.format(val);
11373
+ GridInput.displayName = "MetadataForm.GridInput";
11374
+ const PlaceholderInner = () => {
11375
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11376
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11377
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11378
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
11379
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
11380
+ ] }) })
11381
+ ] });
11433
11382
  };
11434
- function getPromotionIds(items, shippingMethods) {
11435
- const promotionIds = /* @__PURE__ */ new Set();
11436
- for (const item of items) {
11437
- if (item.adjustments) {
11438
- for (const adjustment of item.adjustments) {
11439
- if (adjustment.promotion_id) {
11440
- promotionIds.add(adjustment.promotion_id);
11441
- }
11383
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
11384
+ function getDefaultValues(metadata) {
11385
+ if (!metadata || !Object.keys(metadata).length) {
11386
+ return [
11387
+ {
11388
+ key: "",
11389
+ value: "",
11390
+ disabled: false
11442
11391
  }
11392
+ ];
11393
+ }
11394
+ return Object.entries(metadata).map(([key, value]) => {
11395
+ if (!EDITABLE_TYPES.includes(typeof value)) {
11396
+ return {
11397
+ key,
11398
+ value,
11399
+ disabled: true
11400
+ };
11443
11401
  }
11402
+ let stringValue = value;
11403
+ if (typeof value !== "string") {
11404
+ stringValue = JSON.stringify(value);
11405
+ }
11406
+ return {
11407
+ key,
11408
+ value: stringValue,
11409
+ original_key: key
11410
+ };
11411
+ });
11412
+ }
11413
+ function parseValues(values) {
11414
+ const metadata = values.metadata;
11415
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11416
+ if (isEmpty) {
11417
+ return null;
11444
11418
  }
11445
- for (const shippingMethod of shippingMethods) {
11446
- if (shippingMethod.adjustments) {
11447
- for (const adjustment of shippingMethod.adjustments) {
11448
- if (adjustment.promotion_id) {
11449
- promotionIds.add(adjustment.promotion_id);
11450
- }
11419
+ const update = {};
11420
+ metadata.forEach((field) => {
11421
+ let key = field.key;
11422
+ let value = field.value;
11423
+ const disabled = field.disabled;
11424
+ if (!key || !value) {
11425
+ return;
11426
+ }
11427
+ if (disabled) {
11428
+ update[key] = value;
11429
+ return;
11430
+ }
11431
+ key = key.trim();
11432
+ value = value.trim();
11433
+ if (value === "true") {
11434
+ update[key] = true;
11435
+ } else if (value === "false") {
11436
+ update[key] = false;
11437
+ } else {
11438
+ const parsedNumber = parseFloat(value);
11439
+ if (!isNaN(parsedNumber)) {
11440
+ update[key] = parsedNumber;
11441
+ } else {
11442
+ update[key] = value;
11451
11443
  }
11452
11444
  }
11445
+ });
11446
+ return update;
11447
+ }
11448
+ function getHasUneditableRows(metadata) {
11449
+ if (!metadata) {
11450
+ return false;
11453
11451
  }
11454
- return Array.from(promotionIds);
11452
+ return Object.values(metadata).some(
11453
+ (value) => !EDITABLE_TYPES.includes(typeof value)
11454
+ );
11455
11455
  }
11456
- const ShippingAddress = () => {
11456
+ const SalesChannel = () => {
11457
11457
  const { id } = reactRouterDom.useParams();
11458
- const { order, isPending, isError, error } = useOrder(id, {
11459
- fields: "+shipping_address"
11460
- });
11458
+ const { draft_order, isPending, isError, error } = useDraftOrder(
11459
+ id,
11460
+ {
11461
+ fields: "+sales_channel_id"
11462
+ },
11463
+ {
11464
+ enabled: !!id
11465
+ }
11466
+ );
11461
11467
  if (isError) {
11462
11468
  throw error;
11463
11469
  }
11464
- const isReady = !isPending && !!order;
11470
+ const ISrEADY = !!draft_order && !isPending;
11465
11471
  return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
11466
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11467
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Shipping Address" }) }),
11468
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
11469
- ] }),
11470
- isReady && /* @__PURE__ */ jsxRuntime.jsx(ShippingAddressForm, { order })
11471
- ] });
11472
- };
11473
- const ShippingAddressForm = ({ order }) => {
11474
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
11475
- const form = reactHookForm.useForm({
11476
- defaultValues: {
11477
- first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
11478
- last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
11479
- company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
11480
- address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
11481
- address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
11482
- city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
11483
- province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
11484
- country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
11485
- postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
11486
- phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
11487
- },
11488
- resolver: zod.zodResolver(schema$2)
11489
- });
11490
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11491
- const { handleSuccess } = useRouteModal();
11492
- const onSubmit = form.handleSubmit(async (data) => {
11493
- await mutateAsync(
11494
- {
11495
- shipping_address: {
11496
- first_name: data.first_name,
11497
- last_name: data.last_name,
11498
- company: data.company,
11499
- address_1: data.address_1,
11500
- address_2: data.address_2,
11501
- city: data.city,
11502
- province: data.province,
11503
- country_code: data.country_code,
11504
- postal_code: data.postal_code,
11505
- phone: data.phone
11506
- }
11507
- },
11508
- {
11509
- onSuccess: () => {
11510
- handleSuccess();
11511
- },
11512
- onError: (error) => {
11513
- ui.toast.error(error.message);
11514
- }
11515
- }
11516
- );
11517
- });
11518
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11519
- KeyboundForm,
11520
- {
11521
- className: "flex flex-1 flex-col overflow-hidden",
11522
- onSubmit,
11523
- children: [
11524
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-4", children: [
11525
- /* @__PURE__ */ jsxRuntime.jsx(
11526
- Form$2.Field,
11527
- {
11528
- control: form.control,
11529
- name: "country_code",
11530
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11531
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Country" }),
11532
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(CountrySelect, { ...field }) }),
11533
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11534
- ] })
11535
- }
11536
- ),
11537
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11538
- /* @__PURE__ */ jsxRuntime.jsx(
11539
- Form$2.Field,
11540
- {
11541
- control: form.control,
11542
- name: "first_name",
11543
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11544
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "First name" }),
11545
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11546
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11547
- ] })
11548
- }
11549
- ),
11550
- /* @__PURE__ */ jsxRuntime.jsx(
11551
- Form$2.Field,
11552
- {
11553
- control: form.control,
11554
- name: "last_name",
11555
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11556
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Last name" }),
11557
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11558
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11559
- ] })
11560
- }
11561
- )
11562
- ] }),
11563
- /* @__PURE__ */ jsxRuntime.jsx(
11564
- Form$2.Field,
11565
- {
11566
- control: form.control,
11567
- name: "company",
11568
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11569
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Company" }),
11570
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11571
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11572
- ] })
11573
- }
11574
- ),
11575
- /* @__PURE__ */ jsxRuntime.jsx(
11576
- Form$2.Field,
11577
- {
11578
- control: form.control,
11579
- name: "address_1",
11580
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11581
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Address" }),
11582
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11583
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11584
- ] })
11585
- }
11586
- ),
11587
- /* @__PURE__ */ jsxRuntime.jsx(
11588
- Form$2.Field,
11589
- {
11590
- control: form.control,
11591
- name: "address_2",
11592
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11593
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
11594
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11595
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11596
- ] })
11597
- }
11598
- ),
11599
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11600
- /* @__PURE__ */ jsxRuntime.jsx(
11601
- Form$2.Field,
11602
- {
11603
- control: form.control,
11604
- name: "postal_code",
11605
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11606
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Postal code" }),
11607
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11608
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11609
- ] })
11610
- }
11611
- ),
11612
- /* @__PURE__ */ jsxRuntime.jsx(
11613
- Form$2.Field,
11614
- {
11615
- control: form.control,
11616
- name: "city",
11617
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11618
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "City" }),
11619
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11620
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11621
- ] })
11622
- }
11623
- )
11624
- ] }),
11625
- /* @__PURE__ */ jsxRuntime.jsx(
11626
- Form$2.Field,
11627
- {
11628
- control: form.control,
11629
- name: "province",
11630
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11631
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Province / State" }),
11632
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11633
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11634
- ] })
11635
- }
11636
- ),
11637
- /* @__PURE__ */ jsxRuntime.jsx(
11638
- Form$2.Field,
11639
- {
11640
- control: form.control,
11641
- name: "phone",
11642
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11643
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Phone" }),
11644
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11645
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11646
- ] })
11647
- }
11648
- )
11649
- ] }) }),
11472
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11473
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
11474
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
11475
+ ] }),
11476
+ ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
11477
+ ] });
11478
+ };
11479
+ const SalesChannelForm = ({ order }) => {
11480
+ const form = reactHookForm.useForm({
11481
+ defaultValues: {
11482
+ sales_channel_id: order.sales_channel_id || ""
11483
+ },
11484
+ resolver: zod.zodResolver(schema$2)
11485
+ });
11486
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11487
+ const { handleSuccess } = useRouteModal();
11488
+ const onSubmit = form.handleSubmit(async (data) => {
11489
+ await mutateAsync(
11490
+ {
11491
+ sales_channel_id: data.sales_channel_id
11492
+ },
11493
+ {
11494
+ onSuccess: () => {
11495
+ ui.toast.success("Sales channel updated");
11496
+ handleSuccess();
11497
+ },
11498
+ onError: (error) => {
11499
+ ui.toast.error(error.message);
11500
+ }
11501
+ }
11502
+ );
11503
+ });
11504
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11505
+ KeyboundForm,
11506
+ {
11507
+ className: "flex flex-1 flex-col overflow-hidden",
11508
+ onSubmit,
11509
+ children: [
11510
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
11650
11511
  /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11651
11512
  /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11652
11513
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
@@ -11655,7 +11516,49 @@ const ShippingAddressForm = ({ order }) => {
11655
11516
  }
11656
11517
  ) });
11657
11518
  };
11658
- const schema$2 = addressSchema;
11519
+ const SalesChannelField = ({ control, order }) => {
11520
+ const salesChannels = useComboboxData({
11521
+ queryFn: async (params) => {
11522
+ return await sdk.admin.salesChannel.list(params);
11523
+ },
11524
+ queryKey: ["sales-channels"],
11525
+ getOptions: (data) => {
11526
+ return data.sales_channels.map((salesChannel) => ({
11527
+ label: salesChannel.name,
11528
+ value: salesChannel.id
11529
+ }));
11530
+ },
11531
+ defaultValue: order.sales_channel_id || void 0
11532
+ });
11533
+ return /* @__PURE__ */ jsxRuntime.jsx(
11534
+ Form$2.Field,
11535
+ {
11536
+ control,
11537
+ name: "sales_channel_id",
11538
+ render: ({ field }) => {
11539
+ return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11540
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
11541
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11542
+ Combobox,
11543
+ {
11544
+ options: salesChannels.options,
11545
+ fetchNextPage: salesChannels.fetchNextPage,
11546
+ isFetchingNextPage: salesChannels.isFetchingNextPage,
11547
+ searchValue: salesChannels.searchValue,
11548
+ onSearchValueChange: salesChannels.onSearchValueChange,
11549
+ placeholder: "Select sales channel",
11550
+ ...field
11551
+ }
11552
+ ) }),
11553
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11554
+ ] });
11555
+ }
11556
+ }
11557
+ );
11558
+ };
11559
+ const schema$2 = objectType({
11560
+ sales_channel_id: stringType().min(1)
11561
+ });
11659
11562
  const STACKED_FOCUS_MODAL_ID = "shipping-form";
11660
11563
  const Shipping = () => {
11661
11564
  var _a;
@@ -12410,59 +12313,262 @@ const ShippingOptionField = ({
12410
12313
  /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose the shipping option to use." })
12411
12314
  ] }),
12412
12315
  /* @__PURE__ */ jsxRuntime.jsx(
12413
- ConditionalTooltip,
12316
+ ConditionalTooltip,
12317
+ {
12318
+ content: tooltipContent,
12319
+ showTooltip: !locationId || !shippingProfileId,
12320
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12321
+ Combobox,
12322
+ {
12323
+ options: shippingOptions.options,
12324
+ fetchNextPage: shippingOptions.fetchNextPage,
12325
+ isFetchingNextPage: shippingOptions.isFetchingNextPage,
12326
+ searchValue: shippingOptions.searchValue,
12327
+ onSearchValueChange: shippingOptions.onSearchValueChange,
12328
+ placeholder: "Select shipping option",
12329
+ ...field,
12330
+ disabled: !locationId || !shippingProfileId
12331
+ }
12332
+ ) }) })
12333
+ }
12334
+ )
12335
+ ] }) });
12336
+ }
12337
+ }
12338
+ );
12339
+ };
12340
+ const CustomAmountField = ({
12341
+ control,
12342
+ currencyCode
12343
+ }) => {
12344
+ return /* @__PURE__ */ jsxRuntime.jsx(
12345
+ Form$2.Field,
12346
+ {
12347
+ control,
12348
+ name: "custom_amount",
12349
+ render: ({ field: { onChange, ...field } }) => {
12350
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12351
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12352
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12353
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12354
+ ] }),
12355
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12356
+ ui.CurrencyInput,
12357
+ {
12358
+ ...field,
12359
+ onValueChange: (value) => onChange(value),
12360
+ symbol: getNativeSymbol(currencyCode),
12361
+ code: currencyCode
12362
+ }
12363
+ ) })
12364
+ ] });
12365
+ }
12366
+ }
12367
+ );
12368
+ };
12369
+ const ShippingAddress = () => {
12370
+ const { id } = reactRouterDom.useParams();
12371
+ const { order, isPending, isError, error } = useOrder(id, {
12372
+ fields: "+shipping_address"
12373
+ });
12374
+ if (isError) {
12375
+ throw error;
12376
+ }
12377
+ const isReady = !isPending && !!order;
12378
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
12379
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
12380
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Shipping Address" }) }),
12381
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
12382
+ ] }),
12383
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(ShippingAddressForm, { order })
12384
+ ] });
12385
+ };
12386
+ const ShippingAddressForm = ({ order }) => {
12387
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12388
+ const form = reactHookForm.useForm({
12389
+ defaultValues: {
12390
+ first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
12391
+ last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
12392
+ company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
12393
+ address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
12394
+ address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
12395
+ city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
12396
+ province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
12397
+ country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
12398
+ postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12399
+ phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12400
+ },
12401
+ resolver: zod.zodResolver(schema$1)
12402
+ });
12403
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12404
+ const { handleSuccess } = useRouteModal();
12405
+ const onSubmit = form.handleSubmit(async (data) => {
12406
+ await mutateAsync(
12407
+ {
12408
+ shipping_address: {
12409
+ first_name: data.first_name,
12410
+ last_name: data.last_name,
12411
+ company: data.company,
12412
+ address_1: data.address_1,
12413
+ address_2: data.address_2,
12414
+ city: data.city,
12415
+ province: data.province,
12416
+ country_code: data.country_code,
12417
+ postal_code: data.postal_code,
12418
+ phone: data.phone
12419
+ }
12420
+ },
12421
+ {
12422
+ onSuccess: () => {
12423
+ handleSuccess();
12424
+ },
12425
+ onError: (error) => {
12426
+ ui.toast.error(error.message);
12427
+ }
12428
+ }
12429
+ );
12430
+ });
12431
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12432
+ KeyboundForm,
12433
+ {
12434
+ className: "flex flex-1 flex-col overflow-hidden",
12435
+ onSubmit,
12436
+ children: [
12437
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-4", children: [
12438
+ /* @__PURE__ */ jsxRuntime.jsx(
12439
+ Form$2.Field,
12440
+ {
12441
+ control: form.control,
12442
+ name: "country_code",
12443
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12444
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Country" }),
12445
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(CountrySelect, { ...field }) }),
12446
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12447
+ ] })
12448
+ }
12449
+ ),
12450
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12451
+ /* @__PURE__ */ jsxRuntime.jsx(
12452
+ Form$2.Field,
12453
+ {
12454
+ control: form.control,
12455
+ name: "first_name",
12456
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12457
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "First name" }),
12458
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12459
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12460
+ ] })
12461
+ }
12462
+ ),
12463
+ /* @__PURE__ */ jsxRuntime.jsx(
12464
+ Form$2.Field,
12465
+ {
12466
+ control: form.control,
12467
+ name: "last_name",
12468
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12469
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Last name" }),
12470
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12471
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12472
+ ] })
12473
+ }
12474
+ )
12475
+ ] }),
12476
+ /* @__PURE__ */ jsxRuntime.jsx(
12477
+ Form$2.Field,
12478
+ {
12479
+ control: form.control,
12480
+ name: "company",
12481
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12482
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Company" }),
12483
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12484
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12485
+ ] })
12486
+ }
12487
+ ),
12488
+ /* @__PURE__ */ jsxRuntime.jsx(
12489
+ Form$2.Field,
12490
+ {
12491
+ control: form.control,
12492
+ name: "address_1",
12493
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12494
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Address" }),
12495
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12496
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12497
+ ] })
12498
+ }
12499
+ ),
12500
+ /* @__PURE__ */ jsxRuntime.jsx(
12501
+ Form$2.Field,
12414
12502
  {
12415
- content: tooltipContent,
12416
- showTooltip: !locationId || !shippingProfileId,
12417
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12418
- Combobox,
12419
- {
12420
- options: shippingOptions.options,
12421
- fetchNextPage: shippingOptions.fetchNextPage,
12422
- isFetchingNextPage: shippingOptions.isFetchingNextPage,
12423
- searchValue: shippingOptions.searchValue,
12424
- onSearchValueChange: shippingOptions.onSearchValueChange,
12425
- placeholder: "Select shipping option",
12426
- ...field,
12427
- disabled: !locationId || !shippingProfileId
12428
- }
12429
- ) }) })
12503
+ control: form.control,
12504
+ name: "address_2",
12505
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12506
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12507
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12508
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12509
+ ] })
12430
12510
  }
12431
- )
12432
- ] }) });
12433
- }
12434
- }
12435
- );
12436
- };
12437
- const CustomAmountField = ({
12438
- control,
12439
- currencyCode
12440
- }) => {
12441
- return /* @__PURE__ */ jsxRuntime.jsx(
12442
- Form$2.Field,
12443
- {
12444
- control,
12445
- name: "custom_amount",
12446
- render: ({ field: { onChange, ...field } }) => {
12447
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12448
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12449
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12450
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12511
+ ),
12512
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12513
+ /* @__PURE__ */ jsxRuntime.jsx(
12514
+ Form$2.Field,
12515
+ {
12516
+ control: form.control,
12517
+ name: "postal_code",
12518
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12519
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Postal code" }),
12520
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12521
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12522
+ ] })
12523
+ }
12524
+ ),
12525
+ /* @__PURE__ */ jsxRuntime.jsx(
12526
+ Form$2.Field,
12527
+ {
12528
+ control: form.control,
12529
+ name: "city",
12530
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12531
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "City" }),
12532
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12533
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12534
+ ] })
12535
+ }
12536
+ )
12451
12537
  ] }),
12452
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12453
- ui.CurrencyInput,
12538
+ /* @__PURE__ */ jsxRuntime.jsx(
12539
+ Form$2.Field,
12454
12540
  {
12455
- ...field,
12456
- onValueChange: (value) => onChange(value),
12457
- symbol: getNativeSymbol(currencyCode),
12458
- code: currencyCode
12541
+ control: form.control,
12542
+ name: "province",
12543
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12544
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Province / State" }),
12545
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12546
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12547
+ ] })
12459
12548
  }
12460
- ) })
12461
- ] });
12462
- }
12549
+ ),
12550
+ /* @__PURE__ */ jsxRuntime.jsx(
12551
+ Form$2.Field,
12552
+ {
12553
+ control: form.control,
12554
+ name: "phone",
12555
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12556
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Phone" }),
12557
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12558
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12559
+ ] })
12560
+ }
12561
+ )
12562
+ ] }) }),
12563
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
12564
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12565
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12566
+ ] }) })
12567
+ ]
12463
12568
  }
12464
- );
12569
+ ) });
12465
12570
  };
12571
+ const schema$1 = addressSchema;
12466
12572
  const TransferOwnership = () => {
12467
12573
  const { id } = reactRouterDom.useParams();
12468
12574
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -12486,7 +12592,7 @@ const TransferOwnershipForm = ({ order }) => {
12486
12592
  defaultValues: {
12487
12593
  customer_id: order.customer_id || ""
12488
12594
  },
12489
- resolver: zod.zodResolver(schema$1)
12595
+ resolver: zod.zodResolver(schema)
12490
12596
  });
12491
12597
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12492
12598
  const { handleSuccess } = useRouteModal();
@@ -12936,114 +13042,8 @@ const Illustration = () => {
12936
13042
  }
12937
13043
  );
12938
13044
  };
12939
- const schema$1 = objectType({
12940
- customer_id: stringType().min(1)
12941
- });
12942
- const SalesChannel = () => {
12943
- const { id } = reactRouterDom.useParams();
12944
- const { draft_order, isPending, isError, error } = useDraftOrder(
12945
- id,
12946
- {
12947
- fields: "+sales_channel_id"
12948
- },
12949
- {
12950
- enabled: !!id
12951
- }
12952
- );
12953
- if (isError) {
12954
- throw error;
12955
- }
12956
- const ISrEADY = !!draft_order && !isPending;
12957
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
12958
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
12959
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
12960
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
12961
- ] }),
12962
- ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
12963
- ] });
12964
- };
12965
- const SalesChannelForm = ({ order }) => {
12966
- const form = reactHookForm.useForm({
12967
- defaultValues: {
12968
- sales_channel_id: order.sales_channel_id || ""
12969
- },
12970
- resolver: zod.zodResolver(schema)
12971
- });
12972
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12973
- const { handleSuccess } = useRouteModal();
12974
- const onSubmit = form.handleSubmit(async (data) => {
12975
- await mutateAsync(
12976
- {
12977
- sales_channel_id: data.sales_channel_id
12978
- },
12979
- {
12980
- onSuccess: () => {
12981
- ui.toast.success("Sales channel updated");
12982
- handleSuccess();
12983
- },
12984
- onError: (error) => {
12985
- ui.toast.error(error.message);
12986
- }
12987
- }
12988
- );
12989
- });
12990
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12991
- KeyboundForm,
12992
- {
12993
- className: "flex flex-1 flex-col overflow-hidden",
12994
- onSubmit,
12995
- children: [
12996
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
12997
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
12998
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12999
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
13000
- ] }) })
13001
- ]
13002
- }
13003
- ) });
13004
- };
13005
- const SalesChannelField = ({ control, order }) => {
13006
- const salesChannels = useComboboxData({
13007
- queryFn: async (params) => {
13008
- return await sdk.admin.salesChannel.list(params);
13009
- },
13010
- queryKey: ["sales-channels"],
13011
- getOptions: (data) => {
13012
- return data.sales_channels.map((salesChannel) => ({
13013
- label: salesChannel.name,
13014
- value: salesChannel.id
13015
- }));
13016
- },
13017
- defaultValue: order.sales_channel_id || void 0
13018
- });
13019
- return /* @__PURE__ */ jsxRuntime.jsx(
13020
- Form$2.Field,
13021
- {
13022
- control,
13023
- name: "sales_channel_id",
13024
- render: ({ field }) => {
13025
- return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
13026
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
13027
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
13028
- Combobox,
13029
- {
13030
- options: salesChannels.options,
13031
- fetchNextPage: salesChannels.fetchNextPage,
13032
- isFetchingNextPage: salesChannels.isFetchingNextPage,
13033
- searchValue: salesChannels.searchValue,
13034
- onSearchValueChange: salesChannels.onSearchValueChange,
13035
- placeholder: "Select sales channel",
13036
- ...field
13037
- }
13038
- ) }),
13039
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
13040
- ] });
13041
- }
13042
- }
13043
- );
13044
- };
13045
13045
  const schema = objectType({
13046
- sales_channel_id: stringType().min(1)
13046
+ customer_id: stringType().min(1)
13047
13047
  });
13048
13048
  const widgetModule = { widgets: [] };
13049
13049
  const routeModule = {
@@ -13065,14 +13065,14 @@ const routeModule = {
13065
13065
  handle,
13066
13066
  loader,
13067
13067
  children: [
13068
- {
13069
- Component: BillingAddress,
13070
- path: "/draft-orders/:id/billing-address"
13071
- },
13072
13068
  {
13073
13069
  Component: CustomItems,
13074
13070
  path: "/draft-orders/:id/custom-items"
13075
13071
  },
13072
+ {
13073
+ Component: BillingAddress,
13074
+ path: "/draft-orders/:id/billing-address"
13075
+ },
13076
13076
  {
13077
13077
  Component: Email,
13078
13078
  path: "/draft-orders/:id/email"
@@ -13081,29 +13081,29 @@ const routeModule = {
13081
13081
  Component: Items,
13082
13082
  path: "/draft-orders/:id/items"
13083
13083
  },
13084
- {
13085
- Component: Metadata,
13086
- path: "/draft-orders/:id/metadata"
13087
- },
13088
13084
  {
13089
13085
  Component: Promotions,
13090
13086
  path: "/draft-orders/:id/promotions"
13091
13087
  },
13092
13088
  {
13093
- Component: ShippingAddress,
13094
- path: "/draft-orders/:id/shipping-address"
13089
+ Component: Metadata,
13090
+ path: "/draft-orders/:id/metadata"
13091
+ },
13092
+ {
13093
+ Component: SalesChannel,
13094
+ path: "/draft-orders/:id/sales-channel"
13095
13095
  },
13096
13096
  {
13097
13097
  Component: Shipping,
13098
13098
  path: "/draft-orders/:id/shipping"
13099
13099
  },
13100
13100
  {
13101
- Component: TransferOwnership,
13102
- path: "/draft-orders/:id/transfer-ownership"
13101
+ Component: ShippingAddress,
13102
+ path: "/draft-orders/:id/shipping-address"
13103
13103
  },
13104
13104
  {
13105
- Component: SalesChannel,
13106
- path: "/draft-orders/:id/sales-channel"
13105
+ Component: TransferOwnership,
13106
+ path: "/draft-orders/:id/transfer-ownership"
13107
13107
  }
13108
13108
  ]
13109
13109
  }