-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13 from Quiddlee/add_login_page_draft
Add login page draft
- Loading branch information
Showing
41 changed files
with
1,783 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,18 @@ | ||
import { createHashRouter, RouterProvider } from 'react-router-dom'; | ||
import { RouterProvider } from 'react-router-dom'; | ||
|
||
import MainLayout from '@/layouts/MainLayout'; | ||
import LoginPage from '@pages/LoginPage'; | ||
import MainPage from '@pages/MainPage'; | ||
import WelcomePage from '@pages/WelcomePage'; | ||
import router from '@/router/router'; | ||
|
||
import ROUTES from './shared/constatns/routes'; | ||
|
||
const router = createHashRouter([ | ||
{ | ||
path: '/', | ||
element: <MainLayout />, | ||
children: [ | ||
{ | ||
path: ROUTES.WELCOME_PAGE, | ||
element: <WelcomePage />, | ||
}, | ||
{ | ||
path: ROUTES.LOGIN, | ||
element: <LoginPage />, | ||
}, | ||
{ | ||
path: ROUTES.MAIN, | ||
element: <MainPage />, | ||
}, | ||
], | ||
}, | ||
]); | ||
import AuthProvider from './shared/Context/AuthContext'; | ||
import LanguageProvider from './shared/Context/LanguageContext'; | ||
|
||
const App = () => { | ||
return <RouterProvider router={router} />; | ||
return ( | ||
<AuthProvider> | ||
<LanguageProvider> | ||
<RouterProvider router={router} /> | ||
</LanguageProvider> | ||
</AuthProvider> | ||
); | ||
}; | ||
|
||
export default App; |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import React from 'react'; | ||
|
||
import { createComponent } from '@lit/react'; | ||
import { MdOutlinedTextField } from '@material/web/textfield/outlined-text-field'; | ||
|
||
const FormInput = createComponent({ | ||
react: React, | ||
tagName: 'md-outlined-text-field', | ||
elementClass: MdOutlinedTextField, | ||
}); | ||
|
||
export default FormInput; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import React from 'react'; | ||
|
||
import { createComponent } from '@lit/react'; | ||
import { MdIcon } from '@material/web/icon/icon'; | ||
import { MdIconButton } from '@material/web/iconbutton/icon-button'; | ||
|
||
const Icon = createComponent({ | ||
react: React, | ||
tagName: 'md-icon', | ||
elementClass: MdIcon, | ||
}); | ||
|
||
const IconSlot = createComponent({ | ||
react: React, | ||
tagName: 'md-icon-button', | ||
elementClass: MdIconButton, | ||
}); | ||
|
||
const PassVisibilityIcon = ({ onClick }: { onClick: () => void }) => { | ||
return ( | ||
<IconSlot toggle slot="trailing-icon" onClick={onClick}> | ||
<Icon>visibility</Icon> | ||
<Icon slot="selected">visibility_off</Icon> | ||
</IconSlot> | ||
); | ||
}; | ||
|
||
export default PassVisibilityIcon; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import React from 'react'; | ||
|
||
import { createComponent } from '@lit/react'; | ||
import { MdFilledTonalButton } from '@material/web/button/filled-tonal-button'; | ||
|
||
const SubmitBtn = createComponent({ | ||
react: React, | ||
tagName: 'md-filled-tonal-button', | ||
elementClass: MdFilledTonalButton, | ||
}); | ||
|
||
export default SubmitBtn; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { initializeApp } from 'firebase/app'; | ||
|
||
const firebaseConfig = { | ||
apiKey: 'AIzaSyAijnqgoeQIQJu_lKQ6fgNC7a0fIEuND2c', | ||
authDomain: 'graphiql-app-47127.firebaseapp.com', | ||
projectId: 'graphiql-app-47127', | ||
storageBucket: 'graphiql-app-47127.appspot.com', | ||
messagingSenderId: '1033759243197', | ||
appId: '1:1033759243197:web:3757214e041ae1ab0bf0d4', | ||
}; | ||
|
||
const initFirebaseApp = () => initializeApp(firebaseConfig); | ||
|
||
export default initFirebaseApp; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,103 @@ | ||
const LoginPage = () => { | ||
return <section>Here is my fancy login page!</section>; | ||
}; | ||
import { useState } from 'react'; | ||
|
||
export default LoginPage; | ||
import { yupResolver } from '@hookform/resolvers/yup'; | ||
import { TextFieldType } from '@material/web/textfield/outlined-text-field'; | ||
import { getAuth, signInWithEmailAndPassword } from 'firebase/auth'; | ||
import { useForm } from 'react-hook-form'; | ||
import { Link, useNavigate } from 'react-router-dom'; | ||
|
||
import PassVisibilityIcon from '@/components/loginReg/PassVisibilityIcon'; | ||
import AUTH_ERRORS from '@/shared/constants/authErrors'; | ||
import ROUTES from '@/shared/constants/routes'; | ||
import { loginValidationSchema } from '@/shared/constants/validationSchema'; | ||
import useAuth from '@/shared/Context/authHook'; | ||
import useLanguage from '@/shared/Context/hooks'; | ||
import notationLocalizer from '@/shared/helpers/notationLocalizer'; | ||
import switchPassType from '@/shared/helpers/switchPassType'; | ||
import toastifyNotation from '@/shared/helpers/toastifyNotation'; | ||
import { ErrorType, TextInputProps } from '@/shared/types'; | ||
import FormInput from '@components/loginReg/FormInput'; | ||
import SubmitBtn from '@components/loginReg/SubmitBtn'; | ||
|
||
export default function LoginPage() { | ||
const navigate = useNavigate(); | ||
const [passType, setPassType] = useState('password'); | ||
const { translation, language } = useLanguage(); | ||
const { title, subtitle, emailPlaceHold, passPlaceHold, btnTitle, linkClue, linkTitle } = translation.loginPage; | ||
const { logInAuth } = useAuth(); | ||
|
||
const { | ||
register, | ||
handleSubmit, | ||
formState: { errors, isValid }, | ||
reset, | ||
} = useForm({ | ||
resolver: yupResolver(loginValidationSchema), | ||
mode: 'all', | ||
}); | ||
|
||
async function onSubmit({ email, password }: { email: string; password: string }) { | ||
const auth = getAuth(); | ||
try { | ||
const { user } = await signInWithEmailAndPassword(auth, email, password); | ||
if (user) { | ||
logInAuth(user.email as string); | ||
reset(); | ||
navigate(`/${ROUTES.MAIN}`); | ||
} | ||
return null; | ||
} catch (e) { | ||
if ((e as ErrorType).code === AUTH_ERRORS.INVALID_EMAIL) | ||
return toastifyNotation(notationLocalizer(language, 'code8')); | ||
if ((e as ErrorType).code === AUTH_ERRORS.INVALID_PASS) | ||
return toastifyNotation(notationLocalizer(language, 'code9')); | ||
return toastifyNotation(notationLocalizer(language, 'code11')); | ||
} | ||
} | ||
|
||
return ( | ||
<section className="mx-5 flex items-center justify-center"> | ||
<article className="w-[560px] rounded-[30px] bg-surface-container px-7 py-[60px] sm:px-20"> | ||
<h1 className="text-center text-2xl font-[400] text-on-surface">{title}</h1> | ||
<h2 className="mt-3 text-center text-base font-[400] text-on-surface-variant">{subtitle}</h2> | ||
<form noValidate className="mt-8" onSubmit={handleSubmit(onSubmit)}> | ||
<div className="relative"> | ||
<FormInput | ||
style={{ width: '100%' }} | ||
{...(register('email') as TextInputProps)} | ||
type="email" | ||
placeholder={emailPlaceHold} | ||
label={emailPlaceHold} | ||
/> | ||
<p className="absolute left-4 top-[62px] text-sm font-[400] text-on-surface"> | ||
{notationLocalizer(language, errors.email?.message)} | ||
</p> | ||
</div> | ||
<div className="relative mt-12"> | ||
<FormInput | ||
className="w-full" | ||
{...(register('password') as TextInputProps)} | ||
type={passType as TextFieldType} | ||
placeholder={passPlaceHold} | ||
label={passPlaceHold} | ||
> | ||
<PassVisibilityIcon onClick={() => setPassType((prev) => switchPassType(prev))} /> | ||
</FormInput> | ||
<p className="absolute left-4 top-[62px] text-sm font-[400] text-on-surface"> | ||
{notationLocalizer(language, errors.password?.message)} | ||
</p> | ||
</div> | ||
<SubmitBtn className="mt-[52px] w-full" disabled={!isValid}> | ||
{btnTitle} | ||
</SubmitBtn> | ||
</form> | ||
<p className="mt-8 text-center text-sm font-[400] text-on-surface-variant"> | ||
{linkClue}{' '} | ||
<Link className="text-primary" to={`/${ROUTES.AUTH}/${ROUTES.SIGNUP}`}> | ||
{linkTitle} | ||
</Link> | ||
</p> | ||
</article> | ||
</section> | ||
); | ||
} |
Oops, something went wrong.