@medusajs/draft-order 0.0.8 → 0.0.9

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