@medusajs/draft-order 3.0.0-preview-20251214180138 → 3.0.0-preview-20251214210141

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.
@@ -9762,27 +9762,6 @@ const BillingAddressForm = ({ order }) => {
9762
9762
  ) });
9763
9763
  };
9764
9764
  const schema$5 = addressSchema;
9765
- const CustomItems = () => {
9766
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9767
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9768
- /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9769
- ] });
9770
- };
9771
- const CustomItemsForm = () => {
9772
- const form = reactHookForm.useForm({
9773
- resolver: zod.zodResolver(schema$4)
9774
- });
9775
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9776
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9777
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9778
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9779
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9780
- ] }) })
9781
- ] }) });
9782
- };
9783
- const schema$4 = objectType({
9784
- email: stringType().email()
9785
- });
9786
9765
  const Email = () => {
9787
9766
  const { id } = reactRouterDom.useParams();
9788
9767
  const { order, isPending, isError, error } = useOrder(id, {
@@ -9805,7 +9784,7 @@ const EmailForm = ({ order }) => {
9805
9784
  defaultValues: {
9806
9785
  email: order.email ?? ""
9807
9786
  },
9808
- resolver: zod.zodResolver(schema$3)
9787
+ resolver: zod.zodResolver(schema$4)
9809
9788
  });
9810
9789
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9811
9790
  const { handleSuccess } = useRouteModal();
@@ -9848,25 +9827,151 @@ const EmailForm = ({ order }) => {
9848
9827
  }
9849
9828
  ) });
9850
9829
  };
9830
+ const schema$4 = objectType({
9831
+ email: stringType().email()
9832
+ });
9833
+ const CustomItems = () => {
9834
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9835
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9836
+ /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9837
+ ] });
9838
+ };
9839
+ const CustomItemsForm = () => {
9840
+ const form = reactHookForm.useForm({
9841
+ resolver: zod.zodResolver(schema$3)
9842
+ });
9843
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9844
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9845
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9846
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9847
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9848
+ ] }) })
9849
+ ] }) });
9850
+ };
9851
9851
  const schema$3 = objectType({
9852
9852
  email: stringType().email()
9853
9853
  });
