Update login styles

This commit is contained in:
jeffvli
2022-11-17 02:51:58 -08:00
parent 2a6167441a
commit fe678b546e
@@ -1,62 +1,66 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { import { Stack, Alert, Box, Center, Group } from '@mantine/core';
TextInput, import { ErrorBoundary } from 'react-error-boundary';
PasswordInput,
Button,
Stack,
Title,
Loader,
Alert,
Box,
} from '@mantine/core';
import { useDebouncedValue } from '@mantine/hooks';
import { useTranslation } from 'react-i18next';
import { RiCheckboxCircleFill } from 'react-icons/ri';
import { useSearchParams } from 'react-router-dom'; import { useSearchParams } from 'react-router-dom';
import styled from 'styled-components'; import styled from 'styled-components';
import { Button, PasswordInput, Text, TextInput } from '@/renderer/components';
import { ErrorFallback } from '@/renderer/features/action-required';
import { useLogin } from '@/renderer/features/auth/queries/use-login'; import { useLogin } from '@/renderer/features/auth/queries/use-login';
import { usePingServer } from '@/renderer/features/auth/queries/use-ping-server';
import { normalizeServerUrl } from '@/renderer/utils'; import { normalizeServerUrl } from '@/renderer/utils';
const Container = styled(Box)` const Container = styled(Box)`
min-width: 400px; width: 100%;
max-width: 50%; background: var(--main-bg);
margin: auto;
padding: 3rem;
background: rgba(50, 50, 50, 40%);
border-radius: 5px;
`; `;
export const LoginRoute = () => { export const LoginRoute = () => {
const { t } = useTranslation();
const [searchParams] = useSearchParams(); const [searchParams] = useSearchParams();
const [errorMessage, setErrorMessage] = useState('');
const [username, setUsername] = useState(searchParams.get('username') || ''); const [username, setUsername] = useState(searchParams.get('username') || '');
const [password, setPassword] = useState(searchParams.get('password') || ''); const [password, setPassword] = useState(searchParams.get('password') || '');
const [server, setServer] = useState( const [server, setServer] = useState(
searchParams.get('server') || 'http://localhost:8843' searchParams.get('server') || 'http://localhost:8843'
); );
const [debouncedServer] = useDebouncedValue(server, 500);
const { const {
mutate: handleLogin, mutate: handleLogin,
isLoading, isLoading,
isError, isError,
} = useLogin(normalizeServerUrl(server), { } = useLogin(
normalizeServerUrl(server),
{
password, password,
username, username,
}); },
{
const { onError: (error) => {
isLoading: isCheckingServer, setErrorMessage(error?.response?.data?.error || error.message);
isSuccess: isValidServer, },
isFetched, }
} = usePingServer(normalizeServerUrl(debouncedServer)); );
return ( return (
<Container> <Container>
<Title>{t('auth.login')}</Title> <Center sx={{ height: '100%' }}>
<Stack
spacing={0}
sx={{
filter: 'drop-shadow(0 0 5px var(--generic-border-color))',
height: '50%',
maxWidth: '800px',
minWidth: '500px',
width: '40vw',
}}
>
<ErrorBoundary FallbackComponent={ErrorFallback}>
<Group position="center">
<form <form
style={{
display: 'flex',
justifyContent: 'center',
width: '100%',
}}
onSubmit={(e) => { onSubmit={(e) => {
e.preventDefault(); e.preventDefault();
handleLogin(undefined, { handleLogin(undefined, {
@@ -65,58 +69,62 @@ export const LoginRoute = () => {
}); });
}} }}
> >
<Stack spacing="md"> <Stack
p="2rem"
spacing="xl"
sx={{
background: 'var(--main-bg)',
borderRadius: '5px',
width: '80%',
}}
>
<Text
gradient={{ deg: 45, from: 'indigo', to: 'cyan' }}
size="xl"
variant="gradient"
>
Login to Feishin
</Text>
<TextInput <TextInput
required
disabled={isLoading} disabled={isLoading}
error={!isValidServer && isFetched} label="Server URL"
label={t('auth.server.label')} placeholder="http://localhost:8843"
placeholder={t('auth.server.placeholder')}
rightSection={
isCheckingServer ? (
<Loader size="xs" />
) : isValidServer ? (
<RiCheckboxCircleFill size={20} />
) : null
}
value={server} value={server}
variant="default"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setServer(e.currentTarget.value) setServer(e.currentTarget.value)
} }
/> />
<TextInput <TextInput
required
disabled={isLoading} disabled={isLoading}
label={`${t('auth.username.label')}`} label="Username"
placeholder={`${t('auth.username.placeholder')}`}
value={username} value={username}
variant="default"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setUsername(e.currentTarget.value) setUsername(e.currentTarget.value)
} }
/> />
<PasswordInput <PasswordInput
required
disabled={isLoading} disabled={isLoading}
label={`${t('auth.password.label')}`} label="Password"
placeholder={`${t('auth.password.placeholder')}`}
value={password} value={password}
variant="default"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setPassword(e.currentTarget.value) setPassword(e.currentTarget.value)
} }
/> />
<Button disabled={!isValidServer} type="submit"> <Button
disabled={!username || !password}
loading={isLoading}
radius="xl"
type="submit"
>
Login Login
</Button> </Button>
{isError && ( {isError && <Alert color="red">{errorMessage}</Alert>}
<Alert color="red" variant="outline">
{t('Invalid username or password.')}
</Alert>
)}
</Stack> </Stack>
</form> </form>
</Group>
</ErrorBoundary>
</Stack>
</Center>
</Container> </Container>
); );
}; };