@medusajs/draft-order 0.0.8 → 0.0.9

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.
@@ -9712,95 +9712,6 @@ const ID = () => {
9712
9712
  /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Outlet, {})
9713
9713
  ] });
9714
9714
  };
9715
- const CustomItems = () => {
9716
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9717
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9718
- /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9719
- ] });
9720
- };
9721
- const CustomItemsForm = () => {
9722
- const form = reactHookForm.useForm({
9723
- resolver: zod.zodResolver(schema$5)
9724
- });
9725
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9726
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9727
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9728
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9729
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9730
- ] }) })
9731
- ] }) });
9732
- };
9733
- const schema$5 = z.object({
9734
- email: z.string().email()
9735
- });
9736
- const Email = () => {
9737
- const { id } = reactRouterDom.useParams();
9738
- const { order, isPending, isError, error } = useOrder(id, {
9739
- fields: "+email"
9740
- });
9741
- if (isError) {
9742
- throw error;
9743
- }
9744
- const isReady = !isPending && !!order;
9745
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9746
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
9747
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Email" }) }),
9748
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
9749
- ] }),
9750
- isReady && /* @__PURE__ */ jsxRuntime.jsx(EmailForm, { order })
9751
- ] });
9752
- };
9753
- const EmailForm = ({ order }) => {
9754
- const form = reactHookForm.useForm({
9755
- defaultValues: {
9756
- email: order.email ?? ""
9757
- },
9758
- resolver: zod.zodResolver(schema$4)
9759
- });
9760
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9761
- const { handleSuccess } = useRouteModal();
9762
- const onSubmit = form.handleSubmit(async (data) => {
9763
- await mutateAsync(
9764
- { email: data.email },
9765
- {
9766
- onSuccess: () => {
9767
- handleSuccess();
9768
- },
9769
- onError: (error) => {
9770
- ui.toast.error(error.message);
9771
- }
9772
- }
9773
- );
9774
- });
9775
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
9776
- KeyboundForm,
9777
- {
9778
- className: "flex flex-1 flex-col overflow-hidden",
9779
- onSubmit,
9780
- children: [
9781
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
9782
- Form$2.Field,
9783
- {
9784
- control: form.control,
9785
- name: "email",
9786
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9787
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Email" }),
9788
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9789
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9790
- ] })
9791
- }
9792
- ) }),
9793
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9794
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9795
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
9796
- ] }) })
9797
- ]
9798
- }
9799
- ) });
9800
- };
9801
- const schema$4 = z.object({
9802
- email: z.string().email()
9803
- });
9804
9715
  const BillingAddress = () => {
9805
9716
  const { id } = reactRouterDom.useParams();
9806
9717
  const { order, isPending, isError, error } = useOrder(id, {
@@ -9833,7 +9744,7 @@ const BillingAddressForm = ({ order }) => {
9833
9744
  postal_code: ((_i = order.billing_address) == null ? void 0 : _i.postal_code) ?? "",
9834
9745
  phone: ((_j = order.billing_address) == null ? void 0 : _j.phone) ?? ""
9835
9746
  },
9836
- resolver: zod.zodResolver(schema$3)
9747
+ resolver: zod.zodResolver(schema$5)
9837
9748
  });
9838
9749
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9839
9750
  const { handleSuccess } = useRouteModal();
@@ -9990,23 +9901,149 @@ const BillingAddressForm = ({ order }) => {
9990
9901
  }
9991
9902
  ) });
9992
9903
  };
9993
- const schema$3 = addressSchema;
9994
- const PROMOTION_QUERY_KEY = "promotions";
9995
- const promotionsQueryKeys = {
9904
+ const schema$5 = addressSchema;
9905
+ const CustomItems = () => {
9906
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9907
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9908
+ /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9909
+ ] });
9910
+ };
9911
+ const CustomItemsForm = () => {
9912
+ const form = reactHookForm.useForm({
9913
+ resolver: zod.zodResolver(schema$4)
9914
+ });
9915
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9916
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9917
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9918
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9919
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9920
+ ] }) })
9921
+ ] }) });
9922
+ };
9923
+ const schema$4 = z.object({
9924
+ email: z.string().email()
9925
+ });
9926
+ const NumberInput = React.forwardRef(
9927
+ ({
9928
+ value,
9929
+ onChange,
9930
+ size = "base",
9931
+ min = 0,
9932
+ max = 100,
9933
+ step = 1,
9934
+ className,
9935
+ disabled,
9936
+ ...props
9937
+ }, ref) => {
9938
+ const handleChange = (event) => {
9939
+ const newValue = event.target.value === "" ? min : Number(event.target.value);
9940
+ if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
9941
+ onChange(newValue);
9942
+ }
9943
+ };
9944
+ const handleIncrement = () => {
9945
+ const newValue = value + step;
9946
+ if (max === void 0 || newValue <= max) {
9947
+ onChange(newValue);
9948
+ }
9949
+ };
9950
+ const handleDecrement = () => {
9951
+ const newValue = value - step;
9952
+ if (min === void 0 || newValue >= min) {
9953
+ onChange(newValue);
9954
+ }
9955
+ };
9956
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9957
+ "div",
9958
+ {
9959
+ className: ui.clx(
9960
+ "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
9961
+ "[&:has(input:focus)]:shadow-borders-interactive-with-active",
9962
+ {
9963
+ "h-7": size === "small",
9964
+ "h-8": size === "base"
9965
+ },
9966
+ className
9967
+ ),
9968
+ children: [
9969
+ /* @__PURE__ */ jsxRuntime.jsx(
9970
+ "input",
9971
+ {
9972
+ ref,
9973
+ type: "number",
9974
+ value,
9975
+ onChange: handleChange,
9976
+ min,
9977
+ max,
9978
+ step,
9979
+ className: ui.clx(
9980
+ "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
9981
+ "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
9982
+ "placeholder:text-ui-fg-muted"
9983
+ ),
9984
+ ...props
9985
+ }
9986
+ ),
9987
+ /* @__PURE__ */ jsxRuntime.jsxs(
9988
+ "button",
9989
+ {
9990
+ className: ui.clx(
9991
+ "flex items-center justify-center outline-none transition-fg",
9992
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9993
+ "focus:bg-ui-bg-field-component-hover",
9994
+ "hover:bg-ui-bg-field-component-hover",
9995
+ {
9996
+ "size-7": size === "small",
9997
+ "size-8": size === "base"
9998
+ }
9999
+ ),
10000
+ type: "button",
10001
+ onClick: handleDecrement,
10002
+ disabled: min !== void 0 && value <= min || disabled,
10003
+ children: [
10004
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Minus, {}),
10005
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
10006
+ ]
10007
+ }
10008
+ ),
10009
+ /* @__PURE__ */ jsxRuntime.jsxs(
10010
+ "button",
10011
+ {
10012
+ className: ui.clx(
10013
+ "flex items-center justify-center outline-none transition-fg",
10014
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10015
+ "focus:bg-ui-bg-field-hover",
10016
+ "hover:bg-ui-bg-field-hover",
10017
+ {
10018
+ "size-7": size === "small",
10019
+ "size-8": size === "base"
10020
+ }
10021
+ ),
10022
+ type: "button",
10023
+ onClick: handleIncrement,
10024
+ disabled: max !== void 0 && value >= max || disabled,
10025
+ children: [
10026
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
10027
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Increase by ${step}` })
10028
+ ]
10029
+ }
10030
+ )
10031
+ ]
10032
+ }
10033
+ );
10034
+ }
10035
+ );
10036
+ const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
10037
+ const productVariantsQueryKeys = {
9996
10038
  list: (query2) => [
9997
- PROMOTION_QUERY_KEY,
9998
- query2 ? query2 : void 0
9999
- ],
10000
- detail: (id, query2) => [
10001
- PROMOTION_QUERY_KEY,
10002
- id,
10039
+ PRODUCT_VARIANTS_QUERY_KEY,
10003
10040
  query2 ? query2 : void 0
10004
10041
  ]
10005
10042
  };
10006
- const usePromotions = (query2, options) => {
10043
+ const useProductVariants = (query2, options) => {
10007
10044
  const { data, ...rest } = reactQuery.useQuery({
10008
- queryKey: promotionsQueryKeys.list(query2),
10009
- queryFn: async () => sdk.admin.promotion.list(query2),
10045
+ queryKey: productVariantsQueryKeys.list(query2),
10046
+ queryFn: async () => await sdk.admin.productVariant.list(query2),
10010
10047
  ...options
10011
10048
  });
10012
10049
  return { ...data, ...rest };
@@ -10057,85 +10094,65 @@ const useInitiateOrderEdit = ({
10057
10094
  run();
10058
10095
  }, [preview, navigate, mutateAsync]);
10059
10096
  };
10060
- const Promotions = () => {
10097
+ function convertNumber(value) {
10098
+ return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10099
+ }
10100
+ const STACKED_MODAL_ID = "items_stacked_modal";
10101
+ const Items = () => {
10061
10102
  const { id } = reactRouterDom.useParams();
10062
10103
  const {
10063
10104
  order: preview,
10105
+ isPending: isPreviewPending,
10064
10106
  isError: isPreviewError,
10065
10107
  error: previewError
10066
- } = useOrderPreview(id, void 0);
10108
+ } = useOrderPreview(id, void 0, {
10109
+ placeholderData: reactQuery.keepPreviousData
10110
+ });
10067
10111
  useInitiateOrderEdit({ preview });
10068
- const { onCancel } = useCancelOrderEdit({ preview });
10069
- if (isPreviewError) {
10070
- throw previewError;
10071
- }
10072
- const isReady = !!preview;
10073
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
10074
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
10075
- isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
10076
- ] });
10077
- };
10078
- const PromotionForm = ({ preview }) => {
10079
- const { items, shipping_methods } = preview;
10080
- const [isSubmitting, setIsSubmitting] = React.useState(false);
10081
- const [comboboxValue, setComboboxValue] = React.useState("");
10082
- const { handleSuccess } = useRouteModal();
10083
- const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
10084
- const promoCodes = getPromotionCodes(items, shipping_methods);
10085
- const { promotions, isPending, isError, error } = usePromotions(
10112
+ const { draft_order, isPending, isError, error } = useDraftOrder(
10113
+ id,
10086
10114
  {
10087
- code: promoCodes
10115
+ fields: "currency_code"
10088
10116
  },
10089
10117
  {
10090
- enabled: !!promoCodes.length
10118
+ enabled: !!id
10091
10119
  }
10092
10120
  );
10093
- const comboboxData = useComboboxData({
10094
- queryKey: ["promotions", "combobox", promoCodes],
10095
- queryFn: async (params) => {
10096
- return await sdk.admin.promotion.list({
10097
- ...params,
10098
- code: {
10099
- $nin: promoCodes
10100
- }
10101
- });
10102
- },
10103
- getOptions: (data) => {
10104
- return data.promotions.map((promotion) => ({
10105
- label: promotion.code,
10106
- value: promotion.code
10107
- }));
10108
- }
10109
- });
10110
- const add = async (value) => {
10111
- if (!value) {
10112
- return;
10113
- }
10114
- addPromotions(
10115
- {
10116
- promo_codes: [value]
10117
- },
10118
- {
10119
- onError: (e) => {
10120
- ui.toast.error(e.message);
10121
- comboboxData.onSearchValueChange("");
10122
- setComboboxValue("");
10123
- },
10124
- onSuccess: () => {
10125
- comboboxData.onSearchValueChange("");
10126
- setComboboxValue("");
10127
- }
10128
- }
10129
- );
10130
- };
10121
+ const { onCancel } = useCancelOrderEdit({ preview });
10122
+ if (isError) {
10123
+ throw error;
10124
+ }
10125
+ if (isPreviewError) {
10126
+ throw previewError;
10127
+ }
10128
+ const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10129
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsxRuntime.jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10130
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10131
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10132
+ ] }) });
10133
+ };
10134
+ const ItemsForm = ({ preview, currencyCode }) => {
10135
+ var _a;
10136
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
10137
+ const [modalContent, setModalContent] = React.useState(
10138
+ null
10139
+ );
10140
+ const { handleSuccess } = useRouteModal();
10141
+ const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10131
10142
  const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10132
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
10143
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10144
+ const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10145
+ const matches = React.useMemo(() => {
10146
+ return matchSorter.matchSorter(preview.items, query2, {
10147
+ keys: ["product_title", "variant_title", "variant_sku", "title"]
10148
+ });
10149
+ }, [preview.items, query2]);
10133
10150
  const onSubmit = async () => {
10134
10151
  setIsSubmitting(true);
10135
10152
  let requestSucceeded = false;
10136
10153
  await requestOrderEdit(void 0, {
10137
10154
  onError: (e) => {
10138
- ui.toast.error(e.message);
10155
+ ui.toast.error(`Failed to request order edit: ${e.message}`);
10139
10156
  },
10140
10157
  onSuccess: () => {
10141
10158
  requestSucceeded = true;
@@ -10147,7 +10164,7 @@ const PromotionForm = ({ preview }) => {
10147
10164
  }
10148
10165
  await confirmOrderEdit(void 0, {
10149
10166
  onError: (e) => {
10150
- ui.toast.error(e.message);
10167
+ ui.toast.error(`Failed to confirm order edit: ${e.message}`);
10151
10168
  },
10152
10169
  onSuccess: () => {
10153
10170
  handleSuccess();
@@ -10157,621 +10174,401 @@ const PromotionForm = ({ preview }) => {
10157
10174
  }
10158
10175
  });
10159
10176
  };
10160
- if (isError) {
10161
- throw error;
10162
- }
10163
- return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
10164
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
10165
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
10166
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10167
- /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
10168
- /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
10169
- ] }),
10170
- /* @__PURE__ */ jsxRuntime.jsx(
10171
- Combobox,
10172
- {
10173
- id: "promotion-combobox",
10174
- "aria-describedby": "promotion-combobox-hint",
10175
- isFetchingNextPage: comboboxData.isFetchingNextPage,
10176
- fetchNextPage: comboboxData.fetchNextPage,
10177
- options: comboboxData.options,
10178
- onSearchValueChange: comboboxData.onSearchValueChange,
10179
- searchValue: comboboxData.searchValue,
10180
- disabled: comboboxData.disabled || isAddingPromotions,
10181
- onChange: add,
10182
- value: comboboxValue
10177
+ const onKeyDown = React.useCallback(
10178
+ (e) => {
10179
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10180
+ if (modalContent || isSubmitting) {
10181
+ return;
10182
+ }
10183
+ onSubmit();
10184
+ }
10185
+ },
10186
+ [modalContent, isSubmitting, onSubmit]
10187
+ );
10188
+ React.useEffect(() => {
10189
+ document.addEventListener("keydown", onKeyDown);
10190
+ return () => {
10191
+ document.removeEventListener("keydown", onKeyDown);
10192
+ };
10193
+ }, [onKeyDown]);
10194
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10195
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
10196
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
10197
+ StackedFocusModal,
10198
+ {
10199
+ id: STACKED_MODAL_ID,
10200
+ onOpenChangeCallback: (open) => {
10201
+ if (!open) {
10202
+ setModalContent(null);
10183
10203
  }
10184
- )
10185
- ] }),
10186
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10187
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
10188
- PromotionItem,
10189
- {
10190
- promotion,
10191
- orderId: preview.id,
10192
- isLoading: isPending
10193
10204
  },
10194
- promotion.id
10195
- )) })
10196
- ] }) }),
10197
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
10198
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10205
+ children: [
10206
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-6 py-16", children: [
10207
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10208
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Items" }) }),
10209
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Edit the items in the draft order." }) })
10210
+ ] }),
10211
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10212
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
10213
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10214
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10215
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10216
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10217
+ ] }),
10218
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10219
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10220
+ ui.Input,
10221
+ {
10222
+ type: "search",
10223
+ placeholder: "Search items",
10224
+ value: searchValue,
10225
+ onChange: (e) => onSearchValueChange(e.target.value)
10226
+ }
10227
+ ) }),
10228
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
10229
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}) }) }),
10230
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
10231
+ /* @__PURE__ */ jsxRuntime.jsx(
10232
+ StackedModalTrigger$1,
10233
+ {
10234
+ type: "add-items",
10235
+ setModalContent
10236
+ }
10237
+ ),
10238
+ /* @__PURE__ */ jsxRuntime.jsx(
10239
+ StackedModalTrigger$1,
10240
+ {
10241
+ type: "add-custom-item",
10242
+ setModalContent
10243
+ }
10244
+ )
10245
+ ] })
10246
+ ] })
10247
+ ] })
10248
+ ] }),
10249
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10250
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_1fr_1fr_28px] gap-3 px-4 py-2 text-ui-fg-muted", children: [
10251
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
10252
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10253
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Price" }) }),
10254
+ /* @__PURE__ */ jsxRuntime.jsx("div", {})
10255
+ ] }) }),
10256
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
10257
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10258
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10259
+ ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
10260
+ Item,
10261
+ {
10262
+ item,
10263
+ preview,
10264
+ currencyCode
10265
+ },
10266
+ item.id
10267
+ )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
10268
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10269
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
10270
+ 'No items found for "',
10271
+ query2,
10272
+ '".'
10273
+ ] })
10274
+ ] }) })
10275
+ ] })
10276
+ ] }),
10277
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10278
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10279
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10280
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(
10281
+ ui.Text,
10282
+ {
10283
+ size: "small",
10284
+ leading: "compact",
10285
+ className: "text-ui-fg-subtle",
10286
+ children: [
10287
+ itemCount,
10288
+ " ",
10289
+ itemCount === 1 ? "item" : "items"
10290
+ ]
10291
+ }
10292
+ ) }),
10293
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10294
+ ] })
10295
+ ] }) }),
10296
+ modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsxRuntime.jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsxRuntime.jsx(
10297
+ CustomItemForm,
10298
+ {
10299
+ orderId: preview.id,
10300
+ currencyCode
10301
+ }
10302
+ ) : null)
10303
+ ]
10304
+ }
10305
+ ) }),
10306
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
10307
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10199
10308
  /* @__PURE__ */ jsxRuntime.jsx(
10200
10309
  ui.Button,
10201
10310
  {
10202
10311
  size: "small",
10203
- type: "submit",
10204
- isLoading: isSubmitting || isAddingPromotions,
10312
+ type: "button",
10313
+ onClick: onSubmit,
10314
+ isLoading: isSubmitting,
10205
10315
  children: "Save"
10206
10316
  }
10207
10317
  )
10208
10318
  ] }) })
10209
10319
  ] });
10210
10320
  };
10211
- const PromotionItem = ({
10212
- promotion,
10213
- orderId,
10214
- isLoading
10215
- }) => {
10216
- var _a;
10217
- const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
10218
- const onRemove = async () => {
10219
- removePromotions(
10321
+ const Item = ({ item, preview, currencyCode }) => {
10322
+ if (item.variant_id) {
10323
+ return /* @__PURE__ */ jsxRuntime.jsx(VariantItem, { item, preview, currencyCode });
10324
+ }
10325
+ return /* @__PURE__ */ jsxRuntime.jsx(CustomItem, { item, preview, currencyCode });
10326
+ };
10327
+ const VariantItem = ({ item, preview, currencyCode }) => {
10328
+ const [editing, setEditing] = React.useState(false);
10329
+ const form = reactHookForm.useForm({
10330
+ defaultValues: {
10331
+ quantity: item.quantity,
10332
+ unit_price: item.unit_price
10333
+ },
10334
+ resolver: zod.zodResolver(variantItemSchema)
10335
+ });
10336
+ const actionId = React.useMemo(() => {
10337
+ var _a, _b;
10338
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10339
+ }, [item]);
10340
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10341
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10342
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10343
+ const onSubmit = form.handleSubmit(async (data) => {
10344
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10345
+ setEditing(false);
10346
+ return;
10347
+ }
10348
+ if (!actionId) {
10349
+ await updateOriginalItem(
10350
+ {
10351
+ item_id: item.id,
10352
+ quantity: data.quantity,
10353
+ unit_price: convertNumber(data.unit_price)
10354
+ },
10355
+ {
10356
+ onSuccess: () => {
10357
+ setEditing(false);
10358
+ },
10359
+ onError: (e) => {
10360
+ ui.toast.error(e.message);
10361
+ }
10362
+ }
10363
+ );
10364
+ return;
10365
+ }
10366
+ await updateActionItem(
10220
10367
  {
10221
- promo_codes: [promotion.code]
10368
+ action_id: actionId,
10369
+ quantity: data.quantity,
10370
+ unit_price: convertNumber(data.unit_price)
10222
10371
  },
10223
10372
  {
10373
+ onSuccess: () => {
10374
+ setEditing(false);
10375
+ },
10224
10376
  onError: (e) => {
10225
10377
  ui.toast.error(e.message);
10226
10378
  }
10227
10379
  }
10228
10380
  );
10229
- };
10230
- const displayValue = getDisplayValue(promotion);
10231
- return /* @__PURE__ */ jsxRuntime.jsxs(
10232
- "div",
10233
- {
10234
- className: ui.clx(
10235
- "px-3 py-2 rounded-lg bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between",
10381
+ });
10382
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_28px] gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center", children: [
10383
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3 w-full", children: [
10384
+ /* @__PURE__ */ jsxRuntime.jsx(
10385
+ Thumbnail,
10236
10386
  {
10237
- "animate-pulse": isLoading
10387
+ thumbnail: item.thumbnail,
10388
+ alt: item.product_title ?? void 0
10238
10389
  }
10239
10390
  ),
10240
- children: [
10241
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10242
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
10243
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-ui-fg-subtle", children: [
10244
- displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
10245
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
10246
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
10247
- ] }),
10248
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
10249
- ] })
10391
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10392
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
10393
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10394
+ /* @__PURE__ */ jsxRuntime.jsxs(
10395
+ ui.Text,
10396
+ {
10397
+ size: "small",
10398
+ leading: "compact",
10399
+ className: "text-ui-fg-subtle",
10400
+ children: [
10401
+ "(",
10402
+ item.variant_title,
10403
+ ")"
10404
+ ]
10405
+ }
10406
+ )
10250
10407
  ] }),
10251
10408
  /* @__PURE__ */ jsxRuntime.jsx(
10252
- ui.IconButton,
10409
+ ui.Text,
10253
10410
  {
10254
10411
  size: "small",
10255
- type: "button",
10256
- variant: "transparent",
10257
- onClick: onRemove,
10258
- isLoading: isPending || isLoading,
10259
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
10412
+ leading: "compact",
10413
+ className: "text-ui-fg-subtle",
10414
+ children: item.variant_sku
10260
10415
  }
10261
10416
  )
10262
- ]
10263
- },
10264
- promotion.id
10265
- );
10266
- };
10267
- function getDisplayValue(promotion) {
10268
- var _a, _b, _c, _d;
10269
- const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
10270
- if (!value) {
10271
- return null;
10272
- }
10273
- if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
10274
- const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
10275
- if (!currency) {
10276
- return null;
10277
- }
10278
- return getLocaleAmount(value, currency);
10279
- } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
10280
- return formatPercentage(value);
10281
- }
10282
- return null;
10283
- }
10284
- const formatter = new Intl.NumberFormat([], {
10285
- style: "percent",
10286
- minimumFractionDigits: 2
10287
- });
10288
- const formatPercentage = (value, isPercentageValue = false) => {
10289
- let val = value || 0;
10290
- if (!isPercentageValue) {
10291
- val = val / 100;
10292
- }
10293
- return formatter.format(val);
10294
- };
10295
- function getPromotionCodes(items, shippingMethods) {
10296
- const codes = /* @__PURE__ */ new Set();
10297
- for (const item of items) {
10298
- if (item.adjustments) {
10299
- for (const adjustment of item.adjustments) {
10300
- if (adjustment.code) {
10301
- codes.add(adjustment.code);
10302
- }
10303
- }
10304
- }
10305
- }
10306
- for (const shippingMethod of shippingMethods) {
10307
- if (shippingMethod.adjustments) {
10308
- for (const adjustment of shippingMethod.adjustments) {
10309
- if (adjustment.code) {
10310
- codes.add(adjustment.code);
10417
+ ] })
10418
+ ] }),
10419
+ editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
10420
+ Form$2.Field,
10421
+ {
10422
+ control: form.control,
10423
+ name: "quantity",
10424
+ render: ({ field }) => {
10425
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10311
10426
  }
10312
10427
  }
10313
- }
10314
- }
10315
- return Array.from(codes);
10316
- }
10317
- const NumberInput = React.forwardRef(
10318
- ({
10319
- value,
10320
- onChange,
10321
- size = "base",
10322
- min = 0,
10323
- max = 100,
10324
- step = 1,
10325
- className,
10326
- disabled,
10327
- ...props
10328
- }, ref) => {
10329
- const handleChange = (event) => {
10330
- const newValue = event.target.value === "" ? min : Number(event.target.value);
10331
- if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
10332
- onChange(newValue);
10333
- }
10334
- };
10335
- const handleIncrement = () => {
10336
- const newValue = value + step;
10337
- if (max === void 0 || newValue <= max) {
10338
- onChange(newValue);
10339
- }
10340
- };
10341
- const handleDecrement = () => {
10342
- const newValue = value - step;
10343
- if (min === void 0 || newValue >= min) {
10344
- onChange(newValue);
10345
- }
10346
- };
10347
- return /* @__PURE__ */ jsxRuntime.jsxs(
10348
- "div",
10428
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }) }),
10429
+ editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
10430
+ Form$2.Field,
10349
10431
  {
10350
- className: ui.clx(
10351
- "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
10352
- "[&:has(input:focus)]:shadow-borders-interactive-with-active",
10353
- {
10354
- "h-7": size === "small",
10355
- "h-8": size === "base"
10356
- },
10357
- className
10358
- ),
10359
- children: [
10360
- /* @__PURE__ */ jsxRuntime.jsx(
10361
- "input",
10432
+ control: form.control,
10433
+ name: "unit_price",
10434
+ render: ({ field: { onChange, ...field } }) => {
10435
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10436
+ ui.CurrencyInput,
10362
10437
  {
10363
- ref,
10364
- type: "number",
10365
- value,
10366
- onChange: handleChange,
10367
- min,
10368
- max,
10369
- step,
10370
- className: ui.clx(
10371
- "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
10372
- "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
10373
- "placeholder:text-ui-fg-muted"
10374
- ),
10375
- ...props
10438
+ ...field,
10439
+ symbol: getNativeSymbol(currencyCode),
10440
+ code: currencyCode,
10441
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10376
10442
  }
10377
- ),
10378
- /* @__PURE__ */ jsxRuntime.jsxs(
10379
- "button",
10380
- {
10381
- className: ui.clx(
10382
- "flex items-center justify-center outline-none transition-fg",
10383
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10384
- "focus:bg-ui-bg-field-component-hover",
10385
- "hover:bg-ui-bg-field-component-hover",
10386
- {
10387
- "size-7": size === "small",
10388
- "size-8": size === "base"
10389
- }
10390
- ),
10391
- type: "button",
10392
- onClick: handleDecrement,
10393
- disabled: min !== void 0 && value <= min || disabled,
10394
- children: [
10395
- /* @__PURE__ */ jsxRuntime.jsx(icons.Minus, {}),
10396
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
10397
- ]
10398
- }
10399
- ),
10400
- /* @__PURE__ */ jsxRuntime.jsxs(
10401
- "button",
10402
- {
10403
- className: ui.clx(
10404
- "flex items-center justify-center outline-none transition-fg",
10405
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10406
- "focus:bg-ui-bg-field-hover",
10407
- "hover:bg-ui-bg-field-hover",
10408
- {
10409
- "size-7": size === "small",
10410
- "size-8": size === "base"
10411
- }
10412
- ),
10413
- type: "button",
10414
- onClick: handleIncrement,
10415
- disabled: max !== void 0 && value >= max || disabled,
10416
- children: [
10417
- /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
10418
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Increase by ${step}` })
10419
- ]
10420
- }
10421
- )
10422
- ]
10443
+ ) }) });
10444
+ }
10423
10445
  }