9854
- const PROMOTION_QUERY_KEY = "promotions";
9855
- const promotionsQueryKeys = {
9854
+ const NumberInput = React.forwardRef(
9855
+ ({
9856
+ value,
9857
+ onChange,
9858
+ size = "base",
9859
+ min = 0,
9860
+ max = 100,
9861
+ step = 1,
9862
+ className,
9863
+ disabled,
9864
+ ...props
9865
+ }, ref) => {
9866
+ const handleChange = (event) => {
9867
+ const newValue = event.target.value === "" ? min : Number(event.target.value);
9868
+ if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
9869
+ onChange(newValue);
9870
+ }
9871
+ };
9872
+ const handleIncrement = () => {
9873
+ const newValue = value + step;
9874
+ if (max === void 0 || newValue <= max) {
9875
+ onChange(newValue);
9876
+ }
9877
+ };
9878
+ const handleDecrement = () => {
9879
+ const newValue = value - step;
9880
+ if (min === void 0 || newValue >= min) {
9881
+ onChange(newValue);
9882
+ }
9883
+ };
9884
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9885
+ "div",
9886
+ {
9887
+ className: ui.clx(
9888
+ "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
9889
+ "[&:has(input:focus)]:shadow-borders-interactive-with-active",
9890
+ {
9891
+ "h-7": size === "small",
9892
+ "h-8": size === "base"
9893
+ },
9894
+ className
9895
+ ),
9896
+ children: [
9897
+ /* @__PURE__ */ jsxRuntime.jsx(
9898
+ "input",
9899
+ {
9900
+ ref,
9901
+ type: "number",
9902
+ value,
9903
+ onChange: handleChange,
9904
+ min,
9905
+ max,
9906
+ step,
9907
+ className: ui.clx(
9908
+ "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
9909
+ "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
9910
+ "placeholder:text-ui-fg-muted"
9911
+ ),
9912
+ ...props
9913
+ }
9914
+ ),
9915
+ /* @__PURE__ */ jsxRuntime.jsxs(
9916
+ "button",
9917
+ {
9918
+ className: ui.clx(
9919
+ "flex items-center justify-center outline-none transition-fg",
9920
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9921
+ "focus:bg-ui-bg-field-component-hover",
9922
+ "hover:bg-ui-bg-field-component-hover",
9923
+ {
9924
+ "size-7": size === "small",
9925
+ "size-8": size === "base"
9926
+ }
9927
+ ),
9928
+ type: "button",
9929
+ onClick: handleDecrement,
9930
+ disabled: min !== void 0 && value <= min || disabled,
9931
+ children: [
9932
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Minus, {}),
9933
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
9934
+ ]
9935
+ }
9936
+ ),
9937
+ /* @__PURE__ */ jsxRuntime.jsxs(
9938
+ "button",
9939
+ {
9940
+ className: ui.clx(
9941
+ "flex items-center justify-center outline-none transition-fg",
9942
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9943
+ "focus:bg-ui-bg-field-hover",
9944
+ "hover:bg-ui-bg-field-hover",
9945
+ {
9946
+ "size-7": size === "small",
9947
+ "size-8": size === "base"
9948
+ }
9949
+ ),
9950
+ type: "button",
9951
+ onClick: handleIncrement,
9952
+ disabled: max !== void 0 && value >= max || disabled,
9953
+ children: [
9954
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
9955
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Increase by ${step}` })
9956
+ ]
9957
+ }
9958
+ )
9959
+ ]
9960
+ }
9961
+ );
9962
+ }
9963
+ );
9964
+ const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
9965
+ const productVariantsQueryKeys = {
9856
9966
  list: (query2) => [
9857
- PROMOTION_QUERY_KEY,
9858
- query2 ? query2 : void 0
9859
- ],
9860
- detail: (id, query2) => [
9861
- PROMOTION_QUERY_KEY,
9862
- id,
9967
+ PRODUCT_VARIANTS_QUERY_KEY,
9863
9968
  query2 ? query2 : void 0
9864
9969
  ]
9865
9970
  };
9866
- const usePromotions = (query2, options) => {
9971
+ const useProductVariants = (query2, options) => {
9867
9972
  const { data, ...rest } = reactQuery.useQuery({
9868
- queryKey: promotionsQueryKeys.list(query2),
9869
- queryFn: async () => sdk.admin.promotion.list(query2),
9973
+ queryKey: productVariantsQueryKeys.list(query2),
9974
+ queryFn: async () => await sdk.admin.productVariant.list(query2),
9870
9975
  ...options
9871
9976
  });
9872
9977
  return { ...data, ...rest };
@@ -9917,97 +10022,77 @@ const useInitiateOrderEdit = ({
9917
10022
  run();
9918
10023
  }, [preview, navigate, mutateAsync]);
9919
10024
  };
9920
- const Promotions = () => {
10025
+ function convertNumber(value) {
10026
+ return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10027
+ }
10028
+ const STACKED_MODAL_ID = "items_stacked_modal";
10029
+ const Items = () => {
9921
10030
  const { id } = reactRouterDom.useParams();
9922
10031
  const {
9923
10032
  order: preview,
10033
+ isPending: isPreviewPending,
9924
10034
  isError: isPreviewError,
9925
10035
  error: previewError
9926
- } = useOrderPreview(id, void 0);
10036
+ } = useOrderPreview(id, void 0, {
10037
+ placeholderData: reactQuery.keepPreviousData
10038
+ });
9927
10039
  useInitiateOrderEdit({ preview });
10040
+ const { draft_order, isPending, isError, error } = useDraftOrder(
10041
+ id,
10042
+ {
10043
+ fields: "currency_code"
10044
+ },
10045
+ {
10046
+ enabled: !!id
10047
+ }
10048
+ );
9928
10049
  const { onCancel } = useCancelOrderEdit({ preview });
10050
+ if (isError) {
10051
+ throw error;
10052
+ }
9929
10053
  if (isPreviewError) {
9930
10054
  throw previewError;
9931
10055
  }
9932
- const isReady = !!preview;
9933
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
9934
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
9935
- isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
9936
- ] });
10056
+ const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10057
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsxRuntime.jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10058
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10059
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10060
+ ] }) });
9937
10061
  };
9938
- const PromotionForm = ({ preview }) => {
9939
- const { items, shipping_methods } = preview;
10062
+ const ItemsForm = ({ preview, currencyCode }) => {
10063
+ var _a;
9940
10064
  const [isSubmitting, setIsSubmitting] = React.useState(false);
9941
- const [comboboxValue, setComboboxValue] = React.useState("");
10065
+ const [modalContent, setModalContent] = React.useState(
10066
+ null
10067
+ );
9942
10068
  const { handleSuccess } = useRouteModal();
9943
- const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
9944
- const promoIds = getPromotionIds(items, shipping_methods);
9945
- const { promotions, isPending, isError, error } = usePromotions(
9946
- {
9947
- id: promoIds
9948
- },
9949
- {
9950
- enabled: !!promoIds.length
9951
- }
9952
- );
9953
- const comboboxData = useComboboxData({
9954
- queryKey: ["promotions", "combobox", promoIds],
9955
- queryFn: async (params) => {
9956
- return await sdk.admin.promotion.list({
9957
- ...params,
9958
- id: {
9959
- $nin: promoIds
9960
- }
9961
- });
9962
- },
9963
- getOptions: (data) => {
9964
- return data.promotions.map((promotion) => ({
9965
- label: promotion.code,
9966
- value: promotion.code
9967
- }));
9968
- }
9969
- });
9970
- const add = async (value) => {
9971
- if (!value) {
9972
- return;
9973
- }
9974
- addPromotions(
9975
- {
9976
- promo_codes: [value]
9977
- },
9978
- {
9979
- onError: (e) => {
9980
- ui.toast.error(e.message);
9981
- comboboxData.onSearchValueChange("");
9982
- setComboboxValue("");
9983
- },
9984
- onSuccess: () => {
9985
- comboboxData.onSearchValueChange("");
9986
- setComboboxValue("");
9987
- }
9988
- }
9989
- );
9990
- };
9991
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
9992
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
9993
- const onSubmit = async () => {
9994
- setIsSubmitting(true);
9995
- let requestSucceeded = false;
9996
- await requestOrderEdit(void 0, {
9997
- onError: (e) => {
9998
- ui.toast.error(e.message);
9999
- },
10000
- onSuccess: () => {
10001
- requestSucceeded = true;
10002
- }
10003
- });
10004
- if (!requestSucceeded) {
10005
- setIsSubmitting(false);
10006
- return;
10069
+ const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10070
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10071
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10072
+ const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10073
+ const matches = React.useMemo(() => {
10074
+ return matchSorter.matchSorter(preview.items, query2, {
10075
+ keys: ["product_title", "variant_title", "variant_sku", "title"]
10076
+ });
10077
+ }, [preview.items, query2]);
10078
+ const onSubmit = async () => {
10079
+ setIsSubmitting(true);
10080
+ let requestSucceeded = false;
10081
+ await requestOrderEdit(void 0, {
10082
+ onError: (e) => {
10083
+ ui.toast.error(`Failed to request order edit: ${e.message}`);
10084
+ },
10085
+ onSuccess: () => {
10086
+ requestSucceeded = true;
10087
+ }
10088
+ });
10089
+ if (!requestSucceeded) {
10090
+ setIsSubmitting(false);
10091
+ return;
10007
10092
  }
10008
10093
  await confirmOrderEdit(void 0, {
10009
10094
  onError: (e) => {
10010
- ui.toast.error(e.message);
10095
+ ui.toast.error(`Failed to confirm order edit: ${e.message}`);
10011
10096
  },
10012
10097
  onSuccess: () => {
10013
10098
  handleSuccess();
@@ -10017,1441 +10102,1356 @@ const PromotionForm = ({ preview }) => {
10017
10102
  }
10018
10103
  });
10019
10104
  };
10020
- if (isError) {
10021
- throw error;
10022
- }
10023
- return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
10024
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
10025
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
10026
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10027
- /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
10028
- /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
10029
- ] }),
10030
- /* @__PURE__ */ jsxRuntime.jsx(
10031
- Combobox,
10032
- {
10033
- id: "promotion-combobox",
10034
- "aria-describedby": "promotion-combobox-hint",
10035
- isFetchingNextPage: comboboxData.isFetchingNextPage,
10036
- fetchNextPage: comboboxData.fetchNextPage,
10037
- options: comboboxData.options,
10038
- onSearchValueChange: comboboxData.onSearchValueChange,
10039
- searchValue: comboboxData.searchValue,
10040
- disabled: comboboxData.disabled || isAddingPromotions,
10041
- onChange: add,
10042
- value: comboboxValue
10105
+ const onKeyDown = React.useCallback(
10106
+ (e) => {
10107
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10108
+ if (modalContent || isSubmitting) {
10109
+ return;
10110
+ }
10111
+ onSubmit();
10112
+ }
10113
+ },
10114
+ [modalContent, isSubmitting, onSubmit]
10115
+ );
10116
+ React.useEffect(() => {
10117
+ document.addEventListener("keydown", onKeyDown);
10118
+ return () => {
10119
+ document.removeEventListener("keydown", onKeyDown);
10120
+ };
10121
+ }, [onKeyDown]);
10122
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10123
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
10124
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
10125
+ StackedFocusModal,
10126
+ {
10127
+ id: STACKED_MODAL_ID,
10128
+ onOpenChangeCallback: (open) => {
10129
+ if (!open) {
10130
+ setModalContent(null);
10043
10131
  }
10044
- )
10045
- ] }),
10046
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10047
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
10048
- PromotionItem,
10049
- {
10050
- promotion,
10051
- orderId: preview.id,
10052
- isLoading: isPending
10053
10132
  },
10054
- promotion.id
10055
- )) })
10056
- ] }) }),
10057
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
10058
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10133
+ children: [
10134
+ /* @__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: [
10135
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10136
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Items" }) }),
10137
+ /* @__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" }) })
10138
+ ] }),
10139
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10140
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
10141
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10142
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10143
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10144
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10145
+ ] }),
10146
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10147
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10148
+ ui.Input,
10149
+ {
10150
+ type: "search",
10151
+ placeholder: "Search items",
10152
+ value: searchValue,
10153
+ onChange: (e) => onSearchValueChange(e.target.value)
10154
+ }
10155
+ ) }),
10156
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
10157
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}) }) }),
10158
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
10159
+ /* @__PURE__ */ jsxRuntime.jsx(
10160
+ StackedModalTrigger$1,
10161
+ {
10162
+ type: "add-items",
10163
+ setModalContent
10164
+ }
10165
+ ),
10166
+ /* @__PURE__ */ jsxRuntime.jsx(
10167
+ StackedModalTrigger$1,
10168
+ {
10169
+ type: "add-custom-item",
10170
+ setModalContent
10171
+ }
10172
+ )
10173
+ ] })
10174
+ ] })
10175
+ ] })
10176
+ ] }),
10177
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10178
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-muted grid grid-cols-[2fr_1fr_2fr_28px] gap-3 px-4 py-2", children: [
10179
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
10180
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10181
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Price" }) }),
10182
+ /* @__PURE__ */ jsxRuntime.jsx("div", {})
10183
+ ] }) }),
10184
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest flex flex-col items-center justify-center gap-1 gap-x-3 rounded-lg p-4", children: [
10185
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10186
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10187
+ ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
10188
+ Item,
10189
+ {
10190
+ item,
10191
+ preview,
10192
+ currencyCode
10193
+ },
10194
+ item.id
10195
+ )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest flex flex-col items-center justify-center gap-1 gap-x-3 rounded-lg p-4", children: [
10196
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10197
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
10198
+ 'No items found for "',
10199
+ query2,
10200
+ '".'
10201
+ ] })
10202
+ ] }) })
10203
+ ] })
10204
+ ] }),
10205
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10206
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10207
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10208
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(
10209
+ ui.Text,
10210
+ {
10211
+ size: "small",
10212
+ leading: "compact",
10213
+ className: "text-ui-fg-subtle",
10214
+ children: [
10215
+ itemCount,
10216
+ " ",
10217
+ itemCount === 1 ? "item" : "items"
10218
+ ]
10219
+ }
10220
+ ) }),
10221
+ /* @__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) }) })
10222
+ ] })
10223
+ ] }) }),
10224
+ modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsxRuntime.jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsxRuntime.jsx(
10225
+ CustomItemForm,
10226
+ {
10227
+ orderId: preview.id,
10228
+ currencyCode
10229
+ }
10230
+ ) : null)
10231
+ ]
10232
+ }
10233
+ ) }),
10234
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10235
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10059
10236
  /* @__PURE__ */ jsxRuntime.jsx(
10060
10237
  ui.Button,
10061
10238
  {
10062
10239
  size: "small",
10063
- type: "submit",
10064
- isLoading: isSubmitting || isAddingPromotions,
10240
+ type: "button",
10241
+ onClick: onSubmit,
10242
+ isLoading: isSubmitting,
10065
10243
  children: "Save"
10066
10244
  }
10067
10245
  )
10068
10246
  ] }) })
10069
10247
  ] });
10070
10248
  };
10071
- const PromotionItem = ({
10072
- promotion,
10073
- orderId,
10074
- isLoading
10075
- }) => {
10076
- var _a;
10077
- const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
10078
- const onRemove = async () => {
10079
- removePromotions(
10080
- {
10081
- promo_codes: [promotion.code]
10082
- },
10083
- {
10084
- onError: (e) => {
10085
- ui.toast.error(e.message);
10086
- }
10087
- }
10088
- );
10089
- };
10090
- const displayValue = getDisplayValue(promotion);
10091
- return /* @__PURE__ */ jsxRuntime.jsxs(
10092
- "div",
10093
- {
10094
- className: ui.clx(
10095
- "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
10096
- {
10097
- "animate-pulse": isLoading
10098
- }
10099
- ),
10100
- children: [
10101
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10102
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
10103
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
10104
- displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
10105
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
10106
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
10107
- ] }),
10108
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
10109
- ] })
10110
- ] }),
10111
- /* @__PURE__ */ jsxRuntime.jsx(
10112
- ui.IconButton,
10113
- {
10114
- size: "small",
10115
- type: "button",
10116
- variant: "transparent",
10117
- onClick: onRemove,
10118
- isLoading: isPending || isLoading,
10119
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
10120
- }
10121
- )
10122
- ]
10123
- },
10124
- promotion.id
10125
- );
10126
- };
10127
- function getDisplayValue(promotion) {
10128
- var _a, _b, _c, _d;
10129
- const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
10130
- if (!value) {
10131
- return null;
10132
- }
10133
- if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
10134
- const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
10135
- if (!currency) {
10136
- return null;
10137
- }
10138
- return getLocaleAmount(value, currency);
10139
- } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
10140
- return formatPercentage(value);
10141
- }
10142
- return null;
10143
- }
10144
- const formatter = new Intl.NumberFormat([], {
10145
- style: "percent",
10146
- minimumFractionDigits: 2
10147
- });
10148
- const formatPercentage = (value, isPercentageValue = false) => {
10149
- let val = value || 0;
10150
- if (!isPercentageValue) {
10151
- val = val / 100;
10152
- }
10153
- return formatter.format(val);
10154
- };
10155
- function getPromotionIds(items, shippingMethods) {
10156
- const promotionIds = /* @__PURE__ */ new Set();
10157
- for (const item of items) {
10158
- if (item.adjustments) {
10159
- for (const adjustment of item.adjustments) {
10160
- if (adjustment.promotion_id) {
10161
- promotionIds.add(adjustment.promotion_id);
10162
- }
10163
- }
10164
- }
10165
- }
10166
- for (const shippingMethod of shippingMethods) {
10167
- if (shippingMethod.adjustments) {
10168
- for (const adjustment of shippingMethod.adjustments) {
10169
- if (adjustment.promotion_id) {
10170
- promotionIds.add(adjustment.promotion_id);
10171
- }
10172
- }
10173
- }
10174
- }
10175
- return Array.from(promotionIds);
10176
- }
10177
- const InlineTip = React.forwardRef(
10178
- ({ variant = "tip", label, className, children, ...props }, ref) => {
10179
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10180
- return /* @__PURE__ */ jsxRuntime.jsxs(
10181
- "div",
10182
- {
10183
- ref,
10184
- className: ui.clx(
10185
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10186
- className
10187
- ),
10188
- ...props,
10189
- children: [
10190
- /* @__PURE__ */ jsxRuntime.jsx(
10191
- "div",
10192
- {
10193
- role: "presentation",
10194
- className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10195
- "bg-ui-tag-orange-icon": variant === "warning"
10196
- })
10197
- }
10198
- ),
10199
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
10200
- /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10201
- labelValue,
10202
- ":"
10203
- ] }),
10204
- " ",
10205
- children
10206
- ] })
10207
- ]
10208
- }
10209
- );
10210
- }
10211
- );
10212
- InlineTip.displayName = "InlineTip";
10213
- const MetadataFieldSchema = objectType({
10214
- key: stringType(),
10215
- disabled: booleanType().optional(),
10216
- value: anyType()
10217
- });
10218
- const MetadataSchema = objectType({
10219
- metadata: arrayType(MetadataFieldSchema)
10220
- });
10221
- const Metadata = () => {
10222
- const { id } = reactRouterDom.useParams();
10223
- const { order, isPending, isError, error } = useOrder(id, {
10224
- fields: "metadata"
10225
- });
10226
- if (isError) {
10227
- throw error;
10249
+ const Item = ({ item, preview, currencyCode }) => {
10250
+ if (item.variant_id) {
10251
+ return /* @__PURE__ */ jsxRuntime.jsx(VariantItem, { item, preview, currencyCode });
10228
10252
  }
10229
- const isReady = !isPending && !!order;
10230
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10231
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10232
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
10233
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10234
- ] }),
10235
- !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10236
- ] });
10253
+ return /* @__PURE__ */ jsxRuntime.jsx(CustomItem, { item, preview, currencyCode });
10237
10254
  };
10238
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10239
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10240
- const MetadataForm = ({ orderId, metadata }) => {
10241
- const { handleSuccess } = useRouteModal();
10242
- const hasUneditableRows = getHasUneditableRows(metadata);
10243
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10255
+ const VariantItem = ({ item, preview, currencyCode }) => {
10256
+ const [editing, setEditing] = React.useState(false);
10244
10257
  const form = reactHookForm.useForm({
10245
10258
  defaultValues: {
10246
- metadata: getDefaultValues(metadata)
10259
+ quantity: item.quantity,
10260
+ unit_price: item.unit_price
10247
10261
  },
10248
- resolver: zod.zodResolver(MetadataSchema)
10262
+ resolver: zod.zodResolver(variantItemSchema)
10249
10263
  });
10250
- const handleSubmit = form.handleSubmit(async (data) => {
10251
- const parsedData = parseValues(data);
10252
- await mutateAsync(
10264
+ const actionId = React.useMemo(() => {
10265
+ var _a, _b;
10266
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10267
+ }, [item]);
10268
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10269
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10270
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10271
+ const onSubmit = form.handleSubmit(async (data) => {
10272
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10273
+ setEditing(false);
10274
+ return;
10275
+ }
10276
+ if (!actionId) {
10277
+ await updateOriginalItem(
10278
+ {
10279
+ item_id: item.id,
10280
+ quantity: data.quantity,
10281
+ unit_price: convertNumber(data.unit_price)
10282
+ },
10283
+ {
10284
+ onSuccess: () => {
10285
+ setEditing(false);
10286
+ },
10287
+ onError: (e) => {
10288
+ ui.toast.error(e.message);
10289
+ }
10290
+ }
10291
+ );
10292
+ return;
10293
+ }
10294
+ await updateActionItem(
10253
10295
  {
10254
- metadata: parsedData
10296
+ action_id: actionId,
10297
+ quantity: data.quantity,
10298
+ unit_price: convertNumber(data.unit_price)
10255
10299
  },
10256
10300
  {
10257
10301
  onSuccess: () => {
10258
- ui.toast.success("Metadata updated");
10259
- handleSuccess();
10302
+ setEditing(false);
10260
10303
  },
10261
- onError: (error) => {
10262
- ui.toast.error(error.message);
10304
+ onError: (e) => {
10305
+ ui.toast.error(e.message);
10263
10306
  }
10264
10307
  }
10265
10308
  );
10266
10309
  });
10267
- const { fields, insert, remove } = reactHookForm.useFieldArray({
10268
- control: form.control,
10269
- name: "metadata"
10270
- });
10271
- function deleteRow(index) {
10272
- remove(index);
10273
- if (fields.length === 1) {
10274
- insert(0, {
10275
- key: "",
10276
- value: "",
10277
- disabled: false
10278
- });
10279
- }
10280
- }
10281
- function insertRow(index, position) {
10282
- insert(index + (position === "above" ? 0 : 1), {
10283
- key: "",
10284
- value: "",
10285
- disabled: false
10286
- });
10287
- }
10288
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
10289
- KeyboundForm,
10290
- {
10291
- onSubmit: handleSubmit,
10292
- className: "flex flex-1 flex-col overflow-hidden",
10293
- children: [
10294
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10295
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10296
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10297
- /* @__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" }) }),
10298
- /* @__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" }) })
10299
- ] }),
10300
- fields.map((field, index) => {
10301
- const isDisabled = field.disabled || false;
10302
- let placeholder = "-";
10303
- if (typeof field.value === "object") {
10304
- placeholder = "{ ... }";
10305
- }
10306
- if (Array.isArray(field.value)) {
10307
- placeholder = "[ ... ]";
10308
- }
10309
- return /* @__PURE__ */ jsxRuntime.jsx(
10310
- ConditionalTooltip,
10311
- {
10312
- showTooltip: isDisabled,
10313
- content: "This row is disabled because it contains non-primitive data.",
10314
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
10315
- /* @__PURE__ */ jsxRuntime.jsxs(
10316
- "div",
10317
- {
10318
- className: ui.clx("grid grid-cols-2 divide-x", {
10319
- "overflow-hidden rounded-b-lg": index === fields.length - 1
10320
- }),
10321
- children: [
10322
- /* @__PURE__ */ jsxRuntime.jsx(
10323
- Form$2.Field,
10324
- {
10325
- control: form.control,
10326
- name: `metadata.${index}.key`,
10327
- render: ({ field: field2 }) => {
10328
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10329
- GridInput,
10330
- {
10331
- "aria-labelledby": METADATA_KEY_LABEL_ID,
10332
- ...field2,
10333
- disabled: isDisabled,
10334
- placeholder: "Key"
10335
- }
10336
- ) }) });
10337
- }
10338
- }
10339
- ),
10340
- /* @__PURE__ */ jsxRuntime.jsx(
10341
- Form$2.Field,
10342
- {
10343
- control: form.control,
10344
- name: `metadata.${index}.value`,
10345
- render: ({ field: { value, ...field2 } }) => {
10346
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10347
- GridInput,
10348
- {
10349
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
10350
- ...field2,
10351
- value: isDisabled ? placeholder : value,
10352
- disabled: isDisabled,
10353
- placeholder: "Value"
10354
- }
10355
- ) }) });
10356
- }
10357
- }
10358
- )
10359
- ]
10360
- }
10361
- ),
10362
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
10363
- /* @__PURE__ */ jsxRuntime.jsx(
10364
- ui.DropdownMenu.Trigger,
10365
- {
10366
- className: ui.clx(
10367
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
10368
- {
10369
- hidden: isDisabled
10370
- }
10371
- ),
10372
- disabled: isDisabled,
10373
- asChild: true,
10374
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
10375
- }
10376
- ),
10377
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
10378
- /* @__PURE__ */ jsxRuntime.jsxs(
10379
- ui.DropdownMenu.Item,
10380
- {
10381
- className: "gap-x-2",
10382
- onClick: () => insertRow(index, "above"),
10383
- children: [
10384
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
10385
- "Insert row above"
10386
- ]
10387
- }
10388
- ),
10389
- /* @__PURE__ */ jsxRuntime.jsxs(
10390
- ui.DropdownMenu.Item,
10391
- {
10392
- className: "gap-x-2",
10393
- onClick: () => insertRow(index, "below"),
10394
- children: [
10395
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
10396
- "Insert row below"
10397
- ]
10398
- }
10399
- ),
10400
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
10401
- /* @__PURE__ */ jsxRuntime.jsxs(
10402
- ui.DropdownMenu.Item,
10403
- {
10404
- className: "gap-x-2",
10405
- onClick: () => deleteRow(index),
10406
- children: [
10407
- /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
10408
- "Delete row"
10409
- ]
10410
- }
10411
- )
10412
- ] })
10413
- ] })
10414
- ] })
10415
- },
10416
- field.id
10417
- );
10418
- })
10419
- ] }),
10420
- 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." })
10310
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-[minmax(0,2fr)_minmax(0,1fr)_minmax(0,2fr)_28px] items-center gap-3 rounded-lg px-4 py-2", children: [
10311
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10312
+ /* @__PURE__ */ jsxRuntime.jsx(
10313
+ Thumbnail,
10314
+ {
10315
+ thumbnail: item.thumbnail,
10316
+ alt: item.product_title ?? void 0
10317
+ }
10318
+ ),
10319
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10320
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
10321
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10322
+ /* @__PURE__ */ jsxRuntime.jsxs(
10323
+ ui.Text,
10324
+ {
10325
+ size: "small",
10326
+ leading: "compact",
10327
+ className: "text-ui-fg-subtle",
10328
+ children: [
10329
+ "(",
10330
+ item.variant_title,
10331
+ ")"
10332
+ ]
10333
+ }
10334
+ )
10421
10335
  ] }),
10422
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10423
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10424
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10425
- ] }) })
10426
- ]
10427
- }
10428
- ) });
10429
- };
10430
- const GridInput = React.forwardRef(({ className, ...props }, ref) => {
10431
- return /* @__PURE__ */ jsxRuntime.jsx(
10432
- "input",
10433
- {
10434
- ref,
10435
- ...props,
10436
- autoComplete: "off",
10437
- className: ui.clx(
10438
- "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",
10439
- className
10440
- )
10441
- }
10442
- );
10443
- });
10444
- GridInput.displayName = "MetadataForm.GridInput";
10445
- const PlaceholderInner = () => {
10446
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
10447
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
10448
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10449
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
10450
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
10451
- ] }) })
10452
- ] });
10453
- };
10454
- const EDITABLE_TYPES = ["string", "number", "boolean"];
10455
- function getDefaultValues(metadata) {
10456
- if (!metadata || !Object.keys(metadata).length) {
10457
- return [
10336
+ /* @__PURE__ */ jsxRuntime.jsx(
10337
+ ui.Text,
10338
+ {
10339
+ size: "small",
10340
+ leading: "compact",
10341
+ className: "text-ui-fg-subtle",
10342
+ children: item.variant_sku
10343
+ }
10344
+ )
10345
+ ] })
10346
+ ] }),
10347
+ editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10348
+ Form$2.Field,
10458
10349
  {
10459
- key: "",
10460
- value: "",
10461
- disabled: false
10350
+ control: form.control,
10351
+ name: "quantity",
10352
+ render: ({ field }) => {
10353
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10354
+ }
10462
10355
  }
10463
- ];
10464
- }
10465
- return Object.entries(metadata).map(([key, value]) => {
10466
- if (!EDITABLE_TYPES.includes(typeof value)) {
10467
- return {
10468
- key,
10469
- value,
10470
- disabled: true
10471
- };
10472
- }
10473
- let stringValue = value;
10474
- if (typeof value !== "string") {
10475
- stringValue = JSON.stringify(value);
10476
- }
10477
- return {
10478
- key,
10479
- value: stringValue,
10480
- original_key: key
10481
- };
10356
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }) }),
10357
+ editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10358
+ Form$2.Field,
10359
+ {
10360
+ control: form.control,
10361
+ name: "unit_price",
10362
+ render: ({ field: { onChange, ...field } }) => {
10363
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10364
+ ui.CurrencyInput,
10365
+ {
10366
+ ...field,
10367
+ symbol: getNativeSymbol(currencyCode),
10368
+ code: currencyCode,
10369
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10370
+ }
10371
+ ) }) });
10372
+ }
10373
+ }
10374
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex w-full flex-1 items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10375
+ /* @__PURE__ */ jsxRuntime.jsx(
10376
+ ui.IconButton,
10377
+ {
10378
+ type: "button",
10379
+ size: "small",
10380
+ onClick: editing ? onSubmit : () => {
10381
+ setEditing(true);
10382
+ },
10383
+ disabled: isPending,
10384
+ children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
10385
+ }
10386
+ )
10387
+ ] }) }) });
10388
+ };
10389
+ const variantItemSchema = objectType({
10390
+ quantity: numberType(),
10391
+ unit_price: unionType([numberType(), stringType()])
10392
+ });
10393
+ const CustomItem = ({ item, preview, currencyCode }) => {
10394
+ const [editing, setEditing] = React.useState(false);
10395
+ const { quantity, unit_price, title } = item;
10396
+ const form = reactHookForm.useForm({
10397
+ defaultValues: {
10398
+ title,
10399
+ quantity,
10400
+ unit_price
10401
+ },
10402
+ resolver: zod.zodResolver(customItemSchema)
10482
10403
  });
10483
- }
10484
- function parseValues(values) {
10485
- const metadata = values.metadata;
10486
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
10487
- if (isEmpty) {
10488
- return null;
10489
- }
10490
- const update = {};
10491
- metadata.forEach((field) => {
10492
- let key = field.key;
10493
- let value = field.value;
10494
- const disabled = field.disabled;
10495
- if (!key || !value) {
10404
+ React.useEffect(() => {
10405
+ form.reset({
10406
+ title,
10407
+ quantity,
10408
+ unit_price
10409
+ });
10410
+ }, [form, title, quantity, unit_price]);
10411
+ const actionId = React.useMemo(() => {
10412
+ var _a, _b;
10413
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10414
+ }, [item]);
10415
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10416
+ const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10417
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10418
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10419
+ const onSubmit = form.handleSubmit(async (data) => {
10420
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10421
+ setEditing(false);
10496
10422
  return;
10497
10423
  }
10498
- if (disabled) {
10499
- update[key] = value;
10424
+ if (!actionId) {
10425
+ await updateOriginalItem(
10426
+ {
10427
+ item_id: item.id,
10428
+ quantity: data.quantity,
10429
+ unit_price: convertNumber(data.unit_price)
10430
+ },
10431
+ {
10432
+ onSuccess: () => {
10433
+ setEditing(false);
10434
+ },
10435
+ onError: (e) => {
10436
+ ui.toast.error(e.message);
10437
+ }
10438
+ }
10439
+ );
10500
10440
  return;
10501
10441
  }
10502
- key = key.trim();
10503
- value = value.trim();
10504
- if (value === "true") {
10505
- update[key] = true;
10506
- } else if (value === "false") {
10507
- update[key] = false;
10508
- } else {
10509
- const parsedNumber = parseFloat(value);
10510
- if (!isNaN(parsedNumber)) {
10511
- update[key] = parsedNumber;
10512
- } else {
10513
- update[key] = value;
10514
- }
10442
+ if (data.quantity === 0) {
10443
+ await removeActionItem(actionId, {
10444
+ onSuccess: () => {
10445
+ setEditing(false);
10446
+ },
10447
+ onError: (e) => {
10448
+ ui.toast.error(e.message);
10449
+ }
10450
+ });
10451
+ return;
10515
10452
  }
10516
- });
10517
- return update;
10518
- }
10519
- function getHasUneditableRows(metadata) {
10520
- if (!metadata) {
10521
- return false;
10522
- }
10523
- return Object.values(metadata).some(
10524
- (value) => !EDITABLE_TYPES.includes(typeof value)
10525
- );
10526
- }
10527
- const NumberInput = React.forwardRef(
10528
- ({
10529
- value,
10530
- onChange,
10531
- size = "base",
10532
- min = 0,
10533
- max = 100,
10534
- step = 1,
10535
- className,
10536
- disabled,
10537
- ...props
10538
- }, ref) => {
10539
- const handleChange = (event) => {
10540
- const newValue = event.target.value === "" ? min : Number(event.target.value);
10541
- if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
10542
- onChange(newValue);
10543
- }
10544
- };
10545
- const handleIncrement = () => {
10546
- const newValue = value + step;
10547
- if (max === void 0 || newValue <= max) {
10548
- onChange(newValue);
10453
+ await updateActionItem(
10454
+ {
10455
+ action_id: actionId,
10456
+ quantity: data.quantity,
10457
+ unit_price: convertNumber(data.unit_price)
10458
+ },
10459
+ {
10460
+ onSuccess: () => {
10461
+ setEditing(false);
10462
+ },
10463
+ onError: (e) => {
10464
+ ui.toast.error(e.message);
10465
+ }
10549
10466
  }
10550
- };
10551
- const handleDecrement = () => {
10552
- const newValue = value - step;
10553
- if (min === void 0 || newValue >= min) {
10554
- onChange(newValue);
10467
+ );
10468
+ });
10469
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-[minmax(0,2fr)_minmax(0,1fr)_minmax(0,2fr)_28px] items-center gap-3 rounded-lg px-4 py-2", children: [
10470
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
10471
+ /* @__PURE__ */ jsxRuntime.jsx(
10472
+ Thumbnail,
10473
+ {
10474
+ thumbnail: item.thumbnail,
10475
+ alt: item.title ?? void 0
10476
+ }
10477
+ ),
10478
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
10479
+ Form$2.Field,
10480
+ {
10481
+ control: form.control,
10482
+ name: "title",
10483
+ render: ({ field }) => {
10484
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }) });
10485
+ }
10486
+ }
10487
+ ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.title })
10488
+ ] }),
10489
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
10490
+ Form$2.Field,
10491
+ {
10492
+ control: form.control,
10493
+ name: "quantity",
10494
+ render: ({ field }) => {
10495
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10496
+ }
10555
10497
  }
10556
- };
10557
- return /* @__PURE__ */ jsxRuntime.jsxs(
10558
- "div",
10498
+ ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }),
10499
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
10500
+ Form$2.Field,
10559
10501
  {
10560
- className: ui.clx(
10561
- "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
10562
- "[&:has(input:focus)]:shadow-borders-interactive-with-active",
10563
- {
10564
- "h-7": size === "small",
10565
- "h-8": size === "base"
10566
- },
10567
- className
10568
- ),
10569
- children: [
10570
- /* @__PURE__ */ jsxRuntime.jsx(
10571
- "input",
10572
- {
10573
- ref,
10574
- type: "number",
10575
- value,
10576
- onChange: handleChange,
10577
- min,
10578
- max,
10579
- step,
10580
- className: ui.clx(
10581
- "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
10582
- "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
10583
- "placeholder:text-ui-fg-muted"
10584
- ),
10585
- ...props
10586
- }
10587
- ),
10588
- /* @__PURE__ */ jsxRuntime.jsxs(
10589
- "button",
10590
- {
10591
- className: ui.clx(
10592
- "flex items-center justify-center outline-none transition-fg",
10593
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10594
- "focus:bg-ui-bg-field-component-hover",
10595
- "hover:bg-ui-bg-field-component-hover",
10596
- {
10597
- "size-7": size === "small",
10598
- "size-8": size === "base"
10599
- }
10600
- ),
10601
- type: "button",
10602
- onClick: handleDecrement,
10603
- disabled: min !== void 0 && value <= min || disabled,
10604
- children: [
10605
- /* @__PURE__ */ jsxRuntime.jsx(icons.Minus, {}),
10606
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
10607
- ]
10608
- }
10609
- ),
10610
- /* @__PURE__ */ jsxRuntime.jsxs(
10611
- "button",
10502
+ control: form.control,
10503
+ name: "unit_price",
10504
+ render: ({ field: { onChange, ...field } }) => {
10505
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10506
+ ui.CurrencyInput,
10612
10507
  {
10613
- className: ui.clx(
10614
- "flex items-center justify-center outline-none transition-fg",
10615
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10616
- "focus:bg-ui-bg-field-hover",
10617
- "hover:bg-ui-bg-field-hover",
10618
- {
10619
- "size-7": size === "small",
10620
- "size-8": size === "base"
10621
- }
10622
- ),
10623
- type: "button",
10624
- onClick: handleIncrement,
10625
- disabled: max !== void 0 && value >= max || disabled,
10626
- children: [
10627
- /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
10628
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Increase by ${step}` })
10629
- ]
10508
+ ...field,
10509
+ symbol: getNativeSymbol(currencyCode),
10510
+ code: currencyCode,
10511
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10630
10512
  }
10631
- )
10632
- ]
10513
+ ) }) });
10514
+ }
10633
10515
  }
