Add new login page design

This commit is contained in:
Manuel
2023-08-11 21:44:33 +02:00
parent 74bf117fe3
commit 9ae2dc3037
5 changed files with 148 additions and 34 deletions

View File

@@ -0,0 +1,54 @@
import { Box, createStyles, useMantineTheme } from '@mantine/core';
import { useMouse, useViewportSize } from '@mantine/hooks';
import { PolkaElement } from './PolkaElement';
export const FloatingBackground = () => {
const { classes } = useStyles();
return (
<Box className={classes.noOverflow} pos="absolute" w="100%" h="100%" top={0} left={0}>
<MouseBackdrop />
<Box pos="relative" h="100%">
<PolkaElement rotation={95} top={0} left={100} />
<PolkaElement rotation={10} top={50} right={20} />
<PolkaElement rotation={-4} bottom={20} left={20} />
</Box>
</Box>
);
};
const MouseBackdrop = () => {
const { x, y } = useMouse();
const { width, height } = useViewportSize();
const smaller = Math.min(width, height);
const radius = Math.max(smaller - 500, 200);
return (
<Box pos="absolute" top={0} left={0} w="100%" h="100%">
<Box
sx={(theme) => {
const dropColor =
theme.colorScheme === 'dark'
? theme.fn.rgba(theme.colors.red[8], 0.05)
: theme.fn.rgba(theme.colors.red[2], 0.4);
const boxShadow = `0px 0px ${radius}px ${radius}px ${dropColor}`;
return {
width: 50,
height: 50,
borderRadius: '5rem',
boxShadow: boxShadow,
backgroundColor: dropColor,
};
}}
top={y - 25}
left={x - 25}
pos="absolute"
></Box>
</Box>
);
};
const useStyles = createStyles(() => ({
noOverflow: {
overflow: 'hidden',
},
}));

View File

@@ -0,0 +1,32 @@
import { Box } from '@mantine/core';
export const PolkaElement = ({
rotation,
left,
top,
right,
bottom,
}: {
rotation: number;
top?: number;
left?: number;
right?: number;
bottom?: number;
}) => {
return (
<Box
style={{
transform: `rotate(${rotation}deg)`,
pointerEvents: 'none'
}}
className="polka"
pos="absolute"
w="20%"
h="40%"
top={top}
right={right}
left={left}
bottom={bottom}
/>
);
};

View File

@@ -113,6 +113,7 @@ function App(
}}
withGlobalStyles
withNormalizeCSS
withCSSVariables
>
<ConfigProvider {...props.pageProps}>
<Notifications limit={4} position="bottom-left" />

View File

@@ -15,9 +15,11 @@ import { GetServerSideProps } from 'next';
import { signIn } from 'next-auth/react';
import { useTranslation } from 'next-i18next';
import Head from 'next/head';
import Image from 'next/image';
import { useRouter } from 'next/router';
import { useState } from 'react';
import { z } from 'zod';
import { FloatingBackground } from '~/components/layout/Background/FloatingBackground';
import { getServerAuthSession } from '~/server/auth';
import { getServerSideTranslations } from '~/tools/server/getServerSideTranslations';
import { useI18nZodResolver } from '~/utils/i18n-zod-resolver';
@@ -63,45 +65,62 @@ export default function LoginPage() {
</Head>
<Flex h="100dvh" display="flex" w="100%" direction="column" align="center" justify="center">
<Card withBorder shadow="md" p="xl" radius="md" w="90%" maw={420}>
<Title align="center" weight={900}>
{t('title')}
</Title>
<FloatingBackground />
<Stack spacing={40} align="center" w="100%">
<Stack spacing={0} align="center">
<Image src="/imgs/logo/logo.svg" width={80} height={80} alt="" />
<Text
sx={(theme) => ({
color: theme.colorScheme === 'dark' ? theme.colors.gray[5] : theme.colors.dark[6],
fontSize: '4rem',
fontWeight: 800,
lineHeight: 1,
})}
align="center"
>
Homarr
</Text>
</Stack>
<Card withBorder shadow="md" p="xl" radius="md" w="90%" maw={450}>
<Title style={{ whiteSpace: 'nowrap' }} align="center" weight={900}>
{t('title')}
</Title>
<Text color="dimmed" size="sm" align="center" mt={5} mb="md">
{t('text')}
</Text>
<Text color="dimmed" size="sm" align="center" mt={5} mb="md">
{t('text')}
</Text>
{isError && (
<Alert icon={<IconAlertTriangle size="1rem" />} color="red">
{t('alert')}
</Alert>
)}
{isError && (
<Alert icon={<IconAlertTriangle size="1rem" />} color="red">
{t('alert')}
</Alert>
)}
<form onSubmit={form.onSubmit(handleSubmit)}>
<Stack>
<TextInput
variant="filled"
label={t('form.fields.username.label')}
autoComplete="homarr-username"
withAsterisk
{...form.getInputProps('name')}
/>
<form onSubmit={form.onSubmit(handleSubmit)}>
<Stack>
<TextInput
variant="filled"
label={t('form.fields.username.label')}
autoComplete="homarr-username"
withAsterisk
{...form.getInputProps('name')}
/>
<PasswordInput
variant="filled"
label={t('form.fields.password.label')}
autoComplete="homarr-password"
withAsterisk
{...form.getInputProps('password')}
/>
<PasswordInput
variant="filled"
label={t('form.fields.password.label')}
autoComplete="homarr-password"
withAsterisk
{...form.getInputProps('password')}
/>
<Button fullWidth type="submit" loading={isLoading}>
{t('form.buttons.submit')}
</Button>
</Stack>
</form>
</Card>
<Button variant="light" fullWidth type="submit" mt="md" loading={isLoading}>
{t('form.buttons.submit')}
</Button>
</Stack>
</form>
</Card>
</Stack>
</Flex>
</>
);

View File

@@ -97,3 +97,11 @@
width: 100%;
display: inherit !important;
}
.polka {
background-image: radial-gradient(
color-mix(in srgb, var(--mantine-color-red-6) 20%, transparent) 6px,
transparent 6px
);
background-size: 60px 60px;
}