@medusajs/draft-order 2.10.0-snapshot-20250828141936 → 2.10.0-snapshot-20250904131418

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.
@@ -9839,1079 +9839,582 @@ const EmailForm = ({ order }) => {
9839
9839
  const schema$3 = objectType({
9840
9840
  email: stringType().email()
9841
9841
  });
9842
- const NumberInput = React.forwardRef(
9843
- ({
9844
- value,
9845
- onChange,
9846
- size = "base",
9847
- min = 0,
9848
- max = 100,
9849
- step = 1,
9850
- className,
9851
- disabled,
9852
- ...props
9853
- }, ref) => {
9854
- const handleChange = (event) => {
9855
- const newValue = event.target.value === "" ? min : Number(event.target.value);
9856
- if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
9857
- onChange(newValue);
9858
- }
9859
- };
9860
- const handleIncrement = () => {
9861
- const newValue = value + step;
9862
- if (max === void 0 || newValue <= max) {
9863
- onChange(newValue);
9864
- }
9865
- };
9866
- const handleDecrement = () => {
9867
- const newValue = value - step;
9868
- if (min === void 0 || newValue >= min) {
9869
- onChange(newValue);
9870
- }
9871
- };
9842
+ const InlineTip = React.forwardRef(
9843
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
9844
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
9872
9845
  return /* @__PURE__ */ jsxRuntime.jsxs(
9873
9846
  "div",
9874
9847
  {
9848
+ ref,
9875
9849
  className: ui.clx(
9876
- "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
9877
- "[&:has(input:focus)]:shadow-borders-interactive-with-active",
9878
- {
9879
- "h-7": size === "small",
9880
- "h-8": size === "base"
9881
- },
9850
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
9882
9851
  className
9883
9852
  ),
9853
+ ...props,
9884
9854
  children: [
9885
9855
  /* @__PURE__ */ jsxRuntime.jsx(
9886
- "input",
9887
- {
9888
- ref,
9889
- type: "number",
9890
- value,
9891
- onChange: handleChange,
9892
- min,
9893
- max,
9894
- step,
9895
- className: ui.clx(
9896
- "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
9897
- "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
9898
- "placeholder:text-ui-fg-muted"
9899
- ),
9900
- ...props
9901
- }
9902
- ),
9903
- /* @__PURE__ */ jsxRuntime.jsxs(
9904
- "button",
9856
+ "div",
9905
9857
  {
9906
- className: ui.clx(
9907
- "flex items-center justify-center outline-none transition-fg",
9908
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9909
- "focus:bg-ui-bg-field-component-hover",
9910
- "hover:bg-ui-bg-field-component-hover",
9911
- {
9912
- "size-7": size === "small",
9913
- "size-8": size === "base"
9914
- }
9915
- ),
9916
- type: "button",
9917
- onClick: handleDecrement,
9918
- disabled: min !== void 0 && value <= min || disabled,
9919
- children: [
9920
- /* @__PURE__ */ jsxRuntime.jsx(icons.Minus, {}),
9921
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
9922
- ]
9858
+ role: "presentation",
9859
+ className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
9860
+ "bg-ui-tag-orange-icon": variant === "warning"
9861
+ })
9923
9862
  }
9924
9863
  ),
9925
- /* @__PURE__ */ jsxRuntime.jsxs(
9926
- "button",
9927
- {
9928
- className: ui.clx(
9929
- "flex items-center justify-center outline-none transition-fg",
9930
- "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
9931
- "focus:bg-ui-bg-field-hover",
9932
- "hover:bg-ui-bg-field-hover",
9933
- {
9934
- "size-7": size === "small",
9935
- "size-8": size === "base"
9936
- }
9937
- ),
9938
- type: "button",
9939
- onClick: handleIncrement,
9940
- disabled: max !== void 0 && value >= max || disabled,
9941
- children: [
9942
- /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
9943
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Increase by ${step}` })
9944
- ]
9945
- }
9946
- )
9864
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
9865
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
9866
+ labelValue,
9867
+ ":"
9868
+ ] }),
9869
+ " ",
9870
+ children
9871
+ ] })
9947
9872
  ]
9948
9873
  }
9949
9874
  );
9950
9875
  }
9951
9876
  );
9952
- const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
9953
- const productVariantsQueryKeys = {
9954
- list: (query2) => [
9955
- PRODUCT_VARIANTS_QUERY_KEY,
9956
- query2 ? query2 : void 0
9957
- ]
9958
- };
9959
- const useProductVariants = (query2, options) => {
9960
- const { data, ...rest } = reactQuery.useQuery({
9961
- queryKey: productVariantsQueryKeys.list(query2),
9962
- queryFn: async () => await sdk.admin.productVariant.list(query2),
9963
- ...options
9964
- });
9965
- return { ...data, ...rest };
9966
- };
9967
- const useCancelOrderEdit = ({ preview }) => {
9968
- const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
9969
- const onCancel = React.useCallback(async () => {
9970
- if (!preview) {
9971
- return true;
9972
- }
9973
- let res = false;
9974
- await cancelOrderEdit(void 0, {
9975
- onError: (e) => {
9976
- ui.toast.error(e.message);
9977
- },
9978
- onSuccess: () => {
9979
- res = true;
9980
- }
9981
- });
9982
- return res;
9983
- }, [preview, cancelOrderEdit]);
9984
- return { onCancel };
9985
- };
9986
- let IS_REQUEST_RUNNING = false;
9987
- const useInitiateOrderEdit = ({
9988
- preview
9989
- }) => {
9990
- const navigate = reactRouterDom.useNavigate();
9991
- const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
9992
- React.useEffect(() => {
9993
- async function run() {
9994
- if (IS_REQUEST_RUNNING || !preview) {
9995
- return;
9996
- }
9997
- if (preview.order_change) {
9998
- return;
9999
- }
10000
- IS_REQUEST_RUNNING = true;
10001
- await mutateAsync(void 0, {
10002
- onError: (e) => {
10003
- ui.toast.error(e.message);
10004
- navigate(`/draft-orders/${preview.id}`, { replace: true });
10005
- return;
10006
- }
10007
- });
10008
- IS_REQUEST_RUNNING = false;
10009
- }
10010
- run();
10011
- }, [preview, navigate, mutateAsync]);
10012
- };
10013
- function convertNumber(value) {
10014
- return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10015
- }
10016
- const STACKED_MODAL_ID = "items_stacked_modal";
10017
- const Items = () => {
9877
+ InlineTip.displayName = "InlineTip";
9878
+ const MetadataFieldSchema = objectType({
9879
+ key: stringType(),
9880
+ disabled: booleanType().optional(),
9881
+ value: anyType()
9882
+ });
9883
+ const MetadataSchema = objectType({
9884
+ metadata: arrayType(MetadataFieldSchema)
9885
+ });
9886
+ const Metadata = () => {
10018
9887
  const { id } = reactRouterDom.useParams();
10019
- const {
10020
- order: preview,
10021
- isPending: isPreviewPending,
10022
- isError: isPreviewError,
10023
- error: previewError
10024
- } = useOrderPreview(id, void 0, {
10025
- placeholderData: reactQuery.keepPreviousData
9888
+ const { order, isPending, isError, error } = useOrder(id, {
9889
+ fields: "metadata"
10026
9890
  });
10027
- useInitiateOrderEdit({ preview });
10028
- const { draft_order, isPending, isError, error } = useDraftOrder(
10029
- id,
10030
- {
10031
- fields: "currency_code"
10032
- },
10033
- {
10034
- enabled: !!id
10035
- }
10036
- );
10037
- const { onCancel } = useCancelOrderEdit({ preview });
10038
9891
  if (isError) {
10039
9892
  throw error;
10040
9893
  }
10041
- if (isPreviewError) {
10042
- throw previewError;
10043
- }
10044
- const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
10045
- return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsxRuntime.jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10046
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Items" }) }),
10047
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10048
- ] }) });
9894
+ const isReady = !isPending && !!order;
9895
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
9896
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
9897
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
9898
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
9899
+ ] }),
9900
+ !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
9901
+ ] });
10049
9902
  };
10050
- const ItemsForm = ({ preview, currencyCode }) => {
10051
- var _a;
10052
- const [isSubmitting, setIsSubmitting] = React.useState(false);
10053
- const [modalContent, setModalContent] = React.useState(
10054
- null
10055
- );
9903
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
9904
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
9905
+ const MetadataForm = ({ orderId, metadata }) => {
10056
9906
  const { handleSuccess } = useRouteModal();
10057
- const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
10058
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10059
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10060
- const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
10061
- const matches = React.useMemo(() => {
10062
- return matchSorter.matchSorter(preview.items, query2, {
10063
- keys: ["product_title", "variant_title", "variant_sku", "title"]
10064
- });
10065
- }, [preview.items, query2]);
10066
- const onSubmit = async () => {
10067
- setIsSubmitting(true);
10068
- let requestSucceeded = false;
10069
- await requestOrderEdit(void 0, {
10070
- onError: (e) => {
10071
- ui.toast.error(`Failed to request order edit: ${e.message}`);
10072
- },
10073
- onSuccess: () => {
10074
- requestSucceeded = true;
10075
- }
10076
- });
10077
- if (!requestSucceeded) {
10078
- setIsSubmitting(false);
10079
- return;
10080
- }
10081
- await confirmOrderEdit(void 0, {
10082
- onError: (e) => {
10083
- ui.toast.error(`Failed to confirm order edit: ${e.message}`);
10084
- },
10085
- onSuccess: () => {
10086
- handleSuccess();
10087
- },
10088
- onSettled: () => {
10089
- setIsSubmitting(false);
10090
- }
10091
- });
10092
- };
10093
- const onKeyDown = React.useCallback(
10094
- (e) => {
10095
- if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10096
- if (modalContent || isSubmitting) {
10097
- return;
10098
- }
10099
- onSubmit();
10100
- }
10101
- },
10102
- [modalContent, isSubmitting, onSubmit]
10103
- );
10104
- React.useEffect(() => {
10105
- document.addEventListener("keydown", onKeyDown);
10106
- return () => {
10107
- document.removeEventListener("keydown", onKeyDown);
10108
- };
10109
- }, [onKeyDown]);
10110
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10111
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
10112
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
10113
- StackedFocusModal,
10114
- {
10115
- id: STACKED_MODAL_ID,
10116
- onOpenChangeCallback: (open) => {
10117
- if (!open) {
10118
- setModalContent(null);
10119
- }
10120
- },
10121
- children: [
10122
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-6 py-16", children: [
10123
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10124
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Items" }) }),
10125
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Edit the items in the draft order." }) })
10126
- ] }),
10127
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10128
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
10129
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
10130
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10131
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
10132
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
10133
- ] }),
10134
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10135
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
10136
- ui.Input,
10137
- {
10138
- type: "search",
10139
- placeholder: "Search items",
10140
- value: searchValue,
10141
- onChange: (e) => onSearchValueChange(e.target.value)
10142
- }
10143
- ) }),
10144
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
10145
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}) }) }),
10146
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
10147
- /* @__PURE__ */ jsxRuntime.jsx(
10148
- StackedModalTrigger$1,
10149
- {
10150
- type: "add-items",
10151
- setModalContent
10152
- }
10153
- ),
10154
- /* @__PURE__ */ jsxRuntime.jsx(
10155
- StackedModalTrigger$1,
10156
- {
10157
- type: "add-custom-item",
10158
- setModalContent
10159
- }
10160
- )
10161
- ] })
10162
- ] })
10163
- ] })
10164
- ] }),
10165
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10166
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_1fr_1fr_28px] gap-3 px-4 py-2 text-ui-fg-muted", children: [
10167
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
10168
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) }),
10169
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Price" }) }),
10170
- /* @__PURE__ */ jsxRuntime.jsx("div", {})
10171
- ] }) }),
10172
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
10173
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
10174
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
10175
- ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
10176
- Item,
10177
- {
10178
- item,
10179
- preview,
10180
- currencyCode
10181
- },
10182
- item.id
10183
- )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
10184
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10185
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
10186
- 'No items found for "',
10187
- query2,
10188
- '".'
10189
- ] })
10190
- ] }) })
10191
- ] })
10192
- ] }),
10193
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10194
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
10195
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
10196
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(
10197
- ui.Text,
10198
- {
10199
- size: "small",
10200
- leading: "compact",
10201
- className: "text-ui-fg-subtle",
10202
- children: [
10203
- itemCount,
10204
- " ",
10205
- itemCount === 1 ? "item" : "items"
10206
- ]
10207
- }
10208
- ) }),
10209
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
10210
- ] })
10211
- ] }) }),
10212
- modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsxRuntime.jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsxRuntime.jsx(
10213
- CustomItemForm,
10214
- {
10215
- orderId: preview.id,
10216
- currencyCode
10217
- }
10218
- ) : null)
10219
- ]
10220
- }
10221
- ) }),
10222
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
10223
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10224
- /* @__PURE__ */ jsxRuntime.jsx(
10225
- ui.Button,
10226
- {
10227
- size: "small",
10228
- type: "button",
10229
- onClick: onSubmit,
10230
- isLoading: isSubmitting,
10231
- children: "Save"
10232
- }
10233
- )
10234
- ] }) })
10235
- ] });
10236
- };
10237
- const Item = ({ item, preview, currencyCode }) => {
10238
- if (item.variant_id) {
10239
- return /* @__PURE__ */ jsxRuntime.jsx(VariantItem, { item, preview, currencyCode });
10240
- }
10241
- return /* @__PURE__ */ jsxRuntime.jsx(CustomItem, { item, preview, currencyCode });
10242
- };
10243
- const VariantItem = ({ item, preview, currencyCode }) => {
10244
- const [editing, setEditing] = React.useState(false);
9907
+ const hasUneditableRows = getHasUneditableRows(metadata);
9908
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10245
9909
  const form = reactHookForm.useForm({
10246
9910
  defaultValues: {
10247
- quantity: item.quantity,
10248
- unit_price: item.unit_price
9911
+ metadata: getDefaultValues(metadata)
10249
9912
  },
10250
- resolver: zod.zodResolver(variantItemSchema)
9913
+ resolver: zod.zodResolver(MetadataSchema)
10251
9914
  });
10252
- const actionId = React.useMemo(() => {
10253
- var _a, _b;
10254
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10255
- }, [item]);
10256
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10257
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10258
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10259
- const onSubmit = form.handleSubmit(async (data) => {
10260
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
10261
- setEditing(false);
10262
- return;
10263
- }
10264
- if (!actionId) {
10265
- await updateOriginalItem(
10266
- {
10267
- item_id: item.id,
10268
- quantity: data.quantity,
10269
- unit_price: convertNumber(data.unit_price)
10270
- },
10271
- {
10272
- onSuccess: () => {
10273
- setEditing(false);
10274
- },
10275
- onError: (e) => {
10276
- ui.toast.error(e.message);
10277
- }
10278
- }
10279
- );
10280
- return;
10281
- }
10282
- await updateActionItem(
9915
+ const handleSubmit = form.handleSubmit(async (data) => {
9916
+ const parsedData = parseValues(data);
9917
+ await mutateAsync(
10283
9918
  {
10284
- action_id: actionId,
10285
- quantity: data.quantity,
10286
- unit_price: convertNumber(data.unit_price)
9919
+ metadata: parsedData
10287
9920
  },
10288
9921
  {
10289
9922
  onSuccess: () => {
10290
- setEditing(false);
9923
+ ui.toast.success("Metadata updated");
9924
+ handleSuccess();
10291
9925
  },
10292
- onError: (e) => {
10293
- ui.toast.error(e.message);
9926
+ onError: (error) => {
9927
+ ui.toast.error(error.message);
10294
9928
  }
10295
9929
  }
10296
9930
  );
10297
9931
  });
10298
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_28px] gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center", children: [
10299
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3 w-full", children: [
10300
- /* @__PURE__ */ jsxRuntime.jsx(
10301
- Thumbnail,
10302
- {
10303
- thumbnail: item.thumbnail,
10304
- alt: item.product_title ?? void 0
10305
- }
10306
- ),
10307
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10308
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
10309
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10310
- /* @__PURE__ */ jsxRuntime.jsxs(
10311
- ui.Text,
10312
- {
10313
- size: "small",
10314
- leading: "compact",
10315
- className: "text-ui-fg-subtle",
10316
- children: [
10317
- "(",
10318
- item.variant_title,
10319
- ")"
10320
- ]
10321
- }
10322
- )
10323
- ] }),
10324
- /* @__PURE__ */ jsxRuntime.jsx(
10325
- ui.Text,
10326
- {
10327
- size: "small",
10328
- leading: "compact",
10329
- className: "text-ui-fg-subtle",
10330
- children: item.variant_sku
10331
- }
10332
- )
10333
- ] })
10334
- ] }),
10335
- editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
10336
- Form$2.Field,
10337
- {
10338
- control: form.control,
10339
- name: "quantity",
10340
- render: ({ field }) => {
10341
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10342
- }
10343
- }
10344
- ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }) }),
10345
- editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
10346
- Form$2.Field,
10347
- {
10348
- control: form.control,
10349
- name: "unit_price",
10350
- render: ({ field: { onChange, ...field } }) => {
10351
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10352
- ui.CurrencyInput,
10353
- {
10354
- ...field,
10355
- symbol: getNativeSymbol(currencyCode),
10356
- code: currencyCode,
10357
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10358
- }
10359
- ) }) });
10360
- }
10361
- }
10362
- ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex items-center justify-end w-full", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10363
- /* @__PURE__ */ jsxRuntime.jsx(
10364
- ui.IconButton,
10365
- {
10366
- type: "button",
10367
- size: "small",
10368
- onClick: editing ? onSubmit : () => {
10369
- setEditing(true);
10370
- },
10371
- disabled: isPending,
10372
- children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
10373
- }
10374
- )
10375
- ] }) }) });
10376
- };
10377
- const variantItemSchema = objectType({
10378
- quantity: numberType(),
10379
- unit_price: unionType([numberType(), stringType()])
10380
- });
10381
- const CustomItem = ({ item, preview, currencyCode }) => {
10382
- const [editing, setEditing] = React.useState(false);
10383
- const { quantity, unit_price, title } = item;
10384
- const form = reactHookForm.useForm({
10385
- defaultValues: {
10386
- title,
10387
- quantity,
10388
- unit_price
10389
- },
10390
- resolver: zod.zodResolver(customItemSchema)
9932
+ const { fields, insert, remove } = reactHookForm.useFieldArray({
9933
+ control: form.control,
9934
+ name: "metadata"
10391
9935
  });
10392
- React.useEffect(() => {
10393
- form.reset({
10394
- title,
10395
- quantity,
10396
- unit_price
10397
- });
10398
- }, [form, title, quantity, unit_price]);
10399
- const actionId = React.useMemo(() => {
10400
- var _a, _b;
10401
- return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
10402
- }, [item]);
10403
- const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
10404
- const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
10405
- const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
10406
- const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
10407
- const onSubmit = form.handleSubmit(async (data) => {
10408
- if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
10409
- setEditing(false);
10410
- return;
10411
- }
10412
- if (!actionId) {
10413
- await updateOriginalItem(
10414
- {
10415
- item_id: item.id,
10416
- quantity: data.quantity,
10417
- unit_price: convertNumber(data.unit_price)
10418
- },
10419
- {
10420
- onSuccess: () => {
10421
- setEditing(false);
10422
- },
10423
- onError: (e) => {
10424
- ui.toast.error(e.message);
10425
- }
10426
- }
10427
- );
10428
- return;
10429
- }
10430
- if (data.quantity === 0) {
10431
- await removeActionItem(actionId, {
10432
- onSuccess: () => {
10433
- setEditing(false);
10434
- },
10435
- onError: (e) => {
10436
- ui.toast.error(e.message);
10437
- }
9936
+ function deleteRow(index) {
9937
+ remove(index);
9938
+ if (fields.length === 1) {
9939
+ insert(0, {
9940
+ key: "",
9941
+ value: "",
9942
+ disabled: false
10438
9943
  });
10439
- return;
10440
9944
  }
10441
- await updateActionItem(
10442
- {
10443
- action_id: actionId,
10444
- quantity: data.quantity,
10445
- unit_price: convertNumber(data.unit_price)
10446
- },
10447
- {
10448
- onSuccess: () => {
10449
- setEditing(false);
10450
- },
10451
- onError: (e) => {
10452
- ui.toast.error(e.message);
10453
- }
10454
- }
10455
- );
10456
- });
10457
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_28px] gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center", children: [
10458
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
10459
- /* @__PURE__ */ jsxRuntime.jsx(
10460
- Thumbnail,
10461
- {
10462
- thumbnail: item.thumbnail,
10463
- alt: item.title ?? void 0
10464
- }
10465
- ),
10466
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
10467
- Form$2.Field,
10468
- {
10469
- control: form.control,
10470
- name: "title",
10471
- render: ({ field }) => {
10472
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }) });
10473
- }
10474
- }
10475
- ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.title })
10476
- ] }),
10477
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
10478
- Form$2.Field,
10479
- {
10480
- control: form.control,
10481
- name: "quantity",
10482
- render: ({ field }) => {
10483
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
10484
- }
10485
- }
10486
- ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }),
10487
- editing ? /* @__PURE__ */ jsxRuntime.jsx(
10488
- Form$2.Field,
10489
- {
10490
- control: form.control,
10491
- name: "unit_price",
10492
- render: ({ field: { onChange, ...field } }) => {
10493
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10494
- ui.CurrencyInput,
10495
- {
10496
- ...field,
10497
- symbol: getNativeSymbol(currencyCode),
10498
- code: currencyCode,
10499
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
10500
- }
10501
- ) }) });
10502
- }
10503
- }
10504
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
10505
- /* @__PURE__ */ jsxRuntime.jsx(
10506
- ui.IconButton,
10507
- {
10508
- type: "button",
10509
- size: "small",
10510
- onClick: editing ? onSubmit : () => {
10511
- setEditing(true);
10512
- },
10513
- disabled: isPending,
10514
- children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
10515
- }
10516
- )
10517
- ] }) }) });
10518
- };
10519
- const StackedModalTrigger$1 = ({
10520
- type,
10521
- setModalContent
10522
- }) => {
10523
- const { setIsOpen } = useStackedModal();
10524
- const onClick = React.useCallback(() => {
10525
- setModalContent(type);
10526
- setIsOpen(STACKED_MODAL_ID, true);
10527
- }, [setModalContent, setIsOpen, type]);
10528
- return /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
10529
- };
10530
- const VARIANT_PREFIX = "items";
10531
- const LIMIT = 50;
10532
- const ExistingItemsForm = ({ orderId, items }) => {
10533
- const { setIsOpen } = useStackedModal();
10534
- const [rowSelection, setRowSelection] = React.useState(
10535
- items.reduce((acc, item) => {
10536
- acc[item.variant_id] = true;
10537
- return acc;
10538
- }, {})
10539
- );
10540
- React.useEffect(() => {
10541
- setRowSelection(
10542
- items.reduce((acc, item) => {
10543
- if (item.variant_id) {
10544
- acc[item.variant_id] = true;
10545
- }
10546
- return acc;
10547
- }, {})
10548
- );
10549
- }, [items]);
10550
- const { q, order, offset } = useQueryParams(
10551
- ["q", "order", "offset"],
10552
- VARIANT_PREFIX
10553
- );
10554
- const { variants, count, isPending, isError, error } = useProductVariants(
10555
- {
10556
- q,
10557
- order,
10558
- offset: offset ? parseInt(offset) : void 0,
10559
- limit: LIMIT
10560
- },
9945
+ }
9946
+ function insertRow(index, position) {
9947
+ insert(index + (position === "above" ? 0 : 1), {
9948
+ key: "",
9949
+ value: "",
9950
+ disabled: false
9951
+ });
9952
+ }
9953
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
9954
+ KeyboundForm,
10561
9955
  {
10562
- placeholderData: reactQuery.keepPreviousData
10563
- }
10564
- );
10565
- const columns = useColumns();
10566
- const { mutateAsync } = useDraftOrderAddItems(orderId);
10567
- const onSubmit = async () => {
10568
- const ids = Object.keys(rowSelection).filter(
10569
- (id) => !items.find((i) => i.variant_id === id)
10570
- );
10571
- await mutateAsync(
10572
- {
10573
- items: ids.map((id) => ({
10574
- variant_id: id,
10575
- quantity: 1
10576
- }))
10577
- },
10578
- {
10579
- onSuccess: () => {
10580
- setRowSelection({});
10581
- setIsOpen(STACKED_MODAL_ID, false);
10582
- },
10583
- onError: (e) => {
10584
- ui.toast.error(e.message);
10585
- }
10586
- }
10587
- );
10588
- };
10589
- if (isError) {
10590
- throw error;
10591
- }
10592
- return /* @__PURE__ */ jsxRuntime.jsxs(
10593
- StackedFocusModal.Content,
10594
- {
10595
- onOpenAutoFocus: (e) => {
10596
- e.preventDefault();
10597
- const searchInput = document.querySelector(
10598
- "[data-modal-id='modal-search-input']"
10599
- );
10600
- if (searchInput) {
10601
- searchInput.focus();
10602
- }
10603
- },
9956
+ onSubmit: handleSubmit,
9957
+ className: "flex flex-1 flex-col overflow-hidden",
10604
9958
  children: [
10605
- /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Header, { children: [
10606
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Product Variants" }) }),
10607
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
10608
- ] }),
10609
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
10610
- DataTable,
10611
- {
10612
- data: variants,
10613
- columns,
10614
- isLoading: isPending,
10615
- getRowId: (row) => row.id,
10616
- rowCount: count,
10617
- prefix: VARIANT_PREFIX,
10618
- layout: "fill",
10619
- rowSelection: {
10620
- state: rowSelection,
10621
- onRowSelectionChange: setRowSelection,
10622
- enableRowSelection: (row) => {
10623
- return !items.find((i) => i.variant_id === row.original.id);
9959
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
9960
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
9961
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
9962
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
9963
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
9964
+ ] }),
9965
+ fields.map((field, index) => {
9966
+ const isDisabled = field.disabled || false;
9967
+ let placeholder = "-";
9968
+ if (typeof field.value === "object") {
9969
+ placeholder = "{ ... }";
10624
9970
  }
10625
- },
10626
- autoFocusSearch: true
10627
- }
10628
- ) }),
10629
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
10630
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10631
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
9971
+ if (Array.isArray(field.value)) {
9972
+ placeholder = "[ ... ]";
9973
+ }
9974
+ return /* @__PURE__ */ jsxRuntime.jsx(
9975
+ ConditionalTooltip,
9976
+ {
9977
+ showTooltip: isDisabled,
9978
+ content: "This row is disabled because it contains non-primitive data.",
9979
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
9980
+ /* @__PURE__ */ jsxRuntime.jsxs(
9981
+ "div",
9982
+ {
9983
+ className: ui.clx("grid grid-cols-2 divide-x", {
9984
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
9985
+ }),
9986
+ children: [
9987
+ /* @__PURE__ */ jsxRuntime.jsx(
9988
+ Form$2.Field,
9989
+ {
9990
+ control: form.control,
9991
+ name: `metadata.${index}.key`,
9992
+ render: ({ field: field2 }) => {
9993
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
9994
+ GridInput,
9995
+ {
9996
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
9997
+ ...field2,
9998
+ disabled: isDisabled,
9999
+ placeholder: "Key"
10000
+ }
10001
+ ) }) });
10002
+ }
10003
+ }
10004
+ ),
10005
+ /* @__PURE__ */ jsxRuntime.jsx(
10006
+ Form$2.Field,
10007
+ {
10008
+ control: form.control,
10009
+ name: `metadata.${index}.value`,
10010
+ render: ({ field: { value, ...field2 } }) => {
10011
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10012
+ GridInput,
10013
+ {
10014
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
10015
+ ...field2,
10016
+ value: isDisabled ? placeholder : value,
10017
+ disabled: isDisabled,
10018
+ placeholder: "Value"
10019
+ }
10020
+ ) }) });
10021
+ }
10022
+ }
10023
+ )
10024
+ ]
10025
+ }
10026
+ ),
10027
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
10028
+ /* @__PURE__ */ jsxRuntime.jsx(
10029
+ ui.DropdownMenu.Trigger,
10030
+ {
10031
+ className: ui.clx(
10032
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
10033
+ {
10034
+ hidden: isDisabled
10035
+ }
10036
+ ),
10037
+ disabled: isDisabled,
10038
+ asChild: true,
10039
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
10040
+ }
10041
+ ),
10042
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
10043
+ /* @__PURE__ */ jsxRuntime.jsxs(
10044
+ ui.DropdownMenu.Item,
10045
+ {
10046
+ className: "gap-x-2",
10047
+ onClick: () => insertRow(index, "above"),
10048
+ children: [
10049
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
10050
+ "Insert row above"
10051
+ ]
10052
+ }
10053
+ ),
10054
+ /* @__PURE__ */ jsxRuntime.jsxs(
10055
+ ui.DropdownMenu.Item,
10056
+ {
10057
+ className: "gap-x-2",
10058
+ onClick: () => insertRow(index, "below"),
10059
+ children: [
10060
+ /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
10061
+ "Insert row below"
10062
+ ]
10063
+ }
10064
+ ),
10065
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
10066
+ /* @__PURE__ */ jsxRuntime.jsxs(
10067
+ ui.DropdownMenu.Item,
10068
+ {
10069
+ className: "gap-x-2",
10070
+ onClick: () => deleteRow(index),
10071
+ children: [
10072
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
10073
+ "Delete row"
10074
+ ]
10075
+ }
10076
+ )
10077
+ ] })
10078
+ ] })
10079
+ ] })
10080
+ },
10081
+ field.id
10082
+ );
10083
+ })
10084
+ ] }),
10085
+ hasUneditableRows && /* @__PURE__ */ jsxRuntime.jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
10086
+ ] }),
10087
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10088
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10089
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10632
10090
  ] }) })
10633
10091
  ]
10634
10092
  }
10093
+ ) });
10094
+ };
10095
+ const GridInput = React.forwardRef(({ className, ...props }, ref) => {
10096
+ return /* @__PURE__ */ jsxRuntime.jsx(
10097
+ "input",
10098
+ {
10099
+ ref,
10100
+ ...props,
10101
+ autoComplete: "off",
10102
+ className: ui.clx(
10103
+ "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",
10104
+ className
10105
+ )
10106
+ }
10635
10107
  );
10108
+ });
10109
+ GridInput.displayName = "MetadataForm.GridInput";
10110
+ const PlaceholderInner = () => {
10111
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
10112
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
10113
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10114
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
10115
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
10116
+ ] }) })
10117
+ ] });
10636
10118
  };
10637
- const columnHelper = ui.createDataTableColumnHelper();
10638
- const useColumns = () => {
10639
- return React.useMemo(() => {
10119
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
10120
+ function getDefaultValues(metadata) {
10121
+ if (!metadata || !Object.keys(metadata).length) {
10640
10122
  return [
10641
- columnHelper.select(),
10642
- columnHelper.accessor("product.title", {
10643
- header: "Product",
10644
- cell: ({ row }) => {
10645
- var _a, _b, _c;
10646
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
10647
- /* @__PURE__ */ jsxRuntime.jsx(
10648
- Thumbnail,
10649
- {
10650
- thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
10651
- alt: (_b = row.original.product) == null ? void 0 : _b.title
10652
- }
10653
- ),
10654
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
10655
- ] });
10656
- },
10657
- enableSorting: true
10658
- }),
10659
- columnHelper.accessor("title", {
10660
- header: "Variant",
10661
- enableSorting: true
10662
- }),
10663
- columnHelper.accessor("sku", {
10664
- header: "SKU",
10665
- cell: ({ getValue }) => {
10666
- return getValue() ?? "-";
10667
- },
10668
- enableSorting: true
10669
- }),
10670
- columnHelper.accessor("updated_at", {
10671
- header: "Updated",
10672
- cell: ({ getValue }) => {
10673
- return /* @__PURE__ */ jsxRuntime.jsx(
10674
- ui.Tooltip,
10675
- {
10676
- content: getFullDate({ date: getValue(), includeTime: true }),
10677
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
10678
- }
10679
- );
10680
- },
10681
- enableSorting: true,
10682
- sortAscLabel: "Oldest first",
10683
- sortDescLabel: "Newest first"
10684
- }),
10685
- columnHelper.accessor("created_at", {
10686
- header: "Created",
10687
- cell: ({ getValue }) => {
10688
- return /* @__PURE__ */ jsxRuntime.jsx(
10689
- ui.Tooltip,
10690
- {
10691
- content: getFullDate({ date: getValue(), includeTime: true }),
10692
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
10693
- }
10694
- );
10695
- },
10696
- enableSorting: true,
10697
- sortAscLabel: "Oldest first",
10698
- sortDescLabel: "Newest first"
10699
- })
10123
+ {
10124
+ key: "",
10125
+ value: "",
10126
+ disabled: false
10127
+ }
10700
10128
  ];
10701
- }, []);
10129
+ }
10130
+ return Object.entries(metadata).map(([key, value]) => {
10131
+ if (!EDITABLE_TYPES.includes(typeof value)) {
10132
+ return {
10133
+ key,
10134
+ value,
10135
+ disabled: true
10136
+ };
10137
+ }
10138
+ let stringValue = value;
10139
+ if (typeof value !== "string") {
10140
+ stringValue = JSON.stringify(value);
10141
+ }
10142
+ return {
10143
+ key,
10144
+ value: stringValue,
10145
+ original_key: key
10146
+ };
10147
+ });
10148
+ }
10149
+ function parseValues(values) {
10150
+ const metadata = values.metadata;
10151
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
10152
+ if (isEmpty) {
10153
+ return null;
10154
+ }
10155
+ const update = {};
10156
+ metadata.forEach((field) => {
10157
+ let key = field.key;
10158
+ let value = field.value;
10159
+ const disabled = field.disabled;
10160
+ if (!key || !value) {
10161
+ return;
10162
+ }
10163
+ if (disabled) {
10164
+ update[key] = value;
10165
+ return;
10166
+ }
10167
+ key = key.trim();
10168
+ value = value.trim();
10169
+ if (value === "true") {
10170
+ update[key] = true;
10171
+ } else if (value === "false") {
10172
+ update[key] = false;
10173
+ } else {
10174
+ const parsedNumber = parseFloat(value);
10175
+ if (!isNaN(parsedNumber)) {
10176
+ update[key] = parsedNumber;
10177
+ } else {
10178
+ update[key] = value;
10179
+ }
10180
+ }
10181
+ });
10182
+ return update;
10183
+ }
10184
+ function getHasUneditableRows(metadata) {
10185
+ if (!metadata) {
10186
+ return false;
10187
+ }
10188
+ return Object.values(metadata).some(
10189
+ (value) => !EDITABLE_TYPES.includes(typeof value)
10190
+ );
10191
+ }
10192
+ const SalesChannel = () => {
10193
+ const { id } = reactRouterDom.useParams();
10194
+ const { draft_order, isPending, isError, error } = useDraftOrder(
10195
+ id,
10196
+ {
10197
+ fields: "+sales_channel_id"
10198
+ },
10199
+ {
10200
+ enabled: !!id
10201
+ }
10202
+ );
10203
+ if (isError) {
10204
+ throw error;
10205
+ }
10206
+ const ISrEADY = !!draft_order && !isPending;
10207
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
10208
+ /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
10209
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
10210
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
10211
+ ] }),
10212
+ ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
10213
+ ] });
10702
10214
  };
10703
- const CustomItemForm = ({ orderId, currencyCode }) => {
10704
- const { setIsOpen } = useStackedModal();
10705
- const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
10215
+ const SalesChannelForm = ({ order }) => {
10706
10216
  const form = reactHookForm.useForm({
10707
10217
  defaultValues: {
10708
- title: "",
10709
- quantity: 1,
10710
- unit_price: ""
10218
+ sales_channel_id: order.sales_channel_id || ""
10711
10219
  },
10712
- resolver: zod.zodResolver(customItemSchema)
10220
+ resolver: zod.zodResolver(schema$2)
10713
10221
  });
10222
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
10223
+ const { handleSuccess } = useRouteModal();
10714
10224
  const onSubmit = form.handleSubmit(async (data) => {
10715
- await addItems(
10225
+ await mutateAsync(
10716
10226
  {
10717
- items: [
10718
- {
10719
- title: data.title,
10720
- quantity: data.quantity,
10721
- unit_price: convertNumber(data.unit_price)
10722
- }
10723
- ]
10227
+ sales_channel_id: data.sales_channel_id
10724
10228
  },
10725
10229
  {
10726
10230
  onSuccess: () => {
10727
- setIsOpen(STACKED_MODAL_ID, false);
10231
+ ui.toast.success("Sales channel updated");
10232
+ handleSuccess();
10728
10233
  },
10729
- onError: (e) => {
10730
- ui.toast.error(e.message);
10234
+ onError: (error) => {
10235
+ ui.toast.error(error.message);
10731
10236
  }
10732
10237
  }
10733
10238
  );
10734
10239
  });
10735
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Content, { children: [
10736
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
10737
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-2 py-16", children: [
10738
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10739
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Add custom item" }) }),
10740
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a custom item to the order. This will add a new line item that is not associated with an existing product." }) })
10741
- ] }),
10742
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10743
- /* @__PURE__ */ jsxRuntime.jsx(
10744
- Form$2.Field,
10745
- {
10746
- control: form.control,
10747
- name: "title",
10748
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10749
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10750
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Title" }),
10751
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the title of the item" })
10752
- ] }),
10753
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10754
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
10755
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10756
- ] })
10757
- ] }) })
10758
- }
10759
- ),
10760
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10761
- /* @__PURE__ */ jsxRuntime.jsx(
10762
- Form$2.Field,
10763
- {
10764
- control: form.control,
10765
- name: "unit_price",
10766
- render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10767
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10768
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Unit price" }),
10769
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
10770
- ] }),
10771
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10772
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10773
- ui.CurrencyInput,
10774
- {
10775
- symbol: getNativeSymbol(currencyCode),
10776
- code: currencyCode,
10777
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
10778
- ...field
10779
- }
10780
- ) }),
10781
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10782
- ] })
10783
- ] }) })
10784
- }
10785
- ),
10786
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10787
- /* @__PURE__ */ jsxRuntime.jsx(
10788
- Form$2.Field,
10789
- {
10790
- control: form.control,
10791
- name: "quantity",
10792
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10793
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10794
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Quantity" }),
10795
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
10796
- ] }),
10797
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 w-full", children: [
10798
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field, className: "w-full" }) }) }),
10799
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10800
- ] })
10801
- ] }) })
10802
- }
10803
- )
10804
- ] }) }) }),
10805
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
10806
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10807
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
10808
- ] }) })
10809
- ] }) }) });
10810
- };
10811
- const customItemSchema = objectType({
10812
- title: stringType().min(1),
10813
- quantity: numberType(),
10814
- unit_price: unionType([numberType(), stringType()])
10815
- });
10816
- const PROMOTION_QUERY_KEY = "promotions";
10817
- const promotionsQueryKeys = {
10818
- list: (query2) => [
10819
- PROMOTION_QUERY_KEY,
10820
- query2 ? query2 : void 0
10821
- ],
10822
- detail: (id, query2) => [
10823
- PROMOTION_QUERY_KEY,
10824
- id,
10825
- query2 ? query2 : void 0
10826
- ]
10827
- };
10828
- const usePromotions = (query2, options) => {
10829
- const { data, ...rest } = reactQuery.useQuery({
10830
- queryKey: promotionsQueryKeys.list(query2),
10831
- queryFn: async () => sdk.admin.promotion.list(query2),
10832
- ...options
10833
- });
10834
- return { ...data, ...rest };
10240
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
10241
+ KeyboundForm,
10242
+ {
10243
+ className: "flex flex-1 flex-col overflow-hidden",
10244
+ onSubmit,
10245
+ children: [
10246
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
10247
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
10248
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10249
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
10250
+ ] }) })
10251
+ ]
10252
+ }
10253
+ ) });
10835
10254
  };
10836
- const Promotions = () => {
10837
- const { id } = reactRouterDom.useParams();
10838
- const {
10839
- order: preview,
10840
- isError: isPreviewError,
10255
+ const SalesChannelField = ({ control, order }) => {
10256
+ const salesChannels = useComboboxData({
10257
+ queryFn: async (params) => {
10258
+ return await sdk.admin.salesChannel.list(params);
10259
+ },
10260
+ queryKey: ["sales-channels"],
10261
+ getOptions: (data) => {
10262
+ return data.sales_channels.map((salesChannel) => ({
10263
+ label: salesChannel.name,
10264
+ value: salesChannel.id
10265
+ }));
10266
+ },
10267
+ defaultValue: order.sales_channel_id || void 0
10268
+ });
10269
+ return /* @__PURE__ */ jsxRuntime.jsx(
10270
+ Form$2.Field,
10271
+ {
10272
+ control,
10273
+ name: "sales_channel_id",
10274
+ render: ({ field }) => {
10275
+ return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
10276
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
10277
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
10278
+ Combobox,
10279
+ {
10280
+ options: salesChannels.options,
10281
+ fetchNextPage: salesChannels.fetchNextPage,
10282
+ isFetchingNextPage: salesChannels.isFetchingNextPage,
10283
+ searchValue: salesChannels.searchValue,
10284
+ onSearchValueChange: salesChannels.onSearchValueChange,
10285
+ placeholder: "Select sales channel",
10286
+ ...field
10287
+ }
10288
+ ) }),
10289
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
10290
+ ] });
10291
+ }
10292
+ }
10293
+ );
10294
+ };
10295
+ const schema$2 = objectType({
10296
+ sales_channel_id: stringType().min(1)
10297
+ });
10298
+ const useCancelOrderEdit = ({ preview }) => {
10299
+ const { mutateAsync: cancelOrderEdit } = useDraftOrderCancelEdit(preview == null ? void 0 : preview.id);
10300
+ const onCancel = React.useCallback(async () => {
10301
+ if (!preview) {
10302
+ return true;
10303
+ }
10304
+ let res = false;
10305
+ await cancelOrderEdit(void 0, {
10306
+ onError: (e) => {
10307
+ ui.toast.error(e.message);
10308
+ },
10309
+ onSuccess: () => {
10310
+ res = true;
10311
+ }
10312
+ });
10313
+ return res;
10314
+ }, [preview, cancelOrderEdit]);
10315
+ return { onCancel };
10316
+ };
10317
+ let IS_REQUEST_RUNNING = false;
10318
+ const useInitiateOrderEdit = ({
10319
+ preview
10320
+ }) => {
10321
+ const navigate = reactRouterDom.useNavigate();
10322
+ const { mutateAsync } = useDraftOrderBeginEdit(preview == null ? void 0 : preview.id);
10323
+ React.useEffect(() => {
10324
+ async function run() {
10325
+ if (IS_REQUEST_RUNNING || !preview) {
10326
+ return;
10327
+ }
10328
+ if (preview.order_change) {
10329
+ return;
10330
+ }
10331
+ IS_REQUEST_RUNNING = true;
10332
+ await mutateAsync(void 0, {
10333
+ onError: (e) => {
10334
+ ui.toast.error(e.message);
10335
+ navigate(`/draft-orders/${preview.id}`, { replace: true });
10336
+ return;
10337
+ }
10338
+ });
10339
+ IS_REQUEST_RUNNING = false;
10340
+ }
10341
+ run();
10342
+ }, [preview, navigate, mutateAsync]);
10343
+ };
10344
+ function convertNumber(value) {
10345
+ return typeof value === "string" ? Number(value.replace(",", ".")) : value;
10346
+ }
10347
+ const STACKED_FOCUS_MODAL_ID = "shipping-form";
10348
+ const Shipping = () => {
10349
+ var _a;
10350
+ const { id } = reactRouterDom.useParams();
10351
+ const { order, isPending, isError, error } = useOrder(id, {
10352
+ fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
10353
+ });
10354
+ const {
10355
+ order: preview,
10356
+ isPending: isPreviewPending,
10357
+ isError: isPreviewError,
10841
10358
  error: previewError
10842
- } = useOrderPreview(id, void 0);
10359
+ } = useOrderPreview(id);
10843
10360
  useInitiateOrderEdit({ preview });
10844
10361
  const { onCancel } = useCancelOrderEdit({ preview });
10362
+ if (isError) {
10363
+ throw error;
10364
+ }
10845
10365
  if (isPreviewError) {
10846
10366
  throw previewError;
10847
10367
  }
10848
- const isReady = !!preview;
10849
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
10850
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
10851
- isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
10852
- ] });
10368
+ const orderHasItems = (((_a = order == null ? void 0 : order.items) == null ? void 0 : _a.length) || 0) > 0;
10369
+ const isReady = preview && !isPreviewPending && order && !isPending;
10370
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
10371
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
10372
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
10373
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
10374
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This draft order currently has no items. Add items to the order before adding shipping." }) })
10375
+ ] }) }) }),
10376
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }) })
10377
+ ] }) : isReady ? /* @__PURE__ */ jsxRuntime.jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10378
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
10379
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
10380
+ ] }) });
10853
10381
  };
10854
- const PromotionForm = ({ preview }) => {
10855
- const { items, shipping_methods } = preview;
10382
+ const ShippingForm = ({ preview, order }) => {
10383
+ var _a;
10384
+ const { setIsOpen } = useStackedModal();
10856
10385
  const [isSubmitting, setIsSubmitting] = React.useState(false);
10857
- const [comboboxValue, setComboboxValue] = React.useState("");
10858
- const { handleSuccess } = useRouteModal();
10859
- const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
10860
- const promoCodes = getPromotionCodes(items, shipping_methods);
10861
- const { promotions, isPending, isError, error } = usePromotions(
10386
+ const [data, setData] = React.useState(null);
10387
+ const appliedShippingOptionIds = (_a = preview.shipping_methods) == null ? void 0 : _a.map((method) => method.shipping_option_id).filter(Boolean);
10388
+ const { shipping_options } = useShippingOptions(
10862
10389
  {
10863
- code: promoCodes
10390
+ id: appliedShippingOptionIds,
10391
+ fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
10864
10392
  },
10865
10393
  {
10866
- enabled: !!promoCodes.length
10394
+ enabled: appliedShippingOptionIds.length > 0
10867
10395
  }
10868
10396
  );
10869
- const comboboxData = useComboboxData({
10870
- queryKey: ["promotions", "combobox", promoCodes],
10871
- queryFn: async (params) => {
10872
- return await sdk.admin.promotion.list({
10873
- ...params,
10874
- code: {
10875
- $nin: promoCodes
10876
- }
10877
- });
10878
- },
10879
- getOptions: (data) => {
10880
- return data.promotions.map((promotion) => ({
10881
- label: promotion.code,
10882
- value: promotion.code
10883
- }));
10884
- }
10885
- });
10886
- const add = async (value) => {
10887
- if (!value) {
10888
- return;
10889
- }
10890
- addPromotions(
10891
- {
10892
- promo_codes: [value]
10893
- },
10894
- {
10895
- onError: (e) => {
10896
- ui.toast.error(e.message);
10897
- comboboxData.onSearchValueChange("");
10898
- setComboboxValue("");
10899
- },
10900
- onSuccess: () => {
10901
- comboboxData.onSearchValueChange("");
10902
- setComboboxValue("");
10903
- }
10904
- }
10905
- );
10906
- };
10397
+ const uniqueShippingProfiles = React.useMemo(() => {
10398
+ const profiles = /* @__PURE__ */ new Map();
10399
+ getUniqueShippingProfiles(order.items).forEach((profile) => {
10400
+ profiles.set(profile.id, profile);
10401
+ });
10402
+ shipping_options == null ? void 0 : shipping_options.forEach((option) => {
10403
+ profiles.set(option.shipping_profile_id, option.shipping_profile);
10404
+ });
10405
+ return Array.from(profiles.values());
10406
+ }, [order.items, shipping_options]);
10407
+ const { handleSuccess } = useRouteModal();
10907
10408
  const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
10908
- const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
10409
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
10410
+ const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
10411
+ const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
10909
10412
  const onSubmit = async () => {
10910
10413
  setIsSubmitting(true);
10911
10414
  let requestSucceeded = false;
10912
10415
  await requestOrderEdit(void 0, {
10913
10416
  onError: (e) => {
10914
- ui.toast.error(e.message);
10417
+ ui.toast.error(`Failed to request order edit: ${e.message}`);
10915
10418
  },
10916
10419
  onSuccess: () => {
10917
10420
  requestSucceeded = true;
@@ -10923,7 +10426,7 @@ const PromotionForm = ({ preview }) => {
10923
10426
  }
10924
10427
  await confirmOrderEdit(void 0, {
10925
10428
  onError: (e) => {
10926
- ui.toast.error(e.message);
10429
+ ui.toast.error(`Failed to confirm order edit: ${e.message}`);
10927
10430
  },
10928
10431
  onSuccess: () => {
10929
10432
  handleSuccess();
@@ -10933,379 +10436,24 @@ const PromotionForm = ({ preview }) => {
10933
10436
  }
10934
10437
  });
10935
10438
  };
10936
- if (isError) {
10937
- throw error;
10938
- }
10939
- return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
10940
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
10941
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
10942
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10943
- /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
10944
- /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
10945
- ] }),
10946
- /* @__PURE__ */ jsxRuntime.jsx(
10947
- Combobox,
10948
- {
10949
- id: "promotion-combobox",
10950
- "aria-describedby": "promotion-combobox-hint",
10951
- isFetchingNextPage: comboboxData.isFetchingNextPage,
10952
- fetchNextPage: comboboxData.fetchNextPage,
10953
- options: comboboxData.options,
10954
- onSearchValueChange: comboboxData.onSearchValueChange,
10955
- searchValue: comboboxData.searchValue,
10956
- disabled: comboboxData.disabled || isAddingPromotions,
10957
- onChange: add,
10958
- value: comboboxValue
10959
- }
10960
- )
10961
- ] }),
10962
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10963
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
10964
- PromotionItem,
10965
- {
10966
- promotion,
10967
- orderId: preview.id,
10968
- isLoading: isPending
10969
- },
10970
- promotion.id
10971
- )) })
10972
- ] }) }),
10973
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
10974
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
10975
- /* @__PURE__ */ jsxRuntime.jsx(
10976
- ui.Button,
10977
- {
10978
- size: "small",
10979
- type: "submit",
10980
- isLoading: isSubmitting || isAddingPromotions,
10981
- children: "Save"
10982
- }
10983
- )
10984
- ] }) })
10985
- ] });
10986
- };
10987
- const PromotionItem = ({
10988
- promotion,
10989
- orderId,
10990
- isLoading
10991
- }) => {
10992
- var _a;
10993
- const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
10994
- const onRemove = async () => {
10995
- removePromotions(
10996
- {
10997
- promo_codes: [promotion.code]
10998
- },
10999
- {
11000
- onError: (e) => {
11001
- ui.toast.error(e.message);
11002
- }
11003
- }
11004
- );
11005
- };
11006
- const displayValue = getDisplayValue(promotion);
11007
- return /* @__PURE__ */ jsxRuntime.jsxs(
11008
- "div",
11009
- {
11010
- className: ui.clx(
11011
- "px-3 py-2 rounded-lg bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between",
11012
- {
11013
- "animate-pulse": isLoading
11014
- }
11015
- ),
11016
- children: [
11017
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11018
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
11019
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-ui-fg-subtle", children: [
11020
- displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
11021
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
11022
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
11023
- ] }),
11024
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
11025
- ] })
11026
- ] }),
11027
- /* @__PURE__ */ jsxRuntime.jsx(
11028
- ui.IconButton,
11029
- {
11030
- size: "small",
11031
- type: "button",
11032
- variant: "transparent",
11033
- onClick: onRemove,
11034
- isLoading: isPending || isLoading,
11035
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
11036
- }
11037
- )
11038
- ]
11039
- },
11040
- promotion.id
11041
- );
11042
- };
11043
- function getDisplayValue(promotion) {
11044
- var _a, _b, _c, _d;
11045
- const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
11046
- if (!value) {
11047
- return null;
11048
- }
11049
- if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
11050
- const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
11051
- if (!currency) {
11052
- return null;
11053
- }
11054
- return getLocaleAmount(value, currency);
11055
- } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
11056
- return formatPercentage(value);
11057
- }
11058
- return null;
11059
- }
11060
- const formatter = new Intl.NumberFormat([], {
11061
- style: "percent",
11062
- minimumFractionDigits: 2
11063
- });
11064
- const formatPercentage = (value, isPercentageValue = false) => {
11065
- let val = value || 0;
11066
- if (!isPercentageValue) {
11067
- val = val / 100;
11068
- }
11069
- return formatter.format(val);
11070
- };
11071
- function getPromotionCodes(items, shippingMethods) {
11072
- const codes = /* @__PURE__ */ new Set();
11073
- for (const item of items) {
11074
- if (item.adjustments) {
11075
- for (const adjustment of item.adjustments) {
11076
- if (adjustment.code) {
11077
- codes.add(adjustment.code);
11078
- }
11079
- }
11080
- }
11081
- }
11082
- for (const shippingMethod of shippingMethods) {
11083
- if (shippingMethod.adjustments) {
11084
- for (const adjustment of shippingMethod.adjustments) {
11085
- if (adjustment.code) {
11086
- codes.add(adjustment.code);
11087
- }
11088
- }
11089
- }
11090
- }
11091
- return Array.from(codes);
11092
- }
11093
- const SalesChannel = () => {
11094
- const { id } = reactRouterDom.useParams();
11095
- const { draft_order, isPending, isError, error } = useDraftOrder(
11096
- id,
11097
- {
11098
- fields: "+sales_channel_id"
11099
- },
11100
- {
11101
- enabled: !!id
11102
- }
11103
- );
11104
- if (isError) {
11105
- throw error;
11106
- }
11107
- const ISrEADY = !!draft_order && !isPending;
11108
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
11109
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
11110
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Sales Channel" }) }),
11111
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Update which sales channel the draft order is associated with" }) })
11112
- ] }),
11113
- ISrEADY && /* @__PURE__ */ jsxRuntime.jsx(SalesChannelForm, { order: draft_order })
11114
- ] });
11115
- };
11116
- const SalesChannelForm = ({ order }) => {
11117
- const form = reactHookForm.useForm({
11118
- defaultValues: {
11119
- sales_channel_id: order.sales_channel_id || ""
11120
- },
11121
- resolver: zod.zodResolver(schema$2)
11122
- });
11123
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11124
- const { handleSuccess } = useRouteModal();
11125
- const onSubmit = form.handleSubmit(async (data) => {
11126
- await mutateAsync(
11127
- {
11128
- sales_channel_id: data.sales_channel_id
11129
- },
11130
- {
11131
- onSuccess: () => {
11132
- ui.toast.success("Sales channel updated");
11133
- handleSuccess();
11134
- },
11135
- onError: (error) => {
11136
- ui.toast.error(error.message);
10439
+ const onKeydown = React.useCallback(
10440
+ (e) => {
10441
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
10442
+ if (data || isSubmitting) {
10443
+ return;
11137
10444
  }
10445
+ onSubmit();
11138
10446
  }
11139
- );
11140
- });
11141
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11142
- KeyboundForm,
11143
- {
11144
- className: "flex flex-1 flex-col overflow-hidden",
11145
- onSubmit,
11146
- children: [
11147
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SalesChannelField, { control: form.control, order }) }),
11148
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
11149
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
11150
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11151
- ] }) })
11152
- ]
11153
- }
11154
- ) });
11155
- };
11156
- const SalesChannelField = ({ control, order }) => {
11157
- const salesChannels = useComboboxData({
11158
- queryFn: async (params) => {
11159
- return await sdk.admin.salesChannel.list(params);
11160
- },
11161
- queryKey: ["sales-channels"],
11162
- getOptions: (data) => {
11163
- return data.sales_channels.map((salesChannel) => ({
11164
- label: salesChannel.name,
11165
- value: salesChannel.id
11166
- }));
11167
10447
  },
11168
- defaultValue: order.sales_channel_id || void 0
11169
- });
11170
- return /* @__PURE__ */ jsxRuntime.jsx(
11171
- Form$2.Field,
11172
- {
11173
- control,
11174
- name: "sales_channel_id",
11175
- render: ({ field }) => {
11176
- return /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
11177
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Sales Channel" }),
11178
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11179
- Combobox,
11180
- {
11181
- options: salesChannels.options,
11182
- fetchNextPage: salesChannels.fetchNextPage,
11183
- isFetchingNextPage: salesChannels.isFetchingNextPage,
11184
- searchValue: salesChannels.searchValue,
11185
- onSearchValueChange: salesChannels.onSearchValueChange,
11186
- placeholder: "Select sales channel",
11187
- ...field
11188
- }
11189
- ) }),
11190
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
11191
- ] });
11192
- }
11193
- }
10448
+ [data, isSubmitting, onSubmit]
11194
10449
  );
11195
- };
11196
- const schema$2 = objectType({
11197
- sales_channel_id: stringType().min(1)
11198
- });
11199
- const STACKED_FOCUS_MODAL_ID = "shipping-form";
11200
- const Shipping = () => {
11201
- var _a;
11202
- const { id } = reactRouterDom.useParams();
11203
- const { order, isPending, isError, error } = useOrder(id, {
11204
- fields: "+items.*,+items.variant.*,+items.variant.product.*,+items.variant.product.shipping_profile.*,+currency_code"
11205
- });
11206
- const {
11207
- order: preview,
11208
- isPending: isPreviewPending,
11209
- isError: isPreviewError,
11210
- error: previewError
11211
- } = useOrderPreview(id);
11212
- useInitiateOrderEdit({ preview });
11213
- const { onCancel } = useCancelOrderEdit({ preview });
11214
- if (isError) {
11215
- throw error;
11216
- }
11217
- if (isPreviewError) {
11218
- throw previewError;
11219
- }
11220
- const orderHasItems = (((_a = order == null ? void 0 : order.items) == null ? void 0 : _a.length) || 0) > 0;
11221
- const isReady = preview && !isPreviewPending && order && !isPending;
11222
- return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: !orderHasItems ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden ", children: [
11223
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
11224
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
11225
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
11226
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "This draft order currently has no items. Add items to the order before adding shipping." }) })
11227
- ] }) }) }),
11228
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }) })
11229
- ] }) : isReady ? /* @__PURE__ */ jsxRuntime.jsx(ShippingForm, { preview, order }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11230
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Shipping" }) }),
11231
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
11232
- ] }) });
11233
- };
11234
- const ShippingForm = ({ preview, order }) => {
11235
- var _a;
11236
- const { setIsOpen } = useStackedModal();
11237
- const [isSubmitting, setIsSubmitting] = React.useState(false);
11238
- const [data, setData] = React.useState(null);
11239
- const appliedShippingOptionIds = (_a = preview.shipping_methods) == null ? void 0 : _a.map((method) => method.shipping_option_id).filter(Boolean);
11240
- const { shipping_options } = useShippingOptions(
11241
- {
11242
- id: appliedShippingOptionIds,
11243
- fields: "+service_zone.*,+service_zone.fulfillment_set.*,+service_zone.fulfillment_set.location.*"
11244
- },
11245
- {
11246
- enabled: appliedShippingOptionIds.length > 0
11247
- }
11248
- );
11249
- const uniqueShippingProfiles = React.useMemo(() => {
11250
- const profiles = /* @__PURE__ */ new Map();
11251
- getUniqueShippingProfiles(order.items).forEach((profile) => {
11252
- profiles.set(profile.id, profile);
11253
- });
11254
- shipping_options == null ? void 0 : shipping_options.forEach((option) => {
11255
- profiles.set(option.shipping_profile_id, option.shipping_profile);
11256
- });
11257
- return Array.from(profiles.values());
11258
- }, [order.items, shipping_options]);
11259
- const { handleSuccess } = useRouteModal();
11260
- const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11261
- const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
11262
- const { mutateAsync: removeShippingMethod } = useDraftOrderRemoveShippingMethod(preview.id);
11263
- const { mutateAsync: removeActionShippingMethod } = useDraftOrderRemoveActionShippingMethod(preview.id);
11264
- const onSubmit = async () => {
11265
- setIsSubmitting(true);
11266
- let requestSucceeded = false;
11267
- await requestOrderEdit(void 0, {
11268
- onError: (e) => {
11269
- ui.toast.error(`Failed to request order edit: ${e.message}`);
11270
- },
11271
- onSuccess: () => {
11272
- requestSucceeded = true;
11273
- }
11274
- });
11275
- if (!requestSucceeded) {
11276
- setIsSubmitting(false);
11277
- return;
11278
- }
11279
- await confirmOrderEdit(void 0, {
11280
- onError: (e) => {
11281
- ui.toast.error(`Failed to confirm order edit: ${e.message}`);
11282
- },
11283
- onSuccess: () => {
11284
- handleSuccess();
11285
- },
11286
- onSettled: () => {
11287
- setIsSubmitting(false);
11288
- }
11289
- });
11290
- };
11291
- const onKeydown = React.useCallback(
11292
- (e) => {
11293
- if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
11294
- if (data || isSubmitting) {
11295
- return;
11296
- }
11297
- onSubmit();
11298
- }
11299
- },
11300
- [data, isSubmitting, onSubmit]
11301
- );
11302
- React.useEffect(() => {
11303
- document.addEventListener("keydown", onKeydown);
11304
- return () => {
11305
- document.removeEventListener("keydown", onKeydown);
11306
- };
11307
- }, [onKeydown]);
11308
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
10450
+ React.useEffect(() => {
10451
+ document.addEventListener("keydown", onKeydown);
10452
+ return () => {
10453
+ document.removeEventListener("keydown", onKeydown);
10454
+ };
10455
+ }, [onKeydown]);
10456
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
11309
10457
  /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
11310
10458
  /* @__PURE__ */ jsxRuntime.jsxs(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: [
11311
10459
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
@@ -11503,7 +10651,7 @@ const ShippingForm = ({ preview, order }) => {
11503
10651
  ]
11504
10652
  }
11505
10653
  ) : /* @__PURE__ */ jsxRuntime.jsx(
11506
- StackedModalTrigger,
10654
+ StackedModalTrigger$1,
11507
10655
  {
11508
10656
  shippingProfileId: profile.id,
11509
10657
  shippingOption,
@@ -11578,634 +10726,1633 @@ const ShippingForm = ({ preview, order }) => {
11578
10726
  ] }, item.id);
11579
10727
  })
11580
10728
  ] })
11581
- ]
11582
- },
11583
- profile.id
11584
- );
11585
- }) })
11586
- ] }) })
11587
- ] }) }),
10729
+ ]
10730
+ },
10731
+ profile.id
10732
+ );
10733
+ }) })
10734
+ ] }) })
10735
+ ] }) }),
10736
+ /* @__PURE__ */ jsxRuntime.jsx(
10737
+ StackedFocusModal,
10738
+ {
10739
+ id: STACKED_FOCUS_MODAL_ID,
10740
+ onOpenChangeCallback: (open) => {
10741
+ if (!open) {
10742
+ setData(null);
10743
+ }
10744
+ return open;
10745
+ },
10746
+ children: data && /* @__PURE__ */ jsxRuntime.jsx(ShippingProfileForm, { data, order, preview })
10747
+ }
10748
+ )
10749
+ ] }),
10750
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-x-2", children: [
10751
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10752
+ /* @__PURE__ */ jsxRuntime.jsx(
10753
+ ui.Button,
10754
+ {
10755
+ size: "small",
10756
+ type: "button",
10757
+ isLoading: isSubmitting,
10758
+ onClick: onSubmit,
10759
+ children: "Save"
10760
+ }
10761
+ )
10762
+ ] }) })
10763
+ ] });
10764
+ };
10765
+ const StackedModalTrigger$1 = ({
10766
+ shippingProfileId,
10767
+ shippingOption,
10768
+ shippingMethod,
10769
+ setData,
10770
+ children
10771
+ }) => {
10772
+ const { setIsOpen, getIsOpen } = useStackedModal();
10773
+ const isOpen = getIsOpen(STACKED_FOCUS_MODAL_ID);
10774
+ const onToggle = () => {
10775
+ if (isOpen) {
10776
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
10777
+ setData(null);
10778
+ } else {
10779
+ setIsOpen(STACKED_FOCUS_MODAL_ID, true);
10780
+ setData({
10781
+ shippingProfileId,
10782
+ shippingOption,
10783
+ shippingMethod
10784
+ });
10785
+ }
10786
+ };
10787
+ return /* @__PURE__ */ jsxRuntime.jsx(
10788
+ ui.Button,
10789
+ {
10790
+ size: "small",
10791
+ variant: "secondary",
10792
+ onClick: onToggle,
10793
+ className: "text-ui-fg-primary shrink-0",
10794
+ children
10795
+ }
10796
+ );
10797
+ };
10798
+ const ShippingProfileForm = ({
10799
+ data,
10800
+ order,
10801
+ preview
10802
+ }) => {
10803
+ var _a, _b, _c, _d, _e, _f;
10804
+ const { setIsOpen } = useStackedModal();
10805
+ const form = reactHookForm.useForm({
10806
+ resolver: zod.zodResolver(shippingMethodSchema),
10807
+ defaultValues: {
10808
+ 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,
10809
+ shipping_option_id: (_e = data.shippingOption) == null ? void 0 : _e.id,
10810
+ custom_amount: (_f = data.shippingMethod) == null ? void 0 : _f.amount
10811
+ }
10812
+ });
10813
+ const { mutateAsync: addShippingMethod, isPending } = useDraftOrderAddShippingMethod(order.id);
10814
+ const {
10815
+ mutateAsync: updateShippingMethod,
10816
+ isPending: isUpdatingShippingMethod
10817
+ } = useDraftOrderUpdateShippingMethod(order.id);
10818
+ const onSubmit = form.handleSubmit(async (values) => {
10819
+ if (lodash.isEqual(values, form.formState.defaultValues)) {
10820
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
10821
+ return;
10822
+ }
10823
+ if (data.shippingMethod) {
10824
+ await updateShippingMethod(
10825
+ {
10826
+ method_id: data.shippingMethod.id,
10827
+ shipping_option_id: values.shipping_option_id,
10828
+ custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
10829
+ },
10830
+ {
10831
+ onError: (e) => {
10832
+ ui.toast.error(e.message);
10833
+ },
10834
+ onSuccess: () => {
10835
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
10836
+ }
10837
+ }
10838
+ );
10839
+ return;
10840
+ }
10841
+ await addShippingMethod(
10842
+ {
10843
+ shipping_option_id: values.shipping_option_id,
10844
+ custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
10845
+ },
10846
+ {
10847
+ onError: (e) => {
10848
+ ui.toast.error(e.message);
10849
+ },
10850
+ onSuccess: () => {
10851
+ setIsOpen(STACKED_FOCUS_MODAL_ID, false);
10852
+ }
10853
+ }
10854
+ );
10855
+ });
10856
+ return /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs(
10857
+ KeyboundForm,
10858
+ {
10859
+ className: "flex h-full flex-col overflow-hidden",
10860
+ onSubmit,
10861
+ children: [
10862
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
10863
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
10864
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10865
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
10866
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a shipping method for the selected shipping profile. You can see the items that will be shipped using this method in the preview below." }) })
10867
+ ] }),
10868
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10869
+ /* @__PURE__ */ jsxRuntime.jsx(
10870
+ LocationField,
10871
+ {
10872
+ control: form.control,
10873
+ setValue: form.setValue
10874
+ }
10875
+ ),
10876
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10877
+ /* @__PURE__ */ jsxRuntime.jsx(
10878
+ ShippingOptionField,
10879
+ {
10880
+ shippingProfileId: data.shippingProfileId,
10881
+ preview,
10882
+ control: form.control
10883
+ }
10884
+ ),
10885
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10886
+ /* @__PURE__ */ jsxRuntime.jsx(
10887
+ CustomAmountField,
10888
+ {
10889
+ control: form.control,
10890
+ currencyCode: order.currency_code
10891
+ }
10892
+ ),
10893
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
10894
+ /* @__PURE__ */ jsxRuntime.jsx(
10895
+ ItemsPreview,
10896
+ {
10897
+ order,
10898
+ shippingProfileId: data.shippingProfileId
10899
+ }
10900
+ )
10901
+ ] }) }) }),
10902
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-x-2", children: [
10903
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10904
+ /* @__PURE__ */ jsxRuntime.jsx(
10905
+ ui.Button,
10906
+ {
10907
+ size: "small",
10908
+ type: "submit",
10909
+ isLoading: isPending || isUpdatingShippingMethod,
10910
+ children: data.shippingMethod ? "Update" : "Add"
10911
+ }
10912
+ )
10913
+ ] }) })
10914
+ ]
10915
+ }
10916
+ ) }) });
10917
+ };
10918
+ const shippingMethodSchema = objectType({
10919
+ location_id: stringType(),
10920
+ shipping_option_id: stringType(),
10921
+ custom_amount: unionType([numberType(), stringType()]).optional()
10922
+ });
10923
+ const ItemsPreview = ({ order, shippingProfileId }) => {
10924
+ const matches = order.items.filter(
10925
+ (item) => {
10926
+ var _a, _b, _c;
10927
+ return ((_c = (_b = (_a = item.variant) == null ? void 0 : _a.product) == null ? void 0 : _b.shipping_profile) == null ? void 0 : _c.id) === shippingProfileId;
10928
+ }
10929
+ );
10930
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
10931
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 items-center gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10932
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items to ship" }),
10933
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Items with the selected shipping profile." })
10934
+ ] }) }),
10935
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
10936
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 px-4 py-2 text-ui-fg-muted", children: [
10937
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
10938
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) })
10939
+ ] }),
10940
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
10941
+ "div",
10942
+ {
10943
+ className: "grid grid-cols-2 gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center",
10944
+ children: [
10945
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
10946
+ /* @__PURE__ */ jsxRuntime.jsx(
10947
+ Thumbnail,
10948
+ {
10949
+ thumbnail: item.thumbnail,
10950
+ alt: item.product_title ?? void 0
10951
+ }
10952
+ ),
10953
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
10954
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
10955
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
10956
+ /* @__PURE__ */ jsxRuntime.jsxs(
10957
+ ui.Text,
10958
+ {
10959
+ size: "small",
10960
+ leading: "compact",
10961
+ className: "text-ui-fg-subtle",
10962
+ children: [
10963
+ "(",
10964
+ item.variant_title,
10965
+ ")"
10966
+ ]
10967
+ }
10968
+ )
10969
+ ] }),
10970
+ /* @__PURE__ */ jsxRuntime.jsx(
10971
+ ui.Text,
10972
+ {
10973
+ size: "small",
10974
+ leading: "compact",
10975
+ className: "text-ui-fg-subtle",
10976
+ children: item.variant_sku
10977
+ }
10978
+ )
10979
+ ] })
10980
+ ] }),
10981
+ /* @__PURE__ */ jsxRuntime.jsxs(
10982
+ ui.Text,
10983
+ {
10984
+ size: "small",
10985
+ leading: "compact",
10986
+ className: "text-ui-fg-subtle",
10987
+ children: [
10988
+ item.quantity,
10989
+ "x"
10990
+ ]
10991
+ }
10992
+ )
10993
+ ]
10994
+ },
10995
+ item.id
10996
+ )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
10997
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
10998
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
10999
+ 'No items found for "',
11000
+ query,
11001
+ '".'
11002
+ ] })
11003
+ ] }) })
11004
+ ] })
11005
+ ] });
11006
+ };
11007
+ const LocationField = ({ control, setValue }) => {
11008
+ const locations = useComboboxData({
11009
+ queryKey: ["locations"],
11010
+ queryFn: async (params) => {
11011
+ return await sdk.admin.stockLocation.list(params);
11012
+ },
11013
+ getOptions: (data) => {
11014
+ return data.stock_locations.map((location) => ({
11015
+ label: location.name,
11016
+ value: location.id
11017
+ }));
11018
+ }
11019
+ });
11020
+ return /* @__PURE__ */ jsxRuntime.jsx(
11021
+ Form$2.Field,
11022
+ {
11023
+ control,
11024
+ name: "location_id",
11025
+ render: ({ field: { onChange, ...field } }) => {
11026
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11027
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11028
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Location" }),
11029
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose where you want to ship the items from." })
11030
+ ] }),
11031
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11032
+ Combobox,
11033
+ {
11034
+ options: locations.options,
11035
+ fetchNextPage: locations.fetchNextPage,
11036
+ isFetchingNextPage: locations.isFetchingNextPage,
11037
+ searchValue: locations.searchValue,
11038
+ onSearchValueChange: locations.onSearchValueChange,
11039
+ placeholder: "Select location",
11040
+ onChange: (value) => {
11041
+ setValue("shipping_option_id", "", {
11042
+ shouldDirty: true,
11043
+ shouldTouch: true
11044
+ });
11045
+ onChange(value);
11046
+ },
11047
+ ...field
11048
+ }
11049
+ ) })
11050
+ ] }) });
11051
+ }
11052
+ }
11053
+ );
11054
+ };
11055
+ const ShippingOptionField = ({
11056
+ shippingProfileId,
11057
+ preview,
11058
+ control
11059
+ }) => {
11060
+ var _a;
11061
+ const locationId = reactHookForm.useWatch({ control, name: "location_id" });
11062
+ const shippingOptions = useComboboxData({
11063
+ queryKey: ["shipping_options", locationId, shippingProfileId],
11064
+ queryFn: async (params) => {
11065
+ return await sdk.admin.shippingOption.list({
11066
+ ...params,
11067
+ stock_location_id: locationId,
11068
+ shipping_profile_id: shippingProfileId
11069
+ });
11070
+ },
11071
+ getOptions: (data) => {
11072
+ return data.shipping_options.map((option) => {
11073
+ var _a2;
11074
+ if ((_a2 = option.rules) == null ? void 0 : _a2.find(
11075
+ (r) => r.attribute === "is_return" && r.value === "true"
11076
+ )) {
11077
+ return void 0;
11078
+ }
11079
+ return {
11080
+ label: option.name,
11081
+ value: option.id
11082
+ };
11083
+ }).filter(Boolean);
11084
+ },
11085
+ enabled: !!locationId && !!shippingProfileId,
11086
+ defaultValue: ((_a = preview.shipping_methods[0]) == null ? void 0 : _a.shipping_option_id) || void 0
11087
+ });
11088
+ const tooltipContent = !locationId && !shippingProfileId ? "Choose a location and shipping profile first." : !locationId ? "Choose a location first." : "Choose a shipping profile first.";
11089
+ return /* @__PURE__ */ jsxRuntime.jsx(
11090
+ Form$2.Field,
11091
+ {
11092
+ control,
11093
+ name: "shipping_option_id",
11094
+ render: ({ field }) => {
11095
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11096
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
11097
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Shipping option" }),
11098
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose the shipping option to use." })
11099
+ ] }),
11100
+ /* @__PURE__ */ jsxRuntime.jsx(
11101
+ ConditionalTooltip,
11102
+ {
11103
+ content: tooltipContent,
11104
+ showTooltip: !locationId || !shippingProfileId,
11105
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11106
+ Combobox,
11107
+ {
11108
+ options: shippingOptions.options,
11109
+ fetchNextPage: shippingOptions.fetchNextPage,
11110
+ isFetchingNextPage: shippingOptions.isFetchingNextPage,
11111
+ searchValue: shippingOptions.searchValue,
11112
+ onSearchValueChange: shippingOptions.onSearchValueChange,
11113
+ placeholder: "Select shipping option",
11114
+ ...field,
11115
+ disabled: !locationId || !shippingProfileId
11116
+ }
11117
+ ) }) })
11118
+ }
11119
+ )
11120
+ ] }) });
11121
+ }
11122
+ }
11123
+ );
11124
+ };
11125
+ const CustomAmountField = ({
11126
+ control,
11127
+ currencyCode
11128
+ }) => {
11129
+ return /* @__PURE__ */ jsxRuntime.jsx(
11130
+ Form$2.Field,
11131
+ {
11132
+ control,
11133
+ name: "custom_amount",
11134
+ render: ({ field: { onChange, ...field } }) => {
11135
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11136
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
11137
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
11138
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
11139
+ ] }),
11140
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11141
+ ui.CurrencyInput,
11142
+ {
11143
+ ...field,
11144
+ onValueChange: (value) => onChange(value),
11145
+ symbol: getNativeSymbol(currencyCode),
11146
+ code: currencyCode
11147
+ }
11148
+ ) })
11149
+ ] });
11150
+ }
11151
+ }
11152
+ );
11153
+ };
11154
+ const NumberInput = React.forwardRef(
11155
+ ({
11156
+ value,
11157
+ onChange,
11158
+ size = "base",
11159
+ min = 0,
11160
+ max = 100,
11161
+ step = 1,
11162
+ className,
11163
+ disabled,
11164
+ ...props
11165
+ }, ref) => {
11166
+ const handleChange = (event) => {
11167
+ const newValue = event.target.value === "" ? min : Number(event.target.value);
11168
+ if (!isNaN(newValue) && (max === void 0 || newValue <= max) && (min === void 0 || newValue >= min)) {
11169
+ onChange(newValue);
11170
+ }
11171
+ };
11172
+ const handleIncrement = () => {
11173
+ const newValue = value + step;
11174
+ if (max === void 0 || newValue <= max) {
11175
+ onChange(newValue);
11176
+ }
11177
+ };
11178
+ const handleDecrement = () => {
11179
+ const newValue = value - step;
11180
+ if (min === void 0 || newValue >= min) {
11181
+ onChange(newValue);
11182
+ }
11183
+ };
11184
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11185
+ "div",
11186
+ {
11187
+ className: ui.clx(
11188
+ "inline-flex rounded-md bg-ui-bg-field shadow-borders-base overflow-hidden divide-x transition-fg",
11189
+ "[&:has(input:focus)]:shadow-borders-interactive-with-active",
11190
+ {
11191
+ "h-7": size === "small",
11192
+ "h-8": size === "base"
11193
+ },
11194
+ className
11195
+ ),
11196
+ children: [
11197
+ /* @__PURE__ */ jsxRuntime.jsx(
11198
+ "input",
11199
+ {
11200
+ ref,
11201
+ type: "number",
11202
+ value,
11203
+ onChange: handleChange,
11204
+ min,
11205
+ max,
11206
+ step,
11207
+ className: ui.clx(
11208
+ "flex-1 px-2 py-1 bg-transparent txt-compact-small text-ui-fg-base outline-none [appearance:textfield]",
11209
+ "[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
11210
+ "placeholder:text-ui-fg-muted"
11211
+ ),
11212
+ ...props
11213
+ }
11214
+ ),
11215
+ /* @__PURE__ */ jsxRuntime.jsxs(
11216
+ "button",
11217
+ {
11218
+ className: ui.clx(
11219
+ "flex items-center justify-center outline-none transition-fg",
11220
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
11221
+ "focus:bg-ui-bg-field-component-hover",
11222
+ "hover:bg-ui-bg-field-component-hover",
11223
+ {
11224
+ "size-7": size === "small",
11225
+ "size-8": size === "base"
11226
+ }
11227
+ ),
11228
+ type: "button",
11229
+ onClick: handleDecrement,
11230
+ disabled: min !== void 0 && value <= min || disabled,
11231
+ children: [
11232
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Minus, {}),
11233
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Decrease by ${step}` })
11234
+ ]
11235
+ }
11236
+ ),
11237
+ /* @__PURE__ */ jsxRuntime.jsxs(
11238
+ "button",
11239
+ {
11240
+ className: ui.clx(
11241
+ "flex items-center justify-center outline-none transition-fg",
11242
+ "disabled:cursor-not-allowed disabled:text-ui-fg-muted",
11243
+ "focus:bg-ui-bg-field-hover",
11244
+ "hover:bg-ui-bg-field-hover",
11245
+ {
11246
+ "size-7": size === "small",
11247
+ "size-8": size === "base"
11248
+ }
11249
+ ),
11250
+ type: "button",
11251
+ onClick: handleIncrement,
11252
+ disabled: max !== void 0 && value >= max || disabled,
11253
+ children: [
11254
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
11255
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: `Increase by ${step}` })
11256
+ ]
11257
+ }
11258
+ )
11259
+ ]
11260
+ }
11261
+ );
11262
+ }
11263
+ );
11264
+ const PRODUCT_VARIANTS_QUERY_KEY = "product-variants";
11265
+ const productVariantsQueryKeys = {
11266
+ list: (query2) => [
11267
+ PRODUCT_VARIANTS_QUERY_KEY,
11268
+ query2 ? query2 : void 0
11269
+ ]
11270
+ };
11271
+ const useProductVariants = (query2, options) => {
11272
+ const { data, ...rest } = reactQuery.useQuery({
11273
+ queryKey: productVariantsQueryKeys.list(query2),
11274
+ queryFn: async () => await sdk.admin.productVariant.list(query2),
11275
+ ...options
11276
+ });
11277
+ return { ...data, ...rest };
11278
+ };
11279
+ const STACKED_MODAL_ID = "items_stacked_modal";
11280
+ const Items = () => {
11281
+ const { id } = reactRouterDom.useParams();
11282
+ const {
11283
+ order: preview,
11284
+ isPending: isPreviewPending,
11285
+ isError: isPreviewError,
11286
+ error: previewError
11287
+ } = useOrderPreview(id, void 0, {
11288
+ placeholderData: reactQuery.keepPreviousData
11289
+ });
11290
+ useInitiateOrderEdit({ preview });
11291
+ const { draft_order, isPending, isError, error } = useDraftOrder(
11292
+ id,
11293
+ {
11294
+ fields: "currency_code"
11295
+ },
11296
+ {
11297
+ enabled: !!id
11298
+ }
11299
+ );
11300
+ const { onCancel } = useCancelOrderEdit({ preview });
11301
+ if (isError) {
11302
+ throw error;
11303
+ }
11304
+ if (isPreviewError) {
11305
+ throw previewError;
11306
+ }
11307
+ const ready = !!preview && !isPreviewPending && !!draft_order && !isPending;
11308
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal, { onClose: onCancel, children: ready ? /* @__PURE__ */ jsxRuntime.jsx(ItemsForm, { preview, currencyCode: draft_order.currency_code }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11309
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit Items" }) }),
11310
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Loading data for the draft order, please wait..." }) })
11311
+ ] }) });
11312
+ };
11313
+ const ItemsForm = ({ preview, currencyCode }) => {
11314
+ var _a;
11315
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
11316
+ const [modalContent, setModalContent] = React.useState(
11317
+ null
11318
+ );
11319
+ const { handleSuccess } = useRouteModal();
11320
+ const { searchValue, onSearchValueChange, query: query2 } = useDebouncedSearch();
11321
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
11322
+ const { mutateAsync: requestOrderEdit } = useDraftOrderRequestEdit(preview.id);
11323
+ const itemCount = ((_a = preview.items) == null ? void 0 : _a.reduce((acc, item) => acc + item.quantity, 0)) || 0;
11324
+ const matches = React.useMemo(() => {
11325
+ return matchSorter.matchSorter(preview.items, query2, {
11326
+ keys: ["product_title", "variant_title", "variant_sku", "title"]
11327
+ });
11328
+ }, [preview.items, query2]);
11329
+ const onSubmit = async () => {
11330
+ setIsSubmitting(true);
11331
+ let requestSucceeded = false;
11332
+ await requestOrderEdit(void 0, {
11333
+ onError: (e) => {
11334
+ ui.toast.error(`Failed to request order edit: ${e.message}`);
11335
+ },
11336
+ onSuccess: () => {
11337
+ requestSucceeded = true;
11338
+ }
11339
+ });
11340
+ if (!requestSucceeded) {
11341
+ setIsSubmitting(false);
11342
+ return;
11343
+ }
11344
+ await confirmOrderEdit(void 0, {
11345
+ onError: (e) => {
11346
+ ui.toast.error(`Failed to confirm order edit: ${e.message}`);
11347
+ },
11348
+ onSuccess: () => {
11349
+ handleSuccess();
11350
+ },
11351
+ onSettled: () => {
11352
+ setIsSubmitting(false);
11353
+ }
11354
+ });
11355
+ };
11356
+ const onKeyDown = React.useCallback(
11357
+ (e) => {
11358
+ if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
11359
+ if (modalContent || isSubmitting) {
11360
+ return;
11361
+ }
11362
+ onSubmit();
11363
+ }
11364
+ },
11365
+ [modalContent, isSubmitting, onSubmit]
11366
+ );
11367
+ React.useEffect(() => {
11368
+ document.addEventListener("keydown", onKeyDown);
11369
+ return () => {
11370
+ document.removeEventListener("keydown", onKeyDown);
11371
+ };
11372
+ }, [onKeyDown]);
11373
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-hidden", children: [
11374
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Header, {}),
11375
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
11376
+ StackedFocusModal,
11377
+ {
11378
+ id: STACKED_MODAL_ID,
11379
+ onOpenChangeCallback: (open) => {
11380
+ if (!open) {
11381
+ setModalContent(null);
11382
+ }
11383
+ },
11384
+ children: [
11385
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-6 py-16", children: [
11386
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11387
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Items" }) }),
11388
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Edit the items in the draft order." }) })
11389
+ ] }),
11390
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11391
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
11392
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 items-center gap-3", children: [
11393
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
11394
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items" }),
11395
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Choose items from the product catalog." })
11396
+ ] }),
11397
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
11398
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
11399
+ ui.Input,
11400
+ {
11401
+ type: "search",
11402
+ placeholder: "Search items",
11403
+ value: searchValue,
11404
+ onChange: (e) => onSearchValueChange(e.target.value)
11405
+ }
11406
+ ) }),
11407
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
11408
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { type: "button", children: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}) }) }),
11409
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
11410
+ /* @__PURE__ */ jsxRuntime.jsx(
11411
+ StackedModalTrigger,
11412
+ {
11413
+ type: "add-items",
11414
+ setModalContent
11415
+ }
11416
+ ),
11417
+ /* @__PURE__ */ jsxRuntime.jsx(
11418
+ StackedModalTrigger,
11419
+ {
11420
+ type: "add-custom-item",
11421
+ setModalContent
11422
+ }
11423
+ )
11424
+ ] })
11425
+ ] })
11426
+ ] })
11427
+ ] }),
11428
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
11429
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-[5px]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_1fr_1fr_28px] gap-3 px-4 py-2 text-ui-fg-muted", children: [
11430
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
11431
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) }),
11432
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Price" }) }),
11433
+ /* @__PURE__ */ jsxRuntime.jsx("div", {})
11434
+ ] }) }),
11435
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: itemCount <= 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
11436
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "There are no items in this order" }),
11437
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add items to the order to get started." })
11438
+ ] }) : matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
11439
+ Item,
11440
+ {
11441
+ item,
11442
+ preview,
11443
+ currencyCode
11444
+ },
11445
+ item.id
11446
+ )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
11447
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
11448
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
11449
+ 'No items found for "',
11450
+ query2,
11451
+ '".'
11452
+ ] })
11453
+ ] }) })
11454
+ ] })
11455
+ ] }),
11456
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11457
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_0.5fr_0.5fr] gap-3", children: [
11458
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Subtotal" }) }),
11459
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(
11460
+ ui.Text,
11461
+ {
11462
+ size: "small",
11463
+ leading: "compact",
11464
+ className: "text-ui-fg-subtle",
11465
+ children: [
11466
+ itemCount,
11467
+ " ",
11468
+ itemCount === 1 ? "item" : "items"
11469
+ ]
11470
+ }
11471
+ ) }),
11472
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: getStylizedAmount(preview.item_subtotal, currencyCode) }) })
11473
+ ] })
11474
+ ] }) }),
11475
+ modalContent && (modalContent === "add-items" ? /* @__PURE__ */ jsxRuntime.jsx(ExistingItemsForm, { orderId: preview.id, items: preview.items }) : modalContent === "add-custom-item" ? /* @__PURE__ */ jsxRuntime.jsx(
11476
+ CustomItemForm,
11477
+ {
11478
+ orderId: preview.id,
11479
+ currencyCode
11480
+ }
11481
+ ) : null)
11482
+ ]
11483
+ }
11484
+ ) }),
11485
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
11486
+ /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11588
11487
  /* @__PURE__ */ jsxRuntime.jsx(
11589
- StackedFocusModal,
11488
+ ui.Button,
11590
11489
  {
11591
- id: STACKED_FOCUS_MODAL_ID,
11592
- onOpenChangeCallback: (open) => {
11593
- if (!open) {
11594
- setData(null);
11595
- }
11596
- return open;
11597
- },
11598
- children: data && /* @__PURE__ */ jsxRuntime.jsx(ShippingProfileForm, { data, order, preview })
11490
+ size: "small",
11491
+ type: "button",
11492
+ onClick: onSubmit,
11493
+ isLoading: isSubmitting,
11494
+ children: "Save"
11599
11495
  }
11600
11496
  )
