parent
6252e66372
commit
01d8fba0fd
@ -1,9 +0,0 @@ |
||||
import React from 'react'; |
||||
import { render, screen } from '@testing-library/react'; |
||||
import App from './App'; |
||||
|
||||
test('renders learn react link', () => { |
||||
render(<App />); |
||||
const linkElement = screen.getByText(/learn react/i); |
||||
expect(linkElement).toBeInTheDocument(); |
||||
}); |
@ -1,26 +1,71 @@ |
||||
import React from 'react'; |
||||
import logo from './logo.svg'; |
||||
import './App.css'; |
||||
import 'bootstrap/dist/css/bootstrap.min.css' |
||||
import { BrowserRouter, Link, Navigate, Outlet, Route, Routes } from 'react-router-dom' |
||||
import './App.css' |
||||
import DSAuth from '../src/Services/Auth/Auth.Services' |
||||
import { Login } from './Components/Login/Login' |
||||
import { RptViajesPendientes } from './Components/Reportes/RptViajesPendientes' |
||||
import { Home } from './Components/Home/Home' |
||||
import { Protected } from './Components/Home/Protected/Protected' |
||||
import { useEffect } from 'react' |
||||
import ProtectedRoute, { ProtectedRouteProps } from './Components/ProtectedRoute/ProtectedRoute' |
||||
|
||||
function App() { |
||||
const Userlogued = (): boolean => { |
||||
DSAuth.Validate() |
||||
.then((response) => { |
||||
console.log('Crednciales validas') |
||||
return true |
||||
}) |
||||
.catch((e: Error) => { |
||||
console.log('Credenciales apocrifas') |
||||
return false |
||||
}) |
||||
return false |
||||
} |
||||
|
||||
useEffect(() => { |
||||
Userlogued() |
||||
console.log('Entro al proceso de router') |
||||
}, []) |
||||
|
||||
function PageNotFound() { |
||||
return ( |
||||
<div> |
||||
<h2>Sorry, no matching page</h2> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
const ProtectedRoute = ({ auth = false, redirectPath = '/login' }) => { |
||||
if (!auth) { |
||||
return <Navigate to={redirectPath} replace /> |
||||
} |
||||
|
||||
return <Outlet /> |
||||
} |
||||
|
||||
return ( |
||||
<div className="App"> |
||||
<header className="App-header"> |
||||
<img src={logo} className="App-logo" alt="logo" /> |
||||
<p> |
||||
Edit <code>src/App.tsx</code> and save to reload. |
||||
</p> |
||||
<a |
||||
className="App-link" |
||||
href="https://reactjs.org" |
||||
target="_blank" |
||||
rel="noopener noreferrer" |
||||
> |
||||
Learn React |
||||
</a> |
||||
</header> |
||||
<div className='App'> |
||||
<BrowserRouter> |
||||
<Link to='login'>login</Link> |
||||
<br /> |
||||
<Link to='RptViajesPendientes'>Reporte de viajes</Link> |
||||
<Routes> |
||||
<Route path='/' element={<Home />}></Route> |
||||
<Route path='login' element={<Login />}></Route> |
||||
<Route element={<ProtectedRoute auth={Userlogued()} />}> |
||||
<Route path='RptViajesPendientes' element={<RptViajesPendientes />} /> |
||||
</Route> |
||||
<Route path='*' element={<PageNotFound />} /> |
||||
</Routes> |
||||
</BrowserRouter> |
||||
</div> |
||||
); |
||||
) |
||||
} |
||||
|
||||
export default App; |
||||
export default App |
||||
|
||||
/* export default App |
||||
function useSessionContext(): [any, any] { |
||||
throw new Error('Function not implemented.') |
||||
} */ |
||||
|
@ -0,0 +1,13 @@ |
||||
import React, { FC } from 'react' |
||||
import { Outlet } from 'react-router-dom' |
||||
|
||||
interface IProps {} |
||||
|
||||
export const Home: FC<IProps> = (props) => { |
||||
return ( |
||||
<div> |
||||
<h1>This is the Guest Layout Page</h1> |
||||
<Outlet /> |
||||
</div> |
||||
) |
||||
} |
@ -0,0 +1,12 @@ |
||||
import React, { FC } from 'react' |
||||
|
||||
interface IProps {} |
||||
|
||||
/** |
||||
* @author |
||||
* @function @Protected |
||||
**/ |
||||
|
||||
export const Protected: FC<IProps> = (props) => { |
||||
return <div>Protected</div> |
||||
} |
@ -0,0 +1,97 @@ |
||||
import { FC, useEffect, useState } from 'react' |
||||
import { Navigate, useNavigate } from 'react-router-dom' |
||||
import IAuth from '../../Interfaces/Auth/IAuth' |
||||
import DSAuth from '../../Services/Auth/Auth.Services' |
||||
|
||||
interface IProps {} |
||||
|
||||
export const Login: FC<IProps> = (props) => { |
||||
const navigate = useNavigate() |
||||
const [Usuario, setUsuario] = useState('') |
||||
const [Contrasena, setContrasena] = useState('') |
||||
const [token, setToken] = useState<string>( |
||||
(window.localStorage.getItem('token') ? window.localStorage.getItem('token') : '')! |
||||
) |
||||
|
||||
const Login = () => { |
||||
const data: IAuth = { |
||||
usuario: Usuario, |
||||
contrasena: Contrasena, |
||||
} |
||||
DSAuth.login(data) |
||||
.then((response) => { |
||||
localStorage.setItem('token', response.data.token) |
||||
setToken(response.data.token) |
||||
window.location.href = 'http://localhost:3000/login' |
||||
}) |
||||
.catch((e: Error) => { |
||||
alert('Credeciales invalidas!') |
||||
}) |
||||
} |
||||
|
||||
const ValidateToken = () => { |
||||
if (token.length > 10) { |
||||
DSAuth.Validate() |
||||
.then((response) => { |
||||
navigate('../RptViajesPendientes', { replace: true }) |
||||
}) |
||||
.catch((e: Error) => { |
||||
// navigate('login', { replace: true })
|
||||
}) |
||||
} |
||||
} |
||||
|
||||
useEffect(() => { |
||||
ValidateToken() |
||||
}, []) |
||||
|
||||
useEffect(() => { |
||||
ValidateToken() |
||||
}, []) |
||||
|
||||
return ( |
||||
<div> |
||||
{token && <Navigate to='RptViajesPendientes' replace={true} />} |
||||
<div className='Auth-form-container'> |
||||
<form className='Auth-form'> |
||||
<div className='Auth-form-content'> |
||||
<h3 className='Auth-form-title'>AOL</h3> |
||||
<div className='form-group mt-3'> |
||||
<label>Usuario</label> |
||||
<input |
||||
type='email' |
||||
className='form-control mt-1' |
||||
placeholder='Usuario' |
||||
onChange={(e) => { |
||||
setUsuario(e.target.value) |
||||
}} |
||||
/> |
||||
</div> |
||||
<div className='form-group mt-3'> |
||||
<label>Contraseña</label> |
||||
<input |
||||
type='password' |
||||
className='form-control mt-1' |
||||
placeholder='Contraseña' |
||||
onChange={(e) => { |
||||
setContrasena(e.target.value) |
||||
}} |
||||
/> |
||||
</div> |
||||
<div className='d-grid gap-2 mt-3'> |
||||
<button |
||||
type='button' |
||||
className='btn btn-primary' |
||||
onClick={() => { |
||||
Login() |
||||
}} |
||||
> |
||||
login |
||||
</button> |
||||
</div> |
||||
</div> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
) |
||||
} |
@ -0,0 +1,32 @@ |
||||
import { useEffect } from 'react' |
||||
import { Navigate, useLocation } from 'react-router' |
||||
|
||||
export type ProtectedRouteProps = { |
||||
isAuthenticated: boolean |
||||
authenticationPath: string |
||||
redirectPath: string |
||||
setRedirectPath: (path: string) => void |
||||
outlet: JSX.Element |
||||
} |
||||
|
||||
export default function ProtectedRoute({ |
||||
isAuthenticated, |
||||
authenticationPath, |
||||
redirectPath, |
||||
setRedirectPath, |
||||
outlet, |
||||
}: ProtectedRouteProps) { |
||||
const currentLocation = useLocation() |
||||
|
||||
useEffect(() => { |
||||
if (!isAuthenticated) { |
||||
setRedirectPath(currentLocation.pathname) |
||||
} |
||||
}, [isAuthenticated, setRedirectPath, currentLocation]) |
||||
|
||||
if (isAuthenticated && redirectPath === currentLocation.pathname) { |
||||
return outlet |
||||
} else { |
||||
return <Navigate to={{ pathname: isAuthenticated ? redirectPath : authenticationPath }} /> |
||||
} |
||||
} |
@ -0,0 +1,7 @@ |
||||
import React, { FC } from 'react' |
||||
|
||||
interface IProps {} |
||||
|
||||
export const RptViajesPendientes: FC<IProps> = (props) => { |
||||
return <div>RptViajesPendientes</div> |
||||
} |
@ -0,0 +1,5 @@ |
||||
export class TargetURL { |
||||
get() { |
||||
return (!process.env.NODE_ENV || process.env.NODE_ENV === 'development') ? "https://localhost:7000/api" : "http://reportes.gemcousa.com:5000/api" |
||||
} |
||||
} |
@ -0,0 +1,4 @@ |
||||
export default interface IAuth { |
||||
usuario: string, |
||||
contrasena: string |
||||
} |
@ -0,0 +1,7 @@ |
||||
export default interface IMenu { |
||||
id: number, |
||||
descripcion: string, |
||||
padreId: number, |
||||
posicion: number, |
||||
url: string |
||||
} |
@ -0,0 +1,6 @@ |
||||
import IMenu from "./IMenu"; |
||||
|
||||
export default interface IPermisos { |
||||
menu : IMenu[], |
||||
token: string |
||||
} |
@ -0,0 +1,15 @@ |
||||
import http from "../../Services/Auth/config/http-common"; |
||||
import IAuth from "../../Interfaces/Auth/IAuth" |
||||
//import ItemMenuData from "../../Interfaces/Auth/IMenu";
|
||||
import IPermisos from "../../Interfaces/Auth/IPermisos"; |
||||
//import Token from '../../Interfaces/token'
|
||||
|
||||
class authDataService { |
||||
login(data: IAuth) { |
||||
return http.post<IPermisos>("Auth/Login", data); |
||||
} |
||||
Validate() { |
||||
return http.get<String>("Auth/Validate"); |
||||
} |
||||
} |
||||
export default new authDataService(); |
@ -0,0 +1,52 @@ |
||||
import axios from "axios"; |
||||
import { TargetURL } from '../../../Constants/TargetURL' |
||||
const token = localStorage.getItem("token"); |
||||
const URL = new TargetURL() |
||||
|
||||
const instance = axios.create({ |
||||
baseURL: URL.get(), |
||||
headers: { |
||||
"Content-type": "application/json", |
||||
"Authorization": (token) ? `Bearer ${token}` : ''
|
||||
}, |
||||
}); |
||||
|
||||
|
||||
instance.interceptors.response.use(function (response) { |
||||
//if (process.env.NODE_ENV === 'development') console.log('log: '+JSON.stringify(response))
|
||||
return response; |
||||
}, function (error) { |
||||
if ( (window.location.href.indexOf("login")>0) || (window.location.href.indexOf("reset")>0) ) { |
||||
return Promise.reject(error); |
||||
} |
||||
else if (401 === error.response.status) { |
||||
localStorage.clear(); |
||||
window.location.href = "/login"; |
||||
} else if ((409 === error.response.status) && (error.response.data.respuesta.indexOf('factura'))) { |
||||
console.log(JSON.stringify(error.response)) |
||||
if (error.response.data.registro.factura) { |
||||
(error.response.data.registro.id===-1) ? |
||||
alert(error.response.data.respuesta + |
||||
' en la factura: ' + |
||||
error.response.data.registro.factura + |
||||
' en el trafico: CG' + |
||||
error.response.data.registro.idTrafico) : |
||||
alert(error.response.data.respuesta + ' en TRADE')
|
||||
} |
||||
} else { |
||||
return Promise.reject(error); |
||||
} |
||||
}); |
||||
|
||||
|
||||
instance.interceptors.request.use(function (config) { |
||||
/* if (process.env.NODE_ENV === 'development') |
||||
console.log('log: '+JSON.stringify(config))*/ |
||||
return config;
|
||||
}, function (error) { |
||||
return Promise.reject(error); |
||||
}); |
||||
|
||||
|
||||
export default instance; |
||||
|
@ -1,19 +1,21 @@ |
||||
import React from 'react'; |
||||
import ReactDOM from 'react-dom/client'; |
||||
import './index.css'; |
||||
import App from './App'; |
||||
import reportWebVitals from './reportWebVitals'; |
||||
import React from 'react' |
||||
import ReactDOM from 'react-dom/client' |
||||
import './index.css' |
||||
import App from './App' |
||||
import { Provider } from 'react-redux' |
||||
import { store } from './store/store' |
||||
import reportWebVitals from './reportWebVitals' |
||||
|
||||
const root = ReactDOM.createRoot( |
||||
document.getElementById('root') as HTMLElement |
||||
); |
||||
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement) |
||||
root.render( |
||||
<React.StrictMode> |
||||
<App /> |
||||
</React.StrictMode> |
||||
); |
||||
<Provider store={store}> |
||||
<React.StrictMode> |
||||
<App /> |
||||
</React.StrictMode> |
||||
</Provider> |
||||
) |
||||
|
||||
// If you want to start measuring performance in your app, pass a function
|
||||
// to log results (for example: reportWebVitals(console.log))
|
||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||
reportWebVitals(); |
||||
reportWebVitals() |
||||
|
@ -0,0 +1,41 @@ |
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit' |
||||
import IMenu from '../../../Interfaces/Auth/IMenu'; |
||||
const MenuItems: IMenu[] = [{ id:0, descripcion:'', padreId:0, posicion:0, url:''}] |
||||
const initialState = { MenuItems } |
||||
|
||||
export const MenuItemsSlice = createSlice({ |
||||
name: 'MenuItems', |
||||
initialState: initialState, |
||||
reducers: { |
||||
populateMenuItems : (state, action: PayloadAction<IMenu[]>) => { |
||||
state.MenuItems = [] |
||||
state.MenuItems.push(... action.payload) |
||||
}, |
||||
addMenuItems : (state, action: PayloadAction<IMenu>) => { |
||||
var Existe = state.MenuItems.find(function(item) { |
||||
return item.id === action.payload.id; |
||||
}); |
||||
if (!Existe) state.MenuItems.push(action.payload) |
||||
}, |
||||
updateMenuItems : (state, action: PayloadAction<IMenu>) => { |
||||
const i = state.MenuItems.findIndex(_element => _element.id === action.payload.id); |
||||
if (i > -1) state.MenuItems[i] = action.payload; |
||||
else state.MenuItems.push(action.payload); |
||||
|
||||
}, |
||||
deleteMenuItems : (state, action: PayloadAction<number>) => { |
||||
const newArr = state.MenuItems.filter(data => data.id != action.payload); |
||||
state.MenuItems=newArr |
||||
}, |
||||
InitMenuItems : (state, action: PayloadAction<number>) => { |
||||
state.MenuItems.splice(0,state.MenuItems.length-1) |
||||
}, |
||||
}, |
||||
}) |
||||
|
||||
export const { addMenuItems,
|
||||
populateMenuItems,
|
||||
updateMenuItems,
|
||||
deleteMenuItems, |
||||
InitMenuItems } = MenuItemsSlice.actions; |
||||
export default MenuItemsSlice.reducer; |
@ -0,0 +1,12 @@ |
||||
import { configureStore } from '@reduxjs/toolkit' |
||||
import { MenuItemsSlice } from './features/Auth/MenuItemsSlice' |
||||
|
||||
|
||||
export const store = configureStore({ |
||||
reducer: { |
||||
// MenuItemsSlice: MenuItemsSlice
|
||||
} |
||||
}) |
||||
|
||||
export type RootState = ReturnType<typeof store.getState> |
||||
export type AppDispatch = typeof store.dispatch |
Loading…
Reference in new issue