@vtex/faststore-plugin-buyer-portal 1.0.35 → 1.0.36
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.
- package/package.json +1 -1
- package/public/buyer-portal-icons.svg +22 -1
- package/src/features/addresses/clients/AddressesClient.ts +86 -2
- package/src/features/addresses/clients/PostalCodeClient.ts +19 -0
- package/src/features/addresses/components/AddressDropdownMenu/AddressDropdownMenu.tsx +136 -0
- package/src/features/addresses/components/AddressDropdownMenu/address-dropdown-menu.scss +5 -0
- package/src/features/addresses/components/AddressForm/AddressForm.tsx +280 -0
- package/src/features/addresses/components/AddressLine/AddressLine.tsx +11 -9
- package/src/features/addresses/components/CreateAddressDrawer/CreateAddressDrawer.tsx +187 -0
- package/src/features/addresses/components/CreateAddressDrawer/create-address-drawer.scss +56 -0
- package/src/features/addresses/components/DeleteAddressDrawer/DeleteAddressDrawer.tsx +99 -0
- package/src/features/addresses/components/EditAddressDrawer/EditAddreessDrawer.tsx +100 -0
- package/src/features/addresses/components/EditAddressDrawer/edit-address-drawer.scss +29 -0
- package/src/features/addresses/components/ExistingAddress/ExistingAddress.tsx +35 -0
- package/src/features/addresses/components/ExistingAddress/existing-address.scss +23 -0
- package/src/features/addresses/components/LocationForm/LocationForm.tsx +52 -0
- package/src/features/addresses/components/LocationForm/location-form.scss +29 -0
- package/src/features/addresses/components/LocationsDrawer/LocationsDrawer.tsx +38 -0
- package/src/features/addresses/components/RecipientsDrawer/RecipientsDrawer.tsx +39 -0
- package/src/features/addresses/components/RecipientsForm/RecipientsForm.tsx +73 -0
- package/src/features/addresses/components/RecipientsForm/recipients-form.scss +29 -0
- package/src/features/addresses/components/RemoveAddressDrawer/RemoveAddressDrawer.tsx +80 -0
- package/src/features/addresses/components/RemoveAddressDrawer/remove-address-drawer.scss +15 -0
- package/src/features/addresses/components/index.ts +11 -0
- package/src/features/addresses/data/BRA.ts +29 -0
- package/src/features/addresses/data/CAN.ts +15 -0
- package/src/features/addresses/data/MEX.ts +34 -0
- package/src/features/addresses/data/USA.ts +65 -0
- package/src/features/addresses/data/countries.ts +6 -0
- package/src/features/addresses/data/states.ts +12 -0
- package/src/features/addresses/hooks/index.ts +3 -0
- package/src/features/addresses/hooks/useCreateAddress.ts +28 -0
- package/src/features/addresses/hooks/useDebouncedSearchAddress.ts +20 -0
- package/src/features/addresses/hooks/useDeleteAddress.ts +25 -0
- package/src/features/addresses/hooks/useEditAddress.ts +25 -0
- package/src/features/addresses/hooks/useSearchAddress.ts +20 -0
- package/src/features/addresses/layouts/AddressDetailsLayout/AddressDetailsLayout.tsx +55 -65
- package/src/features/addresses/layouts/AddressDetailsLayout/address-details-layout.scss +46 -15
- package/src/features/addresses/layouts/AddressesLayout/AddressesLayout.tsx +12 -5
- package/src/features/addresses/layouts/AddressesLayout/addresses-layout.scss +3 -0
- package/src/features/addresses/services/auto-complete-address.service.ts +16 -0
- package/src/features/addresses/services/create-new-address.service.ts +14 -0
- package/src/features/addresses/services/delete-address.service.ts +16 -0
- package/src/features/addresses/services/edit-address.service.ts +17 -0
- package/src/features/addresses/services/get-address-details.service.ts +15 -5
- package/src/features/addresses/services/get-addresses.service.ts +3 -3
- package/src/features/addresses/services/index.ts +20 -0
- package/src/features/addresses/services/search-address-by-name.service.ts +30 -0
- package/src/features/addresses/types/AddressData.ts +40 -4
- package/src/features/addresses/types/index.ts +7 -1
- package/src/features/shared/clients/ScopeClient.ts +37 -0
- package/src/features/shared/components/AutocompleteDropdown/autocomplete-dropdown.scss +0 -1
- package/src/features/shared/hooks/index.ts +2 -0
- package/src/features/shared/hooks/useAddToScope.ts +21 -0
- package/src/features/shared/hooks/useRemoveFromScope.ts +24 -0
- package/src/features/shared/services/add-to-scope.service.ts +21 -0
- package/src/features/shared/services/index.ts +8 -0
- package/src/features/shared/services/remove-from-scope.service.ts +21 -0
- package/src/features/shared/types/ScopeInput.d.ts +4 -0
- package/src/features/shared/types/index.ts +1 -0
- package/src/features/shared/utils/addresLabelToPropMapping.ts +7 -7
- package/src/features/shared/utils/api.ts +4 -0
- package/src/features/shared/utils/constants.ts +1 -1
- package/src/features/shared/utils/index.ts +1 -1
- package/src/features/shared/utils/mask.ts +51 -0
- package/src/features/shared/utils/postalCode.ts +79 -0
- package/src/pages/address-details.tsx +9 -2
- package/src/pages/addresses.tsx +2 -2
package/package.json
CHANGED
|
@@ -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
|
-
|
|
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<
|
|
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,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
|
-
<
|
|
39
|
-
<
|
|
40
|
-
name="MoreVert"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
);
|