Create loginPage
This commit is contained in:
parent
709d9e17fc
commit
e61b6460a1
|
@ -3,14 +3,11 @@ import {
|
|||
Box,
|
||||
Button,
|
||||
Checkbox,
|
||||
CssBaseline,
|
||||
FormControlLabel,
|
||||
FormLabel,
|
||||
FormControl,
|
||||
TextField,
|
||||
Typography,
|
||||
Stack,
|
||||
Card as MuiCard,
|
||||
Grid,
|
||||
IconButton,
|
||||
Link,
|
||||
|
@ -25,56 +22,10 @@ import ForgotPassword from "./ForgotPassword.tsx";
|
|||
import { toast } from "sonner";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Visibility, VisibilityOff } from "@mui/icons-material";
|
||||
import RemoveRedEyeOutlinedIcon from "@mui/icons-material/RemoveRedEyeOutlined";
|
||||
import { createTheme, ThemeProvider } from "@mui/material/styles";
|
||||
import { lime, purple } from "@mui/material/colors";
|
||||
const Card = styled(MuiCard)(({ theme }) => ({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignSelf: "center",
|
||||
width: "100%",
|
||||
padding: theme.spacing(4),
|
||||
gap: theme.spacing(2),
|
||||
margin: "16px",
|
||||
backgroundColor: "#1E1F1F",
|
||||
[theme.breakpoints.up("sm")]: {
|
||||
maxWidth: "450px",
|
||||
},
|
||||
// boxShadow:
|
||||
// "hsla(220, 30%, 5%, 0.05) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.05) 0px 15px 35px -5px",
|
||||
// ...theme.applyStyles("dark", {
|
||||
// boxShadow:
|
||||
// "hsla(220, 30%, 5%, 0.5) 0px 5px 15px 0px, hsla(220, 25%, 10%, 0.08) 0px 15px 35px -5px",
|
||||
// }),
|
||||
}));
|
||||
const theme = createTheme({
|
||||
palette: {
|
||||
primary: lime,
|
||||
secondary: purple,
|
||||
},
|
||||
});
|
||||
const SignInContainer = styled(Stack)(({ theme }) => ({
|
||||
height: "calc((1 - var(--template-frame-height, 0)) * 100dvh)",
|
||||
minHeight: "100%",
|
||||
// padding: theme.spacing(2),
|
||||
// [theme.breakpoints.up("sm")]: {
|
||||
// padding: theme.spacing(4),
|
||||
// },
|
||||
"&::before": {
|
||||
content: '""',
|
||||
display: "block",
|
||||
position: "absolute",
|
||||
zIndex: -1,
|
||||
inset: 0,
|
||||
backgroundImage:
|
||||
"radial-gradient(ellipse at 50% 50%, hsl(210, 100%, 97%), hsl(0, 0%, 100%))",
|
||||
backgroundRepeat: "no-repeat",
|
||||
...theme.applyStyles("dark", {
|
||||
backgroundImage:
|
||||
"radial-gradient(at 50% 50%, hsla(210, 100%, 16%, 0.5), hsl(220, 30%, 5%))",
|
||||
}),
|
||||
},
|
||||
}));
|
||||
import { Card, SignInContainer } from "./styled.css.tsx";
|
||||
|
||||
|
||||
|
||||
interface ILoginForm {
|
||||
email: string;
|
||||
password: string;
|
||||
|
@ -82,7 +33,6 @@ interface ILoginForm {
|
|||
export default function Login(props: { disableCustomTheme?: boolean }) {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
|
||||
console.log("theme", theme.palette.background);
|
||||
const [showPassword, setShowPassword] = React.useState(false);
|
||||
const {
|
||||
control,
|
||||
|
@ -113,249 +63,261 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
|||
};
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
<AppTheme {...props}>
|
||||
<CssBaseline enableColorScheme />
|
||||
<SignInContainer
|
||||
direction="column"
|
||||
justifyContent="space-between"
|
||||
>
|
||||
{/* <ColorModeSelect
|
||||
<AppTheme {...props}>
|
||||
{/* <CssBaseline enableColorScheme /> */}
|
||||
<SignInContainer direction="column" justifyContent="space-between">
|
||||
{/* <ColorModeSelect
|
||||
sx={{ position: "fixed", top: "1rem", right: "1rem" }}
|
||||
/> */}
|
||||
|
||||
<Grid container sx={{ height: "100vh" }}>
|
||||
<Grid
|
||||
item
|
||||
xs={7}
|
||||
sx={{
|
||||
background: `url('/mainPageLogo.png') center/cover no-repeat`,
|
||||
}}
|
||||
/>
|
||||
<Grid container sx={{ height: "100vh" }}>
|
||||
<Grid
|
||||
item
|
||||
xs={7}
|
||||
sx={{
|
||||
background: `url('/mainPageLogo.png') center/cover no-repeat`,
|
||||
}}
|
||||
/>
|
||||
|
||||
<Grid
|
||||
item
|
||||
xs={5}
|
||||
<Grid
|
||||
item
|
||||
xs={5}
|
||||
sx={{
|
||||
backgroundColor: "black",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="h3"
|
||||
sx={{
|
||||
backgroundColor: "black",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
flexDirection: "column",
|
||||
color: "white",
|
||||
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="h3"
|
||||
sx={{
|
||||
color: "white",
|
||||
Welcome Back!
|
||||
</Typography>
|
||||
<Card variant="outlined">
|
||||
{/* <SitemarkIcon /> */}
|
||||
|
||||
textAlign: "center",
|
||||
<Box
|
||||
component="form"
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
noValidate
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
width: "100%",
|
||||
gap: 2,
|
||||
}}
|
||||
>
|
||||
Welcome Back!
|
||||
</Typography>
|
||||
<Card variant="outlined">
|
||||
{/* <SitemarkIcon /> */}
|
||||
|
||||
<Box
|
||||
component="form"
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
noValidate
|
||||
<Typography
|
||||
component="h1"
|
||||
variant="h4"
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
width: "100%",
|
||||
gap: 2,
|
||||
textAlign: "center",
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
component="h1"
|
||||
variant="h4"
|
||||
Login
|
||||
</Typography>
|
||||
<Typography
|
||||
component="h6"
|
||||
variant="subtitle2"
|
||||
sx={{
|
||||
width: "100%",
|
||||
textAlign: "center",
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
Log in with your email and password
|
||||
</Typography>
|
||||
<FormControl>
|
||||
<FormLabel
|
||||
htmlFor="email"
|
||||
sx={{
|
||||
width: "100%",
|
||||
textAlign: "center",
|
||||
fontSize: "1rem",
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
Login
|
||||
</Typography>
|
||||
<Typography
|
||||
component="h6"
|
||||
variant="subtitle2"
|
||||
Email
|
||||
</FormLabel>
|
||||
<Controller
|
||||
name="email"
|
||||
control={control}
|
||||
defaultValue=""
|
||||
rules={{
|
||||
required: "Email is required",
|
||||
pattern: {
|
||||
value: /\S+@\S+\.\S+/,
|
||||
message:
|
||||
"Please enter a valid email address.",
|
||||
},
|
||||
}}
|
||||
render={({ field }) => (
|
||||
<TextField
|
||||
{...field}
|
||||
error={!!errors.email}
|
||||
helperText={
|
||||
errors.email?.message
|
||||
}
|
||||
id="email"
|
||||
type="email"
|
||||
placeholder="Email"
|
||||
autoComplete="email"
|
||||
autoFocus
|
||||
required
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
|
||||
color={
|
||||
errors.email
|
||||
? "error"
|
||||
: "primary"
|
||||
}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<FormControl>
|
||||
<FormLabel
|
||||
htmlFor="password"
|
||||
sx={{
|
||||
width: "100%",
|
||||
textAlign: "center",
|
||||
fontSize: "1rem",
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
Log in with your email and password
|
||||
</Typography>
|
||||
<FormControl>
|
||||
<FormLabel
|
||||
htmlFor="email"
|
||||
sx={{ fontSize: "1rem" }}
|
||||
>
|
||||
Email
|
||||
</FormLabel>
|
||||
<Controller
|
||||
name="email"
|
||||
control={control}
|
||||
defaultValue=""
|
||||
rules={{
|
||||
required: "Email is required",
|
||||
pattern: {
|
||||
value: /\S+@\S+\.\S+/,
|
||||
message:
|
||||
"Please enter a valid email address.",
|
||||
},
|
||||
}}
|
||||
render={({ field }) => (
|
||||
Password
|
||||
</FormLabel>
|
||||
<Controller
|
||||
name="password"
|
||||
control={control}
|
||||
defaultValue=""
|
||||
rules={{
|
||||
required: "Password is required",
|
||||
minLength: {
|
||||
value: 6,
|
||||
message:
|
||||
"Password must be at least 6 characters long.",
|
||||
},
|
||||
}}
|
||||
render={({ field }) => (
|
||||
<Box
|
||||
sx={{
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
<TextField
|
||||
{...field}
|
||||
error={!!errors.email}
|
||||
error={!!errors.password}
|
||||
helperText={
|
||||
errors.email?.message
|
||||
errors.password?.message
|
||||
}
|
||||
id="email"
|
||||
type="email"
|
||||
placeholder="Email"
|
||||
autoComplete="email"
|
||||
name="password"
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
id="password"
|
||||
autoComplete="current-password"
|
||||
autoFocus
|
||||
required
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
color={
|
||||
errors.email
|
||||
errors.password
|
||||
? "error"
|
||||
: "primary"
|
||||
}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<FormControl>
|
||||
<FormLabel
|
||||
htmlFor="password"
|
||||
sx={{ fontSize: "1rem" }}
|
||||
>
|
||||
Password
|
||||
</FormLabel>
|
||||
<Controller
|
||||
name="password"
|
||||
control={control}
|
||||
defaultValue=""
|
||||
rules={{
|
||||
required:
|
||||
"Password is required",
|
||||
minLength: {
|
||||
value: 6,
|
||||
message:
|
||||
"Password must be at least 6 characters long.",
|
||||
},
|
||||
}}
|
||||
render={({ field }) => (
|
||||
<Box
|
||||
<IconButton
|
||||
sx={{
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
<TextField
|
||||
{...field}
|
||||
error={
|
||||
!!errors.password
|
||||
}
|
||||
helperText={
|
||||
errors.password
|
||||
?.message
|
||||
}
|
||||
name="password"
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
id="password"
|
||||
autoComplete="current-password"
|
||||
autoFocus
|
||||
required
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
color={
|
||||
errors.password
|
||||
? "error"
|
||||
: "primary"
|
||||
}
|
||||
/>
|
||||
<IconButton
|
||||
sx={{
|
||||
position:
|
||||
"absolute",
|
||||
top: "50%",
|
||||
right: "10px",
|
||||
background: "none",
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
right: "10px",
|
||||
background: "none",
|
||||
borderColor:
|
||||
"transparent",
|
||||
transform:
|
||||
"translateY(-50%)",
|
||||
"&:hover": {
|
||||
backgroundColor:
|
||||
"transparent",
|
||||
borderColor:
|
||||
"transparent",
|
||||
transform:
|
||||
"translateY(-50%)",
|
||||
"&:hover": {
|
||||
backgroundColor:
|
||||
"transparent", // Darker shade on hover
|
||||
borderColor:
|
||||
"transparent",
|
||||
},
|
||||
}}
|
||||
onClick={() =>
|
||||
setShowPassword(
|
||||
(prev) => !prev
|
||||
)
|
||||
}
|
||||
>
|
||||
{showPassword ? (
|
||||
<VisibilityOff />
|
||||
) : (
|
||||
<Visibility />
|
||||
)}
|
||||
</IconButton>
|
||||
</Box>
|
||||
)}
|
||||
/>
|
||||
</FormControl>
|
||||
<Box
|
||||
},
|
||||
}}
|
||||
onClick={() =>
|
||||
setShowPassword(
|
||||
(prev) => !prev
|
||||
)
|
||||
}
|
||||
>
|
||||
{showPassword ? (
|
||||
<VisibilityOff />
|
||||
) : (
|
||||
<Visibility />
|
||||
)}
|
||||
</IconButton>
|
||||
</Box>
|
||||
)}
|
||||
/>
|
||||
</FormControl>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
value="remember"
|
||||
color="primary"
|
||||
/>
|
||||
}
|
||||
label="Remember me"
|
||||
/>
|
||||
|
||||
<Link
|
||||
component="button"
|
||||
type="button"
|
||||
onClick={handleClickOpen}
|
||||
variant="body2"
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignSelf: "center",
|
||||
color: "#01579b",
|
||||
}}
|
||||
>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
value="remember"
|
||||
color="primary"
|
||||
/>
|
||||
}
|
||||
label="Remember me"
|
||||
/>
|
||||
Forgot password?
|
||||
</Link>
|
||||
</Box>
|
||||
<ForgotPassword
|
||||
open={open}
|
||||
handleClose={handleClose}
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
fullWidth
|
||||
// variant="contained"
|
||||
// color="primary"
|
||||
sx={{
|
||||
color: "white",
|
||||
backgroundColor: "#52ACDF",
|
||||
"&:hover": {
|
||||
backgroundColor: "#52ACDF",
|
||||
opacity: 0.9,
|
||||
},
|
||||
}}
|
||||
>
|
||||
Login
|
||||
</Button>
|
||||
|
||||
<Link
|
||||
component="button"
|
||||
type="button"
|
||||
onClick={handleClickOpen}
|
||||
variant="body2"
|
||||
sx={{ alignSelf: "center" }}
|
||||
>
|
||||
Forgot your password?
|
||||
</Link>
|
||||
</Box>
|
||||
<ForgotPassword
|
||||
open={open}
|
||||
handleClose={handleClose}
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
fullWidth
|
||||
variant="contained"
|
||||
color="secondary"
|
||||
>
|
||||
Sign in
|
||||
</Button>
|
||||
|
||||
{/* <Divider>or</Divider>
|
||||
{/* <Divider>or</Divider>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
|
@ -374,12 +336,11 @@ export default function Login(props: { disableCustomTheme?: boolean }) {
|
|||
</Link>
|
||||
</Typography>
|
||||
</Box> */}
|
||||
</Box>
|
||||
</Card>
|
||||
</Grid>
|
||||
</Box>
|
||||
</Card>
|
||||
</Grid>
|
||||
</SignInContainer>
|
||||
</AppTheme>
|
||||
</ThemeProvider>
|
||||
</Grid>
|
||||
</SignInContainer>
|
||||
</AppTheme>
|
||||
);
|
||||
}
|
||||
|
|
31
src/pages/Auth/Login/styled.css.tsx
Normal file
31
src/pages/Auth/Login/styled.css.tsx
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { styled} from "@mui/material/styles";
|
||||
import {
|
||||
Stack,
|
||||
Card as MuiCard
|
||||
} from "@mui/material";
|
||||
// eslint-disable-next-line @typescript-eslint/no-redeclare, @typescript-eslint/no-unused-vars
|
||||
export const Card = styled(MuiCard)(({ theme }) => ({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignSelf: "center",
|
||||
width: "100%",
|
||||
padding: theme.spacing(4),
|
||||
gap: theme.spacing(2),
|
||||
margin: "16px",
|
||||
backgroundColor: "#1E1F1F",
|
||||
[theme.breakpoints.up("sm")]: {
|
||||
maxWidth: "450px",
|
||||
},
|
||||
}));
|
||||
|
||||
export const SignInContainer = styled(Stack)(() => ({
|
||||
height: "calc((1 - var(--template-frame-height, 0)) * 100dvh)",
|
||||
minHeight: "100%",
|
||||
"&::before": {
|
||||
content: '""',
|
||||
display: "block",
|
||||
position: "absolute",
|
||||
zIndex: -1,
|
||||
inset: 0,
|
||||
},
|
||||
}));
|
Loading…
Reference in a new issue