10424
- );
10425
- }
10426
- );
10427
- const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
10428
- const productVariantsQueryKeys = {
10429
- list: (query2) => [
10430
- PRODUCT_VARIANTS_QUERY_KEY,
10431
- query2 ? query2 : void 0
10432
- ]
10433
- };
10434
- const useProductVariants = (query2, options) => {
10435
- const { data, ...rest } = reactQuery.useQuery({
10436
- queryKey: productVariantsQueryKeys.list(query2),
10437
- queryFn: async () => await sdk.admin.productVariant.list(query2),
10438
- ...options
10439
- });
10440
- return { ...data, ...rest };
10446
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex items-center justify-end w-full", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10447
+ /* @__PURE__ */ jsxRuntime.jsx(
10448
+ ui.IconButton,
10449
+ {
10450
+ type: "button",
10451
+ size: "small",
10452
+ onClick: editing ? onSubmit : () => {
10453
+ setEditing(true);
10454
+ },
10455
+ disabled: isPending,
10456
+ children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
10457
+ }
10458
+ )
10459
+ ] }) }) });
10441
10460
  };
10442
- function convertNumber(value) {
10443
- return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10444
- }
10445
- const STACKED_MODAL_ID = "items_stacked_modal";
10446
- const Items = () => {
10447
- const { id } = reactRouterDom.useParams();
10448
- const {
10449
- order: preview,
10450
- isPending: isPreviewPending,
10451
- isError: isPreviewError,
10452
- error: previewError
10453
- } = useOrderPreview(id, void 0, {
10454
- placeholderData: reactQuery.keepPreviousData
10455
- });
10456
- useInitiateOrderEdit({ preview });
10457
- const { draft_order, isPending, isError, error } = useDraftOrder(
10458
- id,
10459
- {
10460
- fields: "currency_code"
10461
+ const variantItemSchema = z.object({
10462
+ quantity: z.number(),
10463
+ unit_price: z.union([z.number(), z.string()])
10464
+ });
10465
+ const CustomItem = ({ item, preview, currencyCode }) => {
10466
+ const [editing, setEditing] = React.useState(false);
10467
+ const { quantity, unit_price, title } = item;
10468
+ const form = reactHookForm.useForm({
10469
+ defaultValues: {
10470
+ title,
10471
+ quantity,
10472
+ unit_price
10461
10473
  },
10462
- {
10463
- enabled: !!id
10464
- }
10465
- );
10466
- const { onCancel } = useCancelOrderEdit({ preview });
10467
- if (isError) {
10468
- throw error;
10469
- }
10470
- if (isPreviewError) {
10471
- throw previewError;
10472
- }
10473
- const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10474
- return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsxRuntime.jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10475
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10476
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10477
- ] }) });
10478
- };
10479
- const ItemsForm = ({ preview, currencyCode }) => {
10480
- var _a;
10481
- const [isSubmitting, setIsSubmitting] = React.useState(false);
10482
- const [modalContent, setModalContent] = React.useState(
10483
- null
10484
- );
10485
- const { handleSuccess } = useRouteModal();
10486
- const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10487
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10488
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10489
- const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10490
- const matches = React.useMemo(() => {
10491
- return matchSorter.matchSorter(preview.items, query2, {
10492
- keys: ["product_title", "variant_title", "variant_sku", "title"]
10493
- });
10494
- }, [preview.items, query2]);
10495
- const onSubmit = async () => {
10496
- setIsSubmitting(true);
10497
- let requestSucceeded = false;
10498
- await requestOrderEdit(void 0, {
10499
- onError: (e) => {
10500
- ui.toast.error(`Failed to request order edit: ${e.message}`);
10501
- },
10502
- onSuccess: () => {
10503
- requestSucceeded = true;
10504
- }
10474
+ resolver: zod.zodResolver(customItemSchema)
10475
+ });
10476
+ React.useEffect(() => {
10477
+ form.reset({
10478
+ title,
10479
+ quantity,
10480
+ unit_price
10505
10481
  });
10506
- if (!requestSucceeded) {
10507
- setIsSubmitting(false);
10482
+ }, [form, title, quantity, unit_price]);
10483
+ const actionId = React.useMemo(() => {
10484
+ var _a, _b;
10485
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10486
+ }, [item]);
10487
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10488
+ const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10489
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10490
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10491
+ const onSubmit = form.handleSubmit(async (data) => {
10492
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10493
+ setEditing(false);
10508
10494
  return;
10509
10495
  }
10510
- await confirmOrderEdit(void 0, {
10511
- onError: (e) => {
10512
- ui.toast.error(`Failed to confirm order edit: ${e.message}`);
10513
- },
10514
- onSuccess: () => {
10515
- handleSuccess();
10496
+ if (!actionId) {
10497
+ await updateOriginalItem(
10498
+ {
10499
+ item_id: item.id,
10500
+ quantity: data.quantity,
10501
+ unit_price: convertNumber(data.unit_price)
10502
+ },
10503
+ {
10504
+ onSuccess: () => {
10505
+ setEditing(false);
10506
+ },
10507
+ onError: (e) => {
10508
+ ui.toast.error(e.message);
10509
+ }
10510
+ }
10511
+ );
10512
+ return;
10513
+ }
10514
+ if (data.quantity === 0) {
10515
+ await removeActionItem(actionId, {
10516
+ onSuccess: () => {
10517
+ setEditing(false);
10518
+ },
10519
+ onError: (e) => {
10520
+ ui.toast.error(e.message);
10521
+ }
10522
+ });
10523
+ return;
10524
+ }
10525
+ await updateActionItem(
10526
+ {
10527
+ action_id: actionId,
10528
+ quantity: data.quantity,
10529
+ unit_price: convertNumber(data.unit_price)
10516
10530
  },
10517
- onSettled: () => {
10518
- setIsSubmitting(false);
10531
+ {
10532
+ onSuccess: () => {
10533
+ setEditing(false);
10534
+ },
10535
+ onError: (e) => {
10536
+ ui.toast.error(e.message);
10537
+ }
10519
10538
  }
10520
- });
10521
- };
10522
- const onKeyDown = React.useCallback(
10523
- (e) => {
10524
- if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10525
- if (modalContent || isSubmitting) {
10526
- return;
10539
+ );
10540
+ });
10541
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_28px] gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center", children: [
10542
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
10543
+ /* @__PURE__ */ jsxRuntime.jsx(
10544
+ Thumbnail,
10545
+ {
10546
+ thumbnail: item.thumbnail,
10547
+ alt: item.title ?? void 0
10548
+ }
10549
+ ),
10550
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
10551
+ Form$2.Field,
10552
+ {
10553
+ control: form.control,
10554
+ name: "title",
10555
+ render: ({ field }) => {
10556
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }) });
10557
+ }
10558
+ }
10559
+ ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.title })
10560
+ ] }),
10561
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
10562
+ Form$2.Field,
10563
+ {
10564
+ control: form.control,
10565
+ name: "quantity",
10566
+ render: ({ field }) => {
10567
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10527
10568
  }
10528
- onSubmit();
10529
10569
  }
