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

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,886 +10102,322 @@ 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." })
10421
- ] }),
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 [
10458
- {
10459
- key: "",
10460
- value: "",
10461
- disabled: false
10462
- }
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
- };
10482
- });
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) {
10496
- return;
10497
- }
10498
- if (disabled) {
10499
- update[key] = value;
10500
- return;
10501
- }
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
- }
10515
- }
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);
10549
- }
10550
- };
10551
- const handleDecrement = () => {
10552
- const newValue = value - step;
10553
- if (min === void 0 || newValue >= min) {
10554
- onChange(newValue);
10555
- }
10556
- };
10557
- return /* @__PURE__ */ jsxRuntime.jsxs(
10558
- "div",
10559
- {
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",
10612
- {
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
- ]
10630
- }
10631
- )
10632
- ]
10633
- }
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
- ]
10643
- };
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 };
10651
- };
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,
10669
- {
10670
- fields: "currency_code"
10671
- },
10672
- {
10673
- enabled: !!id
10674
- }
10675
- );
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]);
10705
- 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();
10726
- },
10727
- onSettled: () => {
10728
- setIsSubmitting(false);
10729
- }
10730
- });
10731
- };
10732
- const onKeyDown = React.useCallback(
10733
- (e) => {
10734
- if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10735
- if (modalContent || isSubmitting) {
10736
- return;
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
+ )
10335
+ ] }),
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,
10349
+ {
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 }) }) });
10737
10354
  }
10738
- onSubmit();
10739
10355
  }
10740
- },
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,
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,
10753
10359
  {
10754
- id: STACKED_MODAL_ID,
10755
- onOpenChangeCallback: (open) => {
10756
- if (!open) {
10757
- setModalContent(null);
10758
- }
10759
- },
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: [
10762
- /* @__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" }) })
10765
- ] }),
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
- ] })
10831
- ] }),
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,
10837
- {
10838
- size: "small",
10839
- leading: "compact",
10840
- className: "text-ui-fg-subtle",
10841
- children: [
10842
- itemCount,
10843
- " ",
10844
- itemCount === 1 ? "item" : "items"
10845
- ]
10846
- }
10847
- ) }),
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) }) })
10849
- ] })
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,
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,
10853
10365
  {
10854
- orderId: preview.id,
10855
- currencyCode
10366
+ ...field,
10367
+ symbol: getNativeSymbol(currencyCode),
10368
+ code: currencyCode,
10369
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10856
10370
  }
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" }) }),
10863
- /* @__PURE__ */ jsxRuntime.jsx(
10864
- ui.Button,
10865
- {
10866
- size: "small",
10867
- type: "button",
10868
- onClick: onSubmit,
10869
- isLoading: isSubmitting,
10870
- children: "Save"
10371
+ ) }) });
10871
10372
  }
10872
- )
10873
- ] }) })
10874
- ] });
10875
- };
10876
- const Item = ({ item, preview, currencyCode }) => {
10877
- if (item.variant_id) {
10878
- return /* @__PURE__ */ jsxRuntime.jsx(VariantItem, { item, preview, currencyCode });
10879
- }
10880
- return /* @__PURE__ */ jsxRuntime.jsx(CustomItem, { item, preview, currencyCode });
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
+ ] }) }) });
10881
10388
  };
10882
- const VariantItem = ({ item, preview, currencyCode }) => {
10389
+ const variantItemSchema = objectType({
10390
+ quantity: numberType(),
10391
+ unit_price: unionType([numberType(), stringType()])
10392
+ });
10393
+ const CustomItem = ({ item, preview, currencyCode }) => {
10883
10394
  const [editing, setEditing] = React.useState(false);
10395
+ const { quantity, unit_price, title } = item;
10884
10396
  const form = reactHookForm.useForm({
10885
10397
  defaultValues: {
10886
- quantity: item.quantity,
10887
- unit_price: item.unit_price
10398
+ title,
10399
+ quantity,
10400
+ unit_price
10888
10401
  },
10889
- resolver: zod.zodResolver(variantItemSchema)
10402
+ resolver: zod.zodResolver(customItemSchema)
10890
10403
  });
10404
+ React.useEffect(() => {
10405
+ form.reset({
10406
+ title,
10407
+ quantity,
10408
+ unit_price
10409
+ });
10410
+ }, [form, title, quantity, unit_price]);
10891
10411
  const actionId = React.useMemo(() => {
10892
10412
  var _a, _b;
10893
10413
  return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10894
10414
  }, [item]);
10895
10415
  const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10416
+ const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10896
10417
  const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10897
10418
  const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10898
10419
  const onSubmit = form.handleSubmit(async (data) => {
10899
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10420
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10900
10421
  setEditing(false);
10901
10422
  return;
10902
10423
  }
@@ -10918,6 +10439,17 @@ const VariantItem = ({ item, preview, currencyCode }) => {
10918
10439
  );
10919
10440
  return;
10920
10441
  }
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;
10452
+ }
10921
10453
  await updateActionItem(
10922
10454
  {
10923
10455
  action_id: actionId,
@@ -10935,43 +10467,26 @@ const VariantItem = ({ item, preview, currencyCode }) => {
10935
10467
  );
10936
10468
  });
10937
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: [
10938
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center gap-x-3", children: [
10470
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
10939
10471
  /* @__PURE__ */ jsxRuntime.jsx(
10940
10472
  Thumbnail,
10941
10473
  {
10942
10474
  thumbnail: item.thumbnail,
10943
- alt: item.product_title ?? void 0
10475
+ alt: item.title ?? void 0
10944
10476
  }
10945
10477
  ),
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
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 }) }) });
10970
10485
  }
