@medusajs/draft-order 2.11.1-preview-20251022000338 → 2.11.1-preview-20251022032035

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.
@@ -4,7 +4,7 @@ import { Tooltip, DropdownMenu, clx, IconButton, useDataTable, DataTable as Data
4
4
  import { useQuery, useQueryClient, useMutation, keepPreviousData, useInfiniteQuery } from "@tanstack/react-query";
5
5
  import React, { useState, useCallback, useMemo, Fragment, createContext, forwardRef, useId, useContext, useTransition, useRef, useImperativeHandle, useDeferredValue, useEffect, Suspense } from "react";
6
6
  import { useSearchParams, Link, useNavigate, Outlet, useBlocker, useLocation, useParams } from "react-router-dom";
7
- import { EllipsisHorizontal, XMark, InformationCircleSolid, XMarkMini, TrianglesMini, CheckMini, EllipseMiniSolid, PlusMini, ExclamationCircleSolid, ArrowPath, FlyingBox, CurrencyDollar, Envelope, Channels, Trash, ArrowUpRightOnBox, TriangleDownMini, Check, SquareTwoStack, Photo, TriangleRightMini, Shopping, Buildings, TruckFast, Plus, ReceiptPercent, Minus, PencilSquare, EllipsisVertical, ArrowUpMini, ArrowDownMini } from "@medusajs/icons";
7
+ import { EllipsisHorizontal, XMark, InformationCircleSolid, XMarkMini, TrianglesMini, CheckMini, EllipseMiniSolid, PlusMini, ExclamationCircleSolid, ArrowPath, FlyingBox, CurrencyDollar, Envelope, Channels, Trash, ArrowUpRightOnBox, TriangleDownMini, Check, SquareTwoStack, Photo, TriangleRightMini, Shopping, Buildings, TruckFast, Plus, ReceiptPercent, EllipsisVertical, ArrowUpMini, ArrowDownMini, Minus, PencilSquare } from "@medusajs/icons";
8
8
  import Medusa from "@medusajs/js-sdk";
9
9
  import { format, formatDistance, sub, subDays, subMonths } from "date-fns";
10
10
  import { enUS } from "date-fns/locale";
@@ -9755,10 +9755,54 @@ const BillingAddressForm = ({ order }) => {
9755
9755
  ) });
9756
9756
  };
9757
9757
  const schema$5 = addressSchema;
9758
- const Email = () => {
9758
+ const InlineTip = forwardRef(
9759
+ ({ variant = "tip", label, className, children, ...props }, ref) => {
9760
+ const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
9761
+ return /* @__PURE__ */ jsxs(
9762
+ "div",
9763
+ {
9764
+ ref,
9765
+ className: clx(
9766
+ "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
9767
+ className
9768
+ ),
9769
+ ...props,
9770
+ children: [
9771
+ /* @__PURE__ */ jsx(
9772
+ "div",
9773
+ {
9774
+ role: "presentation",
9775
+ className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
9776
+ "bg-ui-tag-orange-icon": variant === "warning"
9777
+ })
9778
+ }
9779
+ ),
9780
+ /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
9781
+ /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
9782
+ labelValue,
9783
+ ":"
9784
+ ] }),
9785
+ " ",
9786
+ children
9787
+ ] })
9788
+ ]
9789
+ }
9790
+ );
9791
+ }
9792
+ );
9793
+ InlineTip.displayName = "InlineTip";
9794
+ const MetadataFieldSchema = objectType({
9795
+ key: stringType(),
9796
+ disabled: booleanType().optional(),
9797
+ value: anyType()
9798
+ });
9799
+ const MetadataSchema = objectType({
9800
+ metadata: arrayType(MetadataFieldSchema)
9801
+ });
9802
+ const Metadata = () => {
9759
9803
  const { id } = useParams();
9760
9804
  const { order, isPending, isError, error } = useOrder(id, {
9761
- fields: "+email"
9805
+ fields: "metadata"
9762
9806
  });
9763
9807
  if (isError) {
9764
9808
  throw error;
@@ -9766,26 +9810,33 @@ const Email = () => {
9766
9810
  const isReady = !isPending && !!order;
9767
9811
  return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
9768
9812
  /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
9769
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Email" }) }),
9770
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
9813
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
9814
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
9771
9815
  ] }),
9772
- isReady && /* @__PURE__ */ jsx(EmailForm, { order })
9816
+ !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
9773
9817
  ] });
9774
9818
  };
