@vtex/faststore-plugin-buyer-portal 1.0.35 → 1.0.37

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 (71) hide show
  1. package/package.json +1 -1
  2. package/public/buyer-portal-icons.svg +22 -1
  3. package/src/features/addresses/clients/AddressesClient.ts +86 -2
  4. package/src/features/addresses/clients/PostalCodeClient.ts +19 -0
  5. package/src/features/addresses/components/AddressDropdownMenu/AddressDropdownMenu.tsx +136 -0
  6. package/src/features/addresses/components/AddressDropdownMenu/address-dropdown-menu.scss +5 -0
  7. package/src/features/addresses/components/AddressForm/AddressForm.tsx +280 -0
  8. package/src/features/addresses/components/AddressLine/AddressLine.tsx +11 -9
  9. package/src/features/addresses/components/CreateAddressDrawer/CreateAddressDrawer.tsx +187 -0
  10. package/src/features/addresses/components/CreateAddressDrawer/create-address-drawer.scss +56 -0
  11. package/src/features/addresses/components/DeleteAddressDrawer/DeleteAddressDrawer.tsx +99 -0
  12. package/src/features/addresses/components/EditAddressDrawer/EditAddreessDrawer.tsx +100 -0
  13. package/src/features/addresses/components/EditAddressDrawer/edit-address-drawer.scss +29 -0
  14. package/src/features/addresses/components/ExistingAddress/ExistingAddress.tsx +35 -0
  15. package/src/features/addresses/components/ExistingAddress/existing-address.scss +23 -0
  16. package/src/features/addresses/components/LocationForm/LocationForm.tsx +52 -0
  17. package/src/features/addresses/components/LocationForm/location-form.scss +29 -0
  18. package/src/features/addresses/components/LocationsDrawer/LocationsDrawer.tsx +38 -0
  19. package/src/features/addresses/components/RecipientsDrawer/RecipientsDrawer.tsx +39 -0
  20. package/src/features/addresses/components/RecipientsForm/RecipientsForm.tsx +73 -0
  21. package/src/features/addresses/components/RecipientsForm/recipients-form.scss +29 -0
  22. package/src/features/addresses/components/RemoveAddressDrawer/RemoveAddressDrawer.tsx +80 -0
  23. package/src/features/addresses/components/RemoveAddressDrawer/remove-address-drawer.scss +15 -0
  24. package/src/features/addresses/components/index.ts +11 -0
  25. package/src/features/addresses/data/BRA.ts +29 -0
  26. package/src/features/addresses/data/CAN.ts +15 -0
  27. package/src/features/addresses/data/MEX.ts +34 -0
  28. package/src/features/addresses/data/USA.ts +65 -0
  29. package/src/features/addresses/data/countries.ts +6 -0
  30. package/src/features/addresses/data/states.ts +12 -0
  31. package/src/features/addresses/hooks/index.ts +3 -0
  32. package/src/features/addresses/hooks/useCreateAddress.ts +28 -0
  33. package/src/features/addresses/hooks/useDebouncedSearchAddress.ts +20 -0
  34. package/src/features/addresses/hooks/useDeleteAddress.ts +25 -0
  35. package/src/features/addresses/hooks/useEditAddress.ts +25 -0
  36. package/src/features/addresses/hooks/useSearchAddress.ts +20 -0
  37. package/src/features/addresses/layouts/AddressDetailsLayout/AddressDetailsLayout.tsx +55 -65
  38. package/src/features/addresses/layouts/AddressDetailsLayout/address-details-layout.scss +46 -15
  39. package/src/features/addresses/layouts/AddressesLayout/AddressesLayout.tsx +12 -5
  40. package/src/features/addresses/layouts/AddressesLayout/addresses-layout.scss +3 -0
  41. package/src/features/addresses/services/auto-complete-address.service.ts +16 -0
  42. package/src/features/addresses/services/create-new-address.service.ts +14 -0
  43. package/src/features/addresses/services/delete-address.service.ts +16 -0
  44. package/src/features/addresses/services/edit-address.service.ts +17 -0
  45. package/src/features/addresses/services/get-address-details.service.ts +15 -6
  46. package/src/features/addresses/services/get-addresses.service.ts +3 -3
  47. package/src/features/addresses/services/index.ts +20 -0
  48. package/src/features/addresses/services/search-address-by-name.service.ts +30 -0
  49. package/src/features/addresses/types/AddressData.ts +40 -4
  50. package/src/features/addresses/types/index.ts +7 -1
  51. package/src/features/org-units/mocks/organization-data.ts +1 -2
  52. package/src/features/shared/clients/ScopeClient.ts +37 -0
  53. package/src/features/shared/components/AutocompleteDropdown/autocomplete-dropdown.scss +0 -1
  54. package/src/features/shared/hooks/index.ts +2 -0
  55. package/src/features/shared/hooks/useAddToScope.ts +21 -0
  56. package/src/features/shared/hooks/useRemoveFromScope.ts +24 -0
  57. package/src/features/shared/services/add-to-scope.service.ts +21 -0
  58. package/src/features/shared/services/index.ts +8 -0
  59. package/src/features/shared/services/remove-from-scope.service.ts +21 -0
  60. package/src/features/shared/types/ScopeInput.d.ts +4 -0
  61. package/src/features/shared/types/index.ts +1 -0
  62. package/src/features/shared/utils/addresLabelToPropMapping.ts +7 -7
  63. package/src/features/shared/utils/api.ts +4 -0
  64. package/src/features/shared/utils/constants.ts +1 -1
  65. package/src/features/shared/utils/index.ts +1 -1
  66. package/src/features/shared/utils/mask.ts +51 -0
  67. package/src/features/shared/utils/postalCode.ts +79 -0
  68. package/src/pages/address-details.tsx +9 -2
  69. package/src/pages/addresses.tsx +2 -2
  70. package/src/features/addresses/mocks/addresses-data.ts +0 -244
  71. package/src/features/addresses/mocks/index.ts +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtex/faststore-plugin-buyer-portal",