10971
- )
10972
- ] })
10486
+ }
10487
+ ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.title })
10973
10488
  ] }),
10974
- editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10489
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
10975
10490
  Form$2.Field,
10976
10491
  {
10977
10492
  control: form.control,
@@ -10980,8 +10495,8 @@ const VariantItem = ({ item, preview, currencyCode }) => {
10980
10495
  return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10981
10496
  }
10982
10497
  }
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(
10498
+ ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }),
10499
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
10985
10500
  Form$2.Field,
10986
10501
  {
10987
10502
  control: form.control,
@@ -10990,102 +10505,238 @@ const VariantItem = ({ item, preview, currencyCode }) => {
10990
10505
  return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10991
10506
  ui.CurrencyInput,
10992
10507
  {
10993
- ...field,
10994
- symbol: getNativeSymbol(currencyCode),
10995
- code: currencyCode,
10996
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10508
+ ...field,
10509
+ symbol: getNativeSymbol(currencyCode),
10510
+ code: currencyCode,
10511
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10512
+ }
10513
+ ) }) });
10514
+ }
10515
+ }
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
+ ] }) }) });
10530
+ };
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" }) });
10541
+ };
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(
10567
+ {
10568
+ q,
10569
+ order,
10570
+ offset: offset ? parseInt(offset) : void 0,
10571
+ limit: LIMIT
10572
+ },
10573
+ {
10574
+ placeholderData: reactQuery.keepPreviousData
10575
+ }
10576
+ );
10577
+ const columns = useColumns();
10578
+ const { mutateAsync } = useDraftOrderAddItems(orderId);
10579
+ const onSubmit = async () => {
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
+ }))
10589
+ },
10590
+ {
10591
+ onSuccess: () => {
10592
+ setRowSelection({});
10593
+ setIsOpen(STACKED_MODAL_ID, false);
10594
+ },
10595
+ onError: (e) => {
10596
+ ui.toast.error(e.message);
10597
+ }
10598
+ }
10599
+ );
10600
+ };
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();
10614
+ }
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() }) })
10997
10705
  }
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);
10706
+ );
11009
10707
  },
11010
- disabled: isPending,
11011
- children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
11012
- }
11013
- )
11014
- ] }) }) });
10708
+ enableSorting: true,
10709
+ sortAscLabel: "Oldest first",
10710
+ sortDescLabel: "Newest first"
10711
+ })
10712
+ ];
10713
+ }, []);
11015
10714
  };
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;
10715
+ const CustomItemForm = ({ orderId, currencyCode }) => {
10716
+ const { setIsOpen } = useStackedModal();
10717
+ const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
11023
10718
  const form = reactHookForm.useForm({
11024
10719
  defaultValues: {
11025
- title,
11026
- quantity,
11027
- unit_price
10720
+ title: "",
10721
+ quantity: 1,
10722
+ unit_price: ""
11028
10723
  },
11029
10724
  resolver: zod.zodResolver(customItemSchema)
11030
10725
  });
11031
- React.useEffect(() => {
11032
- form.reset({
11033
- title,
11034
- quantity,
11035
- unit_price
11036
- });
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
10726
  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);
11049
- return;
11050
- }
11051
- if (!actionId) {
11052
- await updateOriginalItem(
11053
- {
11054
- item_id: item.id,
11055
- quantity: data.quantity,
11056
- unit_price: convertNumber(data.unit_price)
11057
- },
11058
- {
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);
11076
- }
11077
- });
11078
- return;
11079
- }
11080
- await updateActionItem(
10727
+ await addItems(
11081
10728
  {
11082
- action_id: actionId,
11083
- quantity: data.quantity,
11084
- unit_price: convertNumber(data.unit_price)
10729
+ items: [
10730
+ {
10731
+ title: data.title,
10732
+ quantity: data.quantity,
10733
+ unit_price: convertNumber(data.unit_price)
10734
+ }
10735
+ ]
11085
10736
  },
11086
10737
  {
11087
10738
  onSuccess: () => {
11088
- setEditing(false);
10739
+ setIsOpen(STACKED_MODAL_ID, false);
11089
10740
  },
11090
10741
  onError: (e) => {
11091
10742
  ui.toast.error(e.message);
@@ -11093,365 +10744,714 @@ const CustomItem = ({ item, preview, currencyCode }) => {
11093
10744
  }
11094
10745
  );
11095
10746
  });
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: [
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" }),
11098
10755
  /* @__PURE__ */ jsxRuntime.jsx(
11099
- Thumbnail,
10756
+ Form$2.Field,
11100
10757
  {
11101
- thumbnail: item.thumbnail,
11102
- alt: item.title ?? void 0
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: [
10761
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10762
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Title" }),
10763
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the title of the item" })
10764
+ ] }),
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
+ ] }) })
11103
10770
  }
11104
10771
  ),
11105
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
10772
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10773
+ /* @__PURE__ */ jsxRuntime.jsx(
11106
10774
  Form$2.Field,
11107
10775
  {
11108
10776
  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 }) }) });