10634
- );
10635
- }
10636
- );
10637
- const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
10638
- const productVariantsQueryKeys = {
10639
- list: (query2) => [
10640
- PRODUCT_VARIANTS_QUERY_KEY,
10641
- query2 ? query2 : void 0
10642
- ]
10516
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10517
+ /* @__PURE__ */ jsxRuntime.jsx(
10518
+ ui.IconButton,
10519
+ {
10520
+ type: "button",
10521
+ size: "small",
10522
+ onClick: editing ? onSubmit : () => {
10523
+ setEditing(true);
10524
+ },
10525
+ disabled: isPending,
10526
+ children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
10527
+ }
10528
+ )
10529
+ ] }) }) });
10643
10530
  };
10644
- const useProductVariants = (query2, options) => {
10645
- const { data, ...rest } = reactQuery.useQuery({
10646
- queryKey: productVariantsQueryKeys.list(query2),
10647
- queryFn: async () => await sdk.admin.productVariant.list(query2),
10648
- ...options
10649
- });
10650
- return { ...data, ...rest };
10531
+ const StackedModalTrigger$1 = ({
10532
+ type,
10533
+ setModalContent
10534
+ }) => {
10535
+ const { setIsOpen } = useStackedModal();
10536
+ const onClick = React.useCallback(() => {
10537
+ setModalContent(type);
10538
+ setIsOpen(STACKED_MODAL_ID, true);
10539
+ }, [setModalContent, setIsOpen, type]);
10540
+ return /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
10651
10541
  };
10652
- function convertNumber(value) {
10653
- return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10654
- }
10655
- const STACKED_MODAL_ID = "items_stacked_modal";
10656
- const Items = () => {
10657
- const { id } = reactRouterDom.useParams();
10658
- const {
10659
- order: preview,
10660
- isPending: isPreviewPending,
10661
- isError: isPreviewError,
10662
- error: previewError
10663
- } = useOrderPreview(id, void 0, {
10664
- placeholderData: reactQuery.keepPreviousData
10665
- });
10666
- useInitiateOrderEdit({ preview });
10667
- const { draft_order, isPending, isError, error } = useDraftOrder(
10668
- id,
10542
+ const VARIANT_PREFIX = "items";
10543
+ const LIMIT = 50;
10544
+ const ExistingItemsForm = ({ orderId, items }) => {
10545
+ const { setIsOpen } = useStackedModal();
10546
+ const [rowSelection, setRowSelection] = React.useState(
10547
+ items.reduce((acc, item) => {
10548
+ acc[item.variant_id] = true;
10549
+ return acc;
10550
+ }, {})
10551
+ );
10552
+ React.useEffect(() => {
10553
+ setRowSelection(
10554
+ items.reduce((acc, item) => {
10555
+ if (item.variant_id) {
10556
+ acc[item.variant_id] = true;
10557
+ }
10558
+ return acc;
10559
+ }, {})
10560
+ );
10561
+ }, [items]);
10562
+ const { q, order, offset } = useQueryParams(
10563
+ ["q", "order", "offset"],
10564
+ VARIANT_PREFIX
10565
+ );
10566
+ const { variants, count, isPending, isError, error } = useProductVariants(
10669
10567
  {
10670
- fields: "currency_code"
10568
+ q,
10569
+ order,
10570
+ offset: offset ? parseInt(offset) : void 0,
10571
+ limit: LIMIT
10671
10572
  },
10672
10573
  {
10673
- enabled: !!id
10574
+ placeholderData: reactQuery.keepPreviousData
10674
10575
  }
10675
10576
  );
10676
- const { onCancel } = useCancelOrderEdit({ preview });
10677
- if (isError) {
10678
- throw error;
10679
- }
10680
- if (isPreviewError) {
10681
- throw previewError;
10682
- }
10683
- const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10684
- return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsxRuntime.jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10685
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10686
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10687
- ] }) });
10688
- };
10689
- const ItemsForm = ({ preview, currencyCode }) => {
10690
- var _a;
10691
- const [isSubmitting, setIsSubmitting] = React.useState(false);
10692
- const [modalContent, setModalContent] = React.useState(
10693
- null
10694
- );
10695
- const { handleSuccess } = useRouteModal();
10696
- const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10697
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10698
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10699
- const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10700
- const matches = React.useMemo(() => {
10701
- return matchSorter.matchSorter(preview.items, query2, {
10702
- keys: ["product_title", "variant_title", "variant_sku", "title"]
10703
- });
10704
- }, [preview.items, query2]);
10577
+ const columns = useColumns();
10578
+ const { mutateAsync } = useDraftOrderAddItems(orderId);
10705
10579
  const onSubmit = async () => {
10706
- setIsSubmitting(true);
10707
- let requestSucceeded = false;
10708
- await requestOrderEdit(void 0, {
10709
- onError: (e) => {
10710
- ui.toast.error(`Failed to request order edit: ${e.message}`);
10711
- },
10712
- onSuccess: () => {
10713
- requestSucceeded = true;
10714
- }
10715
- });
10716
- if (!requestSucceeded) {
10717
- setIsSubmitting(false);
10718
- return;
10719
- }
10720
- await confirmOrderEdit(void 0, {
10721
- onError: (e) => {
10722
- ui.toast.error(`Failed to confirm order edit: ${e.message}`);
10723
- },
10724
- onSuccess: () => {
10725
- handleSuccess();
10580
+ const ids = Object.keys(rowSelection).filter(
10581
+ (id) => !items.find((i) => i.variant_id === id)
10582
+ );
10583
+ await mutateAsync(
10584
+ {
10585
+ items: ids.map((id) => ({
10586
+ variant_id: id,
10587
+ quantity: 1
10588
+ }))
10726
10589
  },
10727
- onSettled: () => {
10728
- setIsSubmitting(false);
10590
+ {
10591
+ onSuccess: () => {
10592
+ setRowSelection({});
10593
+ setIsOpen(STACKED_MODAL_ID, false);
10594
+ },
10595
+ onError: (e) => {
10596
+ ui.toast.error(e.message);
10597
+ }
10729
10598
  }
10730
- });
10599
+ );
10731
10600
  };
10732
- const onKeyDown = React.useCallback(
10733
- (e) => {
10734
- if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10735
- if (modalContent || isSubmitting) {
10736
- return;
10601
+ if (isError) {
10602
+ throw error;
10603
+ }
10604
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10605
+ StackedFocusModal.Content,
10606
+ {
10607
+ onOpenAutoFocus: (e) => {
10608
+ e.preventDefault();
10609
+ const searchInput = document.querySelector(
10610
+ "[data-modal-id='modal-search-input']"
10611
+ );
10612
+ if (searchInput) {
10613
+ searchInput.focus();
10737
10614
  }
10738
- onSubmit();
10739
- }
10615
+ },
10616
+ children: [
10617
+ /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Header, { children: [
10618
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10619
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
10620
+ ] }),
10621
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
10622
+ DataTable,
10623
+ {
10624
+ data: variants,
10625
+ columns,
10626
+ isLoading: isPending,
10627
+ getRowId: (row) => row.id,
10628
+ rowCount: count,
10629
+ prefix: VARIANT_PREFIX,
10630
+ layout: "fill",
10631
+ rowSelection: {
10632
+ state: rowSelection,
10633
+ onRowSelectionChange: setRowSelection,
10634
+ enableRowSelection: (row) => {
10635
+ return !items.find((i) => i.variant_id === row.original.id);
10636
+ }
10637
+ },
10638
+ autoFocusSearch: true
10639
+ }
10640
+ ) }),
10641
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10642
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10643
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
10644
+ ] }) })
10645
+ ]
10646
+ }
10647
+ );
10648
+ };
10649
+ const columnHelper = ui.createDataTableColumnHelper();
10650
+ const useColumns = () => {
10651
+ return React.useMemo(() => {
10652
+ return [
10653
+ columnHelper.select(),
10654
+ columnHelper.accessor("product.title", {
10655
+ header: "Product",
10656
+ cell: ({ row }) => {
10657
+ var _a, _b, _c;
10658
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
10659
+ /* @__PURE__ */ jsxRuntime.jsx(
10660
+ Thumbnail,
10661
+ {
10662
+ thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
10663
+ alt: (_b = row.original.product) == null ? void 0 : _b.title
10664
+ }
10665
+ ),
10666
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
10667
+ ] });
10668
+ },
10669
+ enableSorting: true
10670
+ }),
10671
+ columnHelper.accessor("title", {
10672
+ header: "Variant",
10673
+ enableSorting: true
10674
+ }),
10675
+ columnHelper.accessor("sku", {
10676
+ header: "SKU",
10677
+ cell: ({ getValue }) => {
10678
+ return getValue() ?? "-";
10679
+ },
10680
+ enableSorting: true
10681
+ }),
10682
+ columnHelper.accessor("updated_at", {
10683
+ header: "Updated",
10684
+ cell: ({ getValue }) => {
10685
+ return /* @__PURE__ */ jsxRuntime.jsx(
10686
+ ui.Tooltip,
10687
+ {
10688
+ content: getFullDate({ date: getValue(), includeTime: true }),
10689
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
10690
+ }
10691
+ );
10692
+ },
10693
+ enableSorting: true,
10694
+ sortAscLabel: "Oldest first",
10695
+ sortDescLabel: "Newest first"
10696
+ }),
10697
+ columnHelper.accessor("created_at", {
10698
+ header: "Created",
10699
+ cell: ({ getValue }) => {
10700
+ return /* @__PURE__ */ jsxRuntime.jsx(
10701
+ ui.Tooltip,
10702
+ {
10703
+ content: getFullDate({ date: getValue(), includeTime: true }),
10704
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
10705
+ }
10706
+ );
10707
+ },
10708
+ enableSorting: true,
10709
+ sortAscLabel: "Oldest first",
10710
+ sortDescLabel: "Newest first"
10711
+ })
10712
+ ];
10713
+ }, []);
10714
+ };
10715
+ const CustomItemForm = ({ orderId, currencyCode }) => {
10716
+ const { setIsOpen } = useStackedModal();
10717
+ const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
10718
+ const form = reactHookForm.useForm({
10719
+ defaultValues: {
10720
+ title: "",
10721
+ quantity: 1,
10722
+ unit_price: ""
10740
10723
  },
10741
- [modalContent, isSubmitting, onSubmit]
10742
- );
10743
- React.useEffect(() => {
10744
- document.addEventListener("keydown", onKeyDown);
10745
- return () => {
10746
- document.removeEventListener("keydown", onKeyDown);
10747
- };
10748
- }, [onKeyDown]);
10749
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10750
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
10751
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
10752
- StackedFocusModal,
10724
+ resolver: zod.zodResolver(customItemSchema)
10725
+ });
10726
+ const onSubmit = form.handleSubmit(async (data) => {
10727
+ await addItems(
10753
10728
  {
10754
- id: STACKED_MODAL_ID,
10755
- onOpenChangeCallback: (open) => {
10756
- if (!open) {
10757
- setModalContent(null);
10729
+ items: [
10730
+ {
10731
+ title: data.title,
10732
+ quantity: data.quantity,
10733
+ unit_price: convertNumber(data.unit_price)
10758
10734
  }
10735
+ ]
10736
+ },
10737
+ {
10738
+ onSuccess: () => {
10739
+ setIsOpen(STACKED_MODAL_ID, false);
10759
10740
  },
10760
- children: [
10761
- /* @__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: [
10741
+ onError: (e) => {
10742
+ ui.toast.error(e.message);
10743
+ }
10744
+ }
10745
+ );
10746
+ });
10747
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Content, { children: [
10748
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
10749
+ /* @__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 px-2 py-16", children: [
10750
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10751
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Add custom item" }) }),
10752
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a custom item to the order. This will add a new line item that is not associated with an existing product." }) })
10753
+ ] }),
10754
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10755
+ /* @__PURE__ */ jsxRuntime.jsx(
10756
+ Form$2.Field,
10757
+ {
10758
+ control: form.control,
10759
+ name: "title",
10760
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10762
10761
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10763
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Items" }) }),
10764
- /* @__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" }) })
10762
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Title" }),
10763
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the title of the item" })
10765
10764
  ] }),
10766
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10767
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
10768
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10769
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10770
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10771
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10772
- ] }),
10773
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10774
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10775
- ui.Input,
10776
- {
10777
- type: "search",
10778
- placeholder: "Search items",
10779
- value: searchValue,
10780
- onChange: (e) => onSearchValueChange(e.target.value)
10781
- }
10782
- ) }),
10783
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
10784
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}) }) }),
10785
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
10786
- /* @__PURE__ */ jsxRuntime.jsx(
10787
- StackedModalTrigger$1,
10788
- {
10789
- type: "add-items",
10790
- setModalContent
10791
- }
10792
- ),
10793
- /* @__PURE__ */ jsxRuntime.jsx(
10794
- StackedModalTrigger$1,
10795
- {
10796
- type: "add-custom-item",
10797
- setModalContent
10798
- }
10799
- )
10800
- ] })
10801
- ] })
10802
- ] })
10803
- ] }),
10804
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10805
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-muted grid grid-cols-[2fr_1fr_2fr_28px] gap-3 px-4 py-2", children: [
10806
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
10807
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10808
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Price" }) }),
10809
- /* @__PURE__ */ jsxRuntime.jsx("div", {})
10810
- ] }) }),
10811
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest flex flex-col items-center justify-center gap-1 gap-x-3 rounded-lg p-4", children: [
10812
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10813
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10814
- ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
10815
- Item,
10816
- {
10817
- item,
10818
- preview,
10819
- currencyCode
10820
- },
10821
- item.id
10822
- )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest flex flex-col items-center justify-center gap-1 gap-x-3 rounded-lg p-4", children: [
10823
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10824
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
10825
- 'No items found for "',
10826
- query2,
10827
- '".'
10828
- ] })
10829
- ] }) })
10830
- ] })
10765
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10766
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10767
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10768
+ ] })
10769
+ ] }) })
10770
+ }
10771
+ ),
10772
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10773
+ /* @__PURE__ */ jsxRuntime.jsx(
10774
+ Form$2.Field,
10775
+ {
10776
+ control: form.control,
10777
+ name: "unit_price",
10778
+ render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10779
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10780
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Unit price" }),
10781
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
10831
10782
  ] }),