10530
- },
10531
- [modalContent, isSubmitting, onSubmit]
10532
- );
10533
- React.useEffect(() => {
10534
- document.addEventListener("keydown", onKeyDown);
10535
- return () => {
10536
- document.removeEventListener("keydown", onKeyDown);
10537
- };
10538
- }, [onKeyDown]);
10539
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10540
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
10541
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
10542
- StackedFocusModal,
10543
- {
10544
- id: STACKED_MODAL_ID,
10545
- onOpenChangeCallback: (open) => {
10546
- if (!open) {
10547
- setModalContent(null);
10548
- }
10549
- },
10550
- children: [
10551
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-6 py-16", children: [
10552
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10553
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Items" }) }),
10554
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Edit the items in the draft order." }) })
10555
- ] }),
10556
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10557
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
10558
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10559
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10560
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10561
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10562
- ] }),
10563
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10564
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10565
- ui.Input,
10566
- {
10567
- type: "search",
10568
- placeholder: "Search items",
10569
- value: searchValue,
10570
- onChange: (e) => onSearchValueChange(e.target.value)
10571
- }
10572
- ) }),
10573
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
10574
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}) }) }),
10575
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
10576
- /* @__PURE__ */ jsxRuntime.jsx(
10577
- StackedModalTrigger$1,
10578
- {
10579
- type: "add-items",
10580
- setModalContent
10581
- }
10582
- ),
10583
- /* @__PURE__ */ jsxRuntime.jsx(
10584
- StackedModalTrigger$1,
10585
- {
10586
- type: "add-custom-item",
10587
- setModalContent
10588
- }
10589
- )
10590
- ] })
10591
- ] })
10592
- ] })
10593
- ] }),
10594
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10595
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_1fr_1fr_28px] gap-3 px-4 py-2 text-ui-fg-muted", children: [
10596
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
10597
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10598
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Price" }) }),
10599
- /* @__PURE__ */ jsxRuntime.jsx("div", {})
10600
- ] }) }),
10601
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
10602
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10603
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10604
- ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
10605
- Item,
10606
- {
10607
- item,
10608
- preview,
10609
- currencyCode
10610
- },
10611
- item.id
10612
- )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
10613
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10614
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
10615
- 'No items found for "',
10616
- query2,
10617
- '".'
10618
- ] })
10619
- ] }) })
10620
- ] })
10621
- ] }),
10622
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10623
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10624
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10625
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(
10626
- ui.Text,
10627
- {
10628
- size: "small",
10629
- leading: "compact",
10630
- className: "text-ui-fg-subtle",
10631
- children: [
10632
- itemCount,
10633
- " ",
10634
- itemCount === 1 ? "item" : "items"
10635
- ]
10636
- }
10637
- ) }),
10638
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10639
- ] })
10640
- ] }) }),
10641
- modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsxRuntime.jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsxRuntime.jsx(
10642
- CustomItemForm,
10643
- {
10644
- orderId: preview.id,
10645
- currencyCode
10646
- }
10647
- ) : null)
10648
- ]
10649
- }
10650
- ) }),
10651
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
10652
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10653
- /* @__PURE__ */ jsxRuntime.jsx(
10654
- ui.Button,
10655
- {
10656
- size: "small",
10657
- type: "button",
10658
- onClick: onSubmit,
10659
- isLoading: isSubmitting,
10660
- children: "Save"
10661
- }
10662
- )
10663
- ] }) })
10664
- ] });
10665
- };
10666
- const Item = ({ item, preview, currencyCode }) => {
10667
- if (item.variant_id) {
10668
- return /* @__PURE__ */ jsxRuntime.jsx(VariantItem, { item, preview, currencyCode });
10669
- }
10670
- return /* @__PURE__ */ jsxRuntime.jsx(CustomItem, { item, preview, currencyCode });
10671
- };
10672
- const VariantItem = ({ item, preview, currencyCode }) => {
10673
- const [editing, setEditing] = React.useState(false);
10674
- const form = reactHookForm.useForm({
10675
- defaultValues: {
10676
- quantity: item.quantity,
10677
- unit_price: item.unit_price
10678
- },
10679
- resolver: zod.zodResolver(variantItemSchema)
10680
- });
10681
- const actionId = React.useMemo(() => {
10682
- var _a, _b;
10683
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10684
- }, [item]);
10685
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10686
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10687
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10688
- const onSubmit = form.handleSubmit(async (data) => {
10689
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10690
- setEditing(false);
10691
- return;
10692
- }
10693
- if (!actionId) {
10694
- await updateOriginalItem(
10695
- {
10696
- item_id: item.id,
10697
- quantity: data.quantity,
10698
- unit_price: convertNumber(data.unit_price)
10699
- },
10700
- {
10701
- onSuccess: () => {
10702
- setEditing(false);
10703
- },
10704
- onError: (e) => {
10705
- ui.toast.error(e.message);
10706
- }
10707
- }
10708
- );
10709
- return;
10710
- }
10711
- await updateActionItem(
10712
- {
10713
- action_id: actionId,
10714
- quantity: data.quantity,
10715
- unit_price: convertNumber(data.unit_price)
10716
- },
10717
- {
10718
- onSuccess: () => {
10719
- setEditing(false);
10720
- },
10721
- onError: (e) => {
10722
- ui.toast.error(e.message);
10723
- }
10724
- }
10725
- );
10726
- });
10727
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_28px] gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center", children: [
10728
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3 w-full", children: [
10729
- /* @__PURE__ */ jsxRuntime.jsx(
10730
- Thumbnail,
10731
- {
10732
- thumbnail: item.thumbnail,
10733
- alt: item.product_title ?? void 0
10734
- }
10735
- ),
10736
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10737
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
10738
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10739
- /* @__PURE__ */ jsxRuntime.jsxs(
10740
- ui.Text,
10741
- {
10742
- size: "small",
10743
- leading: "compact",
10744
- className: "text-ui-fg-subtle",
10745
- children: [
10746
- "(",
10747
- item.variant_title,
10748
- ")"
10749
- ]
10750
- }
10751
- )
10752
- ] }),
10753
- /* @__PURE__ */ jsxRuntime.jsx(
10754
- ui.Text,
10755
- {
10756
- size: "small",
10757
- leading: "compact",
10758
- className: "text-ui-fg-subtle",
10759
- children: item.variant_sku
10760
- }
10761
- )
10762
- ] })
10763
- ] }),
10764
- editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
10765
- Form$2.Field,
10766
- {
10767
- control: form.control,
10768
- name: "quantity",
10769
- render: ({ field }) => {
10770
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10771
- }
10772
- }
10773
- ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }) }),
10774
- editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
10570
+ ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }),
10571
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
10775
10572
  Form$2.Field,
10776
10573
  {
10777
10574
  control: form.control,
@@ -10788,149 +10585,7 @@ const VariantItem = ({ item, preview, currencyCode }) => {
10788
10585
  ) }) });
10789
10586
  }
10790
10587
  }
10791
- ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex items-center justify-end w-full", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10792
- /* @__PURE__ */ jsxRuntime.jsx(
10793
- ui.IconButton,
10794
- {
10795
- type: "button",
10796
- size: "small",
10797
- onClick: editing ? onSubmit : () => {
10798
- setEditing(true);
10799
- },
10800
- disabled: isPending,
10801
- children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
10802
- }
10803
- )
10804
- ] }) }) });
10805
- };
10806
- const variantItemSchema = z.object({
10807
- quantity: z.number(),
10808
- unit_price: z.union([z.number(), z.string()])
10809
- });
10810
- const CustomItem = ({ item, preview, currencyCode }) => {
10811
- const [editing, setEditing] = React.useState(false);
10812
- const { quantity, unit_price, title } = item;
10813
- const form = reactHookForm.useForm({
10814
- defaultValues: {
10815
- title,
10816
- quantity,
10817
- unit_price
10818
- },
10819
- resolver: zod.zodResolver(customItemSchema)
10820
- });
10821
- React.useEffect(() => {
10822
- form.reset({
10823
- title,
10824
- quantity,
10825
- unit_price
10826
- });
10827
- }, [form, title, quantity, unit_price]);
10828
- const actionId = React.useMemo(() => {
10829
- var _a, _b;
10830
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10831
- }, [item]);
10832
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10833
- const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10834
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10835
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10836
- const onSubmit = form.handleSubmit(async (data) => {
10837
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10838
- setEditing(false);
10839
- return;
10840
- }
10841
- if (!actionId) {
10842
- await updateOriginalItem(
10843
- {
10844
- item_id: item.id,
10845
- quantity: data.quantity,
10846
- unit_price: convertNumber(data.unit_price)
10847
- },
10848
- {
10849
- onSuccess: () => {
10850
- setEditing(false);
10851
- },
10852
- onError: (e) => {
10853
- ui.toast.error(e.message);
10854
- }
10855
- }
10856
- );
10857
- return;
10858
- }
10859
- if (data.quantity === 0) {
10860
- await removeActionItem(actionId, {
10861
- onSuccess: () => {
10862
- setEditing(false);
10863
- },
10864
- onError: (e) => {
10865
- ui.toast.error(e.message);
10866
- }
10867
- });
10868
- return;
10869
- }
10870
- await updateActionItem(
10871
- {
10872
- action_id: actionId,
10873
- quantity: data.quantity,
10874
- unit_price: convertNumber(data.unit_price)
10875
- },
10876
- {
10877
- onSuccess: () => {
10878
- setEditing(false);
10879
- },
10880
- onError: (e) => {
10881
- ui.toast.error(e.message);
10882
- }
10883
- }
10884
- );
10885
- });
10886
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_28px] gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center", children: [
10887
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
10888
- /* @__PURE__ */ jsxRuntime.jsx(
10889
- Thumbnail,
10890
- {
10891
- thumbnail: item.thumbnail,
10892
- alt: item.title ?? void 0
10893
- }
10894
- ),
10895
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
10896
- Form$2.Field,
10897
- {
10898
- control: form.control,
10899
- name: "title",
10900
- render: ({ field }) => {
10901
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }) });
10902
- }
10903
- }
10904
- ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.title })
10905
- ] }),
10906
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
10907
- Form$2.Field,
10908
- {
10909
- control: form.control,
10910
- name: "quantity",
10911
- render: ({ field }) => {
10912
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10913
- }
10914
- }
10915
- ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }),
10916
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
10917
- Form$2.Field,
10918
- {
10919
- control: form.control,
10920
- name: "unit_price",
10921
- render: ({ field: { onChange, ...field } }) => {
10922
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10923
- ui.CurrencyInput,
10924
- {
10925
- ...field,
10926
- symbol: getNativeSymbol(currencyCode),
10927
- code: currencyCode,
10928
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10929
- }
10930
- ) }) });
10931
- }
10932
- }
10933
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10588
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10934
10589
  /* @__PURE__ */ jsxRuntime.jsx(
10935
10590
  ui.IconButton,
10936
10591
  {
@@ -11242,54 +10897,10 @@ const customItemSchema = z.object({
11242
10897
  quantity: z.number(),
11243
10898
  unit_price: z.union([z.number(), z.string()])
11244
10899
  });
11245
- const InlineTip = React.forwardRef(
11246
- ({ variant = "tip", label, className, children, ...props }, ref) => {
11247
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
11248
- return /* @__PURE__ */ jsxRuntime.jsxs(
11249
- "div",
11250
- {
11251
- ref,
11252
- className: ui.clx(
11253
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
11254
- className
11255
- ),
11256
- ...props,
11257
- children: [
11258
- /* @__PURE__ */ jsxRuntime.jsx(
11259
- "div",
11260
- {
11261
- role: "presentation",
11262
- className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
11263
- "bg-ui-tag-orange-icon": variant === "warning"
11264
- })
11265
- }
11266
- ),
11267
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
11268
- /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
11269
- labelValue,
11270
- ":"
11271
- ] }),
11272
- " ",
11273
- children
11274
- ] })
11275
- ]
11276
- }
11277
- );
11278
- }
11279
- );
11280
- InlineTip.displayName = "InlineTip";
11281
- const MetadataFieldSchema = z.object({
11282
- key: z.string(),
11283
- disabled: z.boolean().optional(),
11284
- value: z.any()
11285
- });
11286
- const MetadataSchema = z.object({
11287
- metadata: z.array(MetadataFieldSchema)
11288
- });
11289
- const Metadata = () => {
10900
+ const Email = () => {
11290
10901
  const { id } = reactRouterDom.useParams();
11291
10902
  const { order, isPending, isError, error } = useOrder(id, {
11292
- fields: "metadata"
10903
+ fields: "+email"
11293
10904
  });
11294
10905
  if (isError) {
11295
10906
  throw error;
@@ -11297,33 +10908,26 @@ const Metadata = () => {
11297
10908
  const isReady = !isPending && !!order;
11298
10909
  return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
11299
10910
  /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11300
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
11301
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10911
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Email" }) }),
10912
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
11302
10913
  ] }),
11303
- !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10914
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(EmailForm, { order })
11304
10915
  ] });
11305
10916
  };
11306
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
11307
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
11308
- const MetadataForm = ({ orderId, metadata }) => {
11309
- const { handleSuccess } = useRouteModal();
11310
- const hasUneditableRows = getHasUneditableRows(metadata);
11311
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10917
+ const EmailForm = ({ order }) => {
11312
10918
  const form = reactHookForm.useForm({
11313
10919
  defaultValues: {
11314
- metadata: getDefaultValues(metadata)
10920
+ email: order.email ?? ""
11315
10921
  },
11316
- resolver: zod.zodResolver(MetadataSchema)
10922
+ resolver: zod.zodResolver(schema$3)
11317
10923
  });
11318
- const handleSubmit = form.handleSubmit(async (data) => {
11319
- const parsedData = parseValues(data);
10924
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
10925
+ const { handleSuccess } = useRouteModal();
10926
+ const onSubmit = form.handleSubmit(async (data) => {
11320
10927
  await mutateAsync(
11321
- {
11322
- metadata: parsedData
11323
- },
10928
+ { email: data.email },
11324
10929
  {
11325
10930
  onSuccess: () => {
11326
- ui.toast.success("Metadata updated");
11327
10931
  handleSuccess();
11328
10932
  },
11329
10933
  onError: (error) => {
@@ -11332,1073 +10936,768 @@ const MetadataForm = ({ orderId, metadata }) => {
11332
10936
  }
11333
10937
  );
11334
10938
  });
11335
- const { fields, insert, remove } = reactHookForm.useFieldArray({
11336
- control: form.control,
11337
- name: "metadata"
11338
- });
11339
- function deleteRow(index) {
11340
- remove(index);
11341
- if (fields.length === 1) {
11342
- insert(0, {
11343
- key: "",
11344
- value: "",
11345
- disabled: false
11346
- });
11347
- }
11348
- }
11349
- function insertRow(index, position) {
11350
- insert(index + (position === "above" ? 0 : 1), {
11351
- key: "",
11352
- value: "",
11353
- disabled: false
11354
- });
11355
- }
11356
10939
  return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11357
10940
  KeyboundForm,
11358
10941
  {
11359
- onSubmit: handleSubmit,
11360
10942
  className: "flex flex-1 flex-col overflow-hidden",
10943
+ onSubmit,
11361
10944
  children: [
11362
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
11363
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
11364
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
11365
- /* @__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" }) }),
11366
- /* @__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" }) })
11367
- ] }),
11368
- fields.map((field, index) => {
11369
- const isDisabled = field.disabled || false;
11370
- let placeholder = "-";
11371
- if (typeof field.value === "object") {
11372
- placeholder = "{ ... }";
11373
- }
11374
- if (Array.isArray(field.value)) {
11375
- placeholder = "[ ... ]";
11376
- }
11377
- return /* @__PURE__ */ jsxRuntime.jsx(
11378
- ConditionalTooltip,
11379
- {
11380
- showTooltip: isDisabled,
11381
- content: "This row is disabled because it contains non-primitive data.",
11382
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
11383
- /* @__PURE__ */ jsxRuntime.jsxs(
11384
- "div",
11385
- {
11386
- className: ui.clx("grid grid-cols-2 divide-x", {
11387
- "overflow-hidden rounded-b-lg": index === fields.length - 1
11388
- }),
11389
- children: [
11390
- /* @__PURE__ */ jsxRuntime.jsx(
11391
- Form$2.Field,
11392
- {
11393
- control: form.control,
11394
- name: `metadata.${index}.key`,
11395
- render: ({ field: field2 }) => {
11396
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11397
- GridInput,
11398
- {
11399
- "aria-labelledby": METADATA_KEY_LABEL_ID,
11400
- ...field2,
11401
- disabled: isDisabled,
11402
- placeholder: "Key"
11403
- }
11404
- ) }) });
11405
- }
11406
- }
11407
- ),
11408
- /* @__PURE__ */ jsxRuntime.jsx(
11409
- Form$2.Field,
11410
- {
11411
- control: form.control,
11412
- name: `metadata.${index}.value`,
11413
- render: ({ field: { value, ...field2 } }) => {
11414
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11415
- GridInput,
11416
- {
11417
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
11418
- ...field2,
11419
- value: isDisabled ? placeholder : value,
11420
- disabled: isDisabled,
11421
- placeholder: "Value"
11422
- }
11423
- ) }) });
11424
- }
11425
- }
11426
- )
11427
- ]
11428
- }
11429
- ),
11430
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
11431
- /* @__PURE__ */ jsxRuntime.jsx(
11432
- ui.DropdownMenu.Trigger,
11433
- {
11434
- className: ui.clx(
11435
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11436
- {
11437
- hidden: isDisabled
11438
- }
11439
- ),
11440
- disabled: isDisabled,
11441
- asChild: true,
11442
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
11443
- }
11444
- ),
11445
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
11446
- /* @__PURE__ */ jsxRuntime.jsxs(
11447
- ui.DropdownMenu.Item,
11448
- {
11449
- className: "gap-x-2",
11450
- onClick: () => insertRow(index, "above"),
11451
- children: [
11452
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
11453
- "Insert row above"
11454
- ]
11455
- }
11456
- ),
11457
- /* @__PURE__ */ jsxRuntime.jsxs(
11458
- ui.DropdownMenu.Item,
11459
- {
11460
- className: "gap-x-2",
11461
- onClick: () => insertRow(index, "below"),
11462
- children: [
11463
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
11464
- "Insert row below"
11465
- ]
11466
- }
11467
- ),
11468
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
11469
- /* @__PURE__ */ jsxRuntime.jsxs(
11470
- ui.DropdownMenu.Item,
11471
- {
11472
- className: "gap-x-2",
11473
- onClick: () => deleteRow(index),
11474
- children: [
11475
- /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
11476
- "Delete row"
11477
- ]
11478
- }
11479
- )
11480
- ] })
11481
- ] })
11482
- ] })
11483
- },
11484
- field.id
11485
- );
11486
- })
11487
- ] }),
11488
- 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." })
11489
- ] }),
11490
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11491
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10945
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
10946
+ Form$2.Field,
10947
+ {
10948
+ control: form.control,
10949
+ name: "email",
10950
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10951
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Email" }),
10952
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10953
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10954
+ ] })
10955
+ }
10956
+ ) }),
10957
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
10958
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11492
10959
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11493
10960
  ] }) })
