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