@medusajs/draft-order 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9902,90 +9902,148 @@ const BillingAddressForm = ({ order }) => {
9902
9902
  ) });
9903
9903
  };
9904
9904
  const schema$5 = addressSchema;
9905
- const Email = () => {
9906
- const { id } = reactRouterDom.useParams();
9907
- const { order, isPending, isError, error } = useOrder(id, {
9908
- fields: "+email"
9909
- });
9910
- if (isError) {
9911
- throw error;
9912
- }
9913
- const isReady = !isPending && !!order;
9905
+ const CustomItems = () => {
9914
9906
  return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9915
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
9916
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Email" }) }),
9917
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
9918
- ] }),
9919
- isReady && /* @__PURE__ */ jsxRuntime.jsx(EmailForm, { order })
9907
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
9908
+ /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
9920
9909
  ] });
9921
9910
  };
9922
- const EmailForm = ({ order }) => {
9911
+ const CustomItemsForm = () => {
9923
9912
  const form = reactHookForm.useForm({
9924
- defaultValues: {
9925
- email: order.email ?? ""
9926
- },
9927
9913
  resolver: zod.zodResolver(schema$4)
9928
9914
  });
9929
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9930
- const { handleSuccess } = useRouteModal();
9931
- const onSubmit = form.handleSubmit(async (data) => {
9932
- await mutateAsync(
9933
- { email: data.email },
9934
- {
9935
- onSuccess: () => {
9936
- handleSuccess();
9937
- },
9938
- onError: (error) => {
9939
- ui.toast.error(error.message);
9940
- }
9941
- }
9942
- );
9943
- });
9944
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
9945
- KeyboundForm,
9946
- {
9947
- className: "flex flex-1 flex-col overflow-hidden",
9948
- onSubmit,
9949
- children: [
9950
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
9951
- Form$2.Field,
9952
- {
9953
- control: form.control,
9954
- name: "email",
9955
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
9956
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Email" }),
9957
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
9958
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
9959
- ] })
9960
- }
9961
- ) }),
9962
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9963
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9964
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
9965
- ] }) })
9966
- ]
9967
- }
9968
- ) });
9915
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
9916
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
9917
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
9918
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9919
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
9920
+ ] }) })
9921
+ ] }) });
9969
9922
  };
9970
9923
  const schema$4 = z.object({
9971
9924
  email: z.string().email()
9972
9925
  });
