Skip to content

Commit b7c45ea

Browse files
Account page. Address Book page (#37)
* create account page * update side menu and profile page * Created Address Book page * Update AddressForm component * add customer update function * Added Address form * update profile page and side menu * Added Address delete modal * Create DeleteAddressDialog component. Update Address component * Small fixes in AddressForm and routes Co-authored-by: yulia-dnistrian <yulia.dnist@gmail.com>
1 parent 5051709 commit b7c45ea

22 files changed

+1336
-18
lines changed

src/AccountDropdown.tsx

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11

22
import React, { useState} from 'react';
3-
// import { Link } from 'react-router-dom';
3+
import {Link, useHistory} from 'react-router-dom';
44
import useOnclickOutside from 'react-cool-onclickoutside';
55
import { useCustomerData, useTranslation } from './app-state';
6+
import { createAccountUrl } from './routes';
67
import { LoginDialog } from './LoginDialog';
78
import { ReactComponent as AccountIcon } from './images/icons/ic_account.svg';
89

@@ -11,12 +12,19 @@ import './AccountDropdown.scss';
1112
export const AccountDropdown: React.FC = (props) => {
1213
const { isLoggedIn, customerEmail, customerName, clearCustomerData } = useCustomerData();
1314
const { t } = useTranslation();
15+
const history = useHistory();
1416

1517
const [isOpen, setIsOpen] = useState(false);
1618
const [isModalOpen, setIsModalOpen] = useState(false);
1719

20+
const accountUrl = createAccountUrl();
21+
22+
const handleHideDropdown = () => {
23+
setIsOpen(false);
24+
};
25+
1826
const handleSelectorClicked = () => {
19-
setIsOpen(true);
27+
setIsOpen(!isOpen);
2028
};
2129

2230
const ref = useOnclickOutside(() => {
@@ -25,27 +33,28 @@ export const AccountDropdown: React.FC = (props) => {
2533

2634
const logout = () => {
2735
clearCustomerData();
36+
history.push('/');
2837
};
2938

3039
if (isLoggedIn) {
3140
return (
3241
<div className="accountdropdown">
33-
<div className={`accountdropdown__dropdown ${isOpen ? 'accountdropdown__open' : ''}`}>
42+
<div className={`accountdropdown__dropdown ${isOpen ? 'accountdropdown__open' : ''}`} ref={ref}>
3443
<button className="accountdropdown__btn" type="button" aria-label="toggle profile menu" onClick={handleSelectorClicked}>
3544
<AccountIcon className="accountdropdown__btnicon" />
3645
</button>
3746
{isOpen && (
38-
<div className="accountdropdown__menu" ref={ref}>
47+
<div className="accountdropdown__menu">
3948
<ul className="accountdropdown__list">
4049
<li className="accountdropdown__listitem accountdropdown__itemtitle">
4150
<p className="accountdropdown__iteminfo">{customerName}</p>
4251
<p className="accountdropdown__iteminfo accountdropdown__emailinfo">{customerEmail}</p>
4352
</li>
44-
{/*<li className="accountdropdown__listitem">*/}
45-
{/* <Link to="/profile" className="accountdropdown__link">*/}
46-
{/* My Account*/}
47-
{/* </Link>*/}
48-
{/*</li>*/}
53+
<li className="accountdropdown__listitem">
54+
<Link to={accountUrl} className="accountdropdown__link" onClick={handleHideDropdown}>
55+
{t('my-account')}
56+
</Link>
57+
</li>
4958
<li className="accountdropdown__listitem accountdropdown__itembtns">
5059
<button className="epbtn --primary --fullwidth" type="button" onClick={logout}>
5160
{t('logout')}

src/Address.scss

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
@import './theme/common';
2+
3+
.address {
4+
position: relative;
5+
6+
&__title {
7+
font-size: 24px;
8+
font-weight: bold;
9+
}
10+
11+
&__maincontainer {
12+
position: relative;
13+
border: 1px solid $firstBorderColor;
14+
display: flex;
15+
flex-wrap: wrap;
16+
padding: 30px 30px 100px 30px;
17+
margin-top: 40px;
18+
}
19+
20+
&__container {
21+
width: 50%;
22+
margin-bottom: 20px;
23+
@media (max-width: 767px) {
24+
width: 100%;
25+
}
26+
}
27+
28+
&__button {
29+
color: $firstComplimentColor;
30+
height: 16px;
31+
32+
&:hover {
33+
text-decoration: underline;
34+
cursor: pointer;
35+
}
36+
37+
&.--edit {
38+
padding-right: 10px;
39+
margin-right: 10px;
40+
border-right: 2px solid $secondBorderColor;
41+
}
42+
}
43+
44+
&__list {
45+
padding: 5px 0;
46+
}
47+
48+
&__addnewaddress {
49+
position: absolute;
50+
bottom: 30px;
51+
left: 30px;
52+
width: 260px;
53+
height: 44px;
54+
text-align: center;
55+
border: 1px solid transparent;
56+
color: $mainBackgroundColor;
57+
background-color: $firstComplimentColor;
58+
59+
&.--noaddresses {
60+
position: relative;
61+
bottom: 0;
62+
left: 0;
63+
margin-top: 10px;
64+
}
65+
66+
&:hover {
67+
cursor: pointer;
68+
}
69+
}
70+
}

src/Address.tsx

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import React, { useState } from 'react';
2+
import { useAddressData } from './app-state';
3+
import { Address as IAddress, deleteAddress } from './service';
4+
import { useTranslation } from './app-state';
5+
import { AddressForm } from './AddressForm';
6+
import { DeleteAddressDialog } from './DeleteAddressDialog';
7+
8+
import './Address.scss';
9+
10+
export const Address: React.FC = () => {
11+
const { t } = useTranslation();
12+
const [isModalOpen, setIsModalOpen] = useState(false);
13+
const [selectedAddress, setSelectedAddress] = useState({});
14+
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
15+
const [selectedDeleteAddress, setSelectedDeleteAddress] = useState('');
16+
const [isLoading, setIsLoading] = useState(false);
17+
const { addressData, updateAddresses } = useAddressData();
18+
19+
const handleDelete = (addressId: string) => {
20+
setIsDeleteModalOpen(true);
21+
setSelectedDeleteAddress(addressId);
22+
};
23+
24+
const handleCancelDelete = () => {
25+
setIsDeleteModalOpen(false);
26+
setSelectedDeleteAddress('');
27+
};
28+
29+
const onDeleteAddress = () => {
30+
const token = localStorage.getItem('mtoken') || '';
31+
const customer = localStorage.getItem('mcustomer') || '';
32+
setIsLoading(true);
33+
34+
deleteAddress(customer, selectedDeleteAddress, token)
35+
.then(() => {
36+
updateAddresses();
37+
setIsLoading(false);
38+
setIsDeleteModalOpen(false);
39+
})
40+
.catch(error => {
41+
setIsLoading(false);
42+
setIsDeleteModalOpen(false);
43+
console.error(error);
44+
});
45+
};
46+
47+
const handleEdit = (address: any) => {
48+
setSelectedAddress(address);
49+
setIsModalOpen(!isModalOpen);
50+
};
51+
52+
const handleAddNewAddress = () => {
53+
setSelectedAddress({});
54+
setIsModalOpen(!isModalOpen);
55+
};
56+
57+
const handleModalClose = () => {
58+
setSelectedAddress({});
59+
setIsModalOpen(false);
60+
};
61+
62+
return (
63+
<div className="address">
64+
<h1 className="address__title">{t("address-book")}</h1>
65+
{addressData && addressData.length > 0 ? (
66+
<div className="address__maincontainer">
67+
{addressData.map((address: IAddress) => (
68+
<div className="address__container" key={address.id}>
69+
<ul className="address__list">
70+
<li className="">
71+
{address.first_name}
72+
&nbsp;
73+
{address.last_name}
74+
</li>
75+
<li className="">
76+
{address.line_1}
77+
</li>
78+
<li className="">
79+
{address.line_2}
80+
</li>
81+
<li>
82+
<span className="">
83+
{address.county}
84+
,&nbsp;
85+
</span>
86+
<span className="">
87+
{(address.country)
88+
? (
89+
`${address.country}, `
90+
) : ('')}
91+
</span>
92+
<span className="">
93+
{address.city}
94+
&nbsp;
95+
</span>
96+
</li>
97+
<li className="">
98+
{address.postcode}
99+
</li>
100+
</ul>
101+
<button type="button" className="address__button --edit" onClick={() => handleEdit(address)}>
102+
{t('edit')}
103+
</button>
104+
<button type="button" className="address__button --delete" onClick={() => handleDelete(address.id)}>
105+
{t('delete')}
106+
</button>
107+
</div>
108+
))}
109+
<button className="address__addnewaddress" onClick={handleAddNewAddress}>{t('add-new-address')}</button>
110+
</div>
111+
) : (
112+
<div>
113+
<div>
114+
{t('no-addresses')}
115+
</div>
116+
<button className="address__addnewaddress --noaddresses" onClick={handleAddNewAddress} >{t('add-new-address')}</button>
117+
</div>
118+
)}
119+
{isModalOpen && (
120+
<AddressForm isModalOpen={isModalOpen} handleModalClose={handleModalClose} addressData={selectedAddress} />
121+
)}
122+
{isDeleteModalOpen && (
123+
<DeleteAddressDialog isDeleteModalOpen={isDeleteModalOpen} handleCancelDelete={handleCancelDelete} onDeleteAddress={onDeleteAddress} isLoading={isLoading} />
124+
)}
125+
</div>
126+
)
127+
};

src/AddressForm.scss

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
@import './theme/common';
2+
3+
.addressform {
4+
max-width: 600px;
5+
margin: auto;
6+
7+
&__header {
8+
display: flex;
9+
justify-content: space-between;
10+
align-items: center;
11+
padding: 5px 5px 10px;
12+
border-bottom: 1px solid $firstBorderColor;
13+
}
14+
15+
&__title {
16+
font-size: 15px;
17+
}
18+
19+
&__content {
20+
background-color: $mainBackgroundColor;
21+
border: none;
22+
23+
&.--loading {
24+
25+
&:before {
26+
content: '';
27+
height: 100%;
28+
width: 100%;
29+
position: absolute;
30+
top: 0;
31+
left: 0;
32+
background-color: $mainBackgroundColor;
33+
opacity: 0.5;
34+
z-index: 1;
35+
}
36+
}
37+
}
38+
39+
&__body {
40+
position: relative;
41+
padding: 25px 5px 5px;
42+
}
43+
44+
&__feedback {
45+
top: 0;
46+
left: 0;
47+
margin-bottom: 15px;
48+
font-weight: bold;
49+
color: $mainErrorColor;
50+
}
51+
52+
.epbtn {
53+
width: 100px;
54+
}
55+
56+
.epbtn + .epbtn {
57+
margin-left: 10px;
58+
}
59+
60+
.required-label {
61+
color: red;
62+
}
63+
64+
.epform {
65+
&.--addressform {
66+
display: flex;
67+
flex-wrap: wrap;
68+
}
69+
70+
&__label {
71+
text-transform: capitalize;
72+
}
73+
74+
&__group {
75+
width: 50%;
76+
padding-right: 25px;
77+
78+
&.--btncontainer {
79+
width: 100%;
80+
text-align: right;
81+
}
82+
}
83+
}
84+
85+
.logindialog {
86+
&__feedback {
87+
position: relative;
88+
margin-bottom: 10px;
89+
}
90+
}
91+
}
92+
93+
@media (max-width: $mobileWidth - 1) {
94+
.logindialog {
95+
height: 100%;
96+
min-width: 100%;
97+
}
98+
}
99+
100+
@media (max-width: 575px) {
101+
.addressform {
102+
.epform {
103+
&__group {
104+
width: 100%;
105+
}
106+
}
107+
}
108+
}
109+
110+

0 commit comments

Comments
 (0)