3
- "version": "1.0.35",
3
+ "version": "1.0.37",
4
4
  "description": "A plugin for faststore with buyer portal",
5
5
  "main": "index.js",
6
6
  "dependencies": {
@@ -247,4 +247,25 @@
247
247
  d="M3 18C2.45 18 1.97917 17.8042 1.5875 17.4125C1.19583 17.0208 1 16.55 1 16V3H0V1H5V0H11V1H16V3H15V16C15 16.55 14.8042 17.0208 14.4125 17.4125C14.0208 17.8042 13.55 18 13 18H3ZM13 3H3V16H13V3ZM5 14H7V5H5V14ZM9 14H11V5H9V14Z"
248
248
  fill="currentColor" />
249
249
  </symbol>
250
- </svg>
250
+
251
+ <symbol
252
+ id="ErrorX"
253
+ xmlns="http://www.w3.org/2000/svg"
254
+ viewBox="0 -960 960 960"
255
+ fill="currentColor">
256
+ <path
257
+ d="m336-280 144-144 144 144 56-56-144-144 144-144-56-56-144 144-144-144-56 56 144 144-144 144 56 56ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Z"/>
258
+ </symbol>
259
+
260
+
261
+ <symbol
262
+ id="BookmarkAdd"
263
+ viewBox="0 0 13 15"
264
+ fill="currentColor"
265
+ xmlns="http://www.w3.org/2000/svg">
266
+ <path d="M0 15V2.5C0 2.08181 0.145833 1.72375 0.4375 1.42583C0.729167 1.12806 1.08333 0.986111 1.5 1H6V2.5H1.5V12.7708L5 11.375L8.5 12.7708V7H10V15L5 13L0 15ZM9.25 5.25V3.75H7.75V2.25H9.25V0.75H10.75V2.25H12.25V3.75H10.75V5.25H9.25Z"/>
267
+ </symbol>
268
+
269
+
270
+ </svg>
271
+
@@ -1,6 +1,10 @@
1
1
  import { Client } from "../../shared/clients/Client";
2
2
  import { getApiUrl } from "../../shared/utils";
3
- import type { AddressData } from "../types";
3
+ import type { AddressData, AddressInput } from "../types";
4
+
5
+ type AddressList = {
6
+ addresses: AddressData[];
7
+ };
4
8
 
5
9
  export default class AddressesClient extends Client {
6
10
  constructor() {
@@ -8,7 +12,87 @@ export default class AddressesClient extends Client {
8
12
  }
9
13
 
10
14
  getAddressesByCustomerId(customerId: string, cookie: string) {
11
- return this.get<{ addresses: AddressData[] }>(`addresses/${customerId}`, {
15
+ return this.get<AddressList>(`addresses/${customerId}`, {
16
+ headers: {
17
+ Cookie: cookie,
18
+ },
19
+ });
20
+ }
21
+
22
+ getAddressById(addressId: string, cookie: string) {
23
+ return this.get<AddressData>(`address/${addressId}`, {
24
+ headers: {
25
+ Cookie: cookie,
26
+ },
27
+ });
28
+ }
29
+
30
+ searchAddressesByName(customerId: string, name: string, cookie: string) {
31
+ return this.get<AddressList>(
32
+ `search/addresses/${customerId}?name=${name}`,
33
+ {
34
+ headers: {
35
+ Cookie: cookie,
36
+ },
37
+ }
38
+ );
39
+ }
40
+
41
+ createNewAddress(data: AddressInput, customerId: string, cookie: string) {
42
+ const formatedAddress = {
43
+ name: data.name,
44
+ zip: data.zip,
45
+ streetAddress: data.streetAddress,
46
+ neighborhood: data.neighborhood,
47
+ streetAddress2: data.streetAddress2,
48
+ city: data.city,
49
+ state: data.state,
50
+ country: data.countryCode,
51
+ geoCordinates: data.geoCordinates,
52
+ types: data.types,
53
+ userId: customerId,
54
+ isActive: true,
55
+ };
56
+
57
+ return this.post(
58
+ `addresses/${customerId}`,
59
+ { ...formatedAddress },
60
+ {
61
+ headers: {
62
+ Cookie: cookie,
63
+ },
64
+ }
65
+ );
66
+ }
67
+
68
+ editAddress(data: AddressInput, addressId: string, cookie: string) {
69
+ const formatedAddress = {
70
+ name: data.name,
71
+ zip: data.zip,
72
+ streetAddress: data.streetAddress,
73
+ neighborhood: data.neighborhood,
74
+ streetAddress2: data.streetAddress2,
75
+ city: data.city,
76
+ state: data.state,
77
+ country: data.countryCode,
78
+ geoCordinates: data.geoCordinates,
79
+ types: data.types,
80
+ isActive: true,
81
+ };
82
+
83
+ return this.patch(
84
+ `address/${addressId}`,
85
+ { ...formatedAddress },
86
+ {
87
+ headers: {
88
+ Cookie: cookie,
89
+ },
90
+ }
91
+ );
92
+ }
93
+
94
+ deleteAddress(addressId: string, cookie: string) {
95
+ return this.delete(`address/${addressId}`, null, {
12
96
  headers: {
13
97
  Cookie: cookie,
14
98
  },
@@ -0,0 +1,19 @@
1
+ import { Client } from "../../shared/clients/Client";
2
+ import { getPostalCodeApiUrl } from "../../shared/utils";
3
+ import type { CheckoutAddress } from "../types";
4
+
5
+ export default class PostalCodeClient extends Client {
6
+ constructor() {
7
+ super(getPostalCodeApiUrl());
8
+ }
9
+
10
+ getAutoCompleteAddress(countryCode: string, postalCode: string) {
11
+ return this.get<CheckoutAddress>(`${countryCode}/${postalCode}`, {
12
+ ignoreContentType: true,
13
+ });
14
+ }
15
+ }
16
+
17
+ const postalCodeClient = new PostalCodeClient();
18
+
19
+ export { postalCodeClient };
@@ -0,0 +1,136 @@
1
+ import { DropdownItem, Icon as UIIcon } from "@faststore/ui";
2
+
3
+ import {
4
+ EditAddressDrawer,
5
+ LocationDrawer,
6
+ RecipientsDrawer,
7
+ RemoveAddressDrawer,
8
+ DeleteAddressDrawer,
9
+ } from "..";
10
+ import { useDrawerProps, useBuyerPortal } from "../../../shared/hooks";
11
+ import { BasicDropdownMenu, Icon } from "../../../shared/components";
12
+ import type { AddressData } from "../../types";
13
+
14
+ export type AddressDropdownMenuProps = {
15
+ currentAddress: AddressData;
16
+ onUpdate?: () => void;
17
+ onCreate?: () => void;
18
+ isComplete?: boolean;
19
+ };
20
+
21
+ export const AddressDropdownMenu = ({
22
+ currentAddress,
23
+ }: AddressDropdownMenuProps) => {
24
+ const { currentOrgUnit } = useBuyerPortal();
25
+
26
+ const idsPath = currentOrgUnit?.path?.ids?.split("/") ?? [];
27
+
28
+ const isRootLevelOrgUnit = idsPath.length === 2 ?? false;
29
+
30
+ const {
31
+ open: openEditDrawerProps,
32
+ isOpen: isEditDrawerOpen,
33
+ ...editDrawerProps
34
+ } = useDrawerProps();
35
+
36
+ const {
37
+ open: openLocationDrawer,
38
+ isOpen: isOpenLocationDrawer,
39
+ ...locationDrawerProps
40
+ } = useDrawerProps();
41
+
42
+ const {
43
+ open: openRecipientsDrawer,
44
+ isOpen: isOpenRecipientsDrawer,
45
+ ...recipientDrawerProps
46
+ } = useDrawerProps();
47
+
48
+ const {
49
+ open: openRemoveAddressDrawer,
50
+ isOpen: isOpenRemoveAddressDrawer,
51
+ ...removeAddressDrawerProps
52
+ } = useDrawerProps();
53
+
54
+ const {
55
+ open: openDeleteAddressDrawer,
56
+ isOpen: isOpenDeleteAddressDrawer,
57
+ ...deleteAddressDrawerProps
58
+ } = useDrawerProps();
59
+
60
+ const sizeProps = { width: 20, height: 20 };
61
+
62
+ return (
63
+ <>
64
+ <BasicDropdownMenu data-fs-bp-dropdown-menu>
65
+ <DropdownItem onClick={openEditDrawerProps}>
66
+ <Icon name="Edit" {...sizeProps} />
67
+ Edit details
68
+ </DropdownItem>
69
+ <DropdownItem onClick={openLocationDrawer}>
70
+ <UIIcon name="PlusCircle" {...sizeProps} />
71
+ Add Locations
72
+ </DropdownItem>
73
+ <DropdownItem onClick={openRecipientsDrawer}>
74
+ <UIIcon name="PlusCircle" {...sizeProps} />
75
+ Add Recipients
76
+ </DropdownItem>
77
+ <DropdownItem onClick={() => {}}>
78
+ <Icon name="BookmarkAdd" {...sizeProps} />
79
+ Set as Default
80
+ </DropdownItem>
81
+
82
+ <BasicDropdownMenu.Separator />
83
+ <DropdownItem onClick={openRemoveAddressDrawer}>
84
+ <UIIcon name="MinusCircle" {...sizeProps} />
85
+ Remove from Unit
86
+ </DropdownItem>
87
+ {isRootLevelOrgUnit && (
88
+ <DropdownItem onClick={openDeleteAddressDrawer}>
89
+ <Icon name="Trash" {...sizeProps} data-fs-bp-delete-address />
90
+ <span data-fs-bp-delete-address>Delete</span>
91
+ </DropdownItem>
92
+ )}
93
+ </BasicDropdownMenu>
94
+ {isEditDrawerOpen && (
95
+ <EditAddressDrawer
96
+ readonly
97
+ {...editDrawerProps}
98
+ isOpen={isEditDrawerOpen}
99
+ currentAddress={currentAddress}
100
+ />
101
+ )}
102
+ {isOpenLocationDrawer && (
103
+ <LocationDrawer
104
+ readonly
105
+ {...locationDrawerProps}
106
+ isOpen={isOpenLocationDrawer}
107
+ />
108
+ )}
109
+ {isOpenRecipientsDrawer && (
110
+ <RecipientsDrawer
111
+ readonly
112
+ {...recipientDrawerProps}
113
+ isOpen={isOpenRecipientsDrawer}
114
+ />
115
+ )}
116
+ {isOpenRemoveAddressDrawer && (
117
+ <RemoveAddressDrawer
118
+ readonly
119
+ addressName={currentAddress.name}
120
+ addressId={currentAddress.id}
121
+ {...removeAddressDrawerProps}
122
+ isOpen={isOpenRemoveAddressDrawer}
123
+ />
124
+ )}
125
+ {isOpenDeleteAddressDrawer && (
126
+ <DeleteAddressDrawer
127
+ readonly
128
+ addressName={currentAddress.name}
129
+ addressId={currentAddress.id}
130
+ isOpen={isOpenDeleteAddressDrawer}
131
+ {...deleteAddressDrawerProps}
132
+ />
133
+ )}
134
+ </>
135
+ );
136
+ };
@@ -0,0 +1,5 @@
1
+ [data-fs-dropdown-menu][data-fs-bp-basic-dropdown-menu]
2
+ [data-fs-dropdown-item]
3
+ [data-fs-bp-delete-address] {
4
+ color: #d32420 !important;
5
+ }
@@ -0,0 +1,280 @@
1
+ import {
2
+ InputText,
3
+ ErrorMessage,
4
+ AutocompleteDropdown,
5
+ Icon,
6
+ } from "../../../shared/components";
7
+ import { CountryOptions } from "../../data/countries";
8
+ import { states as StateOptions } from "../../data/states";
9
+ import {
10
+ maskPostalCode,
11
+ validatePostalCode,
12
+ } from "../../../shared/utils/postalCode";
13
+ import { AddressData, AddressInput } from "../../types";
14
+ import { useState } from "react";
15
+ import { useDebouncedSearchAddress } from "../../hooks/useDebouncedSearchAddress";
16
+ import { ExistingAddress } from "../";
17
+
18
+ export type AddressFormProps = {
19
+ address: AddressInput;
20
+ isTouched: boolean;
21
+ setAddress: (address: AddressInput) => void;
22
+ setInvalidAddress: (hasError: boolean) => void;
23
+ useExistingAddress?: boolean;
24
+ setUseExistingAddress?: (useExistingAddress: boolean) => void;
25
+ completedAddress?: AddressData;
26
+ setCompletedAddress?: (completedAddress: AddressData) => void;
27
+ isEdit?: boolean;
28
+ };
29
+
30
+ export const AddressForm = ({
31
+ address,
32
+ isTouched,
33
+ setAddress,
34
+ setInvalidAddress,
35
+ isEdit = false,
36
+ useExistingAddress,
37
+ setUseExistingAddress,
38
+ completedAddress,
39
+ setCompletedAddress,
40
+ }: AddressFormProps) => {
41
+ const addressTypeOptions = ["Shipping", "Billing", "Sold To"];
42
+
43
+ const [autoCompleteAddressName, setAutoCompleteAddressName] = useState("");
44
+
45
+ const { searchedAddresses } = useDebouncedSearchAddress(
46
+ autoCompleteAddressName
47
+ );
48
+
49
+ const cleanCompletedAddress = () => {
50
+ if (setCompletedAddress && setUseExistingAddress) {
51
+ setCompletedAddress({} as AddressData);
52
+ setUseExistingAddress(false);
53
+ }
54
+ };
55
+
56
+ const handleChangePostalCode = (postalCode: string) => {
57
+ setAddress({
58
+ ...address,
59
+ zip: maskPostalCode(postalCode, address.countryCode),
60
+ });
61
+ };
62
+
63
+ return (
64
+ <>
65
+ {!useExistingAddress ? (
66
+ <div>
67
+ {!isEdit && <span>Fill in the address details</span>}
68
+
69
+ <AutocompleteDropdown
70
+ data-fs-bp-create-address-country-selector
71
+ label="Country"
72
+ value={address.country}
73
+ options={CountryOptions}
74
+ onConfirmKeyPress={(option) =>
75
+ setAddress({
76
+ ...address,
77
+ country: option.name,
78
+ countryCode: option.id,
79
+ })
80
+ }
81
+ renderOption={(option, index) => (
82
+ <AutocompleteDropdown.Item
83
+ key={option.id}
84
+ closeOnClick={true}
85
+ index={index}
86
+ isSelected={address.country === option.name}
87
+ onClick={() =>
88
+ setAddress({
89
+ ...address,
90
+ country: option.name,
91
+ countryCode: option.id,
92
+ })
93
+ }
94
+ >
95
+ {option?.name}
96
+ {address.country === option?.name && (
97
+ <Icon name="Check" width={12} height={12} />
98
+ )}
99
+ </AutocompleteDropdown.Item>
100
+ )}
101
+ />
102
+
103
+ {isEdit ? (
104
+ <InputText
105
+ label="Address Name"
106
+ value={address.name}
107
+ wrapperProps={{ style: { marginTop: 16 } }}
108
+ hasError={isTouched && !address.name?.trim()}
109
+ onChange={(event) =>
110
+ setAddress({ ...address, name: event.target.value })
111
+ }
112
+ />
113
+ ) : (
114
+ <AutocompleteDropdown
115
+ label="Address Name"
116
+ value={autoCompleteAddressName}
117
+ options={searchedAddresses}
118
+ onChange={(event) => {
119
+ setAutoCompleteAddressName(event.currentTarget.value);
120
+ setAddress({ ...address, name: event.target.value });
121
+ }}
122
+ renderOption={(option, index) => (
123
+ <AutocompleteDropdown.Item
124
+ key={option.id}
125
+ closeOnClick
126
+ index={index}
127
+ isSelected={completedAddress?.id === option?.id}
128
+ onClick={() => {
129
+ if (setCompletedAddress && setUseExistingAddress) {
130
+ setCompletedAddress(option);
131
+ setUseExistingAddress(true);
132
+ }
133
+ }}
134
+ >
135
+ {option?.name}
136
+ <br />
137
+ {option?.streetAddress}
138
+ {completedAddress?.id === option?.id && (
139
+ <Icon name="Check" width={12} height={12} />
140
+ )}
141
+ </AutocompleteDropdown.Item>
142
+ )}
143
+ />
144
+ )}
145
+
146
+ <ErrorMessage
147
+ show={isTouched && !address.name?.trim()}
148
+ message="Address Name is required"
149
+ />
150
+
151
+ <InputText
152
+ label="Street Address"
153
+ value={address.streetAddress}
154
+ wrapperProps={{ style: { marginTop: 16 } }}
155
+ hasError={isTouched && !address.streetAddress?.trim()}
156
+ onChange={(event) =>
157
+ setAddress({ ...address, streetAddress: event.target.value })
158
+ }
159
+ />
160
+
161
+ <ErrorMessage
162
+ show={isTouched && !address.streetAddress?.trim()}
163
+ message="Street Address is required"
164
+ />
165
+
166
+ <InputText
167
+ label="Apt, Suite, Building (optional)"
168
+ value={address.streetAddress2}
169
+ wrapperProps={{ style: { marginTop: 16, marginBottom: 16 } }}
170
+ onChange={(event) =>
171
+ setAddress({ ...address, streetAddress2: event.target.value })
172
+ }
173
+ />
174
+
175
+ <InputText
176
+ label="City"
177
+ value={address.city}
178
+ wrapperProps={{ style: { marginTop: 16 } }}
179
+ hasError={isTouched && !address.city?.trim()}
180
+ onChange={(event) =>
181
+ setAddress({ ...address, city: event.target.value })
182
+ }
183
+ />
184
+
185
+ <AutocompleteDropdown
186
+ data-fs-bp-create-address-state-selector
187
+ label="State"
188
+ value={address.state}
189
+ options={
190
+ address.countryCode ? StateOptions[address.countryCode] : []
191
+ }
192
+ onConfirmKeyPress={(option) =>
193
+ setAddress({ ...address, state: option })
194
+ }
195
+ disabled={!address.countryCode}
196
+ renderOption={(option, index) => (
197
+ <AutocompleteDropdown.Item
198
+ key={`${option}-${index}`}
199
+ closeOnClick={true}
200
+ index={index}
201
+ isSelected={
202
+ address.state.toLocaleLowerCase() ===
203
+ option.toLocaleLowerCase()
204
+ }
205
+ onClick={() => setAddress({ ...address, state: option })}
206
+ >
207
+ {option}
208
+ {address.state.toLowerCase() === option.toLocaleLowerCase() && (
209
+ <Icon name="Check" width={12} height={12} />
210
+ )}
211
+ </AutocompleteDropdown.Item>
212
+ )}
213
+ />
214
+
215
+ <InputText
216
+ label="Postal Code"
217
+ value={address.zip}
218
+ wrapperProps={{ style: { marginTop: 16, marginBottom: 16 } }}
219
+ hasError={isTouched && !address.zip?.trim()}
220
+ onChange={(event) => handleChangePostalCode(event.target.value)}
221
+ disabled={!address.countryCode}
222
+ />
223
+
224
+ <ErrorMessage
225
+ show={isTouched && !address.zip?.trim()}
226
+ message="Postal Code is required"
227
+ />
228
+
229
+ <ErrorMessage
230
+ show={isTouched && !address.city?.trim()}
231
+ message="City is required"
232
+ />
233
+
234
+ {isEdit && (
235
+ <InputText
236
+ label="Geo coordinates (Optional)"
237
+ value={address.geoCordinates}
238
+ wrapperProps={{ style: { marginTop: 16, marginBottom: 16 } }}
239
+ onChange={(event) =>
240
+ setAddress({ ...address, geoCordinates: event.target.value })
241
+ }
242
+ />
243
+ )}
244
+
245
+ <AutocompleteDropdown
246
+ label="Address Type"
247
+ value={address.types}
248
+ options={addressTypeOptions}
249
+ onConfirmKeyPress={(option) =>
250
+ setAddress({ ...address, types: [option] })
251
+ }
252
+ renderOption={(option, index) => (
253
+ <AutocompleteDropdown.Item
254
+ key={`${option}-${index}`}
255
+ closeOnClick={true}
256
+ index={index}
257
+ isSelected={
258
+ address?.types[0]?.toLocaleLowerCase() ===
259
+ option.toLocaleLowerCase()
260
+ }
261
+ onClick={() => setAddress({ ...address, types: [option] })}
262
+ >
263
+ {option}
264
+ {address?.types[0]?.toLowerCase() ===
265
+ option.toLocaleLowerCase() && (
266
+ <Icon name="Check" width={12} height={12} />
267
+ )}
268
+ </AutocompleteDropdown.Item>
269
+ )}
270
+ />
271
+ </div>
272
+ ) : (
273
+ <ExistingAddress
274
+ addressName={completedAddress?.name ?? ""}
275
+ removeExistingAddress={cleanCompletedAddress}
276
+ />
277
+ )}
278
+ </>
279
+ );
280
+ };
@@ -1,12 +1,15 @@
1
- import { Toggle } from "@faststore/ui";
1
+ import { Toggle, Dropdown, DropdownButton } from "@faststore/ui";
2
2
  import Link from "next/link";
3
3
  import { Icon, Tag } from "../../../shared/components";
4
+ import type { AddressData } from "../../types";
5
+ import { AddressDropdownMenu } from "..";
4
6
 
5
7
  export type AddressLineProps = {
6
8
  id: string;
7
9
  name: string;
8
10
  types: string[];
9
11
  isActive: boolean;
12
+ currentAddress: AddressData;
10
13
  href: string;
11
14
  };
12
15
 
@@ -16,6 +19,7 @@ export const AddressLine = ({
16
19
  id,
17
20
  href,
18
21
  isActive,
22
+ currentAddress,
19
23
  }: AddressLineProps) => (
20
24
  <li data-fs-addresses-line>
21
25
  <Link href={href} data-fs-addresses-line-link>
@@ -35,13 +39,11 @@ export const AddressLine = ({
35
39
  </Link>
36
40
 
37
41
  <Toggle id={id} defaultChecked={isActive} />
38
- <button type="button" data-fs-addresses-dropdown-trigger>
39
- <Icon
40
- name="MoreVert"
41
- width={20}
42
- height={20}
43
- data-fs-addresses-dropdown-trigger-icon
44
- />
45
- </button>
42
+ <Dropdown>
43
+ <DropdownButton data-fs-addresses-dropdown-trigger>
44
+ <Icon name="MoreVert" data-fs-addresses-dropdown-trigger-icon />
45
+ </DropdownButton>
46
+ <AddressDropdownMenu currentAddress={currentAddress} />
47
+ </Dropdown>
46
48
  </li>
47
49
  );