9973
- const PROMOTION_QUERY_KEY = "promotions";
9974
- const promotionsQueryKeys = {
9926
+ const NumberInput = React.forwardRef(
9927
+ ({
9928
+ value,
9929
+ onChange,
9930
+ size = "base",
9931
+ min = 0,
9932
+ max = 100,
9933
+ step = 1,
9934
+ className,
9935
+ disabled,
9936
+ ...props
9937
+ }, ref) => {
9938
+ const handleChange = (event) => {
9939
+ const newValue = event.target.value === "" ? min : Number(event.target.value);
9940
+ if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
9941
+ onChange(newValue);
9942
+ }
9943
+ };
9944
+ const handleIncrement = () => {
9945
+ const newValue = value + step;
9946
+ if (max === void 0 || newValue <= max) {
9947
+ onChange(newValue);
9948
+ }
9949
+ };
9950
+ const handleDecrement = () => {
9951
+ const newValue = value - step;
9952
+ if (min === void 0 || newValue >= min) {
9953
+ onChange(newValue);
9954
+ }
9955
+ };
9956
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9957
+ "div",
9958
+ {
9959
+ className: ui.clx(
9960
+ "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
9961
+ "[&:has(input:focus)]:shadow-borders-interactive-with-active",
9962
+ {
9963
+ "h-7": size === "small",
9964
+ "h-8": size === "base"
9965
+ },
9966
+ className
9967
+ ),
9968
+ children: [
9969
+ /* @__PURE__ */ jsxRuntime.jsx(
9970
+ "input",
9971
+ {
9972
+ ref,
9973
+ type: "number",
9974
+ value,
9975
+ onChange: handleChange,
9976
+ min,
9977
+ max,
9978
+ step,
9979
+ className: ui.clx(
9980
+ "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
9981
+ "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
9982
+ "placeholder:text-ui-fg-muted"
9983
+ ),
9984
+ ...props
9985
+ }
9986
+ ),
9987
+ /* @__PURE__ */ jsxRuntime.jsxs(
9988
+ "button",
9989
+ {
9990
+ className: ui.clx(
9991
+ "flex items-center justify-center outline-none transition-fg",
9992
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9993
+ "focus:bg-ui-bg-field-component-hover",
9994
+ "hover:bg-ui-bg-field-component-hover",
9995
+ {
9996
+ "size-7": size === "small",
9997
+ "size-8": size === "base"
9998
+ }
9999
+ ),
10000
+ type: "button",
10001
+ onClick: handleDecrement,
10002
+ disabled: min !== void 0 && value <= min || disabled,
10003
+ children: [
10004
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Minus, {}),
10005
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
10006
+ ]
10007
+ }
10008
+ ),
10009
+ /* @__PURE__ */ jsxRuntime.jsxs(
10010
+ "button",
10011
+ {
10012
+ className: ui.clx(
10013
+ "flex items-center justify-center outline-none transition-fg",
10014
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
10015
+ "focus:bg-ui-bg-field-hover",
10016
+ "hover:bg-ui-bg-field-hover",
10017
+ {
10018
+ "size-7": size === "small",
10019
+ "size-8": size === "base"
10020
+ }
10021
+ ),
10022
+ type: "button",
10023
+ onClick: handleIncrement,
10024
+ disabled: max !== void 0 && value >= max || disabled,
10025
+ children: [
10026
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
10027
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Increase by ${step}` })
10028
+ ]
10029
+ }
10030
+ )
10031
+ ]
10032
+ }
10033
+ );
10034
+ }
10035
+ );
10036
+ const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
10037
+ const productVariantsQueryKeys = {
9975
10038
  list: (query2) => [
9976
- PROMOTION_QUERY_KEY,
9977
- query2 ? query2 : void 0
9978
- ],
9979
- detail: (id, query2) => [
9980
- PROMOTION_QUERY_KEY,
9981
- id,
10039
+ PRODUCT_VARIANTS_QUERY_KEY,
9982
10040
  query2 ? query2 : void 0
9983
10041
  ]
9984
10042
  };
9985
- const usePromotions = (query2, options) => {
10043
+ const useProductVariants = (query2, options) => {
9986
10044
  const { data, ...rest } = reactQuery.useQuery({
9987
- queryKey: promotionsQueryKeys.list(query2),
9988
- queryFn: async () => sdk.admin.promotion.list(query2),
10045
+ queryKey: productVariantsQueryKeys.list(query2),
10046
+ queryFn: async () => await sdk.admin.productVariant.list(query2),
9989
10047
  ...options
9990
10048
  });
9991
10049
  return { ...data, ...rest };
@@ -10036,85 +10094,65 @@ const useInitiateOrderEdit = ({
10036
10094
  run();
10037
10095
  }, [preview, navigate, mutateAsync]);
10038
10096
  };
10039
- const Promotions = () => {
10097
+ function convertNumber(value) {
10098
+ return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10099
+ }
10100
+ const STACKED_MODAL_ID = "items_stacked_modal";
10101
+ const Items = () => {
10040
10102
  const { id } = reactRouterDom.useParams();
10041
10103
  const {
10042
10104
  order: preview,
10105
+ isPending: isPreviewPending,
10043
10106
  isError: isPreviewError,
10044
10107
  error: previewError
10045
- } = useOrderPreview(id, void 0);
10108
+ } = useOrderPreview(id, void 0, {
10109
+ placeholderData: reactQuery.keepPreviousData
10110
+ });
10046
10111
  useInitiateOrderEdit({ preview });
10112
+ const { draft_order, isPending, isError, error } = useDraftOrder(
10113
+ id,
10114
+ {
10115
+ fields: "currency_code"
10116
+ },
10117
+ {
10118
+ enabled: !!id
10119
+ }
10120
+ );
10047
10121
  const { onCancel } = useCancelOrderEdit({ preview });
10122
+ if (isError) {
10123
+ throw error;
10124
+ }
10048
10125
  if (isPreviewError) {
10049
10126
  throw previewError;
10050
10127
  }
10051
- const isReady = !!preview;
10052
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
10053
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
10054
- isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
10055
- ] });
10128
+ const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10129
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsxRuntime.jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10130
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10131
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10132
+ ] }) });
10056
10133
  };
10057
- const PromotionForm = ({ preview }) => {
10058
- const { items, shipping_methods } = preview;
10134
+ const ItemsForm = ({ preview, currencyCode }) => {
10135
+ var _a;
10059
10136
  const [isSubmitting, setIsSubmitting] = React.useState(false);
10060
- const [comboboxValue, setComboboxValue] = React.useState("");
10061
- const { handleSuccess } = useRouteModal();
10062
- const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
10063
- const promoCodes = getPromotionCodes(items, shipping_methods);
10064
- const { promotions, isPending, isError, error } = usePromotions(
10065
- {
10066
- code: promoCodes
10067
- },
10068
- {
10069
- enabled: !!promoCodes.length
10070
- }
10137
+ const [modalContent, setModalContent] = React.useState(
10138
+ null
10071
10139
  );
10072
- const comboboxData = useComboboxData({
10073
- queryKey: ["promotions", "combobox", promoCodes],
10074
- queryFn: async (params) => {
10075
- return await sdk.admin.promotion.list({
10076
- ...params,
10077
- code: {
10078
- $nin: promoCodes
10079
- }
10080
- });
10081
- },
10082
- getOptions: (data) => {
10083
- return data.promotions.map((promotion) => ({
10084
- label: promotion.code,
10085
- value: promotion.code
10086
- }));
10087
- }
10088
- });
10089
- const add = async (value) => {
10090
- if (!value) {
10091
- return;
10092
- }
10093
- addPromotions(
10094
- {
10095
- promo_codes: [value]
10096
- },
10097
- {
10098
- onError: (e) => {
10099
- ui.toast.error(e.message);
10100
- comboboxData.onSearchValueChange("");
10101
- setComboboxValue("");
10102
- },
10103
- onSuccess: () => {
10104
- comboboxData.onSearchValueChange("");
10105
- setComboboxValue("");
10106
- }
10107
- }
10108
- );
10109
- };
10140
+ const { handleSuccess } = useRouteModal();
10141
+ const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10110
10142
  const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10111
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
10143
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10144
+ const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10145
+ const matches = React.useMemo(() => {
10146
+ return matchSorter.matchSorter(preview.items, query2, {
10147
+ keys: ["product_title", "variant_title", "variant_sku", "title"]
10148
+ });
10149
+ }, [preview.items, query2]);
10112
10150
  const onSubmit = async () => {
10113
10151
  setIsSubmitting(true);
10114
10152
  let requestSucceeded = false;
10115
10153
  await requestOrderEdit(void 0, {
10116
10154
  onError: (e) => {
10117
- ui.toast.error(e.message);
10155
+ ui.toast.error(`Failed to request order edit: ${e.message}`);
10118
10156
  },
10119
10157
  onSuccess: () => {
10120
10158
  requestSucceeded = true;
@@ -10126,7 +10164,7 @@ const PromotionForm = ({ preview }) => {
10126
10164
  }
10127
10165
  await confirmOrderEdit(void 0, {
10128
10166
  onError: (e) => {
10129
- ui.toast.error(e.message);
10167
+ ui.toast.error(`Failed to confirm order edit: ${e.message}`);
10130
10168
  },
10131
10169
  onSuccess: () => {
10132
10170
  handleSuccess();
@@ -10136,1079 +10174,903 @@ const PromotionForm = ({ preview }) => {
10136
10174
  }
10137
10175
  });
10138
10176
  };
10139
- if (isError) {
10140
- throw error;
10141
- }
10142
- return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
10143
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
10144
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
10145
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10146
- /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
10147
- /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
10148
- ] }),
10149
- /* @__PURE__ */ jsxRuntime.jsx(
10150
- Combobox,
10151
- {
10152
- id: "promotion-combobox",
10153
- "aria-describedby": "promotion-combobox-hint",
10154
- isFetchingNextPage: comboboxData.isFetchingNextPage,
10155
- fetchNextPage: comboboxData.fetchNextPage,
10156
- options: comboboxData.options,
10157
- onSearchValueChange: comboboxData.onSearchValueChange,
10158
- searchValue: comboboxData.searchValue,
10159
- disabled: comboboxData.disabled || isAddingPromotions,
10160
- onChange: add,
10161
- value: comboboxValue
10177
+ const onKeyDown = React.useCallback(
10178
+ (e) => {
10179
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10180
+ if (modalContent || isSubmitting) {
10181
+ return;
10182
+ }
10183
+ onSubmit();
10184
+ }
10185
+ },
10186
+ [modalContent, isSubmitting, onSubmit]
10187
+ );
10188
+ React.useEffect(() => {
10189
+ document.addEventListener("keydown", onKeyDown);
10190
+ return () => {
10191
+ document.removeEventListener("keydown", onKeyDown);
10192
+ };
10193
+ }, [onKeyDown]);
10194
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10195
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
10196
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
10197
+ StackedFocusModal,
10198
+ {
10199
+ id: STACKED_MODAL_ID,
10200
+ onOpenChangeCallback: (open) => {
10201
+ if (!open) {
10202
+ setModalContent(null);
10162
10203
  }
10163
- )
10164
- ] }),
10165
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10166
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
10167
- PromotionItem,
10168
- {
10169
- promotion,
10170
- orderId: preview.id,
10171
- isLoading: isPending
10172
10204
  },
10173
- promotion.id
10174
- )) })
10175
- ] }) }),
10176
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
10177
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10205
+ children: [
10206
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-6 py-16", children: [
10207
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10208
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Items" }) }),
10209
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Edit the items in the draft order." }) })
10210
+ ] }),
10211
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10212
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
10213
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10214
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10215
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10216
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10217
+ ] }),
10218
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10219
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10220
+ ui.Input,
10221
+ {
10222
+ type: "search",
10223
+ placeholder: "Search items",
10224
+ value: searchValue,
10225
+ onChange: (e) => onSearchValueChange(e.target.value)
10226
+ }
10227
+ ) }),
10228
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
10229
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}) }) }),
10230
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
10231
+ /* @__PURE__ */ jsxRuntime.jsx(
10232
+ StackedModalTrigger$1,
10233
+ {
10234
+ type: "add-items",
10235
+ setModalContent
10236
+ }
10237
+ ),
10238
+ /* @__PURE__ */ jsxRuntime.jsx(
10239
+ StackedModalTrigger$1,
10240
+ {
10241
+ type: "add-custom-item",
10242
+ setModalContent
10243
+ }
10244
+ )
10245
+ ] })
10246
+ ] })
10247
+ ] })
10248
+ ] }),
10249
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10250
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_1fr_1fr_28px] gap-3 px-4 py-2 text-ui-fg-muted", children: [
10251
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
10252
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10253
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Price" }) }),
10254
+ /* @__PURE__ */ jsxRuntime.jsx("div", {})
10255
+ ] }) }),
10256
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
10257
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10258
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10259
+ ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
10260
+ Item,
10261
+ {
10262
+ item,
10263
+ preview,
10264
+ currencyCode
10265
+ },
10266
+ item.id
10267
+ )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
10268
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10269
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
10270
+ 'No items found for "',
10271
+ query2,
10272
+ '".'
10273
+ ] })
10274
+ ] }) })
10275
+ ] })
10276
+ ] }),
10277
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10278
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10279
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10280
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(
10281
+ ui.Text,
10282
+ {
10283
+ size: "small",
10284
+ leading: "compact",
10285
+ className: "text-ui-fg-subtle",
10286
+ children: [
10287
+ itemCount,
10288
+ " ",
10289
+ itemCount === 1 ? "item" : "items"
10290
+ ]
10291
+ }
10292
+ ) }),
10293
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10294
+ ] })
10295
+ ] }) }),
10296
+ modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsxRuntime.jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsxRuntime.jsx(
10297
+ CustomItemForm,
10298
+ {
10299
+ orderId: preview.id,
10300
+ currencyCode
10301
+ }
10302
+ ) : null)
10303
+ ]
10304
+ }
10305
+ ) }),
10306
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
10307
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10178
10308
  /* @__PURE__ */ jsxRuntime.jsx(
10179
10309
  ui.Button,
10180
10310
  {
10181
10311
  size: "small",
10182
- type: "submit",
10183
- isLoading: isSubmitting || isAddingPromotions,
10312
+ type: "button",
10313
+ onClick: onSubmit,
10314
+ isLoading: isSubmitting,
10184
10315
  children: "Save"
10185
10316
  }
10186
10317
  )
10187
10318
  ] }) })
10188
10319
  ] });
10189
10320
  };
10190
- const PromotionItem = ({
10191
- promotion,
10192
- orderId,
10193
- isLoading
10194
- }) => {
10195
- var _a;
10196
- const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
10197
- const onRemove = async () => {
10198
- removePromotions(
10199
- {
10200
- promo_codes: [promotion.code]
10201
- },
10202
- {
10203
- onError: (e) => {
10204
- ui.toast.error(e.message);
10205
- }
10206
- }
10207
- );
10208
- };
10209
- const displayValue = getDisplayValue(promotion);
10210
- return /* @__PURE__ */ jsxRuntime.jsxs(
10211
- "div",
10212
- {
10213
- className: ui.clx(
10214
- "px-3 py-2 rounded-lg bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between",
10215
- {
10216
- "animate-pulse": isLoading
10217
- }
10218
- ),
10219
- children: [
10220
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10221
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
10222
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-ui-fg-subtle", children: [
10223
- displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
10224
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
10225
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
10226
- ] }),
10227
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
10228
- ] })
10229
- ] }),
10230
- /* @__PURE__ */ jsxRuntime.jsx(
10231
- ui.IconButton,
10232
- {
10233
- size: "small",
10234
- type: "button",
10235
- variant: "transparent",
10236
- onClick: onRemove,
10237
- isLoading: isPending || isLoading,
10238
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
10239
- }
10240
- )
10241
- ]
10242
- },
10243
- promotion.id
10244
- );
10245
- };
10246
- function getDisplayValue(promotion) {
10247
- var _a, _b, _c, _d;
10248
- const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
10249
- if (!value) {
10250
- return null;
10251
- }
10252
- if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
10253
- const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
10254
- if (!currency) {
10255
- return null;
10256
- }
10257
- return getLocaleAmount(value, currency);
10258
- } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
10259
- return formatPercentage(value);
10260
- }
10261
- return null;
10262
- }
10263
- const formatter = new Intl.NumberFormat([], {
10264
- style: "percent",
10265
- minimumFractionDigits: 2
10266
- });
10267
- const formatPercentage = (value, isPercentageValue = false) => {
10268
- let val = value || 0;
10269
- if (!isPercentageValue) {
10270
- val = val / 100;
10271
- }
10272
- return formatter.format(val);
10273
- };
10274
- function getPromotionCodes(items, shippingMethods) {
10275
- const codes = /* @__PURE__ */ new Set();
10276
- for (const item of items) {
10277
- if (item.adjustments) {
10278
- for (const adjustment of item.adjustments) {
10279
- if (adjustment.code) {
10280
- codes.add(adjustment.code);
10281
- }
10282
- }
10283
- }
10284
- }
10285
- for (const shippingMethod of shippingMethods) {
10286
- if (shippingMethod.adjustments) {
10287
- for (const adjustment of shippingMethod.adjustments) {
10288
- if (adjustment.code) {
10289
- codes.add(adjustment.code);
10290
- }
10291
- }
10292
- }
10293
- }
10294
- return Array.from(codes);
10295
- }
10296
- const SalesChannel = () => {
10297
- const { id } = reactRouterDom.useParams();
10298
- const { draft_order, isPending, isError, error } = useDraftOrder(
10299
- id,
10300
- {
10301
- fields: "+sales_channel_id"
10302
- },
10303
- {
10304
- enabled: !!id
10305
- }
10306
- );
10307
- if (isError) {
10308
- throw error;
10321
+ const Item = ({ item, preview, currencyCode }) => {
10322
+ if (item.variant_id) {
10323
+ return /* @__PURE__ */ jsxRuntime.jsx(VariantItem, { item, preview, currencyCode });
10309
10324
  }
10310
- const ISrEADY = !!draft_order && !isPending;
10311
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10312
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10313
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
10314
- /* @__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" }) })
10315
- ] }),
10316
- ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
10317
- ] });
10325
+ return /* @__PURE__ */ jsxRuntime.jsx(CustomItem, { item, preview, currencyCode });
10318
10326
  };
10319
- const SalesChannelForm = ({ order }) => {
10327
+ const VariantItem = ({ item, preview, currencyCode }) => {
10328
+ const [editing, setEditing] = React.useState(false);
10320
10329
  const form = reactHookForm.useForm({
10321
10330
  defaultValues: {
10322
- sales_channel_id: order.sales_channel_id || ""
10331
+ quantity: item.quantity,
10332
+ unit_price: item.unit_price
10323
10333
  },
10324
- resolver: zod.zodResolver(schema$3)
10334
+ resolver: zod.zodResolver(variantItemSchema)
10325
10335
  });
10326
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
10327
- const { handleSuccess } = useRouteModal();
10336
+ const actionId = React.useMemo(() => {
10337
+ var _a, _b;
10338
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10339
+ }, [item]);
10340
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10341
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10342
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10328
10343
  const onSubmit = form.handleSubmit(async (data) => {
10329
- await mutateAsync(
10344
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10345
+ setEditing(false);
10346
+ return;
10347
+ }
10348
+ if (!actionId) {
10349
+ await updateOriginalItem(
10350
+ {
10351
+ item_id: item.id,
10352
+ quantity: data.quantity,
10353
+ unit_price: convertNumber(data.unit_price)
10354
+ },
10355
+ {
10356
+ onSuccess: () => {
10357
+ setEditing(false);
10358
+ },
10359
+ onError: (e) => {
10360
+ ui.toast.error(e.message);
10361
+ }
10362
+ }
10363
+ );
10364
+ return;
10365
+ }
10366
+ await updateActionItem(
10330
10367
  {
10331
- sales_channel_id: data.sales_channel_id
10368
+ action_id: actionId,
10369
+ quantity: data.quantity,
10370
+ unit_price: convertNumber(data.unit_price)
10332
10371
  },
10333
10372
  {
10334
10373
  onSuccess: () => {
10335
- ui.toast.success("Sales channel updated");
10336
- handleSuccess();
10374
+ setEditing(false);
10337
10375
  },
10338
- onError: (error) => {
10339
- ui.toast.error(error.message);
10376
+ onError: (e) => {
10377
+ ui.toast.error(e.message);
10340
10378
  }
10341
10379
  }
10342
10380
  );
10343
10381
  });
10344
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
10345
- KeyboundForm,
10346
- {
10347
- className: "flex flex-1 flex-col overflow-hidden",
10348
- onSubmit,
10349
- children: [
10350
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
10351
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
10352
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10353
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10354
- ] }) })
10355
- ]
10356
- }
10357
- ) });
10358
- };
10359
- const SalesChannelField = ({ control, order }) => {
10360
- const salesChannels = useComboboxData({
10361
- queryFn: async (params) => {
10362
- return await sdk.admin.salesChannel.list(params);
10363
- },
10364
- queryKey: ["sales-channels"],
10365
- getOptions: (data) => {
10366
- return data.sales_channels.map((salesChannel) => ({
10367
- label: salesChannel.name,
10368
- value: salesChannel.id
10369
- }));
10370
- },
10371
- defaultValue: order.sales_channel_id || void 0
10372
- });
10373
- return /* @__PURE__ */ jsxRuntime.jsx(
10374
- Form$2.Field,
10375
- {
10376
- control,
10377
- name: "sales_channel_id",
10378
- render: ({ field }) => {
10379
- return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10380
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
10381
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10382
- Combobox,
10382
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_28px] gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center", children: [
10383
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3 w-full", children: [
10384
+ /* @__PURE__ */ jsxRuntime.jsx(
10385
+ Thumbnail,
10386
+ {
10387
+ thumbnail: item.thumbnail,
10388
+ alt: item.product_title ?? void 0
10389
+ }
10390
+ ),
10391
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10392
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
10393
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10394
+ /* @__PURE__ */ jsxRuntime.jsxs(
10395
+ ui.Text,
10383
10396
  {
10384
- options: salesChannels.options,
10385
- fetchNextPage: salesChannels.fetchNextPage,
10386
- isFetchingNextPage: salesChannels.isFetchingNextPage,
10387
- searchValue: salesChannels.searchValue,
10388
- onSearchValueChange: salesChannels.onSearchValueChange,
10389
- placeholder: "Select sales channel",
10390
- ...field
10397
+ size: "small",
10398
+ leading: "compact",
10399
+ className: "text-ui-fg-subtle",
10400
+ children: [
10401
+ "(",
10402
+ item.variant_title,
10403
+ ")"
10404
+ ]
10391
10405
  }
10392
- ) }),
10393
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10394
- ] });
10406
+ )
10407
+ ] }),
10408
+ /* @__PURE__ */ jsxRuntime.jsx(
10409
+ ui.Text,
10410
+ {
10411
+ size: "small",
10412
+ leading: "compact",
10413
+ className: "text-ui-fg-subtle",
10414
+ children: item.variant_sku
10415
+ }
10416
+ )
10417
+ ] })
10418
+ ] }),
10419
+ editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
10420
+ Form$2.Field,
10421
+ {
10422
+ control: form.control,
10423
+ name: "quantity",
10424
+ render: ({ field }) => {
10425
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10426
+ }
10395
10427
  }
10396
- }
10397
- );
10398
- };
10399
- const schema$3 = z.object({
10400
- sales_channel_id: z.string().min(1)
10401
- });
10402
- function convertNumber(value) {
10403
- return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10404
- }
10405
- const STACKED_FOCUS_MODAL_ID = "shipping-form";
10406
- const Shipping = () => {
10407
- var _a;
10408
- const { id } = reactRouterDom.useParams();
10409
- const { order, isPending, isError, error } = useOrder(id, {
10410
- fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
10411
- });
10412
- const {
10413
- order: preview,
10414
- isPending: isPreviewPending,
10415
- isError: isPreviewError,
10416
- error: previewError
10417
- } = useOrderPreview(id);
10418
- useInitiateOrderEdit({ preview });
10419
- const { onCancel } = useCancelOrderEdit({ preview });
10420
- if (isError) {
10421
- throw error;
10422
- }
10423
- if (isPreviewError) {
10424
- throw previewError;
10425
- }
10426
- const orderHasItems = (((_a = order == null ? void 0 : order.items) == null ? void 0 : _a.length) || 0) > 0;
10427
- const isReady = preview && !isPreviewPending && order && !isPending;
10428
- return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
10429
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
10430
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
10431
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
10432
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This draft order currently has no items. Add items to the order before adding shipping." }) })
10433
- ] }) }) }),
10434
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }) })
10435
- ] }) : isReady ? /* @__PURE__ */ jsxRuntime.jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10436
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
10437
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10438
- ] }) });
10428
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }) }),
10429
+ editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
10430
+ Form$2.Field,
10431
+ {
10432
+ control: form.control,
10433
+ name: "unit_price",
10434
+ render: ({ field: { onChange, ...field } }) => {
10435
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10436
+ ui.CurrencyInput,
10437
+ {
10438
+ ...field,
10439
+ symbol: getNativeSymbol(currencyCode),
10440
+ code: currencyCode,
10441
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10442
+ }
10443
+ ) }) });
10444
+ }
10445
+ }
10446
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex items-center justify-end w-full", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10447
+ /* @__PURE__ */ jsxRuntime.jsx(
10448
+ ui.IconButton,
10449
+ {
10450
+ type: "button",
10451
+ size: "small",
10452
+ onClick: editing ? onSubmit : () => {
10453
+ setEditing(true);
10454
+ },
10455
+ disabled: isPending,
10456
+ children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
10457
+ }
10458
+ )
10459
+ ] }) }) });
10439
10460
  };
10440
- const ShippingForm = ({ preview, order }) => {
10441
- var _a;
10442
- const { setIsOpen } = useStackedModal();
10443
- const [isSubmitting, setIsSubmitting] = React.useState(false);
10444
- const [data, setData] = React.useState(null);
10445
- const appliedShippingOptionIds = (_a = preview.shipping_methods) == null ? void 0 : _a.map((method) => method.shipping_option_id).filter(Boolean);
10446
- const { shipping_options } = useShippingOptions(
10447
- {
10448
- id: appliedShippingOptionIds,
10449
- fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
10461
+ const variantItemSchema = z.object({
10462
+ quantity: z.number(),
10463
+ unit_price: z.union([z.number(), z.string()])
10464
+ });
10465
+ const CustomItem = ({ item, preview, currencyCode }) => {
10466
+ const [editing, setEditing] = React.useState(false);
10467
+ const { quantity, unit_price, title } = item;
10468
+ const form = reactHookForm.useForm({
10469
+ defaultValues: {
10470
+ title,
10471
+ quantity,
10472
+ unit_price
10450
10473
  },
10451
- {
10452
- enabled: appliedShippingOptionIds.length > 0
10453
- }
10454
- );
10455
- const uniqueShippingProfiles = React.useMemo(() => {
10456
- const profiles = /* @__PURE__ */ new Map();
10457
- getUniqueShippingProfiles(order.items).forEach((profile) => {
10458
- profiles.set(profile.id, profile);
10459
- });
10460
- shipping_options == null ? void 0 : shipping_options.forEach((option) => {
10461
- profiles.set(option.shipping_profile_id, option.shipping_profile);
10462
- });
10463
- return Array.from(profiles.values());
10464
- }, [order.items, shipping_options]);
10465
- const { handleSuccess } = useRouteModal();
10466
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10467
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10468
- const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
10469
- const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
10470
- const onSubmit = async () => {
10471
- setIsSubmitting(true);
10472
- let requestSucceeded = false;
10473
- await requestOrderEdit(void 0, {
10474
- onError: (e) => {
10475
- ui.toast.error(`Failed to request order edit: ${e.message}`);
10476
- },
10477
- onSuccess: () => {
10478
- requestSucceeded = true;
10479
- }
10474
+ resolver: zod.zodResolver(customItemSchema)
10475
+ });
10476
+ React.useEffect(() => {
10477
+ form.reset({
10478
+ title,
10479
+ quantity,
10480
+ unit_price
10480
10481
  });
10481
- if (!requestSucceeded) {
10482
- setIsSubmitting(false);
10482
+ }, [form, title, quantity, unit_price]);
10483
+ const actionId = React.useMemo(() => {
10484
+ var _a, _b;
10485
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10486
+ }, [item]);
10487
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10488
+ const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10489
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10490
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10491
+ const onSubmit = form.handleSubmit(async (data) => {
10492
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10493
+ setEditing(false);
10483
10494
  return;
10484
10495
  }
10485
- await confirmOrderEdit(void 0, {
10486
- onError: (e) => {
10487
- ui.toast.error(`Failed to confirm order edit: ${e.message}`);
10488
- },
10489
- onSuccess: () => {
10490
- handleSuccess();
10496
+ if (!actionId) {
10497
+ await updateOriginalItem(
10498
+ {
10499
+ item_id: item.id,
10500
+ quantity: data.quantity,
10501
+ unit_price: convertNumber(data.unit_price)
10502
+ },
10503
+ {
10504
+ onSuccess: () => {
10505
+ setEditing(false);
10506
+ },
10507
+ onError: (e) => {
10508
+ ui.toast.error(e.message);
10509
+ }
10510
+ }
10511
+ );
10512
+ return;
10513
+ }
10514
+ if (data.quantity === 0) {
10515
+ await removeActionItem(actionId, {
10516
+ onSuccess: () => {
10517
+ setEditing(false);
10518
+ },
10519
+ onError: (e) => {
10520
+ ui.toast.error(e.message);
10521
+ }
10522
+ });
10523
+ return;
10524
+ }
10525
+ await updateActionItem(
10526
+ {
10527
+ action_id: actionId,
10528
+ quantity: data.quantity,
10529
+ unit_price: convertNumber(data.unit_price)
10491
10530
  },
10492
- onSettled: () => {
10493
- setIsSubmitting(false);
10531
+ {
10532
+ onSuccess: () => {
10533
+ setEditing(false);
10534
+ },
10535
+ onError: (e) => {
10536
+ ui.toast.error(e.message);
10537
+ }
10494
10538
  }
10495
- });
10496
- };
10497
- const onKeydown = React.useCallback(
10498
- (e) => {
10499
- if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10500
- if (data || isSubmitting) {
10501
- return;
10539
+ );
10540
+ });
10541
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_28px] gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center", children: [
10542
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
10543
+ /* @__PURE__ */ jsxRuntime.jsx(
10544
+ Thumbnail,
10545
+ {
10546
+ thumbnail: item.thumbnail,
10547
+ alt: item.title ?? void 0
10548
+ }
10549
+ ),
10550
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
10551
+ Form$2.Field,
10552
+ {
10553
+ control: form.control,
10554
+ name: "title",
10555
+ render: ({ field }) => {
10556
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }) });
10557
+ }
10558
+ }
10559
+ ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.title })
10560
+ ] }),
10561
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
10562
+ Form$2.Field,
10563
+ {
10564
+ control: form.control,
10565
+ name: "quantity",
10566
+ render: ({ field }) => {
10567
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10502
10568
  }
10503
- onSubmit();
10504
10569
  }
10505
- },
10506
- [data, isSubmitting, onSubmit]
10507
- );
10508
- React.useEffect(() => {
10509
- document.addEventListener("keydown", onKeydown);
10510
- return () => {
10511
- document.removeEventListener("keydown", onKeydown);
10512
- };
10513
- }, [onKeydown]);
10514
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10515
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
10516
- /* @__PURE__ */ jsxRuntime.jsxs(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: [
10517
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
10518
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10519
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
10520
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose which shipping method(s) to use for the items in the order." }) })
10521
- ] }),
10522
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10523
- /* @__PURE__ */ jsxRuntime.jsx(radixUi.Accordion.Root, { type: "multiple", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle rounded-xl shadow-elevation-card-rest", children: [
10524
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-2 flex items-center justify-between", children: [
10525
- /* @__PURE__ */ jsxRuntime.jsx(
10526
- ui.Text,
10527
- {
10528
- size: "xsmall",
10529
- weight: "plus",
10530
- className: "text-ui-fg-muted",
10531
- children: "Shipping profile"
10532
- }
10533
- ),
10534
- /* @__PURE__ */ jsxRuntime.jsx(
10535
- ui.Text,
10536
- {
10537
- size: "xsmall",
10538
- weight: "plus",
10539
- className: "text-ui-fg-muted",
10540
- children: "Action"
10541
- }
10542
- )
10543
- ] }),
10544
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-[5px] pb-[5px]", children: uniqueShippingProfiles.map((profile) => {
10545
- var _a2, _b, _c, _d, _e, _f, _g;
10546
- const items = getItemsWithShippingProfile(
10547
- profile.id,
10548
- order.items
10549
- );
10550
- const hasItems = items.length > 0;
10551
- const shippingOption = shipping_options == null ? void 0 : shipping_options.find(
10552
- (option) => option.shipping_profile_id === profile.id
10553
- );
10554
- const shippingMethod = preview.shipping_methods.find(
10555
- (method) => method.shipping_option_id === (shippingOption == null ? void 0 : shippingOption.id)
10556
- );
10557
- const addShippingMethodAction = (_a2 = shippingMethod == null ? void 0 : shippingMethod.actions) == null ? void 0 : _a2.find(
10558
- (action) => action.action === "SHIPPING_ADD"
10559
- );
10560
- return /* @__PURE__ */ jsxRuntime.jsxs(
10561
- radixUi.Accordion.Item,
10562
- {
10563
- value: profile.id,
10564
- className: "bg-ui-bg-base shadow-elevation-card-rest rounded-lg",
10565
- children: [
10566
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-2 flex items-center justify-between gap-3", children: [
10567
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3 w-full overflow-hidden", children: [
10568
- /* @__PURE__ */ jsxRuntime.jsx(radixUi.Accordion.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
10569
- ui.IconButton,
10570
- {
10571
- size: "2xsmall",
10572
- variant: "transparent",
10573
- className: "group/trigger",
10574
- disabled: !hasItems,
10575
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.TriangleRightMini, { className: "group-data-[state=open]/trigger:rotate-90 transition-transform" })
10576
- }
10577
- ) }),
10578
- !shippingOption ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
10579
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-7 rounded-md shadow-borders-base flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-6 rounded bg-ui-bg-component-hover flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Shopping, { className: "text-ui-fg-subtle" }) }) }),
10580
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col flex-1", children: [
10581
- /* @__PURE__ */ jsxRuntime.jsx(
10582
- ui.Text,
10583
- {
10584
- size: "small",
10585
- weight: "plus",
10586
- leading: "compact",
10587
- children: profile.name
10588
- }
10589
- ),
10590
- /* @__PURE__ */ jsxRuntime.jsxs(
10591
- ui.Text,
10592
- {
10593
- size: "small",
10594
- leading: "compact",
10595
- className: "text-ui-fg-subtle",
10596
- children: [
10597
- items.length,
10598
- " ",
10599
- pluralize(items.length, "items", "item")
10600
- ]
10601
- }
10602
- )
10603
- ] })
10604
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-[5px] max-sm:flex-col max-sm:items-start flex-1 w-full overflow-hidden", children: [
10605
- /* @__PURE__ */ jsxRuntime.jsx(
10606
- ui.Tooltip,
10607
- {
10608
- content: /* @__PURE__ */ jsxRuntime.jsx("ul", { children: items.map((item) => {
10609
- var _a3, _b2, _c2;
10610
- return /* @__PURE__ */ jsxRuntime.jsx(
10611
- "li",
10612
- {
10613
- children: `${item.quantity}x ${(_b2 = (_a3 = item.variant) == null ? void 0 : _a3.product) == null ? void 0 : _b2.title} (${(_c2 = item.variant) == null ? void 0 : _c2.title})`
10614
- },
10615
- item.id
10616
- );
10617
- }) }),
10618
- children: /* @__PURE__ */ jsxRuntime.jsxs(
10619
- ui.Badge,
10620
- {
10621
- className: "flex items-center gap-x-[3px] overflow-hidden cursor-default",
10622
- size: "xsmall",
10623
- children: [
10624
- /* @__PURE__ */ jsxRuntime.jsx(icons.Shopping, { className: "shrink-0" }),
10625
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "truncate", children: [
10626
- items.reduce(
10627
- (acc, item) => acc + item.quantity,
10628
- 0
10629
- ),
10630
- "x",
10631
- " ",
10632
- pluralize(items.length, "items", "item")
10633
- ] })
10634
- ]
10635
- }
10636
- )
10637
- }
10638
- ),
10639
- /* @__PURE__ */ jsxRuntime.jsx(
10640
- ui.Tooltip,
10641
- {
10642
- content: (_d = (_c = (_b = shippingOption.service_zone) == null ? void 0 : _b.fulfillment_set) == null ? void 0 : _c.location) == null ? void 0 : _d.name,
10643
- children: /* @__PURE__ */ jsxRuntime.jsxs(
10644
- ui.Badge,
10645
- {
10646
- className: "flex items-center gap-x-[3px] overflow-hidden cursor-default",
10647
- size: "xsmall",
10648
- children: [
10649
- /* @__PURE__ */ jsxRuntime.jsx(icons.Buildings, { className: "shrink-0" }),
10650
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: (_g = (_f = (_e = shippingOption.service_zone) == null ? void 0 : _e.fulfillment_set) == null ? void 0 : _f.location) == null ? void 0 : _g.name })
10651
- ]
10652
- }
10653
- )
10654
- }
10655
- ),
10656
- /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: shippingOption.name, children: /* @__PURE__ */ jsxRuntime.jsxs(
10657
- ui.Badge,
10658
- {
10659
- className: "flex items-center gap-x-[3px] overflow-hidden cursor-default",
10660
- size: "xsmall",
10661
- children: [
10662
- /* @__PURE__ */ jsxRuntime.jsx(icons.TruckFast, { className: "shrink-0" }),
10663
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: shippingOption.name })
10664
- ]
10665
- }
10666
- ) })
10667
- ] })
10668
- ] }),
10669
- shippingOption ? /* @__PURE__ */ jsxRuntime.jsx(
10670
- ActionMenu,
10671
- {
10672
- groups: [
10673
- {
10674
- actions: [
10675
- hasItems ? {
10676
- label: "Edit shipping option",
10677
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Channels, {}),
10678
- onClick: () => {
10679
- setIsOpen(
10680
- STACKED_FOCUS_MODAL_ID,
10681
- true
10682
- );
10683
- setData({
10684
- shippingProfileId: profile.id,
10685
- shippingOption,
10686
- shippingMethod
10687
- });
10688
- }
10689
- } : void 0,
10690
- {
10691
- label: "Remove shipping option",
10692
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {}),
10693
- onClick: () => {
10694
- if (shippingMethod) {
10695
- if (addShippingMethodAction) {
10696
- removeActionShippingMethod(
10697
- addShippingMethodAction.id
10698
- );
10699
- } else {
10700
- removeShippingMethod(
10701
- shippingMethod.id
10702
- );
10703
- }
10704
- }
10705
- }
10706
- }
10707
- ].filter(Boolean)
10708
- }
10709
- ]
10710
- }
10711
- ) : /* @__PURE__ */ jsxRuntime.jsx(
10712
- StackedModalTrigger$1,
10713
- {
10714
- shippingProfileId: profile.id,
10715
- shippingOption,
10716
- shippingMethod,
10717
- setData,
10718
- children: "Add shipping option"
10719
- }
10720
- )
10721
- ] }),
10722
- /* @__PURE__ */ jsxRuntime.jsxs(radixUi.Accordion.Content, { children: [
10723
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10724
- items.map((item, idx) => {
10725
- var _a3, _b2, _c2, _d2, _e2;
10726
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10727
- /* @__PURE__ */ jsxRuntime.jsxs(
10728
- "div",
10729
- {
10730
- className: "px-3 flex items-center gap-x-3",
10731
- children: [
10732
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-5 h-[56px] flex flex-col justify-center items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
10733
- ui.Divider,
10734
- {
10735
- variant: "dashed",
10736
- orientation: "vertical"
10737
- }
10738
- ) }),
10739
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-2 flex items-center gap-x-3", children: [
10740
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-7 flex items-center justify-center tabular-nums", children: /* @__PURE__ */ jsxRuntime.jsxs(
10741
- ui.Text,
10742
- {
10743
- size: "small",
10744
- leading: "compact",
10745
- className: "text-ui-fg-subtle",
10746
- children: [
10747
- item.quantity,
10748
- "x"
10749
- ]
10750
- }
10751
- ) }),
10752
- /* @__PURE__ */ jsxRuntime.jsx(Thumbnail, { thumbnail: item.thumbnail }),
10753
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10754
- /* @__PURE__ */ jsxRuntime.jsxs(
10755
- ui.Text,
10756
- {
10757
- size: "small",
10758
- leading: "compact",
10759
- weight: "plus",
10760
- children: [
10761
- (_b2 = (_a3 = item.variant) == null ? void 0 : _a3.product) == null ? void 0 : _b2.title,
10762
- " (",
10763
- (_c2 = item.variant) == null ? void 0 : _c2.title,
10764
- ")"
10765
- ]
10766
- }
10767
- ),
10768
- /* @__PURE__ */ jsxRuntime.jsx(
10769
- ui.Text,
10770
- {
10771
- size: "small",
10772
- leading: "compact",
10773
- className: "text-ui-fg-subtle",
10774
- children: (_e2 = (_d2 = item.variant) == null ? void 0 : _d2.options) == null ? void 0 : _e2.map((option) => option.value).join(" · ")
10775
- }
10776
- )
10777
- ] })
10778
- ] })
10779
- ]
10780
- },
10781
- item.id
10782
- ),
10783
- idx !== items.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" })
10784
- ] }, item.id);
10785
- })
10786
- ] })
10787
- ]
10788
- },
10789
- profile.id
10790
- );
10791
- }) })
10570
+ ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }),
10571
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
10572
+ Form$2.Field,
10573
+ {
10574
+ control: form.control,
10575
+ name: "unit_price",
10576
+ render: ({ field: { onChange, ...field } }) => {
10577
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10578
+ ui.CurrencyInput,
10579
+ {
10580
+ ...field,
10581
+ symbol: getNativeSymbol(currencyCode),
10582
+ code: currencyCode,
10583
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10584
+ }
10585
+ ) }) });
10586
+ }
10587
+ }
10588
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10589
+ /* @__PURE__ */ jsxRuntime.jsx(
10590
+ ui.IconButton,
10591
+ {
10592
+ type: "button",
10593
+ size: "small",
10594
+ onClick: editing ? onSubmit : () => {
10595
+ setEditing(true);
10596
+ },
10597
+ disabled: isPending,
10598
+ children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
10599
+ }
10600
+ )
10601
+ ] }) }) });
10602
+ };
10603
+ const StackedModalTrigger$1 = ({
10604
+ type,
10605
+ setModalContent
10606
+ }) => {
10607
+ const { setIsOpen } = useStackedModal();
10608
+ const onClick = React.useCallback(() => {
10609
+ setModalContent(type);
10610
+ setIsOpen(STACKED_MODAL_ID, true);
10611
+ }, [setModalContent, setIsOpen, type]);
10612
+ 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" }) });
10613
+ };
10614
+ const VARIANT_PREFIX = "items";
10615
+ const LIMIT = 50;
10616
+ const ExistingItemsForm = ({ orderId, items }) => {
10617
+ const { setIsOpen } = useStackedModal();
10618
+ const [rowSelection, setRowSelection] = React.useState(
10619
+ items.reduce((acc, item) => {
10620
+ acc[item.variant_id] = true;
10621
+ return acc;
10622
+ }, {})
10623
+ );
10624
+ React.useEffect(() => {
10625
+ setRowSelection(
10626
+ items.reduce((acc, item) => {
10627
+ if (item.variant_id) {
10628
+ acc[item.variant_id] = true;
10629
+ }
10630
+ return acc;
10631
+ }, {})
10632
+ );
10633
+ }, [items]);
10634
+ const { q, order, offset } = useQueryParams(
10635
+ ["q", "order", "offset"],
10636
+ VARIANT_PREFIX
10637
+ );
10638
+ const { variants, count, isPending, isError, error } = useProductVariants(
10639
+ {
10640
+ q,
10641
+ order,
10642
+ offset: offset ? parseInt(offset) : void 0,
10643
+ limit: LIMIT
10644
+ },
10645
+ {
10646
+ placeholderData: reactQuery.keepPreviousData
10647
+ }
10648
+ );
10649
+ const columns = useColumns();
10650
+ const { mutateAsync } = useDraftOrderAddItems(orderId);
10651
+ const onSubmit = async () => {
10652
+ const ids = Object.keys(rowSelection).filter(
10653
+ (id) => !items.find((i) => i.variant_id === id)
10654
+ );
10655
+ await mutateAsync(
10656
+ {
10657
+ items: ids.map((id) => ({
10658
+ variant_id: id,
10659
+ quantity: 1
10660
+ }))
10661
+ },
10662
+ {
10663
+ onSuccess: () => {
10664
+ setRowSelection({});
10665
+ setIsOpen(STACKED_MODAL_ID, false);
10666
+ },
10667
+ onError: (e) => {
10668
+ ui.toast.error(e.message);
10669
+ }
10670
+ }
10671
+ );
10672
+ };
10673
+ if (isError) {
10674
+ throw error;
10675
+ }
10676
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10677
+ StackedFocusModal.Content,
10678
+ {
10679
+ onOpenAutoFocus: (e) => {
10680
+ e.preventDefault();
10681
+ const searchInput = document.querySelector(
10682
+ "[data-modal-id='modal-search-input']"
10683
+ );
10684
+ if (searchInput) {
10685
+ searchInput.focus();
10686
+ }
10687
+ },
10688
+ children: [
10689
+ /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Header, { children: [
10690
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10691
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
10692
+ ] }),
10693
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
10694
+ DataTable,
10695
+ {
10696
+ data: variants,
10697
+ columns,
10698
+ isLoading: isPending,
10699
+ getRowId: (row) => row.id,
10700
+ rowCount: count,
10701
+ prefix: VARIANT_PREFIX,
10702
+ layout: "fill",
10703
+ rowSelection: {
10704
+ state: rowSelection,
10705
+ onRowSelectionChange: setRowSelection,
10706
+ enableRowSelection: (row) => {
10707
+ return !items.find((i) => i.variant_id === row.original.id);
10708
+ }
10709
+ },
10710
+ autoFocusSearch: true
10711
+ }
10712
+ ) }),
10713
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
10714
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10715
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
10792
10716
  ] }) })
10793
- ] }) }),
10717
+ ]
10718
+ }
10719
+ );
10720
+ };
10721
+ const columnHelper = ui.createDataTableColumnHelper();
10722
+ const useColumns = () => {
10723
+ return React.useMemo(() => {
10724
+ return [
10725
+ columnHelper.select(),
10726
+ columnHelper.accessor("product.title", {
10727
+ header: "Product",
10728
+ cell: ({ row }) => {
10729
+ var _a, _b, _c;
10730
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
10731
+ /* @__PURE__ */ jsxRuntime.jsx(
10732
+ Thumbnail,
10733
+ {
10734
+ thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
10735
+ alt: (_b = row.original.product) == null ? void 0 : _b.title
10736
+ }
10737
+ ),
10738
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
10739
+ ] });
10740
+ },
10741
+ enableSorting: true
10742
+ }),
10743
+ columnHelper.accessor("title", {
10744
+ header: "Variant",
10745
+ enableSorting: true
10746
+ }),
10747
+ columnHelper.accessor("sku", {
10748
+ header: "SKU",
10749
+ cell: ({ getValue }) => {
10750
+ return getValue() ?? "-";
10751
+ },
10752
+ enableSorting: true
10753
+ }),
10754
+ columnHelper.accessor("updated_at", {
10755
+ header: "Updated",
10756
+ cell: ({ getValue }) => {
10757
+ return /* @__PURE__ */ jsxRuntime.jsx(
10758
+ ui.Tooltip,
10759
+ {
10760
+ content: getFullDate({ date: getValue(), includeTime: true }),
10761
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
10762
+ }
10763
+ );
10764
+ },
10765
+ enableSorting: true,
10766
+ sortAscLabel: "Oldest first",
10767
+ sortDescLabel: "Newest first"
10768
+ }),
10769
+ columnHelper.accessor("created_at", {
10770
+ header: "Created",
10771
+ cell: ({ getValue }) => {
10772
+ return /* @__PURE__ */ jsxRuntime.jsx(
10773
+ ui.Tooltip,
10774
+ {
10775
+ content: getFullDate({ date: getValue(), includeTime: true }),
10776
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
10777
+ }
10778
+ );
10779
+ },
10780
+ enableSorting: true,
10781
+ sortAscLabel: "Oldest first",
10782
+ sortDescLabel: "Newest first"
10783
+ })
10784
+ ];
10785
+ }, []);
10786
+ };
10787
+ const CustomItemForm = ({ orderId, currencyCode }) => {
10788
+ const { setIsOpen } = useStackedModal();
10789
+ const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
10790
+ const form = reactHookForm.useForm({
10791
+ defaultValues: {
10792
+ title: "",
10793
+ quantity: 1,
10794
+ unit_price: ""
10795
+ },
10796
+ resolver: zod.zodResolver(customItemSchema)
10797
+ });
10798
+ const onSubmit = form.handleSubmit(async (data) => {
10799
+ await addItems(
10800
+ {
10801
+ items: [
10802
+ {
10803
+ title: data.title,
10804
+ quantity: data.quantity,
10805
+ unit_price: convertNumber(data.unit_price)
10806
+ }
10807
+ ]
10808
+ },
10809
+ {
10810
+ onSuccess: () => {
10811
+ setIsOpen(STACKED_MODAL_ID, false);
10812
+ },
10813
+ onError: (e) => {
10814
+ ui.toast.error(e.message);
10815
+ }
10816
+ }
10817
+ );
10818
+ });
10819
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Content, { children: [
10820
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
10821
+ /* @__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: [
10822
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10823
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Add custom item" }) }),
10824
+ /* @__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." }) })
10825
+ ] }),
10826
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10794
10827
  /* @__PURE__ */ jsxRuntime.jsx(
10795
- StackedFocusModal,
10828
+ Form$2.Field,
10796
10829
  {
10797
- id: STACKED_FOCUS_MODAL_ID,
10798
- onOpenChangeCallback: (open) => {
10799
- if (!open) {
10800
- setData(null);
10801
- }
10802
- return open;
10803
- },
10804
- children: data && /* @__PURE__ */ jsxRuntime.jsx(ShippingProfileForm, { data, order, preview })
10830
+ control: form.control,
10831
+ name: "title",
10832
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10833
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10834
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Title" }),
10835
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the title of the item" })
10836
+ ] }),
10837
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10838
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10839
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10840
+ ] })
10841
+ ] }) })
10842
+ }
10843
+ ),
10844
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10845
+ /* @__PURE__ */ jsxRuntime.jsx(
10846
+ Form$2.Field,
10847
+ {
10848
+ control: form.control,
10849
+ name: "unit_price",
10850
+ render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10851
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10852
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Unit price" }),
10853
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
10854
+ ] }),
10855
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10856
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10857
+ ui.CurrencyInput,
10858
+ {
10859
+ symbol: getNativeSymbol(currencyCode),
10860
+ code: currencyCode,
10861
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
10862
+ ...field
10863
+ }
10864
+ ) }),
10865
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10866
+ ] })
10867
+ ] }) })
10805
10868
  }
10806
- )
10807
- ] }),
10808
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-x-2", children: [
10809
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10869
+ ),
10870
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10810
10871
  /* @__PURE__ */ jsxRuntime.jsx(
10811
- ui.Button,
10872
+ Form$2.Field,
10812
10873
  {
10813
- size: "small",
10814
- type: "button",
10815
- isLoading: isSubmitting,
10816
- onClick: onSubmit,
10817
- children: "Save"
10874
+ control: form.control,
10875
+ name: "quantity",
10876
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10877
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10878
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Quantity" }),
10879
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
10880
+ ] }),
10881
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 w-full", children: [
10882
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field, className: "w-full" }) }) }),
10883
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10884
+ ] })
10885
+ ] }) })
10818
10886
  }
10819
10887
  )
10888
+ ] }) }) }),
10889
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
10890
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10891
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
10820
10892
  ] }) })
10821
- ] });
10893
+ ] }) }) });
10822
10894
  };
10823
- const StackedModalTrigger$1 = ({
10824
- shippingProfileId,
10825
- shippingOption,
10826
- shippingMethod,
10827
- setData,
10828
- children
10829
- }) => {
10830
- const { setIsOpen, getIsOpen } = useStackedModal();
10831
- const isOpen = getIsOpen(STACKED_FOCUS_MODAL_ID);
10832
- const onToggle = () => {
10833
- if (isOpen) {
10834
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
10835
- setData(null);
10836
- } else {
10837
- setIsOpen(STACKED_FOCUS_MODAL_ID, true);
10838
- setData({
10839
- shippingProfileId,
10840
- shippingOption,
10841
- shippingMethod
10842
- });
10843
- }
10844
- };
10845
- return /* @__PURE__ */ jsxRuntime.jsx(
10846
- ui.Button,
10847
- {
10848
- size: "small",
10849
- variant: "secondary",
10850
- onClick: onToggle,
10851
- className: "text-ui-fg-primary shrink-0",
10852
- children
10853
- }
10854
- );
10895
+ const customItemSchema = z.object({
10896
+ title: z.string().min(1),
10897
+ quantity: z.number(),
10898
+ unit_price: z.union([z.number(), z.string()])
10899
+ });
10900
+ const Email = () => {
10901
+ const { id } = reactRouterDom.useParams();
10902
+ const { order, isPending, isError, error } = useOrder(id, {
10903
+ fields: "+email"
10904
+ });
10905
+ if (isError) {
10906
+ throw error;
10907
+ }
10908
+ const isReady = !isPending && !!order;
10909
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10910
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10911
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Email" }) }),
10912
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
10913
+ ] }),
10914
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(EmailForm, { order })
10915
+ ] });
10855
10916
  };
10856
- const ShippingProfileForm = ({
10857
- data,
10858
- order,
10859
- preview
10860
- }) => {
10861
- var _a, _b, _c, _d, _e, _f;
10862
- const { setIsOpen } = useStackedModal();
10917
+ const EmailForm = ({ order }) => {
10863
10918
  const form = reactHookForm.useForm({
10864
- resolver: zod.zodResolver(shippingMethodSchema),
10865
10919
  defaultValues: {
10866
- location_id: (_d = (_c = (_b = (_a = data.shippingOption) == null ? void 0 : _a.service_zone) == null ? void 0 : _b.fulfillment_set) == null ? void 0 : _c.location) == null ? void 0 : _d.id,
10867
- shipping_option_id: (_e = data.shippingOption) == null ? void 0 : _e.id,
10868
- custom_amount: (_f = data.shippingMethod) == null ? void 0 : _f.amount
10869
- }
10920
+ email: order.email ?? ""
10921
+ },
10922
+ resolver: zod.zodResolver(schema$3)
10870
10923
  });
10871
- const { mutateAsync: addShippingMethod, isPending } = useDraftOrderAddShippingMethod(order.id);
10872
- const {
10873
- mutateAsync: updateShippingMethod,
10874
- isPending: isUpdatingShippingMethod
10875
- } = useDraftOrderUpdateShippingMethod(order.id);
10876
- const onSubmit = form.handleSubmit(async (values) => {
10877
- if (lodash.isEqual(values, form.formState.defaultValues)) {
10878
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
10879
- return;
10880
- }
10881
- if (data.shippingMethod) {
10882
- await updateShippingMethod(
10883
- {
10884
- method_id: data.shippingMethod.id,
10885
- shipping_option_id: values.shipping_option_id,
10886
- custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
10887
- },
10888
- {
10889
- onError: (e) => {
10890
- ui.toast.error(e.message);
10891
- },
10892
- onSuccess: () => {
10893
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
10894
- }
10895
- }
10896
- );
10897
- return;
10898
- }
10899
- await addShippingMethod(
10900
- {
10901
- shipping_option_id: values.shipping_option_id,
10902
- custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
10903
- },
10924
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
10925
+ const { handleSuccess } = useRouteModal();
10926
+ const onSubmit = form.handleSubmit(async (data) => {
10927
+ await mutateAsync(
10928
+ { email: data.email },
10904
10929
  {
10905
- onError: (e) => {
10906
- ui.toast.error(e.message);
10907
- },
10908
10930
  onSuccess: () => {
10909
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
10931
+ handleSuccess();
10932
+ },
10933
+ onError: (error) => {
10934
+ ui.toast.error(error.message);
10910
10935
  }
10911
10936
  }
10912
10937
  );
10913
10938
  });
10914
- return /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs(
10939
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
10915
10940
  KeyboundForm,
10916
10941
  {
10917
- className: "flex h-full flex-col overflow-hidden",
10942
+ className: "flex flex-1 flex-col overflow-hidden",
10918
10943
  onSubmit,
10919
10944
  children: [
10920
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
10921
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
10922
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10923
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
10924
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a shipping method for the selected shipping profile. You can see the items that will be shipped using this method in the preview below." }) })
10925
- ] }),
10926
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10927
- /* @__PURE__ */ jsxRuntime.jsx(
10928
- LocationField,
10929
- {
10930
- control: form.control,
10931
- setValue: form.setValue
10932
- }
10933
- ),
10934
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10935
- /* @__PURE__ */ jsxRuntime.jsx(
10936
- ShippingOptionField,
10937
- {
10938
- shippingProfileId: data.shippingProfileId,
10939
- preview,
10940
- control: form.control
10941
- }
10942
- ),
10943
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10944
- /* @__PURE__ */ jsxRuntime.jsx(
10945
- CustomAmountField,
10946
- {
10947
- control: form.control,
10948
- currencyCode: order.currency_code
10949
- }
10950
- ),
10951
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10952
- /* @__PURE__ */ jsxRuntime.jsx(
10953
- ItemsPreview,
10954
- {
10955
- order,
10956
- shippingProfileId: data.shippingProfileId
10957
- }
10958
- )
10959
- ] }) }) }),
10960
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-x-2", children: [
10961
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10962
- /* @__PURE__ */ jsxRuntime.jsx(
10963
- ui.Button,
10964
- {
10965
- size: "small",
10966
- type: "submit",
10967
- isLoading: isPending || isUpdatingShippingMethod,
10968
- children: data.shippingMethod ? "Update" : "Add"
10969
- }
10970
- )
10945
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
10946
+ Form$2.Field,
10947
+ {
10948
+ control: form.control,
10949
+ name: "email",
10950
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10951
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Email" }),
10952
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10953
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10954
+ ] })
10955
+ }
10956
+ ) }),
10957
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
10958
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10959
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10971
10960
  ] }) })
10972
10961
  ]
10973
10962
  }
10974
- ) }) });
10963
+ ) });
10975
10964
  };
10976
- const shippingMethodSchema = z.object({
10977
- location_id: z.string(),
10978
- shipping_option_id: z.string(),
10979
- custom_amount: z.union([z.number(), z.string()]).optional()
10965
+ const schema$3 = z.object({
10966
+ email: z.string().email()
10980
10967
  });
10981
- const ItemsPreview = ({ order, shippingProfileId }) => {
10982
- const matches = order.items.filter(
10983
- (item) => {
10984
- var _a, _b, _c;
10985
- return ((_c = (_b = (_a = item.variant) == null ? void 0 : _a.product) == null ? void 0 : _b.shipping_profile) == null ? void 0 : _c.id) === shippingProfileId;
10968
+ const SalesChannel = () => {
10969
+ const { id } = reactRouterDom.useParams();
10970
+ const { draft_order, isPending, isError, error } = useDraftOrder(
10971
+ id,
10972
+ {
10973
+ fields: "+sales_channel_id"
10974
+ },
10975
+ {
10976
+ enabled: !!id
10986
10977
  }
10987
10978
  );
10988
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
10989
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 items-center gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10990
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items to ship" }),
10991
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Items with the selected shipping profile." })
10992
- ] }) }),
10993
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10994
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 px-4 py-2 text-ui-fg-muted", children: [
10995
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
10996
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) })
10997
- ] }),
10998
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
10999
- "div",
11000
- {
11001
- className: "grid grid-cols-2 gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center",
11002
- children: [
11003
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
11004
- /* @__PURE__ */ jsxRuntime.jsx(
11005
- Thumbnail,
11006
- {
11007
- thumbnail: item.thumbnail,
11008
- alt: item.product_title ?? void 0
11009
- }
11010
- ),
11011
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
11012
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
11013
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
11014
- /* @__PURE__ */ jsxRuntime.jsxs(
11015
- ui.Text,
11016
- {
11017
- size: "small",
11018
- leading: "compact",
11019
- className: "text-ui-fg-subtle",
11020
- children: [
11021
- "(",
11022
- item.variant_title,
11023
- ")"
11024
- ]
11025
- }
11026
- )
11027
- ] }),
11028
- /* @__PURE__ */ jsxRuntime.jsx(
11029
- ui.Text,
11030
- {
11031
- size: "small",
11032
- leading: "compact",
11033
- className: "text-ui-fg-subtle",
11034
- children: item.variant_sku
11035
- }
11036
- )
11037
- ] })
11038
- ] }),
11039
- /* @__PURE__ */ jsxRuntime.jsxs(
11040
- ui.Text,
11041
- {
11042
- size: "small",
11043
- leading: "compact",
11044
- className: "text-ui-fg-subtle",
11045
- children: [
11046
- item.quantity,
11047
- "x"
11048
- ]
11049
- }
11050
- )
11051
- ]
11052
- },
11053
- item.id
11054
- )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
11055
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
11056
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
11057
- 'No items found for "',
11058
- query,
11059
- '".'
11060
- ] })
11061
- ] }) })
11062
- ] })
10979
+ if (isError) {
10980
+ throw error;
10981
+ }
10982
+ const ISrEADY = !!draft_order && !isPending;
10983
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10984
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10985
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
10986
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
10987
+ ] }),
10988
+ ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
11063
10989
  ] });
11064
10990
  };
11065
- const LocationField = ({ control, setValue }) => {
11066
- const locations = useComboboxData({
11067
- queryKey: ["locations"],
11068
- queryFn: async (params) => {
11069
- return await sdk.admin.stockLocation.list(params);
10991
+ const SalesChannelForm = ({ order }) => {
10992
+ const form = reactHookForm.useForm({
10993
+ defaultValues: {
10994
+ sales_channel_id: order.sales_channel_id || ""
11070
10995
  },
11071
- getOptions: (data) => {
11072
- return data.stock_locations.map((location) => ({
11073
- label: location.name,
11074
- value: location.id
11075
- }));
11076
- }
10996
+ resolver: zod.zodResolver(schema$2)
11077
10997
  });
11078
- return /* @__PURE__ */ jsxRuntime.jsx(
11079
- Form$2.Field,
11080
- {
11081
- control,
11082
- name: "location_id",
11083
- render: ({ field: { onChange, ...field } }) => {
11084
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11085
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11086
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Location" }),
11087
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose where you want to ship the items from." })
11088
- ] }),
11089
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11090
- Combobox,
11091
- {
11092
- options: locations.options,
11093
- fetchNextPage: locations.fetchNextPage,
11094
- isFetchingNextPage: locations.isFetchingNextPage,
11095
- searchValue: locations.searchValue,
11096
- onSearchValueChange: locations.onSearchValueChange,
11097
- placeholder: "Select location",
11098
- onChange: (value) => {
11099
- setValue("shipping_option_id", "", {
11100
- shouldDirty: true,
11101
- shouldTouch: true
11102
- });
11103
- onChange(value);
11104
- },
11105
- ...field
11106
- }
11107
- ) })
11108
- ] }) });
10998
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
10999
+ const { handleSuccess } = useRouteModal();
11000
+ const onSubmit = form.handleSubmit(async (data) => {
11001
+ await mutateAsync(
11002
+ {
11003
+ sales_channel_id: data.sales_channel_id
11004
+ },
11005
+ {
11006
+ onSuccess: () => {
11007
+ ui.toast.success("Sales channel updated");
11008
+ handleSuccess();
11009
+ },
11010
+ onError: (error) => {
11011
+ ui.toast.error(error.message);
11012
+ }
11109
11013
  }
11014
+ );
11015
+ });
11016
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11017
+ KeyboundForm,
11018
+ {
11019
+ className: "flex flex-1 flex-col overflow-hidden",
11020
+ onSubmit,
11021
+ children: [
11022
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
11023
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11024
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11025
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11026
+ ] }) })
11027
+ ]
11110
11028
  }
11111
- );
11029
+ ) });
11112
11030
  };
11113
- const ShippingOptionField = ({
11114
- shippingProfileId,
11115
- preview,
11116
- control
11117
- }) => {
11118
- var _a;
11119
- const locationId = reactHookForm.useWatch({ control, name: "location_id" });
11120
- const shippingOptions = useComboboxData({
11121
- queryKey: ["shipping_options", locationId, shippingProfileId],
11031
+ const SalesChannelField = ({ control, order }) => {
11032
+ const salesChannels = useComboboxData({
11122
11033
  queryFn: async (params) => {
11123
- return await sdk.admin.shippingOption.list({
11124
- ...params,
11125
- stock_location_id: locationId,
11126
- shipping_profile_id: shippingProfileId
11127
- });
11034
+ return await sdk.admin.salesChannel.list(params);
11128
11035
  },
11036
+ queryKey: ["sales-channels"],
11129
11037
  getOptions: (data) => {
11130
- return data.shipping_options.map((option) => {
11131
- var _a2;
11132
- if ((_a2 = option.rules) == null ? void 0 : _a2.find(
11133
- (r) => r.attribute === "is_return" && r.value === "true"
11134
- )) {
11135
- return void 0;
11136
- }
11137
- return {
11138
- label: option.name,
11139
- value: option.id
11140
- };
11141
- }).filter(Boolean);
11038
+ return data.sales_channels.map((salesChannel) => ({
11039
+ label: salesChannel.name,
11040
+ value: salesChannel.id
11041
+ }));
11142
11042
  },
11143
- enabled: !!locationId && !!shippingProfileId,
11144
- defaultValue: ((_a = preview.shipping_methods[0]) == null ? void 0 : _a.shipping_option_id) || void 0
11043
+ defaultValue: order.sales_channel_id || void 0
11145
11044
  });
11146
- const tooltipContent = !locationId && !shippingProfileId ? "Choose a location and shipping profile first." : !locationId ? "Choose a location first." : "Choose a shipping profile first.";
11147
11045
  return /* @__PURE__ */ jsxRuntime.jsx(
11148
11046
  Form$2.Field,
11149
11047
  {
11150
11048
  control,
11151
- name: "shipping_option_id",
11049
+ name: "sales_channel_id",
11152
11050
  render: ({ field }) => {
11153
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11154
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
11155
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Shipping option" }),
11156
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose the shipping option to use." })
11157
- ] }),
11158
- /* @__PURE__ */ jsxRuntime.jsx(
11159
- ConditionalTooltip,
11160
- {
11161
- content: tooltipContent,
11162
- showTooltip: !locationId || !shippingProfileId,
11163
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11164
- Combobox,
11165
- {
11166
- options: shippingOptions.options,
11167
- fetchNextPage: shippingOptions.fetchNextPage,
11168
- isFetchingNextPage: shippingOptions.isFetchingNextPage,
11169
- searchValue: shippingOptions.searchValue,
11170
- onSearchValueChange: shippingOptions.onSearchValueChange,
11171
- placeholder: "Select shipping option",
11172
- ...field,
11173
- disabled: !locationId || !shippingProfileId
11174
- }
11175
- ) }) })
11176
- }
11177
- )
11178
- ] }) });
11179
- }
11180
- }
11181
- );
11182
- };
11183
- const CustomAmountField = ({
11184
- control,
11185
- currencyCode
11186
- }) => {
11187
- return /* @__PURE__ */ jsxRuntime.jsx(
11188
- Form$2.Field,
11189
- {
11190
- control,
11191
- name: "custom_amount",
11192
- render: ({ field: { onChange, ...field } }) => {
11193
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11194
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
11195
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
11196
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
11197
- ] }),
11051
+ return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11052
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
11198
11053
  /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11199
- ui.CurrencyInput,
11200
- {
11201
- ...field,
11202
- onValueChange: (value) => onChange(value),
11203
- symbol: getNativeSymbol(currencyCode),
11204
- code: currencyCode
11054
+ Combobox,
11055
+ {
11056
+ options: salesChannels.options,
11057
+ fetchNextPage: salesChannels.fetchNextPage,
11058
+ isFetchingNextPage: salesChannels.isFetchingNextPage,
11059
+ searchValue: salesChannels.searchValue,
11060
+ onSearchValueChange: salesChannels.onSearchValueChange,
11061
+ placeholder: "Select sales channel",
11062
+ ...field
11205
11063
  }
11206
- ) })
11064
+ ) }),
11065
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11207
11066
  ] });
11208
11067
  }
11209
11068
  }
11210
11069
  );
11211
11070
  };
11071
+ const schema$2 = z.object({
11072
+ sales_channel_id: z.string().min(1)
11073
+ });
11212
11074
  const InlineTip = React.forwardRef(
11213
11075
  ({ variant = "tip", label, className, children, ...props }, ref) => {
11214
11076
  const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
@@ -11486,78 +11348,355 @@ const PlaceholderInner = () => {
11486
11348
  ] }) })
11487
11349
  ] });
11488
11350
  };
11489
- const EDITABLE_TYPES = ["string", "number", "boolean"];
11490
- function getDefaultValues(metadata) {
11491
- if (!metadata || !Object.keys(metadata).length) {
11492
- return [
11351
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
11352
+ function getDefaultValues(metadata) {
11353
+ if (!metadata || !Object.keys(metadata).length) {
11354
+ return [
11355
+ {
11356
+ key: "",
11357
+ value: "",
11358
+ disabled: false
11359
+ }
11360
+ ];
11361
+ }
11362
+ return Object.entries(metadata).map(([key, value]) => {
11363
+ if (!EDITABLE_TYPES.includes(typeof value)) {
11364
+ return {
11365
+ key,
11366
+ value,
11367
+ disabled: true
11368
+ };
11369
+ }
11370
+ let stringValue = value;
11371
+ if (typeof value !== "string") {
11372
+ stringValue = JSON.stringify(value);
11373
+ }
11374
+ return {
11375
+ key,
11376
+ value: stringValue,
11377
+ original_key: key
11378
+ };
11379
+ });
11380
+ }
11381
+ function parseValues(values) {
11382
+ const metadata = values.metadata;
11383
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11384
+ if (isEmpty) {
11385
+ return null;
11386
+ }
11387
+ const update = {};
11388
+ metadata.forEach((field) => {
11389
+ let key = field.key;
11390
+ let value = field.value;
11391
+ const disabled = field.disabled;
11392
+ if (!key || !value) {
11393
+ return;
11394
+ }
11395
+ if (disabled) {
11396
+ update[key] = value;
11397
+ return;
11398
+ }
11399
+ key = key.trim();
11400
+ value = value.trim();
11401
+ if (value === "true") {
11402
+ update[key] = true;
11403
+ } else if (value === "false") {
11404
+ update[key] = false;
11405
+ } else {
11406
+ const parsedNumber = parseFloat(value);
11407
+ if (!isNaN(parsedNumber)) {
11408
+ update[key] = parsedNumber;
11409
+ } else {
11410
+ update[key] = value;
11411
+ }
11412
+ }
11413
+ });
11414
+ return update;
11415
+ }
11416
+ function getHasUneditableRows(metadata) {
11417
+ if (!metadata) {
11418
+ return false;
11419
+ }
11420
+ return Object.values(metadata).some(
11421
+ (value) => !EDITABLE_TYPES.includes(typeof value)
11422
+ );
11423
+ }
11424
+ const PROMOTION_QUERY_KEY = "promotions";
11425
+ const promotionsQueryKeys = {
11426
+ list: (query2) => [
11427
+ PROMOTION_QUERY_KEY,
11428
+ query2 ? query2 : void 0
11429
+ ],
11430
+ detail: (id, query2) => [
11431
+ PROMOTION_QUERY_KEY,
11432
+ id,
11433
+ query2 ? query2 : void 0
11434
+ ]
11435
+ };
11436
+ const usePromotions = (query2, options) => {
11437
+ const { data, ...rest } = reactQuery.useQuery({
11438
+ queryKey: promotionsQueryKeys.list(query2),
11439
+ queryFn: async () => sdk.admin.promotion.list(query2),
11440
+ ...options
11441
+ });
11442
+ return { ...data, ...rest };
11443
+ };
11444
+ const Promotions = () => {
11445
+ const { id } = reactRouterDom.useParams();
11446
+ const {
11447
+ order: preview,
11448
+ isError: isPreviewError,
11449
+ error: previewError
11450
+ } = useOrderPreview(id, void 0);
11451
+ useInitiateOrderEdit({ preview });
11452
+ const { onCancel } = useCancelOrderEdit({ preview });
11453
+ if (isPreviewError) {
11454
+ throw previewError;
11455
+ }
11456
+ const isReady = !!preview;
11457
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
11458
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
11459
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
11460
+ ] });
11461
+ };
11462
+ const PromotionForm = ({ preview }) => {
11463
+ const { items, shipping_methods } = preview;
11464
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
11465
+ const [comboboxValue, setComboboxValue] = React.useState("");
11466
+ const { handleSuccess } = useRouteModal();
11467
+ const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
11468
+ const promoCodes = getPromotionCodes(items, shipping_methods);
11469
+ const { promotions, isPending, isError, error } = usePromotions(
11470
+ {
11471
+ code: promoCodes
11472
+ },
11473
+ {
11474
+ enabled: !!promoCodes.length
11475
+ }
11476
+ );
11477
+ const comboboxData = useComboboxData({
11478
+ queryKey: ["promotions", "combobox", promoCodes],
11479
+ queryFn: async (params) => {
11480
+ return await sdk.admin.promotion.list({
11481
+ ...params,
11482
+ code: {
11483
+ $nin: promoCodes
11484
+ }
11485
+ });
11486
+ },
11487
+ getOptions: (data) => {
11488
+ return data.promotions.map((promotion) => ({
11489
+ label: promotion.code,
11490
+ value: promotion.code
11491
+ }));
11492
+ }
11493
+ });
11494
+ const add = async (value) => {
11495
+ if (!value) {
11496
+ return;
11497
+ }
11498
+ addPromotions(
11499
+ {
11500
+ promo_codes: [value]
11501
+ },
11502
+ {
11503
+ onError: (e) => {
11504
+ ui.toast.error(e.message);
11505
+ comboboxData.onSearchValueChange("");
11506
+ setComboboxValue("");
11507
+ },
11508
+ onSuccess: () => {
11509
+ comboboxData.onSearchValueChange("");
11510
+ setComboboxValue("");
11511
+ }
11512
+ }
11513
+ );
11514
+ };
11515
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11516
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
11517
+ const onSubmit = async () => {
11518
+ setIsSubmitting(true);
11519
+ let requestSucceeded = false;
11520
+ await requestOrderEdit(void 0, {
11521
+ onError: (e) => {
11522
+ ui.toast.error(e.message);
11523
+ },
11524
+ onSuccess: () => {
11525
+ requestSucceeded = true;
11526
+ }
11527
+ });
11528
+ if (!requestSucceeded) {
11529
+ setIsSubmitting(false);
11530
+ return;
11531
+ }
11532
+ await confirmOrderEdit(void 0, {
11533
+ onError: (e) => {
11534
+ ui.toast.error(e.message);
11535
+ },
11536
+ onSuccess: () => {
11537
+ handleSuccess();
11538
+ },
11539
+ onSettled: () => {
11540
+ setIsSubmitting(false);
11541
+ }
11542
+ });
11543
+ };
11544
+ if (isError) {
11545
+ throw error;
11546
+ }
11547
+ return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
11548
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
11549
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
11550
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
11551
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
11552
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
11553
+ ] }),
11554
+ /* @__PURE__ */ jsxRuntime.jsx(
11555
+ Combobox,
11556
+ {
11557
+ id: "promotion-combobox",
11558
+ "aria-describedby": "promotion-combobox-hint",
11559
+ isFetchingNextPage: comboboxData.isFetchingNextPage,
11560
+ fetchNextPage: comboboxData.fetchNextPage,
11561
+ options: comboboxData.options,
11562
+ onSearchValueChange: comboboxData.onSearchValueChange,
11563
+ searchValue: comboboxData.searchValue,
11564
+ disabled: comboboxData.disabled || isAddingPromotions,
11565
+ onChange: add,
11566
+ value: comboboxValue
11567
+ }
11568
+ )
11569
+ ] }),
11570
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11571
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
11572
+ PromotionItem,
11573
+ {
11574
+ promotion,
11575
+ orderId: preview.id,
11576
+ isLoading: isPending
11577
+ },
11578
+ promotion.id
11579
+ )) })
11580
+ ] }) }),
11581
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11582
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11583
+ /* @__PURE__ */ jsxRuntime.jsx(
11584
+ ui.Button,
11585
+ {
11586
+ size: "small",
11587
+ type: "submit",
11588
+ isLoading: isSubmitting || isAddingPromotions,
11589
+ children: "Save"
11590
+ }
11591
+ )
11592
+ ] }) })
11593
+ ] });
11594
+ };
11595
+ const PromotionItem = ({
11596
+ promotion,
11597
+ orderId,
11598
+ isLoading
11599
+ }) => {
11600
+ var _a;
11601
+ const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
11602
+ const onRemove = async () => {
11603
+ removePromotions(
11493
11604
  {
11494
- key: "",
11495
- value: "",
11496
- disabled: false
11605
+ promo_codes: [promotion.code]
11606
+ },
11607
+ {
11608
+ onError: (e) => {
11609
+ ui.toast.error(e.message);
11610
+ }
11497
11611
  }
11498
- ];
11612
+ );
11613
+ };
11614
+ const displayValue = getDisplayValue(promotion);
11615
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11616
+ "div",
11617
+ {
11618
+ className: ui.clx(
11619
+ "px-3 py-2 rounded-lg bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between",
11620
+ {
11621
+ "animate-pulse": isLoading
11622
+ }
11623
+ ),
11624
+ children: [
11625
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11626
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11627
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-ui-fg-subtle", children: [
11628
+ displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
11629
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
11630
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
11631
+ ] }),
11632
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11633
+ ] })
11634
+ ] }),
11635
+ /* @__PURE__ */ jsxRuntime.jsx(
11636
+ ui.IconButton,
11637
+ {
11638
+ size: "small",
11639
+ type: "button",
11640
+ variant: "transparent",
11641
+ onClick: onRemove,
11642
+ isLoading: isPending || isLoading,
11643
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
11644
+ }
11645
+ )
11646
+ ]
11647
+ },
11648
+ promotion.id
11649
+ );
11650
+ };
11651
+ function getDisplayValue(promotion) {
11652
+ var _a, _b, _c, _d;
11653
+ const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11654
+ if (!value) {
11655
+ return null;
11499
11656
  }
11500
- return Object.entries(metadata).map(([key, value]) => {
11501
- if (!EDITABLE_TYPES.includes(typeof value)) {
11502
- return {
11503
- key,
11504
- value,
11505
- disabled: true
11506
- };
11507
- }
11508
- let stringValue = value;
11509
- if (typeof value !== "string") {
11510
- stringValue = JSON.stringify(value);
11657
+ if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11658
+ const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11659
+ if (!currency) {
11660
+ return null;
11511
11661
  }
11512
- return {
11513
- key,
11514
- value: stringValue,
11515
- original_key: key
11516
- };
11517
- });
11662
+ return getLocaleAmount(value, currency);
11663
+ } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11664
+ return formatPercentage(value);
11665
+ }
11666
+ return null;
11518
11667
  }
11519
- function parseValues(values) {
11520
- const metadata = values.metadata;
11521
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11522
- if (isEmpty) {
11523
- return null;
11668
+ const formatter = new Intl.NumberFormat([], {
11669
+ style: "percent",
11670
+ minimumFractionDigits: 2
11671
+ });
11672
+ const formatPercentage = (value, isPercentageValue = false) => {
11673
+ let val = value || 0;
11674
+ if (!isPercentageValue) {
11675
+ val = val / 100;
11524
11676
  }
11525
- const update = {};
11526
- metadata.forEach((field) => {
11527
- let key = field.key;
11528
- let value = field.value;
11529
- const disabled = field.disabled;
11530
- if (!key || !value) {
11531
- return;
11532
- }
11533
- if (disabled) {
11534
- update[key] = value;
11535
- return;
11677
+ return formatter.format(val);
11678
+ };
11679
+ function getPromotionCodes(items, shippingMethods) {
11680
+ const codes = /* @__PURE__ */ new Set();
11681
+ for (const item of items) {
11682
+ if (item.adjustments) {
11683
+ for (const adjustment of item.adjustments) {
11684
+ if (adjustment.code) {
11685
+ codes.add(adjustment.code);
11686
+ }
11687
+ }
11536
11688
  }
11537
- key = key.trim();
11538
- value = value.trim();
11539
- if (value === "true") {
11540
- update[key] = true;
11541
- } else if (value === "false") {
11542
- update[key] = false;
11543
- } else {
11544
- const parsedNumber = parseFloat(value);
11545
- if (!isNaN(parsedNumber)) {
11546
- update[key] = parsedNumber;
11547
- } else {
11548
- update[key] = value;
11689
+ }
11690
+ for (const shippingMethod of shippingMethods) {
11691
+ if (shippingMethod.adjustments) {
11692
+ for (const adjustment of shippingMethod.adjustments) {
11693
+ if (adjustment.code) {
11694
+ codes.add(adjustment.code);
11695
+ }
11549
11696
  }
11550
11697
  }
11551
- });
11552
- return update;
11553
- }
11554
- function getHasUneditableRows(metadata) {
11555
- if (!metadata) {
11556
- return false;
11557
11698
  }
11558
- return Object.values(metadata).some(
11559
- (value) => !EDITABLE_TYPES.includes(typeof value)
11560
- );
11699
+ return Array.from(codes);
11561
11700
  }
11562
11701
  const ShippingAddress = () => {
11563
11702
  const { id } = reactRouterDom.useParams();
@@ -11591,7 +11730,7 @@ const ShippingAddressForm = ({ order }) => {
11591
11730
  postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
11592
11731
  phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
11593
11732
  },
11594
- resolver: zod.zodResolver(schema$2)
11733
+ resolver: zod.zodResolver(schema$1)
11595
11734
  });
11596
11735
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11597
11736
  const { handleSuccess } = useRouteModal();
@@ -11761,7 +11900,7 @@ const ShippingAddressForm = ({ order }) => {
11761
11900
  }
11762
11901
  ) });
11763
11902
  };
11764
- const schema$2 = addressSchema;
11903
+ const schema$1 = addressSchema;
11765
11904
  const TransferOwnership = () => {
11766
11905
  const { id } = reactRouterDom.useParams();
11767
11906
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -11785,7 +11924,7 @@ const TransferOwnershipForm = ({ order }) => {
11785
11924
  defaultValues: {
11786
11925
  customer_id: order.customer_id || ""
11787
11926
  },
11788
- resolver: zod.zodResolver(schema$1)
11927
+ resolver: zod.zodResolver(schema)
11789
11928
  });
11790
11929
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11791
11930
  const { handleSuccess } = useRouteModal();
@@ -12189,201 +12328,69 @@ const Illustration = () => {
12189
12328
  "rect",
12190
12329
  {
12191
12330
  width: "12",
12192
- height: "12",
12193
- fill: "white",
12194
- transform: "matrix(0.865865 0.500278 -0.871576 0.490261 148.75 80.6541)"
12195
- }
12196
- ) }),
12197
- /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip2_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
12198
- "rect",
12199
- {
12200
- width: "12",
12201
- height: "12",
12202
- fill: "white",
12203
- transform: "matrix(0.865865 0.500278 -0.871576 0.490261 159.141 86.6575)"
12204
- }
12205
- ) }),
12206
- /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip3_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
12207
- "rect",
12208
- {
12209
- width: "12",
12210
- height: "12",
12211
- fill: "white",
12212
- transform: "matrix(0.865865 0.500278 -0.871576 0.490261 120.928 84.4561)"
12213
- }
12214
- ) }),
12215
- /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip4_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
12216
- "rect",
12217
- {
12218
- width: "12",
12219
- height: "12",
12220
- fill: "white",
12221
- transform: "matrix(0.865865 0.500278 -0.871576 0.490261 131.318 90.4594)"
12222
- }
12223
- ) }),
12224
- /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip5_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
12225
- "rect",
12226
- {
12227
- width: "12",
12228
- height: "12",
12229
- fill: "white",
12230
- transform: "matrix(0.865865 0.500278 -0.871576 0.490261 141.709 96.4627)"
12231
- }
12232
- ) })
12233
- ] })
12234
- ]
12235
- }
12236
- );
12237
- };
12238
- const schema$1 = z.object({
12239
- customer_id: z.string().min(1)
12240
- });
12241
- const NumberInput = React.forwardRef(
12242
- ({
12243
- value,
12244
- onChange,
12245
- size = "base",
12246
- min = 0,
12247
- max = 100,
12248
- step = 1,
12249
- className,
12250
- disabled,
12251
- ...props
12252
- }, ref) => {
12253
- const handleChange = (event) => {
12254
- const newValue = event.target.value === "" ? min : Number(event.target.value);
12255
- if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
12256
- onChange(newValue);
12257
- }
12258
- };
12259
- const handleIncrement = () => {
12260
- const newValue = value + step;
12261
- if (max === void 0 || newValue <= max) {
12262
- onChange(newValue);
12263
- }
12264
- };
12265
- const handleDecrement = () => {
12266
- const newValue = value - step;
12267
- if (min === void 0 || newValue >= min) {
12268
- onChange(newValue);
12269
- }
12270
- };
12271
- return /* @__PURE__ */ jsxRuntime.jsxs(
12272
- "div",
12273
- {
12274
- className: ui.clx(
12275
- "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
12276
- "[&:has(input:focus)]:shadow-borders-interactive-with-active",
12277
- {
12278
- "h-7": size === "small",
12279
- "h-8": size === "base"
12280
- },
12281
- className
12282
- ),
12283
- children: [
12284
- /* @__PURE__ */ jsxRuntime.jsx(
12285
- "input",
12331
+ height: "12",
12332
+ fill: "white",
12333
+ transform: "matrix(0.865865 0.500278 -0.871576 0.490261 148.75 80.6541)"
12334
+ }
12335
+ ) }),
12336
+ /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip2_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
12337
+ "rect",
12286
12338
  {
12287
- ref,
12288
- type: "number",
12289
- value,
12290
- onChange: handleChange,
12291
- min,
12292
- max,
12293
- step,
12294
- className: ui.clx(
12295
- "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
12296
- "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
12297
- "placeholder:text-ui-fg-muted"
12298
- ),
12299
- ...props
12339
+ width: "12",
12340
+ height: "12",
12341
+ fill: "white",
12342
+ transform: "matrix(0.865865 0.500278 -0.871576 0.490261 159.141 86.6575)"
12300
12343
  }
12301
- ),
12302
- /* @__PURE__ */ jsxRuntime.jsxs(
12303
- "button",
12344
+ ) }),
12345
+ /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip3_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
12346
+ "rect",
12304
12347
  {
12305
- className: ui.clx(
12306
- "flex items-center justify-center outline-none transition-fg",
12307
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
12308
- "focus:bg-ui-bg-field-component-hover",
12309
- "hover:bg-ui-bg-field-component-hover",
12310
- {
12311
- "size-7": size === "small",
12312
- "size-8": size === "base"
12313
- }
12314
- ),
12315
- type: "button",
12316
- onClick: handleDecrement,
12317
- disabled: min !== void 0 && value <= min || disabled,
12318
- children: [
12319
- /* @__PURE__ */ jsxRuntime.jsx(icons.Minus, {}),
12320
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
12321
- ]
12348
+ width: "12",
12349
+ height: "12",
12350
+ fill: "white",
12351
+ transform: "matrix(0.865865 0.500278 -0.871576 0.490261 120.928 84.4561)"
12322
12352
  }
12323
- ),
12324
- /* @__PURE__ */ jsxRuntime.jsxs(
12325
- "button",
12353
+ ) }),
12354
+ /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip4_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
12355
+ "rect",
12326
12356
  {
12327
- className: ui.clx(
12328
- "flex items-center justify-center outline-none transition-fg",
12329
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
12330
- "focus:bg-ui-bg-field-hover",
12331
- "hover:bg-ui-bg-field-hover",
12332
- {
12333
- "size-7": size === "small",
12334
- "size-8": size === "base"
12335
- }
12336
- ),
12337
- type: "button",
12338
- onClick: handleIncrement,
12339
- disabled: max !== void 0 && value >= max || disabled,
12340
- children: [
12341
- /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
12342
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Increase by ${step}` })
12343
- ]
12357
+ width: "12",
12358
+ height: "12",
12359
+ fill: "white",
12360
+ transform: "matrix(0.865865 0.500278 -0.871576 0.490261 131.318 90.4594)"
12344
12361
  }
12345
- )
12346
- ]
12347
- }
12348
- );
12349
- }
12350
- );
12351
- const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
12352
- const productVariantsQueryKeys = {
12353
- list: (query2) => [
12354
- PRODUCT_VARIANTS_QUERY_KEY,
12355
- query2 ? query2 : void 0
12356
- ]
12357
- };
12358
- const useProductVariants = (query2, options) => {
12359
- const { data, ...rest } = reactQuery.useQuery({
12360
- queryKey: productVariantsQueryKeys.list(query2),
12361
- queryFn: async () => await sdk.admin.productVariant.list(query2),
12362
- ...options
12363
- });
12364
- return { ...data, ...rest };
12362
+ ) }),
12363
+ /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip5_20915_38670", children: /* @__PURE__ */ jsxRuntime.jsx(
12364
+ "rect",
12365
+ {
12366
+ width: "12",
12367
+ height: "12",
12368
+ fill: "white",
12369
+ transform: "matrix(0.865865 0.500278 -0.871576 0.490261 141.709 96.4627)"
12370
+ }
12371
+ ) })
12372
+ ] })
12373
+ ]
12374
+ }
12375
+ );
12365
12376
  };