11601
- ] }),
11602
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-x-2", children: [
11603
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11497
+ ] }) })
11498
+ ] });
11499
+ };
11500
+ const Item = ({ item, preview, currencyCode }) => {
11501
+ if (item.variant_id) {
11502
+ return /* @__PURE__ */ jsxRuntime.jsx(VariantItem, { item, preview, currencyCode });
11503
+ }
11504
+ return /* @__PURE__ */ jsxRuntime.jsx(CustomItem, { item, preview, currencyCode });
11505
+ };
11506
+ const VariantItem = ({ item, preview, currencyCode }) => {
11507
+ const [editing, setEditing] = React.useState(false);
11508
+ const form = reactHookForm.useForm({
11509
+ defaultValues: {
11510
+ quantity: item.quantity,
11511
+ unit_price: item.unit_price
11512
+ },
11513
+ resolver: zod.zodResolver(variantItemSchema)
11514
+ });
11515
+ const actionId = React.useMemo(() => {
11516
+ var _a, _b;
11517
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
11518
+ }, [item]);
11519
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
11520
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
11521
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
11522
+ const onSubmit = form.handleSubmit(async (data) => {
11523
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity) {
11524
+ setEditing(false);
11525
+ return;
11526
+ }
11527
+ if (!actionId) {
11528
+ await updateOriginalItem(
11529
+ {
11530
+ item_id: item.id,
11531
+ quantity: data.quantity,
11532
+ unit_price: convertNumber(data.unit_price)
11533
+ },
11534
+ {
11535
+ onSuccess: () => {
11536
+ setEditing(false);
11537
+ },
11538
+ onError: (e) => {
11539
+ ui.toast.error(e.message);
11540
+ }
11541
+ }
11542
+ );
11543
+ return;
11544
+ }
11545
+ await updateActionItem(
11546
+ {
11547
+ action_id: actionId,
11548
+ quantity: data.quantity,
11549
+ unit_price: convertNumber(data.unit_price)
11550
+ },
11551
+ {
11552
+ onSuccess: () => {
11553
+ setEditing(false);
11554
+ },
11555
+ onError: (e) => {
11556
+ ui.toast.error(e.message);
11557
+ }
11558
+ }
11559
+ );
11560
+ });
11561
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_28px] gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center", children: [
11562
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3 w-full", children: [
11604
11563
  /* @__PURE__ */ jsxRuntime.jsx(
11605
- ui.Button,
11564
+ Thumbnail,
11606
11565
  {
11607
- size: "small",
11608
- type: "button",
11609
- isLoading: isSubmitting,
11610
- onClick: onSubmit,
11611
- children: "Save"
11566
+ thumbnail: item.thumbnail,
11567
+ alt: item.product_title ?? void 0
11612
11568
  }
11613
- )
11614
- ] }) })
11615
- ] });
11569
+ ),
11570
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
11571
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
11572
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
11573
+ /* @__PURE__ */ jsxRuntime.jsxs(
11574
+ ui.Text,
11575
+ {
11576
+ size: "small",
11577
+ leading: "compact",
11578
+ className: "text-ui-fg-subtle",
11579
+ children: [
11580
+ "(",
11581
+ item.variant_title,
11582
+ ")"
11583
+ ]
11584
+ }
11585
+ )
11586
+ ] }),
11587
+ /* @__PURE__ */ jsxRuntime.jsx(
11588
+ ui.Text,
11589
+ {
11590
+ size: "small",
11591
+ leading: "compact",
11592
+ className: "text-ui-fg-subtle",
11593
+ children: item.variant_sku
11594
+ }
11595
+ )
11596
+ ] })
11597
+ ] }),
11598
+ editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
11599
+ Form$2.Field,
11600
+ {
11601
+ control: form.control,
11602
+ name: "quantity",
11603
+ render: ({ field }) => {
11604
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
11605
+ }
11606
+ }
11607
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }) }),
11608
+ editing ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
11609
+ Form$2.Field,
11610
+ {
11611
+ control: form.control,
11612
+ name: "unit_price",
11613
+ render: ({ field: { onChange, ...field } }) => {
11614
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11615
+ ui.CurrencyInput,
11616
+ {
11617
+ ...field,
11618
+ symbol: getNativeSymbol(currencyCode),
11619
+ code: currencyCode,
11620
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
11621
+ }
11622
+ ) }) });
11623
+ }
11624
+ }
11625
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex items-center justify-end w-full", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
11626
+ /* @__PURE__ */ jsxRuntime.jsx(
11627
+ ui.IconButton,
11628
+ {
11629
+ type: "button",
11630
+ size: "small",
11631
+ onClick: editing ? onSubmit : () => {
11632
+ setEditing(true);
11633
+ },
11634
+ disabled: isPending,
11635
+ children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
11636
+ }
11637
+ )
11638
+ ] }) }) });
11616
11639
  };
