@medusajs/draft-order 2.10.2-preview-20250909081836 → 2.10.2-preview-20250909120201

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