12366
- const STACKED_MODAL_ID = "items_stacked_modal";
12367
- const Items = () => {
12377
+ const schema = z.object({
12378
+ customer_id: z.string().min(1)
12379
+ });
12380
+ const STACKED_FOCUS_MODAL_ID = "shipping-form";
12381
+ const Shipping = () => {
12382
+ var _a;
12368
12383
  const { id } = reactRouterDom.useParams();
12384
+ const { order, isPending, isError, error } = useOrder(id, {
12385
+ fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
12386
+ });
12369
12387
  const {
12370
12388
  order: preview,
12371
12389
  isPending: isPreviewPending,
12372
12390
  isError: isPreviewError,
12373
12391
  error: previewError
12374
- } = useOrderPreview(id, void 0, {
12375
- placeholderData: reactQuery.keepPreviousData
12376
- });
12392
+ } = useOrderPreview(id);
12377
12393
  useInitiateOrderEdit({ preview });
12378
- const { draft_order, isPending, isError, error } = useDraftOrder(
12379
- id,
12380
- {
12381
- fields: "currency_code"
12382
- },
12383
- {
12384
- enabled: !!id
12385
- }
12386
- );
12387
12394
  const { onCancel } = useCancelOrderEdit({ preview });
12388
12395
  if (isError) {
12389
12396
  throw error;
@@ -12391,28 +12398,50 @@ const Items = () => {
12391
12398
  if (isPreviewError) {
12392
12399
  throw previewError;
12393
12400
  }
12394
- const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
12395
- return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsxRuntime.jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12396
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Items" }) }),
12401
+ const orderHasItems = (((_a = order == null ? void 0 : order.items) == null ? void 0 : _a.length) || 0) > 0;
12402
+ const isReady = preview && !isPreviewPending && order && !isPending;
12403
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
12404
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
12405
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
12406
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
12407
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This draft order currently has no items. Add items to the order before adding shipping." }) })
12408
+ ] }) }) }),
12409
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }) })
12410
+ ] }) : isReady ? /* @__PURE__ */ jsxRuntime.jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12411
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
12397
12412
  /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