11617
- const StackedModalTrigger = ({
11618
- shippingProfileId,
11619
- shippingOption,
11620
- shippingMethod,
11621
- setData,
11622
- children
11623
- }) => {
11624
- const { setIsOpen, getIsOpen } = useStackedModal();
11625
- const isOpen = getIsOpen(STACKED_FOCUS_MODAL_ID);
11626
- const onToggle = () => {
11627
- if (isOpen) {
11628
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11629
- setData(null);
11630
- } else {
11631
- setIsOpen(STACKED_FOCUS_MODAL_ID, true);
11632
- setData({
11633
- shippingProfileId,
11634
- shippingOption,
11635
- shippingMethod
11636
- });
11640
+ const variantItemSchema = objectType({
11641
+ quantity: numberType(),
11642
+ unit_price: unionType([numberType(), stringType()])
11643
+ });
11644
+ const CustomItem = ({ item, preview, currencyCode }) => {
11645
+ const [editing, setEditing] = React.useState(false);
11646
+ const { quantity, unit_price, title } = item;
11647
+ const form = reactHookForm.useForm({
11648
+ defaultValues: {
11649
+ title,
11650
+ quantity,
11651
+ unit_price
11652
+ },
11653
+ resolver: zod.zodResolver(customItemSchema)
11654
+ });
11655
+ React.useEffect(() => {
11656
+ form.reset({
11657
+ title,
11658
+ quantity,
11659
+ unit_price
11660
+ });
11661
+ }, [form, title, quantity, unit_price]);
11662
+ const actionId = React.useMemo(() => {
11663
+ var _a, _b;
11664
+ return (_b = (_a = item.actions) == null ? void 0 : _a.find((a) => a.action === "ITEM_ADD")) == null ? void 0 : _b.id;
11665
+ }, [item]);
11666
+ const { mutateAsync: updateActionItem, isPending: isUpdatingActionItem } = useDraftOrderUpdateActionItem(preview.id);
11667
+ const { mutateAsync: removeActionItem, isPending: isRemovingActionItem } = useDraftOrderRemoveActionItem(preview.id);
11668
+ const { mutateAsync: updateOriginalItem, isPending: isUpdatingOriginalItem } = useDraftOrderUpdateItem(preview.id);
11669
+ const isPending = isUpdatingActionItem || isUpdatingOriginalItem;
11670
+ const onSubmit = form.handleSubmit(async (data) => {
11671
+ if (convertNumber(data.unit_price) === item.unit_price && data.quantity === item.quantity && data.title === item.title) {
11672
+ setEditing(false);
11673
+ return;
11637
11674
  }
11638
- };
11639
- return /* @__PURE__ */ jsxRuntime.jsx(
11640
- ui.Button,
11641
- {
11642
- size: "small",
11643
- variant: "secondary",
11644
- onClick: onToggle,
11645
- className: "text-ui-fg-primary shrink-0",
11646
- children
11675
+ if (!actionId) {
11676
+ await updateOriginalItem(
11677
+ {
11678
+ item_id: item.id,
11679
+ quantity: data.quantity,
11680
+ unit_price: convertNumber(data.unit_price)
11681
+ },
11682
+ {
11683
+ onSuccess: () => {
11684
+ setEditing(false);
11685
+ },
11686
+ onError: (e) => {
11687
+ ui.toast.error(e.message);
11688
+ }
11689
+ }
11690
+ );
11691
+ return;
11647
11692
  }
11648
- );
11693
+ if (data.quantity === 0) {
11694
+ await removeActionItem(actionId, {
11695
+ onSuccess: () => {
11696
+ setEditing(false);
11697
+ },
11698
+ onError: (e) => {
11699
+ ui.toast.error(e.message);
11700
+ }
11701
+ });
11702
+ return;
11703
+ }
11704
+ await updateActionItem(
11705
+ {
11706
+ action_id: actionId,
11707
+ quantity: data.quantity,
11708
+ unit_price: convertNumber(data.unit_price)
11709
+ },
11710
+ {
11711
+ onSuccess: () => {
11712
+ setEditing(false);
11713
+ },
11714
+ onError: (e) => {
11715
+ ui.toast.error(e.message);
11716
+ }
11717
+ }
11718
+ );
11719
+ });
11720
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_28px] gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center", children: [
11721
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
11722
+ /* @__PURE__ */ jsxRuntime.jsx(
11723
+ Thumbnail,
11724
+ {
11725
+ thumbnail: item.thumbnail,
11726
+ alt: item.title ?? void 0
11727
+ }
11728
+ ),
11729
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
11730
+ Form$2.Field,
11731
+ {
11732
+ control: form.control,
11733
+ name: "title",
11734
+ render: ({ field }) => {
11735
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }) });
11736
+ }
11737
+ }
11738
+ ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.title })
11739
+ ] }),
11740
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
11741
+ Form$2.Field,
11742
+ {
11743
+ control: form.control,
11744
+ name: "quantity",
11745
+ render: ({ field }) => {
11746
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field }) }) });
11747
+ }
11748
+ }
11749
+ ) : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: item.quantity }),
11750
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(
11751
+ Form$2.Field,
11752
+ {
11753
+ control: form.control,
11754
+ name: "unit_price",
11755
+ render: ({ field: { onChange, ...field } }) => {
11756
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11757
+ ui.CurrencyInput,
11758
+ {
11759
+ ...field,
11760
+ symbol: getNativeSymbol(currencyCode),
11761
+ code: currencyCode,
11762
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value)
11763
+ }
11764
+ ) }) });
11765
+ }
11766
+ }
11767
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex items-center justify-end", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: getLocaleAmount(item.unit_price, currencyCode) }) }),
11768
+ /* @__PURE__ */ jsxRuntime.jsx(
11769
+ ui.IconButton,
11770
+ {
11771
+ type: "button",
11772
+ size: "small",
11773
+ onClick: editing ? onSubmit : () => {
11774
+ setEditing(true);
11775
+ },
11776
+ disabled: isPending,
11777
+ children: editing ? /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.PencilSquare, {})
11778
+ }
11779
+ )
11780
+ ] }) }) });
11649
11781
  };