9775
- const EmailForm = ({ order }) => {
9819
+ const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
9820
+ const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
9821
+ const MetadataForm = ({ orderId, metadata }) => {
9822
+ const { handleSuccess } = useRouteModal();
9823
+ const hasUneditableRows = getHasUneditableRows(metadata);
9824
+ const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
9776
9825
  const form = useForm({
9777
9826
  defaultValues: {
9778
- email: order.email ?? ""
9827
+ metadata: getDefaultValues(metadata)
9779
9828
  },
9780
- resolver: zodResolver(schema$4)
9829
+ resolver: zodResolver(MetadataSchema)
9781
9830
  });
9782
- const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
9783
- const { handleSuccess } = useRouteModal();
9784
- const onSubmit = form.handleSubmit(async (data) => {
9831
+ const handleSubmit = form.handleSubmit(async (data) => {
9832
+ const parsedData = parseValues(data);
9785
9833
  await mutateAsync(
9786
- { email: data.email },
9834
+ {
9835
+ metadata: parsedData
9836
+ },
9787
9837
  {
9788
9838
  onSuccess: () => {
9839
+ toast.success("Metadata updated");
9789
9840
  handleSuccess();
9790
9841
  },
9791
9842
  onError: (error) => {
@@ -9794,46 +9845,277 @@ const EmailForm = ({ order }) => {
9794
9845
  }
9795
9846
  );
9796
9847
  });
9848
+ const { fields, insert, remove } = useFieldArray({
9849
+ control: form.control,
9850
+ name: "metadata"
9851
+ });
9852
+ function deleteRow(index) {
9853
+ remove(index);
9854
+ if (fields.length === 1) {
9855
+ insert(0, {
9856
+ key: "",
9857
+ value: "",
9858
+ disabled: false
9859
+ });
9860
+ }
9861
+ }
9862
+ function insertRow(index, position) {
9863
+ insert(index + (position === "above" ? 0 : 1), {
9864
+ key: "",
9865
+ value: "",
9866
+ disabled: false
9867
+ });
9868
+ }
9797
9869
  return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
9798
9870
  KeyboundForm,
9799
9871
  {
9872
+ onSubmit: handleSubmit,
9800
9873
  className: "flex flex-1 flex-col overflow-hidden",
9801
- onSubmit,
9802
9874
  children: [
9803
- /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(
9804
- Form$2.Field,
9805
- {
9806
- control: form.control,
9807
- name: "email",
9808
- render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
9809
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Email" }),
9810
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
9811
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
9812
- ] })
9813
- }
9814
- ) }),
9815
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
9816
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
9875
+ /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
9876
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
9877
+ /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
9878
+ /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
9879
+ /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
9880
+ ] }),
9881
+ fields.map((field, index) => {
9882
+ const isDisabled = field.disabled || false;
9883
+ let placeholder = "-";
9884
+ if (typeof field.value === "object") {
9885
+ placeholder = "{ ... }";
9886
+ }
9887
+ if (Array.isArray(field.value)) {
9888
+ placeholder = "[ ... ]";
9889
+ }
9890
+ return /* @__PURE__ */ jsx(
9891
+ ConditionalTooltip,
9892
+ {
9893
+ showTooltip: isDisabled,
9894
+ content: "This row is disabled because it contains non-primitive data.",
9895
+ children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
9896
+ /* @__PURE__ */ jsxs(
9897
+ "div",
9898
+ {
9899
+ className: clx("grid grid-cols-2 divide-x", {
9900
+ "overflow-hidden rounded-b-lg": index === fields.length - 1
9901
+ }),
9902
+ children: [
9903
+ /* @__PURE__ */ jsx(
9904
+ Form$2.Field,
9905
+ {
9906
+ control: form.control,
9907
+ name: `metadata.${index}.key`,
9908
+ render: ({ field: field2 }) => {
9909
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
9910
+ GridInput,
9911
+ {
9912
+ "aria-labelledby": METADATA_KEY_LABEL_ID,
9913
+ ...field2,
9914
+ disabled: isDisabled,
9915
+ placeholder: "Key"
9916
+ }
9917
+ ) }) });
9918
+ }
9919
+ }
9920
+ ),
9921
+ /* @__PURE__ */ jsx(
9922
+ Form$2.Field,
9923
+ {
9924
+ control: form.control,
9925
+ name: `metadata.${index}.value`,
9926
+ render: ({ field: { value, ...field2 } }) => {
9927
+ return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
9928
+ GridInput,
9929
+ {
9930
+ "aria-labelledby": METADATA_VALUE_LABEL_ID,
9931
+ ...field2,
9932
+ value: isDisabled ? placeholder : value,
9933
+ disabled: isDisabled,
9934
+ placeholder: "Value"
9935
+ }
9936
+ ) }) });
9937
+ }
9938
+ }
9939
+ )
9940
+ ]
9941
+ }
9942
+ ),
9943
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
9944
+ /* @__PURE__ */ jsx(
9945
+ DropdownMenu.Trigger,
9946
+ {
9947
+ className: clx(
9948
+ "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
9949
+ {
9950
+ hidden: isDisabled
9951
+ }
9952
+ ),
9953
+ disabled: isDisabled,
9954
+ asChild: true,
9955
+ children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
9956
+ }
9957
+ ),
9958
+ /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
9959
+ /* @__PURE__ */ jsxs(
9960
+ DropdownMenu.Item,
9961
+ {
9962
+ className: "gap-x-2",
9963
+ onClick: () => insertRow(index, "above"),
9964
+ children: [
9965
+ /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
9966
+ "Insert row above"
9967
+ ]
9968
+ }
9969
+ ),
9970
+ /* @__PURE__ */ jsxs(
9971
+ DropdownMenu.Item,
9972
+ {
9973
+ className: "gap-x-2",
9974
+ onClick: () => insertRow(index, "below"),
9975
+ children: [
9976
+ /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
9977
+ "Insert row below"
9978
+ ]
9979
+ }
9980
+ ),
9981
+ /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
9982
+ /* @__PURE__ */ jsxs(
9983
+ DropdownMenu.Item,
9984
+ {
9985
+ className: "gap-x-2",
9986
+ onClick: () => deleteRow(index),
9987
+ children: [
9988
+ /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
9989
+ "Delete row"
9990
+ ]
9991
+ }
9992
+ )
9993
+ ] })
9994
+ ] })
9995
+ ] })
9996
+ },
9997
+ field.id
9998
+ );
9999
+ })
10000
+ ] }),
10001
+ hasUneditableRows && /* @__PURE__ */ jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
10002
+ ] }),
10003
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10004
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
9817
10005
  /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
9818
10006
  ] }) })
9819
10007
  ]
9820
10008
  }
9821
10009
  ) });
