blob: f0cd00514cbd000022cf072f63fe6b45465d0bbf [file] [log] [blame]
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -04001/*
2 * Copyright (C) 2022 Savoir-faire Linux Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License as
6 * published by the Free Software Foundation; either version 3 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Affero General Public License for more details.
13 *
14 * You should have received a copy of the GNU Affero General Public
15 * License along with this program. If not, see
16 * <https://www.gnu.org/licenses/>.
17 */
Gabriel Rochon7057b4f2022-11-21 13:28:01 -050018import {
19 Box,
20 Button,
21 FormControl,
22 FormControlLabel,
23 Radio,
24 RadioGroup,
25 Stack,
26 Typography,
27 useMediaQuery,
28} from '@mui/material';
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -040029import { Theme, useTheme } from '@mui/material/styles';
Ziwei Wang9b4e2c12023-02-06 14:45:37 -050030import { HttpStatusCode } from 'jami-web-common';
Ziwei Wang3ce1ac02023-02-03 11:59:03 -050031import { ChangeEvent, FormEvent, ReactNode, useState } from 'react';
Michelle Sepkap Simee580f422022-10-31 23:27:04 -040032import { useTranslation } from 'react-i18next';
Ziwei Wang3ce1ac02023-02-03 11:59:03 -050033import { Form, Link, useNavigate } from 'react-router-dom';
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -040034
Michelle Sepkap Simee580f422022-10-31 23:27:04 -040035import { AlertSnackbar } from '../components/AlertSnackbar';
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -040036import { PasswordInput, UsernameInput } from '../components/Input';
37import ProcessingRequest from '../components/ProcessingRequest';
Ziwei Wang3ce1ac02023-02-03 11:59:03 -050038import withAuthUI from '../components/WithAuthUI';
Michelle Sepkap Simee580f422022-10-31 23:27:04 -040039import { loginUser, setAccessToken } from '../utils/auth';
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -040040import { inputWidth } from '../utils/constants';
Ziwei Wang3ce1ac02023-02-03 11:59:03 -050041function LoginForm() {
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -040042 const theme: Theme = useTheme();
Michelle Sepkap Simee580f422022-10-31 23:27:04 -040043 const navigate = useNavigate();
44 const { t } = useTranslation();
45
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -040046 const [username, setUsername] = useState<string>('');
47 const [password, setPassword] = useState<string>('');
Gabriel Rochon7057b4f2022-11-21 13:28:01 -050048 const [isJams, setIsJams] = useState<boolean>(false);
Ziwei Wang9b4e2c12023-02-06 14:45:37 -050049 const [loading, setLoading] = useState<boolean>(false);
Michelle Sepkap Simee580f422022-10-31 23:27:04 -040050 const [errorAlertContent, setErrorAlertContent] = useState<ReactNode>(undefined);
Ziwei Wang9b4e2c12023-02-06 14:45:37 -050051 const isMobile: boolean = useMediaQuery(theme.breakpoints.only('xs'));
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -040052
53 const handleUsername = (event: ChangeEvent<HTMLInputElement>) => {
54 setUsername(event.target.value);
55 };
56
57 const handlePassword = (event: ChangeEvent<HTMLInputElement>) => {
58 setPassword(event.target.value);
59 };
60
Gabriel Rochon7057b4f2022-11-21 13:28:01 -050061 const handleIsJams = (event: ChangeEvent<HTMLInputElement>) => {
62 setIsJams(event.target.value === 'true');
63 };
64
Ziwei Wang9b4e2c12023-02-06 14:45:37 -050065 const login = async (event: FormEvent) => {
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -040066 event.preventDefault();
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -040067
Ziwei Wang9b4e2c12023-02-06 14:45:37 -050068 if (!(username.length > 0) || !(password.length > 0)) {
69 //TODO: set alert message
70 console.log('Empty Credentials');
71 return;
72 }
73
74 setLoading(true);
75
76 loginUser(username, password, isJams)
77 .then((response) => {
78 if (response.status === HttpStatusCode.Ok) {
79 setAccessToken(response.data.accessToken);
80 navigate('/conversation', { replace: true });
81 }
82 })
83 .catch((e) => {
84 console.log(e);
85 const { status } = e.response;
86 if (status === HttpStatusCode.BadRequest) {
87 //TODO: the only bad request response defined in the server is missing credentials. add the response message to the locale.
88 console.log(e.response.data);
89 // setErrorAlertContent(t('unknown_error_alert'));
90 } else if (status === HttpStatusCode.NotFound) {
91 //TODO: there are two different not found responses that could be returned by the server, use message to differentiate them?
92 console.log(e.response.data);
93 // setErrorAlertContent(t('login_username_not_found'));
94 } else if (status === HttpStatusCode.Unauthorized) {
Michelle Sepkap Simee580f422022-10-31 23:27:04 -040095 setErrorAlertContent(t('login_invalid_password'));
96 } else {
Ziwei Wangce81edd2023-02-03 13:43:22 -050097 setErrorAlertContent(t('unknown_error_alert'));
Michelle Sepkap Simee580f422022-10-31 23:27:04 -040098 }
Ziwei Wang9b4e2c12023-02-06 14:45:37 -050099 })
100 .finally(() => {
101 setLoading(false);
102 });
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -0400103 };
104
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -0400105 return (
106 <>
Ziwei Wang9b4e2c12023-02-06 14:45:37 -0500107 <ProcessingRequest open={loading} />
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -0400108
Michelle Sepkap Simee580f422022-10-31 23:27:04 -0400109 <AlertSnackbar severity={'error'} open={!!errorAlertContent} onClose={() => setErrorAlertContent(undefined)}>
110 {errorAlertContent}
111 </AlertSnackbar>
112
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -0400113 <Stack
114 sx={{
115 minHeight: `${isMobile ? 'auto' : '100%'}`,
116 display: 'flex',
117 alignItems: 'center',
118 justifyContent: 'center',
119 }}
120 >
121 <Box sx={{ mt: theme.typography.pxToRem(50), mb: theme.typography.pxToRem(20) }}>
122 <Typography component={'span'} variant="h2">
Michelle Sepkap Sime559cc802022-11-05 12:06:40 -0400123 {t('login_form_title')}
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -0400124 </Typography>
125 </Box>
126
127 <Form method="post" id="login-form">
128 <div>
129 <UsernameInput
Ziwei Wang9b4e2c12023-02-06 14:45:37 -0500130 value={username}
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -0400131 onChange={handleUsername}
Michelle Sepkap Sime559cc802022-11-05 12:06:40 -0400132 tooltipTitle={t('login_form_username_tooltip')}
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -0400133 sx={{ width: theme.typography.pxToRem(inputWidth) }}
134 />
135 </div>
136 <div>
137 <PasswordInput
Ziwei Wang9b4e2c12023-02-06 14:45:37 -0500138 value={password}
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -0400139 onChange={handlePassword}
Michelle Sepkap Sime559cc802022-11-05 12:06:40 -0400140 tooltipTitle={t('login_form_password_tooltip')}
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -0400141 sx={{ width: theme.typography.pxToRem(inputWidth) }}
142 />
143 </div>
Gabriel Rochon7057b4f2022-11-21 13:28:01 -0500144 <div>
145 <FormControl
146 sx={{
147 width: theme.typography.pxToRem(inputWidth),
148 alignItems: 'center',
149 justifyContent: 'space-between',
150 }}
151 >
152 <RadioGroup row onChange={handleIsJams} value={isJams}>
153 <FormControlLabel value="false" control={<Radio />} label={t('jami')} />
154 <FormControlLabel value="true" control={<Radio />} label={t('jams')} />
155 </RadioGroup>
156 </FormControl>
157 </div>
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -0400158
159 <Button
160 variant="contained"
161 type="submit"
Ziwei Wang9b4e2c12023-02-06 14:45:37 -0500162 onClick={login}
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -0400163 sx={{ width: theme.typography.pxToRem(inputWidth), mt: theme.typography.pxToRem(20) }}
164 >
Michelle Sepkap Sime559cc802022-11-05 12:06:40 -0400165 {t('login_form_submit_button')}
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -0400166 </Button>
167 </Form>
168
169 <Box sx={{ mt: theme.typography.pxToRem(50), mb: theme.typography.pxToRem(50) }}>
170 <Typography variant="body1">
Michelle Sepkap Sime559cc802022-11-05 12:06:40 -0400171 {t('login_form_to_registration_text')} &nbsp;
Ziwei Wang3ce1ac02023-02-03 11:59:03 -0500172 <Link to={'/register'}>{t('login_form_to_registration_link')}</Link>
Michelle Sepkap Sime51c00452022-10-31 21:26:38 -0400173 </Typography>
174 </Box>
175 </Stack>
176 </>
177 );
178}
Ziwei Wang3ce1ac02023-02-03 11:59:03 -0500179
180export default withAuthUI(LoginForm);