11650
- const ShippingProfileForm = ({
11651
- data,
11652
- order,
11653
- preview
11782
+ const StackedModalTrigger = ({
11783
+ type,
11784
+ setModalContent
11654
11785
  }) => {
11655
- var _a, _b, _c, _d, _e, _f;
11656
11786
  const { setIsOpen } = useStackedModal();
11657
- const form = reactHookForm.useForm({
11658
- resolver: zod.zodResolver(shippingMethodSchema),
11659
- defaultValues: {
11660
- 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,
11661
- shipping_option_id: (_e = data.shippingOption) == null ? void 0 : _e.id,
11662
- custom_amount: (_f = data.shippingMethod) == null ? void 0 : _f.amount
11663
- }
11664
- });
11665
- const { mutateAsync: addShippingMethod, isPending } = useDraftOrderAddShippingMethod(order.id);
11666
- const {
11667
- mutateAsync: updateShippingMethod,
11668
- isPending: isUpdatingShippingMethod
11669
- } = useDraftOrderUpdateShippingMethod(order.id);
11670
- const onSubmit = form.handleSubmit(async (values) => {
11671
- if (lodash.isEqual(values, form.formState.defaultValues)) {
11672
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11673
- return;
11674
- }
11675
- if (data.shippingMethod) {
11676
- await updateShippingMethod(
11677
- {
11678
- method_id: data.shippingMethod.id,
11679
- shipping_option_id: values.shipping_option_id,
11680
- custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
11681
- },
11682
- {
11683
- onError: (e) => {
11684
- ui.toast.error(e.message);
11685
- },
11686
- onSuccess: () => {
11687
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11688
- }
11787
+ const onClick = React.useCallback(() => {
11788
+ setModalContent(type);
11789
+ setIsOpen(STACKED_MODAL_ID, true);
11790
+ }, [setModalContent, setIsOpen, type]);
11791
+ return /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Item, { onClick, children: type === "add-items" ? "Add items" : "Add custom item" }) });
11792
+ };
11793
+ const VARIANT_PREFIX = "items";
11794
+ const LIMIT = 50;
11795
+ const ExistingItemsForm = ({ orderId, items }) => {
11796
+ const { setIsOpen } = useStackedModal();
11797
+ const [rowSelection, setRowSelection] = React.useState(
11798
+ items.reduce((acc, item) => {
11799
+ acc[item.variant_id] = true;
11800
+ return acc;
11801
+ }, {})
11802
+ );
11803
+ React.useEffect(() => {
11804
+ setRowSelection(
11805
+ items.reduce((acc, item) => {
11806
+ if (item.variant_id) {
11807
+ acc[item.variant_id] = true;
11689
11808
  }
11690
- );
11691
- return;
11809
+ return acc;
11810
+ }, {})
11811
+ );
11812
+ }, [items]);
11813
+ const { q, order, offset } = useQueryParams(
11814
+ ["q", "order", "offset"],
11815
+ VARIANT_PREFIX
11816
+ );
11817
+ const { variants, count, isPending, isError, error } = useProductVariants(
11818
+ {
11819
+ q,
11820
+ order,
11821
+ offset: offset ? parseInt(offset) : void 0,
11822
+ limit: LIMIT
11823
+ },
11824
+ {
11825
+ placeholderData: reactQuery.keepPreviousData
11692
11826
  }
11693
- await addShippingMethod(
11827
+ );
11828
+ const columns = useColumns();
11829
+ const { mutateAsync } = useDraftOrderAddItems(orderId);
11830
+ const onSubmit = async () => {
11831
+ const ids = Object.keys(rowSelection).filter(
11832
+ (id) => !items.find((i) => i.variant_id === id)
11833
+ );
11834
+ await mutateAsync(
11694
11835
  {
11695
- shipping_option_id: values.shipping_option_id,
11696
- custom_amount: values.custom_amount ? convertNumber(values.custom_amount) : void 0
11836
+ items: ids.map((id) => ({
11837
+ variant_id: id,
11838
+ quantity: 1
11839
+ }))
11697
11840
  },
11698
11841
  {
11842
+ onSuccess: () => {
11843
+ setRowSelection({});
11844
+ setIsOpen(STACKED_MODAL_ID, false);
11845
+ },
11699
11846
  onError: (e) => {
11700
11847
  ui.toast.error(e.message);
11701
- },
11702
- onSuccess: () => {
11703
- setIsOpen(STACKED_FOCUS_MODAL_ID, false);
11704
11848
  }
11705
11849
  }
11706
11850
  );
11707
- });
11708
- return /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs(
11709
- KeyboundForm,
11851
+ };
11852
+ if (isError) {
11853
+ throw error;
11854
+ }
11855
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11856
+ StackedFocusModal.Content,
11710
11857
  {
11711
- className: "flex h-full flex-col overflow-hidden",
11712
- onSubmit,
11858
+ onOpenAutoFocus: (e) => {
11859
+ e.preventDefault();
11860
+ const searchInput = document.querySelector(
11861
+ "[data-modal-id='modal-search-input']"
11862
+ );
11863
+ if (searchInput) {
11864
+ searchInput.focus();
11865
+ }
11866
+ },
11713
11867
  children: [
11714
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
11715
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 py-16 px-6", children: [
11716
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11717
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Shipping" }) }),
11718
- /* @__PURE__ */ jsxRuntime.jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a shipping method for the selected shipping profile. You can see the items that will be shipped using this method in the preview below." }) })
11719
- ] }),
11720
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11721
- /* @__PURE__ */ jsxRuntime.jsx(
11722
- LocationField,
11723
- {
11724
- control: form.control,
11725
- setValue: form.setValue
11726
- }
11727
- ),
11728
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11729
- /* @__PURE__ */ jsxRuntime.jsx(
11730
- ShippingOptionField,
11731
- {
11732
- shippingProfileId: data.shippingProfileId,
11733
- preview,
11734
- control: form.control
11735
- }
11736
- ),
11737
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11738
- /* @__PURE__ */ jsxRuntime.jsx(
11739
- CustomAmountField,
11740
- {
11741
- control: form.control,
11742
- currencyCode: order.currency_code
11743
- }
11744
- ),
11745
- /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
11746
- /* @__PURE__ */ jsxRuntime.jsx(
11747
- ItemsPreview,
11748
- {
11749
- order,
11750
- shippingProfileId: data.shippingProfileId
11751
- }
11752
- )
11753
- ] }) }) }),
11754
- /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-x-2", children: [
11868
+ /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Header, { children: [
11869
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Product Variants" }) }),
11870
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Choose product variants to add to the order." }) })
11871
+ ] }),
11872
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
11873
+ DataTable,
11874
+ {
11875
+ data: variants,
11876
+ columns,
11877
+ isLoading: isPending,
11878
+ getRowId: (row) => row.id,
11879
+ rowCount: count,
11880
+ prefix: VARIANT_PREFIX,
11881
+ layout: "fill",
11882
+ rowSelection: {
11883
+ state: rowSelection,
11884
+ onRowSelectionChange: setRowSelection,
11885
+ enableRowSelection: (row) => {
11886
+ return !items.find((i) => i.variant_id === row.original.id);
11887
+ }
11888
+ },
11889
+ autoFocusSearch: true
11890
+ }
11891
+ ) }),
11892
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
11755
11893
  /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11756