11112
- }
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" })
10782
+ ] }),
10783
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10784
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10785
+ ui.CurrencyInput,
10786
+ {
10787
+ symbol: getNativeSymbol(currencyCode),
10788
+ code: currencyCode,
10789
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
10790
+ ...field
10791
+ }
10792
+ ) }),
10793
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10794
+ ] })
10795
+ ] }) })
11113
10796
  }
11114
- ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.title })
10797
+ ),
10798
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10799
+ /* @__PURE__ */ jsxRuntime.jsx(
10800
+ Form$2.Field,
10801
+ {
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
+ ] }) })
10814
+ }
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" })
10820
+ ] }) })
10821
+ ] }) }) });
10822
+ };
10823
+ const customItemSchema = objectType({
10824
+ title: stringType().min(1),
10825
+ quantity: numberType(),
10826
+ unit_price: unionType([numberType(), stringType()])
10827
+ });
10828
+ const InlineTip = React.forwardRef(
10829
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
10830
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10831
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10832
+ "div",
10833
+ {
10834
+ ref,
10835
+ className: ui.clx(
10836
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10837
+ className
10838
+ ),
10839
+ ...props,
10840
+ children: [
10841
+ /* @__PURE__ */ jsxRuntime.jsx(
10842
+ "div",
10843
+ {
10844
+ role: "presentation",
10845
+ className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10846
+ "bg-ui-tag-orange-icon": variant === "warning"
10847
+ })
10848
+ }
10849
+ ),
10850
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
10851
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10852
+ labelValue,
10853
+ ":"
10854
+ ] }),
10855
+ " ",
10856
+ children
10857
+ ] })
10858
+ ]
10859
+ }
10860
+ );
10861
+ }
10862
+ );
10863
+ InlineTip.displayName = "InlineTip";
10864
+ const MetadataFieldSchema = objectType({
10865
+ key: stringType(),
10866
+ disabled: booleanType().optional(),
10867
+ value: anyType()
10868
+ });
10869
+ const MetadataSchema = objectType({
10870
+ metadata: arrayType(MetadataFieldSchema)
10871
+ });
10872
+ const Metadata = () => {
10873
+ const { id } = reactRouterDom.useParams();
10874
+ const { order, isPending, isError, error } = useOrder(id, {
10875
+ fields: "metadata"
10876
+ });
10877
+ if (isError) {
10878
+ throw error;
10879
+ }
10880
+ const isReady = !isPending && !!order;
10881
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10882
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10883
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
10884
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
11115
10885
  ] }),
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,
10886
+ !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10887
+ ] });
10888
+ };
10889
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10890
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10891
+ const MetadataForm = ({ orderId, metadata }) => {
10892
+ const { handleSuccess } = useRouteModal();
10893
+ const hasUneditableRows = getHasUneditableRows(metadata);
10894
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10895
+ const form = reactHookForm.useForm({
10896
+ defaultValues: {
10897
+ metadata: getDefaultValues(metadata)
10898
+ },
10899
+ resolver: zod.zodResolver(MetadataSchema)
10900
+ });
10901
+ const handleSubmit = form.handleSubmit(async (data) => {
10902
+ const parsedData = parseValues(data);
10903
+ await mutateAsync(
11128
10904
  {
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,
10905
+ metadata: parsedData
10906
+ },
11146
10907
  {
11147
- type: "button",
11148
- size: "small",
11149
- onClick: editing ? onSubmit : () => {
11150
- setEditing(true);
10908
+ onSuccess: () => {
10909
+ ui.toast.success("Metadata updated");
10910
+ handleSuccess();
11151
10911
  },
11152
- disabled: isPending,
11153
- children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
11154
- }
11155
- )
11156
- ] }) }) });
11157
- };
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" }) });
11168
- };
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;
10912
+ onError: (error) => {
10913
+ ui.toast.error(error.message);
11184
10914
  }
11185
- return acc;
11186
- }, {})
10915
+ }
11187
10916
  );
