feat: login and routes finally ok

issue #46
This commit is contained in:
Ricardo Campos
2024-09-19 12:10:55 -03:00
parent ea5c563b20
commit d267635c73
12 changed files with 189 additions and 44 deletions
+11 -4
View File
@@ -1,5 +1,5 @@
import React, { useContext, useEffect } from 'react';
import { createBrowserRouter, RouteObject, RouterProvider } from 'react-router-dom';
import { createBrowserRouter, Navigate, RouteObject, RouterProvider } from 'react-router-dom';
import AuthContext from './context/AuthContext';
import BrowserRoutes from './routes';
@@ -9,6 +9,7 @@ import Layout from './layout/PrivateLayout';
import Landing from './views/Landing';
import Login from './views/Login';
import NotFound from './views/NotFound';
import Register from './views/Register';
import './styles/custom.scss';
@@ -21,9 +22,17 @@ const App: React.FC = () => {
element: <Landing />
},
{
path: '/signin',
path: '/login',
element: <Login />
},
{
path: '/register',
element: <Register />
},
{
path: '/home',
element: <Navigate to={"/login"} replace />
},
{
path: '*',
element: <NotFound />
@@ -49,10 +58,8 @@ const App: React.FC = () => {
const getBrowserRouter = () => {
if (signed) {
console.log('app signed');
return createBrowserRouter(signedRouter);
}
console.log('app not signed');
return createBrowserRouter(notSignedRouter);
};
+4 -4
View File
@@ -7,10 +7,10 @@ const server = env.VITE_BACKEND_SERVER;
/**
*
*/
async function privateSessionState(signed: boolean): Promise<SigninResponse | undefined> {
async function privateSessionState(): Promise<SigninResponse | undefined> {
const tokenState = localStorage.getItem(API_TOKEN);
if (signed && tokenState) {
if (tokenState) {
const response = await fetch(ApiConfig.refreshTokenUrl, {
method: 'GET',
mode: 'cors',
@@ -38,7 +38,7 @@ const ApiConfig = {
refreshTokenUrl: `${server}/rest/user-sessions/refresh`,
signin: async (email: string, password: string): Promise<SigninResponse | undefined> => {
login: async (email: string, password: string): Promise<SigninResponse | undefined> => {
try {
const response = await fetch(ApiConfig.signinUrl, {
method: 'POST',
@@ -56,7 +56,7 @@ const ApiConfig = {
token: data.token
};
} else {
console.error('signin error', response);
console.error('login error', response);
}
}
catch (error) {
+1 -1
View File
@@ -5,7 +5,7 @@ export interface AuthContextData {
signed: boolean;
user: User | undefined;
checkCurrentAuthUser: (pathname: string) => Promise<void>;
signIn: (email: string, password: string) => void;
signIn: (email: string, password: string) => Promise<void>;
signOut: () => void;
isAdmin: boolean;
}
+2 -4
View File
@@ -19,7 +19,7 @@ const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }: Pro
const fetchCurrentSession = async (pathname: string): Promise<SigninResponse | undefined> => {
try {
const bearerToken: SigninResponse | undefined = await ApiConfig.currentSessionState(signed);
const bearerToken: SigninResponse | undefined = await ApiConfig.currentSessionState();
if (bearerToken && bearerToken.token) {
setSigned(true);
}
@@ -47,16 +47,14 @@ const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }: Pro
};
const checkCurrentAuthUser = async (pathname: string): Promise<void> => {
console.log('checkCurrentAuthUser', pathname);
const bearerToken: SigninResponse | undefined = await fetchCurrentSession(pathname);
if (bearerToken && bearerToken.token) {
console.log('checkCurrentAuthUser token', bearerToken);
updateUserSession(null, bearerToken.token);
}
};
const signIn = async (email: string, password: string): Promise<void> => {
const bearerToken: SigninResponse | undefined = await ApiConfig.signin(email, password);
const bearerToken: SigninResponse | undefined = await ApiConfig.login(email, password);
if (bearerToken && bearerToken.token) {
const currentUser: User = {
email
@@ -8,7 +8,6 @@ import Footer from '../../components/Footer';
*
*/
function Layout() {
console.log('Layout');
return (
<>
<Header />
+7 -9
View File
@@ -1,9 +1,7 @@
import React from 'react';
import { Navigate, RouteObject } from 'react-router-dom';
import getStoredPath from '../utils/PathUtils';
import Home from '../views/Home';
import About from '../views/About';
import NotFound from '../views/NotFound';
const BrowserRoutes: RouteObject[] = [
{
@@ -15,7 +13,13 @@ const BrowserRoutes: RouteObject[] = [
{
path: '/login',
element: (
<Navigate to="/home" replace />
<Navigate to={"/home"} replace />
)
},
{
path: '/register',
element: (
<Navigate to={"/home"} replace />
)
},
{
@@ -29,12 +33,6 @@ const BrowserRoutes: RouteObject[] = [
element: (
<About />
)
},
{
path: '/404',
element: (
<NotFound />
)
}
];
+6 -5
View File
@@ -1,10 +1,11 @@
$theme-colors: (
'info': tomato,
'danger': teal
);
//$theme-colors: (
// 'info': tomato,
// 'danger': teal,
// 'primary': green,
//);
@import '~bootstrap/scss/bootstrap';
.bg-body-secondary {
background-color: red;
}
}
-2
View File
@@ -4,8 +4,6 @@ import React from 'react';
*
*/
function Home() {
console.log('This is home!');
return (
<h1>This is home!</h1>
);
+17 -5
View File
@@ -1,4 +1,4 @@
import React, { useContext, useEffect } from 'react';
import React, { useCallback, useContext, useEffect } from 'react';
import { Button } from 'react-bootstrap';
import './styles.scss';
import { useNavigate } from 'react-router-dom';
@@ -12,14 +12,18 @@ function Landing() {
const navigate = useNavigate();
const handleLogin = () => {
console.log('Landing signed', signed);
console.log('Landing handleLogin signed', signed);
if (signed) {
navigate('/home');
goTo('/home');
} else {
navigate('/signin');
goTo('/login');
}
};
const goTo = useCallback((page: string) => {
navigate(page);
}, []);
useEffect(() => {
checkCurrentAuthUser(window.location.pathname);
}, []);
@@ -29,9 +33,17 @@ function Landing() {
<h1>This is landing page</h1>
<Button
type="button"
variant="primary"
onClick={handleLogin}
>
SignIn
Login
</Button>
<Button
variant="seconday"
type="button"
onClick={() => goTo("/register")}
>
Register
</Button>
</>
);
+28 -7
View File
@@ -1,13 +1,14 @@
import React, { useContext, useEffect, useState } from 'react';
import React, { useCallback, useContext, useEffect, useState } from 'react';
import { Alert, Button, Col, Form } from 'react-bootstrap';
import AuthContext from '../../context/AuthContext';
import { redirect } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
/**
* Created the Login component.
*/
function Login() {
const { signIn } = useContext(AuthContext);
const navigate = useNavigate();
const [validated, setValidated] = useState<boolean>(true);
const [formInvalid, setFormInvalid] = useState<boolean>(false);
@@ -18,18 +19,19 @@ function Login() {
const form = event.currentTarget;
if (form.checkValidity() === false) {
console.log('something is invalid!');
setFormInvalid(true);
return;
}
setFormInvalid(false);
console.log(`email=${form.email.value}, password=${form.password.value}`);
await signIn(form.email.value, form.password.value);
console.log('finished!? login component!?');
redirect("/home");
goTo("/home");
};
const goTo = useCallback((page: string) => {
navigate(page);
}, []);
useEffect(() => {}, [formInvalid]);
return (
@@ -56,11 +58,30 @@ function Login() {
/>
</Form.Group>
<Button variant="primary" type="submit">
<Button
variant="primary"
type="submit"
>
Login
</Button>
</Form>
<Button
variant="seconday"
type="button"
onClick={() => goTo("/register")}
>
Register
</Button>
<Button
variant="seconday"
type="button"
onClick={() => goTo("/")}
>
Back to home
</Button>
{formInvalid ? (
<Alert variant={"danger"}>
Something is wrong! Check your email and password!
+19 -2
View File
@@ -1,11 +1,28 @@
import React from 'react';
import React, { useCallback } from 'react';
import { Button } from 'react-bootstrap';
import { useNavigate } from 'react-router-dom';
/**
*
*/
function NotFound() {
const navigate = useNavigate();
const goTo = useCallback((page: string) => {
navigate(page);
}, []);
return (
<h2>Not found!</h2>
<>
<h2>Not found!</h2>
<Button
type="button"
variant="primary"
onClick={() => goTo('/')}
>
Back to index
</Button>
</>
);
}
+94
View File
@@ -0,0 +1,94 @@
import React, { useCallback, useContext, useEffect, useState } from 'react';
import { Alert, Button, Col, Form } from 'react-bootstrap';
import AuthContext from '../../context/AuthContext';
import { useNavigate } from 'react-router-dom';
/**
* Created the Login component.
*/
function Login() {
const { signIn } = useContext(AuthContext);
const navigate = useNavigate();
const [validated, setValidated] = useState<boolean>(true);
const [formInvalid, setFormInvalid] = useState<boolean>(false);
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
event.stopPropagation();
setValidated(true);
const form = event.currentTarget;
if (form.checkValidity() === false) {
setFormInvalid(true);
return;
}
setFormInvalid(false);
await signIn(form.email.value, form.password.value);
goTo("/home");
};
const goTo = useCallback((page: string) => {
navigate(page);
}, []);
useEffect(() => {}, [formInvalid]);
return (
<>
<h1>This is register page</h1>
<Form noValidate validated={validated} onSubmit={handleSubmit}>
<Form.Group as={Col} md="4" className="mb-3" controlId="formBasicEmail">
<Form.Label>Email address</Form.Label>
<Form.Control
required
type="email"
name="email"
placeholder="Enter email"
/>
</Form.Group>
<Form.Group as={Col} md="4" className="mb-3" controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control
required
type="password"
name="password"
placeholder="Password"
/>
</Form.Group>
<Button
variant="primary"
type="submit"
>
Register
</Button>
</Form>
<Button
variant="seconday"
type="button"
onClick={() => goTo("/login")}
>
Go to login instead
</Button>
<Button
variant="seconday"
type="button"
onClick={() => goTo("/")}
>
Back to home
</Button>
{formInvalid ? (
<Alert variant={"danger"}>
Something is wrong! Check your email and password!
</Alert>
) : null}
</>
);
}
export default Login;