12398
12413
  ] }) });
12399
12414
  };
12400
- const ItemsForm = ({ preview, currencyCode }) => {
12415
+ const ShippingForm = ({ preview, order }) => {
12401
12416
  var _a;
12417
+ const { setIsOpen } = useStackedModal();
12402
12418
  const [isSubmitting, setIsSubmitting] = React.useState(false);
12403
- const [modalContent, setModalContent] = React.useState(
12404
- null
12419
+ const [data, setData] = React.useState(null);
12420
+ const appliedShippingOptionIds = (_a = preview.shipping_methods) == null ? void 0 : _a.map((method) => method.shipping_option_id).filter(Boolean);
12421
+ const { shipping_options } = useShippingOptions(
12422
+ {
12423
+ id: appliedShippingOptionIds,
12424
+ fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
12425
+ },
12426
+ {
12427
+ enabled: appliedShippingOptionIds.length > 0
12428
+ }
12405
12429
  );
12430
+ const uniqueShippingProfiles = React.useMemo(() => {
12431
+ const profiles = /* @__PURE__ */ new Map();
12432
+ getUniqueShippingProfiles(order.items).forEach((profile) => {
12433
+ profiles.set(profile.id, profile);
12434
+ });
12435
+ shipping_options == null ? void 0 : shipping_options.forEach((option) => {
12436
+ profiles.set(option.shipping_profile_id, option.shipping_profile);
12437
+ });
12438
+ return Array.from(profiles.values());
12439
+ }, [order.items, shipping_options]);
12406
12440
  const { handleSuccess } = useRouteModal();
12407
- const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
12408
12441
  const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
12409
12442
  const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
12410
- const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
12411
- const matches = React.useMemo(() => {
12412
- return matchSorter.matchSorter(preview.items, query2, {
12413
- keys: ["product_title", "variant_title", "variant_sku", "title"]
12414
- });
12415
- }, [preview.items, query2]);
12443
+ const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
12444
+ const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
12416
12445
  const onSubmit = async () => {
12417
12446
  setIsSubmitting(true);
12418
12447
  let requestSucceeded = false;
@@ -12440,750 +12469,721 @@ const ItemsForm = ({ preview, currencyCode }) => {
12440
12469
  }
12441
12470
  });
12442
12471
  };
12443
- const onKeyDown = React.useCallback(
12472
+ const onKeydown = React.useCallback(
12444
12473
  (e) => {
12445
12474
  if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
12446
- if (modalContent || isSubmitting) {
12475
+ if (data || isSubmitting) {
12447
12476
  return;
12448
12477
  }
12449
12478
  onSubmit();
12450
12479
  }
12451
12480
  },
12452
- [modalContent, isSubmitting, onSubmit]
12481
+ [data, isSubmitting, onSubmit]
12453
12482
  );
12454
12483
  React.useEffect(() => {
12455
- document.addEventListener("keydown", onKeyDown);
12484
+ document.addEventListener("keydown", onKeydown);
12456
12485
  return () => {
12457
- document.removeEventListener("keydown", onKeyDown);
12486
+ document.removeEventListener("keydown", onKeydown);
12458
12487
  };
12459
- }, [onKeyDown]);
12488
+ }, [onKeydown]);
12460
12489
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
12461
12490
  /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
