-
Notifications
You must be signed in to change notification settings - Fork 1
Sprint-2 login-page #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
57b885c
953c226
a1ec125
e25eb40
aa1c374
7aa13eb
ad68b3a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,161 @@ | ||
| import React from 'react'; | ||
| import AppBar from '@mui/material/AppBar'; | ||
| import Box from '@mui/material/Box'; | ||
| import Toolbar from '@mui/material/Toolbar'; | ||
| import IconButton from '@mui/material/IconButton'; | ||
| import Typography from '@mui/material/Typography'; | ||
| import MenuIcon from '@mui/icons-material/Menu'; | ||
| import Container from '@mui/material/Container'; | ||
| import Button from '@mui/material/Button'; | ||
| import Tooltip from '@mui/material/Tooltip'; | ||
| import MenuItem from '@mui/material/MenuItem'; | ||
| import logo from '../../assets/logo/free-icon-tree-740936.png'; | ||
| import Avatar from '@mui/material/Avatar'; | ||
| import Menu from '@mui/material/Menu'; | ||
|
|
||
| const pages = ['Catalog', 'About Us', 'Login', 'Registration', 'Home']; | ||
| const settings = ['User', 'Logout']; | ||
|
|
||
|
|
||
| export const Header: React.FC = () => { | ||
| const [anchorElNav, setAnchorElNav] = React.useState<null | HTMLElement>(null); | ||
| const [anchorElUser, setAnchorElUser] = React.useState<null | HTMLElement>(null); | ||
|
|
||
| const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => { | ||
| setAnchorElNav(event.currentTarget); | ||
| }; | ||
| const handleOpenUserMenu = (event: React.MouseEvent<HTMLElement>) => { | ||
| setAnchorElUser(event.currentTarget); | ||
| }; | ||
|
|
||
| const handleCloseNavMenu = () => { | ||
| setAnchorElNav(null); | ||
| }; | ||
|
|
||
| const handleCloseUserMenu = () => { | ||
| setAnchorElUser(null); | ||
| }; | ||
|
|
||
| return ( | ||
| <AppBar position="sticky" color='default'> | ||
| <Container maxWidth="xl"> | ||
| <Toolbar disableGutters> | ||
| <a href="/"><img src={logo} alt='logo' width={60} height={60} /></a> | ||
| <Typography | ||
| variant="h6" | ||
| noWrap | ||
| component="a" | ||
| href="/" | ||
| sx={{ | ||
| mr: 2, | ||
| display: { xs: 'none', md: 'flex' }, | ||
| fontFamily: 'monospace', | ||
| fontWeight: 700, | ||
| letterSpacing: '.3rem', | ||
| color: 'green', | ||
| textDecoration: 'none', | ||
| }} | ||
| > | ||
| RSdzen | ||
| </Typography> | ||
|
|
||
| <Box sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}> | ||
| <IconButton | ||
| size="large" | ||
| aria-label="account of current user" | ||
| aria-controls="menu-appbar" | ||
| aria-haspopup="true" | ||
| onClick={handleOpenNavMenu} | ||
| color="inherit" | ||
| > | ||
| <MenuIcon /> | ||
| </IconButton> | ||
| <Menu | ||
| id="menu-appbar" | ||
| anchorEl={anchorElNav} | ||
| anchorOrigin={{ | ||
| vertical: 'bottom', | ||
| horizontal: 'left', | ||
| }} | ||
| keepMounted | ||
| transformOrigin={{ | ||
| vertical: 'top', | ||
| horizontal: 'left', | ||
| }} | ||
| open={Boolean(anchorElNav)} | ||
| onClose={handleCloseNavMenu} | ||
| sx={{ | ||
| display: { xs: 'block', md: 'none' }, | ||
| }} | ||
| > | ||
| {pages.map((page) => ( | ||
| <MenuItem key={page} onClick={handleCloseNavMenu}> | ||
| <Typography textAlign="center">{page}</Typography> | ||
| </MenuItem> | ||
| ))} | ||
|
Comment on lines
+91
to
+95
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO: create a new NavBar component with navigation links |
||
| </Menu> | ||
| </Box> | ||
| <Typography | ||
| variant="h5" | ||
| noWrap | ||
| component="a" | ||
| href="/" | ||
| sx={{ | ||
| mr: 2, | ||
| display: { xs: 'flex', md: 'none' }, | ||
| flexGrow: 1, | ||
| fontFamily: 'monospace', | ||
| fontWeight: 700, | ||
| letterSpacing: '.3rem', | ||
| color: 'green', | ||
| textDecoration: 'none', | ||
| }} | ||
| > | ||
| RSdzen | ||
| </Typography> | ||
| <Box sx={{ flexGrow: 1, display: { xs: 'none', md: 'flex' } }}> | ||
| {pages.map((page) => ( | ||
| <Button | ||
| key={page} | ||
| onClick={handleCloseNavMenu} | ||
| sx={{ my: 2, color: 'green', display: 'block' }} | ||
| > | ||
| {page} | ||
| </Button> | ||
| ))} | ||
| </Box> | ||
|
|
||
| <Box sx={{ flexGrow: 0 }}> | ||
| <Tooltip title="Open settings"> | ||
| <IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}> | ||
| <Avatar alt="Remy Sharp" src="/static/images/avatar/2.jpg" /> | ||
| </IconButton> | ||
| </Tooltip> | ||
| <Menu | ||
| sx={{ mt: '45px' }} | ||
| id="menu-appbar" | ||
| anchorEl={anchorElUser} | ||
| anchorOrigin={{ | ||
| vertical: 'top', | ||
| horizontal: 'right', | ||
| }} | ||
| keepMounted | ||
| transformOrigin={{ | ||
| vertical: 'top', | ||
| horizontal: 'right', | ||
| }} | ||
| open={Boolean(anchorElUser)} | ||
| onClose={handleCloseUserMenu} | ||
| > | ||
| {settings.map((setting) => ( | ||
| <MenuItem key={setting} onClick={handleCloseUserMenu}> | ||
| <Typography textAlign="center">{setting}</Typography> | ||
| </MenuItem> | ||
| ))} | ||
| </Menu> | ||
| </Box> | ||
| </Toolbar> | ||
| </Container> | ||
| </AppBar> | ||
| ); | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,11 @@ | ||
| body { | ||
| margin: 0; | ||
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', | ||
| 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', | ||
| sans-serif; | ||
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', | ||
| 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; | ||
| -webkit-font-smoothing: antialiased; | ||
| -moz-osx-font-smoothing: grayscale; | ||
| } | ||
|
|
||
| code { | ||
| font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', | ||
| monospace; | ||
| font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,69 @@ | ||
| import React from 'react'; | ||
| import { Grid, Box, TextField, Button, Alert, Typography } from '@mui/material'; | ||
| import LoginImage from '../../assets/images/ImgLoginPage.png'; | ||
| import { NavLink } from 'react-router-dom'; | ||
| import { useState } from 'react'; | ||
|
|
||
| export const LoginPage: React.FC = () => { | ||
| return <div>Login Page</div>; | ||
| const [error, setError] = useState({ | ||
| status: false, | ||
| message: '', | ||
| type: '' | ||
| }); | ||
| const handleSubmit=(e: React.FormEvent<HTMLFormElement>)=>{ | ||
| e.preventDefault(); | ||
| const data=new FormData(e.currentTarget); | ||
| const actualData = { | ||
| email: data.get('email'), | ||
| password: data.get('password'), | ||
| }; | ||
| if (actualData.email && actualData.password) { | ||
| console.log(actualData); | ||
| (document.getElementById('login-form') as HTMLFormElement).reset(); | ||
| setError({ | ||
| status: true, | ||
| message: 'Successful!', | ||
| type: 'success' | ||
| }); | ||
| } else { | ||
| setError({ | ||
| status: true, | ||
| message: 'All fields are required', | ||
| type: 'error' | ||
| }); | ||
| } | ||
| }; | ||
| return ( | ||
| <Grid container sx={{ height: '80vh'}}> | ||
| <Grid item lg={7} sm={5} sx={{ | ||
| backgroundImage: `url(${LoginImage})`, | ||
| backgroundRepeat: 'no-repeat', | ||
| backgroundSize: 'cover', | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. better to do backgroundSize to contain and backgroundPosition to top. |
||
| backgroundPosition: 'center' | ||
| }}> | ||
| </Grid> | ||
| <Grid item lg={5} sm={7}> | ||
| <Box component='form' noValidate sx={{ mt: 5, ml:8, mr:8}} id='login-form' onSubmit={handleSubmit}> | ||
| <Box> | ||
| {error.status ? <Alert severity={'error'}>{error.message}</Alert> : ''} | ||
| </Box> | ||
| <TextField sx={{mt: 2}} required fullWidth id='email' name='email' label='Email Address' type='email' /> | ||
| <TextField required fullWidth margin='normal' id='password' name='password' label='Password' type='password'/> | ||
| <Box textAlign='center'> | ||
| <Button type='submit' variant='contained' sx={{px:5, mt: 2, backgroundColor: 'green'}}>Login</Button> | ||
| <Typography component='p' color='gray'>Remember me</Typography> | ||
| </Box> | ||
| <Box> | ||
| <NavLink to='/'>Forgot Password?</NavLink> | ||
| </Box> | ||
| <Box sx={{mt: 10}}> | ||
| <Typography component='p' textAlign='center'>Don't have account yet? Sign up</Typography> | ||
| </Box> | ||
| <Box textAlign='center'> | ||
| <Button type='submit' variant='contained' sx={{px:2, mt: 2, backgroundColor: 'green'}}>Registration</Button> | ||
| </Box> | ||
| </Box> | ||
| </Grid> | ||
| </Grid> | ||
|
|
||
| ); | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| import {JSX} from 'react'; | ||
| import { Outlet } from 'react-router-dom'; | ||
| import {Header} from '../../components/Header/Header'; | ||
|
|
||
| const RootPage = (): JSX.Element => { | ||
| return ( | ||
| <> | ||
| <Header /> | ||
| <div className="app"> | ||
| <Outlet /> | ||
| </div> | ||
| </> | ||
| ); | ||
| }; | ||
| export default RootPage; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All styles should be placed in the scss file. Check also other places.