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