10832
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10833
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10834
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10835
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(
10836
- ui.Text,
10783
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10784
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10785
+ ui.CurrencyInput,
10837
10786
  {
10838
- size: "small",
10839
- leading: "compact",
10840
- className: "text-ui-fg-subtle",
10841
- children: [
10842
- itemCount,
10843
- " ",
10844
- itemCount === 1 ? "item" : "items"
10845
- ]
10787
+ symbol: getNativeSymbol(currencyCode),
10788
+ code: currencyCode,
10789
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
10790
+ ...field
10846
10791
  }
10847
10792
  ) }),
10848
- /* @__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) }) })
10793
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10849
10794
  ] })
10850
- ] }) }),
10851
- modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsxRuntime.jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsxRuntime.jsx(
10852
- CustomItemForm,
10853
- {
10854
- orderId: preview.id,
10855
- currencyCode
10856
- }
10857
- ) : null)
10858
- ]
10859
- }
10860
- ) }),
10861
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10862
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10795
+ ] }) })
10796
+ }
10797
+ ),
10798
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10863
10799
  /* @__PURE__ */ jsxRuntime.jsx(
10864
- ui.Button,
10800
+ Form$2.Field,
10865
10801
  {
10866
- size: "small",
10867
- type: "button",
10868
- onClick: onSubmit,
10869
- isLoading: isSubmitting,
10870
- children: "Save"
10802
+ control: form.control,
10803
+ name: "quantity",
10804
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10805
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10806
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Quantity" }),
10807
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
10808
+ ] }),
10809
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex-1", children: [
10810
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field, className: "w-full" }) }) }),
10811
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10812
+ ] })
10813
+ ] }) })
10871
10814
  }