11494
10961
  ]
11495
10962
  }
11496
10963
  ) });
11497
10964
  };
11498
- const GridInput = React.forwardRef(({ className, ...props }, ref) => {
11499
- return /* @__PURE__ */ jsxRuntime.jsx(
11500
- "input",
10965
+ const schema$3 = z.object({
10966
+ email: z.string().email()
10967
+ });
10968
+ const SalesChannel = () => {
10969
+ const { id } = reactRouterDom.useParams();
10970
+ const { draft_order, isPending, isError, error } = useDraftOrder(
10971
+ id,
11501
10972
  {
11502
- ref,
11503
- ...props,
11504
- autoComplete: "off",
11505
- className: ui.clx(
11506
- "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",
11507
- className
11508
- )
10973
+ fields: "+sales_channel_id"
10974
+ },
10975
+ {
10976
+ enabled: !!id
11509
10977
  }
11510
10978
  );
11511
- });
11512
- GridInput.displayName = "MetadataForm.GridInput";
11513
- const PlaceholderInner = () => {
11514
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11515
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11516
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11517
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
11518
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
11519
- ] }) })
10979
+ if (isError) {
10980
+ throw error;
10981
+ }
10982
+ const ISrEADY = !!draft_order && !isPending;
10983
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10984
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10985
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
10986
+ /* @__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" }) })
10987
+ ] }),
10988
+ ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
11520
10989
  ] });
11521
10990
  };
11522
- const EDITABLE_TYPES = ["string", "number", "boolean"];
11523
- function getDefaultValues(metadata) {
11524
- if (!metadata || !Object.keys(metadata).length) {
11525
- return [
10991
+ const SalesChannelForm = ({ order }) => {
10992
+ const form = reactHookForm.useForm({
10993
+ defaultValues: {
10994
+ sales_channel_id: order.sales_channel_id || ""
10995
+ },
10996
+ resolver: zod.zodResolver(schema$2)
10997
+ });
10998
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
10999
+ const { handleSuccess } = useRouteModal();
11000
+ const onSubmit = form.handleSubmit(async (data) => {
11001
+ await mutateAsync(
11526
11002
  {
11527
- key: "",
11528
- value: "",
11529
- disabled: false
11003
+ sales_channel_id: data.sales_channel_id
11004
+ },
11005
+ {
11006
+ onSuccess: () => {
11007
+ ui.toast.success("Sales channel updated");
11008
+ handleSuccess();
11009
+ },
11010
+ onError: (error) => {
11011
+ ui.toast.error(error.message);
11012
+ }
11530
11013
  }
11531
- ];
11532
- }
11533
- return Object.entries(metadata).map(([key, value]) => {
11534
- if (!EDITABLE_TYPES.includes(typeof value)) {
11535
- return {
11536
- key,
11537
- value,
11538
- disabled: true
11539
- };
11540
- }
11541
- let stringValue = value;
11542
- if (typeof value !== "string") {
11543
- stringValue = JSON.stringify(value);
11544
- }
11545
- return {
11546
- key,
11547
- value: stringValue,
11548
- original_key: key
11549
- };
11014
+ );
11550
11015
  });
11551
- }
11552
- function parseValues(values) {
11553
- const metadata = values.metadata;
11554
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11555
- if (isEmpty) {
11556
- return null;
11557
- }
11558
- const update = {};
11559
- metadata.forEach((field) => {
11560
- let key = field.key;
11561
- let value = field.value;
11562
- const disabled = field.disabled;
11563
- if (!key || !value) {
11564
- return;
11565
- }
11566
- if (disabled) {
11567
- update[key] = value;
11568
- return;
11569
- }
11570
- key = key.trim();
11571
- value = value.trim();
11572
- if (value === "true") {
11573
- update[key] = true;
11574
- } else if (value === "false") {
11575
- update[key] = false;
11576
- } else {
11577
- const parsedNumber = parseFloat(value);
11578
- if (!isNaN(parsedNumber)) {
11579
- update[key] = parsedNumber;
11580
- } else {
11581
- update[key] = value;
11582
- }
11016
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11017
+ KeyboundForm,
11018
+ {
11019
+ className: "flex flex-1 flex-col overflow-hidden",
11020
+ onSubmit,
11021
+ children: [
11022
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
11023
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11024
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11025
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11026
+ ] }) })
11027
+ ]
11028
+ }
11029
+ ) });
11030
+ };
11031
+ const SalesChannelField = ({ control, order }) => {
11032
+ const salesChannels = useComboboxData({
11033
+ queryFn: async (params) => {
11034
+ return await sdk.admin.salesChannel.list(params);
11035
+ },
11036
+ queryKey: ["sales-channels"],
11037
+ getOptions: (data) => {
11038
+ return data.sales_channels.map((salesChannel) => ({
11039
+ label: salesChannel.name,
11040
+ value: salesChannel.id
11041
+ }));
11042
+ },
11043
+ defaultValue: order.sales_channel_id || void 0
11044
+ });
11045
+ return /* @__PURE__ */ jsxRuntime.jsx(
11046
+ Form$2.Field,
11047
+ {
11048
+ control,
11049
+ name: "sales_channel_id",
11050
+ render: ({ field }) => {
11051
+ return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11052
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
11053
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11054
+ Combobox,
11055
+ {
11056
+ options: salesChannels.options,
11057
+ fetchNextPage: salesChannels.fetchNextPage,
11058
+ isFetchingNextPage: salesChannels.isFetchingNextPage,
11059
+ searchValue: salesChannels.searchValue,
11060
+ onSearchValueChange: salesChannels.onSearchValueChange,
11061
+ placeholder: "Select sales channel",
11062
+ ...field
11063
+ }
11064
+ ) }),
11065
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11066
+ ] });
11067
+ }
11583
11068
  }
11584
- });
11585
- return update;
11586
- }
11587
- function getHasUneditableRows(metadata) {
11588
- if (!metadata) {
11589
- return false;
11590
- }
11591
- return Object.values(metadata).some(
11592
- (value) => !EDITABLE_TYPES.includes(typeof value)
11593
11069
  );
11594
- }
11595
- const STACKED_FOCUS_MODAL_ID = "shipping-form";
11596
- const Shipping = () => {
11597
- var _a;
11070
+ };
11071
+ const schema$2 = z.object({
11072
+ sales_channel_id: z.string().min(1)
11073
+ });
11074
+ const InlineTip = React.forwardRef(
11075
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
11076
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
11077
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11078
+ "div",
11079
+ {
11080
+ ref,
11081
+ className: ui.clx(
11082
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
11083
+ className
11084
+ ),
11085
+ ...props,
11086
+ children: [
11087
+ /* @__PURE__ */ jsxRuntime.jsx(
11088
+ "div",
11089
+ {
11090
+ role: "presentation",
11091
+ className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
11092
+ "bg-ui-tag-orange-icon": variant === "warning"
11093
+ })
11094
+ }
11095
+ ),
11096
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
11097
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
11098
+ labelValue,
11099
+ ":"
11100
+ ] }),
11101
+ " ",
11102
+ children
11103
+ ] })
11104
+ ]
11105
+ }
11106
+ );
11107
+ }
11108
+ );
11109
+ InlineTip.displayName = "InlineTip";
11110
+ const MetadataFieldSchema = z.object({
11111
+ key: z.string(),
11112
+ disabled: z.boolean().optional(),
11113
+ value: z.any()
11114
+ });
11115
+ const MetadataSchema = z.object({
11116
+ metadata: z.array(MetadataFieldSchema)
11117
+ });
11118
+ const Metadata = () => {
11598
11119
  const { id } = reactRouterDom.useParams();
11599
11120
  const { order, isPending, isError, error } = useOrder(id, {
11600
- fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
11121
+ fields: "metadata"
11601
11122
  });
11602
- const {
11603
- order: preview,
11604
- isPending: isPreviewPending,
11605
- isError: isPreviewError,
11606
- error: previewError
11607
- } = useOrderPreview(id);
11608
- useInitiateOrderEdit({ preview });
11609
- const { onCancel } = useCancelOrderEdit({ preview });
11610
11123
  if (isError) {
11611
11124
  throw error;
11612
11125
  }
11613
- if (isPreviewError) {
11614
- throw previewError;
11615
- }
11616
- const orderHasItems = (((_a = order == null ? void 0 : order.items) == null ? void 0 : _a.length) || 0) > 0;
11617
- const isReady = preview && !isPreviewPending && order && !isPending;
11618
- return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
11619
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
11620
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
11621
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
11622
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This draft order currently has no items. Add items to the order before adding shipping." }) })
11623
- ] }) }) }),
11624
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }) })
11625
- ] }) : isReady ? /* @__PURE__ */ jsxRuntime.jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11626
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
11627
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
11628
- ] }) });
11126
+ const isReady = !isPending && !!order;
11127
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
11128
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11129
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
11130
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
11131
+ ] }),
11132
+ !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
11133
+ ] });
11629
11134
  };
11630
- const ShippingForm = ({ preview, order }) => {
11631
- var _a;
11632
- const { setIsOpen } = useStackedModal();
11633
- const [isSubmitting, setIsSubmitting] = React.useState(false);
11634
- const [data, setData] = React.useState(null);
11635
- const appliedShippingOptionIds = (_a = preview.shipping_methods) == null ? void 0 : _a.map((method) => method.shipping_option_id).filter(Boolean);
11636
- const { shipping_options } = useShippingOptions(
11637
- {
11638
- id: appliedShippingOptionIds,
11639
- fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
11640
- },
11641
- {
11642
- enabled: appliedShippingOptionIds.length > 0
11643
- }
11644
- );
11645
- const uniqueShippingProfiles = React.useMemo(() => {
11646
- const profiles = /* @__PURE__ */ new Map();
11647
- getUniqueShippingProfiles(order.items).forEach((profile) => {
11648
- profiles.set(profile.id, profile);
11649
- });
11650
- shipping_options == null ? void 0 : shipping_options.forEach((option) => {
11651
- profiles.set(option.shipping_profile_id, option.shipping_profile);
11652
- });
11653
- return Array.from(profiles.values());
11654
- }, [order.items, shipping_options]);
11135
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
11136
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
11137
+ const MetadataForm = ({ orderId, metadata }) => {
11655
11138
  const { handleSuccess } = useRouteModal();
11656
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11657
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
11658
- const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
11659
- const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
11660
- const onSubmit = async () => {
11661
- setIsSubmitting(true);
11662
- let requestSucceeded = false;
11663
- await requestOrderEdit(void 0, {
11664
- onError: (e) => {
11665
- ui.toast.error(`Failed to request order edit: ${e.message}`);
11139
+ const hasUneditableRows = getHasUneditableRows(metadata);
11140
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
11141
+ const form = reactHookForm.useForm({
11142
+ defaultValues: {
11143
+ metadata: getDefaultValues(metadata)
11144
+ },
11145
+ resolver: zod.zodResolver(MetadataSchema)
11146
+ });
11147
+ const handleSubmit = form.handleSubmit(async (data) => {
11148
+ const parsedData = parseValues(data);
11149
+ await mutateAsync(
11150
+ {
11151
+ metadata: parsedData
11666
11152
  },
11667
- onSuccess: () => {
11668
- requestSucceeded = true;
11153
+ {
11154
+ onSuccess: () => {
11155
+ ui.toast.success("Metadata updated");
11156
+ handleSuccess();
11157
+ },
11158
+ onError: (error) => {
11159
+ ui.toast.error(error.message);
11160
+ }
11669
11161
  }
11670
- });
11671
- if (!requestSucceeded) {
11672
- setIsSubmitting(false);
11673
- return;
11162
+ );
11163
+ });
11164
+ const { fields, insert, remove } = reactHookForm.useFieldArray({
11165
+ control: form.control,
11166
+ name: "metadata"
11167
+ });
11168
+ function deleteRow(index) {
11169
+ remove(index);
11170
+ if (fields.length === 1) {
11171
+ insert(0, {
11172
+ key: "",
11173
+ value: "",
11174
+ disabled: false
11175
+ });
11674
11176
  }
11675
- await confirmOrderEdit(void 0, {
11676
- onError: (e) => {
11677
- ui.toast.error(`Failed to confirm order edit: ${e.message}`);
11678
- },
11679
- onSuccess: () => {
11680
- handleSuccess();
11681
- },
11682
- onSettled: () => {
11683
- setIsSubmitting(false);
11684
- }
11177
+ }
11178
+ function insertRow(index, position) {
11179
+ insert(index + (position === "above" ? 0 : 1), {
11180
+ key: "",
11181
+ value: "",
11182
+ disabled: false
11685
11183
  });
11686
- };
11687
- const onKeydown = React.useCallback(
11688
- (e) => {
11689
- if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
11690
- if (data || isSubmitting) {
11691
- return;
11692
- }
11693
- onSubmit();
11694
- }
11695
- },
11696
- [data, isSubmitting, onSubmit]
11697
- );
11698
- React.useEffect(() => {
11699
- document.addEventListener("keydown", onKeydown);
11700
- return () => {
11701
- document.removeEventListener("keydown", onKeydown);
11702
- };
11703
- }, [onKeydown]);
11704
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
11705
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
11706
- /* @__PURE__ */ jsxRuntime.jsxs(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: [
11707
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
11708
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11709
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
11710
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose which shipping method(s) to use for the items in the order." }) })
11711
- ] }),
11712
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11713
- /* @__PURE__ */ jsxRuntime.jsx(radixUi.Accordion.Root, { type: "multiple", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle rounded-xl shadow-elevation-card-rest", children: [
11714
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-2 flex items-center justify-between", children: [
11715
- /* @__PURE__ */ jsxRuntime.jsx(
11716
- ui.Text,
11717
- {
11718
- size: "xsmall",
11719
- weight: "plus",
11720
- className: "text-ui-fg-muted",
11721
- children: "Shipping profile"
11184
+ }
11185
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11186
+ KeyboundForm,
11187
+ {
11188
+ onSubmit: handleSubmit,
11189
+ className: "flex flex-1 flex-col overflow-hidden",
11190
+ children: [
11191
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
11192
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
11193
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
11194
+ /* @__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" }) }),
11195
+ /* @__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" }) })
11196
+ ] }),
11197
+ fields.map((field, index) => {
11198
+ const isDisabled = field.disabled || false;
11199
+ let placeholder = "-";
11200
+ if (typeof field.value === "object") {
11201
+ placeholder = "{ ... }";
11722
11202
  }
11723
- ),
11724
- /* @__PURE__ */ jsxRuntime.jsx(
11725
- ui.Text,
11726
- {
11727
- size: "xsmall",
11728
- weight: "plus",
11729
- className: "text-ui-fg-muted",
11730
- children: "Action"
11203
+ if (Array.isArray(field.value)) {
11204
+ placeholder = "[ ... ]";
11731
11205
  }
11732
- )
11733
- ] }),
11734
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-[5px] pb-[5px]", children: uniqueShippingProfiles.map((profile) => {
11735
- var _a2, _b, _c, _d, _e, _f, _g;
11736
- const items = getItemsWithShippingProfile(
11737
- profile.id,
11738
- order.items
11739
- );
11740
- const hasItems = items.length > 0;
11741
- const shippingOption = shipping_options == null ? void 0 : shipping_options.find(
11742
- (option) => option.shipping_profile_id === profile.id
11743
- );
11744
- const shippingMethod = preview.shipping_methods.find(
11745
- (method) => method.shipping_option_id === (shippingOption == null ? void 0 : shippingOption.id)
11746
- );
11747
- const addShippingMethodAction = (_a2 = shippingMethod == null ? void 0 : shippingMethod.actions) == null ? void 0 : _a2.find(
11748
- (action) => action.action === "SHIPPING_ADD"
11749
- );
11750
- return /* @__PURE__ */ jsxRuntime.jsxs(
11751
- radixUi.Accordion.Item,
11752
- {
11753
- value: profile.id,
11754
- className: "bg-ui-bg-base shadow-elevation-card-rest rounded-lg",
11755
- children: [
11756
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-2 flex items-center justify-between gap-3", children: [
11757
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3 w-full overflow-hidden", children: [
11758
- /* @__PURE__ */ jsxRuntime.jsx(radixUi.Accordion.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
11759
- ui.IconButton,
11760
- {
11761
- size: "2xsmall",
11762
- variant: "transparent",
11763
- className: "group/trigger",
11764
- disabled: !hasItems,
11765
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.TriangleRightMini, { className: "group-data-[state=open]/trigger:rotate-90 transition-transform" })
11766
- }
11767
- ) }),
11768
- !shippingOption ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
11769
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-7 rounded-md shadow-borders-base flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-6 rounded bg-ui-bg-component-hover flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Shopping, { className: "text-ui-fg-subtle" }) }) }),
11770
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col flex-1", children: [
11206
+ return /* @__PURE__ */ jsxRuntime.jsx(
11207
+ ConditionalTooltip,
11208
+ {
11209
+ showTooltip: isDisabled,
11210
+ content: "This row is disabled because it contains non-primitive data.",
11211
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
11212
+ /* @__PURE__ */ jsxRuntime.jsxs(
11213
+ "div",
11214
+ {
11215
+ className: ui.clx("grid grid-cols-2 divide-x", {
11216
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
11217
+ }),
11218
+ children: [
11771
11219
  /* @__PURE__ */ jsxRuntime.jsx(
11772
- ui.Text,
11220
+ Form$2.Field,
11773
11221
  {
11774
- size: "small",
11775
- weight: "plus",
11776
- leading: "compact",
11777
- children: profile.name
11222
+ control: form.control,
11223
+ name: `metadata.${index}.key`,
11224
+ render: ({ field: field2 }) => {
11225
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11226
+ GridInput,
11227
+ {
11228
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
11229
+ ...field2,
11230
+ disabled: isDisabled,
11231
+ placeholder: "Key"
11232
+ }
11233
+ ) }) });
11234
+ }
11778
11235
  }
11779
11236
  ),
11780
- /* @__PURE__ */ jsxRuntime.jsxs(
11781
- ui.Text,
11237
+ /* @__PURE__ */ jsxRuntime.jsx(
11238
+ Form$2.Field,
11782
11239
  {
11783
- size: "small",
11784
- leading: "compact",
11785
- className: "text-ui-fg-subtle",
11786
- children: [
11787
- items.length,
11788
- " ",
11789
- pluralize(items.length, "items", "item")
11790
- ]
11240
+ control: form.control,
11241
+ name: `metadata.${index}.value`,
11242
+ render: ({ field: { value, ...field2 } }) => {
11243
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11244
+ GridInput,
11245
+ {
11246
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
11247
+ ...field2,
11248
+ value: isDisabled ? placeholder : value,
11249
+ disabled: isDisabled,
11250
+ placeholder: "Value"
11251
+ }
11252
+ ) }) });
11253
+ }
11791
11254
  }
11792
11255
  )