12462
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
12463
- StackedFocusModal,
12464
- {
12465
- id: STACKED_MODAL_ID,
12466
- onOpenChangeCallback: (open) => {
12467
- if (!open) {
12468
- setModalContent(null);
12469
- }
12470
- },
12471
- children: [
12472
- /* @__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: [
12473
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12474
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Items" }) }),
12475
- /* @__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." }) })
12476
- ] }),
12477
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12478
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
12479
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
12480
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12481
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
12482
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
12483
- ] }),
12484
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
12485
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
12486
- ui.Input,
12487
- {
12488
- type: "search",
12489
- placeholder: "Search items",
12490
- value: searchValue,
12491
- onChange: (e) => onSearchValueChange(e.target.value)
12492
- }
12493
- ) }),
12494
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
12495
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}) }) }),
12496
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
12497
- /* @__PURE__ */ jsxRuntime.jsx(
12498
- StackedModalTrigger,
12499
- {
12500
- type: "add-items",
12501
- setModalContent
12502
- }
12503
- ),
12504
- /* @__PURE__ */ jsxRuntime.jsx(
12505
- StackedModalTrigger,
12491
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: [
12492
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
12493
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12494
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
12495
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose which shipping method(s) to use for the items in the order." }) })
12496
+ ] }),
12497
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12498
+ /* @__PURE__ */ jsxRuntime.jsx(radixUi.Accordion.Root, { type: "multiple", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle rounded-xl shadow-elevation-card-rest", children: [
12499
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-2 flex items-center justify-between", children: [
12500
+ /* @__PURE__ */ jsxRuntime.jsx(
12501
+ ui.Text,
12502
+ {
12503
+ size: "xsmall",
12504
+ weight: "plus",
12505
+ className: "text-ui-fg-muted",
12506
+ children: "Shipping profile"
12507
+ }
12508
+ ),
12509
+ /* @__PURE__ */ jsxRuntime.jsx(
12510
+ ui.Text,
12511
+ {
12512
+ size: "xsmall",
12513
+ weight: "plus",
12514
+ className: "text-ui-fg-muted",
12515
+ children: "Action"
12516
+ }
12517
+ )
12518
+ ] }),
12519
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-[5px] pb-[5px]", children: uniqueShippingProfiles.map((profile) => {
12520
+ var _a2, _b, _c, _d, _e, _f, _g;
12521
+ const items = getItemsWithShippingProfile(
12522
+ profile.id,
12523
+ order.items
12524
+ );
12525
+ const hasItems = items.length > 0;
12526
+ const shippingOption = shipping_options == null ? void 0 : shipping_options.find(
12527
+ (option) => option.shipping_profile_id === profile.id
12528
+ );
12529
+ const shippingMethod = preview.shipping_methods.find(
12530
+ (method) => method.shipping_option_id === (shippingOption == null ? void 0 : shippingOption.id)
12531
+ );
12532
+ const addShippingMethodAction = (_a2 = shippingMethod == null ? void 0 : shippingMethod.actions) == null ? void 0 : _a2.find(
12533
+ (action) => action.action === "SHIPPING_ADD"
12534
+ );
12535
+ return /* @__PURE__ */ jsxRuntime.jsxs(
12536
+ radixUi.Accordion.Item,
12537
+ {
12538
+ value: profile.id,
12539
+ className: "bg-ui-bg-base shadow-elevation-card-rest rounded-lg",
12540
+ children: [
12541
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-2 flex items-center justify-between gap-3", children: [
12542
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3 w-full overflow-hidden", children: [
12543
+ /* @__PURE__ */ jsxRuntime.jsx(radixUi.Accordion.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
12544
+ ui.IconButton,
12506
12545
  {
12507
- type: "add-custom-item",
12508
- setModalContent
12546
+ size: "2xsmall",
12547
+ variant: "transparent",
12548
+ className: "group/trigger",
12549
+ disabled: !hasItems,
12550
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.TriangleRightMini, { className: "group-data-[state=open]/trigger:rotate-90 transition-transform" })
12509
12551
  }
12510
- )
12511
- ] })
12512
- ] })
12513
- ] })
12514
- ] }),
12515
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
12516
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_1fr_1fr_28px] gap-3 px-4 py-2 text-ui-fg-muted", children: [
12517
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
12518
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) }),
12519
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Price" }) }),
12520
- /* @__PURE__ */ jsxRuntime.jsx("div", {})
12521
- ] }) }),
12522
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
12523
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
12524
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
12525
- ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
12526
- Item,
12527
- {
12528
- item,
12529
- preview,
12530
- currencyCode
12531
- },
12532
- item.id
12533
- )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
12534
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
12535
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
12536
- 'No items found for "',
12537
- query2,
12538
- '".'
12552
+ ) }),
12553
+ !shippingOption ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
12554
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-7 rounded-md shadow-borders-base flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-6 rounded bg-ui-bg-component-hover flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Shopping, { className: "text-ui-fg-subtle" }) }) }),
12555
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col flex-1", children: [
12556
+ /* @__PURE__ */ jsxRuntime.jsx(
12557
+ ui.Text,
12558
+ {
12559
+ size: "small",
12560
+ weight: "plus",
12561
+ leading: "compact",
12562
+ children: profile.name
12563
+ }
12564
+ ),
12565
+ /* @__PURE__ */ jsxRuntime.jsxs(
12566
+ ui.Text,
12567
+ {
12568
+ size: "small",
12569
+ leading: "compact",
12570
+ className: "text-ui-fg-subtle",
12571
+ children: [
12572
+ items.length,
12573
+ " ",
12574
+ pluralize(items.length, "items", "item")
12575
+ ]
12576
+ }
12577
+ )
12578
+ ] })
12579
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-[5px] max-sm:flex-col max-sm:items-start flex-1 w-full overflow-hidden", children: [
12580
+ /* @__PURE__ */ jsxRuntime.jsx(
12581
+ ui.Tooltip,
12582
+ {
12583
+ content: /* @__PURE__ */ jsxRuntime.jsx("ul", { children: items.map((item) => {
12584
+ var _a3, _b2, _c2;
12585
+ return /* @__PURE__ */ jsxRuntime.jsx(
12586
+ "li",
12587
+ {
12588
+ children: `${item.quantity}x ${(_b2 = (_a3 = item.variant) == null ? void 0 : _a3.product) == null ? void 0 : _b2.title} (${(_c2 = item.variant) == null ? void 0 : _c2.title})`
12589
+ },
12590
+ item.id
12591
+ );
12592
+ }) }),
12593
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
12594
+ ui.Badge,
12595
+ {
12596
+ className: "flex items-center gap-x-[3px] overflow-hidden cursor-default",
12597
+ size: "xsmall",
12598
+ children: [
12599
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Shopping, { className: "shrink-0" }),
12600
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "truncate", children: [
12601
+ items.reduce(
12602
+ (acc, item) => acc + item.quantity,
12603
+ 0
12604
+ ),
12605
+ "x",
12606
+ " ",
12607
+ pluralize(items.length, "items", "item")
12608
+ ] })
12609
+ ]
12610
+ }
12611
+ )
12612
+ }
12613
+ ),
12614
+ /* @__PURE__ */ jsxRuntime.jsx(
12615
+ ui.Tooltip,
12616
+ {
12617
+ content: (_d = (_c = (_b = shippingOption.service_zone) == null ? void 0 : _b.fulfillment_set) == null ? void 0 : _c.location) == null ? void 0 : _d.name,
12618
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
12619
+ ui.Badge,
12620
+ {
12621
+ className: "flex items-center gap-x-[3px] overflow-hidden cursor-default",
12622
+ size: "xsmall",
12623
+ children: [
12624
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Buildings, { className: "shrink-0" }),
12625
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: (_g = (_f = (_e = shippingOption.service_zone) == null ? void 0 : _e.fulfillment_set) == null ? void 0 : _f.location) == null ? void 0 : _g.name })
12626
+ ]
12627
+ }
12628
+ )
12629
+ }
12630
+ ),
12631
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { content: shippingOption.name, children: /* @__PURE__ */ jsxRuntime.jsxs(
12632
+ ui.Badge,
12633
+ {
12634
+ className: "flex items-center gap-x-[3px] overflow-hidden cursor-default",
12635
+ size: "xsmall",
12636
+ children: [
12637
+ /* @__PURE__ */ jsxRuntime.jsx(icons.TruckFast, { className: "shrink-0" }),
12638
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: shippingOption.name })
12639
+ ]
12640
+ }
12641
+ ) })
12642
+ ] })
12643
+ ] }),
12644
+ shippingOption ? /* @__PURE__ */ jsxRuntime.jsx(
12645
+ ActionMenu,
12646
+ {
12647
+ groups: [
12648
+ {
12649
+ actions: [
12650
+ hasItems ? {
12651
+ label: "Edit shipping option",
12652
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Channels, {}),
12653
+ onClick: () => {
12654
+ setIsOpen(
12655
+ STACKED_FOCUS_MODAL_ID,
12656
+ true
12657
+ );
12658
+ setData({
12659
+ shippingProfileId: profile.id,
12660
+ shippingOption,
12661
+ shippingMethod
12662
+ });
12663
+ }
12664
+ } : void 0,
12665
+ {
12666
+ label: "Remove shipping option",
12667
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {}),
12668
+ onClick: () => {
12669
+ if (shippingMethod) {
12670
+ if (addShippingMethodAction) {
12671
+ removeActionShippingMethod(
12672
+ addShippingMethodAction.id
12673
+ );
12674
+ } else {
12675
+ removeShippingMethod(
12676
+ shippingMethod.id
12677
+ );
12678
+ }
12679
+ }
12680
+ }
12681
+ }
12682
+ ].filter(Boolean)
12683
+ }
12684
+ ]
12685
+ }
12686
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
12687
+ StackedModalTrigger,
12688
+ {
12689
+ shippingProfileId: profile.id,
12690
+ shippingOption,
12691
+ shippingMethod,
12692
+ setData,
12693
+ children: "Add shipping option"
12694
+ }
12695
+ )
12696
+ ] }),
12697
+ /* @__PURE__ */ jsxRuntime.jsxs(radixUi.Accordion.Content, { children: [
12698
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12699
+ items.map((item, idx) => {
12700
+ var _a3, _b2, _c2, _d2, _e2;
12701
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12702
+ /* @__PURE__ */ jsxRuntime.jsxs(
12703
+ "div",
12704
+ {
12705
+ className: "px-3 flex items-center gap-x-3",
12706
+ children: [
12707
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-5 h-[56px] flex flex-col justify-center items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
12708
+ ui.Divider,
12709
+ {
12710
+ variant: "dashed",
12711
+ orientation: "vertical"
12712
+ }
12713
+ ) }),
12714
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-2 flex items-center gap-x-3", children: [
12715
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "size-7 flex items-center justify-center tabular-nums", children: /* @__PURE__ */ jsxRuntime.jsxs(
12716
+ ui.Text,
12717
+ {
12718
+ size: "small",
12719
+ leading: "compact",
12720
+ className: "text-ui-fg-subtle",
12721
+ children: [
12722
+ item.quantity,
12723
+ "x"
12724
+ ]
12725
+ }
12726
+ ) }),
12727
+ /* @__PURE__ */ jsxRuntime.jsx(Thumbnail, { thumbnail: item.thumbnail }),
12728
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12729
+ /* @__PURE__ */ jsxRuntime.jsxs(
12730
+ ui.Text,
12731
+ {
12732
+ size: "small",
12733
+ leading: "compact",
12734
+ weight: "plus",
12735
+ children: [
12736
+ (_b2 = (_a3 = item.variant) == null ? void 0 : _a3.product) == null ? void 0 : _b2.title,
12737
+ " (",
12738
+ (_c2 = item.variant) == null ? void 0 : _c2.title,
12739
+ ")"
12740
+ ]
12741
+ }
12742
+ ),
12743
+ /* @__PURE__ */ jsxRuntime.jsx(
12744
+ ui.Text,
12745
+ {
12746
+ size: "small",
12747
+ leading: "compact",
12748
+ className: "text-ui-fg-subtle",
12749
+ children: (_e2 = (_d2 = item.variant) == null ? void 0 : _d2.options) == null ? void 0 : _e2.map((option) => option.value).join(" · ")
12750
+ }
12751
+ )
12752
+ ] })
12753
+ ] })
12754
+ ]
12755
+ },
12756
+ item.id
12757
+ ),
12758
+ idx !== items.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" })
12759
+ ] }, item.id);
12760
+ })
12539
12761
  ] })