10872
10815
  )
10816
+ ] }) }) }),
10817
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10818
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10819
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
10873
10820
  ] }) })
10874
- ] });
10821
+ ] }) }) });
10822
+ };
10823
+ const customItemSchema = objectType({
10824
+ title: stringType().min(1),
10825
+ quantity: numberType(),
10826
+ unit_price: unionType([numberType(), stringType()])
10827
+ });
10828
+ const PROMOTION_QUERY_KEY = "promotions";
10829
+ const promotionsQueryKeys = {
10830
+ list: (query2) => [
10831
+ PROMOTION_QUERY_KEY,
10832
+ query2 ? query2 : void 0
10833
+ ],
10834
+ detail: (id, query2) => [
10835
+ PROMOTION_QUERY_KEY,
10836
+ id,
10837
+ query2 ? query2 : void 0
10838
+ ]
10875
10839
  };
10876
- const Item = ({ item, preview, currencyCode }) => {
10877
- if (item.variant_id) {
10878
- return /* @__PURE__ */ jsxRuntime.jsx(VariantItem, { item, preview, currencyCode });
10840
+ const usePromotions = (query2, options) => {
10841
+ const { data, ...rest } = reactQuery.useQuery({
10842
+ queryKey: promotionsQueryKeys.list(query2),
10843
+ queryFn: async () => sdk.admin.promotion.list(query2),
10844
+ ...options
10845
+ });
10846
+ return { ...data, ...rest };
10847
+ };
10848
+ const Promotions = () => {
10849
+ const { id } = reactRouterDom.useParams();
10850
+ const {
10851
+ order: preview,
10852
+ isError: isPreviewError,
10853
+ error: previewError
10854
+ } = useOrderPreview(id, void 0);
10855
+ useInitiateOrderEdit({ preview });
10856
+ const { onCancel } = useCancelOrderEdit({ preview });
10857
+ if (isPreviewError) {
10858
+ throw previewError;
10879
10859
  }
10880
- return /* @__PURE__ */ jsxRuntime.jsx(CustomItem, { item, preview, currencyCode });
10860
+ const isReady = !!preview;
10861
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
10862
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
10863
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
10864
+ ] });
10881
10865
  };
10882
- const VariantItem = ({ item, preview, currencyCode }) => {
10883
- const [editing, setEditing] = React.useState(false);
10884
- const form = reactHookForm.useForm({
10885
- defaultValues: {
10886
- quantity: item.quantity,
10887
- unit_price: item.unit_price
10866
+ const PromotionForm = ({ preview }) => {
10867
+ const { items, shipping_methods } = preview;
10868
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
10869
+ const [comboboxValue, setComboboxValue] = React.useState("");
10870
+ const { handleSuccess } = useRouteModal();
10871
+ const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
10872
+ const promoIds = getPromotionIds(items, shipping_methods);
10873
+ const { promotions, isPending, isError, error } = usePromotions(
10874
+ {
10875
+ id: promoIds
10888
10876
  },
10889
- resolver: zod.zodResolver(variantItemSchema)
10890
- });
10891
- const actionId = React.useMemo(() => {
10892
- var _a, _b;
10893
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10894
- }, [item]);
10895
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10896
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10897
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10898
- const onSubmit = form.handleSubmit(async (data) => {
10899
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10900
- setEditing(false);
10901
- return;
10877
+ {
10878
+ enabled: !!promoIds.length
10902
10879
  }
10903
- if (!actionId) {
10904
- await updateOriginalItem(
10905
- {
10906
- item_id: item.id,
10907
- quantity: data.quantity,
10908
- unit_price: convertNumber(data.unit_price)
10909
- },
10910
- {
10911
- onSuccess: () => {
10912
- setEditing(false);
10913
- },
10914
- onError: (e) => {
10915
- ui.toast.error(e.message);
10916
- }
10880
+ );
10881
+ const comboboxData = useComboboxData({
10882
+ queryKey: ["promotions", "combobox", promoIds],
10883
+ queryFn: async (params) => {
10884
+ return await sdk.admin.promotion.list({
10885
+ ...params,
10886
+ id: {
10887
+ $nin: promoIds
10917
10888
  }
10918
- );
10889
+ });
10890
+ },
10891
+ getOptions: (data) => {
10892
+ return data.promotions.map((promotion) => ({
10893
+ label: promotion.code,
10894
+ value: promotion.code
10895
+ }));
10896
+ }
10897
+ });
10898
+ const add = async (value) => {
10899
+ if (!value) {
10919
10900
  return;
10920
10901
  }
10921
- await updateActionItem(
10902
+ addPromotions(
10922
10903
  {
10923
- action_id: actionId,
10924
- quantity: data.quantity,
10925
- unit_price: convertNumber(data.unit_price)
10904
+ promo_codes: [value]
10926
10905
  },
10927
10906
  {
10928
- onSuccess: () => {
10929
- setEditing(false);
10930
- },
10931
10907
  onError: (e) => {
10932
10908
  ui.toast.error(e.message);
10909
+ comboboxData.onSearchValueChange("");
10910
+ setComboboxValue("");
10911
+ },
10912
+ onSuccess: () => {
10913
+ comboboxData.onSearchValueChange("");
10914
+ setComboboxValue("");
10933
10915
  }
10934
10916
  }
10935
10917
  );
10936
- });
10937
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-[minmax(0,2fr)_minmax(0,1fr)_minmax(0,2fr)_28px] items-center gap-3 rounded-lg px-4 py-2", children: [
10938
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10939
- /* @__PURE__ */ jsxRuntime.jsx(
10940
- Thumbnail,
10941
- {
10942
- thumbnail: item.thumbnail,
10943
- alt: item.product_title ?? void 0
10944
- }
10945
- ),
10946
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10947
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
10948
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10949
- /* @__PURE__ */ jsxRuntime.jsxs(
10950
- ui.Text,
10951
- {
10952
- size: "small",
10953
- leading: "compact",
10954
- className: "text-ui-fg-subtle",
10955
- children: [
10956
- "(",
10957
- item.variant_title,
10958
- ")"
10959
- ]
10960
- }
10961
- )
10962
- ] }),
10963
- /* @__PURE__ */ jsxRuntime.jsx(
10964
- ui.Text,
10965
- {
10966
- size: "small",
10967
- leading: "compact",
10968
- className: "text-ui-fg-subtle",
10969
- children: item.variant_sku
10970
- }
10971
- )
10972
- ] })
10973
- ] }),
10974
- editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10975
- Form$2.Field,
10976
- {
10977
- control: form.control,
10978
- name: "quantity",
10979
- render: ({ field }) => {
10980
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10981
- }
10982
- }
10983
- ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }) }),
10984
- editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10985
- Form$2.Field,
10986
- {
10987
- control: form.control,
10988
- name: "unit_price",
10989
- render: ({ field: { onChange, ...field } }) => {
10990
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10991
- ui.CurrencyInput,
10992
- {
10993
- ...field,
10994
- symbol: getNativeSymbol(currencyCode),
10995
- code: currencyCode,
10996
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10997
- }
10998
- ) }) });
10999
- }
11000
- }
11001
- ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex w-full flex-1 items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
11002
- /* @__PURE__ */ jsxRuntime.jsx(
11003
- ui.IconButton,
11004
- {
11005
- type: "button",
11006
- size: "small",
11007
- onClick: editing ? onSubmit : () => {
11008
- setEditing(true);
11009
- },
11010
- disabled: isPending,
11011
- children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
10918
+ };
10919
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10920
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
10921
+ const onSubmit = async () => {
10922
+ setIsSubmitting(true);
10923
+ let requestSucceeded = false;
10924
+ await requestOrderEdit(void 0, {
10925
+ onError: (e) => {
10926
+ ui.toast.error(e.message);
10927
+ },
10928
+ onSuccess: () => {
10929
+ requestSucceeded = true;
11012
10930
  }
11013
- )
11014
- ] }) }) });
11015
- };
11016
- const variantItemSchema = objectType({
11017
- quantity: numberType(),
11018
- unit_price: unionType([numberType(), stringType()])
11019
- });
11020
- const CustomItem = ({ item, preview, currencyCode }) => {
11021
- const [editing, setEditing] = React.useState(false);
11022
- const { quantity, unit_price, title } = item;
11023
- const form = reactHookForm.useForm({
11024
- defaultValues: {
11025
- title,
11026
- quantity,
11027
- unit_price
11028
- },
11029
- resolver: zod.zodResolver(customItemSchema)
11030
- });
11031
- React.useEffect(() => {
11032
- form.reset({
11033
- title,
11034
- quantity,
11035
- unit_price
11036
10931
  });
11037
- }, [form, title, quantity, unit_price]);
11038
- const actionId = React.useMemo(() => {
11039
- var _a, _b;
11040
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
11041
- }, [item]);
11042
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
11043
- const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
11044
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
11045
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
11046
- const onSubmit = form.handleSubmit(async (data) => {
11047
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
11048
- setEditing(false);
10932
+ if (!requestSucceeded) {
10933
+ setIsSubmitting(false);
11049
10934
  return;
11050
10935
  }
11051
- if (!actionId) {
11052
- await updateOriginalItem(
10936
+ await confirmOrderEdit(void 0, {
10937
+ onError: (e) => {
10938
+ ui.toast.error(e.message);
10939
+ },
10940
+ onSuccess: () => {
10941
+ handleSuccess();
10942
+ },
10943
+ onSettled: () => {
10944
+ setIsSubmitting(false);
10945
+ }
10946
+ });
10947
+ };
10948
+ if (isError) {
10949
+ throw error;
10950
+ }
10951
+ return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
10952
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
10953
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
10954
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10955
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
10956
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
10957
+ ] }),
10958
+ /* @__PURE__ */ jsxRuntime.jsx(
10959
+ Combobox,
10960
+ {
10961
+ id: "promotion-combobox",
10962
+ "aria-describedby": "promotion-combobox-hint",
10963
+ isFetchingNextPage: comboboxData.isFetchingNextPage,
10964
+ fetchNextPage: comboboxData.fetchNextPage,
10965
+ options: comboboxData.options,
10966
+ onSearchValueChange: comboboxData.onSearchValueChange,
10967
+ searchValue: comboboxData.searchValue,
10968
+ disabled: comboboxData.disabled || isAddingPromotions,
10969
+ onChange: add,
10970
+ value: comboboxValue
10971
+ }
10972
+ )
10973
+ ] }),
10974
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10975
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
10976
+ PromotionItem,
11053
10977
  {
11054
- item_id: item.id,
11055
- quantity: data.quantity,
11056
- unit_price: convertNumber(data.unit_price)
10978
+ promotion,
10979
+ orderId: preview.id,
10980
+ isLoading: isPending
11057
10981
  },