11793
- ] })
11794
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-[5px] max-sm:flex-col max-sm:items-start flex-1 w-full overflow-hidden", children: [
11795
- /* @__PURE__ */ jsxRuntime.jsx(
11796
- ui.Tooltip,
11256
+ ]
11257
+ }
11258
+ ),
11259
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
11260
+ /* @__PURE__ */ jsxRuntime.jsx(
11261
+ ui.DropdownMenu.Trigger,
11262
+ {
11263
+ className: ui.clx(
11264
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11265
+ {
11266
+ hidden: isDisabled
11267
+ }
11268
+ ),
11269
+ disabled: isDisabled,
11270
+ asChild: true,
11271
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
11272
+ }
11273
+ ),
11274
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
11275
+ /* @__PURE__ */ jsxRuntime.jsxs(
11276
+ ui.DropdownMenu.Item,
11797
11277
  {
11798
- content: /* @__PURE__ */ jsxRuntime.jsx("ul", { children: items.map((item) => {
11799
- var _a3, _b2, _c2;
11800
- return /* @__PURE__ */ jsxRuntime.jsx(
11801
- "li",
11802
- {
11803
- children: `${item.quantity}x ${(_b2 = (_a3 = item.variant) == null ? void 0 : _a3.product) == null ? void 0 : _b2.title} (${(_c2 = item.variant) == null ? void 0 : _c2.title})`
11804
- },
11805
- item.id
11806
- );
11807
- }) }),
11808
- children: /* @__PURE__ */ jsxRuntime.jsxs(
11809
- ui.Badge,
11810
- {
11811
- className: "flex items-center gap-x-[3px] overflow-hidden cursor-default",
11812
- size: "xsmall",
11813
- children: [
11814
- /* @__PURE__ */ jsxRuntime.jsx(icons.Shopping, { className: "shrink-0" }),
11815
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "truncate", children: [
11816
- items.reduce(
11817
- (acc, item) => acc + item.quantity,
11818
- 0
11819
- ),
11820
- "x",
11821
- " ",
11822
- pluralize(items.length, "items", "item")
11823
- ] })
11824
- ]
11825
- }
11826
- )
11278
+ className: "gap-x-2",
11279
+ onClick: () => insertRow(index, "above"),
11280
+ children: [
11281
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
11282
+ "Insert row above"
11283
+ ]
11827
11284
  }
11828
11285
  ),
11829
- /* @__PURE__ */ jsxRuntime.jsx(
11830
- ui.Tooltip,
11286
+ /* @__PURE__ */ jsxRuntime.jsxs(
11287
+ ui.DropdownMenu.Item,
11831
11288
  {
11832
- content: (_d = (_c = (_b = shippingOption.service_zone) == null ? void 0 : _b.fulfillment_set) == null ? void 0 : _c.location) == null ? void 0 : _d.name,
11833
- children: /* @__PURE__ */ jsxRuntime.jsxs(
11834
- ui.Badge,
11835
- {
11836
- className: "flex items-center gap-x-[3px] overflow-hidden cursor-default",
11837
- size: "xsmall",
11838
- children: [
11839
- /* @__PURE__ */ jsxRuntime.jsx(icons.Buildings, { className: "shrink-0" }),
11840
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: (_g = (_f = (_e = shippingOption.service_zone) == null ? void 0 : _e.fulfillment_set) == null ? void 0 : _f.location) == null ? void 0 : _g.name })
11841
- ]
11842
- }
11843
- )
11289
+ className: "gap-x-2",
11290
+ onClick: () => insertRow(index, "below"),
11291
+ children: [
11292
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
11293
+ "Insert row below"
11294
+ ]
11844
11295
  }
11845
11296
  ),
11846
- /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: shippingOption.name, children: /* @__PURE__ */ jsxRuntime.jsxs(
11847
- ui.Badge,
11297
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
11298
+ /* @__PURE__ */ jsxRuntime.jsxs(
11299
+ ui.DropdownMenu.Item,
11848
11300
  {
11849
- className: "flex items-center gap-x-[3px] overflow-hidden cursor-default",
11850
- size: "xsmall",
11301
+ className: "gap-x-2",
11302
+ onClick: () => deleteRow(index),
11851
11303
  children: [
11852
- /* @__PURE__ */ jsxRuntime.jsx(icons.TruckFast, { className: "shrink-0" }),
11853
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: shippingOption.name })
11304
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
11305
+ "Delete row"
11854
11306
  ]
11855
11307
  }
11856
- ) })
11308
+ )
11857
11309
  ] })
11858
- ] }),
11859
- shippingOption ? /* @__PURE__ */ jsxRuntime.jsx(
11860
- ActionMenu,
11861
- {
11862
- groups: [
11863
- {
11864
- actions: [
11865
- hasItems ? {
11866
- label: "Edit shipping option",
11867
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Channels, {}),
11868
- onClick: () => {
11869
- setIsOpen(
11870
- STACKED_FOCUS_MODAL_ID,
11871
- true
11872
- );
11873
- setData({
11874
- shippingProfileId: profile.id,
11875
- shippingOption,
11876
- shippingMethod
11877
- });
11878
- }
11879
- } : void 0,
11880
- {
11881
- label: "Remove shipping option",
11882
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {}),
11883
- onClick: () => {
11884
- if (shippingMethod) {
11885
- if (addShippingMethodAction) {
11886
- removeActionShippingMethod(
11887
- addShippingMethodAction.id
11888
- );
11889
- } else {
11890
- removeShippingMethod(
11891
- shippingMethod.id
11892
- );
11893
- }
11894
- }
11895
- }
11896
- }
11897
- ].filter(Boolean)
11898
- }
11899
- ]
11900
- }
11901
- ) : /* @__PURE__ */ jsxRuntime.jsx(
11902
- StackedModalTrigger,
11903
- {
11904
- shippingProfileId: profile.id,
11905
- shippingOption,
11906
- shippingMethod,
11907
- setData,
11908
- children: "Add shipping option"
11909
- }
11910
- )
11911
- ] }),
11912
- /* @__PURE__ */ jsxRuntime.jsxs(radixUi.Accordion.Content, { children: [
11913
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11914
- items.map((item, idx) => {
11915
- var _a3, _b2, _c2, _d2, _e2;
11916
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11917
- /* @__PURE__ */ jsxRuntime.jsxs(
11918
- "div",
11919
- {
11920
- className: "px-3 flex items-center gap-x-3",
11921
- children: [
11922
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-5 h-[56px] flex flex-col justify-center items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
11923
- ui.Divider,
11924
- {
11925
- variant: "dashed",
11926
- orientation: "vertical"
11927
- }
11928
- ) }),
11929
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-2 flex items-center gap-x-3", children: [
11930
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-7 flex items-center justify-center tabular-nums", children: /* @__PURE__ */ jsxRuntime.jsxs(
11931
- ui.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
- /* @__PURE__ */ jsxRuntime.jsx(Thumbnail, { thumbnail: item.thumbnail }),
11943
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11944
- /* @__PURE__ */ jsxRuntime.jsxs(
11945
- ui.Text,
11946
- {
11947
- size: "small",
11948
- leading: "compact",
11949
- weight: "plus",
11950
- children: [
11951
- (_b2 = (_a3 = item.variant) == null ? void 0 : _a3.product) == null ? void 0 : _b2.title,
11952
- " (",
11953
- (_c2 = item.variant) == null ? void 0 : _c2.title,
11954
- ")"
11955
- ]
11956
- }
11957
- ),
11958
- /* @__PURE__ */ jsxRuntime.jsx(
11959
- ui.Text,
11960
- {
11961
- size: "small",
11962
- leading: "compact",
11963
- className: "text-ui-fg-subtle",
11964
- children: (_e2 = (_d2 = item.variant) == null ? void 0 : _d2.options) == null ? void 0 : _e2.map((option) => option.value).join(" · ")
11965
- }
11966
- )
11967
- ] })
11968
- ] })
11969
- ]
11970
- },
11971
- item.id
11972
- ),
11973
- idx !== items.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" })
11974
- ] }, item.id);
11975
- })
11310
+ ] })
11976
11311
  ] })
11977
- ]
11978
- },
11979
- profile.id
11980
- );
11981
- }) })
11312
+ },
11313
+ field.id
11314
+ );
11315
+ })
11316
+ ] }),
11317
+ 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." })
11318
+ ] }),
11319
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11320
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11321
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11982
11322
  ] }) })
11983
- ] }) }),
11984
- /* @__PURE__ */ jsxRuntime.jsx(
11985
- StackedFocusModal,
11986
- {
11987
- id: STACKED_FOCUS_MODAL_ID,
11988
- onOpenChangeCallback: (open) => {
11989
- if (!open) {
11990
- setData(null);
11991
- }
11992
- return open;
11993
- },
11994
- children: data && /* @__PURE__ */ jsxRuntime.jsx(ShippingProfileForm, { data, order, preview })
11995
- }
11996
- )
11997
- ] }),
11998
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-x-2", children: [
11999
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12000
- /* @__PURE__ */ jsxRuntime.jsx(
12001
- ui.Button,
12002
- {
12003
- size: "small",
12004
- type: "button",
12005
- isLoading: isSubmitting,
12006
- onClick: onSubmit,
12007
- children: "Save"
12008
- }
12009
- )
12010
- ] }) })
12011
- ] });
12012
- };
12013
- const StackedModalTrigger = ({
12014
- shippingProfileId,
12015
- shippingOption,
12016
- shippingMethod,
12017
- setData,
12018
- children
12019
- }) => {
12020
- const { setIsOpen, getIsOpen } = useStackedModal();
12021
- const isOpen = getIsOpen(STACKED_FOCUS_MODAL_ID);
12022
- const onToggle = () => {
12023
- if (isOpen) {
12024
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12025
- setData(null);
12026
- } else {
12027
- setIsOpen(STACKED_FOCUS_MODAL_ID, true);
12028
- setData({
12029
- shippingProfileId,
12030
- shippingOption,
12031
- shippingMethod
12032
- });
11323
+ ]
12033
11324
  }
12034
- };
11325
+ ) });
11326
+ };
11327
+ const GridInput = React.forwardRef(({ className, ...props }, ref) => {
12035
11328
  return /* @__PURE__ */ jsxRuntime.jsx(
12036
- ui.Button,
11329
+ "input",
12037
11330
  {
12038
- size: "small",
12039
- variant: "secondary",
12040
- onClick: onToggle,
12041
- className: "text-ui-fg-primary shrink-0",
12042
- children
11331
+ ref,
11332
+ ...props,
11333
+ autoComplete: "off",
11334
+ className: ui.clx(
11335
+ "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",
11336
+ className
11337
+ )
12043
11338
  }
12044
11339
  );
11340
+ });
11341
+ GridInput.displayName = "MetadataForm.GridInput";
11342
+ const PlaceholderInner = () => {
11343
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11344
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11345
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11346
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
11347
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
11348
+ ] }) })
11349
+ ] });
12045
11350
  };
12046
- const ShippingProfileForm = ({
12047
- data,
12048
- order,
12049
- preview
12050
- }) => {
12051
- var _a, _b, _c, _d, _e, _f;
12052
- const { setIsOpen } = useStackedModal();
12053
- const form = reactHookForm.useForm({
12054
- resolver: zod.zodResolver(shippingMethodSchema),
12055
- defaultValues: {
12056
- 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,
12057
- shipping_option_id: (_e = data.shippingOption) == null ? void 0 : _e.id,
12058
- custom_amount: (_f = data.shippingMethod) == null ? void 0 : _f.amount
11351
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
11352
+ function getDefaultValues(metadata) {
11353
+ if (!metadata || !Object.keys(metadata).length) {
11354
+ return [
11355
+ {
11356
+ key: "",
11357
+ value: "",
11358
+ disabled: false
11359
+ }
11360
+ ];
11361
+ }
11362
+ return Object.entries(metadata).map(([key, value]) => {
11363
+ if (!EDITABLE_TYPES.includes(typeof value)) {
11364
+ return {
11365
+ key,
11366
+ value,
11367
+ disabled: true
11368
+ };
11369
+ }
11370
+ let stringValue = value;
11371
+ if (typeof value !== "string") {
11372
+ stringValue = JSON.stringify(value);
12059
11373
  }
11374
+ return {
11375
+ key,
11376
+ value: stringValue,
11377
+ original_key: key
11378
+ };
12060
11379
  });
12061
- const { mutateAsync: addShippingMethod, isPending } = useDraftOrderAddShippingMethod(order.id);
12062
- const {
12063
- mutateAsync: updateShippingMethod,
12064
- isPending: isUpdatingShippingMethod
12065
- } = useDraftOrderUpdateShippingMethod(order.id);
12066
- const onSubmit = form.handleSubmit(async (values) => {
12067
- if (lodash.isEqual(values, form.formState.defaultValues)) {
12068
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11380
+ }
11381
+ function parseValues(values) {
11382
+ const metadata = values.metadata;
11383
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11384
+ if (isEmpty) {
11385
+ return null;
11386
+ }
11387
+ const update = {};
11388
+ metadata.forEach((field) => {
11389
+ let key = field.key;
11390
+ let value = field.value;
11391
+ const disabled = field.disabled;
11392
+ if (!key || !value) {
12069
11393
  return;
12070
11394
  }
12071
- if (data.shippingMethod) {
12072
- await updateShippingMethod(
12073
- {
12074
- method_id: data.shippingMethod.id,
12075
- shipping_option_id: values.shipping_option_id,
12076
- custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
12077
- },
12078
- {
12079
- onError: (e) => {
12080
- ui.toast.error(e.message);
12081
- },
12082
- onSuccess: () => {
12083
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12084
- }
12085
- }
12086
- );
11395
+ if (disabled) {
11396
+ update[key] = value;
12087
11397
  return;
12088
11398
  }
12089
- await addShippingMethod(
11399
+ key = key.trim();
11400
+ value = value.trim();
11401
+ if (value === "true") {
11402
+ update[key] = true;
11403
+ } else if (value === "false") {
11404
+ update[key] = false;
11405
+ } else {
11406
+ const parsedNumber = parseFloat(value);
11407
+ if (!isNaN(parsedNumber)) {
11408
+ update[key] = parsedNumber;
11409
+ } else {
11410
+ update[key] = value;
11411
+ }
11412
+ }
11413
+ });
11414
+ return update;
11415
+ }
11416
+ function getHasUneditableRows(metadata) {
11417
+ if (!metadata) {
11418
+ return false;
11419
+ }
11420
+ return Object.values(metadata).some(
11421
+ (value) => !EDITABLE_TYPES.includes(typeof value)
11422
+ );
11423
+ }
11424
+ const PROMOTION_QUERY_KEY = "promotions";
11425
+ const promotionsQueryKeys = {
11426
+ list: (query2) => [
11427
+ PROMOTION_QUERY_KEY,
11428
+ query2 ? query2 : void 0
11429
+ ],
11430
+ detail: (id, query2) => [
11431
+ PROMOTION_QUERY_KEY,
11432
+ id,
11433
+ query2 ? query2 : void 0
11434
+ ]
11435
+ };
11436
+ const usePromotions = (query2, options) => {
11437
+ const { data, ...rest } = reactQuery.useQuery({
11438
+ queryKey: promotionsQueryKeys.list(query2),
11439
+ queryFn: async () => sdk.admin.promotion.list(query2),
11440
+ ...options
11441
+ });
11442
+ return { ...data, ...rest };
11443
+ };
11444
+ const Promotions = () => {
11445
+ const { id } = reactRouterDom.useParams();
11446
+ const {
11447
+ order: preview,
11448
+ isError: isPreviewError,
11449
+ error: previewError
11450
+ } = useOrderPreview(id, void 0);
11451
+ useInitiateOrderEdit({ preview });
11452
+ const { onCancel } = useCancelOrderEdit({ preview });
11453
+ if (isPreviewError) {
11454
+ throw previewError;
11455
+ }
11456
+ const isReady = !!preview;
11457
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
11458
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
11459
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
11460
+ ] });
11461
+ };
11462
+ const PromotionForm = ({ preview }) => {
11463
+ const { items, shipping_methods } = preview;
11464
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
11465
+ const [comboboxValue, setComboboxValue] = React.useState("");
11466
+ const { handleSuccess } = useRouteModal();
11467
+ const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
11468
+ const promoCodes = getPromotionCodes(items, shipping_methods);
11469
+ const { promotions, isPending, isError, error } = usePromotions(
11470
+ {
11471
+ code: promoCodes
11472
+ },
11473
+ {
11474
+ enabled: !!promoCodes.length
11475
+ }
11476
+ );
11477
+ const comboboxData = useComboboxData({
11478
+ queryKey: ["promotions", "combobox", promoCodes],
11479
+ queryFn: async (params) => {
11480
+ return await sdk.admin.promotion.list({
11481
+ ...params,
11482
+ code: {
11483
+ $nin: promoCodes
11484
+ }
11485
+ });
11486
+ },
11487
+ getOptions: (data) => {
11488
+ return data.promotions.map((promotion) => ({
11489
+ label: promotion.code,
11490
+ value: promotion.code
11491
+ }));
11492
+ }
11493
+ });
11494
+ const add = async (value) => {
11495
+ if (!value) {
11496
+ return;
11497
+ }
11498
+ addPromotions(
12090
11499
  {
12091
- shipping_option_id: values.shipping_option_id,
12092
- custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
11500
+ promo_codes: [value]
12093
11501
  },
12094
11502
  {
12095
11503
  onError: (e) => {
12096
11504
  ui.toast.error(e.message);
11505
+ comboboxData.onSearchValueChange("");
11506
+ setComboboxValue("");
12097
11507
  },
12098
11508
  onSuccess: () => {
12099
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11509
+ comboboxData.onSearchValueChange("");
11510
+ setComboboxValue("");
12100
11511
  }
12101
11512
  }
12102
11513
  );
12103
- });
12104
- return /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12105
- KeyboundForm,
12106
- {
12107
- className: "flex h-full flex-col overflow-hidden",
12108
- onSubmit,
12109
- children: [
12110
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
12111
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
12112
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12113
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
12114
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.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." }) })
12115
- ] }),
12116
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12117
- /* @__PURE__ */ jsxRuntime.jsx(
12118
- LocationField,
12119
- {
12120
- control: form.control,
12121
- setValue: form.setValue
12122
- }
12123
- ),
12124
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12125
- /* @__PURE__ */ jsxRuntime.jsx(
12126
- ShippingOptionField,
12127
- {
12128
- shippingProfileId: data.shippingProfileId,
12129
- preview,
12130
- control: form.control
12131
- }
12132
- ),
12133
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12134
- /* @__PURE__ */ jsxRuntime.jsx(
12135
- CustomAmountField,
12136
- {
12137
- control: form.control,
12138
- currencyCode: order.currency_code
12139
- }
12140
- ),
12141
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12142
- /* @__PURE__ */ jsxRuntime.jsx(
12143
- ItemsPreview,
12144
- {
12145
- order,
12146
- shippingProfileId: data.shippingProfileId
12147
- }
12148
- )
12149
- ] }) }) }),
12150
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-x-2", children: [
12151
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12152
- /* @__PURE__ */ jsxRuntime.jsx(
12153
- ui.Button,
12154
- {
12155
- size: "small",
12156
- type: "submit",
12157
- isLoading: isPending || isUpdatingShippingMethod,
12158
- children: data.shippingMethod ? "Update" : "Add"
12159
- }
12160
- )
12161
- ] }) })
12162
- ]
12163
- }
12164
- ) }) });
12165
- };
12166
- const shippingMethodSchema = z.object({
12167
- location_id: z.string(),
12168
- shipping_option_id: z.string(),
12169
- custom_amount: z.union([z.number(), z.string()]).optional()
12170
- });
12171
- const ItemsPreview = ({ order, shippingProfileId }) => {
12172
- const matches = order.items.filter(
12173
- (item) => {
12174
- var _a, _b, _c;
12175
- return ((_c = (_b = (_a = item.variant) == null ? void 0 : _a.product) == null ? void 0 : _b.shipping_profile) == null ? void 0 : _c.id) === shippingProfileId;
11514
+ };
11515
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11516
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
11517
+ const onSubmit = async () => {
11518
+ setIsSubmitting(true);
11519
+ let requestSucceeded = false;
11520
+ await requestOrderEdit(void 0, {
11521
+ onError: (e) => {
11522
+ ui.toast.error(e.message);
11523
+ },
11524
+ onSuccess: () => {
11525
+ requestSucceeded = true;
11526
+ }
11527
+ });
11528
+ if (!requestSucceeded) {
11529
+ setIsSubmitting(false);
11530
+ return;
12176
11531
  }
12177
- );
12178
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
12179
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 items-center gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12180
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items to ship" }),
12181
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Items with the selected shipping profile." })
12182
- ] }) }),
12183
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
12184
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 px-4 py-2 text-ui-fg-muted", children: [
12185
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
12186
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) })
11532
+ await confirmOrderEdit(void 0, {
11533
+ onError: (e) => {
11534
+ ui.toast.error(e.message);
11535
+ },
11536
+ onSuccess: () => {
11537
+ handleSuccess();
11538
+ },
11539
+ onSettled: () => {
11540
+ setIsSubmitting(false);
11541
+ }
11542
+ });
11543
+ };
11544
+ if (isError) {
11545
+ throw error;
11546
+ }
11547
+ return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
11548
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
11549
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
11550
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
11551
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
11552
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
11553
+ ] }),
11554
+ /* @__PURE__ */ jsxRuntime.jsx(
11555
+ Combobox,
11556
+ {
11557
+ id: "promotion-combobox",
11558
+ "aria-describedby": "promotion-combobox-hint",
11559
+ isFetchingNextPage: comboboxData.isFetchingNextPage,
11560
+ fetchNextPage: comboboxData.fetchNextPage,
11561
+ options: comboboxData.options,
11562
+ onSearchValueChange: comboboxData.onSearchValueChange,
11563
+ searchValue: comboboxData.searchValue,
11564
+ disabled: comboboxData.disabled || isAddingPromotions,
11565
+ onChange: add,
11566
+ value: comboboxValue
11567
+ }
11568
+ )
12187
11569
  ] }),