- /* @__PURE__ */ jsxRuntime.jsx(
11757
- ui.Button,
11758
- {
11759
- size: "small",
11760
- type: "submit",
11761
- isLoading: isPending || isUpdatingShippingMethod,
11762
- children: data.shippingMethod ? "Update" : "Add"
11763
- }
11764
- )
11894
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Update items" })
11765
11895
  ] }) })
11766
11896
  ]
11767
11897
  }
11768
- ) }) });
11898
+ );
11899
+ };
11900
+ const columnHelper = ui.createDataTableColumnHelper();
11901
+ const useColumns = () => {
11902
+ return React.useMemo(() => {
11903
+ return [
11904
+ columnHelper.select(),
11905
+ columnHelper.accessor("product.title", {
11906
+ header: "Product",
11907
+ cell: ({ row }) => {
11908
+ var _a, _b, _c;
11909
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2", children: [
11910
+ /* @__PURE__ */ jsxRuntime.jsx(
11911
+ Thumbnail,
11912
+ {
11913
+ thumbnail: (_a = row.original.product) == null ? void 0 : _a.thumbnail,
11914
+ alt: (_b = row.original.product) == null ? void 0 : _b.title
11915
+ }
11916
+ ),
11917
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: (_c = row.original.product) == null ? void 0 : _c.title })
11918
+ ] });
11919
+ },
11920
+ enableSorting: true
11921
+ }),
11922
+ columnHelper.accessor("title", {
11923
+ header: "Variant",
11924
+ enableSorting: true
11925
+ }),
11926
+ columnHelper.accessor("sku", {
11927
+ header: "SKU",
11928
+ cell: ({ getValue }) => {
11929
+ return getValue() ?? "-";
11930
+ },
11931
+ enableSorting: true
11932
+ }),
11933
+ columnHelper.accessor("updated_at", {
11934
+ header: "Updated",
11935
+ cell: ({ getValue }) => {
11936
+ return /* @__PURE__ */ jsxRuntime.jsx(
11937
+ ui.Tooltip,
11938
+ {
11939
+ content: getFullDate({ date: getValue(), includeTime: true }),
11940
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
11941
+ }
11942
+ );
11943
+ },
11944
+ enableSorting: true,
11945
+ sortAscLabel: "Oldest first",
11946
+ sortDescLabel: "Newest first"
11947
+ }),
11948
+ columnHelper.accessor("created_at", {
11949
+ header: "Created",
11950
+ cell: ({ getValue }) => {
11951
+ return /* @__PURE__ */ jsxRuntime.jsx(
11952
+ ui.Tooltip,
11953
+ {
11954
+ content: getFullDate({ date: getValue(), includeTime: true }),
11955
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: getFullDate({ date: getValue() }) })
11956
+ }
11957
+ );
11958
+ },
11959
+ enableSorting: true,
11960
+ sortAscLabel: "Oldest first",
11961
+ sortDescLabel: "Newest first"
11962
+ })
11963
+ ];
11964
+ }, []);
11769
11965
  };