10982
+ promotion.id
10983
+ )) })
10984
+ ] }) }),
10985
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
10986
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10987
+ /* @__PURE__ */ jsxRuntime.jsx(
10988
+ ui.Button,
11058
10989
  {
11059
- onSuccess: () => {
11060
- setEditing(false);
11061
- },
11062
- onError: (e) => {
11063
- ui.toast.error(e.message);
11064
- }
11065
- }
11066
- );
11067
- return;
11068
- }
11069
- if (data.quantity === 0) {
11070
- await removeActionItem(actionId, {
11071
- onSuccess: () => {
11072
- setEditing(false);
11073
- },
11074
- onError: (e) => {
11075
- ui.toast.error(e.message);
10990
+ size: "small",
10991
+ type: "submit",
10992
+ isLoading: isSubmitting || isAddingPromotions,
10993
+ children: "Save"
11076
10994
  }
11077
- });
11078
- return;
11079
- }
11080
- await updateActionItem(
10995
+ )
10996
+ ] }) })
10997
+ ] });
10998
+ };
10999
+ const PromotionItem = ({
11000
+ promotion,
11001
+ orderId,
11002
+ isLoading
11003
+ }) => {
11004
+ var _a;
11005
+ const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
11006
+ const onRemove = async () => {
11007
+ removePromotions(
11081
11008
  {
11082
- action_id: actionId,
11083
- quantity: data.quantity,
11084
- unit_price: convertNumber(data.unit_price)
11009
+ promo_codes: [promotion.code]
11085
11010
  },
11086
11011
  {
11087
- onSuccess: () => {
11088
- setEditing(false);
11089
- },
11090
11012
  onError: (e) => {
11091
11013
  ui.toast.error(e.message);
11092
11014
  }
11093
11015
  }
11094
11016
  );
11095
- });
11096
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-[minmax(0,2fr)_minmax(0,1fr)_minmax(0,2fr)_28px] items-center gap-3 rounded-lg px-4 py-2", children: [
11097
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
11098
- /* @__PURE__ */ jsxRuntime.jsx(
11099
- Thumbnail,
11017
+ };
11018
+ const displayValue = getDisplayValue(promotion);
11019
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11020
+ "div",
11021
+ {
11022
+ className: ui.clx(
11023
+ "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
11100
11024
  {
11101
- thumbnail: item.thumbnail,
11102
- alt: item.title ?? void 0
11025
+ "animate-pulse": isLoading
11103
11026
  }
11104
11027
  ),
11105
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
11106
- Form$2.Field,
11107
- {
11108
- control: form.control,
11109
- name: "title",
11110
- render: ({ field }) => {
11111
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }) });
11028
+ children: [
11029
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11030
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11031
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
11032
+ displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
11033
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
11034
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
11035
+ ] }),
11036
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11037
+ ] })
11038
+ ] }),
11039
+ /* @__PURE__ */ jsxRuntime.jsx(
11040
+ ui.IconButton,
11041
+ {
11042
+ size: "small",
11043
+ type: "button",
11044
+ variant: "transparent",
11045
+ onClick: onRemove,
11046
+ isLoading: isPending || isLoading,
11047
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
11112
11048
  }
11113
- }
11114
- ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.title })
11115
- ] }),
11116
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
11117
- Form$2.Field,
11118
- {
11119
- control: form.control,
11120
- name: "quantity",
11121
- render: ({ field }) => {
11122
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
11123
- }
11124
- }
11125
- ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }),
11126
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
11127
- Form$2.Field,
11128
- {
11129
- control: form.control,
11130
- name: "unit_price",
11131
- render: ({ field: { onChange, ...field } }) => {
11132
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11133
- ui.CurrencyInput,
11134
- {
11135
- ...field,
11136
- symbol: getNativeSymbol(currencyCode),
11137
- code: currencyCode,
11138
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
11139
- }
11140
- ) }) });
11141
- }
11142
- }
11143
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
11144
- /* @__PURE__ */ jsxRuntime.jsx(
11145
- ui.IconButton,
11146
- {
11147
- type: "button",
11148
- size: "small",
11149
- onClick: editing ? onSubmit : () => {
11150
- setEditing(true);
11151
- },
11152
- disabled: isPending,
11153
- children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
11154
- }
11155
- )
11156
- ] }) }) });
11049
+ )
11050
+ ]
11051
+ },
11052
+ promotion.id
11053
+ );
11157
11054
  };
11158
- const StackedModalTrigger$1 = ({
11159
- type,
11160
- setModalContent
11161
- }) => {
11162
- const { setIsOpen } = useStackedModal();
11163
- const onClick = React.useCallback(() => {
11164
- setModalContent(type);
11165
- setIsOpen(STACKED_MODAL_ID, true);
11166
- }, [setModalContent, setIsOpen, type]);
11167
- return /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
11055
+ function getDisplayValue(promotion) {
11056
+ var _a, _b, _c, _d;
11057
+ const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11058
+ if (!value) {
11059
+ return null;
11060
+ }
11061
+ if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11062
+ const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11063
+ if (!currency) {
11064
+ return null;
11065
+ }
11066
+ return getLocaleAmount(value, currency);
11067
+ } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11068
+ return formatPercentage(value);
11069
+ }
11070
+ return null;
11071
+ }
11072
+ const formatter = new Intl.NumberFormat([], {
11073
+ style: "percent",
11074
+ minimumFractionDigits: 2
11075
+ });
11076
+ const formatPercentage = (value, isPercentageValue = false) => {
11077
+ let val = value || 0;
11078
+ if (!isPercentageValue) {
11079
+ val = val / 100;
11080
+ }
11081
+ return formatter.format(val);
11168
11082
  };
11169
- const VARIANT_PREFIX = "items";
11170
- const LIMIT = 50;
11171
- const ExistingItemsForm = ({ orderId, items }) => {
11172
- const { setIsOpen } = useStackedModal();
11173
- const [rowSelection, setRowSelection] = React.useState(
11174
- items.reduce((acc, item) => {
11175
- acc[item.variant_id] = true;
11176
- return acc;
11177
- }, {})
11178
- );
11179
- React.useEffect(() => {
11180
- setRowSelection(
11181
- items.reduce((acc, item) => {
11182
- if (item.variant_id) {
11183
- acc[item.variant_id] = true;
11083
+ function getPromotionIds(items, shippingMethods) {
11084
+ const promotionIds = /* @__PURE__ */ new Set();
11085
+ for (const item of items) {
11086
+ if (item.adjustments) {
11087
+ for (const adjustment of item.adjustments) {
11088
+ if (adjustment.promotion_id) {
11089
+ promotionIds.add(adjustment.promotion_id);
11184
11090
  }
11185
- return acc;
11186
- }, {})
11187
- );
11188
- }, [items]);
11189
- const { q, order, offset } = useQueryParams(
11190
- ["q", "order", "offset"],
11191
- VARIANT_PREFIX
11192
- );
11193
- const { variants, count, isPending, isError, error } = useProductVariants(
11194
- {
11195
- q,
11196
- order,
11197
- offset: offset ? parseInt(offset) : void 0,
11198
- limit: LIMIT
11199
- },
11200
- {
11201
- placeholderData: reactQuery.keepPreviousData
11091
+ }
11092
+ }
11093
+ }
11094
+ for (const shippingMethod of shippingMethods) {
11095
+ if (shippingMethod.adjustments) {
11096
+ for (const adjustment of shippingMethod.adjustments) {
11097
+ if (adjustment.promotion_id) {
11098
+ promotionIds.add(adjustment.promotion_id);
11099
+ }
11100
+ }
11202
11101
  }
11203
- );
11204
- const columns = useColumns();
11205
- const { mutateAsync } = useDraftOrderAddItems(orderId);
11206
- const onSubmit = async () => {
11207
- const ids = Object.keys(rowSelection).filter(
11208
- (id) => !items.find((i) => i.variant_id === id)
11102
+ }
11103
+ return Array.from(promotionIds);
11104
+ }
11105
+ const InlineTip = React.forwardRef(
11106
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
11107
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
11108
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11109
+ "div",
11110
+ {
11111
+ ref,
11112
+ className: ui.clx(
11113
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
11114
+ className
11115
+ ),
11116
+ ...props,
11117
+ children: [
11118
+ /* @__PURE__ */ jsxRuntime.jsx(
11119
+ "div",
11120
+ {
11121
+ role: "presentation",
11122
+ className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
11123
+ "bg-ui-tag-orange-icon": variant === "warning"
11124
+ })
11125
+ }
11126
+ ),
11127
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
11128
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
11129
+ labelValue,
11130
+ ":"
11131
+ ] }),
11132
+ " ",
11133
+ children
11134
+ ] })
11135
+ ]
11136
+ }
11209
11137
  );
11138
+ }
11139
+ );
11140
+ InlineTip.displayName = "InlineTip";
11141
+ const MetadataFieldSchema = objectType({
11142
+ key: stringType(),
11143
+ disabled: booleanType().optional(),
11144
+ value: anyType()
11145
+ });
11146
+ const MetadataSchema = objectType({
11147
+ metadata: arrayType(MetadataFieldSchema)
11148
+ });
11149
+ const Metadata = () => {
11150
+ const { id } = reactRouterDom.useParams();
11151
+ const { order, isPending, isError, error } = useOrder(id, {
11152
+ fields: "metadata"
11153
+ });
11154
+ if (isError) {
11155
+ throw error;
11156
+ }
11157
+ const isReady = !isPending && !!order;
11158
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
11159
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11160
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
11161
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
11162
+ ] }),
11163
+ !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
11164
+ ] });
11165
+ };
11166
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
11167
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
11168
+ const MetadataForm = ({ orderId, metadata }) => {
11169
+ const { handleSuccess } = useRouteModal();
11170
+ const hasUneditableRows = getHasUneditableRows(metadata);
11171
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
11172
+ const form = reactHookForm.useForm({
11173
+ defaultValues: {
11174
+ metadata: getDefaultValues(metadata)
11175
+ },
11176
+ resolver: zod.zodResolver(MetadataSchema)
11177
+ });
11178
+ const handleSubmit = form.handleSubmit(async (data) => {
11179
+ const parsedData = parseValues(data);
11210
11180
  await mutateAsync(
11211
11181
  {
11212
- items: ids.map((id) => ({
11213
- variant_id: id,
11214
- quantity: 1
11215
- }))
11182
+ metadata: parsedData
11216
11183
  },
11217
11184
  {
11218
11185
  onSuccess: () => {
11219
- setRowSelection({});
11220
- setIsOpen(STACKED_MODAL_ID, false);
11186
+ ui.toast.success("Metadata updated");
11187
+ handleSuccess();
11221
11188
  },
11222
- onError: (e) => {
11223
- ui.toast.error(e.message);
11189
+ onError: (error) => {
11190
+ ui.toast.error(error.message);
11224
11191
  }
11225
11192
  }
11226
11193
  );
11227
- };
11228
- if (isError) {
11229
- throw error;
11194
+ });
11195
+ const { fields, insert, remove } = reactHookForm.useFieldArray({
11196
+ control: form.control,
11197
+ name: "metadata"
11198
+ });
11199
+ function deleteRow(index) {
11200
+ remove(index);
11201
+ if (fields.length === 1) {
11202
+ insert(0, {
11203
+ key: "",
11204
+ value: "",
11205
+ disabled: false
11206
+ });
11207
+ }
11230
11208
  }
11231
- return /* @__PURE__ */ jsxRuntime.jsxs(
11232
- StackedFocusModal.Content,
11209
+ function insertRow(index, position) {
11210
+ insert(index + (position === "above" ? 0 : 1), {
11211
+ key: "",
11212
+ value: "",
11213
+ disabled: false
11214
+ });
11215
+ }
11216
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11217
+ KeyboundForm,
11233
11218
  {
11234
- onOpenAutoFocus: (e) => {
11235
- e.preventDefault();
11236
- const searchInput = document.querySelector(
11237
- "[data-modal-id='modal-search-input']"
11238
- );
11239
- if (searchInput) {
11240
- searchInput.focus();
11241
- }
11242
- },
11219
+ onSubmit: handleSubmit,
11220
+ className: "flex flex-1 flex-col overflow-hidden",
11243
11221
  children: [
11244
- /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Header, { children: [
11245
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Product Variants" }) }),
11246
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
11222
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
11223
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
11224
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
11225
+ /* @__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" }) }),
11226
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
11227
+ ] }),
11228
+ fields.map((field, index) => {
11229
+ const isDisabled = field.disabled || false;
11230
+ let placeholder = "-";
11231
+ if (typeof field.value === "object") {
11232
+ placeholder = "{ ... }";
11233
+ }
11234
+ if (Array.isArray(field.value)) {
11235
+ placeholder = "[ ... ]";
11236
+ }
11237
+ return /* @__PURE__ */ jsxRuntime.jsx(
11238
+ ConditionalTooltip,
11239
+ {
11240
+ showTooltip: isDisabled,
11241
+ content: "This row is disabled because it contains non-primitive data.",
11242
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
11243
+ /* @__PURE__ */ jsxRuntime.jsxs(
11244
+ "div",
11245
+ {
11246
+ className: ui.clx("grid grid-cols-2 divide-x", {
11247
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
11248
+ }),
11249
+ children: [
11250
+ /* @__PURE__ */ jsxRuntime.jsx(
11251
+ Form$2.Field,
11252
+ {
11253
+ control: form.control,
11254
+ name: `metadata.${index}.key`,
11255
+ render: ({ field: field2 }) => {
11256
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11257
+ GridInput,
11258
+ {
11259
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
11260
+ ...field2,
11261
+ disabled: isDisabled,
11262
+ placeholder: "Key"
11263
+ }
11264
+ ) }) });
11265
+ }
11266
+ }
11267
+ ),
11268
+ /* @__PURE__ */ jsxRuntime.jsx(
11269
+ Form$2.Field,
11270
+ {
11271
+ control: form.control,
11272
+ name: `metadata.${index}.value`,
11273
+ render: ({ field: { value, ...field2 } }) => {
11274
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11275
+ GridInput,
11276
+ {
11277
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
11278
+ ...field2,
11279
+ value: isDisabled ? placeholder : value,
11280
+ disabled: isDisabled,
11281
+ placeholder: "Value"
11282
+ }
11283
+ ) }) });
11284
+ }
11285
+ }
11286
+ )
11287
+ ]
11288
+ }
11289
+ ),
11290
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
11291
+ /* @__PURE__ */ jsxRuntime.jsx(
11292
+ ui.DropdownMenu.Trigger,
11293
+ {
11294
+ className: ui.clx(
11295
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11296
+ {
11297
+ hidden: isDisabled
11298
+ }
11299
+ ),
11300
+ disabled: isDisabled,
11301
+ asChild: true,
11302
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
11303
+ }
11304
+ ),
11305
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
11306
+ /* @__PURE__ */ jsxRuntime.jsxs(
11307
+ ui.DropdownMenu.Item,
11308
+ {
11309
+ className: "gap-x-2",
11310
+ onClick: () => insertRow(index, "above"),
11311
+ children: [
11312
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
11313
+ "Insert row above"
11314
+ ]
11315
+ }
11316
+ ),
11317
+ /* @__PURE__ */ jsxRuntime.jsxs(
11318
+ ui.DropdownMenu.Item,
11319
+ {
11320
+ className: "gap-x-2",
11321
+ onClick: () => insertRow(index, "below"),
11322
+ children: [
11323
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
11324
+ "Insert row below"
11325
+ ]
11326
+ }
11327
+ ),
11328
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
11329
+ /* @__PURE__ */ jsxRuntime.jsxs(
11330
+ ui.DropdownMenu.Item,
11331
+ {
11332
+ className: "gap-x-2",
11333
+ onClick: () => deleteRow(index),
11334
+ children: [
11335
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
11336
+ "Delete row"
11337
+ ]
11338
+ }
11339
+ )
11340
+ ] })
11341
+ ] })
11342
+ ] })
11343
+ },
11344
+ field.id
11345
+ );
11346
+ })
11347
+ ] }),
11348
+ 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." })
11247
11349
  ] }),
