Added base login func and some refactoring
This commit is contained in:
25
src/App.tsx
25
src/App.tsx
@@ -1,25 +1,30 @@
|
||||
import React from 'react';
|
||||
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
|
||||
import { AuthProvider } from './context/AuthContext';
|
||||
import ProtectedRoute from './components/ProtectedRoute';
|
||||
import Layout from './Layout';
|
||||
import HomePage from './pages/Home';
|
||||
import AboutPage from './pages/About';
|
||||
import Contact from './pages/Contact';
|
||||
import LoginPage from './pages/Login';
|
||||
|
||||
// import './App.css';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<Router>
|
||||
<Routes>
|
||||
{/* Layout route */}
|
||||
<Route path="/" element={<Layout />}>
|
||||
<Route index element={<HomePage />} />
|
||||
<Route path="about" element={<AboutPage />} />
|
||||
<Route path="contact" element={<Contact />} />
|
||||
<Route path="login" element={<LoginPage />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
<AuthProvider>
|
||||
<Routes>
|
||||
{/* Layout route */}
|
||||
<Route path="/" element={<Layout />}>
|
||||
<Route index element={<HomePage />} />
|
||||
<Route path="about" element={<AboutPage />} />
|
||||
<Route element={<ProtectedRoute />}>
|
||||
<Route path="contact" element={<Contact />} />
|
||||
</Route>
|
||||
<Route path="login" element={<LoginPage />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</AuthProvider>
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import React from 'react';
|
||||
import { Outlet, Link } from 'react-router-dom';
|
||||
import NewsletterSignup from './components/NewsletterSignup';
|
||||
import { useAuth } from './context/AuthContext';
|
||||
|
||||
const Layout: React.FC = () => {
|
||||
const { isAuthenticated, logout } = useAuth();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<nav className="navbar navbar-expand-lg navbar-light bg-light">
|
||||
@@ -21,7 +24,10 @@ const Layout: React.FC = () => {
|
||||
<Link className="nav-link" to="/contact">Contact</Link>
|
||||
</li>
|
||||
<li className="nav-item">
|
||||
<a className="btn btn-primary" href="/login">Sign Up</a>
|
||||
{isAuthenticated ?
|
||||
<button className="btn btn-danger" onClick={logout}>Logout</button> :
|
||||
<Link className="btn btn-primary" to="/login">Sign In</Link>
|
||||
}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { GetProducts } from '../services/CatalogAPI';
|
||||
import { GetProducts } from '../services/api/CatalogAPI';
|
||||
|
||||
function FeaturedProducts() {
|
||||
const [products, setProducts] = useState([]);
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Login } from '../services/IdentityAPI';
|
||||
import { Login } from '../services/api/IdentityAPI';
|
||||
import { useAuth } from '../context/AuthContext';
|
||||
|
||||
function LoginForm() {
|
||||
const { login } = useAuth();
|
||||
const [username, setUsername] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [message, setMessage] = useState('');
|
||||
const nav = useNavigate();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
@@ -15,11 +17,9 @@ function LoginForm() {
|
||||
const res = await Login(JSON.stringify({ username, password }));
|
||||
|
||||
if (res.status === 200) { // FIXME get rid of a magic numbers!@#
|
||||
console.log(res);
|
||||
// const body = await res.json();
|
||||
localStorage.setItem('token', res.data.token);
|
||||
login(res.data);
|
||||
|
||||
nav('/');
|
||||
navigate('/');
|
||||
}
|
||||
} catch (res) {
|
||||
setMessage('Login failed');
|
||||
|
||||
13
src/components/ProtectedRoute.tsx
Normal file
13
src/components/ProtectedRoute.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import React from 'react';
|
||||
import { Navigate, Outlet } from 'react-router-dom';
|
||||
import { useAuth } from '../context/AuthContext';
|
||||
|
||||
interface ProtectedRouteProps {}
|
||||
|
||||
const ProtectedRoute: React.FC<ProtectedRouteProps> = () => {
|
||||
const { isAuthenticated } = useAuth();
|
||||
|
||||
return isAuthenticated ? <Outlet /> : <Navigate to="/login" />;
|
||||
};
|
||||
|
||||
export default ProtectedRoute;
|
||||
39
src/context/AuthContext.tsx
Normal file
39
src/context/AuthContext.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import React, { ReactNode, createContext, useContext, useState } from 'react';
|
||||
|
||||
interface AuthContextType {
|
||||
isAuthenticated: boolean;
|
||||
login: (data: any) => void; // FIXME type any...
|
||||
logout: () => void;
|
||||
}
|
||||
|
||||
const AuthContext = createContext<AuthContextType | undefined>(undefined);
|
||||
|
||||
export const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
|
||||
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
||||
|
||||
const login = (data: any) => { // FIXME type any...
|
||||
// Here you'd typically call your login API
|
||||
setIsAuthenticated(true);
|
||||
localStorage.setItem('token', data.token);
|
||||
};
|
||||
|
||||
const logout = () => {
|
||||
setIsAuthenticated(false);
|
||||
localStorage.removeItem('token');
|
||||
};
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={{ isAuthenticated, login, logout }}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useAuth = () => {
|
||||
const context = useContext(AuthContext);
|
||||
if (!context) {
|
||||
throw new Error('useAuth must be used within an AuthProvider');
|
||||
}
|
||||
|
||||
return context;
|
||||
};
|
||||
Reference in New Issue
Block a user