11770
- const shippingMethodSchema = objectType({
11771
- location_id: stringType(),
11772
- shipping_option_id: stringType(),
11773
- custom_amount: unionType([numberType(), stringType()]).optional()
11774
- });
11775
- const ItemsPreview = ({ order, shippingProfileId }) => {
11776
- const matches = order.items.filter(
11777
- (item) => {
11778
- var _a, _b, _c;
11779
- return ((_c = (_b = (_a = item.variant) == null ? void 0 : _a.product) == null ? void 0 : _b.shipping_profile) == null ? void 0 : _c.id) === shippingProfileId;
11780
- }
11781
- );
11782
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
11783
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 items-center gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
11784
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "Items to ship" }),
11785
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Items with the selected shipping profile." })
11786
- ] }) }),
11787
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle shadow-elevation-card-rest rounded-xl", children: [
11788
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-3 px-4 py-2 text-ui-fg-muted", children: [
11789
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Item" }) }),
11790
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", children: "Quantity" }) })
11966
+ const CustomItemForm = ({ orderId, currencyCode }) => {
11967
+ const { setIsOpen } = useStackedModal();
11968
+ const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
11969
+ const form = reactHookForm.useForm({
11970
+ defaultValues: {
11971
+ title: "",
11972
+ quantity: 1,
11973
+ unit_price: ""
11974
+ },
11975
+ resolver: zod.zodResolver(customItemSchema)
11976
+ });
11977
+ const onSubmit = form.handleSubmit(async (data) => {
11978
+ await addItems(
11979
+ {
11980
+ items: [
11981
+ {
11982
+ title: data.title,
11983
+ quantity: data.quantity,
11984
+ unit_price: convertNumber(data.unit_price)
11985
+ }
11986
+ ]
11987
+ },
11988
+ {
11989
+ onSuccess: () => {
11990
+ setIsOpen(STACKED_MODAL_ID, false);
11991
+ },
11992
+ onError: (e) => {
11993
+ ui.toast.error(e.message);
11994
+ }
11995
+ }
11996
+ );
11997
+ });
11998
+ return /* @__PURE__ */ jsxRuntime.jsx(Form$2, { ...form, children: /* @__PURE__ */ jsxRuntime.jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxRuntime.jsxs(StackedFocusModal.Content, { children: [
11999
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Header, {}),
12000
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-2 py-16", children: [
12001
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12002
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Add custom item" }) }),
12003
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: "Add a custom item to the order. This will add a new line item that is not associated with an existing product." }) })
11791
12004
  ] }),
11792
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-y-1.5 px-[5px] pb-[5px]", children: matches.length > 0 ? matches == null ? void 0 : matches.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
11793
- "div",
12005
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12006
+ /* @__PURE__ */ jsxRuntime.jsx(
12007
+ Form$2.Field,
11794
12008
  {
11795
- className: "grid grid-cols-2 gap-3 px-4 py-2 bg-ui-bg-base shadow-elevation-card-rest rounded-lg items-center",
11796
- children: [
11797
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-3", children: [
11798
- /* @__PURE__ */ jsxRuntime.jsx(
11799
- Thumbnail,
12009
+ control: form.control,
12010
+ name: "title",
12011
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12012
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12013
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Title" }),
12014
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the title of the item" })
12015
+ ] }),
12016
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12017
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12018
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12019
+ ] })
12020
+ ] }) })
12021
+ }
12022
+ ),
12023
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12024
+ /* @__PURE__ */ jsxRuntime.jsx(
12025
+ Form$2.Field,
12026
+ {
12027
+ control: form.control,
12028
+ name: "unit_price",
12029
+ render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12030
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12031
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Unit price" }),
12032
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
12033
+ ] }),
12034
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12035
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12036
+ ui.CurrencyInput,
11800
12037
  {
11801
- thumbnail: item.thumbnail,
11802
- alt: item.product_title ?? void 0
12038
+ symbol: getNativeSymbol(currencyCode),
12039
+ code: currencyCode,
12040
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
12041
+ ...field
11803
12042
  }
11804
- ),
11805
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
11806
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
11807
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: item.product_title }),
11808
- /* @__PURE__ */ jsxRuntime.jsxs(
11809
- ui.Text,
11810
- {
11811
- size: "small",
11812
- leading: "compact",
11813
- className: "text-ui-fg-subtle",
11814
- children: [
11815
- "(",
11816
- item.variant_title,
11817
- ")"
11818
- ]
11819
- }
11820
- )
11821
- ] }),
11822
- /* @__PURE__ */ jsxRuntime.jsx(
11823
- ui.Text,
11824
- {
11825
- size: "small",
11826
- leading: "compact",
11827
- className: "text-ui-fg-subtle",
11828
- children: item.variant_sku
11829
- }
11830
- )
11831
- ] })
12043
+ ) }),
12044
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12045
+ ] })
12046
+ ] }) })
12047
+ }
12048
+ ),
12049
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12050
+ /* @__PURE__ */ jsxRuntime.jsx(
12051
+ Form$2.Field,
12052
+ {
12053
+ control: form.control,
12054
+ name: "quantity",
12055
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
12056
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12057
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Quantity" }),
12058
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
11832
12059
  ] }),
11833
- /* @__PURE__ */ jsxRuntime.jsxs(
11834
- ui.Text,
11835
- {
11836
- size: "small",
11837
- leading: "compact",
11838
- className: "text-ui-fg-subtle",
11839
- children: [
11840
- item.quantity,
11841
- "x"
11842
- ]
11843
- }
11844
- )
11845
- ]
11846
- },
11847
- item.id
11848
- )) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-x-3 bg-ui-bg-base rounded-lg p-4 shadow-elevation-card-rest flex-col gap-1", children: [
11849
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: "No items found" }),
11850
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: [
11851
- 'No items found for "',
11852
- query,
11853
- '".'
11854
- ] })
11855
- ] }) })
11856
- ] })
11857
- ] });
12060
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 w-full", children: [
12061
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(NumberInput, { ...field, className: "w-full" }) }) }),
12062
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12063
+ ] })
12064
+ ] }) })
12065
+ }
12066
+ )
12067
+ ] }) }) }),
12068
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-2 justify-end", children: [
12069
+ /* @__PURE__ */ jsxRuntime.jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12070
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
12071
+ ] }) })
12072
+ ] }) }) });
11858
12073
  };
