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