11248
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
11249
- DataTable,
11250
- {
11251
- data: variants,
11252
- columns,
11253
- isLoading: isPending,
11254
- getRowId: (row) => row.id,
11255
- rowCount: count,
11256
- prefix: VARIANT_PREFIX,
11257
- layout: "fill",
11258
- rowSelection: {
11259
- state: rowSelection,
11260
- onRowSelectionChange: setRowSelection,
11261
- enableRowSelection: (row) => {
11262
- return !items.find((i) => i.variant_id === row.original.id);
11263
- }
11264
- },
11265
- autoFocusSearch: true
11266
- }
11267
- ) }),
11268
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11269
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11270
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
11350
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11351
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11352
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11271
11353
  ] }) })
11272
11354
  ]
11273
11355
  }
11356
+ ) });
11357
+ };
11358
+ const GridInput = React.forwardRef(({ className, ...props }, ref) => {
11359
+ return /* @__PURE__ */ jsxRuntime.jsx(
11360
+ "input",
11361
+ {
11362
+ ref,
11363
+ ...props,
11364
+ autoComplete: "off",
11365
+ className: ui.clx(
11366
+ "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",
11367
+ className
11368
+ )
11369
+ }
11274
11370
  );
11371
+ });
11372
+ GridInput.displayName = "MetadataForm.GridInput";
11373
+ const PlaceholderInner = () => {
11374
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11375
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11376
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11377
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
11378
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
11379
+ ] }) })
11380
+ ] });
11275
11381
  };
11276
- const columnHelper = ui.createDataTableColumnHelper();
11277
- const useColumns = () => {
11278
- return React.useMemo(() => {
11382
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
11383
+ function getDefaultValues(metadata) {
11384
+ if (!metadata || !Object.keys(metadata).length) {
11279
11385
  return [
11280
- columnHelper.select(),
11281
- columnHelper.accessor("product.title", {
11282
- header: "Product",
11283
- cell: ({ row }) => {
11284
- var _a, _b, _c;
11285
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
11286
- /* @__PURE__ */ jsxRuntime.jsx(
11287
- Thumbnail,
11288
- {
11289
- thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
11290
- alt: (_b = row.original.product) == null ? void 0 : _b.title
11291
- }
11292
- ),
11293
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
11294
- ] });
11295
- },
11296
- enableSorting: true
11297
- }),
11298
- columnHelper.accessor("title", {
11299
- header: "Variant",
11300
- enableSorting: true
11301
- }),
11302
- columnHelper.accessor("sku", {
11303
- header: "SKU",
11304
- cell: ({ getValue }) => {
11305
- return getValue() ?? "-";
11306
- },
11307
- enableSorting: true
11308
- }),
11309
- columnHelper.accessor("updated_at", {
11310
- header: "Updated",
11311
- cell: ({ getValue }) => {
11312
- return /* @__PURE__ */ jsxRuntime.jsx(
11313
- ui.Tooltip,
11314
- {
11315
- content: getFullDate({ date: getValue(), includeTime: true }),
11316
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
11317
- }
11318
- );
11319
- },
11320
- enableSorting: true,
11321
- sortAscLabel: "Oldest first",
11322
- sortDescLabel: "Newest first"
11323
- }),
11324
- columnHelper.accessor("created_at", {
11325
- header: "Created",
11326
- cell: ({ getValue }) => {
11327
- return /* @__PURE__ */ jsxRuntime.jsx(
11328
- ui.Tooltip,
11329
- {
11330
- content: getFullDate({ date: getValue(), includeTime: true }),
11331
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
11332
- }
11333
- );
11334
- },
11335
- enableSorting: true,
11336
- sortAscLabel: "Oldest first",
11337
- sortDescLabel: "Newest first"
11338
- })
11339
- ];
11340
- }, []);
11341
- };
11342
- const CustomItemForm = ({ orderId, currencyCode }) => {
11343
- const { setIsOpen } = useStackedModal();
11344
- const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
11345
- const form = reactHookForm.useForm({
11346
- defaultValues: {
11347
- title: "",
11348
- quantity: 1,
11349
- unit_price: ""
11350
- },
11351
- resolver: zod.zodResolver(customItemSchema)
11352
- });
11353
- const onSubmit = form.handleSubmit(async (data) => {
11354
- await addItems(
11355
- {
11356
- items: [
11357
- {
11358
- title: data.title,
11359
- quantity: data.quantity,
11360
- unit_price: convertNumber(data.unit_price)
11361
- }
11362
- ]
11363
- },
11364
11386
  {
11365
- onSuccess: () => {
11366
- setIsOpen(STACKED_MODAL_ID, false);
11367
- },
11368
- onError: (e) => {
11369
- ui.toast.error(e.message);
11370
- }
11387
+ key: "",
11388
+ value: "",
11389
+ disabled: false
11371
11390
  }
11372
- );
11373
- });
11374
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Content, { children: [
11375
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
11376
- /* @__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 px-2 py-16", children: [
11377
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11378
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Add custom item" }) }),
11379
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a custom item to the order. This will add a new line item that is not associated with an existing product." }) })
11380
- ] }),
11381
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11382
- /* @__PURE__ */ jsxRuntime.jsx(
11383
- Form$2.Field,
11384
- {
11385
- control: form.control,
11386
- name: "title",
11387
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11388
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11389
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Title" }),
11390
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the title of the item" })
11391
- ] }),
11392
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11393
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11394
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11395
- ] })
11396
- ] }) })
11397
- }
11398
- ),
11399
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11400
- /* @__PURE__ */ jsxRuntime.jsx(
11401
- Form$2.Field,
11402
- {
11403
- control: form.control,
11404
- name: "unit_price",
11405
- render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11406
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11407
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Unit price" }),
11408
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
11409
- ] }),
11410
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11411
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11412
- ui.CurrencyInput,
11413
- {
11414
- symbol: getNativeSymbol(currencyCode),
11415
- code: currencyCode,
11416
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
11417
- ...field
11418
- }
11419
- ) }),
11420
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11421
- ] })
11422
- ] }) })
11423
- }
11424
- ),
11425
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11426
- /* @__PURE__ */ jsxRuntime.jsx(
11427
- Form$2.Field,
11428
- {
11429
- control: form.control,
11430
- name: "quantity",
11431
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11432
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11433
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Quantity" }),
11434
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
11435
- ] }),
11436
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex-1", children: [
11437
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field, className: "w-full" }) }) }),
11438
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11439
- ] })
11440
- ] }) })
11441
- }
11442
- )
11443
- ] }) }) }),
11444
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11445
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11446
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
11447
- ] }) })
11448
- ] }) }) });
11449
- };
11450
- const customItemSchema = objectType({
11451
- title: stringType().min(1),
11452
- quantity: numberType(),
11453
- unit_price: unionType([numberType(), stringType()])
11454
- });
11391
+ ];
11392
+ }
11393
+ return Object.entries(metadata).map(([key, value]) => {
11394
+ if (!EDITABLE_TYPES.includes(typeof value)) {
11395
+ return {
11396
+ key,
11397
+ value,
11398
+ disabled: true
11399
+ };
11400
+ }
11401
+ let stringValue = value;
11402
+ if (typeof value !== "string") {
11403
+ stringValue = JSON.stringify(value);
11404
+ }
11405
+ return {
11406
+ key,
11407
+ value: stringValue,
11408
+ original_key: key
11409
+ };
11410
+ });
11411
+ }
11412
+ function parseValues(values) {
11413
+ const metadata = values.metadata;
11414
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11415
+ if (isEmpty) {
11416
+ return null;
11417
+ }
11418
+ const update = {};
11419
+ metadata.forEach((field) => {
11420
+ let key = field.key;
11421
+ let value = field.value;
11422
+ const disabled = field.disabled;
11423
+ if (!key || !value) {
11424
+ return;
11425
+ }
11426
+ if (disabled) {
11427
+ update[key] = value;
11428
+ return;
11429
+ }
11430
+ key = key.trim();
11431
+ value = value.trim();
11432
+ if (value === "true") {
11433
+ update[key] = true;
11434
+ } else if (value === "false") {
11435
+ update[key] = false;
11436
+ } else {
11437
+ const parsedNumber = parseFloat(value);
11438
+ if (!isNaN(parsedNumber)) {
11439
+ update[key] = parsedNumber;
11440
+ } else {
11441
+ update[key] = value;
11442
+ }
11443
+ }
11444
+ });
11445
+ return update;
11446
+ }
11447
+ function getHasUneditableRows(metadata) {
11448
+ if (!metadata) {
11449
+ return false;
11450
+ }
11451
+ return Object.values(metadata).some(
11452
+ (value) => !EDITABLE_TYPES.includes(typeof value)
11453
+ );
11454
+ }
11455
11455
  const SalesChannel = () => {
11456
11456
  const { id } = reactRouterDom.useParams();
11457
11457
  const { draft_order, isPending, isError, error } = useDraftOrder(
@@ -12344,230 +12344,27 @@ const CustomAmountField = ({
12344
12344
  Form$2.Field,
12345
12345
  {
12346
12346
  control,
12347
- name: "custom_amount",
12348
- render: ({ field: { onChange, ...field } }) => {
12349
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12350
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12351
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12352
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12353
- ] }),
12354
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12355
- ui.CurrencyInput,
12356
- {
12357
- ...field,
12358
- onValueChange: (value) => onChange(value),
12359
- symbol: getNativeSymbol(currencyCode),
12360
- code: currencyCode
12361
- }
12362
- ) })
12363
- ] });
12364
- }
12365
- }
12366
- );
12367
- };
12368
- const ShippingAddress = () => {
12369
- const { id } = reactRouterDom.useParams();
12370
- const { order, isPending, isError, error } = useOrder(id, {
12371
- fields: "+shipping_address"
12372
- });
12373
- if (isError) {
12374
- throw error;
12375
- }
12376
- const isReady = !isPending && !!order;
12377
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
12378
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
12379
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Shipping Address" }) }),
12380
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
12381
- ] }),
12382
- isReady && /* @__PURE__ */ jsxRuntime.jsx(ShippingAddressForm, { order })
12383
- ] });
12384
- };
12385
- const ShippingAddressForm = ({ order }) => {
12386
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12387
- const form = reactHookForm.useForm({
12388
- defaultValues: {
12389
- first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
12390
- last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
12391
- company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
12392
- address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
12393
- address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
12394
- city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
12395
- province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
12396
- country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
12397
- postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12398
- phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12399
- },
12400
- resolver: zod.zodResolver(schema$1)
12401
- });
12402
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12403
- const { handleSuccess } = useRouteModal();
12404
- const onSubmit = form.handleSubmit(async (data) => {
12405
- await mutateAsync(
12406
- {
12407
- shipping_address: {
12408
- first_name: data.first_name,
12409
- last_name: data.last_name,
12410
- company: data.company,
12411
- address_1: data.address_1,
12412
- address_2: data.address_2,
12413
- city: data.city,
12414
- province: data.province,
12415
- country_code: data.country_code,
12416
- postal_code: data.postal_code,
12417
- phone: data.phone
12418
- }
12419
- },
12420
- {
12421
- onSuccess: () => {
12422
- handleSuccess();
12423
- },
12424
- onError: (error) => {
12425
- ui.toast.error(error.message);
12426
- }
12427
- }
12428
- );
12429
- });
12430
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12431
- KeyboundForm,
12432
- {
12433
- className: "flex flex-1 flex-col overflow-hidden",
12434
- onSubmit,
12435
- children: [
12436
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-4", children: [
12437
- /* @__PURE__ */ jsxRuntime.jsx(
12438
- Form$2.Field,
12439
- {
12440
- control: form.control,
12441
- name: "country_code",
12442
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12443
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Country" }),
12444
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(CountrySelect, { ...field }) }),
12445
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12446
- ] })
12447
- }
12448
- ),
12449
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12450
- /* @__PURE__ */ jsxRuntime.jsx(
12451
- Form$2.Field,
12452
- {
12453
- control: form.control,
12454
- name: "first_name",
12455
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12456
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "First name" }),
12457
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12458
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12459
- ] })
12460
- }
12461
- ),
12462
- /* @__PURE__ */ jsxRuntime.jsx(
12463
- Form$2.Field,
12464
- {
12465
- control: form.control,
12466
- name: "last_name",
12467
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12468
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Last name" }),
12469
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12470
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12471
- ] })
12472
- }
12473
- )
12474
- ] }),
12475
- /* @__PURE__ */ jsxRuntime.jsx(
12476
- Form$2.Field,
12477
- {
12478
- control: form.control,
12479
- name: "company",
12480
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12481
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Company" }),
12482
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12483
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12484
- ] })
12485
- }
12486
- ),
12487
- /* @__PURE__ */ jsxRuntime.jsx(
12488
- Form$2.Field,
12489
- {
12490
- control: form.control,
12491
- name: "address_1",
12492
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12493
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Address" }),
12494
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12495
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12496
- ] })
12497
- }
12498
- ),
12499
- /* @__PURE__ */ jsxRuntime.jsx(
12500
- Form$2.Field,
12501
- {
12502
- control: form.control,
12503
- name: "address_2",
12504
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12505
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12506
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12507
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12508
- ] })
12509
- }
12510
- ),
12511
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12512
- /* @__PURE__ */ jsxRuntime.jsx(
12513
- Form$2.Field,
12514
- {
12515
- control: form.control,
12516
- name: "postal_code",
12517
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12518
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Postal code" }),
12519
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12520
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12521
- ] })
12522
- }
12523
- ),
12524
- /* @__PURE__ */ jsxRuntime.jsx(
12525
- Form$2.Field,
12526
- {
12527
- control: form.control,
12528
- name: "city",
12529
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12530
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "City" }),
12531
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12532
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12533
- ] })
12534
- }
12535
- )
12536
- ] }),
12537
- /* @__PURE__ */ jsxRuntime.jsx(
12538
- Form$2.Field,
12539
- {
12540
- control: form.control,
12541
- name: "province",
12542
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12543
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Province / State" }),
12544
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12545
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12546
- ] })
12547
- }
12548
- ),
12549
- /* @__PURE__ */ jsxRuntime.jsx(
12550
- Form$2.Field,
12347
+ name: "custom_amount",
12348
+ render: ({ field: { onChange, ...field } }) => {
12349
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12350
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12351
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
12352
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
12353
+ ] }),
12354
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12355
+ ui.CurrencyInput,
12551
12356
  {
12552
- control: form.control,
12553
- name: "phone",
12554
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12555
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Phone" }),
12556
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12557
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12558
- ] })
12357
+ ...field,
12358
+ onValueChange: (value) => onChange(value),
12359
+ symbol: getNativeSymbol(currencyCode),
12360
+ code: currencyCode
12559
12361
  }