12188
- /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsxs(
12189
- "div",
11570
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11571
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
11572
+ PromotionItem,
12190
11573
  {
12191
- className: "grid grid-cols-2 gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center",
12192
- children: [
12193
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
12194
- /* @__PURE__ */ jsxRuntime.jsx(
12195
- Thumbnail,
12196
- {
12197
- thumbnail: item.thumbnail,
12198
- alt: item.product_title ?? void 0
12199
- }
12200
- ),
12201
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12202
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
12203
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
12204
- /* @__PURE__ */ jsxRuntime.jsxs(
12205
- ui.Text,
12206
- {
12207
- size: "small",
12208
- leading: "compact",
12209
- className: "text-ui-fg-subtle",
12210
- children: [
12211
- "(",
12212
- item.variant_title,
12213
- ")"
12214
- ]
12215
- }
12216
- )
12217
- ] }),
12218
- /* @__PURE__ */ jsxRuntime.jsx(
12219
- ui.Text,
12220
- {
12221
- size: "small",
12222
- leading: "compact",
12223
- className: "text-ui-fg-subtle",
12224
- children: item.variant_sku
12225
- }
12226
- )
12227
- ] })
12228
- ] }),
12229
- /* @__PURE__ */ jsxRuntime.jsxs(
12230
- ui.Text,
12231
- {
12232
- size: "small",
12233
- leading: "compact",
12234
- className: "text-ui-fg-subtle",
12235
- children: [
12236
- item.quantity,
12237
- "x"
12238
- ]
12239
- }
12240
- )
12241
- ]
11574
+ promotion,
11575
+ orderId: preview.id,
11576
+ isLoading: isPending
12242
11577
  },
12243
- item.id
12244
- )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
12245
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
12246
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
12247
- 'No items found for "',
12248
- query,
12249
- '".'
12250
- ] })
12251
- ] }) })
12252
- ] })
11578
+ promotion.id
11579
+ )) })
11580
+ ] }) }),
11581
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11582
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11583
+ /* @__PURE__ */ jsxRuntime.jsx(
11584
+ ui.Button,
11585
+ {
11586
+ size: "small",
11587
+ type: "submit",
11588
+ isLoading: isSubmitting || isAddingPromotions,
11589
+ children: "Save"
11590
+ }
11591
+ )
11592
+ ] }) })
12253
11593
  ] });
12254
11594
  };
12255
- const LocationField = ({ control, setValue }) => {
12256
- const locations = useComboboxData({
12257
- queryKey: ["locations"],
12258
- queryFn: async (params) => {
12259
- return await sdk.admin.stockLocation.list(params);
12260
- },
12261
- getOptions: (data) => {
12262
- return data.stock_locations.map((location) => ({
12263
- label: location.name,
12264
- value: location.id
12265
- }));
12266
- }
12267
- });
12268
- return /* @__PURE__ */ jsxRuntime.jsx(
12269
- Form$2.Field,
12270
- {
12271
- control,
12272
- name: "location_id",
12273
- render: ({ field: { onChange, ...field } }) => {
12274
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12275
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12276
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Location" }),
12277
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose where you want to ship the items from." })
12278
- ] }),
12279
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12280
- Combobox,
12281
- {
12282
- options: locations.options,
12283
- fetchNextPage: locations.fetchNextPage,
12284
- isFetchingNextPage: locations.isFetchingNextPage,
12285
- searchValue: locations.searchValue,
12286
- onSearchValueChange: locations.onSearchValueChange,
12287
- placeholder: "Select location",
12288
- onChange: (value) => {
12289
- setValue("shipping_option_id", "", {
12290
- shouldDirty: true,
12291
- shouldTouch: true
12292
- });
12293
- onChange(value);
12294
- },
12295
- ...field
12296
- }
12297
- ) })
12298
- ] }) });
12299
- }
12300
- }
12301
- );
12302
- };
12303
- const ShippingOptionField = ({
12304
- shippingProfileId,
12305
- preview,
12306
- control
11595
+ const PromotionItem = ({
11596
+ promotion,
11597
+ orderId,
11598
+ isLoading
12307
11599
  }) => {
12308
11600
  var _a;
12309
- const locationId = reactHookForm.useWatch({ control, name: "location_id" });
12310
- const shippingOptions = useComboboxData({
12311
- queryKey: ["shipping_options", locationId, shippingProfileId],
12312
- queryFn: async (params) => {
12313
- return await sdk.admin.shippingOption.list({
12314
- ...params,
12315
- stock_location_id: locationId,
12316
- shipping_profile_id: shippingProfileId
12317
- });
12318
- },
12319
- getOptions: (data) => {
12320
- return data.shipping_options.map((option) => {
12321
- var _a2;
12322
- if ((_a2 = option.rules) == null ? void 0 : _a2.find(
12323
- (r) => r.attribute === "is_return" && r.value === "true"
12324
- )) {
12325
- return void 0;
11601
+ const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
11602
+ const onRemove = async () => {
11603
+ removePromotions(
11604
+ {
11605
+ promo_codes: [promotion.code]
11606
+ },
11607
+ {
11608
+ onError: (e) => {
11609
+ ui.toast.error(e.message);
12326
11610
  }
12327
- return {
12328
- label: option.name,
12329
- value: option.id
12330
- };
12331
- }).filter(Boolean);
12332
- },
12333
- enabled: !!locationId && !!shippingProfileId,
12334
- defaultValue: ((_a = preview.shipping_methods[0]) == null ? void 0 : _a.shipping_option_id) || void 0
12335
- });
12336
- const tooltipContent = !locationId && !shippingProfileId ? "Choose a location and shipping profile first." : !locationId ? "Choose a location first." : "Choose a shipping profile first.";
12337
- return /* @__PURE__ */ jsxRuntime.jsx(
12338
- Form$2.Field,
12339
- {
12340
- control,
12341
- name: "shipping_option_id",
12342
- render: ({ field }) => {
12343
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12344
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12345
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Shipping option" }),
12346
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose the shipping option to use." })
12347
- ] }),
12348
- /* @__PURE__ */ jsxRuntime.jsx(
12349
- ConditionalTooltip,
12350
- {
12351
- content: tooltipContent,
12352
- showTooltip: !locationId || !shippingProfileId,
12353
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12354
- Combobox,
12355
- {
12356
- options: shippingOptions.options,
12357
- fetchNextPage: shippingOptions.fetchNextPage,
12358
- isFetchingNextPage: shippingOptions.isFetchingNextPage,
12359
- searchValue: shippingOptions.searchValue,
12360
- onSearchValueChange: shippingOptions.onSearchValueChange,
12361
- placeholder: "Select shipping option",
12362
- ...field,
12363
- disabled: !locationId || !shippingProfileId
12364
- }
12365
- ) }) })
12366
- }
12367
- )
12368
- ] }) });
12369
11611
  }
12370
- }
11612
+ );
11613
+ };
11614
+ const displayValue = getDisplayValue(promotion);
11615
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11616
+ "div",
11617
+ {
11618
+ className: ui.clx(
11619
+ "px-3 py-2 rounded-lg bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between",
11620
+ {
11621
+ "animate-pulse": isLoading
11622
+ }
11623
+ ),
11624
+ children: [
11625
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11626
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11627
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-ui-fg-subtle", children: [
11628
+ displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
11629
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
11630
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
11631
+ ] }),
11632
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11633
+ ] })
11634
+ ] }),
11635
+ /* @__PURE__ */ jsxRuntime.jsx(
11636
+ ui.IconButton,
11637
+ {
11638
+ size: "small",
11639
+ type: "button",
11640
+ variant: "transparent",
11641
+ onClick: onRemove,
11642
+ isLoading: isPending || isLoading,
11643
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
11644
+ }
11645
+ )
11646
+ ]
11647
+ },
11648
+ promotion.id
12371
11649
  );
12372
11650
  };
12373
- const CustomAmountField = ({
12374
- control,
12375
- currencyCode
12376
- }) => {
12377
- return /* @__PURE__ */ jsxRuntime.jsx(
12378
- Form$2.Field,
12379
- {
12380
- control,
12381
- name: "custom_amount",
12382
- render: ({ field: { onChange, ...field } }) => {
12383
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12384
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12385
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12386
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12387
- ] }),
12388
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12389
- ui.CurrencyInput,
12390
- {
12391
- ...field,
12392
- onValueChange: (value) => onChange(value),
12393
- symbol: getNativeSymbol(currencyCode),
12394
- code: currencyCode
12395
- }
12396
- ) })
12397
- ] });
12398
- }
11651
+ function getDisplayValue(promotion) {
11652
+ var _a, _b, _c, _d;
11653
+ const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11654
+ if (!value) {
11655
+ return null;
11656
+ }
11657
+ if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11658
+ const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11659
+ if (!currency) {
11660
+ return null;
12399
11661
  }
12400
- );
11662
+ return getLocaleAmount(value, currency);
11663
+ } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11664
+ return formatPercentage(value);
11665
+ }
11666
+ return null;
11667
+ }
11668
+ const formatter = new Intl.NumberFormat([], {
11669
+ style: "percent",
11670
+ minimumFractionDigits: 2
11671
+ });
11672
+ const formatPercentage = (value, isPercentageValue = false) => {
11673
+ let val = value || 0;
11674
+ if (!isPercentageValue) {
11675
+ val = val / 100;
11676
+ }
11677
+ return formatter.format(val);
12401
11678
  };
11679
+ function getPromotionCodes(items, shippingMethods) {
11680
+ const codes = /* @__PURE__ */ new Set();
11681
+ for (const item of items) {
11682
+ if (item.adjustments) {
11683
+ for (const adjustment of item.adjustments) {
11684
+ if (adjustment.code) {
11685
+ codes.add(adjustment.code);
11686
+ }
11687
+ }
11688
+ }
11689
+ }
11690
+ for (const shippingMethod of shippingMethods) {
11691
+ if (shippingMethod.adjustments) {
11692
+ for (const adjustment of shippingMethod.adjustments) {
11693
+ if (adjustment.code) {
11694
+ codes.add(adjustment.code);
11695
+ }
11696
+ }
11697
+ }
11698
+ }
11699
+ return Array.from(codes);
11700
+ }
12402
11701
  const ShippingAddress = () => {
12403
11702
  const { id } = reactRouterDom.useParams();
12404
11703
  const { order, isPending, isError, error } = useOrder(id, {
@@ -12431,7 +11730,7 @@ const ShippingAddressForm = ({ order }) => {
12431
11730
  postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12432
11731
  phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12433
11732
  },
12434
- resolver: zod.zodResolver(schema$2)
11733
+ resolver: zod.zodResolver(schema$1)
12435
11734
  });
12436
11735
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12437
11736
  const { handleSuccess } = useRouteModal();
@@ -12601,7 +11900,7 @@ const ShippingAddressForm = ({ order }) => {
12601
11900
  }
12602
11901
  ) });
12603
11902
  };
12604
- const schema$2 = addressSchema;
11903
+ const schema$1 = addressSchema;
12605
11904
  const TransferOwnership = () => {
12606
11905
  const { id } = reactRouterDom.useParams();
12607
11906
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -12625,7 +11924,7 @@ const TransferOwnershipForm = ({ order }) => {
12625
11924
  defaultValues: {
12626
11925
  customer_id: order.customer_id || ""
12627
11926
  },
12628
- resolver: zod.zodResolver(schema$1)
11927
+ resolver: zod.zodResolver(schema)
12629
11928
  });
12630
11929
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12631
11930
  const { handleSuccess } = useRouteModal();
@@ -13014,176 +12313,877 @@ const Illustration = () => {
13014
12313
  strokeLinecap: "round",
13015
12314
  strokeLinejoin: "round"
13016
12315
  }