12540
- ] }) })
12541
- ] })
12542
- ] }),
12543
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12544
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
12545
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
12546
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(
12547
- ui.Text,
12548
- {
12549
- size: "small",
12550
- leading: "compact",
12551
- className: "text-ui-fg-subtle",
12552
- children: [
12553
- itemCount,
12554
- " ",
12555
- itemCount === 1 ? "item" : "items"
12556
- ]
12557
- }
12558
- ) }),
12559
- /* @__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) }) })
12560
- ] })
12561
- ] }) }),
12562
- modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsxRuntime.jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsxRuntime.jsx(
12563
- CustomItemForm,
12564
- {
12565
- orderId: preview.id,
12566
- currencyCode
12762
+ ]
12763
+ },
12764
+ profile.id
12765
+ );
12766
+ }) })
12767
+ ] }) })
12768
+ ] }) }),
12769
+ /* @__PURE__ */ jsxRuntime.jsx(
12770
+ StackedFocusModal,
12771
+ {
12772
+ id: STACKED_FOCUS_MODAL_ID,
12773
+ onOpenChangeCallback: (open) => {
12774
+ if (!open) {
12775
+ setData(null);
12567
12776
  }
12568
- ) : null)
12569
- ]
12570
- }
12571
- ) }),
12572
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
12777
+ return open;
12778
+ },
12779
+ children: data && /* @__PURE__ */ jsxRuntime.jsx(ShippingProfileForm, { data, order, preview })
12780
+ }
12781
+ )
12782
+ ] }),
12783
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-x-2", children: [
12573
12784
  /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12574