12560
- )
12561
- ] }) }),
12562
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
12563
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12564
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12565
- ] }) })
12566
- ]
12362
+ ) })
12363
+ ] });
12364
+ }
12567
12365
  }
12568
- ) });
12366
+ );
12569
12367
  };
12570
- const schema$1 = addressSchema;
12571
12368
  const TransferOwnership = () => {
12572
12369
  const { id } = reactRouterDom.useParams();
12573
12370
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -12591,7 +12388,7 @@ const TransferOwnershipForm = ({ order }) => {
12591
12388
  defaultValues: {
12592
12389
  customer_id: order.customer_id || ""
12593
12390
  },
12594
- resolver: zod.zodResolver(schema)
12391
+ resolver: zod.zodResolver(schema$1)
12595
12392
  });
12596
12393
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12597
12394
  const { handleSuccess } = useRouteModal();
@@ -13041,9 +12838,212 @@ const Illustration = () => {
13041
12838
  }
13042
12839
  );
13043
12840
  };
13044
- const schema = objectType({
12841
+ const schema$1 = objectType({
13045
12842
  customer_id: stringType().min(1)
13046
12843
  });
12844
+ const ShippingAddress = () => {
12845
+ const { id } = reactRouterDom.useParams();
12846
+ const { order, isPending, isError, error } = useOrder(id, {
12847
+ fields: "+shipping_address"
12848
+ });
12849
+ if (isError) {
12850
+ throw error;
12851
+ }
12852
+ const isReady = !isPending && !!order;
12853
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
12854
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
12855
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Shipping Address" }) }),
12856
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
12857
+ ] }),
12858
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(ShippingAddressForm, { order })
12859
+ ] });
12860
+ };
12861
+ const ShippingAddressForm = ({ order }) => {
12862
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12863
+ const form = reactHookForm.useForm({
12864
+ defaultValues: {
12865
+ first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
12866
+ last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
12867
+ company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
12868
+ address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
12869
+ address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
12870
+ city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
12871
+ province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
12872
+ country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
12873
+ postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12874
+ phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12875
+ },
12876
+ resolver: zod.zodResolver(schema)
12877
+ });
12878
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12879
+ const { handleSuccess } = useRouteModal();
12880
+ const onSubmit = form.handleSubmit(async (data) => {
12881
+ await mutateAsync(
12882
+ {
12883
+ shipping_address: {
12884
+ first_name: data.first_name,
12885
+ last_name: data.last_name,
12886
+ company: data.company,
12887
+ address_1: data.address_1,
12888
+ address_2: data.address_2,
12889
+ city: data.city,
12890
+ province: data.province,
12891
+ country_code: data.country_code,
12892
+ postal_code: data.postal_code,
12893
+ phone: data.phone
12894
+ }
12895
+ },
12896
+ {
12897
+ onSuccess: () => {
12898
+ handleSuccess();
12899
+ },
12900
+ onError: (error) => {
12901
+ ui.toast.error(error.message);
12902
+ }
12903
+ }
12904
+ );
12905
+ });
12906
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12907
+ KeyboundForm,
12908
+ {
12909
+ className: "flex flex-1 flex-col overflow-hidden",
12910
+ onSubmit,
12911
+ children: [
12912
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-4", children: [
12913
+ /* @__PURE__ */ jsxRuntime.jsx(
12914
+ Form$2.Field,
12915
+ {
12916
+ control: form.control,
12917
+ name: "country_code",
12918
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12919
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Country" }),
12920
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(CountrySelect, { ...field }) }),
12921
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12922
+ ] })
12923
+ }
12924
+ ),
12925
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12926
+ /* @__PURE__ */ jsxRuntime.jsx(
12927
+ Form$2.Field,
12928
+ {
12929
+ control: form.control,
12930
+ name: "first_name",
12931
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12932
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "First name" }),
12933
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12934
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12935
+ ] })
12936
+ }
12937
+ ),
12938
+ /* @__PURE__ */ jsxRuntime.jsx(
12939
+ Form$2.Field,
12940
+ {
12941
+ control: form.control,
12942
+ name: "last_name",
12943
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12944
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Last name" }),
12945
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12946
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12947
+ ] })
12948
+ }
12949
+ )
12950
+ ] }),
12951
+ /* @__PURE__ */ jsxRuntime.jsx(
12952
+ Form$2.Field,
12953
+ {
12954
+ control: form.control,
12955
+ name: "company",
12956
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12957
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Company" }),
12958
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12959
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12960
+ ] })
12961
+ }
12962
+ ),
12963
+ /* @__PURE__ */ jsxRuntime.jsx(
12964
+ Form$2.Field,
12965
+ {
12966
+ control: form.control,
12967
+ name: "address_1",
12968
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12969
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Address" }),
12970
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12971
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12972
+ ] })
12973
+ }
12974
+ ),
12975
+ /* @__PURE__ */ jsxRuntime.jsx(
12976
+ Form$2.Field,
12977
+ {
12978
+ control: form.control,
12979
+ name: "address_2",
12980
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12981
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12982
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12983
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12984
+ ] })
12985
+ }
12986
+ ),
12987
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12988
+ /* @__PURE__ */ jsxRuntime.jsx(
12989
+ Form$2.Field,
12990
+ {
12991
+ control: form.control,
12992
+ name: "postal_code",
12993
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12994
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Postal code" }),
12995
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12996
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12997
+ ] })
12998
+ }
12999
+ ),
13000
+ /* @__PURE__ */ jsxRuntime.jsx(
13001
+ Form$2.Field,
13002
+ {
13003
+ control: form.control,
13004
+ name: "city",
13005
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
13006
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "City" }),
13007
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
13008
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
13009
+ ] })
13010
+ }
13011
+ )
13012
+ ] }),
13013
+ /* @__PURE__ */ jsxRuntime.jsx(
13014
+ Form$2.Field,
13015
+ {
13016
+ control: form.control,
13017
+ name: "province",
13018
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
13019
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Province / State" }),
13020
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
13021
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
13022
+ ] })
13023
+ }
13024
+ ),
13025
+ /* @__PURE__ */ jsxRuntime.jsx(
13026
+ Form$2.Field,
13027
+ {
13028
+ control: form.control,
13029
+ name: "phone",
13030
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
13031
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Phone" }),
13032
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
13033
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
13034
+ ] })
13035
+ }
13036
+ )
13037
+ ] }) }),
13038
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
13039
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
13040
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
13041
+ ] }) })
13042
+ ]
13043
+ }
13044
+ ) });
13045
+ };
13046
+ const schema = addressSchema;
13047
13047
  const widgetModule = { widgets: [] };
13048
13048
  const routeModule = {
13049
13049
  routes: [
@@ -13068,13 +13068,17 @@ const routeModule = {
13068
13068
  Component: BillingAddress,
13069
13069
  path: "/draft-orders/:id/billing-address"
13070
13070
  },
13071
+ {
13072
+ Component: Email,
13073
+ path: "/draft-orders/:id/email"
13074
+ },
13071
13075
  {
13072
13076
  Component: CustomItems,
13073
13077
  path: "/draft-orders/:id/custom-items"
13074
13078
  },
13075
13079
  {
13076
- Component: Email,
13077
- path: "/draft-orders/:id/email"
13080
+ Component: Items,
13081
+ path: "/draft-orders/:id/items"
13078
13082
  },
13079
13083
  {
13080
13084
  Component: Promotions,
@@ -13084,10 +13088,6 @@ const routeModule = {
13084
13088
  Component: Metadata,
13085
13089
  path: "/draft-orders/:id/metadata"
13086
13090
  },
13087
- {
13088
- Component: Items,
13089
- path: "/draft-orders/:id/items"
13090
- },
13091
13091
  {
13092
13092
  Component: SalesChannel,
13093
13093
  path: "/draft-orders/:id/sales-channel"
@@ -13096,13 +13096,13 @@ const routeModule = {
13096
13096
  Component: Shipping,
13097
13097
  path: "/draft-orders/:id/shipping"
13098
13098
  },
13099
- {
13100
- Component: ShippingAddress,
13101
- path: "/draft-orders/:id/shipping-address"
13102
- },
13103
13099
  {
13104
13100
  Component: TransferOwnership,
13105
13101
  path: "/draft-orders/:id/transfer-ownership"
13102
+ },
13103
+ {
13104
+ Component: ShippingAddress,
13105
+ path: "/draft-orders/:id/shipping-address"
13106
13106
  }
13107
13107
  ]
13108
13108
  }