13017
- ) }),
13018
- /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
13019
- /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip0_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
13020
- "rect",
13021
- {
13022
- width: "12",
13023
- height: "12",
13024
- fill: "white",
13025
- transform: "matrix(0.865865 0.500278 -0.871576 0.490261 138.36 74.6508)"
13026
- }
13027
- ) }),
13028
- /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip1_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
13029
- "rect",
12316
+ ) }),
12317
+ /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
12318
+ /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip0_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
12319
+ "rect",
12320
+ {
12321
+ width: "12",
12322
+ height: "12",
12323
+ fill: "white",
12324
+ transform: "matrix(0.865865 0.500278 -0.871576 0.490261 138.36 74.6508)"
12325
+ }
12326
+ ) }),
12327
+ /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip1_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
12328
+ "rect",
12329
+ {
12330
+ width: "12",
12331
+ height: "12",
12332
+ fill: "white",
12333
+ transform: "matrix(0.865865 0.500278 -0.871576 0.490261 148.75 80.6541)"
12334
+ }
12335
+ ) }),
12336
+ /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip2_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
12337
+ "rect",
12338
+ {
12339
+ width: "12",
12340
+ height: "12",
12341
+ fill: "white",
12342
+ transform: "matrix(0.865865 0.500278 -0.871576 0.490261 159.141 86.6575)"
12343
+ }
12344
+ ) }),
12345
+ /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip3_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
12346
+ "rect",
12347
+ {
12348
+ width: "12",
12349
+ height: "12",
12350
+ fill: "white",
12351
+ transform: "matrix(0.865865 0.500278 -0.871576 0.490261 120.928 84.4561)"
12352
+ }
12353
+ ) }),
12354
+ /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip4_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
12355
+ "rect",
12356
+ {
12357
+ width: "12",
12358
+ height: "12",
12359
+ fill: "white",
12360
+ transform: "matrix(0.865865 0.500278 -0.871576 0.490261 131.318 90.4594)"
12361
+ }
12362
+ ) }),
12363
+ /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip5_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
12364
+ "rect",
12365
+ {
12366
+ width: "12",
12367
+ height: "12",
12368
+ fill: "white",
12369
+ transform: "matrix(0.865865 0.500278 -0.871576 0.490261 141.709 96.4627)"
12370
+ }
12371
+ ) })
12372
+ ] })
12373
+ ]
12374
+ }
12375
+ );
12376
+ };
12377
+ const schema = z.object({
12378
+ customer_id: z.string().min(1)
12379
+ });
12380
+ const STACKED_FOCUS_MODAL_ID = "shipping-form";
12381
+ const Shipping = () => {
12382
+ var _a;
12383
+ const { id } = reactRouterDom.useParams();
12384
+ const { order, isPending, isError, error } = useOrder(id, {
12385
+ fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
12386
+ });
12387
+ const {
12388
+ order: preview,
12389
+ isPending: isPreviewPending,
12390
+ isError: isPreviewError,
12391
+ error: previewError
12392
+ } = useOrderPreview(id);
12393
+ useInitiateOrderEdit({ preview });
12394
+ const { onCancel } = useCancelOrderEdit({ preview });
12395
+ if (isError) {
12396
+ throw error;
12397
+ }
12398
+ if (isPreviewError) {
12399
+ throw previewError;
12400
+ }
12401
+ const orderHasItems = (((_a = order == null ? void 0 : order.items) == null ? void 0 : _a.length) || 0) > 0;
12402
+ const isReady = preview && !isPreviewPending && order && !isPending;
12403
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
12404
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
12405
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
12406
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
12407
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This draft order currently has no items. Add items to the order before adding shipping." }) })
12408
+ ] }) }) }),
12409
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }) })
12410
+ ] }) : isReady ? /* @__PURE__ */ jsxRuntime.jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12411
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
12412
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
12413
+ ] }) });
12414
+ };
12415
+ const ShippingForm = ({ preview, order }) => {
12416
+ var _a;
12417
+ const { setIsOpen } = useStackedModal();
12418
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
12419
+ const [data, setData] = React.useState(null);
12420
+ const appliedShippingOptionIds = (_a = preview.shipping_methods) == null ? void 0 : _a.map((method) => method.shipping_option_id).filter(Boolean);
12421
+ const { shipping_options } = useShippingOptions(
12422
+ {
12423
+ id: appliedShippingOptionIds,
12424
+ fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
12425
+ },
12426
+ {
12427
+ enabled: appliedShippingOptionIds.length > 0
12428
+ }
12429
+ );
12430
+ const uniqueShippingProfiles = React.useMemo(() => {
12431
+ const profiles = /* @__PURE__ */ new Map();
12432
+ getUniqueShippingProfiles(order.items).forEach((profile) => {
12433
+ profiles.set(profile.id, profile);
12434
+ });
12435
+ shipping_options == null ? void 0 : shipping_options.forEach((option) => {
12436
+ profiles.set(option.shipping_profile_id, option.shipping_profile);
12437
+ });
12438
+ return Array.from(profiles.values());
12439
+ }, [order.items, shipping_options]);
12440
+ const { handleSuccess } = useRouteModal();
12441
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
12442
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
12443
+ const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
12444
+ const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
12445
+ const onSubmit = async () => {
12446
+ setIsSubmitting(true);
12447
+ let requestSucceeded = false;
12448
+ await requestOrderEdit(void 0, {
12449
+ onError: (e) => {
12450
+ ui.toast.error(`Failed to request order edit: ${e.message}`);
12451
+ },
12452
+ onSuccess: () => {
12453
+ requestSucceeded = true;
12454
+ }
12455
+ });
12456
+ if (!requestSucceeded) {
12457
+ setIsSubmitting(false);
12458
+ return;
12459
+ }
12460
+ await confirmOrderEdit(void 0, {
12461
+ onError: (e) => {
12462
+ ui.toast.error(`Failed to confirm order edit: ${e.message}`);
12463
+ },
12464
+ onSuccess: () => {
12465
+ handleSuccess();
12466
+ },
12467
+ onSettled: () => {
12468
+ setIsSubmitting(false);
12469
+ }
12470
+ });
12471
+ };
12472
+ const onKeydown = React.useCallback(
12473
+ (e) => {
12474
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
12475
+ if (data || isSubmitting) {
12476
+ return;
12477
+ }
12478
+ onSubmit();
12479
+ }
12480
+ },
12481
+ [data, isSubmitting, onSubmit]
12482
+ );
12483
+ React.useEffect(() => {
12484
+ document.addEventListener("keydown", onKeydown);
12485
+ return () => {
12486
+ document.removeEventListener("keydown", onKeydown);
12487
+ };
12488
+ }, [onKeydown]);
12489
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
12490
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
12491
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: [
12492
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
12493
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12494
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
12495
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose which shipping method(s) to use for the items in the order." }) })
12496
+ ] }),
12497
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12498
+ /* @__PURE__ */ jsxRuntime.jsx(radixUi.Accordion.Root, { type: "multiple", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle rounded-xl shadow-elevation-card-rest", children: [
12499
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-2 flex items-center justify-between", children: [
12500
+ /* @__PURE__ */ jsxRuntime.jsx(
12501
+ ui.Text,
12502
+ {
12503
+ size: "xsmall",
12504
+ weight: "plus",
12505
+ className: "text-ui-fg-muted",
12506
+ children: "Shipping profile"
12507
+ }
12508
+ ),
12509
+ /* @__PURE__ */ jsxRuntime.jsx(
12510
+ ui.Text,
12511
+ {
12512
+ size: "xsmall",
12513
+ weight: "plus",
12514
+ className: "text-ui-fg-muted",
12515
+ children: "Action"
12516
+ }
12517
+ )
12518
+ ] }),
12519
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-[5px] pb-[5px]", children: uniqueShippingProfiles.map((profile) => {
12520
+ var _a2, _b, _c, _d, _e, _f, _g;
12521
+ const items = getItemsWithShippingProfile(
12522
+ profile.id,
12523
+ order.items
12524
+ );
12525
+ const hasItems = items.length > 0;
12526
+ const shippingOption = shipping_options == null ? void 0 : shipping_options.find(
12527
+ (option) => option.shipping_profile_id === profile.id
12528
+ );
12529
+ const shippingMethod = preview.shipping_methods.find(
12530
+ (method) => method.shipping_option_id === (shippingOption == null ? void 0 : shippingOption.id)
12531
+ );
12532
+ const addShippingMethodAction = (_a2 = shippingMethod == null ? void 0 : shippingMethod.actions) == null ? void 0 : _a2.find(
12533
+ (action) => action.action === "SHIPPING_ADD"
12534
+ );
12535
+ return /* @__PURE__ */ jsxRuntime.jsxs(
12536
+ radixUi.Accordion.Item,
12537
+ {
12538
+ value: profile.id,
12539
+ className: "bg-ui-bg-base shadow-elevation-card-rest rounded-lg",
12540
+ children: [
12541
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-2 flex items-center justify-between gap-3", children: [
12542
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3 w-full overflow-hidden", children: [
12543
+ /* @__PURE__ */ jsxRuntime.jsx(radixUi.Accordion.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
12544
+ ui.IconButton,
12545
+ {
12546
+ size: "2xsmall",
12547
+ variant: "transparent",
12548
+ className: "group/trigger",
12549
+ disabled: !hasItems,
12550
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.TriangleRightMini, { className: "group-data-[state=open]/trigger:rotate-90 transition-transform" })
12551
+ }
12552
+ ) }),
12553
+ !shippingOption ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
12554
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-7 rounded-md shadow-borders-base flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-6 rounded bg-ui-bg-component-hover flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Shopping, { className: "text-ui-fg-subtle" }) }) }),
12555
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col flex-1", children: [
12556
+ /* @__PURE__ */ jsxRuntime.jsx(
12557
+ ui.Text,
12558
+ {
12559
+ size: "small",
12560
+ weight: "plus",
12561
+ leading: "compact",
12562
+ children: profile.name
12563
+ }
12564
+ ),
12565
+ /* @__PURE__ */ jsxRuntime.jsxs(
12566
+ ui.Text,
12567
+ {
12568
+ size: "small",
12569
+ leading: "compact",
12570
+ className: "text-ui-fg-subtle",
12571
+ children: [
12572
+ items.length,
12573
+ " ",
12574
+ pluralize(items.length, "items", "item")
12575
+ ]
12576
+ }
12577
+ )
12578
+ ] })
12579
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-[5px] max-sm:flex-col max-sm:items-start flex-1 w-full overflow-hidden", children: [
12580
+ /* @__PURE__ */ jsxRuntime.jsx(
12581
+ ui.Tooltip,
12582
+ {
12583
+ content: /* @__PURE__ */ jsxRuntime.jsx("ul", { children: items.map((item) => {
12584
+ var _a3, _b2, _c2;
12585
+ return /* @__PURE__ */ jsxRuntime.jsx(
12586
+ "li",
12587
+ {
12588
+ children: `${item.quantity}x ${(_b2 = (_a3 = item.variant) == null ? void 0 : _a3.product) == null ? void 0 : _b2.title} (${(_c2 = item.variant) == null ? void 0 : _c2.title})`
12589
+ },
12590
+ item.id
12591
+ );
12592
+ }) }),
12593
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
12594
+ ui.Badge,
12595
+ {
12596
+ className: "flex items-center gap-x-[3px] overflow-hidden cursor-default",
12597
+ size: "xsmall",
12598
+ children: [
12599
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Shopping, { className: "shrink-0" }),
12600
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "truncate", children: [
12601
+ items.reduce(
12602
+ (acc, item) => acc + item.quantity,
12603
+ 0
12604
+ ),
12605
+ "x",
12606
+ " ",
12607
+ pluralize(items.length, "items", "item")
12608
+ ] })
12609
+ ]
12610
+ }
12611
+ )
12612
+ }
12613
+ ),
12614
+ /* @__PURE__ */ jsxRuntime.jsx(
12615
+ ui.Tooltip,
12616
+ {
12617
+ content: (_d = (_c = (_b = shippingOption.service_zone) == null ? void 0 : _b.fulfillment_set) == null ? void 0 : _c.location) == null ? void 0 : _d.name,
12618
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
12619
+ ui.Badge,
12620
+ {
12621
+ className: "flex items-center gap-x-[3px] overflow-hidden cursor-default",
12622
+ size: "xsmall",
12623
+ children: [
12624
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Buildings, { className: "shrink-0" }),
12625
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: (_g = (_f = (_e = shippingOption.service_zone) == null ? void 0 : _e.fulfillment_set) == null ? void 0 : _f.location) == null ? void 0 : _g.name })
12626
+ ]
12627
+ }
12628
+ )
12629
+ }
12630
+ ),
12631
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: shippingOption.name, children: /* @__PURE__ */ jsxRuntime.jsxs(
12632
+ ui.Badge,
12633
+ {
12634
+ className: "flex items-center gap-x-[3px] overflow-hidden cursor-default",
12635
+ size: "xsmall",
12636
+ children: [
12637
+ /* @__PURE__ */ jsxRuntime.jsx(icons.TruckFast, { className: "shrink-0" }),
12638
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: shippingOption.name })
12639
+ ]
12640
+ }
12641
+ ) })
12642
+ ] })
12643
+ ] }),
12644
+ shippingOption ? /* @__PURE__ */ jsxRuntime.jsx(
12645
+ ActionMenu,
12646
+ {
12647
+ groups: [
12648
+ {
12649
+ actions: [
12650
+ hasItems ? {
12651
+ label: "Edit shipping option",
12652
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Channels, {}),
12653
+ onClick: () => {
12654
+ setIsOpen(
12655
+ STACKED_FOCUS_MODAL_ID,
12656
+ true
12657
+ );
12658
+ setData({
12659
+ shippingProfileId: profile.id,
12660
+ shippingOption,
12661
+ shippingMethod
12662
+ });
12663
+ }
12664
+ } : void 0,
12665
+ {
12666
+ label: "Remove shipping option",
12667
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {}),
12668
+ onClick: () => {
12669
+ if (shippingMethod) {
12670
+ if (addShippingMethodAction) {
12671
+ removeActionShippingMethod(
12672
+ addShippingMethodAction.id
12673
+ );
12674
+ } else {
12675
+ removeShippingMethod(
12676
+ shippingMethod.id
12677
+ );
12678
+ }
12679
+ }
12680
+ }
12681
+ }
12682
+ ].filter(Boolean)
12683
+ }
12684
+ ]
12685
+ }
12686
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
12687
+ StackedModalTrigger,
12688
+ {
12689
+ shippingProfileId: profile.id,
12690
+ shippingOption,
12691
+ shippingMethod,
12692
+ setData,
12693
+ children: "Add shipping option"
12694
+ }
12695
+ )
12696
+ ] }),
12697
+ /* @__PURE__ */ jsxRuntime.jsxs(radixUi.Accordion.Content, { children: [
12698
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12699
+ items.map((item, idx) => {
12700
+ var _a3, _b2, _c2, _d2, _e2;
12701
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12702
+ /* @__PURE__ */ jsxRuntime.jsxs(
12703
+ "div",
12704
+ {
12705
+ className: "px-3 flex items-center gap-x-3",
12706
+ children: [
12707
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-5 h-[56px] flex flex-col justify-center items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
12708
+ ui.Divider,
12709
+ {
12710
+ variant: "dashed",
12711
+ orientation: "vertical"
12712
+ }
12713
+ ) }),
12714
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-2 flex items-center gap-x-3", children: [
12715
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-7 flex items-center justify-center tabular-nums", children: /* @__PURE__ */ jsxRuntime.jsxs(
12716
+ ui.Text,
12717
+ {
12718
+ size: "small",
12719
+ leading: "compact",
12720
+ className: "text-ui-fg-subtle",
12721
+ children: [
12722
+ item.quantity,
12723
+ "x"
12724
+ ]
12725
+ }
12726
+ ) }),
12727
+ /* @__PURE__ */ jsxRuntime.jsx(Thumbnail, { thumbnail: item.thumbnail }),
12728
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12729
+ /* @__PURE__ */ jsxRuntime.jsxs(
12730
+ ui.Text,
12731
+ {
12732
+ size: "small",
12733
+ leading: "compact",
12734
+ weight: "plus",
12735
+ children: [
12736
+ (_b2 = (_a3 = item.variant) == null ? void 0 : _a3.product) == null ? void 0 : _b2.title,
12737
+ " (",
12738
+ (_c2 = item.variant) == null ? void 0 : _c2.title,
12739
+ ")"
12740
+ ]
12741
+ }
12742
+ ),
12743
+ /* @__PURE__ */ jsxRuntime.jsx(
12744
+ ui.Text,
12745
+ {
12746
+ size: "small",
12747
+ leading: "compact",
12748
+ className: "text-ui-fg-subtle",
12749
+ children: (_e2 = (_d2 = item.variant) == null ? void 0 : _d2.options) == null ? void 0 : _e2.map((option) => option.value).join(" · ")
12750
+ }
12751
+ )
12752
+ ] })
12753
+ ] })
12754
+ ]
12755
+ },
12756
+ item.id
12757
+ ),
12758
+ idx !== items.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" })
12759
+ ] }, item.id);
12760
+ })
12761
+ ] })
12762
+ ]
12763
+ },
12764
+ profile.id
12765
+ );
12766
+ }) })
12767
+ ] }) })
12768
+ ] }) }),
12769
+ /* @__PURE__ */ jsxRuntime.jsx(
12770
+ StackedFocusModal,
12771
+ {
12772
+ id: STACKED_FOCUS_MODAL_ID,
12773
+ onOpenChangeCallback: (open) => {
12774
+ if (!open) {
12775
+ setData(null);
12776
+ }
12777
+ return open;
12778
+ },
12779
+ children: data && /* @__PURE__ */ jsxRuntime.jsx(ShippingProfileForm, { data, order, preview })
12780
+ }
12781
+ )
12782
+ ] }),
12783
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-x-2", children: [
12784
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12785
+ /* @__PURE__ */ jsxRuntime.jsx(
12786
+ ui.Button,
12787
+ {
12788
+ size: "small",
12789
+ type: "button",
12790
+ isLoading: isSubmitting,
12791
+ onClick: onSubmit,
12792
+ children: "Save"
12793
+ }
12794
+ )
12795
+ ] }) })
12796
+ ] });
12797
+ };
12798
+ const StackedModalTrigger = ({
12799
+ shippingProfileId,
12800
+ shippingOption,
12801
+ shippingMethod,
12802
+ setData,
12803
+ children
12804
+ }) => {
12805
+ const { setIsOpen, getIsOpen } = useStackedModal();
12806
+ const isOpen = getIsOpen(STACKED_FOCUS_MODAL_ID);
12807
+ const onToggle = () => {
12808
+ if (isOpen) {
12809
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12810
+ setData(null);
12811
+ } else {
12812
+ setIsOpen(STACKED_FOCUS_MODAL_ID, true);
12813
+ setData({
12814
+ shippingProfileId,
12815
+ shippingOption,
12816
+ shippingMethod
12817
+ });
12818
+ }
12819
+ };
12820
+ return /* @__PURE__ */ jsxRuntime.jsx(
12821
+ ui.Button,
12822
+ {
12823
+ size: "small",
12824
+ variant: "secondary",
12825
+ onClick: onToggle,
12826
+ className: "text-ui-fg-primary shrink-0",
12827
+ children
12828
+ }
12829
+ );
12830
+ };
12831
+ const ShippingProfileForm = ({
12832
+ data,
12833
+ order,
12834
+ preview
12835
+ }) => {
12836
+ var _a, _b, _c, _d, _e, _f;
12837
+ const { setIsOpen } = useStackedModal();
12838
+ const form = reactHookForm.useForm({
12839
+ resolver: zod.zodResolver(shippingMethodSchema),
12840
+ defaultValues: {
12841
+ 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,
12842
+ shipping_option_id: (_e = data.shippingOption) == null ? void 0 : _e.id,
12843
+ custom_amount: (_f = data.shippingMethod) == null ? void 0 : _f.amount
12844
+ }
12845
+ });
12846
+ const { mutateAsync: addShippingMethod, isPending } = useDraftOrderAddShippingMethod(order.id);
12847
+ const {
12848
+ mutateAsync: updateShippingMethod,
12849
+ isPending: isUpdatingShippingMethod
12850
+ } = useDraftOrderUpdateShippingMethod(order.id);
12851
+ const onSubmit = form.handleSubmit(async (values) => {
12852
+ if (lodash.isEqual(values, form.formState.defaultValues)) {
12853
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12854
+ return;
12855
+ }
12856
+ if (data.shippingMethod) {
12857
+ await updateShippingMethod(
12858
+ {
12859
+ method_id: data.shippingMethod.id,
12860
+ shipping_option_id: values.shipping_option_id,
12861
+ custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
12862
+ },
12863
+ {
12864
+ onError: (e) => {
12865
+ ui.toast.error(e.message);
12866
+ },
12867
+ onSuccess: () => {
12868
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12869
+ }
12870
+ }
12871
+ );
12872
+ return;
12873
+ }
12874
+ await addShippingMethod(
12875
+ {
12876
+ shipping_option_id: values.shipping_option_id,
12877
+ custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
12878
+ },
12879
+ {
12880
+ onError: (e) => {
12881
+ ui.toast.error(e.message);
12882
+ },
12883
+ onSuccess: () => {
12884
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12885
+ }
12886
+ }
12887
+ );
12888
+ });
12889
+ return /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12890
+ KeyboundForm,
12891
+ {
12892
+ className: "flex h-full flex-col overflow-hidden",
12893
+ onSubmit,
12894
+ children: [
12895
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
12896
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
12897
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12898
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
12899
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.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." }) })
12900
+ ] }),
12901
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12902
+ /* @__PURE__ */ jsxRuntime.jsx(
12903
+ LocationField,
13030
12904
  {
13031
- width: "12",
13032
- height: "12",
13033
- fill: "white",
13034
- transform: "matrix(0.865865 0.500278 -0.871576 0.490261 148.75 80.6541)"
12905
+ control: form.control,
12906
+ setValue: form.setValue
13035
12907
  }
13036
- ) }),
13037
- /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip2_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
13038
- "rect",
12908
+ ),
12909
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12910
+ /* @__PURE__ */ jsxRuntime.jsx(
12911
+ ShippingOptionField,
13039
12912
  {
13040
- width: "12",
13041
- height: "12",
13042
- fill: "white",
13043
- transform: "matrix(0.865865 0.500278 -0.871576 0.490261 159.141 86.6575)"
12913
+ shippingProfileId: data.shippingProfileId,
12914
+ preview,
12915
+ control: form.control
13044
12916
  }
13045
- ) }),
13046
- /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip3_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
13047
- "rect",
12917
+ ),
12918
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12919
+ /* @__PURE__ */ jsxRuntime.jsx(
12920
+ CustomAmountField,
13048
12921
  {
13049
- width: "12",
13050
- height: "12",
13051
- fill: "white",
13052
- transform: "matrix(0.865865 0.500278 -0.871576 0.490261 120.928 84.4561)"
12922
+ control: form.control,
12923
+ currencyCode: order.currency_code
13053
12924
  }
13054
- ) }),
13055
- /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip4_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
13056
- "rect",
12925
+ ),
12926
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12927
+ /* @__PURE__ */ jsxRuntime.jsx(
12928
+ ItemsPreview,
13057
12929
  {
13058
- width: "12",
13059
- height: "12",
13060
- fill: "white",
13061
- transform: "matrix(0.865865 0.500278 -0.871576 0.490261 131.318 90.4594)"
12930
+ order,
12931
+ shippingProfileId: data.shippingProfileId
13062
12932
  }
13063
- ) }),
13064
- /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip5_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
13065
- "rect",
12933
+ )
12934
+ ] }) }) }),
12935
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-x-2", children: [
12936
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12937
+ /* @__PURE__ */ jsxRuntime.jsx(
12938
+ ui.Button,
13066
12939
  {
13067
- width: "12",
13068
- height: "12",
13069
- fill: "white",
13070
- transform: "matrix(0.865865 0.500278 -0.871576 0.490261 141.709 96.4627)"
12940
+ size: "small",
12941
+ type: "submit",
12942
+ isLoading: isPending || isUpdatingShippingMethod,
12943
+ children: data.shippingMethod ? "Update" : "Add"
13071
12944
  }
13072
- ) })
12945
+ )
12946
+ ] }) })
12947
+ ]
12948
+ }
12949
+ ) }) });
12950
+ };
12951
+ const shippingMethodSchema = z.object({
12952
+ location_id: z.string(),
12953
+ shipping_option_id: z.string(),
12954
+ custom_amount: z.union([z.number(), z.string()]).optional()
12955
+ });
12956
+ const ItemsPreview = ({ order, shippingProfileId }) => {
12957
+ const matches = order.items.filter(
12958
+ (item) => {
12959
+ var _a, _b, _c;
12960
+ return ((_c = (_b = (_a = item.variant) == null ? void 0 : _a.product) == null ? void 0 : _b.shipping_profile) == null ? void 0 : _c.id) === shippingProfileId;
12961
+ }
12962
+ );
12963
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
12964
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 items-center gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12965
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items to ship" }),
12966
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Items with the selected shipping profile." })
12967
+ ] }) }),
12968
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
12969
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 px-4 py-2 text-ui-fg-muted", children: [
12970
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
12971
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) })
12972
+ ] }),
12973
+ /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsxs(
12974
+ "div",
12975
+ {
12976
+ className: "grid grid-cols-2 gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center",
12977
+ children: [
12978
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
12979
+ /* @__PURE__ */ jsxRuntime.jsx(
12980
+ Thumbnail,
12981
+ {
12982
+ thumbnail: item.thumbnail,
12983
+ alt: item.product_title ?? void 0
12984
+ }
12985
+ ),
12986
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12987
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
12988
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
12989
+ /* @__PURE__ */ jsxRuntime.jsxs(
12990
+ ui.Text,
12991
+ {
12992
+ size: "small",
12993
+ leading: "compact",
12994
+ className: "text-ui-fg-subtle",
12995
+ children: [
12996
+ "(",
12997
+ item.variant_title,
12998
+ ")"
12999
+ ]
13000
+ }
13001
+ )
13002
+ ] }),
13003
+ /* @__PURE__ */ jsxRuntime.jsx(
13004
+ ui.Text,
13005
+ {
13006
+ size: "small",
13007
+ leading: "compact",
13008
+ className: "text-ui-fg-subtle",
13009
+ children: item.variant_sku
13010
+ }
13011
+ )
13012
+ ] })
13013
+ ] }),
13014
+ /* @__PURE__ */ jsxRuntime.jsxs(
13015
+ ui.Text,
13016
+ {
13017
+ size: "small",
13018
+ leading: "compact",
13019
+ className: "text-ui-fg-subtle",
13020
+ children: [
13021
+ item.quantity,
13022
+ "x"
13023
+ ]
13024
+ }
13025
+ )
13026
+ ]
13027
+ },
13028
+ item.id
13029
+ )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
13030
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
13031
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
13032
+ 'No items found for "',
13033
+ query,
13034
+ '".'
13073
13035
  ] })