9822
10010
  };
9823
- const schema$4 = objectType({
9824
- email: stringType().email()
9825
- });
9826
- const NumberInput = forwardRef(
9827
- ({
9828
- value,
9829
- onChange,
9830
- size = "base",
9831
- min = 0,
9832
- max = 100,
9833
- step = 1,
9834
- className,
9835
- disabled,
9836
- ...props
10011
+ const GridInput = forwardRef(({ className, ...props }, ref) => {
10012
+ return /* @__PURE__ */ jsx(
10013
+ "input",
10014
+ {
10015
+ ref,
10016
+ ...props,
10017
+ autoComplete: "off",
10018
+ className: clx(
10019
+ "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",
10020
+ className
10021
+ )
10022
+ }
10023
+ );
10024
+ });
10025
+ GridInput.displayName = "MetadataForm.GridInput";
10026
+ const PlaceholderInner = () => {
10027
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
10028
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
10029
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10030
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
10031
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
10032
+ ] }) })
10033
+ ] });
10034
+ };
10035
+ const EDITABLE_TYPES = ["string", "number", "boolean"];
10036
+ function getDefaultValues(metadata) {
10037
+ if (!metadata || !Object.keys(metadata).length) {
10038
+ return [
10039
+ {
10040
+ key: "",
10041
+ value: "",
10042
+ disabled: false
10043
+ }
10044
+ ];
10045
+ }
10046
+ return Object.entries(metadata).map(([key, value]) => {
10047
+ if (!EDITABLE_TYPES.includes(typeof value)) {
10048
+ return {
10049
+ key,
10050
+ value,
10051
+ disabled: true
10052
+ };
10053
+ }
10054
+ let stringValue = value;
10055
+ if (typeof value !== "string") {
10056
+ stringValue = JSON.stringify(value);
10057
+ }
10058
+ return {
10059
+ key,
10060
+ value: stringValue,
10061
+ original_key: key
10062
+ };
10063
+ });
10064
+ }
10065
+ function parseValues(values) {
10066
+ const metadata = values.metadata;
10067
+ const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
10068
+ if (isEmpty) {
10069
+ return null;
10070
+ }
10071
+ const update = {};
10072
+ metadata.forEach((field) => {
10073
+ let key = field.key;
10074
+ let value = field.value;
10075
+ const disabled = field.disabled;
10076
+ if (!key || !value) {
10077
+ return;
10078
+ }
10079
+ if (disabled) {
10080
+ update[key] = value;
10081
+ return;
10082
+ }
10083
+ key = key.trim();
10084
+ value = value.trim();
10085
+ if (value === "true") {
10086
+ update[key] = true;
10087
+ } else if (value === "false") {
10088
+ update[key] = false;
10089
+ } else {
10090
+ const parsedNumber = parseFloat(value);
10091
+ if (!isNaN(parsedNumber)) {
10092
+ update[key] = parsedNumber;
10093
+ } else {
10094
+ update[key] = value;
10095
+ }
10096
+ }
10097
+ });
10098
+ return update;
10099
+ }
10100
+ function getHasUneditableRows(metadata) {
10101
+ if (!metadata) {
10102
+ return false;
10103
+ }
10104
+ return Object.values(metadata).some(
10105
+ (value) => !EDITABLE_TYPES.includes(typeof value)
10106
+ );
10107
+ }
10108
+ const NumberInput = forwardRef(
10109
+ ({
10110
+ value,
10111
+ onChange,
10112
+ size = "base",
10113
+ min = 0,
10114
+ max = 100,
10115
+ step = 1,
10116
+ className,
10117
+ disabled,
10118
+ ...props
9837
10119
  }, ref) => {
9838
10120
  const handleChange = (event) => {
9839
10121
  const newValue = event.target.value === "" ? min : Number(event.target.value);
@@ -10670,483 +10952,133 @@ const useColumns = () => {
10670
10952
  header: "Created",
10671
10953
  cell: ({ getValue }) => {
10672
10954
  return /* @__PURE__ */ jsx(
10673
- Tooltip,
10674
- {
10675
- content: getFullDate({ date: getValue(), includeTime: true }),
10676
- children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
10677
- }
10678
- );
10679
- },
10680
- enableSorting: true,
10681
- sortAscLabel: "Oldest first",
10682
- sortDescLabel: "Newest first"
10683
- })
10684
- ];
10685
- }, []);
10686
- };
10687
- const CustomItemForm = ({ orderId, currencyCode }) => {
10688
- const { setIsOpen } = useStackedModal();
10689
- const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
10690
- const form = useForm({
10691
- defaultValues: {
10692
- title: "",
10693
- quantity: 1,
10694
- unit_price: ""
10695
- },
10696
- resolver: zodResolver(customItemSchema)
10697
- });
10698
- const onSubmit = form.handleSubmit(async (data) => {
10699
- await addItems(
10700
- {
10701
- items: [
10702
- {
10703
- title: data.title,
10704
- quantity: data.quantity,
10705
- unit_price: convertNumber(data.unit_price)
10706
- }
10707
- ]
10708
- },
10709
- {
10710
- onSuccess: () => {
10711
- setIsOpen(STACKED_MODAL_ID, false);
10712
- },
10713
- onError: (e) => {
10714
- toast.error(e.message);
10715
- }
10716
- }
10717
- );
10718
- });
10719
- return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxs(StackedFocusModal.Content, { children: [
10720
- /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
10721
- /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-2 py-16", children: [
10722
- /* @__PURE__ */ jsxs("div", { children: [
10723
- /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Add custom item" }) }),
10724
- /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(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." }) })
10725
- ] }),
10726
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10727
- /* @__PURE__ */ jsx(
10728
- Form$2.Field,
10729
- {
10730
- control: form.control,
10731
- name: "title",
10732
- render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10733
- /* @__PURE__ */ jsxs("div", { children: [
10734
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Title" }),
10735
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the title of the item" })
10736
- ] }),
10737
- /* @__PURE__ */ jsxs("div", { children: [
10738
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
10739
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10740
- ] })
10741
- ] }) })
10742
- }
10743
- ),
10744
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10745
- /* @__PURE__ */ jsx(
10746
- Form$2.Field,
10747
- {
10748
- control: form.control,
10749
- name: "unit_price",
10750
- render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10751
- /* @__PURE__ */ jsxs("div", { children: [
10752
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Unit price" }),
10753
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
10754
- ] }),
10755
- /* @__PURE__ */ jsxs("div", { children: [
10756
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10757
- CurrencyInput,
10758
- {
10759
- symbol: getNativeSymbol(currencyCode),
10760
- code: currencyCode,
10761
- onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
10762
- ...field
10763
- }
10764
- ) }),
10765
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10766
- ] })
10767
- ] }) })
10768
- }
10769
- ),
10770
- /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
10771
- /* @__PURE__ */ jsx(
10772
- Form$2.Field,
10773
- {
10774
- control: form.control,
10775
- name: "quantity",
10776
- render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
10777
- /* @__PURE__ */ jsxs("div", { children: [
10778
- /* @__PURE__ */ jsx(Form$2.Label, { children: "Quantity" }),
10779
- /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
10780
- ] }),
10781
- /* @__PURE__ */ jsxs("div", { className: "w-full flex-1", children: [
10782
- /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(NumberInput, { ...field, className: "w-full" }) }) }),
10783
- /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
10784
- ] })
10785
- ] }) })
10786
- }
10787
- )
10788
- ] }) }) }),
10789
- /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
10790
- /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
10791
- /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
10792
- ] }) })
10793
- ] }) }) });
10794
- };
10795
- const customItemSchema = objectType({
10796
- title: stringType().min(1),
10797
- quantity: numberType(),
10798
- unit_price: unionType([numberType(), stringType()])
10799
- });
10800
- const InlineTip = forwardRef(
10801
- ({ variant = "tip", label, className, children, ...props }, ref) => {
10802
- const labelValue = label || (variant === "warning" ? "Warning" : "Tip");
10803
- return /* @__PURE__ */ jsxs(
10804
- "div",
10805
- {
10806
- ref,
10807
- className: clx(
10808
- "bg-ui-bg-component txt-small text-ui-fg-subtle grid grid-cols-[4px_1fr] items-start gap-3 rounded-lg border p-3",
10809
- className
10810
- ),
10811
- ...props,
10812
- children: [
10813
- /* @__PURE__ */ jsx(
10814
- "div",
10815
- {
10816
- role: "presentation",
10817
- className: clx("w-4px bg-ui-tag-neutral-icon h-full rounded-full", {
10818
- "bg-ui-tag-orange-icon": variant === "warning"
10819
- })
10820
- }
10821
- ),
10822
- /* @__PURE__ */ jsxs("div", { className: "text-pretty", children: [
10823
- /* @__PURE__ */ jsxs("strong", { className: "txt-small-plus text-ui-fg-base", children: [
10824
- labelValue,
10825
- ":"
10826
- ] }),
10827
- " ",
10828
- children
10829
- ] })
10830
- ]
10831
- }
10832
- );
10833
- }
10834
- );
10835
- InlineTip.displayName = "InlineTip";
10836
- const MetadataFieldSchema = objectType({
10837
- key: stringType(),
10838
- disabled: booleanType().optional(),
10839
- value: anyType()
10840
- });
10841
- const MetadataSchema = objectType({
10842
- metadata: arrayType(MetadataFieldSchema)
10843
- });
10844
- const Metadata = () => {
10845
- const { id } = useParams();
10846
- const { order, isPending, isError, error } = useOrder(id, {
10847
- fields: "metadata"
10848
- });
10849
- if (isError) {
10850
- throw error;
10851
- }
10852
- const isReady = !isPending && !!order;
10853
- return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
10854
- /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
10855
- /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Metadata" }) }),
10856
- /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Add metadata to the draft order." }) })
10857
- ] }),
10858
- !isReady ? /* @__PURE__ */ jsx(PlaceholderInner, {}) : /* @__PURE__ */ jsx(MetadataForm, { orderId: id, metadata: order == null ? void 0 : order.metadata })
10859
- ] });
10860
- };
10861
- const METADATA_KEY_LABEL_ID = "metadata-form-key-label";
10862
- const METADATA_VALUE_LABEL_ID = "metadata-form-value-label";
10863
- const MetadataForm = ({ orderId, metadata }) => {
10864
- const { handleSuccess } = useRouteModal();
10865
- const hasUneditableRows = getHasUneditableRows(metadata);
10866
- const { mutateAsync, isPending } = useUpdateDraftOrder(orderId);
10867
- const form = useForm({
10868
- defaultValues: {
10869
- metadata: getDefaultValues(metadata)
10870
- },
10871
- resolver: zodResolver(MetadataSchema)
10872
- });
10873
- const handleSubmit = form.handleSubmit(async (data) => {
10874
- const parsedData = parseValues(data);
10875
- await mutateAsync(
10876
- {
10877
- metadata: parsedData
10878
- },
10879
- {
10880
- onSuccess: () => {
10881
- toast.success("Metadata updated");
10882
- handleSuccess();
10883
- },
10884
- onError: (error) => {
10885
- toast.error(error.message);
10886
- }
10887
- }
10888
- );
10889
- });
10890
- const { fields, insert, remove } = useFieldArray({
10891
- control: form.control,
10892
- name: "metadata"
10893
- });
10894
- function deleteRow(index) {
10895
- remove(index);
10896
- if (fields.length === 1) {
10897
- insert(0, {
10898
- key: "",
10899
- value: "",
10900
- disabled: false
10901
- });
10902
- }
10903
- }
10904
- function insertRow(index, position) {
10905
- insert(index + (position === "above" ? 0 : 1), {
10906
- key: "",
10907
- value: "",
10908
- disabled: false
10909
- });
10910
- }
10911
- return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
10912
- KeyboundForm,
10913
- {
10914
- onSubmit: handleSubmit,
10915
- className: "flex flex-1 flex-col overflow-hidden",
10916
- children: [
10917
- /* @__PURE__ */ jsxs(RouteDrawer.Body, { className: "flex flex-1 flex-col gap-y-8 overflow-y-auto", children: [
10918
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-base shadow-elevation-card-rest grid grid-cols-1 divide-y rounded-lg", children: [
10919
- /* @__PURE__ */ jsxs("div", { className: "bg-ui-bg-subtle grid grid-cols-2 divide-x rounded-t-lg", children: [
10920
- /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_KEY_LABEL_ID, children: "Key" }) }),
10921
- /* @__PURE__ */ jsx("div", { className: "txt-compact-small-plus text-ui-fg-subtle px-2 py-1.5", children: /* @__PURE__ */ jsx("label", { id: METADATA_VALUE_LABEL_ID, children: "Value" }) })
10922
- ] }),
10923
- fields.map((field, index) => {
10924
- const isDisabled = field.disabled || false;
10925
- let placeholder = "-";
10926
- if (typeof field.value === "object") {
10927
- placeholder = "{ ... }";
10928
- }
10929
- if (Array.isArray(field.value)) {
10930
- placeholder = "[ ... ]";
10931
- }
10932
- return /* @__PURE__ */ jsx(
10933
- ConditionalTooltip,
10934
- {
10935
- showTooltip: isDisabled,
10936
- content: "This row is disabled because it contains non-primitive data.",
10937
- children: /* @__PURE__ */ jsxs("div", { className: "group/table relative", children: [
10938
- /* @__PURE__ */ jsxs(
10939
- "div",
10940
- {
10941
- className: clx("grid grid-cols-2 divide-x", {
10942
- "overflow-hidden rounded-b-lg": index === fields.length - 1
10943
- }),
10944
- children: [
10945
- /* @__PURE__ */ jsx(
10946
- Form$2.Field,
10947
- {
10948
- control: form.control,
10949
- name: `metadata.${index}.key`,
10950
- render: ({ field: field2 }) => {
10951
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10952
- GridInput,
10953
- {
10954
- "aria-labelledby": METADATA_KEY_LABEL_ID,
10955
- ...field2,
10956
- disabled: isDisabled,
10957
- placeholder: "Key"
10958
- }
10959
- ) }) });
10960
- }
10961
- }
10962
- ),
10963
- /* @__PURE__ */ jsx(
10964
- Form$2.Field,
10965
- {
10966
- control: form.control,
10967
- name: `metadata.${index}.value`,
10968
- render: ({ field: { value, ...field2 } }) => {
10969
- return /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
10970
- GridInput,
10971
- {
10972
- "aria-labelledby": METADATA_VALUE_LABEL_ID,
10973
- ...field2,
10974
- value: isDisabled ? placeholder : value,
10975
- disabled: isDisabled,
10976
- placeholder: "Value"
10977
- }
10978
- ) }) });
10979
- }
10980
- }
10981
- )
10982
- ]
10983
- }
10984
- ),
10985
- /* @__PURE__ */ jsxs(DropdownMenu, { children: [
10986
- /* @__PURE__ */ jsx(
10987
- DropdownMenu.Trigger,
10988
- {
10989
- className: clx(
10990
- "invisible absolute inset-y-0 -right-2.5 my-auto group-hover/table:visible data-[state='open']:visible",
10991
- {
10992
- hidden: isDisabled
10993
- }
10994
- ),
10995
- disabled: isDisabled,
10996
- asChild: true,
10997
- children: /* @__PURE__ */ jsx(IconButton, { size: "2xsmall", children: /* @__PURE__ */ jsx(EllipsisVertical, {}) })
10998
- }
10999
- ),
11000
- /* @__PURE__ */ jsxs(DropdownMenu.Content, { children: [
11001
- /* @__PURE__ */ jsxs(
11002
- DropdownMenu.Item,
11003
- {
11004
- className: "gap-x-2",
11005
- onClick: () => insertRow(index, "above"),
11006
- children: [
11007
- /* @__PURE__ */ jsx(ArrowUpMini, { className: "text-ui-fg-subtle" }),
11008
- "Insert row above"
11009
- ]
11010
- }
11011
- ),
11012
- /* @__PURE__ */ jsxs(
11013
- DropdownMenu.Item,
11014
- {
11015
- className: "gap-x-2",
11016
- onClick: () => insertRow(index, "below"),
11017
- children: [
11018
- /* @__PURE__ */ jsx(ArrowDownMini, { className: "text-ui-fg-subtle" }),
11019
- "Insert row below"
11020
- ]
11021
- }
11022
- ),
11023
- /* @__PURE__ */ jsx(DropdownMenu.Separator, {}),
11024
- /* @__PURE__ */ jsxs(
11025
- DropdownMenu.Item,
11026
- {
11027
- className: "gap-x-2",
11028
- onClick: () => deleteRow(index),
11029
- children: [
11030
- /* @__PURE__ */ jsx(Trash, { className: "text-ui-fg-subtle" }),
11031
- "Delete row"
11032
- ]
11033
- }
11034
- )
11035
- ] })
11036
- ] })
11037
- ] })
11038
- },
11039
- field.id
11040
- );
11041
- })
11042
- ] }),
11043
- hasUneditableRows && /* @__PURE__ */ jsx(InlineTip, { variant: "warning", label: "Some rows are disabled", children: "This object contains non-primitive metadata, such as arrays or objects, that can't be edited here. To edit the disabled rows, use the API directly." })
11044
- ] }),
11045
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11046
- /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11047
- /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
11048
- ] }) })
11049
- ]
11050
- }
11051
- ) });
11052
- };
11053
- const GridInput = forwardRef(({ className, ...props }, ref) => {
11054
- return /* @__PURE__ */ jsx(
11055
- "input",
11056
- {
11057
- ref,
11058
- ...props,
11059
- autoComplete: "off",
11060
- className: clx(
11061
- "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",
11062
- className
11063
- )
11064
- }
11065
- );
11066
- });
11067
- GridInput.displayName = "MetadataForm.GridInput";
11068
- const PlaceholderInner = () => {
11069
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
11070
- /* @__PURE__ */ jsx(RouteDrawer.Body, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-[148ox] w-full rounded-lg" }) }),
11071
- /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11072
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" }),
11073
- /* @__PURE__ */ jsx(Skeleton, { className: "h-7 w-12 rounded-md" })
11074
- ] }) })
11075
- ] });
11076
- };
11077
- const EDITABLE_TYPES = ["string", "number", "boolean"];
11078
- function getDefaultValues(metadata) {
11079
- if (!metadata || !Object.keys(metadata).length) {
11080
- return [
11081
- {
11082
- key: "",
11083
- value: "",
11084
- disabled: false
11085
- }
11086
- ];
11087
- }
11088
- return Object.entries(metadata).map(([key, value]) => {
11089
- if (!EDITABLE_TYPES.includes(typeof value)) {
11090
- return {
11091
- key,
11092
- value,
11093
- disabled: true
11094
- };
11095
- }
11096
- let stringValue = value;
11097
- if (typeof value !== "string") {
11098
- stringValue = JSON.stringify(value);
11099
- }
11100
- return {
11101
- key,
11102
- value: stringValue,
11103
- original_key: key
11104
- };
10955
+ Tooltip,
10956
+ {
10957
+ content: getFullDate({ date: getValue(), includeTime: true }),
10958
+ children: /* @__PURE__ */ jsx("span", { children: getFullDate({ date: getValue() }) })
10959
+ }
10960
+ );
10961
+ },
10962
+ enableSorting: true,
10963
+ sortAscLabel: "Oldest first",
10964
+ sortDescLabel: "Newest first"
10965
+ })
10966
+ ];
10967
+ }, []);
10968
+ };
10969
+ const CustomItemForm = ({ orderId, currencyCode }) => {
10970
+ const { setIsOpen } = useStackedModal();
10971
+ const { mutateAsync: addItems } = useDraftOrderAddItems(orderId);
10972
+ const form = useForm({
10973
+ defaultValues: {
10974
+ title: "",
10975
+ quantity: 1,
10976
+ unit_price: ""
10977
+ },
10978
+ resolver: zodResolver(customItemSchema)
11105
10979
  });
11106
- }
11107
- function parseValues(values) {
11108
- const metadata = values.metadata;
11109
- const isEmpty = !metadata.length || metadata.length === 1 && !metadata[0].key && !metadata[0].value;
11110
- if (isEmpty) {
11111
- return null;
11112
- }
11113
- const update = {};
11114
- metadata.forEach((field) => {
11115
- let key = field.key;
11116
- let value = field.value;
11117
- const disabled = field.disabled;
11118
- if (!key || !value) {
11119
- return;
11120
- }
11121
- if (disabled) {
11122
- update[key] = value;
11123
- return;
11124
- }
11125
- key = key.trim();
11126
- value = value.trim();
11127
- if (value === "true") {
11128
- update[key] = true;
11129
- } else if (value === "false") {
11130
- update[key] = false;
11131
- } else {
11132
- const parsedNumber = parseFloat(value);
11133
- if (!isNaN(parsedNumber)) {
11134
- update[key] = parsedNumber;
11135
- } else {
11136
- update[key] = value;
10980
+ const onSubmit = form.handleSubmit(async (data) => {
10981
+ await addItems(
10982
+ {
10983
+ items: [
10984
+ {
10985
+ title: data.title,
10986
+ quantity: data.quantity,
10987
+ unit_price: convertNumber(data.unit_price)
10988
+ }
10989
+ ]
10990
+ },
10991
+ {
10992
+ onSuccess: () => {
10993
+ setIsOpen(STACKED_MODAL_ID, false);
10994
+ },
10995
+ onError: (e) => {
10996
+ toast.error(e.message);
10997
+ }
11137
10998
  }
11138
- }
10999
+ );
11139
11000
  });
11140
- return update;
11141
- }
11142
- function getHasUneditableRows(metadata) {
11143
- if (!metadata) {
11144
- return false;
11145
- }
11146
- return Object.values(metadata).some(
11147
- (value) => !EDITABLE_TYPES.includes(typeof value)
11148
- );
11149
- }
11001
+ return /* @__PURE__ */ jsx(Form$2, { ...form, children: /* @__PURE__ */ jsx(KeyboundForm, { onSubmit, children: /* @__PURE__ */ jsxs(StackedFocusModal.Content, { children: [
11002
+ /* @__PURE__ */ jsx(StackedFocusModal.Header, {}),
11003
+ /* @__PURE__ */ jsx(StackedFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-2 py-16", children: [
11004
+ /* @__PURE__ */ jsxs("div", { children: [
11005
+ /* @__PURE__ */ jsx(StackedFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Add custom item" }) }),
11006
+ /* @__PURE__ */ jsx(StackedFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx(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." }) })
11007
+ ] }),
11008
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11009
+ /* @__PURE__ */ jsx(
11010
+ Form$2.Field,
11011
+ {
11012
+ control: form.control,
11013
+ name: "title",
11014
+ render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11015
+ /* @__PURE__ */ jsxs("div", { children: [
11016
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Title" }),
11017
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the title of the item" })
11018
+ ] }),
11019
+ /* @__PURE__ */ jsxs("div", { children: [
11020
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
11021
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11022
+ ] })
11023
+ ] }) })
11024
+ }
11025
+ ),
11026
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11027
+ /* @__PURE__ */ jsx(
11028
+ Form$2.Field,
11029
+ {
11030
+ control: form.control,
11031
+ name: "unit_price",
11032
+ render: ({ field: { onChange, ...field } }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11033
+ /* @__PURE__ */ jsxs("div", { children: [
11034
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Unit price" }),
11035
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the unit price of the item" })
11036
+ ] }),
11037
+ /* @__PURE__ */ jsxs("div", { children: [
11038
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(
11039
+ CurrencyInput,
11040
+ {
11041
+ symbol: getNativeSymbol(currencyCode),
11042
+ code: currencyCode,
11043
+ onValueChange: (_value, _name, values) => onChange(values == null ? void 0 : values.value),
11044
+ ...field
11045
+ }
11046
+ ) }),
11047
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11048
+ ] })
11049
+ ] }) })
11050
+ }
11051
+ ),
11052
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
11053
+ /* @__PURE__ */ jsx(
11054
+ Form$2.Field,
11055
+ {
11056
+ control: form.control,
11057
+ name: "quantity",
11058
+ render: ({ field }) => /* @__PURE__ */ jsx(Form$2.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
11059
+ /* @__PURE__ */ jsxs("div", { children: [
11060
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Quantity" }),
11061
+ /* @__PURE__ */ jsx(Form$2.Hint, { children: "Enter the quantity of the item" })
11062
+ ] }),
11063
+ /* @__PURE__ */ jsxs("div", { className: "w-full flex-1", children: [
11064
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx("div", { className: "w-full flex-1", children: /* @__PURE__ */ jsx(NumberInput, { ...field, className: "w-full" }) }) }),
11065
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
11066
+ ] })
11067
+ ] }) })
11068
+ }
11069
+ )
11070
+ ] }) }) }),
11071
+ /* @__PURE__ */ jsx(StackedFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-x-2", children: [
11072
+ /* @__PURE__ */ jsx(StackedFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", type: "button", children: "Cancel" }) }),
11073
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "button", onClick: onSubmit, children: "Add item" })
11074
+ ] }) })
11075
+ ] }) }) });
11076
+ };
11077
+ const customItemSchema = objectType({
11078
+ title: stringType().min(1),
11079
+ quantity: numberType(),
11080
+ unit_price: unionType([numberType(), stringType()])
11081
+ });
11150
11082
  const PROMOTION_QUERY_KEY = "promotions";