11859
- const LocationField = ({ control, setValue }) => {
11860
- const locations = useComboboxData({
11861
- queryKey: ["locations"],
11862
- queryFn: async (params) => {
11863
- return await sdk.admin.stockLocation.list(params);
11864
- },
11865
- getOptions: (data) => {
11866
- return data.stock_locations.map((location) => ({
11867
- label: location.name,
11868
- value: location.id
11869
- }));
11870
- }
12074
+ const customItemSchema = objectType({
12075
+ title: stringType().min(1),
12076
+ quantity: numberType(),
12077
+ unit_price: unionType([numberType(), stringType()])
12078
+ });
12079
+ const PROMOTION_QUERY_KEY = "promotions";
12080
+ const promotionsQueryKeys = {
12081
+ list: (query2) => [
12082
+ PROMOTION_QUERY_KEY,
12083
+ query2 ? query2 : void 0
12084
+ ],
12085
+ detail: (id, query2) => [
12086
+ PROMOTION_QUERY_KEY,
12087
+ id,
12088
+ query2 ? query2 : void 0
12089
+ ]
12090
+ };
12091
+ const usePromotions = (query2, options) => {
12092
+ const { data, ...rest } = reactQuery.useQuery({
12093
+ queryKey: promotionsQueryKeys.list(query2),
12094
+ queryFn: async () => sdk.admin.promotion.list(query2),
12095
+ ...options
11871
12096
  });
11872
- return /* @__PURE__ */ jsxRuntime.jsx(
11873
- Form$2.Field,
12097
+ return { ...data, ...rest };
12098
+ };
12099
+ const Promotions = () => {
12100
+ const { id } = reactRouterDom.useParams();
12101
+ const {
12102
+ order: preview,
12103
+ isError: isPreviewError,
12104
+ error: previewError
12105
+ } = useOrderPreview(id, void 0);
12106
+ useInitiateOrderEdit({ preview });
12107
+ const { onCancel } = useCancelOrderEdit({ preview });
12108
+ if (isPreviewError) {
12109
+ throw previewError;
12110
+ }
12111
+ const isReady = !!preview;
12112
+ return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { onClose: onCancel, children: [
12113
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Promotions" }) }) }),
12114
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(PromotionForm, { preview })
12115
+ ] });
12116
+ };
12117
+ const PromotionForm = ({ preview }) => {
12118
+ const { items, shipping_methods } = preview;
12119
+ const [isSubmitting, setIsSubmitting] = React.useState(false);
12120
+ const [comboboxValue, setComboboxValue] = React.useState("");
12121
+ const { handleSuccess } = useRouteModal();
12122
+ const { mutateAsync: addPromotions, isPending: isAddingPromotions } = useDraftOrderAddPromotions(preview.id);
12123
+ const promoCodes = getPromotionCodes(items, shipping_methods);
12124
+ const { promotions, isPending, isError, error } = usePromotions(
11874
12125
  {
11875
- control,
11876
- name: "location_id",
11877
- render: ({ field: { onChange, ...field } }) => {
11878
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11879
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11880
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Location" }),
11881
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose where you want to ship the items from." })
11882
- ] }),
11883
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11884
- Combobox,
11885
- {
11886
- options: locations.options,
11887
- fetchNextPage: locations.fetchNextPage,
11888
- isFetchingNextPage: locations.isFetchingNextPage,
11889
- searchValue: locations.searchValue,
11890
- onSearchValueChange: locations.onSearchValueChange,
11891
- placeholder: "Select location",
11892
- onChange: (value) => {
11893
- setValue("shipping_option_id", "", {
11894
- shouldDirty: true,
11895
- shouldTouch: true
11896
- });
11897
- onChange(value);
11898
- },
11899
- ...field
11900
- }
11901
- ) })
11902
- ] }) });
11903
- }
12126
+ code: promoCodes
12127
+ },
12128
+ {
12129
+ enabled: !!promoCodes.length
11904
12130
  }
11905
12131
  );
11906
- };
11907
- const ShippingOptionField = ({
11908
- shippingProfileId,
11909
- preview,
11910
- control
11911
- }) => {
11912
- var _a;
11913
- const locationId = reactHookForm.useWatch({ control, name: "location_id" });
11914
- const shippingOptions = useComboboxData({
11915
- queryKey: ["shipping_options", locationId, shippingProfileId],
12132
+ const comboboxData = useComboboxData({
12133
+ queryKey: ["promotions", "combobox", promoCodes],
11916
12134
  queryFn: async (params) => {
11917
- return await sdk.admin.shippingOption.list({
12135
+ return await sdk.admin.promotion.list({
11918
12136
  ...params,
11919
- stock_location_id: locationId,
11920
- shipping_profile_id: shippingProfileId
12137
+ code: {
12138
+ $nin: promoCodes
12139
+ }
11921
12140
  });
11922
12141
  },
11923
12142
  getOptions: (data) => {
11924
- return data.shipping_options.map((option) => {
11925
- var _a2;
11926
- if ((_a2 = option.rules) == null ? void 0 : _a2.find(
11927
- (r) => r.attribute === "is_return" && r.value === "true"
11928
- )) {
11929
- return void 0;
11930
- }
11931
- return {
11932
- label: option.name,
11933
- value: option.id
11934
- };
11935
- }).filter(Boolean);
11936
- },
11937
- enabled: !!locationId && !!shippingProfileId,
11938
- defaultValue: ((_a = preview.shipping_methods[0]) == null ? void 0 : _a.shipping_option_id) || void 0
12143
+ return data.promotions.map((promotion) => ({
12144
+ label: promotion.code,
12145
+ value: promotion.code
12146
+ }));
12147
+ }
11939
12148
  });
11940
- const tooltipContent = !locationId && !shippingProfileId ? "Choose a location and shipping profile first." : !locationId ? "Choose a location first." : "Choose a shipping profile first.";
11941
- return /* @__PURE__ */ jsxRuntime.jsx(
11942
- Form$2.Field,
11943
- {
11944
- control,
11945
- name: "shipping_option_id",
11946
- render: ({ field }) => {
11947
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11948
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
11949
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Shipping option" }),
11950
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Choose the shipping option to use." })
11951
- ] }),
11952
- /* @__PURE__ */ jsxRuntime.jsx(
11953
- ConditionalTooltip,
11954
- {
11955
- content: tooltipContent,
11956
- showTooltip: !locationId || !shippingProfileId,
11957
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11958
- Combobox,
11959
- {
11960
- options: shippingOptions.options,
11961
- fetchNextPage: shippingOptions.fetchNextPage,
11962
- isFetchingNextPage: shippingOptions.isFetchingNextPage,
11963
- searchValue: shippingOptions.searchValue,
11964
- onSearchValueChange: shippingOptions.onSearchValueChange,
11965
- placeholder: "Select shipping option",
11966
- ...field,
11967
- disabled: !locationId || !shippingProfileId
11968
- }
11969
- ) }) })
11970
- }
11971
- )
11972
- ] }) });
11973
- }
12149
+ const add = async (value) => {
12150
+ if (!value) {
12151
+ return;
11974
12152
  }
11975
- );
11976
- };
11977
- const CustomAmountField = ({
11978
- control,
11979
- currencyCode
11980
- }) => {
11981
- return /* @__PURE__ */ jsxRuntime.jsx(
11982
- Form$2.Field,
11983
- {
11984
- control,
11985
- name: "custom_amount",
11986
- render: ({ field: { onChange, ...field } }) => {
11987
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11988
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
11989
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Custom amount" }),
11990
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Hint, { children: "Set a custom amount for the shipping option." })
11991
- ] }),
11992
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
11993
- ui.CurrencyInput,
11994
- {
11995
- ...field,
11996
- onValueChange: (value) => onChange(value),
11997
- symbol: getNativeSymbol(currencyCode),
11998
- code: currencyCode
11999
- }
12000
- ) })
12001
- ] });
12153
+ addPromotions(
12154
+ {
12155
+ promo_codes: [value]
12156
+ },
12157
+ {
12158
+ onError: (e) => {
12159
+ ui.toast.error(e.message);
12160
+ comboboxData.onSearchValueChange("");
12161
+ setComboboxValue("");
12162
+ },
12163
+ onSuccess: () => {
12164
+ comboboxData.onSearchValueChange("");
12165
+ setComboboxValue("");
12166
+ }
12167
+ }
12168
+ );
12169
+ };
12170
+ const { mutateAsync: confirmOrderEdit } = useDraftOrderConfirmEdit(preview.id);
12171
+ const { mutateAsync: requestOrderEdit } = useOrderEditRequest(preview.id);
12172
+ const onSubmit = async () => {
12173
+ setIsSubmitting(true);
12174
+ let requestSucceeded = false;
12175
+ await requestOrderEdit(void 0, {
12176
+ onError: (e) => {
12177
+ ui.toast.error(e.message);
12178
+ },
12179
+ onSuccess: () => {
12180
+ requestSucceeded = true;
12002
12181
  }
12182
+ });
12183
+ if (!requestSucceeded) {
12184
+ setIsSubmitting(false);
12185
+ return;
12003
12186
  }
12004
- );
12005
- };
12006
- const ShippingAddress = () => {
12007
- const { id } = reactRouterDom.useParams();
12008
- const { order, isPending, isError, error } = useOrder(id, {
12009
- fields: "+shipping_address"
12010
- });
12187
+ await confirmOrderEdit(void 0, {
12188
+ onError: (e) => {
12189
+ ui.toast.error(e.message);
12190
+ },
12191
+ onSuccess: () => {
12192
+ handleSuccess();
12193
+ },
12194
+ onSettled: () => {
12195
+ setIsSubmitting(false);
12196
+ }
12197
+ });
12198
+ };
12011
12199
  if (isError) {
12012
12200
  throw error;
12013
12201
  }
12014
- const isReady = !isPending && !!order;
12015
- return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
12016
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
12017
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Shipping Address" }) }),
12018
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
12019
- ] }),
12020
- isReady && /* @__PURE__ */ jsxRuntime.jsx(ShippingAddressForm, { order })
12021
- ] });
12022
- };
12023
- const ShippingAddressForm = ({ order }) => {
12024
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12025
- const form = reactHookForm.useForm({
12026
- defaultValues: {
12027
- first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
12028
- last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
12029
- company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
12030
- address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
12031
- address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
12032
- city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
12033
- province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
12034
- country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
12035
- postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12036
- phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12037
- },
12038
- resolver: zod.zodResolver(schema$1)
12039
- });
12040
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12041
- const { handleSuccess } = useRouteModal();
12042
- const onSubmit = form.handleSubmit(async (data) => {
12043
- await mutateAsync(
12044
- {
12045
- shipping_address: {
12046
- first_name: data.first_name,
12047
- last_name: data.last_name,
12048
- company: data.company,
12049
- address_1: data.address_1,
12050
- address_2: data.address_2,
12051
- city: data.city,
12052
- province: data.province,
12053
- country_code: data.country_code,
12054
- postal_code: data.postal_code,
12055
- phone: data.phone
12202
+ return /* @__PURE__ */ jsxRuntime.jsxs(KeyboundForm, { className: "flex flex-1 flex-col", onSubmit, children: [
12203
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
12204
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
12205
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
12206
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: "small", weight: "plus", htmlFor: "promotion-combobox", children: "Apply promotions" }),
12207
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { id: "promotion-combobox-hint", children: "Manage promotions that should be applied to the order." })
12208
+ ] }),
12209
+ /* @__PURE__ */ jsxRuntime.jsx(
12210
+ Combobox,
12211
+ {
12212
+ id: "promotion-combobox",
12213
+ "aria-describedby": "promotion-combobox-hint",
12214
+ isFetchingNextPage: comboboxData.isFetchingNextPage,
12215
+ fetchNextPage: comboboxData.fetchNextPage,
12216
+ options: comboboxData.options,
12217
+ onSearchValueChange: comboboxData.onSearchValueChange,
12218
+ searchValue: comboboxData.searchValue,
12219
+ disabled: comboboxData.disabled || isAddingPromotions,
12220
+ onChange: add,
12221
+ value: comboboxValue
12222
+ }
12223
+ )
12224
+ ] }),
12225
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Divider, { variant: "dashed" }),
12226
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: promotions == null ? void 0 : promotions.map((promotion) => /* @__PURE__ */ jsxRuntime.jsx(
12227
+ PromotionItem,
12228
+ {
12229
+ promotion,
12230
+ orderId: preview.id,
12231
+ isLoading: isPending
12232
+ },
12233
+ promotion.id
12234
+ )) })
12235
+ ] }) }),
12236
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
12237
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12238
+ /* @__PURE__ */ jsxRuntime.jsx(
12239
+ ui.Button,
12240
+ {
12241
+ size: "small",
12242
+ type: "submit",
12243
+ isLoading: isSubmitting || isAddingPromotions,
12244
+ children: "Save"
12056
12245
  }
12246
+ )
12247
+ ] }) })
12248
+ ] });
12249
+ };
12250
+ const PromotionItem = ({
12251
+ promotion,
12252
+ orderId,
12253
+ isLoading
12254
+ }) => {
12255
+ var _a;
12256
+ const { mutateAsync: removePromotions, isPending } = useDraftOrderRemovePromotions(orderId);
12257
+ const onRemove = async () => {
12258
+ removePromotions(
12259
+ {
12260
+ promo_codes: [promotion.code]
12057
12261
  },
12058
12262
  {
12059
- onSuccess: () => {
12060
- handleSuccess();
12061
- },
12062
- onError: (error) => {
12063
- ui.toast.error(error.message);
12263
+ onError: (e) => {
12264
+ ui.toast.error(e.message);
12064
12265
  }
12065
12266
  }
12066
12267
  );
12067
- });
12068
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12069
- KeyboundForm,
12268
+ };
12269
+ const displayValue = getDisplayValue(promotion);
12270
+ return /* @__PURE__ */ jsxRuntime.jsxs(
12271
+ "div",
12070
12272
  {
12071
- className: "flex flex-1 flex-col overflow-hidden",
12072
- onSubmit,
12273
+ className: ui.clx(
12274
+ "px-3 py-2 rounded-lg bg-ui-bg-component shadow-elevation-card-rest flex items-center justify-between",
12275
+ {
12276
+ "animate-pulse": isLoading
12277
+ }
12278
+ ),
12073
12279
  children: [
12074
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-4", children: [
12075
- /* @__PURE__ */ jsxRuntime.jsx(
12076
- Form$2.Field,
12077
- {
12078
- control: form.control,
12079
- name: "country_code",
12080
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12081
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Country" }),
12082
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(CountrySelect, { ...field }) }),
12083
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12084
- ] })
12085
- }
12086
- ),
12087
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12088
- /* @__PURE__ */ jsxRuntime.jsx(
12089
- Form$2.Field,
12090
- {
12091
- control: form.control,
12092
- name: "first_name",
12093
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12094
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "First name" }),
12095
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12096
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12097
- ] })
12098
- }
12099
- ),
12100
- /* @__PURE__ */ jsxRuntime.jsx(
12101
- Form$2.Field,
12102
- {
12103
- control: form.control,
12104
- name: "last_name",
12105
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12106
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Last name" }),
12107
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12108
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12109
- ] })
12110
- }
12111
- )
12112
- ] }),
12113
- /* @__PURE__ */ jsxRuntime.jsx(
12114
- Form$2.Field,
12115
- {
12116
- control: form.control,
12117
- name: "company",
12118
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12119
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Company" }),
12120
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12121
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12122
- ] })
12123
- }
12124
- ),
12125
- /* @__PURE__ */ jsxRuntime.jsx(
12126
- Form$2.Field,
12127
- {
12128
- control: form.control,
12129
- name: "address_1",
12130
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12131
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Address" }),
12132
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12133
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12134
- ] })
12135
- }
12136
- ),
12137
- /* @__PURE__ */ jsxRuntime.jsx(
12138
- Form$2.Field,
12139
- {
12140
- control: form.control,
12141
- name: "address_2",
12142
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12143
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12144
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12145
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12146
- ] })
12147
- }
12148
- ),
12149
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12150
- /* @__PURE__ */ jsxRuntime.jsx(
12151
- Form$2.Field,
12152
- {
12153
- control: form.control,
12154
- name: "postal_code",
12155
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12156
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Postal code" }),
12157
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12158
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12159
- ] })
12160
- }
12161
- ),
12162
- /* @__PURE__ */ jsxRuntime.jsx(
12163
- Form$2.Field,
12164
- {
12165
- control: form.control,
12166
- name: "city",
12167
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12168
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "City" }),
12169
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12170
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12171
- ] })
12172
- }
12173
- )
12174
- ] }),
12175
- /* @__PURE__ */ jsxRuntime.jsx(
12176
- Form$2.Field,
12177
- {
12178
- control: form.control,
12179
- name: "province",
12180
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12181
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Province / State" }),
12182
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12183
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12184
- ] })
12185
- }
12186
- ),
12187
- /* @__PURE__ */ jsxRuntime.jsx(
12188
- Form$2.Field,
12189
- {
12190
- control: form.control,
12191
- name: "phone",
12192
- render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12193
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Phone" }),
12194
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12195
- /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12196
- ] })
12197
- }
12198
- )
12199
- ] }) }),
12200
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
12201
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12202
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12203
- ] }) })
12280
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
12281
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", weight: "plus", leading: "compact", children: promotion.code }),
12282
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-ui-fg-subtle", children: [
12283
+ displayValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
12284
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: displayValue }),
12285
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", children: "·" })
12286
+ ] }),
12287
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "capitalize", children: (_a = promotion.application_method) == null ? void 0 : _a.allocation })
12288
+ ] })
12289
+ ] }),
12290
+ /* @__PURE__ */ jsxRuntime.jsx(
12291
+ ui.IconButton,
12292
+ {
12293
+ size: "small",
12294
+ type: "button",
12295
+ variant: "transparent",
12296
+ onClick: onRemove,
12297
+ isLoading: isPending || isLoading,
12298
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.XMark, {})
12299
+ }
12300
+ )
12204
12301
  ]
12302
+ },
12303
+ promotion.id
12304
+ );
12305
+ };
12306
+ function getDisplayValue(promotion) {
12307
+ var _a, _b, _c, _d;
12308
+ const value = (_a = promotion.application_method) == null ? void 0 : _a.value;
12309
+ if (!value) {
12310
+ return null;
12311
+ }
12312
+ if (((_b = promotion.application_method) == null ? void 0 : _b.type) === "fixed") {
12313
+ const currency = (_c = promotion.application_method) == null ? void 0 : _c.currency_code;
12314
+ if (!currency) {
12315
+ return null;
12316
+ }
12317
+ return getLocaleAmount(value, currency);
12318
+ } else if (((_d = promotion.application_method) == null ? void 0 : _d.type) === "percentage") {
12319
+ return formatPercentage(value);
12320
+ }
12321
+ return null;
12322
+ }
12323
+ const formatter = new Intl.NumberFormat([], {
12324
+ style: "percent",
12325
+ minimumFractionDigits: 2
12326
+ });
12327
+ const formatPercentage = (value, isPercentageValue = false) => {
12328
+ let val = value || 0;
12329
+ if (!isPercentageValue) {
12330
+ val = val / 100;
12331
+ }
12332
+ return formatter.format(val);
12333
+ };
12334
+ function getPromotionCodes(items, shippingMethods) {
12335
+ const codes = /* @__PURE__ */ new Set();
12336
+ for (const item of items) {
12337
+ if (item.adjustments) {
12338
+ for (const adjustment of item.adjustments) {
12339
+ if (adjustment.code) {
12340
+ codes.add(adjustment.code);
12341
+ }
12342
+ }
12343
+ }
12344
+ }
12345
+ for (const shippingMethod of shippingMethods) {
12346
+ if (shippingMethod.adjustments) {
12347
+ for (const adjustment of shippingMethod.adjustments) {
12348
+ if (adjustment.code) {
12349
+ codes.add(adjustment.code);
12350
+ }
12351
+ }
12205
12352
  }
12206
- ) });
12207
- };
12208
- const schema$1 = addressSchema;
12353
+ }
12354
+ return Array.from(codes);
12355
+ }
12209
12356
  const TransferOwnership = () => {
12210
12357
  const { id } = reactRouterDom.useParams();
12211
12358
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -12229,7 +12376,7 @@ const TransferOwnershipForm = ({ order }) => {
12229
12376
  defaultValues: {
12230
12377
  customer_id: order.customer_id || ""
12231
12378
  },
12232
- resolver: zod.zodResolver(schema)
12379
+ resolver: zod.zodResolver(schema$1)
12233
12380
  });