11188
- }, [items]);
11189
- const { q, order, offset } = useQueryParams(
11190
- ["q", "order", "offset"],
11191
- VARIANT_PREFIX
11192
- );
11193
- const { variants, count, isPending, isError, error } = useProductVariants(
10917
+ });
10918
+ const { fields, insert, remove } = reactHookForm.useFieldArray({
10919
+ control: form.control,
10920
+ name: "metadata"
10921
+ });
10922
+ function deleteRow(index) {
10923
+ remove(index);
10924
+ if (fields.length === 1) {
10925
+ insert(0, {
10926
+ key: "",
10927
+ value: "",
10928
+ disabled: false
10929
+ });
10930
+ }
10931
+ }
10932
+ function insertRow(index, position) {
10933
+ insert(index + (position === "above" ? 0 : 1), {
10934
+ key: "",
10935
+ value: "",
10936
+ disabled: false
10937
+ });
10938
+ }
10939
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
10940
+ KeyboundForm,
11194
10941
  {
11195
- q,
11196
- order,
11197
- offset: offset ? parseInt(offset) : void 0,
11198
- limit: LIMIT
11199
- },
10942
+ onSubmit: handleSubmit,
10943
+ className: "flex flex-1 flex-col overflow-hidden",
10944
+ children: [
10945
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10946
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10947
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10948
+ /* @__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" }) }),
10949
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
10950
+ ] }),
10951
+ fields.map((field, index) => {
10952
+ const isDisabled = field.disabled || false;
10953
+ let placeholder = "-";
10954
+ if (typeof field.value === "object") {
10955
+ placeholder = "{ ... }";
10956
+ }
10957
+ if (Array.isArray(field.value)) {
10958
+ placeholder = "[ ... ]";
10959
+ }
10960
+ return /* @__PURE__ */ jsxRuntime.jsx(
10961
+ ConditionalTooltip,
10962
+ {
10963
+ showTooltip: isDisabled,
10964
+ content: "This row is disabled because it contains non-primitive data.",
10965
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
10966
+ /* @__PURE__ */ jsxRuntime.jsxs(
10967
+ "div",
10968
+ {
10969
+ className: ui.clx("grid grid-cols-2 divide-x", {
10970
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
10971
+ }),
10972
+ children: [
10973
+ /* @__PURE__ */ jsxRuntime.jsx(
10974
+ Form$2.Field,
10975
+ {
10976
+ control: form.control,
10977
+ name: `metadata.${index}.key`,
10978
+ render: ({ field: field2 }) => {
10979
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10980
+ GridInput,
10981
+ {
10982
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
10983
+ ...field2,
10984
+ disabled: isDisabled,
10985
+ placeholder: "Key"
10986
+ }
10987
+ ) }) });
10988
+ }
10989
+ }
10990
+ ),
10991
+ /* @__PURE__ */ jsxRuntime.jsx(
10992
+ Form$2.Field,
10993
+ {
10994
+ control: form.control,
10995
+ name: `metadata.${index}.value`,
10996
+ render: ({ field: { value, ...field2 } }) => {
10997
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10998
+ GridInput,
10999
+ {
11000
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
11001
+ ...field2,
11002
+ value: isDisabled ? placeholder : value,
11003
+ disabled: isDisabled,
11004
+ placeholder: "Value"
11005
+ }
11006
+ ) }) });
11007
+ }
11008
+ }
11009
+ )
11010
+ ]
11011
+ }
11012
+ ),
11013
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
11014
+ /* @__PURE__ */ jsxRuntime.jsx(
11015
+ ui.DropdownMenu.Trigger,
11016
+ {
11017
+ className: ui.clx(
11018
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
11019
+ {
11020
+ hidden: isDisabled
11021
+ }
11022
+ ),
11023
+ disabled: isDisabled,
11024
+ asChild: true,
11025
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
11026
+ }
11027
+ ),
11028
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
11029
+ /* @__PURE__ */ jsxRuntime.jsxs(
11030
+ ui.DropdownMenu.Item,
11031
+ {
11032
+ className: "gap-x-2",
11033
+ onClick: () => insertRow(index, "above"),
11034
+ children: [
11035
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
11036
+ "Insert row above"
11037
+ ]
11038
+ }
11039
+ ),
11040
+ /* @__PURE__ */ jsxRuntime.jsxs(
11041
+ ui.DropdownMenu.Item,
11042
+ {
11043
+ className: "gap-x-2",
11044
+ onClick: () => insertRow(index, "below"),
11045
+ children: [
11046
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
11047
+ "Insert row below"
11048
+ ]
11049
+ }
11050
+ ),
11051
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
11052
+ /* @__PURE__ */ jsxRuntime.jsxs(
11053
+ ui.DropdownMenu.Item,
11054
+ {
11055
+ className: "gap-x-2",
11056
+ onClick: () => deleteRow(index),
11057
+ children: [
11058
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
11059
+ "Delete row"
11060
+ ]
11061
+ }
11062
+ )
11063
+ ] })
11064
+ ] })
11065
+ ] })
11066
+ },
11067
+ field.id
11068
+ );
11069
+ })
11070
+ ] }),
11071
+ 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." })
11072
+ ] }),
11073
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11074
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11075
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11076
+ ] }) })
11077
+ ]
11078
+ }
11079
+ ) });
11080
+ };
11081
+ const GridInput = React.forwardRef(({ className, ...props }, ref) => {
11082
+ return /* @__PURE__ */ jsxRuntime.jsx(
11083
+ "input",
11200
11084
  {
11201
- placeholderData: reactQuery.keepPreviousData
11085
+ ref,
11086
+ ...props,
11087
+ autoComplete: "off",
11088
+ className: ui.clx(
11089
+ "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",
11090
+ className
11091
+ )
11202
11092
  }
11203
11093
  );
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)
11209
- );
11210
- await mutateAsync(
11211
- {
11212
- items: ids.map((id) => ({
11213
- variant_id: id,
11214
- quantity: 1
11215
- }))
11216
- },
11094
+ });
11095
+ GridInput.displayName = "MetadataForm.GridInput";
11096
+ const PlaceholderInner = () => {
11097
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11098
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11099
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11100
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
11101
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
11102
+ ] }) })
11103
+ ] });
11104
+ };
11105
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
11106
+ function getDefaultValues(metadata) {
11107
+ if (!metadata || !Object.keys(metadata).length) {
11108
+ return [
11217
11109
  {
11218
- onSuccess: () => {
11219
- setRowSelection({});
11220
- setIsOpen(STACKED_MODAL_ID, false);
11221
- },
11222
- onError: (e) => {
11223
- ui.toast.error(e.message);
11224
- }
11110
+ key: "",
11111
+ value: "",
11112
+ disabled: false
11225
11113
  }
11226
- );
11227
- };
11228
- if (isError) {
11229
- throw error;
11114
+ ];
11230
11115
  }
