@medusajs/draft-order 2.13.3-preview-20260227091110 → 2.13.3

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