11151
11083
  const promotionsQueryKeys = {
11152
11084
  list: (query2) => [
@@ -11452,7 +11384,7 @@ const SalesChannelForm = ({ order }) => {
11452
11384
  defaultValues: {
11453
11385
  sales_channel_id: order.sales_channel_id || ""
11454
11386
  },
11455
- resolver: zodResolver(schema$3)
11387
+ resolver: zodResolver(schema$4)
11456
11388
  });
11457
11389
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
11458
11390
  const { handleSuccess } = useRouteModal();
@@ -11527,7 +11459,7 @@ const SalesChannelField = ({ control, order }) => {
11527
11459
  }
11528
11460
  );
11529
11461
  };
11530
- const schema$3 = objectType({
11462
+ const schema$4 = objectType({
11531
11463
  sales_channel_id: stringType().min(1)
11532
11464
  });
11533
11465
  const STACKED_FOCUS_MODAL_ID = "shipping-form";
@@ -12369,7 +12301,7 @@ const ShippingAddressForm = ({ order }) => {
12369
12301
  postal_code: ((_i = order.shipping_address) == null ? void 0 : _i.postal_code) ?? "",
12370
12302
  phone: ((_j = order.shipping_address) == null ? void 0 : _j.phone) ?? ""
12371
12303
  },
12372
- resolver: zodResolver(schema$2)
12304
+ resolver: zodResolver(schema$3)
12373
12305
  });