12234
12381
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12235
12382
  const { handleSuccess } = useRouteModal();
@@ -12679,57 +12826,13 @@ const Illustration = () => {
12679
12826
  }
12680
12827
  );
12681
12828
  };
12682
- const schema = objectType({
12829
+ const schema$1 = objectType({
12683
12830
  customer_id: stringType().min(1)
12684
12831
  });
12685
- const InlineTip = React.forwardRef(
12686
- ({ variant = "tip", label, className, children, ...props }, ref) => {
12687
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
12688
- return /* @__PURE__ */ jsxRuntime.jsxs(
12689
- "div",
12690
- {
12691
- ref,
12692
- className: ui.clx(
12693
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
12694
- className
12695
- ),
12696
- ...props,
12697
- children: [
12698
- /* @__PURE__ */ jsxRuntime.jsx(
12699
- "div",
12700
- {
12701
- role: "presentation",
12702
- className: ui.clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
12703
- "bg-ui-tag-orange-icon": variant === "warning"
12704
- })
12705
- }
12706
- ),
12707
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-pretty", children: [
12708
- /* @__PURE__ */ jsxRuntime.jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
12709
- labelValue,
12710
- ":"
12711
- ] }),
12712
- " ",
12713
- children
12714
- ] })
12715
- ]
12716
- }
12717
- );
12718
- }
12719
- );
12720
- InlineTip.displayName = "InlineTip";
12721
- const MetadataFieldSchema = objectType({
12722
- key: stringType(),
12723
- disabled: booleanType().optional(),
12724
- value: anyType()
12725
- });
12726
- const MetadataSchema = objectType({
12727
- metadata: arrayType(MetadataFieldSchema)
12728
- });
12729
- const Metadata = () => {
12832
+ const ShippingAddress = () => {
12730
12833
  const { id } = reactRouterDom.useParams();
12731
12834
  const { order, isPending, isError, error } = useOrder(id, {
12732
- fields: "metadata"
12835
+ fields: "+shipping_address"
12733
12836
  });
12734
12837
  if (isError) {
12735
12838
  throw error;
@@ -12737,301 +12840,198 @@ const Metadata = () => {
12737
12840
  const isReady = !isPending && !!order;
12738
12841
  return /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer, { children: [
12739
12842
  /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Header, { children: [
12740
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Metadata" }) }),
12741
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
12843
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { children: "Edit Shipping Address" }) }),
12844
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Edit the shipping address for the draft order" }) })
12742
12845
  ] }),
12743
- !isReady ? /* @__PURE__ */ jsxRuntime.jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsxRuntime.jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
12846
+ isReady && /* @__PURE__ */ jsxRuntime.jsx(ShippingAddressForm, { order })
12744
12847
  ] });
12745
12848
  };
12746
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
12747
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
12748
- const MetadataForm = ({ orderId, metadata }) => {
12749
- const { handleSuccess } = useRouteModal();
12750
- const hasUneditableRows = getHasUneditableRows(metadata);
12751
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
12849
+ const ShippingAddressForm = ({ order }) => {
12850
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
12752
12851
  const form = reactHookForm.useForm({
12753
12852
  defaultValues: {
12754
- metadata: getDefaultValues(metadata)
12853
+ first_name: ((_a = order.shipping_address) == null ? void 0 : _a.first_name) ?? "",
12854
+ last_name: ((_b = order.shipping_address) == null ? void 0 : _b.last_name) ?? "",
12855
+ company: ((_c = order.shipping_address) == null ? void 0 : _c.company) ?? "",
12856
+ address_1: ((_d = order.shipping_address) == null ? void 0 : _d.address_1) ?? "",
12857
+ address_2: ((_e = order.shipping_address) == null ? void 0 : _e.address_2) ?? "",
12858
+ city: ((_f = order.shipping_address) == null ? void 0 : _f.city) ?? "",
12859
+ province: ((_g = order.shipping_address) == null ? void 0 : _g.province) ?? "",
12860
+ country_code: ((_h = order.shipping_address) == null ? void 0 : _h.country_code) ?? "",
12861
+ postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12862
+ phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12755
12863
  },
12756
- resolver: zod.zodResolver(MetadataSchema)
12864
+ resolver: zod.zodResolver(schema)
12757
12865
  });
12758
- const handleSubmit = form.handleSubmit(async (data) => {
12759
- const parsedData = parseValues(data);
12866
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12867
+ const { handleSuccess } = useRouteModal();
12868
+ const onSubmit = form.handleSubmit(async (data) => {
12760
12869
  await mutateAsync(
12761
12870
  {
12762
- metadata: parsedData
12871
+ shipping_address: {
12872
+ first_name: data.first_name,
12873
+ last_name: data.last_name,
12874
+ company: data.company,
12875
+ address_1: data.address_1,
12876
+ address_2: data.address_2,
12877
+ city: data.city,
12878
+ province: data.province,
12879
+ country_code: data.country_code,
12880
+ postal_code: data.postal_code,
12881
+ phone: data.phone
12882
+ }
12763
12883
  },
12764
12884
  {
12765
12885
  onSuccess: () => {
12766
- ui.toast.success("Metadata updated");
12767
12886
  handleSuccess();
12768
12887
  },
12769
12888
  onError: (error) => {
12770
12889
  ui.toast.error(error.message);
12771
12890
  }
12772
12891
  }
12773
- );
12774
- });
12775
- const { fields, insert, remove } = reactHookForm.useFieldArray({
12776
- control: form.control,
12777
- name: "metadata"
12778
- });
12779
- function deleteRow(index) {
12780
- remove(index);
12781
- if (fields.length === 1) {
12782
- insert(0, {
12783
- key: "",
12784
- value: "",
12785
- disabled: false
12786
- });
12787
- }
12788
- }
12789
- function insertRow(index, position) {
12790
- insert(index + (position === "above" ? 0 : 1), {
12791
- key: "",
12792
- value: "",
12793
- disabled: false
12794
- });
12795
- }
12796
- return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12797
- KeyboundForm,
12798
- {
12799
- onSubmit: handleSubmit,
12800
- className: "flex flex-1 flex-col overflow-hidden",
12801
- children: [
12802
- /* @__PURE__ */ jsxRuntime.jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
12803
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
12804
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
12805
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
12806
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
12807
- ] }),
12808
- fields.map((field, index) => {
12809
- const isDisabled = field.disabled || false;
12810
- let placeholder = "-";
12811
- if (typeof field.value === "object") {
12812
- placeholder = "{ ... }";
12813
- }
12814
- if (Array.isArray(field.value)) {
12815
- placeholder = "[ ... ]";
12816
- }
12817
- return /* @__PURE__ */ jsxRuntime.jsx(
12818
- ConditionalTooltip,
12819
- {
12820
- showTooltip: isDisabled,
12821
- content: "This row is disabled because it contains non-primitive data.",
12822
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group/table relative", children: [
12823
- /* @__PURE__ */ jsxRuntime.jsxs(
12824
- "div",
12825
- {
12826
- className: ui.clx("grid grid-cols-2 divide-x", {
12827
- "overflow-hidden rounded-b-lg": index === fields.length - 1
12828
- }),
12829
- children: [
12830
- /* @__PURE__ */ jsxRuntime.jsx(
12831
- Form$2.Field,
12832
- {
12833
- control: form.control,
12834
- name: `metadata.${index}.key`,
12835
- render: ({ field: field2 }) => {
12836
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12837
- GridInput,
12838
- {
12839
- "aria-labelledby": METADATA_KEY_LABEL_ID,
12840
- ...field2,
12841
- disabled: isDisabled,
12842
- placeholder: "Key"
12843
- }
12844
- ) }) });
12845
- }
12846
- }
12847
- ),
12848
- /* @__PURE__ */ jsxRuntime.jsx(
12849
- Form$2.Field,
12850
- {
12851
- control: form.control,
12852
- name: `metadata.${index}.value`,
12853
- render: ({ field: { value, ...field2 } }) => {
12854
- return /* @__PURE__ */ jsxRuntime.jsx(Form$2.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(
12855
- GridInput,
12856
- {
12857
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
12858
- ...field2,
12859
- value: isDisabled ? placeholder : value,
12860
- disabled: isDisabled,
12861
- placeholder: "Value"
12862
- }
12863
- ) }) });
12864
- }
12865
- }
12866
- )
12867
- ]
12868
- }
12869
- ),
12870
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu, { children: [
12871
- /* @__PURE__ */ jsxRuntime.jsx(
12872
- ui.DropdownMenu.Trigger,
12873
- {
12874
- className: ui.clx(
12875
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
12876
- {
12877
- hidden: isDisabled
12878
- }
12879
- ),
12880
- disabled: isDisabled,
12881
- asChild: true,
12882
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsxRuntime.jsx(icons.EllipsisVertical, {}) })
12883
- }
12884
- ),
12885
- /* @__PURE__ */ jsxRuntime.jsxs(ui.DropdownMenu.Content, { children: [
12886
- /* @__PURE__ */ jsxRuntime.jsxs(
12887
- ui.DropdownMenu.Item,
12888
- {
12889
- className: "gap-x-2",
12890
- onClick: () => insertRow(index, "above"),
12891
- children: [
12892
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowUpMini, { className: "text-ui-fg-subtle" }),
12893
- "Insert row above"
12894
- ]
12895
- }
12896
- ),
12897
- /* @__PURE__ */ jsxRuntime.jsxs(
12898
- ui.DropdownMenu.Item,
12899
- {
12900
- className: "gap-x-2",
12901
- onClick: () => insertRow(index, "below"),
12902
- children: [
12903
- /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowDownMini, { className: "text-ui-fg-subtle" }),
12904
- "Insert row below"
12905
- ]
12906
- }
12907
- ),
12908
- /* @__PURE__ */ jsxRuntime.jsx(ui.DropdownMenu.Separator, {}),
12909
- /* @__PURE__ */ jsxRuntime.jsxs(
12910
- ui.DropdownMenu.Item,
12911
- {
12912
- className: "gap-x-2",
12913
- onClick: () => deleteRow(index),
12914
- children: [
12915
- /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { className: "text-ui-fg-subtle" }),
12916
- "Delete row"
12917
- ]
12918
- }
12919
- )
12920
- ] })
12921
- ] })
12922
- ] })
12923
- },
12924
- field.id
12925
- );
12926
- })
12892
+ );
12893
+ });
12894
+ return /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxRuntime.jsxs(
12895
+ KeyboundForm,
12896
+ {
12897
+ className: "flex flex-1 flex-col overflow-hidden",
12898
+ onSubmit,
12899
+ children: [
12900
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-4", children: [
12901
+ /* @__PURE__ */ jsxRuntime.jsx(
12902
+ Form$2.Field,
12903
+ {
12904
+ control: form.control,
12905
+ name: "country_code",
12906
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12907
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Country" }),
12908
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(CountrySelect, { ...field }) }),
12909
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12910
+ ] })
12911
+ }
12912
+ ),
12913
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12914
+ /* @__PURE__ */ jsxRuntime.jsx(
12915
+ Form$2.Field,
12916
+ {
12917
+ control: form.control,
12918
+ name: "first_name",
12919
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12920
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "First name" }),
12921
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12922
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12923
+ ] })
12924
+ }
12925
+ ),
12926
+ /* @__PURE__ */ jsxRuntime.jsx(
12927
+ Form$2.Field,
12928
+ {
12929
+ control: form.control,
12930
+ name: "last_name",
12931
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12932
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Last name" }),
12933
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12934
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12935
+ ] })
12936
+ }
12937
+ )
12927
12938
  ] }),
12928
- hasUneditableRows && /* @__PURE__ */ jsxRuntime.jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
12929
- ] }),
12930
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
12931
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
12939
+ /* @__PURE__ */ jsxRuntime.jsx(
12940
+ Form$2.Field,
12941
+ {
12942
+ control: form.control,
12943
+ name: "company",
12944
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12945
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Company" }),
12946
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12947
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12948
+ ] })
12949
+ }
12950
+ ),
12951
+ /* @__PURE__ */ jsxRuntime.jsx(
12952
+ Form$2.Field,
12953
+ {
12954
+ control: form.control,
12955
+ name: "address_1",
12956
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12957
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Address" }),
12958
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12959
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12960
+ ] })
12961
+ }
12962
+ ),
12963
+ /* @__PURE__ */ jsxRuntime.jsx(
12964
+ Form$2.Field,
12965
+ {
12966
+ control: form.control,
12967
+ name: "address_2",
12968
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12969
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Apartment, suite, etc." }),
12970
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12971
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12972
+ ] })
12973
+ }
12974
+ ),
12975
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
12976
+ /* @__PURE__ */ jsxRuntime.jsx(
12977
+ Form$2.Field,
12978
+ {
12979
+ control: form.control,
12980
+ name: "postal_code",
12981
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12982
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "Postal code" }),
12983
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12984
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12985
+ ] })
12986
+ }
12987
+ ),
12988
+ /* @__PURE__ */ jsxRuntime.jsx(
12989
+ Form$2.Field,
12990
+ {
12991
+ control: form.control,
12992
+ name: "city",
12993
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
12994
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { children: "City" }),
12995
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
12996
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
12997
+ ] })
12998
+ }
12999
+ )
13000
+ ] }),
13001
+ /* @__PURE__ */ jsxRuntime.jsx(
13002
+ Form$2.Field,
13003
+ {
13004
+ control: form.control,
13005
+ name: "province",
13006
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
13007
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Province / State" }),
13008
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
13009
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
13010
+ ] })
13011
+ }
13012
+ ),
13013
+ /* @__PURE__ */ jsxRuntime.jsx(
13014
+ Form$2.Field,
13015
+ {
13016
+ control: form.control,
13017
+ name: "phone",
13018
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs(Form$2.Item, { children: [
13019
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Label, { optional: true, children: "Phone" }),
13020
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.Control, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Input, { ...field }) }),
13021
+ /* @__PURE__ */ jsxRuntime.jsx(Form$2.ErrorMessage, {})
13022
+ ] })
13023
+ }
13024
+ )
13025
+ ] }) }),
13026
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2", children: [
13027
+ /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
12932
13028
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
12933
13029
  ] }) })
12934
13030
  ]
12935
13031
  }
12936
13032
  ) });
12937
13033
  };
12938
- const GridInput = React.forwardRef(({ className, ...props }, ref) => {
12939
- return /* @__PURE__ */ jsxRuntime.jsx(
12940
- "input",
12941
- {
12942
- ref,
12943
- ...props,
12944
- autoComplete: "off",
12945
- className: ui.clx(
12946
- "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",
12947
- className
12948
- )
12949
- }
12950
- );
12951
- });
12952
- GridInput.displayName = "MetadataForm.GridInput";
12953
- const PlaceholderInner = () => {
12954
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
12955
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
12956
- /* @__PURE__ */ jsxRuntime.jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
12957
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" }),
12958
- /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-7 w-12 rounded-md" })
12959
- ] }) })
12960
- ] });
12961
- };
12962
- const EDITABLE_TYPES = ["string", "number", "boolean"];
12963
- function getDefaultValues(metadata) {
12964
- if (!metadata || !Object.keys(metadata).length) {
12965
- return [
12966
- {
12967
- key: "",
12968
- value: "",
12969
- disabled: false
12970
- }
12971
- ];
12972
- }
12973
- return Object.entries(metadata).map(([key, value]) => {
12974
- if (!EDITABLE_TYPES.includes(typeof value)) {
12975
- return {
12976
- key,
12977
- value,
12978
- disabled: true
12979
- };
12980
- }
12981
- let stringValue = value;
12982
- if (typeof value !== "string") {
12983
- stringValue = JSON.stringify(value);
12984
- }
12985
- return {
12986
- key,
12987
- value: stringValue,
12988
- original_key: key
12989
- };
12990
- });
12991
- }
12992
- function parseValues(values) {
12993
- const metadata = values.metadata;
12994
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
12995
- if (isEmpty) {
12996
- return null;
12997
- }
12998
- const update = {};
12999
- metadata.forEach((field) => {
13000
- let key = field.key;
13001
- let value = field.value;
13002
- const disabled = field.disabled;
13003
- if (!key || !value) {
13004
- return;
13005
- }
13006
- if (disabled) {
13007
- update[key] = value;
13008
- return;
13009
- }
13010
- key = key.trim();
13011
- value = value.trim();
13012
- if (value === "true") {
13013
- update[key] = true;
13014
- } else if (value === "false") {
13015
- update[key] = false;
13016
- } else {
13017
- const parsedNumber = parseFloat(value);
13018
- if (!isNaN(parsedNumber)) {
13019
- update[key] = parsedNumber;
13020
- } else {
13021
- update[key] = value;
13022
- }
13023
- }
13024
- });
13025
- return update;
13026
- }
13027
- function getHasUneditableRows(metadata) {
13028
- if (!metadata) {
13029
- return false;
13030
- }
13031
- return Object.values(metadata).some(
13032
- (value) => !EDITABLE_TYPES.includes(typeof value)
13033
- );
13034
- }
13034
+ const schema = addressSchema;
13035
13035
  const widgetModule = { widgets: [] };
13036
13036
  const routeModule = {
13037
13037
  routes: [
@@ -13065,12 +13065,8 @@ const routeModule = {
13065
13065
  path: "/draft-orders/:id/email"
13066
13066
  },
13067
13067
  {
13068
- Component: Items,
13069
- path: "/draft-orders/:id/items"
13070
- },
13071
- {
13072
- Component: Promotions,
13073
- path: "/draft-orders/:id/promotions"
13068
+ Component: Metadata,
13069
+ path: "/draft-orders/:id/metadata"
13074
13070
  },
13075
13071
  {
13076
13072
  Component: SalesChannel,
@@ -13081,16 +13077,20 @@ const routeModule = {
13081
13077
  path: "/draft-orders/:id/shipping"
13082
13078
  },
13083
13079
  {
13084
- Component: ShippingAddress,
13085
- path: "/draft-orders/:id/shipping-address"
13080
+ Component: Items,
13081
+ path: "/draft-orders/:id/items"
13082
+ },
13083
+ {
13084
+ Component: Promotions,
13085
+ path: "/draft-orders/:id/promotions"
13086
13086
  },
13087
13087
  {
13088
13088
  Component: TransferOwnership,
13089
13089
  path: "/draft-orders/:id/transfer-ownership"
13090
13090
  },
13091
13091
  {
13092
- Component: Metadata,
13093
- path: "/draft-orders/:id/metadata"
13092
+ Component: ShippingAddress,
13093
+ path: "/draft-orders/:id/shipping-address"
13094
13094
  }
13095
13095
  ]
13096
13096
  }