12785
  /* @__PURE__ */ jsxRuntime.jsx(
12575
12786
  ui.Button,
12576
12787
  {
12577
12788
  size: "small",
12578
12789
  type: "button",
12579
- onClick: onSubmit,
12580
12790
  isLoading: isSubmitting,
12791
+ onClick: onSubmit,
12581
12792
  children: "Save"
12582
12793
  }
12583
12794
  )
12584
12795
  ] }) })
12585
12796
  ] });
12586
12797
  };
12587
- const Item = ({ item, preview, currencyCode }) => {
12588
- if (item.variant_id) {
12589
- return /* @__PURE__ */ jsxRuntime.jsx(VariantItem, { item, preview, currencyCode });
12590
- }
12591
- return /* @__PURE__ */ jsxRuntime.jsx(CustomItem, { item, preview, currencyCode });
12592
- };
12593
- const VariantItem = ({ item, preview, currencyCode }) => {
12594
- const [editing, setEditing] = React.useState(false);
12595
- const form = reactHookForm.useForm({
12596
- defaultValues: {
12597
- quantity: item.quantity,
12598
- unit_price: item.unit_price
12599
- },
12600
- resolver: zod.zodResolver(variantItemSchema)
12601
- });
12602
- const actionId = React.useMemo(() => {
12603
- var _a, _b;
12604
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
12605
- }, [item]);
12606
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
12607
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
12608
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
12609
- const onSubmit = form.handleSubmit(async (data) => {
12610
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
12611
- setEditing(false);
12612
- return;
12798
+ const StackedModalTrigger = ({
12799
+ shippingProfileId,
12800
+ shippingOption,
12801
+ shippingMethod,
12802
+ setData,
12803
+ children
12804
+ }) => {
12805
+ const { setIsOpen, getIsOpen } = useStackedModal();
12806
+ const isOpen = getIsOpen(STACKED_FOCUS_MODAL_ID);
12807
+ const onToggle = () => {
12808
+ if (isOpen) {
12809
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12810
+ setData(null);
12811
+ } else {
12812
+ setIsOpen(STACKED_FOCUS_MODAL_ID, true);
12813
+ setData({
12814
+ shippingProfileId,
12815
+ shippingOption,
12816
+ shippingMethod
12817
+ });
12613
12818
  }
12614
- if (!actionId) {
12615
- await updateOriginalItem(
12616
- {
12617
- item_id: item.id,
12618
- quantity: data.quantity,
12619
- unit_price: convertNumber(data.unit_price)
12620
- },
12621
- {
12622
- onSuccess: () => {
12623
- setEditing(false);
12624
- },
12625
- onError: (e) => {
12626
- ui.toast.error(e.message);
12627
- }
12628
- }
12629
- );
12630
- return;
12819
+ };
12820
+ return /* @__PURE__ */ jsxRuntime.jsx(
12821
+ ui.Button,
12822
+ {
12823
+ size: "small",
12824
+ variant: "secondary",
12825
+ onClick: onToggle,
12826
+ className: "text-ui-fg-primary shrink-0",
12827
+ children
12631
12828
  }
12632
- await updateActionItem(
12633
- {
12634
- action_id: actionId,
12635
- quantity: data.quantity,
12636
- unit_price: convertNumber(data.unit_price)
12637
- },
12638
- {
12639
- onSuccess: () => {
12640
- setEditing(false);
12641
- },
12642
- onError: (e) => {
12643
- ui.toast.error(e.message);
12644
- }
12645
- }
12646
- );
12647
- });
12648
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_28px] gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center", children: [
12649
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3 w-full", children: [
12650
- /* @__PURE__ */ jsxRuntime.jsx(
12651
- Thumbnail,
12652
- {
12653
- thumbnail: item.thumbnail,
12654
- alt: item.product_title ?? void 0
12655
- }
12656
- ),
12657
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12658
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
12659
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
12660
- /* @__PURE__ */ jsxRuntime.jsxs(
12661
- ui.Text,
12662
- {
12663
- size: "small",
12664
- leading: "compact",
12665
- className: "text-ui-fg-subtle",
12666
- children: [
12667
- "(",
12668
- item.variant_title,
12669
- ")"
12670
- ]
12671
- }
12672
- )
12673
- ] }),
12674
- /* @__PURE__ */ jsxRuntime.jsx(
12675
- ui.Text,
12676
- {
12677
- size: "small",
12678
- leading: "compact",
12679
- className: "text-ui-fg-subtle",
12680
- children: item.variant_sku
12681
- }
12682
- )
12683
- ] })
12684
- ] }),
12685
- editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
12686
- Form$2.Field,
12687
- {
12688
- control: form.control,
12689
- name: "quantity",
12690
- render: ({ field }) => {
12691
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
12692
- }
12693
- }
12694
- ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }) }),
12695
- editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
12696
- Form$2.Field,
12697
- {
12698
- control: form.control,
12699
- name: "unit_price",
12700
- render: ({ field: { onChange, ...field } }) => {
12701
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12702
- ui.CurrencyInput,
12703
- {
12704
- ...field,
12705
- symbol: getNativeSymbol(currencyCode),
12706
- code: currencyCode,
12707
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
12708
- }
12709
- ) }) });
12710
- }
12711
- }
12712
- ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex items-center justify-end w-full", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
12713
- /* @__PURE__ */ jsxRuntime.jsx(
12714
- ui.IconButton,
12715
- {
12716
- type: "button",
12717
- size: "small",
12718
- onClick: editing ? onSubmit : () => {
12719
- setEditing(true);
12720
- },
12721
- disabled: isPending,
12722
- children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
12723
- }
12724
- )
12725
- ] }) }) });
12829
+ );
12726
12830
  };
12727
- const variantItemSchema = z.object({
12728
- quantity: z.number(),
12729
- unit_price: z.union([z.number(), z.string()])
12730
- });
12731
- const CustomItem = ({ item, preview, currencyCode }) => {
12732
- const [editing, setEditing] = React.useState(false);
12733
- const { quantity, unit_price, title } = item;
12831
+ const ShippingProfileForm = ({
12832
+ data,
12833
+ order,
12834
+ preview
12835
+ }) => {
12836
+ var _a, _b, _c, _d, _e, _f;
12837
+ const { setIsOpen } = useStackedModal();
12734
12838
  const form = reactHookForm.useForm({
12839
+ resolver: zod.zodResolver(shippingMethodSchema),
12735
12840
  defaultValues: {
12736
- title,
12737
- quantity,
12738
- unit_price
12739
- },
12740
- resolver: zod.zodResolver(customItemSchema)
12841
+ location_id: (_d = (_c = (_b = (_a = data.shippingOption) == null ? void 0 : _a.service_zone) == null ? void 0 : _b.fulfillment_set) == null ? void 0 : _c.location) == null ? void 0 : _d.id,
12842
+ shipping_option_id: (_e = data.shippingOption) == null ? void 0 : _e.id,
12843
+ custom_amount: (_f = data.shippingMethod) == null ? void 0 : _f.amount
12844
+ }
12741
12845
  });
12742
- React.useEffect(() => {
12743
- form.reset({
12744
- title,
12745
- quantity,
12746
- unit_price
12747
- });
12748
- }, [form, title, quantity, unit_price]);
12749
- const actionId = React.useMemo(() => {
12750
- var _a, _b;
12751
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
12752
- }, [item]);
12753
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
12754
- const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
12755
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
12756
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
12757
- const onSubmit = form.handleSubmit(async (data) => {
12758
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
12759
- setEditing(false);
12846
+ const { mutateAsync: addShippingMethod, isPending } = useDraftOrderAddShippingMethod(order.id);
12847
+ const {
12848
+ mutateAsync: updateShippingMethod,
12849
+ isPending: isUpdatingShippingMethod
12850
+ } = useDraftOrderUpdateShippingMethod(order.id);
12851
+ const onSubmit = form.handleSubmit(async (values) => {
12852
+ if (lodash.isEqual(values, form.formState.defaultValues)) {
12853
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12760
12854
  return;
12761
12855
  }
12762
- if (!actionId) {
12763
- await updateOriginalItem(
12856
+ if (data.shippingMethod) {
12857
+ await updateShippingMethod(
12764
12858
  {
12765
- item_id: item.id,
12766
- quantity: data.quantity,
12767
- unit_price: convertNumber(data.unit_price)
12859
+ method_id: data.shippingMethod.id,
12860
+ shipping_option_id: values.shipping_option_id,
12861
+ custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
12768
12862
  },
12769
12863
  {
12770
- onSuccess: () => {
12771
- setEditing(false);
12772
- },
12773
12864
  onError: (e) => {
12774
12865
  ui.toast.error(e.message);
12866
+ },
12867
+ onSuccess: () => {
12868
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12775
12869
  }
12776
12870
  }
12777
12871
  );
12778
12872
  return;
12779
12873
  }
12780
- if (data.quantity === 0) {
12781
- await removeActionItem(actionId, {
12782
- onSuccess: () => {
12783
- setEditing(false);
12784
- },
12785
- onError: (e) => {
12786
- ui.toast.error(e.message);
12787
- }
12788
- });
12789
- return;
12790
- }
12791
- await updateActionItem(
12792
- {
12793
- action_id: actionId,
12794
- quantity: data.quantity,
12795
- unit_price: convertNumber(data.unit_price)
12796
- },
12797
- {
12798
- onSuccess: () => {
12799
- setEditing(false);
12800
- },
12801
- onError: (e) => {
12802
- ui.toast.error(e.message);
12803
- }
12804
- }
12805
- );
12806
- });
12807
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_28px] gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center", children: [
12808
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
12809
- /* @__PURE__ */ jsxRuntime.jsx(
12810
- Thumbnail,
12811
- {
12812
- thumbnail: item.thumbnail,
12813
- alt: item.title ?? void 0
12814
- }
12815
- ),
12816
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
12817
- Form$2.Field,
12818
- {
12819
- control: form.control,
12820
- name: "title",
12821
- render: ({ field }) => {
12822
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }) });
12823
- }
12824
- }
12825
- ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.title })
12826
- ] }),
12827
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
12828
- Form$2.Field,
12829
- {
12830
- control: form.control,
12831
- name: "quantity",
12832
- render: ({ field }) => {
12833
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
12834
- }
12835
- }
12836
- ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }),
12837
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
12838
- Form$2.Field,
12839
- {
12840
- control: form.control,
12841
- name: "unit_price",
12842
- render: ({ field: { onChange, ...field } }) => {
12843
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12844
- ui.CurrencyInput,
12845
- {
12846
- ...field,
12847
- symbol: getNativeSymbol(currencyCode),
12848
- code: currencyCode,
12849
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
12850
- }
12851
- ) }) });
12852
- }
12853
- }
12854
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
12855
- /* @__PURE__ */ jsxRuntime.jsx(
12856
- ui.IconButton,
12857
- {
12858
- type: "button",
12859
- size: "small",
12860
- onClick: editing ? onSubmit : () => {
12861
- setEditing(true);
12862
- },
12863
- disabled: isPending,
12864
- children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
12865
- }
12866
- )
12867
- ] }) }) });
12868
- };
12869
- const StackedModalTrigger = ({
12870
- type,
12871
- setModalContent
12872
- }) => {
12873
- const { setIsOpen } = useStackedModal();
12874
- const onClick = React.useCallback(() => {
12875
- setModalContent(type);
12876
- setIsOpen(STACKED_MODAL_ID, true);
12877
- }, [setModalContent, setIsOpen, type]);
12878
- 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" }) });
12879
- };
12880
- const VARIANT_PREFIX = "items";
12881
- const LIMIT = 50;
12882
- const ExistingItemsForm = ({ orderId, items }) => {
12883
- const { setIsOpen } = useStackedModal();
12884
- const [rowSelection, setRowSelection] = React.useState(
12885
- items.reduce((acc, item) => {
12886
- acc[item.variant_id] = true;
12887
- return acc;
12888
- }, {})
12889
- );
12890
- React.useEffect(() => {
12891
- setRowSelection(
12892
- items.reduce((acc, item) => {
12893
- if (item.variant_id) {
12894
- acc[item.variant_id] = true;
12895
- }
12896
- return acc;
12897
- }, {})
12898
- );
12899
- }, [items]);
12900
- const { q, order, offset } = useQueryParams(
12901
- ["q", "order", "offset"],
12902
- VARIANT_PREFIX
12903
- );
12904
- const { variants, count, isPending, isError, error } = useProductVariants(
12905
- {
12906
- q,
12907
- order,
12908
- offset: offset ? parseInt(offset) : void 0,
12909
- limit: LIMIT
12910
- },
12911
- {
12912
- placeholderData: reactQuery.keepPreviousData
12913
- }
12914
- );
12915
- const columns = useColumns();
12916
- const { mutateAsync } = useDraftOrderAddItems(orderId);
12917
- const onSubmit = async () => {
12918
- const ids = Object.keys(rowSelection).filter(
12919
- (id) => !items.find((i) => i.variant_id === id)
12920
- );
12921
- await mutateAsync(
12922
- {
12923
- items: ids.map((id) => ({
12924
- variant_id: id,
12925
- quantity: 1
12926
- }))
12927
- },
12874
+ await addShippingMethod(
12928
12875
  {
12929
- onSuccess: () => {
12930
- setRowSelection({});
12931
- setIsOpen(STACKED_MODAL_ID, false);
12932
- },
12933
- onError: (e) => {
12934
- ui.toast.error(e.message);
12935
- }
12936
- }
12937
- );
12938
- };
12939
- if (isError) {
12940
- throw error;
12941
- }
12942
- return /* @__PURE__ */ jsxRuntime.jsxs(
12943
- StackedFocusModal.Content,
12944
- {
12945
- onOpenAutoFocus: (e) => {
12946
- e.preventDefault();
12947
- const searchInput = document.querySelector(
12948
- "[data-modal-id='modal-search-input']"
12949
- );
12950
- if (searchInput) {
12951
- searchInput.focus();
12952
- }
12953
- },
12954
- children: [
12955
- /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Header, { children: [
12956
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Product Variants" }) }),
12957
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
12958
- ] }),
12959
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
12960
- DataTable,
12961
- {
12962
- data: variants,
12963
- columns,
12964
- isLoading: isPending,
12965
- getRowId: (row) => row.id,
12966
- rowCount: count,
12967
- prefix: VARIANT_PREFIX,
12968
- layout: "fill",
12969
- rowSelection: {
12970
- state: rowSelection,
12971
- onRowSelectionChange: setRowSelection,
12972
- enableRowSelection: (row) => {
12973
- return !items.find((i) => i.variant_id === row.original.id);
12974
- }
12975
- },
12976
- autoFocusSearch: true
12977
- }
12978
- ) }),
12979
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
12876
+ shipping_option_id: values.shipping_option_id,
12877
+ custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
12878
+ },
12879
+ {
12880
+ onError: (e) => {
12881
+ ui.toast.error(e.message);
12882
+ },
12883
+ onSuccess: () => {
12884
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
12885
+ }
12886
+ }
12887
+ );
12888
+ });
12889
+ return /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12890
+ KeyboundForm,
12891
+ {
12892
+ className: "flex h-full flex-col overflow-hidden",
12893
+ onSubmit,
12894
+ children: [
12895
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
12896
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
12897
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12898
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
12899
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a shipping method for the selected shipping profile. You can see the items that will be shipped using this method in the preview below." }) })
12900
+ ] }),
12901
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12902
+ /* @__PURE__ */ jsxRuntime.jsx(
12903
+ LocationField,
12904
+ {
12905
+ control: form.control,
12906
+ setValue: form.setValue
12907
+ }
12908
+ ),
12909
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12910
+ /* @__PURE__ */ jsxRuntime.jsx(
12911
+ ShippingOptionField,
12912
+ {
12913
+ shippingProfileId: data.shippingProfileId,
12914
+ preview,
12915
+ control: form.control
12916
+ }
12917
+ ),
12918
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12919
+ /* @__PURE__ */ jsxRuntime.jsx(
12920
+ CustomAmountField,
12921
+ {
12922
+ control: form.control,
12923
+ currencyCode: order.currency_code
12924
+ }
12925
+ ),
12926
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12927
+ /* @__PURE__ */ jsxRuntime.jsx(
12928
+ ItemsPreview,
12929
+ {
12930
+ order,
12931
+ shippingProfileId: data.shippingProfileId
12932
+ }
12933
+ )
12934
+ ] }) }) }),
12935
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-x-2", children: [
12980
12936
  /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12981
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
12937
+ /* @__PURE__ */ jsxRuntime.jsx(
12938
+ ui.Button,
12939
+ {
12940
+ size: "small",
12941
+ type: "submit",
12942
+ isLoading: isPending || isUpdatingShippingMethod,
12943
+ children: data.shippingMethod ? "Update" : "Add"
12944
+ }
12945
+ )
12982
12946
  ] }) })
