@medusajs/draft-order 0.0.1

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.
Files changed (82) hide show
  1. package/.medusa/server/src/admin/components/common/action-menu.js +77 -0
  2. package/.medusa/server/src/admin/components/common/conditional-tooltip.js +15 -0
  3. package/.medusa/server/src/admin/components/common/data-table.js +249 -0
  4. package/.medusa/server/src/admin/components/common/form.js +151 -0
  5. package/.medusa/server/src/admin/components/common/inline-tip.js +42 -0
  6. package/.medusa/server/src/admin/components/common/keybound-form.js +32 -0
  7. package/.medusa/server/src/admin/components/common/page-skeleton.js +51 -0
  8. package/.medusa/server/src/admin/components/common/thumbnail.js +15 -0
  9. package/.medusa/server/src/admin/components/draft-orders/activity-section.js +205 -0
  10. package/.medusa/server/src/admin/components/draft-orders/customer-section.js +165 -0
  11. package/.medusa/server/src/admin/components/draft-orders/general-section.js +36 -0
  12. package/.medusa/server/src/admin/components/draft-orders/json-view-section.js +140 -0
  13. package/.medusa/server/src/admin/components/draft-orders/metadata-section.js +28 -0
  14. package/.medusa/server/src/admin/components/draft-orders/shipping-section.js +211 -0
  15. package/.medusa/server/src/admin/components/draft-orders/summary-section.js +148 -0
  16. package/.medusa/server/src/admin/components/inputs/combobox.js +311 -0
  17. package/.medusa/server/src/admin/components/inputs/country-select.js +59 -0
  18. package/.medusa/server/src/admin/components/inputs/number-input.js +100 -0
  19. package/.medusa/server/src/admin/components/inputs/switch-block.js +30 -0
  20. package/.medusa/server/src/admin/components/modals/index.js +19 -0
  21. package/.medusa/server/src/admin/components/modals/route-drawer/index.js +4 -0
  22. package/.medusa/server/src/admin/components/modals/route-drawer/route-drawer.js +57 -0
  23. package/.medusa/server/src/admin/components/modals/route-focus-modal/index.js +4 -0
  24. package/.medusa/server/src/admin/components/modals/route-focus-modal/route-focus-modal.js +71 -0
  25. package/.medusa/server/src/admin/components/modals/route-modal-form/index.js +4 -0
  26. package/.medusa/server/src/admin/components/modals/route-modal-form/route-modal-form.js +60 -0
  27. package/.medusa/server/src/admin/components/modals/route-modal-provider/index.js +6 -0
  28. package/.medusa/server/src/admin/components/modals/route-modal-provider/route-modal-context.js +5 -0
  29. package/.medusa/server/src/admin/components/modals/route-modal-provider/route-provider.js +30 -0
  30. package/.medusa/server/src/admin/components/modals/route-modal-provider/use-route-modal.js +12 -0
  31. package/.medusa/server/src/admin/components/modals/stacked-drawer/index.js +5 -0
  32. package/.medusa/server/src/admin/components/modals/stacked-drawer/stacked-drawer.js +55 -0
  33. package/.medusa/server/src/admin/components/modals/stacked-focus-modal/index.js +5 -0
  34. package/.medusa/server/src/admin/components/modals/stacked-focus-modal/stacked-focus-modal.js +63 -0
  35. package/.medusa/server/src/admin/components/modals/stacked-modal-provider/index.js +6 -0
  36. package/.medusa/server/src/admin/components/modals/stacked-modal-provider/stacked-modal-context.js +5 -0
  37. package/.medusa/server/src/admin/components/modals/stacked-modal-provider/stacked-modal-provider.js +47 -0
  38. package/.medusa/server/src/admin/components/modals/stacked-modal-provider/use-stacked-modal.js +14 -0
  39. package/.medusa/server/src/admin/components/utilities/generic-forward-ref.js +7 -0
  40. package/.medusa/server/src/admin/hooks/api/customers.js +53 -0
  41. package/.medusa/server/src/admin/hooks/api/draft-orders.js +161 -0
  42. package/.medusa/server/src/admin/hooks/api/orders.js +274 -0
  43. package/.medusa/server/src/admin/hooks/api/product-variants.js +21 -0
  44. package/.medusa/server/src/admin/hooks/api/regions.js +35 -0
  45. package/.medusa/server/src/admin/hooks/api/sales-channels.js +35 -0
  46. package/.medusa/server/src/admin/hooks/api/shipping-options.js +35 -0
  47. package/.medusa/server/src/admin/hooks/api/users.js +26 -0
  48. package/.medusa/server/src/admin/hooks/common/use-combobox-data.js +61 -0
  49. package/.medusa/server/src/admin/hooks/common/use-data-table-date-filters.js +89 -0
  50. package/.medusa/server/src/admin/hooks/common/use-debounced-search.js +22 -0
  51. package/.medusa/server/src/admin/hooks/common/use-query-params.js +14 -0
  52. package/.medusa/server/src/admin/hooks/order-edits/use-cancel-order-edit.js +25 -0
  53. package/.medusa/server/src/admin/hooks/order-edits/use-initiate-order-edit.js +39 -0
  54. package/.medusa/server/src/admin/lib/data/countries.js +1762 -0
  55. package/.medusa/server/src/admin/lib/data/currencies.js +36 -0
  56. package/.medusa/server/src/admin/lib/queries/draft-order-details.js +1 -0
  57. package/.medusa/server/src/admin/lib/queries/sdk.js +10 -0
  58. package/.medusa/server/src/admin/lib/schemas/address.js +16 -0
  59. package/.medusa/server/src/admin/lib/utils/address-utils.js +57 -0
  60. package/.medusa/server/src/admin/lib/utils/date-utils.js +27 -0
  61. package/.medusa/server/src/admin/lib/utils/order-utils.js +13 -0
  62. package/.medusa/server/src/admin/routes/draft-orders/@create/page.js +659 -0
  63. package/.medusa/server/src/admin/routes/draft-orders/_id_/@billing-address/page.js +228 -0
  64. package/.medusa/server/src/admin/routes/draft-orders/_id_/@custom-items/page.js +38 -0
  65. package/.medusa/server/src/admin/routes/draft-orders/_id_/@email/page.js +89 -0
  66. package/.medusa/server/src/admin/routes/draft-orders/_id_/@items/page.js +576 -0
  67. package/.medusa/server/src/admin/routes/draft-orders/_id_/@metadata/page.js +338 -0
  68. package/.medusa/server/src/admin/routes/draft-orders/_id_/@promotions/page.js +70 -0
  69. package/.medusa/server/src/admin/routes/draft-orders/_id_/@sales-channel/page.js +113 -0
  70. package/.medusa/server/src/admin/routes/draft-orders/_id_/@shipping/page.js +465 -0
  71. package/.medusa/server/src/admin/routes/draft-orders/_id_/@shipping-address/page.js +241 -0
  72. package/.medusa/server/src/admin/routes/draft-orders/_id_/page.js +70 -0
  73. package/.medusa/server/src/admin/routes/draft-orders/page.js +148 -0
  74. package/.medusa/server/src/api/admin/draft-orders/[id]/convert/route.js +18 -0
  75. package/.medusa/server/src/types/http/draft-orders/payloads.js +3 -0
  76. package/.medusa/server/src/types/http/draft-orders/responses.js +3 -0
  77. package/.medusa/server/src/types/http/orders/entity.js +3 -0
  78. package/.medusa/server/src/types/http/orders/requests.js +3 -0
  79. package/.medusa/server/src/workflows/draft-orders/convert-draft-order-workflow.js +54 -0
  80. package/.medusa/server/tailwind.config.js +12 -0
  81. package/README.md +64 -0
  82. package/package.json +104 -0
