auth WIP 2

This commit is contained in:
2025-08-28 18:37:26 +03:00
parent 533da219b3
commit d23546d6e0
9 changed files with 97 additions and 35 deletions

View File

@ -1,9 +1,16 @@
import { BrowserRouter as Router, Routes, Route, Navigate, Outlet, useLocation } from 'react-router-dom';
import {useContext } from "react";
import {useContext, useEffect, useState } from "react";
import AuthContext, { AuthProvider } from "./auth/auth-provider"
import ping from "./auth/ping";
import Login from "./pages/login/login"
import Register from "./pages/register/register"
import Home from "./pages/home/home"
import AuthContext, { AuthProvider } from "./auth/auth-provider"
import Dashboard from "./pages/dashboard/dashboard"
import Settings from "./pages/settings/settings"
import useAuth from './auth/auth';
function App() {
@ -16,7 +23,11 @@ function App() {
<Route element={<PrivateRoute />}>
<Route path='/' element={<Home />} />
<Route path='/dashboard' element={<Dashboard />} />
<Route path='/settings' element={<Settings />} />
</Route>
<Route path="*" element={<div>404</div>} />
</Routes>
</Router>
</AuthProvider>
@ -25,14 +36,34 @@ function App() {
const PrivateRoute = () => {
const { isAuthenticated } = useContext(AuthContext);
const { token } = useAuth();
const location = useLocation();
const [checked, setChecked] = useState(false);
const [isValid, setIsValid] = useState(false);
useEffect(() => {
const checkAuth = async () => {
if (!token) {
setIsValid(false);
setChecked(true);
return;
}
const result = await ping(token);
console.log(result)
setIsValid(result);
setChecked(true);
};
checkAuth();
}, [token]);
if (!checked) {
return <div>Checking server availability...</div>;
}
return (
isAuthenticated === true ?
<Outlet />
:
<Navigate to="/login" state={{ from: location }} replace />
isValid
? <Outlet />
: <Navigate to="/login" state={{ from: location }} replace />
);
}

View File

@ -9,7 +9,7 @@ type AuthContextType = {
const AuthContext = createContext<AuthContextType>({
token: null,
setToken: () => { },
setToken: () => {},
});
@ -20,15 +20,19 @@ export const AuthProvider = ({ children }: { children: JSX.Element }) => {
const savedToken = localStorage.getItem("token");
if (savedToken) {
setTokenState(savedToken);
console.log("meow")
}
console.log(savedToken)
}, []);
const setToken = (newToken: string | null) => {
setTokenState(newToken);
if (newToken) {
localStorage.setItem("token", newToken);
console.log("saved")
} else {
localStorage.removeItem("token");
console.log("removed")
}
};

View File

@ -3,9 +3,7 @@ import AuthContext from "./auth-provider"
function useAuth() {
return (
useContext(AuthContext)
);
return useContext(AuthContext);
}
export default useAuth;

View File

@ -1,12 +1,15 @@
import { useNavigate } from "react-router-dom";
import useAuth from "./auth";
const logout = () => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const { setToken: setAuth } = useAuth();
const useLogout = () => {
const { setToken } = useAuth();
const navigate = useNavigate();
return () => {
setAuth(false);
setToken(null);
navigate("/login");
};
}
export default logout;
export default useLogout;

View File

@ -1,16 +1,10 @@
const ping = () => {
const ping = async (token: string | null): Promise<boolean> => {
// TODO: request to API
return () => {
return true;
};
}
// const ping = async (token: string): Promise<boolean> => {
// return new Promise((resolve) => {
// setTimeout(() => {
// resolve(!!token);
// }, 300);
// });
// };
return new Promise((resolve) => {
setTimeout(() => {
resolve(!!token);
}, 300);
});
};
export default ping;

View File

@ -0,0 +1,9 @@
const Dashboard = () => {
return (
<div>
<h2>Dashboard</h2>
</div>
)
}
export default Dashboard;

View File

@ -1,11 +1,23 @@
import { useNavigate } from "react-router-dom";
import useAuth from "../../auth/auth";
import { Link } from 'react-router-dom';
import logout from "../../auth/logout"
import useLogout from "../../auth/logout"
const Home = () => {
const { setToken } = useAuth();
const navigate = useNavigate();
const handleLogout = () => {
setToken(null);
navigate("/login");
};
return (
<div>
<h2>Home</h2>
<button onClick={logout()}>
<button onClick={handleLogout}>
Logout
</button>
<nav>

View File

@ -2,24 +2,26 @@ import { useState } from "react";
import { useNavigate, useLocation } from "react-router-dom";
import useAuth from "../../auth/auth";
const Login = () => {
const { setToken: setAuth } = useAuth();
const { setToken } = useAuth();
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const navigate = useNavigate();
const location = useLocation();
const from = location.state?.from?.pathname || "/home";
const from = location.state?.from?.pathname || "/";
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// TODO: request to API
if (username === "admin" && password === "1234") {
setAuth(true);
const token = "todo.jwt.token";
setToken(token);
navigate(from, { replace: true });
} else {
alert("Неверный логин или пароль");
alert("Wrong login or password");
}
};

View File

@ -0,0 +1,9 @@
const Settings = () => {
return (
<div>
<h2>Settings</h2>
</div>
)
}
export default Settings;