12374
12306
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12375
12307
  const { handleSuccess } = useRouteModal();
@@ -12539,7 +12471,7 @@ const ShippingAddressForm = ({ order }) => {
12539
12471
  }
12540
12472
  ) });
12541
12473
  };
12542
- const schema$2 = addressSchema;
12474
+ const schema$3 = addressSchema;
12543
12475
  const TransferOwnership = () => {
12544
12476
  const { id } = useParams();
12545
12477
  const { draft_order, isPending, isError, error } = useDraftOrder(id, {
@@ -12563,7 +12495,7 @@ const TransferOwnershipForm = ({ order }) => {
12563
12495
  defaultValues: {
12564
12496
  customer_id: order.customer_id || ""
12565
12497
  },
12566
- resolver: zodResolver(schema$1)
12498
+ resolver: zodResolver(schema$2)
12567
12499
  });
12568
12500
  const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12569
12501
  const { handleSuccess } = useRouteModal();
@@ -13013,7 +12945,7 @@ const Illustration = () => {
13013
12945
  }
13014
12946
  );
13015
12947
  };
13016
- const schema$1 = objectType({
12948
+ const schema$2 = objectType({
13017
12949
  customer_id: stringType().min(1)
13018
12950
  });
13019
12951
  const CustomItems = () => {
@@ -13024,7 +12956,7 @@ const CustomItems = () => {
13024
12956
  };
13025
12957
  const CustomItemsForm = () => {
13026
12958
  const form = useForm({
13027
- resolver: zodResolver(schema)
12959
+ resolver: zodResolver(schema$1)
13028
12960
  });
13029
12961
  return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(KeyboundForm, { className: "flex flex-1 flex-col", children: [
13030
12962
  /* @__PURE__ */ jsx(RouteDrawer.Body, {}),
@@ -13034,6 +12966,74 @@ const CustomItemsForm = () => {
13034
12966
  ] }) })
13035
12967
  ] }) });