11231
- return /* @__PURE__ */ jsxRuntime.jsxs(
11232
- StackedFocusModal.Content,
11233
- {
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
- },
11243
- 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." }) })
11247
- ] }),
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" })
11271
- ] }) })
11272
- ]
11116
+ return Object.entries(metadata).map(([key, value]) => {
11117
+ if (!EDITABLE_TYPES.includes(typeof value)) {
11118
+ return {
11119
+ key,
11120
+ value,
11121
+ disabled: true
11122
+ };
11123
+ }
11124
+ let stringValue = value;
11125
+ if (typeof value !== "string") {
11126
+ stringValue = JSON.stringify(value);
11127
+ }
11128
+ return {
11129
+ key,
11130
+ value: stringValue,
11131
+ original_key: key
11132
+ };
11133
+ });
11134
+ }
11135
+ function parseValues(values) {
11136
+ const metadata = values.metadata;
11137
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11138
+ if (isEmpty) {
11139
+ return null;
11140
+ }
11141
+ const update = {};
11142
+ metadata.forEach((field) => {
11143
+ let key = field.key;
11144
+ let value = field.value;
11145
+ const disabled = field.disabled;
11146
+ if (!key || !value) {
11147
+ return;
11148
+ }
11149
+ if (disabled) {
11150
+ update[key] = value;
11151
+ return;
11152
+ }
11153
+ key = key.trim();
11154
+ value = value.trim();
11155
+ if (value === "true") {
11156
+ update[key] = true;
11157
+ } else if (value === "false") {
11158
+ update[key] = false;
11159
+ } else {
11160
+ const parsedNumber = parseFloat(value);
11161
+ if (!isNaN(parsedNumber)) {
11162
+ update[key] = parsedNumber;
11163
+ } else {
11164
+ update[key] = value;
11165
+ }
11273
11166
  }
11167
+ });
11168
+ return update;
11169
+ }
11170
+ function getHasUneditableRows(metadata) {
11171
+ if (!metadata) {
11172
+ return false;
11173
+ }
11174
+ return Object.values(metadata).some(
11175
+ (value) => !EDITABLE_TYPES.includes(typeof value)
11274
11176
  );
11177
+ }
11178
+ const PROMOTION_QUERY_KEY = "promotions";
11179
+ const promotionsQueryKeys = {
11180
+ list: (query2) => [
11181
+ PROMOTION_QUERY_KEY,
11182
+ query2 ? query2 : void 0
11183
+ ],
11184
+ detail: (id, query2) => [
11185
+ PROMOTION_QUERY_KEY,
11186
+ id,
11187
+ query2 ? query2 : void 0
11188
+ ]
11275
11189
  };