@@ -0,0 +1,659 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { zodResolver } from "/Users/oliverjuhl/Desktop/medusa/draft-order-plugin/node_modules/@hookform/resolvers/zod/dist/zod.mjs";
3
+ import { toast, Heading, Divider, Input, Button, Label, Hint, Switch } from "@medusajs/ui";
4
+ import { useCallback } from "react";
5
+ import { useForm, useWatch } from "react-hook-form";
6
+ import { z } from "/Users/oliverjuhl/Desktop/medusa/draft-order-plugin/node_modules/zod/lib/index.mjs";
7
+ import { Form } from "../../../components/common/form.js";
8
+ import { KeyboundForm } from "../../../components/common/keybound-form.js";
9
+ import { Combobox } from "../../../components/inputs/combobox.js";
10
+ import { CountrySelect } from "../../../components/inputs/country-select.js";
11
+ import "../../../components/modals/route-drawer/route-drawer.js";
12
+ import { RouteFocusModal } from "../../../components/modals/route-focus-modal/route-focus-modal.js";
13
+ import "react-router-dom";
14
+ import "../../../components/modals/route-modal-provider/route-modal-context.js";
15
+ import { useRouteModal } from "../../../components/modals/route-modal-provider/use-route-modal.js";
16
+ import "../../../components/modals/stacked-drawer/stacked-drawer.js";
17
+ import "../../../components/modals/stacked-focus-modal/stacked-focus-modal.js";
18
+ import "../../../components/modals/stacked-modal-provider/stacked-modal-context.js";
19
+ import { useCreateDraftOrder } from "../../../hooks/api/draft-orders.js";
20
+ import { useComboboxData } from "../../../hooks/common/use-combobox-data.js";
21
+ import { sdk } from "../../../lib/queries/sdk.js";
22
+ import { addressSchema } from "../../../lib/schemas/address.js";
23
+ import { getFormattedAddress } from "../../../lib/utils/address-utils.js";
24
+ const Create = () => {
25
+ return /* @__PURE__ */ jsx(RouteFocusModal, { children: /* @__PURE__ */ jsx(CreateForm, {}) });
26
+ };
27
+ const CreateForm = () => {
28
+ const { handleSuccess } = useRouteModal();
29
+ const form = useForm({
30
+ defaultValues: {
31
+ region_id: "",
32
+ sales_channel_id: "",
33
+ customer_id: "",
34
+ email: "",
35
+ shipping_address_id: "",
36
+ shipping_address: {
37
+ country_code: "",
38
+ first_name: "",
39
+ last_name: "",
40
+ address_1: "",
41
+ address_2: "",
42
+ city: "",
43
+ province: "",
44
+ postal_code: "",
45
+ phone: "",
46
+ company: ""
47
+ },
48
+ billing_address_id: "",
49
+ billing_address: {
50
+ country_code: "",
51
+ first_name: "",
52
+ last_name: "",
53
+ address_1: "",
54
+ address_2: "",
55
+ city: "",
56
+ province: "",
57
+ company: "",
58
+ postal_code: "",
59
+ phone: ""
60
+ },
61
+ same_as_shipping: true
62
+ },
63
+ resolver: zodResolver(schema)
64
+ });
65
+ const regions = useComboboxData({
66
+ queryFn: async (params) => {
67
+ return await sdk.admin.region.list(params);
68
+ },
69
+ queryKey: ["regions"],
70
+ getOptions: (data) => {
71
+ return data.regions.map((region) => ({
72
+ label: region.name,
73
+ value: region.id
74
+ }));
75
+ }
76
+ });
77
+ const salesChannels = useComboboxData({
78
+ queryFn: async (params) => {
79
+ return await sdk.admin.salesChannel.list(params);
80
+ },
81
+ queryKey: ["sales-channels"],
82
+ getOptions: (data) => {
83
+ return data.sales_channels.map((salesChannel) => ({
84
+ label: salesChannel.name,
85
+ value: salesChannel.id
86
+ }));
87
+ }
88
+ });
89
+ const { mutateAsync } = useCreateDraftOrder();
90
+ const onSubmit = form.handleSubmit(async (data) => {
91
+ await mutateAsync(
92
+ {
93
+ region_id: data.region_id,
94
+ sales_channel_id: data.sales_channel_id,
95
+ customer_id: data.customer_id,
96
+ email: data.email,
97
+ shipping_address: data.shipping_address,
98
+ billing_address: data.same_as_shipping ? data.shipping_address : data.billing_address ? data.billing_address : void 0
99
+ },
100
+ {
101
+ onSuccess: (response) => {
102
+ handleSuccess(`/draft-orders/${response.draft_order.id}`);
103
+ },
104
+ onError: (error) => {
105
+ toast.error(error.message);
106
+ }
107
+ }
108
+ );
109
+ });
110
+ if (regions.isError) {
111
+ throw regions.error;
112
+ }
113
+ if (salesChannels.isError) {
114
+ throw salesChannels.error;
115
+ }
116
+ return /* @__PURE__ */ jsx(RouteFocusModal.Form, { form, children: /* @__PURE__ */ jsxs(
117
+ KeyboundForm,
118
+ {
119
+ className: "flex h-full flex-col overflow-hidden",
120
+ onSubmit,
121
+ children: [
122
+ /* @__PURE__ */ jsx(RouteFocusModal.Header, {}),
123
+ /* @__PURE__ */ jsx(RouteFocusModal.Body, { className: "flex flex-1 flex-col overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-[720px] flex-col gap-y-6 px-2 py-16", children: [
124
+ /* @__PURE__ */ jsxs("div", { children: [
125
+ /* @__PURE__ */ jsx(RouteFocusModal.Title, { asChild: true, children: /* @__PURE__ */ jsx(Heading, { children: "Create Draft Order" }) }),
126
+ /* @__PURE__ */ jsx(RouteFocusModal.Description, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Create a new draft order" }) })
127
+ ] }),
128
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
129
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
130
+ Form.Field,
131
+ {
132
+ control: form.control,
133
+ name: "region_id",
134
+ render: ({ field }) => {
135
+ return /* @__PURE__ */ jsx(Form.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
136
+ /* @__PURE__ */ jsxs("div", { children: [
137
+ /* @__PURE__ */ jsx(Form.Label, { children: "Region" }),
138
+ /* @__PURE__ */ jsx(Form.Hint, { children: "Choose region" })
139
+ ] }),
140
+ /* @__PURE__ */ jsxs("div", { children: [
141
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(
142
+ Combobox,
143
+ {
144
+ options: regions.options,
145
+ fetchNextPage: regions.fetchNextPage,
146
+ isFetchingNextPage: regions.isFetchingNextPage,
147
+ searchValue: regions.searchValue,
148
+ onSearchValueChange: regions.onSearchValueChange,
149
+ placeholder: "Select region",
150
+ ...field
151
+ }
152
+ ) }),
153
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
154
+ ] })
155
+ ] }) });
156
+ }
157
+ }
158
+ ) }),
159
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
160
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
161
+ Form.Field,
162
+ {
163
+ control: form.control,
164
+ name: "sales_channel_id",
165
+ render: ({ field }) => {
166
+ return /* @__PURE__ */ jsx(Form.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
167
+ /* @__PURE__ */ jsxs("div", { children: [
168
+ /* @__PURE__ */ jsx(Form.Label, { children: "Sales Channel" }),
169
+ /* @__PURE__ */ jsx(Form.Hint, { children: "Choose sales channel" })
170
+ ] }),
171
+ /* @__PURE__ */ jsxs("div", { children: [
172
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(
173
+ Combobox,
174
+ {
175
+ options: salesChannels.options,
176
+ fetchNextPage: salesChannels.fetchNextPage,
177
+ isFetchingNextPage: salesChannels.isFetchingNextPage,
178
+ searchValue: salesChannels.searchValue,
179
+ onSearchValueChange: salesChannels.onSearchValueChange,
180
+ placeholder: "Select sales channel",
181
+ ...field
182
+ }
183
+ ) }),
184
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
185
+ ] })
186
+ ] }) });
187
+ }
188
+ }
189
+ ) }),
190
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
191
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
192
+ CustomerField,
193
+ {
194
+ control: form.control,
195
+ setValue: form.setValue
196
+ }
197
+ ) }),
198
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
199
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
200
+ Form.Field,
201
+ {
202
+ control: form.control,
203
+ name: "email",
204
+ render: ({ field }) => {
205
+ return /* @__PURE__ */ jsx(Form.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
206
+ /* @__PURE__ */ jsxs("div", { children: [
207
+ /* @__PURE__ */ jsx(Form.Label, { children: "Email" }),
208
+ /* @__PURE__ */ jsx(Form.Hint, { children: "Input a email to associate with the order" })
209
+ ] }),
210
+ /* @__PURE__ */ jsxs("div", { children: [
211
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field, placeholder: "john@doe.com" }) }),
212
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
213
+ ] })
214
+ ] }) });
215
+ }
216
+ }
217
+ ) }),
218
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
219
+ /* @__PURE__ */ jsx(ShippingAddressField, { control: form.control }),
220
+ /* @__PURE__ */ jsx(Divider, { variant: "dashed" }),
221
+ /* @__PURE__ */ jsx(BillingAddressField, { control: form.control })
222
+ ] }) }) }),
223
+ /* @__PURE__ */ jsx(RouteFocusModal.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-x-2", children: [
224
+ /* @__PURE__ */ jsx(RouteFocusModal.Close, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "small", children: "Cancel" }) }),
225
+ /* @__PURE__ */ jsx(Button, { size: "small", children: "Save" })
226
+ ] }) })
227
+ ]
228
+ }
229
+ ) });
230
+ };
231
+ const CustomerField = ({ control, setValue }) => {
232
+ const email = useWatch({ control, name: "email" });
233
+ const customers = useComboboxData({
234
+ queryFn: async (params) => {
235
+ return await sdk.admin.customer.list(params);
236
+ },
237
+ queryKey: ["customers"],
238
+ getOptions: (data) => {
239
+ return data.customers.map((customer) => {
240
+ const name = [customer.first_name, customer.last_name].filter(Boolean).join(" ");
241
+ return {
242
+ label: name ? `${name} (${customer.email})` : customer.email,
243
+ value: customer.id
244
+ };
245
+ });
246
+ }
247
+ });
248
+ const onPropagateEmail = useCallback(
249
+ (value) => {
250
+ var _a, _b;
251
+ const label = (_a = customers.options.find(
252
+ (option) => option.value === value
253
+ )) == null ? void 0 : _a.label;
254
+ const customerEmail = ((_b = label == null ? void 0 : label.match(/\((.*@.*)\)$/)) == null ? void 0 : _b[1]) || label;
255
+ if (!email && customerEmail) {
256
+ setValue("email", customerEmail, {
257
+ shouldDirty: true,
258
+ shouldTouch: true
259
+ });
260
+ }
261
+ },
262
+ [email, setValue, customers.options]
263
+ );
264
+ if (customers.isError) {
265
+ throw customers.error;
266
+ }
267
+ return /* @__PURE__ */ jsx(
268
+ Form.Field,
269
+ {
270
+ control,
271
+ name: "customer_id",
272
+ render: ({ field: { onChange, ...field } }) => {
273
+ return /* @__PURE__ */ jsx(Form.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
274
+ /* @__PURE__ */ jsxs("div", { children: [
275
+ /* @__PURE__ */ jsx(Form.Label, { optional: true, children: "Customer" }),
276
+ /* @__PURE__ */ jsx(Form.Hint, { children: "Choose an existing customer" })
277
+ ] }),
278
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(
279
+ Combobox,
280
+ {
281
+ options: customers.options,
282
+ fetchNextPage: customers.fetchNextPage,
283
+ isFetchingNextPage: customers.isFetchingNextPage,
284
+ searchValue: customers.searchValue,
285
+ onSearchValueChange: customers.onSearchValueChange,
286
+ placeholder: "Select customer",
287
+ onChange: (value) => {
288
+ onPropagateEmail(value);
289
+ onChange(value);
290
+ },
291
+ ...field
292
+ }
293
+ ) })
294
+ ] }) });
295
+ }
296
+ }
297
+ );
298
+ };
299
+ const ShippingAddressField = ({ control }) => {
300
+ const customerId = useWatch({ control, name: "customer_id" });
301
+ useComboboxData({
302
+ queryFn: async (params) => {
303
+ const response = await sdk.client.fetch(
304
+ "/admin/customers/" + customerId + "/addresses",
305
+ {
306
+ method: "GET",
307
+ headers: {
308
+ "Content-Type": "application/json"
309
+ },
310
+ query: params,
311
+ credentials: "include"
312
+ }
313
+ );
314
+ return response;
315
+ },
316
+ queryKey: ["addresses"],
317
+ getOptions: (data) => {
318
+ return data.addresses.map((address) => {
319
+ const formattedAddress = getFormattedAddress(address).join(",\n");
320
+ return {
321
+ label: formattedAddress,
322
+ value: address.id
323
+ };
324
+ });
325
+ },
326
+ enabled: !!customerId
327
+ });
328
+ return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
329
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-1", children: [
330
+ /* @__PURE__ */ jsx(Label, { size: "small", weight: "plus", children: "Shipping address" }),
331
+ /* @__PURE__ */ jsx(Hint, { children: "Address used for shipping" })
332
+ ] }),
333
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-y-3", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-3", children: [
334
+ /* @__PURE__ */ jsx(
335
+ Form.Field,
336
+ {
337
+ control,
338
+ name: "shipping_address.country_code",
339
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
340
+ /* @__PURE__ */ jsx(Form.Label, { variant: "subtle", children: "Country" }),
341
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
342
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
343
+ ] })
344
+ }
345
+ ),
346
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
347
+ /* @__PURE__ */ jsx(
348
+ Form.Field,
349
+ {
350
+ control,
351
+ name: "shipping_address.first_name",
352
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
353
+ /* @__PURE__ */ jsx(Form.Label, { variant: "subtle", children: "First name" }),
354
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
355
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
356
+ ] })
357
+ }
358
+ ),
359
+ /* @__PURE__ */ jsx(
360
+ Form.Field,
361
+ {
362
+ control,
363
+ name: "shipping_address.last_name",
364
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
365
+ /* @__PURE__ */ jsx(Form.Label, { variant: "subtle", children: "Last name" }),
366
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
367
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
368
+ ] })
369
+ }
370
+ )
371
+ ] }),
372
+ /* @__PURE__ */ jsx(
373
+ Form.Field,
374
+ {
375
+ control,
376
+ name: "shipping_address.company",
377
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
378
+ /* @__PURE__ */ jsx(Form.Label, { optional: true, variant: "subtle", children: "Company" }),
379
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
380
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
381
+ ] })
382
+ }
383
+ ),
384
+ /* @__PURE__ */ jsx(
385
+ Form.Field,
386
+ {
387
+ control,
388
+ name: "shipping_address.address_1",
389
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
390
+ /* @__PURE__ */ jsx(Form.Label, { variant: "subtle", children: "Address" }),
391
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
392
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
393
+ ] })
394
+ }
395
+ ),
396
+ /* @__PURE__ */ jsx(
397
+ Form.Field,
398
+ {
399
+ control,
400
+ name: "shipping_address.address_2",
401
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
402
+ /* @__PURE__ */ jsx(Form.Label, { optional: true, variant: "subtle", children: "Apartment, suite, etc." }),
403
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
404
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
405
+ ] })
406
+ }
407
+ ),
408
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
409
+ /* @__PURE__ */ jsx(
410
+ Form.Field,
411
+ {
412
+ control,
413
+ name: "shipping_address.postal_code",
414
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
415
+ /* @__PURE__ */ jsx(Form.Label, { variant: "subtle", children: "Postal code" }),
416
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
417
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
418
+ ] })
419
+ }
420
+ ),
421
+ /* @__PURE__ */ jsx(
422
+ Form.Field,
423
+ {
424
+ control,
425
+ name: "shipping_address.city",
426
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
427
+ /* @__PURE__ */ jsx(Form.Label, { variant: "subtle", children: "City" }),
428
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
429
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
430
+ ] })
431
+ }
432
+ )
433
+ ] }),
434
+ /* @__PURE__ */ jsx(
435
+ Form.Field,
436
+ {
437
+ control,
438
+ name: "shipping_address.province",
439
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
440
+ /* @__PURE__ */ jsx(Form.Label, { optional: true, variant: "subtle", children: "Province / State" }),
441
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
442
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
443
+ ] })
444
+ }
445
+ ),
446
+ /* @__PURE__ */ jsx(
447
+ Form.Field,
448
+ {
449
+ control,
450
+ name: "shipping_address.phone",
451
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
452
+ /* @__PURE__ */ jsx(Form.Label, { optional: true, variant: "subtle", children: "Phone" }),
453
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
454
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
455
+ ] })
456
+ }
457
+ )
458
+ ] }) })
459
+ ] });
460
+ };
461
+ const BillingAddressField = ({ control }) => {
462
+ const sameAsShipping = useWatch({ control, name: "same_as_shipping" });
463
+ return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-x-3", children: [
464
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-1", children: [
465
+ /* @__PURE__ */ jsx(Label, { size: "small", weight: "plus", children: "Billing address" }),
466
+ /* @__PURE__ */ jsx(Hint, { children: "Address used for billing" })
467
+ ] }),
468
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-3", children: [
469
+ /* @__PURE__ */ jsx(
470
+ Form.Field,
471
+ {
472
+ control,
473
+ name: "same_as_shipping",
474
+ render: ({ field: { value, onChange, ...field } }) => {
475
+ return /* @__PURE__ */ jsx(Form.Item, { children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[28px_1fr] items-start gap-3", children: [
476
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(
477
+ Switch,
478
+ {
479
+ size: "small",
480
+ ...field,
481
+ checked: value,
482
+ onCheckedChange: onChange
483
+ }
484
+ ) }),
485
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
486
+ /* @__PURE__ */ jsx(Form.Label, { children: "Same as shipping address" }),
487
+ /* @__PURE__ */ jsx(Form.Hint, { children: "Use the same address for billing and shipping" })
488
+ ] })
489
+ ] }) });
490
+ }
491
+ }
492
+ ),
493
+ !sameAsShipping && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-y-3", children: [
494
+ /* @__PURE__ */ jsx(
495
+ Form.Field,
496
+ {
497
+ control,
498
+ name: "billing_address.country_code",
499
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
500
+ /* @__PURE__ */ jsx(Form.Label, { variant: "subtle", children: "Country" }),
501
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(CountrySelect, { ...field }) }),
502
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
503
+ ] })
504
+ }
505
+ ),
506
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
507
+ /* @__PURE__ */ jsx(
508
+ Form.Field,
509
+ {
510
+ control,
511
+ name: "billing_address.first_name",
512
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
513
+ /* @__PURE__ */ jsx(Form.Label, { variant: "subtle", children: "First name" }),
514
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
515
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
516
+ ] })
517
+ }
518
+ ),
519
+ /* @__PURE__ */ jsx(
520
+ Form.Field,
521
+ {
522
+ control,
523
+ name: "billing_address.last_name",
524
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
525
+ /* @__PURE__ */ jsx(Form.Label, { variant: "subtle", children: "Last name" }),
526
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
527
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
528
+ ] })
529
+ }
530
+ )
531
+ ] }),
532
+ /* @__PURE__ */ jsx(
533
+ Form.Field,
534
+ {
535
+ control,
536
+ name: "billing_address.company",
537
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
538
+ /* @__PURE__ */ jsx(Form.Label, { optional: true, variant: "subtle", children: "Company" }),
539
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
540
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
541
+ ] })
542
+ }
543
+ ),
544
+ /* @__PURE__ */ jsx(
545
+ Form.Field,
546
+ {
547
+ control,
548
+ name: "billing_address.address_1",
549
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
550
+ /* @__PURE__ */ jsx(Form.Label, { variant: "subtle", children: "Address" }),
551
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
552
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
553
+ ] })
554
+ }
555
+ ),
556
+ /* @__PURE__ */ jsx(
557
+ Form.Field,
558
+ {
559
+ control,
560
+ name: "billing_address.address_2",
561
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
562
+ /* @__PURE__ */ jsx(Form.Label, { optional: true, variant: "subtle", children: "Apartment, suite, etc." }),
563
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
564
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
565
+ ] })
566
+ }
567
+ ),
568
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
569
+ /* @__PURE__ */ jsx(
570
+ Form.Field,
571
+ {
572
+ control,
573
+ name: "billing_address.postal_code",
574
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
575
+ /* @__PURE__ */ jsx(Form.Label, { variant: "subtle", children: "Postal code" }),
576
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
577
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
578
+ ] })
579
+ }
580
+ ),
581
+ /* @__PURE__ */ jsx(
582
+ Form.Field,
583
+ {
584
+ control,
585
+ name: "billing_address.city",
586
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
587
+ /* @__PURE__ */ jsx(Form.Label, { variant: "subtle", children: "City" }),
588
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
589
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
590
+ ] })
591
+ }
592
+ )
593
+ ] }),
594
+ /* @__PURE__ */ jsx(
595
+ Form.Field,
596
+ {
597
+ control,
598
+ name: "billing_address.province",
599
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
600
+ /* @__PURE__ */ jsx(Form.Label, { optional: true, variant: "subtle", children: "Province / State" }),
601
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
602
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
603
+ ] })
604
+ }
605
+ ),
606
+ /* @__PURE__ */ jsx(
607
+ Form.Field,
608
+ {
609
+ control,
610
+ name: "billing_address.phone",
611
+ render: ({ field }) => /* @__PURE__ */ jsxs(Form.Item, { children: [
612
+ /* @__PURE__ */ jsx(Form.Label, { optional: true, variant: "subtle", children: "Phone" }),
613
+ /* @__PURE__ */ jsx(Form.Control, { children: /* @__PURE__ */ jsx(Input, { ...field }) }),
614
+ /* @__PURE__ */ jsx(Form.ErrorMessage, {})
615
+ ] })
616
+ }
617
+ )
618
+ ] })
619
+ ] })
620
+ ] });
621
+ };
622
+ const schema = z.object({
623
+ region_id: z.string().min(1),
624
+ sales_channel_id: z.string().min(1),
625
+ customer_id: z.string().optional(),
626
+ email: z.string().email().optional(),
627
+ shipping_address_id: z.string().optional(),
628
+ shipping_address: addressSchema.optional(),
629
+ billing_address_id: z.string().optional(),
630
+ billing_address: addressSchema.nullish(),
631
+ same_as_shipping: z.boolean().optional()
632
+ }).superRefine((data, ctx) => {
633
+ if (!data.customer_id && !data.email) {
634
+ ctx.addIssue({
635
+ code: z.ZodIssueCode.custom,
636
+ message: "Either a customer or email must be provided",
637
+ path: ["customer_id", "email"]
638
+ });
639
+ }
640
+ if (!data.shipping_address && !data.shipping_address_id) {
641
+ ctx.addIssue({
642
+ code: z.ZodIssueCode.custom,
643
+ message: "Shipping address is required",
644
+ path: ["shipping_address"]
645
+ });
646
+ }
647
+ if (!data.same_as_shipping) {
648
+ if (!data.billing_address && !data.billing_address_id) {
649
+ ctx.addIssue({
650
+ code: z.ZodIssueCode.custom,
651
+ message: "Billing address is required",
652
+ path: ["billing_address"]
653
+ });
654
+ }
655
+ }
656
+ });
657
+ export {
658
+ Create as default
659
+ };