frontend/containers/Profile/index.js (view raw)
1import {useState} from 'react';
2import Card from '@material-ui/core/Card';
3import CardContent from '@material-ui/core/CardContent';
4import CardActions from '@material-ui/core/CardActions';
5import Button from '@material-ui/core/Button';
6import {makeStyles} from '@material-ui/core';
7import {useTranslation} from 'react-i18next';
8import EditPassword from './EditPassword';
9import ProfileField from './ProfileField';
10import useToastStore from '../../stores/useToastStore';
11import useBannerStore from '../../stores/useBannerStore';
12
13const Profile = ({profile, updateProfile, logout}) => {
14 const {t} = useTranslation();
15 const addToast = useToastStore(s => s.addToast);
16 const bannerHeight = useBannerStore(s => s.height);
17 const classes = useStyles({bannerHeight});
18 const [isEditing, setIsEditing] = useState(false);
19 const [isEditingPassword, setIsEditingPassword] = useState(false);
20 const [firstName, setFirstName] = useState(profile.firstName);
21 const [lastName, setLastName] = useState(profile.lastName);
22 const [email, setEmail] = useState(profile.email);
23 const [oldPassword, setOldPassword] = useState('');
24 const [newPassword, setNewPassword] = useState('');
25 const [errorPassword, setErrorPassword] = useState('');
26
27 const resetPassword = () => {
28 setIsEditingPassword(false);
29 setNewPassword('');
30 setOldPassword('');
31 setErrorPassword('');
32 };
33
34 const savePassword = async () => {
35 try {
36 await updateProfile({
37 old_password: oldPassword,
38 password: newPassword,
39 });
40 addToast(t('profile.password_changed'));
41 resetPassword();
42 } catch (err) {
43 if (err.message === 'Auth.form.error.password.matching') {
44 setErrorPassword(t('profile.errors.password_nomatch'));
45 return;
46 }
47 }
48 };
49
50 const onSave = async () => {
51 try {
52 await updateProfile({firstName, lastName, email});
53 setIsEditing(false);
54 } catch (error) {
55 console.error(error);
56 }
57 };
58
59 if (isEditingPassword)
60 return (
61 <EditPassword
62 oldPassword={oldPassword}
63 newPassword={newPassword}
64 setOldPassword={setOldPassword}
65 setNewPassword={setNewPassword}
66 error={errorPassword}
67 save={savePassword}
68 cancel={resetPassword}
69 />
70 );
71
72 return (
73 <form>
74 <Card className={classes.container}>
75 <CardContent>
76 <ProfileField
77 name="firstName"
78 value={firstName}
79 label={t('profile.firstName')}
80 defaultValue={t('profile.not_defined', {
81 field: '$t(profile.firstName)',
82 })}
83 onChange={setFirstName}
84 isEditing={isEditing}
85 />
86 <ProfileField
87 name="lastName"
88 value={lastName}
89 label={t('profile.lastName')}
90 defaultValue={t('profile.not_defined', {
91 field: '$t(profile.lastName)',
92 })}
93 onChange={setLastName}
94 isEditing={isEditing}
95 />
96 <ProfileField
97 name="email"
98 value={email}
99 label={t('profile.email')}
100 defaultValue={t('profile.not_defined', {
101 field: '$t(profile.email)',
102 })}
103 onChange={setEmail}
104 isEditing={isEditing}
105 />
106 </CardContent>
107 <CardActions className={classes.actions}>
108 {!isEditing && (
109 <>
110 <Button type="button" onClick={() => logout()}>
111 {t('profile.actions.logout')}
112 </Button>
113 <Button
114 type="button"
115 color="primary"
116 onClick={() => setIsEditing(true)}
117 variant="contained"
118 >
119 {t('profile.actions.edit')}
120 </Button>
121 </>
122 )}
123 {isEditing && (
124 <>
125 <Button
126 type="button"
127 onClick={evt => {
128 if (evt.preventDefault) evt.preventDefault();
129 setIsEditingPassword(true);
130 }}
131 >
132 {t('profile.actions.change_password')}
133 </Button>
134 <Button
135 type="submit"
136 color="primary"
137 onClick={onSave}
138 variant="contained"
139 >
140 {t('profile.actions.save')}
141 </Button>
142 </>
143 )}
144 </CardActions>
145 </Card>
146 </form>
147 );
148};
149
150const useStyles = makeStyles(theme => ({
151 container: ({bannerHeight}) => ({
152 marginTop: bannerHeight + theme.mixins.toolbar.minHeight,
153 }),
154 actions: {
155 marginTop: theme.spacing(2),
156 justifyContent: 'flex-end',
157 },
158}));
159
160export default Profile;