11276
- const columnHelper = ui.createDataTableColumnHelper();
11277
- const useColumns = () => {
11278
- return React.useMemo(() => {
11279
- 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
- }, []);
11190
+ const usePromotions = (query2, options) => {
11191
+ const { data, ...rest } = reactQuery.useQuery({
11192
+ queryKey: promotionsQueryKeys.list(query2),
11193
+ queryFn: async () => sdk.admin.promotion.list(query2),
11194
+ ...options
11195
+ });
11196
+ return { ...data, ...rest };
11197
+ };
11198
+ const Promotions = () => {
11199
+ const { id } = reactRouterDom.useParams();
11200
+ const {
11201
+ order: preview,
11202
+ isError: isPreviewError,
11203
+ error: previewError
11204
+ } = useOrderPreview(id, void 0);
11205
+ useInitiateOrderEdit({ preview });
11206
+ const { onCancel } = useCancelOrderEdit({ preview });
11207
+ if (isPreviewError) {
11208
+ throw previewError;
11209
+ }
11210
+ const isReady = !!preview;
11211
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
11212
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
11213
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
11214
+ ] });
11341
11215
  };
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: ""
11216
+ const PromotionForm = ({ preview }) => {
11217
+ const { items, shipping_methods } = preview;
11218
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
11219
+ const [comboboxValue, setComboboxValue] = React.useState("");
11220
+ const { handleSuccess } = useRouteModal();
11221
+ const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
11222
+ const promoIds = getPromotionIds(items, shipping_methods);
11223
+ const { promotions, isPending, isError, error } = usePromotions(
11224
+ {
11225
+ id: promoIds
11350
11226
  },
11351
- resolver: zod.zodResolver(customItemSchema)
11227
+ {
11228
+ enabled: !!promoIds.length
11229
+ }
11230
+ );
11231
+ const comboboxData = useComboboxData({
11232
+ queryKey: ["promotions", "combobox", promoIds],
11233
+ queryFn: async (params) => {
11234
+ return await sdk.admin.promotion.list({
11235
+ ...params,
11236
+ id: {
11237
+ $nin: promoIds
11238
+ }
11239
+ });
11240
+ },
11241
+ getOptions: (data) => {
11242
+ return data.promotions.map((promotion) => ({
11243
+ label: promotion.code,
11244
+ value: promotion.code
11245
+ }));
11246
+ }
11352
11247
  });
11353
- const onSubmit = form.handleSubmit(async (data) => {
11354
- await addItems(
11248
+ const add = async (value) => {
11249
+ if (!value) {
11250
+ return;
11251
+ }
11252
+ addPromotions(
11355
11253
  {
11356
- items: [
11357
- {
11358
- title: data.title,
11359
- quantity: data.quantity,
11360
- unit_price: convertNumber(data.unit_price)
11361
- }
11362
- ]
11254
+ promo_codes: [value]
11363
11255
  },
11364
11256
  {
11365
- onSuccess: () => {
11366
- setIsOpen(STACKED_MODAL_ID, false);
11367
- },
11368
11257
  onError: (e) => {
11369
11258
  ui.toast.error(e.message);
11259
+ comboboxData.onSearchValueChange("");
11260
+ setComboboxValue("");
11261
+ },
11262
+ onSuccess: () => {
11263
+ comboboxData.onSearchValueChange("");
11264
+ setComboboxValue("");
11370
11265
  }
11371
11266
  }
11372
11267
  );
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." }) })
11268
+ };
11269
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11270
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
11271
+ const onSubmit = async () => {
11272
+ setIsSubmitting(true);
11273
+ let requestSucceeded = false;
11274
+ await requestOrderEdit(void 0, {
11275
+ onError: (e) => {
11276
+ ui.toast.error(e.message);
11277
+ },
11278
+ onSuccess: () => {
11279
+ requestSucceeded = true;
11280
+ }
11281
+ });
11282
+ if (!requestSucceeded) {
11283
+ setIsSubmitting(false);
11284
+ return;
11285
+ }
11286
+ await confirmOrderEdit(void 0, {
11287
+ onError: (e) => {
11288
+ ui.toast.error(e.message);
11289
+ },
11290
+ onSuccess: () => {
11291
+ handleSuccess();
11292
+ },
11293
+ onSettled: () => {
11294
+ setIsSubmitting(false);
11295
+ }
11296
+ });
11297
+ };
11298
+ if (isError) {
11299
+ throw error;
11300
+ }
11301
+ return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
11302
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
11303
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
11304
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
11305
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
11306
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
11307
+ ] }),
11308
+ /* @__PURE__ */ jsxRuntime.jsx(
11309
+ Combobox,
11310
+ {
11311
+ id: "promotion-combobox",
11312
+ "aria-describedby": "promotion-combobox-hint",
11313
+ isFetchingNextPage: comboboxData.isFetchingNextPage,
11314
+ fetchNextPage: comboboxData.fetchNextPage,
11315
+ options: comboboxData.options,
11316
+ onSearchValueChange: comboboxData.onSearchValueChange,
11317
+ searchValue: comboboxData.searchValue,
11318
+ disabled: comboboxData.disabled || isAddingPromotions,
11319
+ onChange: add,
11320
+ value: comboboxValue
11321
+ }
11322
+ )
11380
11323
  ] }),
11381
11324
  /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11325
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
11326
+ PromotionItem,
11327
+ {
11328
+ promotion,
11329
+ orderId: preview.id,
11330
+ isLoading: isPending
11331
+ },
11332
+ promotion.id
11333
+ )) })
11334
+ ] }) }),
11335
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11336
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11382
11337
  /* @__PURE__ */ jsxRuntime.jsx(
11383
- Form$2.Field,
11338
+ ui.Button,
11384
11339
  {
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
- ] }) })
11340
+ size: "small",
11341
+ type: "submit",
11342
+ isLoading: isSubmitting || isAddingPromotions,
11343
+ children: "Save"
11397
11344
  }
11398
- ),
11399
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11400
- /* @__PURE__ */ jsxRuntime.jsx(
11401
- Form$2.Field,
11345
+ )
11346
+ ] }) })
11347
+ ] });
11348
+ };
11349
+ const PromotionItem = ({
11350
+ promotion,
11351
+ orderId,
11352
+ isLoading
11353
+ }) => {
11354
+ var _a;
11355
+ const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
11356
+ const onRemove = async () => {
11357
+ removePromotions(
11358
+ {
11359
+ promo_codes: [promotion.code]
11360
+ },
11361
+ {
11362
+ onError: (e) => {
11363
+ ui.toast.error(e.message);
11364
+ }
11365
+ }
11366
+ );
11367
+ };
11368
+ const displayValue = getDisplayValue(promotion);
11369
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11370
+ "div",
11371
+ {
11372
+ className: ui.clx(
11373
+ "bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between rounded-lg px-3 py-2",
11402
11374
  {
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
- ] }) })
11375
+ "animate-pulse": isLoading
11423
11376
  }
11424
11377
  ),
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" })
11378
+ children: [
11379
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11380
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11381
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-ui-fg-subtle flex items-center gap-1.5", children: [
11382
+ displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
11383
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
11384
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
11435
11385
  ] }),
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
- ] }) }) });
11386
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11387
+ ] })
11388
+ ] }),
11389
+ /* @__PURE__ */ jsxRuntime.jsx(
11390
+ ui.IconButton,
11391
+ {
11392
+ size: "small",
11393
+ type: "button",
11394
+ variant: "transparent",
11395
+ onClick: onRemove,
11396
+ isLoading: isPending || isLoading,
11397
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
11398
+ }
11399
+ )
11400
+ ]
11401
+ },
11402
+ promotion.id
11403
+ );
11449
11404
  };