13036
12968
  };
12969
+ const schema$1 = objectType({
12970
+ email: stringType().email()
12971
+ });
12972
+ const Email = () => {
12973
+ const { id } = useParams();
12974
+ const { order, isPending, isError, error } = useOrder(id, {
12975
+ fields: "+email"
12976
+ });
12977
+ if (isError) {
12978
+ throw error;
12979
+ }
12980
+ const isReady = !isPending && !!order;
12981
+ return /* @__PURE__ */ jsxs(RouteDrawer, { children: [
12982
+ /* @__PURE__ */ jsxs(RouteDrawer.Header, { children: [
12983
+ /* @__PURE__ */ jsx(RouteDrawer.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Edit Email" }) }),
12984
+ /* @__PURE__ */ jsx(RouteDrawer.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit the email for the draft order" }) })
12985
+ ] }),
12986
+ isReady && /* @__PURE__ */ jsx(EmailForm, { order })
12987
+ ] });
12988
+ };
12989
+ const EmailForm = ({ order }) => {
12990
+ const form = useForm({
12991
+ defaultValues: {
12992
+ email: order.email ?? ""
12993
+ },
12994
+ resolver: zodResolver(schema)
12995
+ });
12996
+ const { mutateAsync, isPending } = useUpdateDraftOrder(order.id);
12997
+ const { handleSuccess } = useRouteModal();
12998
+ const onSubmit = form.handleSubmit(async (data) => {
12999
+ await mutateAsync(
13000
+ { email: data.email },
13001
+ {
13002
+ onSuccess: () => {
13003
+ handleSuccess();
13004
+ },
13005
+ onError: (error) => {
13006
+ toast.error(error.message);
13007
+ }
13008
+ }
13009
+ );
13010
+ });
13011
+ return /* @__PURE__ */ jsx(RouteDrawer.Form, { form, children: /* @__PURE__ */ jsxs(
13012
+ KeyboundForm,
13013
+ {
13014
+ className: "flex flex-1 flex-col overflow-hidden",
13015
+ onSubmit,
13016
+ children: [
13017
+ /* @__PURE__ */ jsx(RouteDrawer.Body, { className: "flex flex-col gap-y-6 overflow-y-auto", children: /* @__PURE__ */ jsx(
13018
+ Form$2.Field,
13019
+ {
13020
+ control: form.control,
13021
+ name: "email",
13022
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form$2.Item, { children: [
13023
+ /* @__PURE__ */ jsx(Form$2.Label, { children: "Email" }),
13024
+ /* @__PURE__ */ jsx(Form$2.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
13025
+ /* @__PURE__ */ jsx(Form$2.ErrorMessage, {})
13026
+ ] })
13027
+ }
13028
+ ) }),
13029
+ /* @__PURE__ */ jsx(RouteDrawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
13030
+ /* @__PURE__ */ jsx(RouteDrawer.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", children: "Cancel" }) }),
13031
+ /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", isLoading: isPending, children: "Save" })
13032
+ ] }) })
13033
+ ]
13034
+ }
13035
+ ) });
13036
+ };
13037
13037
  const schema = objectType({
13038
13038
  email: stringType().email()
13039
13039
  });
@@ -13062,17 +13062,13 @@ const routeModule = {
13062
13062
  path: "/draft-orders/:id/billing-address"
13063
13063
  },
13064
13064
  {
13065
- Component: Email,
13066
- path: "/draft-orders/:id/email"
13065
+ Component: Metadata,
13066
+ path: "/draft-orders/:id/metadata"
13067
13067
  },
13068
13068
  {
13069
13069
  Component: Items,
13070
13070
  path: "/draft-orders/:id/items"
13071
13071
  },
13072
- {
13073
- Component: Metadata,
13074
- path: "/draft-orders/:id/metadata"
13075
- },
13076
13072
  {
13077
13073
  Component: Promotions,
13078
13074
  path: "/draft-orders/:id/promotions"
@@ -13096,6 +13092,10 @@ const routeModule = {
13096
13092
  {
13097
13093
  Component: CustomItems,
13098
13094
  path: "/draft-orders/:id/custom-items"
13095
+ },
13096
+ {
13097
+ Component: Email,
13098
+ path: "/draft-orders/:id/email"
13099
13099
  }
13100
13100
  ]
13101
13101
  }