12983
12947
  ]
12984
12948
  }
12985
- );
12949
+ ) }) });
12986
12950
  };
12987
- const columnHelper = ui.createDataTableColumnHelper();
12988
- const useColumns = () => {
12989
- return React.useMemo(() => {
12990
- return [
12991
- columnHelper.select(),
12992
- columnHelper.accessor("product.title", {
12993
- header: "Product",
12994
- cell: ({ row }) => {
12995
- var _a, _b, _c;
12996
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
12997
- /* @__PURE__ */ jsxRuntime.jsx(
12998
- Thumbnail,
12951
+ const shippingMethodSchema = z.object({
12952
+ location_id: z.string(),
12953
+ shipping_option_id: z.string(),
12954
+ custom_amount: z.union([z.number(), z.string()]).optional()
12955
+ });
12956
+ const ItemsPreview = ({ order, shippingProfileId }) => {
12957
+ const matches = order.items.filter(
12958
+ (item) => {
12959
+ var _a, _b, _c;
12960
+ return ((_c = (_b = (_a = item.variant) == null ? void 0 : _a.product) == null ? void 0 : _b.shipping_profile) == null ? void 0 : _c.id) === shippingProfileId;
12961
+ }
12962
+ );
12963
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
12964
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 items-center gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12965
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items to ship" }),
12966
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Items with the selected shipping profile." })
12967
+ ] }) }),
12968
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
12969
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 px-4 py-2 text-ui-fg-muted", children: [
12970
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
12971
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) })
12972
+ ] }),
12973
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
12974
+ "div",
12975
+ {
12976
+ className: "grid grid-cols-2 gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center",
12977
+ children: [
12978
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
12979
+ /* @__PURE__ */ jsxRuntime.jsx(
12980
+ Thumbnail,
12981
+ {
12982
+ thumbnail: item.thumbnail,
12983
+ alt: item.product_title ?? void 0
12984
+ }
12985
+ ),
12986
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12987
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
12988
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
12989
+ /* @__PURE__ */ jsxRuntime.jsxs(
12990
+ ui.Text,
12991
+ {
12992
+ size: "small",
12993
+ leading: "compact",
12994
+ className: "text-ui-fg-subtle",
12995
+ children: [
12996
+ "(",
12997
+ item.variant_title,
12998
+ ")"
12999
+ ]
13000
+ }
13001
+ )
13002
+ ] }),
13003
+ /* @__PURE__ */ jsxRuntime.jsx(
13004
+ ui.Text,
13005
+ {
13006
+ size: "small",
13007
+ leading: "compact",
13008
+ className: "text-ui-fg-subtle",
13009
+ children: item.variant_sku
13010
+ }
13011
+ )
13012
+ ] })
13013
+ ] }),
13014
+ /* @__PURE__ */ jsxRuntime.jsxs(
13015
+ ui.Text,
12999
13016
  {
13000
- thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
13001
- alt: (_b = row.original.product) == null ? void 0 : _b.title
13017
+ size: "small",
13018
+ leading: "compact",
13019
+ className: "text-ui-fg-subtle",
13020
+ children: [
13021
+ item.quantity,
13022
+ "x"
13023
+ ]
13002
13024
  }
13003
- ),
13004
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
13005
- ] });
13006
- },
13007
- enableSorting: true
13008
- }),
13009
- columnHelper.accessor("title", {
13010
- header: "Variant",
13011
- enableSorting: true
13012
- }),
13013
- columnHelper.accessor("sku", {
13014
- header: "SKU",
13015
- cell: ({ getValue }) => {
13016
- return getValue() ?? "-";
13017
- },
13018
- enableSorting: true
13019
- }),
13020
- columnHelper.accessor("updated_at", {
13021
- header: "Updated",
13022
- cell: ({ getValue }) => {
13023
- return /* @__PURE__ */ jsxRuntime.jsx(
13024
- ui.Tooltip,
13025
- {
13026
- content: getFullDate({ date: getValue(), includeTime: true }),
13027
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
13028
- }
13029
- );
13025
+ )
13026
+ ]
13030
13027
  },
13031
- enableSorting: true,
13032
- sortAscLabel: "Oldest first",
13033
- sortDescLabel: "Newest first"
13034
- }),
13035
- columnHelper.accessor("created_at", {
13036
- header: "Created",
13037
- cell: ({ getValue }) => {
13038
- return /* @__PURE__ */ jsxRuntime.jsx(
13039
- ui.Tooltip,
13028
+ item.id
13029
+ )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
13030
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
13031
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
13032
+ 'No items found for "',
13033
+ query,
13034
+ '".'
13035
+ ] })
13036
+ ] }) })
13037
+ ] })
13038
+ ] });
13039
+ };
13040
+ const LocationField = ({ control, setValue }) => {
13041
+ const locations = useComboboxData({
13042
+ queryKey: ["locations"],
13043
+ queryFn: async (params) => {
13044
+ return await sdk.admin.stockLocation.list(params);
13045
+ },
13046
+ getOptions: (data) => {
13047
+ return data.stock_locations.map((location) => ({
13048
+ label: location.name,
13049
+ value: location.id
13050
+ }));
13051
+ }
13052
+ });
13053
+ return /* @__PURE__ */ jsxRuntime.jsx(
13054
+ Form$2.Field,
13055
+ {
13056
+ control,
13057
+ name: "location_id",
13058
+ render: ({ field: { onChange, ...field } }) => {
13059
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
13060
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
13061
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Location" }),
13062
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose where you want to ship the items from." })
13063
+ ] }),
13064
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
13065
+ Combobox,
13040
13066
  {
13041
- content: getFullDate({ date: getValue(), includeTime: true }),
13042
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
13043
- }
13044
- );
13045
- },
13046
- enableSorting: true,
13047
- sortAscLabel: "Oldest first",
13048
- sortDescLabel: "Newest first"
13049
- })
13050
- ];
13051
- }, []);
13067
+ options: locations.options,
13068
+ fetchNextPage: locations.fetchNextPage,
13069
+ isFetchingNextPage: locations.isFetchingNextPage,
13070
+ searchValue: locations.searchValue,
13071
+ onSearchValueChange: locations.onSearchValueChange,
13072
+ placeholder: "Select location",
13073
+ onChange: (value) => {
13074
+ setValue("shipping_option_id", "", {
13075
+ shouldDirty: true,
13076
+ shouldTouch: true
13077
+ });
13078
+ onChange(value);
13079
+ },
13080
+ ...field
13081
+ }
13082
+ ) })
13083
+ ] }) });
13084
+ }
13085
+ }
13086
+ );
13052
13087
  };
13053
- const CustomItemForm = ({ orderId, currencyCode }) => {
13054
- const { setIsOpen } = useStackedModal();
13055
- const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
13056
- const form = reactHookForm.useForm({
13057
- defaultValues: {
13058
- title: "",
13059
- quantity: 1,
13060
- unit_price: ""
13088
+ const ShippingOptionField = ({
13089
+ shippingProfileId,
13090
+ preview,
13091
+ control
13092
+ }) => {
13093
+ var _a;
13094
+ const locationId = reactHookForm.useWatch({ control, name: "location_id" });
13095
+ const shippingOptions = useComboboxData({
13096
+ queryKey: ["shipping_options", locationId, shippingProfileId],
13097
+ queryFn: async (params) => {
13098
+ return await sdk.admin.shippingOption.list({
13099
+ ...params,
13100
+ stock_location_id: locationId,
13101
+ shipping_profile_id: shippingProfileId
13102
+ });
13061
13103
  },
13062
- resolver: zod.zodResolver(customItemSchema)
13063
- });
13064
- const onSubmit = form.handleSubmit(async (data) => {
13065
- await addItems(
13066
- {
13067
- items: [
13068
- {
13069
- title: data.title,
13070
- quantity: data.quantity,
13071
- unit_price: convertNumber(data.unit_price)
13072
- }
13073
- ]
13074
- },
13075
- {
13076
- onSuccess: () => {
13077
- setIsOpen(STACKED_MODAL_ID, false);
13078
- },
13079
- onError: (e) => {
13080
- ui.toast.error(e.message);
13104
+ getOptions: (data) => {
13105
+ return data.shipping_options.map((option) => {
13106
+ var _a2;
13107
+ if ((_a2 = option.rules) == null ? void 0 : _a2.find(
13108
+ (r) => r.attribute === "is_return" && r.value === "true"
13109
+ )) {
13110
+ return void 0;
13081
13111
  }
13082
- }
13083
- );
13112
+ return {
13113
+ label: option.name,
13114
+ value: option.id
13115
+ };
13116
+ }).filter(Boolean);
13117
+ },
13118
+ enabled: !!locationId && !!shippingProfileId,
13119
+ defaultValue: ((_a = preview.shipping_methods[0]) == null ? void 0 : _a.shipping_option_id) || void 0
13084
13120
  });
13085
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Content, { children: [
13086
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
13087
- /* @__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: [
13088
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
13089
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Add custom item" }) }),
13090
- /* @__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." }) })
13091
- ] }),
13092
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
13093
- /* @__PURE__ */ jsxRuntime.jsx(
13094
- Form$2.Field,
13095
- {
13096
- control: form.control,
13097
- name: "title",
13098
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
13099
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
13100
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Title" }),
13101
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the title of the item" })
13102
- ] }),
13103
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
13104
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
13105
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
13106
- ] })
13107
- ] }) })
13108
- }
13109
- ),
13110
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
13111
- /* @__PURE__ */ jsxRuntime.jsx(
13112
- Form$2.Field,
13113
- {
13114
- control: form.control,
13115
- name: "unit_price",
13116
- render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
13117
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
13118
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Unit price" }),
13119
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
13120
- ] }),
13121
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
13122
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
13123
- ui.CurrencyInput,
13121
+ const tooltipContent = !locationId && !shippingProfileId ? "Choose a location and shipping profile first." : !locationId ? "Choose a location first." : "Choose a shipping profile first.";
13122
+ return /* @__PURE__ */ jsxRuntime.jsx(
13123
+ Form$2.Field,
13124
+ {
13125
+ control,
13126
+ name: "shipping_option_id",
13127
+ render: ({ field }) => {
13128
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
13129
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
13130
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Shipping option" }),
13131
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose the shipping option to use." })
13132
+ ] }),
13133
+ /* @__PURE__ */ jsxRuntime.jsx(
13134
+ ConditionalTooltip,
13135
+ {
13136
+ content: tooltipContent,
13137
+ showTooltip: !locationId || !shippingProfileId,
13138
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
13139
+ Combobox,
13124
13140
  {
13125
- symbol: getNativeSymbol(currencyCode),
13126
- code: currencyCode,
13127
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
13128
- ...field
13141
+ options: shippingOptions.options,
13142
+ fetchNextPage: shippingOptions.fetchNextPage,
13143
+ isFetchingNextPage: shippingOptions.isFetchingNextPage,
13144
+ searchValue: shippingOptions.searchValue,
13145
+ onSearchValueChange: shippingOptions.onSearchValueChange,
13146
+ placeholder: "Select shipping option",
13147
+ ...field,
13148
+ disabled: !locationId || !shippingProfileId
13129
13149
  }
13130
- ) }),
13131
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
13132
- ] })
13133
- ] }) })
13134
- }
13135
- ),
13136
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
13137
- /* @__PURE__ */ jsxRuntime.jsx(
13138
- Form$2.Field,
13139
- {
13140
- control: form.control,
13141
- name: "quantity",
13142
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
13143
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
13144
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Quantity" }),
13145
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
13146
- ] }),
13147
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 w-full", children: [
13148
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field, className: "w-full" }) }) }),
13149
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
13150
- ] })
13151
- ] }) })
13152
- }
13153
- )
13154
- ] }) }) }),
13155
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
13156
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
13157
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
13158
- ] }) })
13159
- ] }) }) });
13160
- };
13161
- const customItemSchema = z.object({
13162
- title: z.string().min(1),
13163
- quantity: z.number(),
13164
- unit_price: z.union([z.number(), z.string()])
13165
- });
13166
- const CustomItems = () => {
13167
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
13168
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Custom Items" }) }) }),
13169
- /* @__PURE__ */ jsxRuntime.jsx(CustomItemsForm, {})
13170
- ] });
13150
+ ) }) })
13151
+ }
13152
+ )
13153
+ ] }) });
13154
+ }
13155
+ }
13156
+ );
13171
13157
  };
13172
- const CustomItemsForm = () => {
13173
- const form = reactHookForm.useForm({
13174
- resolver: zod.zodResolver(schema)
13175
- });
13176
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
13177
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, {}),
13178
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
13179
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
13180
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", children: "Save" })
13181
- ] }) })
13182
- ] }) });
13158
+ const CustomAmountField = ({
13159
+ control,
13160
+ currencyCode
13161
+ }) => {
13162
+ return /* @__PURE__ */ jsxRuntime.jsx(
13163
+ Form$2.Field,
13164
+ {
13165
+ control,
13166
+ name: "custom_amount",
13167
+ render: ({ field: { onChange, ...field } }) => {
13168
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
13169
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
13170
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
13171
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
13172
+ ] }),
13173
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
13174
+ ui.CurrencyInput,
13175
+ {
13176
+ ...field,
13177
+ onValueChange: (value) => onChange(value),
13178
+ symbol: getNativeSymbol(currencyCode),
13179
+ code: currencyCode
13180
+ }
13181
+ ) })
13182
+ ] });
13183
+ }
13184
+ }
13185
+ );
13183
13186
  };
13184
- const schema = z.object({
13185
- email: z.string().email()
13186
- });
13187
13187
  const widgetModule = { widgets: [] };
13188
13188
  const routeModule = {
13189
13189
  routes: [
@@ -13209,25 +13209,29 @@ const routeModule = {
13209
13209
  path: "/draft-orders/:id/billing-address"
13210
13210
  },
13211
13211
  {
13212
- Component: Email,
13213
- path: "/draft-orders/:id/email"
13212
+ Component: CustomItems,
13213
+ path: "/draft-orders/:id/custom-items"
13214
13214
  },
13215
13215
  {
13216
- Component: Promotions,
13217
- path: "/draft-orders/:id/promotions"
13216
+ Component: Items,
13217
+ path: "/draft-orders/:id/items"
13218
13218
  },
13219
13219
  {
13220
- Component: SalesChannel,
13221
- path: "/draft-orders/:id/sales-channel"
13220
+ Component: Email,
13221
+ path: "/draft-orders/:id/email"
13222
13222
  },
13223
13223
  {
13224
- Component: Shipping,
13225
- path: "/draft-orders/:id/shipping"
13224
+ Component: SalesChannel,
13225
+ path: "/draft-orders/:id/sales-channel"
13226
13226
  },
13227
13227
  {
13228
13228
  Component: Metadata,
13229
13229
  path: "/draft-orders/:id/metadata"
13230
13230
  },
13231
+ {
13232
+ Component: Promotions,
13233
+ path: "/draft-orders/:id/promotions"
13234
+ },
13231
13235
  {
13232
13236
  Component: ShippingAddress,
13233
13237
  path: "/draft-orders/:id/shipping-address"
@@ -13237,12 +13241,8 @@ const routeModule = {
13237
13241
  path: "/draft-orders/:id/transfer-ownership"
13238
13242
  },
13239
13243
  {
13240
- Component: Items,
13241
- path: "/draft-orders/:id/items"
13242
- },
13243
- {
13244
- Component: CustomItems,
13245
- path: "/draft-orders/:id/custom-items"
13244
+ Component: Shipping,
13245
+ path: "/draft-orders/:id/shipping"
13246
13246
  }
13247
13247
  ]
13248
13248
  }