11450
- const customItemSchema = objectType({
11451
- title: stringType().min(1),
11452
- quantity: numberType(),
11453
- unit_price: unionType([numberType(), stringType()])
11405
+ function getDisplayValue(promotion) {
11406
+ var _a, _b, _c, _d;
11407
+ const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11408
+ if (!value) {
11409
+ return null;
11410
+ }
11411
+ if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11412
+ const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11413
+ if (!currency) {
11414
+ return null;
11415
+ }
11416
+ return getLocaleAmount(value, currency);
11417
+ } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11418
+ return formatPercentage(value);
11419
+ }
11420
+ return null;
11421
+ }
11422
+ const formatter = new Intl.NumberFormat([], {
11423
+ style: "percent",
11424
+ minimumFractionDigits: 2
11454
11425
  });
11426
+ const formatPercentage = (value, isPercentageValue = false) => {
11427
+ let val = value || 0;
11428
+ if (!isPercentageValue) {
11429
+ val = val / 100;
11430
+ }
11431
+ return formatter.format(val);
11432
+ };
11433
+ function getPromotionIds(items, shippingMethods) {
11434
+ const promotionIds = /* @__PURE__ */ new Set();
11435
+ for (const item of items) {
11436
+ if (item.adjustments) {
11437
+ for (const adjustment of item.adjustments) {
11438
+ if (adjustment.promotion_id) {
11439
+ promotionIds.add(adjustment.promotion_id);
11440
+ }
11441
+ }
11442
+ }
11443
+ }
11444
+ for (const shippingMethod of shippingMethods) {
11445
+ if (shippingMethod.adjustments) {
11446
+ for (const adjustment of shippingMethod.adjustments) {
11447
+ if (adjustment.promotion_id) {
11448
+ promotionIds.add(adjustment.promotion_id);
11449
+ }
11450
+ }
11451
+ }
11452
+ }
11453
+ return Array.from(promotionIds);
11454
+ }
11455
11455
  const SalesChannel = () => {
11456
11456
  const { id } = reactRouterDom.useParams();
11457
11457
  const { draft_order, isPending, isError, error } = useDraftOrder(
@@ -11548,16 +11548,219 @@ const SalesChannelField = ({ control, order }) => {
11548
11548
  placeholder: "Select sales channel",
11549
11549
  ...field
11550
11550
  }
11551
- ) }),
11552
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11553
- ] });
11554
- }
11551
+ ) }),
11552
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11553
+ ] });
11554
+ }
11555
+ }
11556
+ );
11557
+ };
11558
+ const schema$2 = objectType({
11559
+ sales_channel_id: stringType().min(1)
11560
+ });
11561
+ const ShippingAddress = () => {
11562
+ const { id } = reactRouterDom.useParams();
11563
+ const { order, isPending, isError, error } = useOrder(id, {
11564
+ fields: "+shipping_address"
11565
+ });
11566
+ if (isError) {
11567
+ throw error;
11568
+ }
11569
+ const isReady = !isPending && !!order;
11570
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
11571
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11572
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Shipping Address" }) }),
11573
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
11574
+ ] }),
11575
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(ShippingAddressForm, { order })
11576
+ ] });
11577
+ };
11578
+ const ShippingAddressForm = ({ order }) => {
11579
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
11580
+ const form = reactHookForm.useForm({
11581
+ defaultValues: {
11582
+ first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
11583
+ last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
11584
+ company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
11585
+ address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
11586
+ address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
11587
+ city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
11588
+ province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
11589
+ country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
11590
+ postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
11591
+ phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
11592
+ },
11593
+ resolver: zod.zodResolver(schema$1)
11594
+ });
11595
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11596
+ const { handleSuccess } = useRouteModal();
11597
+ const onSubmit = form.handleSubmit(async (data) => {
11598
+ await mutateAsync(
11599
+ {
11600
+ shipping_address: {
11601
+ first_name: data.first_name,
11602
+ last_name: data.last_name,
11603
+ company: data.company,
11604
+ address_1: data.address_1,
11605
+ address_2: data.address_2,
11606
+ city: data.city,
11607
+ province: data.province,
11608
+ country_code: data.country_code,
11609
+ postal_code: data.postal_code,
11610
+ phone: data.phone
11611
+ }
11612
+ },
11613
+ {
11614
+ onSuccess: () => {
11615
+ handleSuccess();
11616
+ },
11617
+ onError: (error) => {
11618
+ ui.toast.error(error.message);
11619
+ }
11620
+ }
11621
+ );
11622
+ });
11623
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11624
+ KeyboundForm,
11625
+ {
11626
+ className: "flex flex-1 flex-col overflow-hidden",
11627
+ onSubmit,
11628
+ children: [
11629
+ /* @__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: [
11630
+ /* @__PURE__ */ jsxRuntime.jsx(
11631
+ Form$2.Field,
11632
+ {
11633
+ control: form.control,
11634
+ name: "country_code",
11635
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11636
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Country" }),
11637
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(CountrySelect, { ...field }) }),
11638
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11639
+ ] })
11640
+ }
11641
+ ),
11642
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11643
+ /* @__PURE__ */ jsxRuntime.jsx(
11644
+ Form$2.Field,
11645
+ {
11646
+ control: form.control,
11647
+ name: "first_name",
11648
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11649
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "First name" }),
11650
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11651
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11652
+ ] })
11653
+ }
11654
+ ),
11655
+ /* @__PURE__ */ jsxRuntime.jsx(
11656
+ Form$2.Field,
11657
+ {
11658
+ control: form.control,
11659
+ name: "last_name",
11660
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11661
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Last name" }),
11662
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11663
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11664
+ ] })
11665
+ }
11666
+ )
11667
+ ] }),
11668
+ /* @__PURE__ */ jsxRuntime.jsx(
11669
+ Form$2.Field,
11670
+ {
11671
+ control: form.control,
11672
+ name: "company",
11673
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11674
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Company" }),
11675
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11676
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11677
+ ] })
11678
+ }
11679
+ ),
11680
+ /* @__PURE__ */ jsxRuntime.jsx(
11681
+ Form$2.Field,
11682
+ {
11683
+ control: form.control,
11684
+ name: "address_1",
11685
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11686
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Address" }),
11687
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11688
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11689
+ ] })
11690
+ }
11691
+ ),
11692
+ /* @__PURE__ */ jsxRuntime.jsx(
11693
+ Form$2.Field,
11694
+ {
11695
+ control: form.control,
11696
+ name: "address_2",
11697
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11698
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
11699
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11700
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11701
+ ] })
11702
+ }
11703
+ ),
11704
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
11705
+ /* @__PURE__ */ jsxRuntime.jsx(
11706
+ Form$2.Field,
11707
+ {
11708
+ control: form.control,
11709
+ name: "postal_code",
11710
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11711
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Postal code" }),
11712
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11713
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11714
+ ] })
11715
+ }
11716
+ ),
11717
+ /* @__PURE__ */ jsxRuntime.jsx(
11718
+ Form$2.Field,
11719
+ {
11720
+ control: form.control,
11721
+ name: "city",
11722
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11723
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "City" }),
11724
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11725
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11726
+ ] })
11727
+ }
11728
+ )
11729
+ ] }),
11730
+ /* @__PURE__ */ jsxRuntime.jsx(
11731
+ Form$2.Field,
11732
+ {
11733
+ control: form.control,
11734
+ name: "province",
11735
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11736
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Province / State" }),
11737
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11738
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11739
+ ] })
11740
+ }
11741
+ ),
11742
+ /* @__PURE__ */ jsxRuntime.jsx(
11743
+ Form$2.Field,
11744
+ {
11745
+ control: form.control,
11746
+ name: "phone",
11747
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11748
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Phone" }),
11749
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
11750
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11751
+ ] })
11752
+ }
11753
+ )
11754
+ ] }) }),
11755
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11756
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11757
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11758
+ ] }) })
11759
+ ]
11555
11760
  }
