diff --git a/client/src/app/(auth)/layout.tsx b/client/src/app/(auth)/layout.tsx index bbf40be2c..d787d73fb 100644 --- a/client/src/app/(auth)/layout.tsx +++ b/client/src/app/(auth)/layout.tsx @@ -1,46 +1,67 @@ 'use client'; import { GoogleOAuthProvider } from '@react-oauth/google'; -import { useRouter } from 'next/navigation'; +import { usePathname, useRouter } from 'next/navigation'; import { ReactNode, useState } from 'react'; -import { ArrowLeft, LogoBig } from '@/shared/assets'; -import { Button, Tabs } from '@/shared/ui'; +import { LogoBig } from '@/shared/assets'; +import { Flex, Tabs } from '@/shared/ui'; import styles from './styles.module.scss'; export default function AuthLayout({ children }: { children: ReactNode }) { const router = useRouter(); + const pathname = usePathname(); const options = ['Login', 'Sign Up']; const [tab, setTab] = useState(options[0]); + const handleBack = () => { + router.push('/'); + }; const handleChange = (option: string) => { setTab(option); router.push(`/${option.toLowerCase().replace(/\s/g, '')}`); }; - const handleBack = () => { - router.push('/'); - }; + const header = ( +
+
+ +
+
+ +
+
+ ); - return ( - -
-
-
- -
-
- -
-
- -
-
+ const basic = ( +
+ {header} + + {children} + +
+ ); -
{children}
+ const alternative = ( + +
+ {header} + + {children} +
+ Main image +
+ ); + + return ( + + {pathname === '/login' || pathname === '/signup' ? alternative : basic} ); } diff --git a/client/src/app/(auth)/login/confirmation/page.tsx b/client/src/app/(auth)/login/confirmation/page.tsx deleted file mode 100644 index 9756c7b20..000000000 --- a/client/src/app/(auth)/login/confirmation/page.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { IllustrationStatus } from '../../ui'; - -export default function Confirmation() { - return ( - - ); -} diff --git a/client/src/app/(auth)/login/page.tsx b/client/src/app/(auth)/login/page.tsx index dd7f14668..66554bd83 100644 --- a/client/src/app/(auth)/login/page.tsx +++ b/client/src/app/(auth)/login/page.tsx @@ -4,11 +4,11 @@ import { useGoogleLogin } from '@react-oauth/google'; import { useRouter } from 'next/navigation'; import { SubmitHandler, useForm } from 'react-hook-form'; -import { Button, Input, InputPassword, Typography } from '@/shared/ui'; +import { Button, Flex, Input, InputPassword, Typography } from '@/shared/ui'; import { useState } from 'react'; import styles from '../shared.module.scss'; -import { Github, Google, Login } from '@/shared/assets'; +import { Github, Google, LogoBig } from '@/shared/assets'; interface LoginProps { email: string; @@ -35,66 +35,64 @@ export default function LoginPage() { return (
-
-
-
- setEmail(e.target.value)} + + + + + + setEmail(e.target.value)} + /> + +
+ setPassword(e.target.value)} /> -
- setPassword(e.target.value)} - /> -
-
router.push('/password/recover')} - > - - Forgot Password? - -
+ +
router.push('/password/recover')}> + + Forgot Password? +
-
+
-
- -
-
- - or log in with - -
-
+ -
- - -
-
-
-
-
-
- -
-
+ + + + +
+ + or log in with + +
+ + + + + + + + ); } diff --git a/client/src/app/(auth)/password/confirmation/page.tsx b/client/src/app/(auth)/password/confirmation/page.tsx index f01203f79..e792e207c 100644 --- a/client/src/app/(auth)/password/confirmation/page.tsx +++ b/client/src/app/(auth)/password/confirmation/page.tsx @@ -1,10 +1,18 @@ +'use client'; import { IllustrationStatus } from '../../ui'; +import { useRouter } from 'next/navigation'; export default function Confirmation() { + const router = useRouter(); + const handleBack = () => { + router.push('/'); + }; return ( ); } diff --git a/client/src/app/(auth)/password/expired/page.tsx b/client/src/app/(auth)/password/expired/page.tsx index 204eca55b..72ef31b86 100644 --- a/client/src/app/(auth)/password/expired/page.tsx +++ b/client/src/app/(auth)/password/expired/page.tsx @@ -1,10 +1,18 @@ +'use client'; import { IllustrationStatus } from '../../ui'; +import { useRouter } from 'next/navigation'; export default function Expired() { + const router = useRouter(); + const handleBack = () => { + router.push('/'); + }; return ( ); } diff --git a/client/src/app/(auth)/password/password.module.scss b/client/src/app/(auth)/password/password.module.scss new file mode 100644 index 000000000..fae2c9a11 --- /dev/null +++ b/client/src/app/(auth)/password/password.module.scss @@ -0,0 +1,3 @@ +.text_align { + text-align: center; +} diff --git a/client/src/app/(auth)/password/recover/page.tsx b/client/src/app/(auth)/password/recover/page.tsx index e5fcdee6b..c6fcc3fb1 100644 --- a/client/src/app/(auth)/password/recover/page.tsx +++ b/client/src/app/(auth)/password/recover/page.tsx @@ -3,10 +3,9 @@ import Link from 'next/link'; import { useState } from 'react'; import { SubmitHandler, useForm } from 'react-hook-form'; import { ArrowLeft } from '@/shared/assets'; -import { Button, Input, Typography } from '@/shared/ui'; -import styles from '../shared.module.scss'; +import { Button, Flex, Input, Typography } from '@/shared/ui'; +import styles from '../password.module.scss'; import { useRouter } from 'next/navigation'; -import clsx from 'clsx'; interface RecoverProps { email: string; @@ -28,46 +27,40 @@ export default function Recover() { }; return ( -
-
- - Recover Password - - - Enter the email you used to register and we will send you link to reset your password - -
- setEmail(e.target.value)} - /> -
- - -
+ + + + + Recover Password + + + Enter the email you used to register and we will send you link to reset your password + + + setEmail(e.target.value)} + /> + + + + +
); } diff --git a/client/src/app/(auth)/password/shared.module.scss b/client/src/app/(auth)/password/shared.module.scss deleted file mode 100644 index b93c5d063..000000000 --- a/client/src/app/(auth)/password/shared.module.scss +++ /dev/null @@ -1,36 +0,0 @@ -.info { - width: 100%; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - gap: 48px; - - &.width370px { - max-width: 370px; - } - - &.width470px { - max-width: 470px; - } -} - -.gapContainer { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - width: 100%; - - &.gap8px { - gap: 8px; - } - - &.gap36px { - gap: 36px; - } - - &.alignText { - text-align: center; - } -} diff --git a/client/src/app/(auth)/password/update/[id]/[token]/page.tsx b/client/src/app/(auth)/password/update/[id]/[token]/page.tsx index 06a16af6d..bcd5e91e0 100644 --- a/client/src/app/(auth)/password/update/[id]/[token]/page.tsx +++ b/client/src/app/(auth)/password/update/[id]/[token]/page.tsx @@ -1,9 +1,9 @@ 'use client'; -import styles from '../../../shared.module.scss'; -import { Button, InputPassword, Typography } from '@/shared/ui'; -import clsx from 'clsx'; +import styles from '../../../password.module.scss'; +import { Button, Flex, InputPassword, Typography } from '@/shared/ui'; import { useState } from 'react'; import { SubmitHandler, useForm } from 'react-hook-form'; +import { useRouter } from 'next/navigation'; interface UpdateProps { password: string; @@ -13,6 +13,7 @@ export default function Update({ params }: { params: { id: string; token: string const { id, token } = params; const [password, setPassword] = useState(''); const [repeatPassword, setRepeatPassword] = useState(''); + const router = useRouter(); const { register, @@ -22,54 +23,49 @@ export default function Update({ params }: { params: { id: string; token: string const onSubmit: SubmitHandler = data => { console.log(data, id, token); + router.push('/password/success'); }; return ( -
-
- - Recover Password - - - Enter a new password and confirm it by re-entering it in the appropriate fields - -
-
- setPassword(e.target.value)} - /> - value === password || 'The passwords do not match', - })} - error={errors?.repeatPassword ? errors.repeatPassword.message : undefined} - value={repeatPassword} - onChange={e => setRepeatPassword(e.target.value)} - /> -
- + + + + + Recover Password + + + Enter a new password and confirm it by re-entering it in the appropriate fields + + + + setPassword(e.target.value)} + /> + value === password || 'The passwords do not match', + })} + error={errors?.repeatPassword ? errors.repeatPassword.message : undefined} + value={repeatPassword} + onChange={e => setRepeatPassword(e.target.value)} + /> + + +
); } diff --git a/client/src/app/(auth)/shared.module.scss b/client/src/app/(auth)/shared.module.scss index f46e5497f..dd84533e3 100644 --- a/client/src/app/(auth)/shared.module.scss +++ b/client/src/app/(auth)/shared.module.scss @@ -1,79 +1,23 @@ .container { width: 100%; display: flex; - max-width: 1370px; - - @media (width <= 1440px) { - max-width: 1104px; - } -} - -.left { - display: flex; - flex-direction: column; justify-content: center; - width: 50%; - - @media (width <= 1024px) { - align-items: center; - width: 100%; - } -} - -.interactive_container { - width: 100%; - max-width: 370px; - display: flex; - gap: 48px; - flex-direction: column; + align-items: center; } -.flex_wrapper { - display: flex; - flex-direction: column; - gap: 36px; - - &__s { +.additional_logo { + display: none; + @media (width <= 420px) { display: flex; - flex-direction: column; - gap: 24px; - } -} - -.right { - width: 50%; - display: flex; - justify-content: flex-end; - - @media (width <= 1024px) { - display: none; } } -.svg_container { - max-width: 564px; - width: 100%; - max-height: 600px; - height: 100%; -} - -.forgot_link_wrapper { - width: 100%; - display: flex; - justify-content: flex-end; - margin-top: 8px; -} - .forgot_link { cursor: pointer; } .lines_container { - display: flex; - justify-content: center; - align-items: center; white-space: nowrap; - gap: 13px; } .line { @@ -81,22 +25,3 @@ height: 1px; background: var(--grey-normal-color); } - -.buttons_container { - width: 100%; - display: flex; - justify-content: center; - align-items: center; - gap: 16px; -} - -.button { - background: var(--white-color); - cursor: pointer; - display: flex; - width: 48px; - height: 48px; - justify-content: center; - align-items: center; - border-radius: 10px; -} diff --git a/client/src/app/(auth)/signup/confirmation/page.tsx b/client/src/app/(auth)/signup/confirmation/page.tsx index 9756c7b20..b5c534b6f 100644 --- a/client/src/app/(auth)/signup/confirmation/page.tsx +++ b/client/src/app/(auth)/signup/confirmation/page.tsx @@ -1,7 +1,18 @@ +'use client'; import { IllustrationStatus } from '../../ui'; +import { useRouter } from 'next/navigation'; export default function Confirmation() { + const router = useRouter(); + const handleBack = () => { + router.push('/'); + }; return ( - + ); } diff --git a/client/src/app/(auth)/signup/page.tsx b/client/src/app/(auth)/signup/page.tsx index b0c5d6d8a..62890e5cf 100644 --- a/client/src/app/(auth)/signup/page.tsx +++ b/client/src/app/(auth)/signup/page.tsx @@ -2,9 +2,9 @@ import { useGoogleLogin } from '@react-oauth/google'; import { useState } from 'react'; -import { Github, Google, Login } from '@/shared/assets'; +import { Github, Google, LogoBig } from '@/shared/assets'; import { SubmitHandler, useForm } from 'react-hook-form'; -import { Button, Input, InputPassword, Typography } from '@/shared/ui'; +import { Button, Flex, Input, InputPassword, Typography } from '@/shared/ui'; import styles from '../shared.module.scss'; interface SignupProps { @@ -33,63 +33,64 @@ export default function SignupPage() { return (
-
-
-
- setEmail(e.target.value)} - /> - setPassword(e.target.value)} - /> - value === password || 'The passwords do not match', - })} - error={errors?.repeatPassword ? errors.repeatPassword.message : undefined} - value={repeatPassword} - onChange={e => setRepeatPassword(e.target.value)} - /> -
-
- -
-
- - or continue with - -
-
+ + + + + + setEmail(e.target.value)} + /> -
- - -
-
-
-
-
-
- -
-
+ setPassword(e.target.value)} + /> + value === password || 'The passwords do not match', + })} + error={errors?.repeatPassword ? errors.repeatPassword.message : undefined} + value={repeatPassword} + onChange={e => setRepeatPassword(e.target.value)} + /> + + + + + + +
+ + or continue with + +
+ + + + + + + + ); } diff --git a/client/src/app/(auth)/styles.module.scss b/client/src/app/(auth)/styles.module.scss index 07d5920d9..826ad2ed8 100644 --- a/client/src/app/(auth)/styles.module.scss +++ b/client/src/app/(auth)/styles.module.scss @@ -1,5 +1,6 @@ .logo { - @media (width <= 740px) { + cursor: pointer; + @media (width <= 420px) { display: none; } } @@ -8,16 +9,17 @@ display: flex; align-items: center; justify-content: space-between; -} -.headerNormalizer { - width: 144px; + @media (width <= 420px) { + justify-content: center; + } } .container { height: 100dvh; width: 100%; padding: 48px 55px; + background: var(--cards-color); @media (width <= 1120px) { padding: 48px 24px; @@ -28,11 +30,37 @@ } } +.alternative { + height: 100dvh; + background: var(--cards-color); +} + .children { - width: 100%; min-height: calc(100% - 48px); - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; +} + +.left { + width: 50%; + height: 100%; + padding: 48px 55px; + + @media (width <= 1024px) { + width: 100%; + padding: 48px 24px; + } + + @media (width <= 580px) { + padding: 24px; + } +} + +.right { + width: 50%; + height: 100%; + object-fit: cover; + user-select: none; + + @media (width <= 1024px) { + display: none; + } } diff --git a/client/src/app/(auth)/ui/illustration/illustration.module.scss b/client/src/app/(auth)/ui/illustration/illustration.module.scss index e02a97554..28aff1a25 100644 --- a/client/src/app/(auth)/ui/illustration/illustration.module.scss +++ b/client/src/app/(auth)/ui/illustration/illustration.module.scss @@ -3,21 +3,3 @@ max-width: 705px; margin-bottom: 56px; } - -.info { - width: 100%; - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - gap: 8px; - text-align: center; -} - -.buttonWrapper { - width: 100%; - display: flex; - justify-content: center; - align-items: center; - margin-top: 16px; -} diff --git a/client/src/app/(auth)/ui/illustration/illustration.tsx b/client/src/app/(auth)/ui/illustration/illustration.tsx index 7f5119e93..ec360afca 100644 --- a/client/src/app/(auth)/ui/illustration/illustration.tsx +++ b/client/src/app/(auth)/ui/illustration/illustration.tsx @@ -1,5 +1,5 @@ import { Email } from '@/shared/assets'; -import { Button, Typography } from '@/shared/ui'; +import { Button, Flex, Typography } from '@/shared/ui'; import styles from './illustration.module.scss'; import { FC } from 'react'; @@ -15,18 +15,18 @@ export const IllustrationStatus: FC = props => { return (
-
+ {mainText} {subText} -
+ {buttonText && ( -
- -
+ )}
); diff --git a/client/src/shared/assets/icons/socials/github.tsx b/client/src/shared/assets/icons/socials/github.tsx index 5eca25836..997ae2334 100644 --- a/client/src/shared/assets/icons/socials/github.tsx +++ b/client/src/shared/assets/icons/socials/github.tsx @@ -2,16 +2,16 @@ import { FC, SVGProps } from 'react'; export const Github: FC> = props => { return ( ); diff --git a/client/src/shared/assets/icons/socials/google.tsx b/client/src/shared/assets/icons/socials/google.tsx index c740ce440..a8e6b0135 100644 --- a/client/src/shared/assets/icons/socials/google.tsx +++ b/client/src/shared/assets/icons/socials/google.tsx @@ -2,34 +2,34 @@ import { FC, SVGProps } from 'react'; export const Google: FC> = props => { return ( - + - - + + diff --git a/client/src/shared/ui/flex/flex.tsx b/client/src/shared/ui/flex/flex.tsx index 022c50830..7e8178ffa 100644 --- a/client/src/shared/ui/flex/flex.tsx +++ b/client/src/shared/ui/flex/flex.tsx @@ -1,6 +1,7 @@ import React from 'react'; import styles from './flex.module.scss'; +import clsx from 'clsx'; export interface FlexProps { /** @@ -60,6 +61,12 @@ export interface FlexProps { */ shrink?: string | number; + /** + * [props.className] - adds additional classes to base + + */ + className?: string; + /** * props.children - The content to be laid out. */ @@ -109,6 +116,7 @@ export const Flex: React.FC = props => { wrap, shrink, children, + className, } = props; const style = { @@ -128,7 +136,7 @@ export const Flex: React.FC = props => { } as React.CSSProperties; return ( -
+
{children}
);