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