Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions public/svgs/auth-top.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion src/app/(auth)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const AuthLayout: FC<AuthLayoutProps> = ({ children }) => {
height: '100vh',
display: 'grid',
placeItems: 'center',
overflow: 'hidden',
}}
>
{children}
Expand Down
4 changes: 2 additions & 2 deletions src/app/test/arrow-link/page.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Box } from '@mui/material';

import ArrowLink from '@/components/common/ui/arrow-link';
import { ArrowVariant } from '@/components/common/ui/arrow-link/types';
import { IconPlace } from '@/components/common/ui/arrow-link/types';

const Page = () => {
return (
<Box sx={{ backgroundColor: 'dark.400', height: '400px' }}>
<ArrowLink
href={'/'}
text={'Повернутись до авторизації'}
arrow={ArrowVariant.RIGHT}
arrow={IconPlace.RIGHT}
/>
</Box>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/icons/Logo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const Logo: FC<LogoProps> = ({
color = 'orange',
}) => {
const fill =
color !== 'black' ? theme.palette.orange[300] : theme.palette.dark[400];
color === 'black' ? theme.palette.dark[400] : theme.palette.orange[300];

if (size === LogoVariant.MEDIUM) {
return (
Expand Down
6 changes: 6 additions & 0 deletions src/components/common/ui/arrow-link/ArrowLink.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { SxProps, Theme } from '@mui/material/styles';

export const wrapper: SxProps<Theme> = {
a: {
margin: 0,
display: 'flex',
alignItems: 'center',
color: 'white.main',
Expand All @@ -13,5 +14,10 @@ export const wrapper: SxProps<Theme> = {
'&:active': {
color: 'gray.400',
},

svg: {
width: '24px',
height: '24px',
},
},
};
20 changes: 9 additions & 11 deletions src/components/common/ui/arrow-link/ArrowLink.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,37 @@
import { FC } from 'react';
import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
import { ChevronLeftIcon } from '@heroicons/react/24/outline';
import { Box, Typography } from '@mui/material';
import { SxProps, Theme } from '@mui/material/styles';
import Link from 'next/link';

import { ArrowVariant } from '@/components/common/ui/arrow-link/types';
import { IconPlace } from '@/components/common/ui/arrow-link/types';
import mergeSx from '@/lib/utils/mergeSx';

import * as styles from './ArrowLink.styles';

interface ArrowLinkProps {
text: string;
href: string;
arrow?: ArrowVariant;
iconPlace?: IconPlace;
icon?: React.ReactNode;
target?: string;
sx?: SxProps<Theme>;
}

const ArrowLink: FC<ArrowLinkProps> = ({
text,
href,
arrow = ArrowVariant.LEFT,
iconPlace = 'left',
icon = <ChevronLeftIcon />,
target,
sx = {},
}) => {
return (
<Box sx={mergeSx(styles.wrapper, sx)}>
<Link href={href} target={target}>
{arrow === ArrowVariant.LEFT && (
<ChevronLeftIcon height={24} width={24} />
)}
<Typography typography="h6Bold">{text}</Typography>
{arrow === ArrowVariant.RIGHT && (
<ChevronRightIcon height={24} width={24} />
)}
{iconPlace === 'left' && icon}
<Typography typography="body1Bold">{text}</Typography>
{iconPlace === 'right' && icon}
</Link>
</Box>
);
Expand Down
6 changes: 1 addition & 5 deletions src/components/common/ui/arrow-link/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
export enum ArrowVariant {
RIGHT = 'right',
LEFT = 'left',
NONE = 'none',
}
export type IconPlace = 'right' | 'left' | 'none';
48 changes: 39 additions & 9 deletions src/components/pages/auth-pages/login-page/LoginPage.styles.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,40 @@
import { SxProps, Theme } from '@mui/material/styles';

export const wrapper: SxProps<Theme> = {
width: '1064px',
height: '648px',
width: {
desktop: '1064px',
mobile: '100%',
},
height: {
desktop: '648px',
mobile: '100%',
},
backgroundColor: 'dark.400',
display: 'flex',
flexDirection: 'row',
flexDirection: {
desktop: 'row',
mobile: 'column',
},
justifyContent: 'space-between',
alignItems: 'center',
overflow: 'hidden',

form: {
paddingLeft: '74px',
maxWidth: '520px',
width: {
desktop: '70%',
mobile: '100%',
},
ml: {
desktop: '74px',
mobile: 0,
},
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
},

section: {
display: 'flex',
flexDirection: 'column',
Expand All @@ -27,6 +47,7 @@ export const wrapper: SxProps<Theme> = {
width: '100%',
pr: '80px',
},

a: {
alignSelf: 'flex-start',
color: 'orange.500',
Expand All @@ -36,17 +57,26 @@ export const wrapper: SxProps<Theme> = {
textDecoration: 'underline',
},
},
};

export const textField: SxProps<Theme> = {
width: '420px',
height: '44px',
img: {
width: '100%',
height: 'auto',
},
};

export const input: SxProps<Theme> = {};

export const image = {
width: '100%',
height: 'auto',
marginBottom: '20px',
};

export const signInText: SxProps<Theme> = {
typography: 'h4Bold',
typography: {
desktop: 'h4Bold',
mobile: 'h5Bold',
},
color: 'white.main',
mb: '24px',
};
Expand Down
108 changes: 35 additions & 73 deletions src/components/pages/auth-pages/login-page/LoginPage.tsx
Original file line number Diff line number Diff line change
@@ -1,91 +1,53 @@
'use client';

import { FC } from 'react';
import { Box, Stack, Typography } from '@mui/material';
import axios from 'axios';
import { useFormik } from 'formik';
import { Box, Stack, Typography, useMediaQuery } from '@mui/material';
import Image from 'next/image';
import Link from 'next/link';
import { useRouter } from 'next/navigation';

import ArrowLink from '@/components/common/ui/arrow-link';
import Button from '@/components/common/ui/button';
import Input from '@/components/common/ui/input/Input';
import SideSection from '@/components/pages/auth-pages/components/side-section';
import useToast from '@/hooks/use-toast';
import AuthAPI from '@/lib/api/auth/AuthAPI';
import { exceptionMapper } from '@/lib/utils/exception-mapper';
import storageUtil from '@/lib/utils/storageUtil';
import LoginForm from '@/components/pages/auth-pages/login-page/components/login-form';
import theme from '@/styles/theme';

import { initialValues } from './constants/initialValues';
import * as styles from './LoginPage.styles';

const LoginPage: FC = () => {
const router = useRouter();
const toast = useToast();
const formik = useFormik({
initialValues,
onSubmit: async (values) => {
try {
const { accessToken } = await AuthAPI.login(values);
storageUtil.setToken(accessToken);
router.replace('/profile?tab=organisations');
return;
} catch (e) {
if (axios.isAxiosError(e)) {
const { error } = e.response?.data;
const mapper = exceptionMapper[error];
toast.error(mapper.title, mapper.description, 3000, 'filled');
}
}
},
});
const isMobile = useMediaQuery(theme.breakpoints.down('desktop'));

return (
<Box sx={styles.wrapper}>
<form onSubmit={formik.handleSubmit}>
<Typography sx={styles.signInText}>Вхід</Typography>
<Stack flexDirection="column" gap="24px" mb="18px">
<Input
name="username"
label="Логін"
placeholder="Пошта / нікнейм / номер телефону"
variant="black"
sx={styles.textField}
value={formik.values.username}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
/>
<Input
password
name="password"
label="Пароль"
placeholder="Пароль"
variant="black"
sx={styles.textField}
value={formik.values.password}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
/>
</Stack>
<Link href="/login/recover">Забув пароль?</Link>
<Button
color="primary"
size="medium"
variant="contained"
fullWidth
type="submit"
>
Увійти
</Button>
<ArrowLink
sx={styles.arrowLink}
text="Повернутись на головну"
href="/"
{isMobile && (
<Image
src="/svgs/auth-top.svg"
alt="picture"
width={360}
height={136}
/>
</form>
<Box component="section">
<SideSection text="login" link="/register" />
</Box>
)}
<LoginForm />
{!isMobile ? (
<Box component="section">
<SideSection text="login" link="/register" />
</Box>
) : (
<Stack
alignItems="center"
mx="16px"
mb="36px"
flexDirection="column"
gap="10px"
>
<Typography typography="body1" color="white.main">
Не маєте акаунту?
</Typography>
<Link style={{ textDecoration: 'none' }} href="/register">
<Button size="small" color="secondary" variant="outlined">
Зареєструватися
</Button>
</Link>
</Stack>
)}
</Box>
);
};
Expand Down
Loading