11556
- );
11761
+ ) });
11557
11762
  };
11558
- const schema$2 = objectType({
11559
- sales_channel_id: stringType().min(1)
11560
- });
11763
+ const schema$1 = addressSchema;
11561
11764
  const STACKED_FOCUS_MODAL_ID = "shipping-form";
11562
11765
  const Shipping = () => {
11563
11766
  var _a;
@@ -12365,209 +12568,6 @@ const CustomAmountField = ({
12365
12568
  }
12366
12569
  );
12367
12570
  };
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,
12551
- {
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
- ] })
12559
- }
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
- ]
12567
- }
12568
- ) });
12569
- };
12570
- const schema$1 = addressSchema;
12571
12571
  const TransferOwnership = () => {
12572
12572
  const { id } = reactRouterDom.useParams();
12573
12573
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -13068,38 +13068,38 @@ const routeModule = {
13068
13068
  Component: BillingAddress,
13069
13069
  path: "/draft-orders/:id/billing-address"
13070
13070
  },
13071
- {
13072
- Component: CustomItems,
13073
- path: "/draft-orders/:id/custom-items"
13074
- },
13075
13071
  {
13076
13072
  Component: Email,
13077
13073
  path: "/draft-orders/:id/email"
13078
13074
  },
13079
13075
  {
13080
- Component: Promotions,
13081
- path: "/draft-orders/:id/promotions"
13076
+ Component: CustomItems,
13077
+ path: "/draft-orders/:id/custom-items"
13078
+ },
13079
+ {
13080
+ Component: Items,
13081
+ path: "/draft-orders/:id/items"
13082
13082
  },
13083
13083
  {
13084
13084
  Component: Metadata,
13085
13085
  path: "/draft-orders/:id/metadata"
13086
13086
  },
13087
13087
  {
13088
- Component: Items,
13089
- path: "/draft-orders/:id/items"
13088
+ Component: Promotions,
13089
+ path: "/draft-orders/:id/promotions"
13090
13090
  },
13091
13091
  {
13092
13092
  Component: SalesChannel,
13093
13093
  path: "/draft-orders/:id/sales-channel"
13094
13094
  },
13095
- {
13096
- Component: Shipping,
13097
- path: "/draft-orders/:id/shipping"
13098
- },
13099
13095
  {
13100
13096
  Component: ShippingAddress,
13101
13097
  path: "/draft-orders/:id/shipping-address"
13102
13098
  },
13099
+ {
13100
+ Component: Shipping,
13101
+ path: "/draft-orders/:id/shipping"
13102
+ },
13103
13103
  {
13104
13104
  Component: TransferOwnership,
13105
13105
  path: "/draft-orders/:id/transfer-ownership"