all repos — caroster @ 8a4f9e069b406ad3b9c2405dbef767b2a5304477

[Octree] Group carpool to your event https://caroster.io

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 {useTranslation} from 'next-i18next';
  8import EditPassword from './EditPassword';
  9import ProfileField from './ProfileField';
 10import useToastStore from '../../stores/useToastStore';
 11import {
 12  UsersPermissionsUser,
 13  useUpdateMeMutation,
 14} from '../../generated/graphql';
 15import ManagingNotificationsField from './ManagingNotificationsField';
 16import StripeDashboardLink from './StripeDashboardLink';
 17import {Box, Divider} from '@mui/material';
 18import theme from '../../theme';
 19
 20interface Props {
 21  profile: UsersPermissionsUser;
 22  logout: () => void;
 23}
 24
 25const Profile = ({profile, logout}: Props) => {
 26  const {t} = useTranslation();
 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          <Box>
119            <ProfileField
120              name="firstName"
121              value={firstName}
122              label={t('profile.firstName')}
123              defaultValue={t('profile.not_defined', {
124                field: '$t(profile.firstName)',
125              })}
126              onChange={setFirstName}
127              isEditing={isEditing}
128            />
129            <ProfileField
130              name="lastName"
131              value={lastName}
132              label={t('profile.lastName')}
133              defaultValue={t('profile.not_defined', {
134                field: '$t(profile.lastName)',
135              })}
136              onChange={setLastName}
137              isEditing={isEditing}
138            />
139            <ProfileField
140              name="email"
141              value={email}
142              label={t('profile.email')}
143              defaultValue={t('profile.not_defined', {
144                field: '$t(profile.email)',
145              })}
146              onChange={setEmail}
147              isEditing={isEditing}
148              disabled={!isStrapiUser}
149            />
150          </Box>
151        </CardContent>
152        <Divider />
153        <Box my={4}>
154          <ManagingNotificationsField
155            isEditing={isEditing}
156            notificationChecked={notificationEnabled}
157            newsletterChecked={newsletterConsent}
158            toggleNotification={toggleNotification}
159            toggleNewsletter={toggleNewsletter}
160          />
161          <StripeDashboardLink />
162        </Box>
163        <Divider />
164        <CardActions sx={{justifyContent: 'flex-end'}}>
165          {!isEditing && (
166            <>
167              <Button type="button" onClick={logout}>
168                {t('profile.actions.logout')}
169              </Button>
170              <Button
171                type="button"
172                color="primary"
173                onClick={() => setIsEditing(true)}
174                variant="contained"
175              >
176                {t('profile.actions.edit')}
177              </Button>
178            </>
179          )}
180          {isEditing && isStrapiUser && (
181            <Button
182              type="button"
183              onClick={evt => {
184                if (evt.preventDefault) evt.preventDefault();
185                setIsEditingPassword(true);
186              }}
187            >
188              {t('profile.actions.change_password')}
189            </Button>
190          )}
191          {isEditing && (
192            <Button
193              type="submit"
194              color="primary"
195              onClick={onSave}
196              variant="contained"
197            >
198              {t('profile.actions.save')}
199            </Button>
200          )}
201        </CardActions>
202      </Card>
203    </Container>
204  );
205};
206
207export default Profile;