mirror of
https://github.com/AmanTahiliani/PeerNotes.git
synced 2026-08-07 19:56:19 -04:00
finish login, logout, session context
This commit is contained in:
@@ -1,31 +1,56 @@
|
|||||||
import "./styles/App.css";
|
import "./styles/App.css";
|
||||||
import { Link } from 'react-router-dom';
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
import MainSearch from './components/MainSearch';
|
import MainSearch from './components/MainSearch';
|
||||||
|
import { SessionContext, destroySessionCookie, getSessionCookie } from "./contexts/session";
|
||||||
|
import { useState, useEffect, useContext } from "react";
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
|
const [session, setSession] = useState(getSessionCookie());
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
// Redirect to login if session is undefined
|
||||||
|
useEffect(
|
||||||
|
() => {
|
||||||
|
setSession(getSessionCookie());
|
||||||
|
if (session === undefined) {
|
||||||
|
navigate("/login");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[session, navigate]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Navbar />
|
<SessionContext.Provider value={session}>
|
||||||
<div className="App" style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', height: '90vh' , gap: 15}}>
|
<Navbar />
|
||||||
<img
|
<div className="App" style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', height: '90vh' , gap: 15}}>
|
||||||
src="/PeerNotes.png"
|
<img
|
||||||
alt="PeerNotes Logo"
|
src="/PeerNotes.png"
|
||||||
style={{
|
alt="PeerNotes Logo"
|
||||||
height: "100px"
|
style={{
|
||||||
}}
|
height: "100px"
|
||||||
/>
|
}}
|
||||||
<MainSearch />
|
/>
|
||||||
</div>
|
<MainSearch />
|
||||||
|
</div>
|
||||||
|
</SessionContext.Provider>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function Navbar() {
|
function Navbar() {
|
||||||
|
const session = useContext(SessionContext);
|
||||||
|
|
||||||
|
const links = session ? (
|
||||||
|
<>
|
||||||
|
<Link to="/">Home</Link>
|
||||||
|
<Link to="/login" onClick={destroySessionCookie}>Logout</Link>
|
||||||
|
</>
|
||||||
|
): (
|
||||||
|
<Link to="/login">Login</Link>
|
||||||
|
)
|
||||||
return (
|
return (
|
||||||
<nav>
|
<nav>
|
||||||
<Link to="/">Home</Link>
|
{links}
|
||||||
<Link to="/logout">Logout</Link>
|
|
||||||
</nav>
|
</nav>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
17
frontend/src/contexts/session.ts
Normal file
17
frontend/src/contexts/session.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
type SessionContextType = string | undefined;
|
||||||
|
|
||||||
|
export const getSessionCookie = () => {
|
||||||
|
const sessionCookie = document.cookie
|
||||||
|
.split('; ')
|
||||||
|
.find(row => row.startsWith('token='))
|
||||||
|
?.split('=')[1];
|
||||||
|
return sessionCookie;
|
||||||
|
}
|
||||||
|
export const destroySessionCookie = () => {
|
||||||
|
document.cookie = "token=; Max-Age=0;"
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SessionContext = React.createContext<SessionContextType>(getSessionCookie());
|
||||||
|
|
||||||
14
frontend/src/hooks/sessionRedirect.ts
Normal file
14
frontend/src/hooks/sessionRedirect.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { useEffect, useContext } from "react";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { SessionContext } from "../contexts/session";
|
||||||
|
|
||||||
|
export const useSessionRedirect = () => {
|
||||||
|
const session = useContext(SessionContext);
|
||||||
|
const navigate = useNavigate();
|
||||||
|
// Redirect to home if session is defined
|
||||||
|
useEffect(() => {
|
||||||
|
if (session !== undefined) {
|
||||||
|
navigate('/');
|
||||||
|
}
|
||||||
|
}, [session, navigate])
|
||||||
|
}
|
||||||
@@ -1,40 +1,48 @@
|
|||||||
import { Link } from "react-router-dom"
|
import { Link, useNavigate } from "react-router-dom"
|
||||||
import "../styles/Login.css"
|
import "../styles/Login.css"
|
||||||
import { FormEvent } from "react";
|
import { FormEvent } from "react";
|
||||||
|
import { useSessionRedirect } from "../hooks/sessionRedirect";
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
function handleSubmit(e: FormEvent) {
|
const navigate = useNavigate();
|
||||||
e.preventDefault();
|
|
||||||
const formData = new FormData(e.target as HTMLFormElement);
|
useSessionRedirect();
|
||||||
const username = formData.get('username');
|
|
||||||
const password = formData.get('password');
|
function handleSubmit(e: FormEvent) {
|
||||||
fetch('http://localhost:8000/api/login/', {
|
e.preventDefault();
|
||||||
method: 'POST',
|
const formData = new FormData(e.target as HTMLFormElement);
|
||||||
credentials: 'include',
|
const username = formData.get('username');
|
||||||
headers: {
|
const password = formData.get('password');
|
||||||
'Content-Type': 'application/json',
|
fetch('http://localhost:8000/api/login/', {
|
||||||
},
|
method: 'POST',
|
||||||
body: JSON.stringify({ username, password }),
|
credentials: 'include',
|
||||||
})
|
headers: {
|
||||||
.catch((error) => {
|
'Content-Type': 'application/json',
|
||||||
console.error('Error:', error);
|
},
|
||||||
});
|
body: JSON.stringify({ username, password }),
|
||||||
}
|
})
|
||||||
return (
|
.then(() => {
|
||||||
<main>
|
navigate('/');
|
||||||
<form className="login-container" onSubmit={handleSubmit}>
|
})
|
||||||
<h1>Login</h1>
|
.catch((error) => {
|
||||||
<div className="form-input">
|
console.error('Error:', error);
|
||||||
<label htmlFor="username">Username</label>
|
});
|
||||||
<input type="text" name="username" id="username" />
|
}
|
||||||
</div>
|
return (
|
||||||
<div className="form-input">
|
<main>
|
||||||
<label htmlFor="password">Password</label>
|
<form className="login-container" onSubmit={handleSubmit}>
|
||||||
<input type="password" name="password" id="password" />
|
<h1>Login</h1>
|
||||||
</div>
|
<div className="form-input">
|
||||||
<button className="submit-button">Login</button>
|
<label htmlFor="username">Username</label>
|
||||||
<p>or <Link to="/signup">Sign up</Link></p>
|
<input type="text" name="username" id="username" />
|
||||||
</form>
|
</div>
|
||||||
</main>
|
<div className="form-input">
|
||||||
);
|
<label htmlFor="password">Password</label>
|
||||||
|
<input type="password" name="password" id="password" />
|
||||||
|
</div>
|
||||||
|
<button className="submit-button">Login</button>
|
||||||
|
<p>or <Link to="/signup">Sign up</Link></p>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
import { Link } from "react-router-dom";
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
import "../styles/Login.css"
|
import "../styles/Login.css"
|
||||||
import { FormEvent } from "react";
|
import { FormEvent } from "react";
|
||||||
|
import { useSessionRedirect } from "../hooks/sessionRedirect";
|
||||||
export default function Signup() {
|
export default function Signup() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
useSessionRedirect();
|
||||||
|
|
||||||
function handleSubmit(e: FormEvent) {
|
function handleSubmit(e: FormEvent) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const formData = new FormData(e.target as HTMLFormElement);
|
const formData = new FormData(e.target as HTMLFormElement);
|
||||||
@@ -16,8 +20,8 @@ export default function Signup() {
|
|||||||
body: JSON.stringify({ email, username, password }),
|
body: JSON.stringify({ email, username, password }),
|
||||||
})
|
})
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(() => {
|
||||||
console.log('Success:', data);
|
navigate('/login');
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Error:', error);
|
console.error('Error:', error);
|
||||||
|
|||||||
Reference in New Issue
Block a user