mirror of
https://github.com/TurTaskProject/TurTaskWeb.git
synced 2025-12-19 22:14:07 +01:00
Modify Login Page
This commit is contained in:
parent
97e1557a56
commit
93c8df313f
@ -3,12 +3,11 @@ import { BrowserRouter, Route, Routes, Link } from 'react-router-dom';
|
||||
|
||||
import TestAuth from './components/testAuth';
|
||||
import IconSideNav from './components/IconSideNav';
|
||||
import AuthenticantionPage from './components/authentication/AuthenticationPage';
|
||||
import LoginPage from './components/authentication/LoginPage';
|
||||
import SignUpPage from './components/authentication/SignUpPage';
|
||||
import NavBar from './components/Nav/Navbar';
|
||||
import Home from './components/Home';
|
||||
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
@ -16,7 +15,7 @@ const App = () => {
|
||||
<NavBar/>
|
||||
<Routes>
|
||||
<Route path="/" element={<Home/>}/>
|
||||
<Route path="/login" element={<AuthenticantionPage/>}/>
|
||||
<Route path="/login" element={<LoginPage/>}/>
|
||||
<Route path="/signup" element={<SignUpPage/>}/>
|
||||
<Route path="/testAuth" element={<TestAuth/>}/>
|
||||
</Routes>
|
||||
|
||||
@ -1,206 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useGoogleLogin } from '@react-oauth/google';
|
||||
import Avatar from '@mui/material/Avatar';
|
||||
import Button from '@mui/material/Button';
|
||||
import CssBaseline from '@mui/material/CssBaseline';
|
||||
import TextField from '@mui/material/TextField';
|
||||
import FormControlLabel from '@mui/material/FormControlLabel';
|
||||
import Checkbox from '@mui/material/Checkbox';
|
||||
import Link from '@mui/material/Link';
|
||||
import Divider from '@mui/material/Divider';
|
||||
import Paper from '@mui/material/Paper';
|
||||
import Box from '@mui/material/Box';
|
||||
import Grid from '@mui/material/Grid';
|
||||
import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
||||
|
||||
import refreshAccessToken from './refreshAcesstoken';
|
||||
import axiosapi from '../../api/axiosapi';
|
||||
|
||||
|
||||
function Copyright(props) {
|
||||
return (
|
||||
<Typography variant="body2" color="text.secondary" align="center" {...props}>
|
||||
{'Copyright © '}
|
||||
<Link color="inherit" href="https://github.com/TurTaskProject/TurTaskWeb">
|
||||
TurTask
|
||||
</Link>{' '}
|
||||
{new Date().getFullYear()}
|
||||
{'.'}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const defaultTheme = createTheme();
|
||||
|
||||
export default function SignInSide() {
|
||||
|
||||
const Navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
if (!refreshAccessToken()) {
|
||||
Navigate("/");
|
||||
}
|
||||
}, []);
|
||||
|
||||
const [email, setEmail] = useState("");
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
|
||||
const handleUsernameChange = (event) => {
|
||||
setUsername(event.target.value);
|
||||
}
|
||||
|
||||
const handleEmailChange = (event) => {
|
||||
setEmail(event.target.value);
|
||||
}
|
||||
|
||||
const handlePasswordChange = (event) => {
|
||||
setPassword(event.target.value);
|
||||
}
|
||||
|
||||
const handleSubmit = (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
// Send a POST request to the authentication API
|
||||
axiosapi.apiUserLogin({
|
||||
email: email,
|
||||
username: username,
|
||||
password: password
|
||||
}).then(res => {
|
||||
// On successful login, store tokens and set the authorization header
|
||||
localStorage.setItem('access_token', res.data.access);
|
||||
localStorage.setItem('refresh_token', res.data.refresh);
|
||||
axiosapi.axiosInstance.defaults.headers['Authorization'] = "Bearer " + res.data.access;
|
||||
Navigate('/');
|
||||
}).catch(err => {
|
||||
console.log('Login failed'); // Handle login failure
|
||||
console.log(err)
|
||||
});
|
||||
}
|
||||
|
||||
const googleLoginImplicit = useGoogleLogin({
|
||||
flow: 'auth-code',
|
||||
redirect_uri: 'postmessage',
|
||||
onSuccess: async (response) => {
|
||||
try {
|
||||
const loginResponse = await axiosapi.googleLogin(response.code);
|
||||
if (loginResponse && loginResponse.data) {
|
||||
const { access_token, refresh_token } = loginResponse.data;
|
||||
|
||||
// Save the tokens in localStorage
|
||||
localStorage.setItem('access_token', access_token);
|
||||
localStorage.setItem('refresh_token', refresh_token);
|
||||
Navigate('/');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error with the POST request:', error);
|
||||
}
|
||||
},
|
||||
onError: errorResponse => console.log(errorResponse),
|
||||
});
|
||||
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={defaultTheme}>
|
||||
<Grid container component="main" sx={{ height: '100vh' }}>
|
||||
<CssBaseline />
|
||||
<Grid
|
||||
item
|
||||
xs={false}
|
||||
sm={4}
|
||||
md={7}
|
||||
sx={{
|
||||
backgroundImage: 'url(https://source.unsplash.com/random?wallpapers)',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundColor: (t) =>
|
||||
t.palette.mode === 'light' ? t.palette.grey[50] : t.palette.grey[900],
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
}}
|
||||
/>
|
||||
<Grid item xs={12} sm={8} md={5} component={Paper} elevation={6} square>
|
||||
<Box
|
||||
sx={{
|
||||
my: 8,
|
||||
mx: 4,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Avatar sx={{ m: 1, bgcolor: 'secondary.main' }}>
|
||||
<LockOutlinedIcon />
|
||||
</Avatar>
|
||||
<Typography component="h1" variant="h5">
|
||||
Sign in
|
||||
</Typography>
|
||||
<Box component="form" noValidate onSubmit={handleSubmit} sx={{ mt: 1 }}>
|
||||
<TextField
|
||||
margin="normal"
|
||||
required
|
||||
fullWidth
|
||||
id="email"
|
||||
label="Email Address"
|
||||
name="email"
|
||||
autoComplete="email"
|
||||
autoFocus
|
||||
onChange={handleEmailChange}
|
||||
/>
|
||||
<TextField
|
||||
margin="normal"
|
||||
required
|
||||
fullWidth
|
||||
name="password"
|
||||
label="Password"
|
||||
type="password"
|
||||
id="password"
|
||||
autoComplete="current-password"
|
||||
onChange={handlePasswordChange}
|
||||
/>
|
||||
<FormControlLabel
|
||||
control={<Checkbox value="remember" color="primary" />}
|
||||
label="Remember me"
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
fullWidth
|
||||
variant="contained"
|
||||
sx={{ mt: 3, mb: 2 }}
|
||||
>
|
||||
Sign In
|
||||
</Button>
|
||||
<Divider>OR</Divider>
|
||||
<Box py={2}>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={() => googleLoginImplicit()}
|
||||
>
|
||||
Sign in with Google 🚀
|
||||
</Button>
|
||||
</Box>
|
||||
<Grid container>
|
||||
<Grid item xs>
|
||||
<Link href="#" variant="body2">
|
||||
Forgot password?
|
||||
</Link>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Link href="#" variant="body2">
|
||||
{"Don't have an account? Sign Up"}
|
||||
</Link>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Copyright sx={{ mt: 5 }} />
|
||||
</Box>
|
||||
</Box>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
143
frontend/src/components/authentication/LoginPage.jsx
Normal file
143
frontend/src/components/authentication/LoginPage.jsx
Normal file
@ -0,0 +1,143 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useGoogleLogin } from "@react-oauth/google"
|
||||
|
||||
import refreshAccessToken from './refreshAcesstoken';
|
||||
import axiosapi from '../../api/axiosapi';
|
||||
|
||||
function LoginPage() {
|
||||
const Navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
if (!refreshAccessToken()) {
|
||||
Navigate("/");
|
||||
}
|
||||
}, []);
|
||||
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
|
||||
const handleEmailChange = event => {
|
||||
setEmail(event.target.value);
|
||||
};
|
||||
|
||||
const handlePasswordChange = event => {
|
||||
setPassword(event.target.value);
|
||||
};
|
||||
|
||||
const handleSubmit = event => {
|
||||
event.preventDefault();
|
||||
|
||||
// Send a POST request to the authentication API
|
||||
axiosapi
|
||||
.apiUserLogin({
|
||||
email: email,
|
||||
password: password,
|
||||
})
|
||||
.then(res => {
|
||||
// On successful login, store tokens and set the authorization header
|
||||
localStorage.setItem("access_token", res.data.access);
|
||||
localStorage.setItem("refresh_token", res.data.refresh);
|
||||
axiosapi.axiosInstance.defaults.headers["Authorization"] = "Bearer " + res.data.access;
|
||||
Navigate("/");
|
||||
})
|
||||
.catch(err => {
|
||||
console.log("Login failed");
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
|
||||
const googleLoginImplicit = useGoogleLogin({
|
||||
flow: "auth-code",
|
||||
redirect_uri: "postmessage",
|
||||
onSuccess: async response => {
|
||||
try {
|
||||
const loginResponse = await axiosapi.googleLogin(response.code);
|
||||
if (loginResponse && loginResponse.data) {
|
||||
const { access_token, refresh_token } = loginResponse.data;
|
||||
|
||||
localStorage.setItem("access_token", access_token);
|
||||
localStorage.setItem("refresh_token", refresh_token);
|
||||
Navigate("/");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error with the POST request:", error);
|
||||
}
|
||||
},
|
||||
onError: errorResponse => console.log(errorResponse),
|
||||
});
|
||||
|
||||
return (
|
||||
<html data-theme="night">
|
||||
<div className="min-h-screen flex">
|
||||
{/* Left Section (Login Box) */}
|
||||
<div className="w-1/2 flex items-center justify-center">
|
||||
<div className="w-96 bg-neutral rounded-lg p-8 shadow-md space-y-4">
|
||||
<h2 className="text-2xl font-semibold text-left">Log in to your account</h2>
|
||||
{/* Email Input */}
|
||||
<div className="form-control">
|
||||
<label className="label" htmlFor="email">
|
||||
<p className="text-bold">
|
||||
Email<span className="text-red-500 text-bold">*</span>
|
||||
</p>
|
||||
</label>
|
||||
<input
|
||||
className="input"
|
||||
type="email"
|
||||
id="email"
|
||||
placeholder="Enter your email"
|
||||
onChange={handleEmailChange}
|
||||
/>
|
||||
</div>
|
||||
{/* Password Input */}
|
||||
<div className="form-control">
|
||||
<label className="label" htmlFor="password">
|
||||
<p className="text-bold">
|
||||
Password<span className="text-red-500 text-bold">*</span>
|
||||
</p>
|
||||
</label>
|
||||
<input
|
||||
className="input"
|
||||
type="password"
|
||||
id="password"
|
||||
placeholder="Enter your password"
|
||||
onChange={handlePasswordChange}
|
||||
/>
|
||||
</div>
|
||||
{/* Login Button */}
|
||||
<button className="btn btn-primary w-full" onClick={handleSubmit}>
|
||||
Login
|
||||
</button>
|
||||
<div className="divider">OR</div>
|
||||
{/* Login with Google Button */}
|
||||
<button className="btn btn-outline btn-secondary w-full" onClick={() => googleLoginImplicit()}>
|
||||
Login with Google
|
||||
</button>
|
||||
{/* Forgot Password Link */}
|
||||
<div className="justify-left">
|
||||
<a href="#" className="text-blue-500 text-sm text-left">
|
||||
Forgot your password?
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right Section (Blurred Image Background) */}
|
||||
<div className="w-1/2 relative">
|
||||
<div
|
||||
className="w-full h-full bg-cover bg-center"
|
||||
style={{
|
||||
backgroundImage: 'url("https://th.bing.com/th/id/OIG.9byG0pWUCcbGL7Kly9tA?pid=ImgGn&w=1024&h=1024&rs=1")',
|
||||
filter: "blur(2px) brightness(.5)",
|
||||
}}></div>
|
||||
|
||||
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 text-white text-2xl font-semibold">
|
||||
Text Overlay
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
export default LoginPage;
|
||||
Loading…
Reference in New Issue
Block a user