13074
- ]
13075
- }
13076
- );
13077
- };
13078
- const schema$1 = z.object({
13079
- customer_id: z.string().min(1)
13080
- });
13081
- const SalesChannel = () => {
13082
- const { id } = reactRouterDom.useParams();
13083
- const { draft_order, isPending, isError, error } = useDraftOrder(
13084
- id,
13085
- {
13086
- fields: "+sales_channel_id"
13087
- },
13088
- {
13089
- enabled: !!id
13090
- }
13091
- );
13092
- if (isError) {
13093
- throw error;
13094
- }
13095
- const ISrEADY = !!draft_order && !isPending;
13096
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
13097
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
13098
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
13099
- /* @__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" }) })
13100
- ] }),
13101
- ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
13036
+ ] }) })
13037
+ ] })
13102
13038
  ] });
13103
13039
  };
13104
- const SalesChannelForm = ({ order }) => {
13105
- const form = reactHookForm.useForm({
13106
- defaultValues: {
13107
- sales_channel_id: order.sales_channel_id || ""
13040
+ const LocationField = ({ control, setValue }) => {
13041
+ const locations = useComboboxData({
13042
+ queryKey: ["locations"],
13043
+ queryFn: async (params) => {
13044
+ return await sdk.admin.stockLocation.list(params);
13108
13045
  },
13109
- resolver: zod.zodResolver(schema)
13110
- });
13111
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
13112
- const { handleSuccess } = useRouteModal();
13113
- const onSubmit = form.handleSubmit(async (data) => {
13114
- await mutateAsync(
13115
- {
13116
- sales_channel_id: data.sales_channel_id
13117
- },
13118
- {
13119
- onSuccess: () => {
13120
- ui.toast.success("Sales channel updated");
13121
- handleSuccess();
13122
- },
13123
- onError: (error) => {
13124
- ui.toast.error(error.message);
13125
- }
13126
- }
13127
- );
13046
+ getOptions: (data) => {
13047
+ return data.stock_locations.map((location) => ({
13048
+ label: location.name,
13049
+ value: location.id
13050
+ }));
13051
+ }
13128
13052
  });
13129
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
13130
- KeyboundForm,
13053
+ return /* @__PURE__ */ jsxRuntime.jsx(
13054
+ Form$2.Field,
13131
13055
  {
13132
- className: "flex flex-1 flex-col overflow-hidden",
13133
- onSubmit,
13134
- children: [
13135
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
13136
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
13137
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
13138
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
13139
- ] }) })
13140
- ]
13056
+ control,
13057
+ name: "location_id",
13058
+ render: ({ field: { onChange, ...field } }) => {
13059
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
13060
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
13061
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Location" }),
13062
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose where you want to ship the items from." })
13063
+ ] }),
13064
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
13065
+ Combobox,
13066
+ {
13067
+ options: locations.options,
13068
+ fetchNextPage: locations.fetchNextPage,
13069
+ isFetchingNextPage: locations.isFetchingNextPage,
13070
+ searchValue: locations.searchValue,
13071
+ onSearchValueChange: locations.onSearchValueChange,
13072
+ placeholder: "Select location",
13073
+ onChange: (value) => {
13074
+ setValue("shipping_option_id", "", {
13075
+ shouldDirty: true,
13076
+ shouldTouch: true
13077
+ });
13078
+ onChange(value);
13079
+ },
13080
+ ...field
13081
+ }
13082
+ ) })
13083
+ ] }) });
13084
+ }
13141
13085
  }
13142
- ) });
13086
+ );
13143
13087
  };
13144
- const SalesChannelField = ({ control, order }) => {
13145
- const salesChannels = useComboboxData({
13088
+ const ShippingOptionField = ({
13089
+ shippingProfileId,
13090
+ preview,
13091
+ control
13092
+ }) => {
13093
+ var _a;
13094
+ const locationId = reactHookForm.useWatch({ control, name: "location_id" });
13095
+ const shippingOptions = useComboboxData({
13096
+ queryKey: ["shipping_options", locationId, shippingProfileId],
13146
13097
  queryFn: async (params) => {
13147
- return await sdk.admin.salesChannel.list(params);
13098
+ return await sdk.admin.shippingOption.list({
13099
+ ...params,
13100
+ stock_location_id: locationId,
13101
+ shipping_profile_id: shippingProfileId
13102
+ });
13148
13103
  },
13149
- queryKey: ["sales-channels"],
13150
13104
  getOptions: (data) => {
13151
- return data.sales_channels.map((salesChannel) => ({
13152
- label: salesChannel.name,
13153
- value: salesChannel.id
13154
- }));
13105
+ return data.shipping_options.map((option) => {
13106
+ var _a2;
13107
+ if ((_a2 = option.rules) == null ? void 0 : _a2.find(
13108
+ (r) => r.attribute === "is_return" && r.value === "true"
13109
+ )) {
13110
+ return void 0;
13111
+ }
13112
+ return {
13113
+ label: option.name,
13114
+ value: option.id
13115
+ };
13116
+ }).filter(Boolean);
13155
13117
  },
13156
- defaultValue: order.sales_channel_id || void 0
13118
+ enabled: !!locationId && !!shippingProfileId,
13119
+ defaultValue: ((_a = preview.shipping_methods[0]) == null ? void 0 : _a.shipping_option_id) || void 0
13157
13120
  });
13121
+ const tooltipContent = !locationId && !shippingProfileId ? "Choose a location and shipping profile first." : !locationId ? "Choose a location first." : "Choose a shipping profile first.";
13158
13122
  return /* @__PURE__ */ jsxRuntime.jsx(
13159
13123
  Form$2.Field,
13160
13124
  {
13161
13125
  control,
13162
- name: "sales_channel_id",
13126
+ name: "shipping_option_id",
13163
13127
  render: ({ field }) => {
13164
- return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
13165
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
13128
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
13129
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
13130
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Shipping option" }),
13131
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose the shipping option to use." })
13132
+ ] }),
13133
+ /* @__PURE__ */ jsxRuntime.jsx(
13134
+ ConditionalTooltip,
13135
+ {
13136
+ content: tooltipContent,
13137
+ showTooltip: !locationId || !shippingProfileId,
13138
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
13139
+ Combobox,
13140
+ {
13141
+ options: shippingOptions.options,
13142
+ fetchNextPage: shippingOptions.fetchNextPage,
13143
+ isFetchingNextPage: shippingOptions.isFetchingNextPage,
13144
+ searchValue: shippingOptions.searchValue,
13145
+ onSearchValueChange: shippingOptions.onSearchValueChange,
13146
+ placeholder: "Select shipping option",
13147
+ ...field,
13148
+ disabled: !locationId || !shippingProfileId
13149
+ }
13150
+ ) }) })
13151
+ }
13152
+ )
13153
+ ] }) });
13154
+ }
13155
+ }
13156
+ );
13157
+ };
13158
+ const CustomAmountField = ({
13159
+ control,
13160
+ currencyCode
13161
+ }) => {
13162
+ return /* @__PURE__ */ jsxRuntime.jsx(
13163
+ Form$2.Field,
13164
+ {
13165
+ control,
13166
+ name: "custom_amount",
13167
+ render: ({ field: { onChange, ...field } }) => {
13168
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
13169
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
13170
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
13171
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
13172
+ ] }),
13166
13173
  /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
13167
- Combobox,
13174
+ ui.CurrencyInput,
13168
13175
  {
13169
- options: salesChannels.options,
13170
- fetchNextPage: salesChannels.fetchNextPage,
13171
- isFetchingNextPage: salesChannels.isFetchingNextPage,
13172
- searchValue: salesChannels.searchValue,
13173
- onSearchValueChange: salesChannels.onSearchValueChange,
13174
- placeholder: "Select sales channel",
13175
- ...field
13176
+ ...field,
13177
+ onValueChange: (value) => onChange(value),
13178
+ symbol: getNativeSymbol(currencyCode),
13179
+ code: currencyCode
13176
13180
  }
13177
- ) }),
13178
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
13181
+ ) })
13179
13182
  ] });
13180
13183
  }
13181
13184
  }
13182
13185
  );
13183
13186
  };
13184
- const schema = z.object({
13185
- sales_channel_id: z.string().min(1)
13186
- });
13187
13187
  const widgetModule = { widgets: [] };
13188
13188
  const routeModule = {
13189
13189
  routes: [
@@ -13204,33 +13204,33 @@ const routeModule = {
13204
13204
  handle,
13205
13205
  loader,
13206
13206
  children: [
13207
- {
13208
- Component: CustomItems,
13209
- path: "/draft-orders/:id/custom-items"
13210
- },
13211
- {
13212
- Component: Email,
13213
- path: "/draft-orders/:id/email"
13214
- },
13215
13207
  {
13216
13208
  Component: BillingAddress,
13217
13209
  path: "/draft-orders/:id/billing-address"
13218
13210
  },
13219
13211
  {
13220
- Component: Promotions,
13221
- path: "/draft-orders/:id/promotions"
13212
+ Component: CustomItems,
13213
+ path: "/draft-orders/:id/custom-items"
13222
13214
  },
13223
13215
  {
13224
13216
  Component: Items,
13225
13217
  path: "/draft-orders/:id/items"
13226
13218
  },
13219
+ {
13220
+ Component: Email,
13221
+ path: "/draft-orders/:id/email"
13222
+ },
13223
+ {
13224
+ Component: SalesChannel,
13225
+ path: "/draft-orders/:id/sales-channel"
13226
+ },
13227
13227
  {
13228
13228
  Component: Metadata,
13229
13229
  path: "/draft-orders/:id/metadata"
13230
13230
  },
13231
13231
  {
13232
- Component: Shipping,
13233
- path: "/draft-orders/:id/shipping"
13232
+ Component: Promotions,
13233
+ path: "/draft-orders/:id/promotions"
13234
13234
  },
13235
13235
  {
13236
13236
  Component: ShippingAddress,
@@ -13241,8 +13241,8 @@ const routeModule = {
13241
13241
  path: "/draft-orders/:id/transfer-ownership"
13242
13242
  },
13243
13243
  {
13244
- Component: SalesChannel,
13245
- path: "/draft-orders/:id/sales-channel"
13244
+ Component: Shipping,
13245
+ path: "/draft-orders/:id/shipping"
13246
13246
  }
13247
13247
  ]
13248
13248
  }