Procesos como autenticacion, reset password, accept reset password ahora estaran en el controller Auth

develop
Al Garcia 2 years ago
parent be52fe1147
commit 9bd5fc4ec1
  1. 2
      src/App.tsx
  2. 202
      src/Components/Catalogos/CatUsuarios.tsx
  3. 5
      src/Components/Login/Login.tsx
  4. 135
      src/Components/Operaciones/OpMonitor.tsx
  5. 123
      src/Components/ResetAccount/ResetAccount.tsx
  6. 333
      src/Components/Utils/MFileManager/MFileManager.tsx
  7. 51
      src/Components/Utils/Toast/MsgInformativo.tsx
  8. 9
      src/Interfaces/Catalogos/ICatUsuarios.ts
  9. 9
      src/Interfaces/Utils/IFileManager.ts
  10. 5
      src/Services/Auth/Auth.Services.ts
  11. 17
      src/Services/Catalogos/CatUsuarios.Services.ts
  12. 26
      src/Services/Utils/MFileManager.Service.ts
  13. 6
      src/css/masterDetail.css
  14. BIN
      src/images/Clean.png

@ -17,6 +17,7 @@ import { CatRutas } from './Components/Catalogos/CatRutas'
import { OpMonitor } from './Components/Operaciones/OpMonitor' import { OpMonitor } from './Components/Operaciones/OpMonitor'
import { CatServicios } from './Components/Catalogos/CatServicios' import { CatServicios } from './Components/Catalogos/CatServicios'
import { CatUsuarios } from './Components/Catalogos/CatUsuarios' import { CatUsuarios } from './Components/Catalogos/CatUsuarios'
import { ResetAccount } from './Components/ResetAccount/ResetAccount'
function App() { function App() {
const UserLogued = useSelector((state: RootState) => state.UserProfile.UserProfile.logueado) const UserLogued = useSelector((state: RootState) => state.UserProfile.UserProfile.logueado)
@ -42,6 +43,7 @@ function App() {
<Route path='login' element={<Login />}></Route> */} <Route path='login' element={<Login />}></Route> */}
<Route path='/' element={<Login />}></Route> <Route path='/' element={<Login />}></Route>
<Route path='logout' element={<Logout />}></Route> <Route path='logout' element={<Logout />}></Route>
<Route path='reset' element={<ResetAccount />}></Route>
<Route element={<ProtectedRoute />}> <Route element={<ProtectedRoute />}>
<Route path='OpMonitor' element={<OpMonitor />} /> <Route path='OpMonitor' element={<OpMonitor />} />
<Route path='CatClientes' element={<CatClientes />} /> <Route path='CatClientes' element={<CatClientes />} />

@ -1,16 +1,118 @@
import React, { FC, useState } from 'react' import React, { FC, useEffect, useState } from 'react'
import { Card, Col, FloatingLabel, Form, Row } from 'react-bootstrap' import { Button, Card, Col, FloatingLabel, Form, Row } from 'react-bootstrap'
import { useSelector } from 'react-redux' import { useSelector } from 'react-redux'
import { RootState } from '../../store/store' import { RootState } from '../../store/store'
import DSCatUsuarios from '../../Services/Catalogos/CatUsuarios.Services'
import ICatUsuarios from '../../Interfaces/Catalogos/ICatUsuarios'
import DataTable from 'react-data-table-component'
import { IconContext } from 'react-icons'
import { BsFillPencilFill } from 'react-icons/bs'
import Clean from '../../images/Clean.png'
interface IProps {} interface IProps {}
export const CatUsuarios: FC<IProps> = (props) => { export const CatUsuarios: FC<IProps> = (props) => {
const mCatClientes = useSelector((state: RootState) => state.CatClientes.CatClientes) const mCatClientes = useSelector((state: RootState) => state.CatClientes.CatClientes)
const mCatProveedores = useSelector((state: RootState) => state.CatProveedores.CatProveedores) const mCatProveedores = useSelector((state: RootState) => state.CatProveedores.CatProveedores)
const [DataUsuarios, setDataUsuarios] = useState<ICatUsuarios[]>([])
const [IDUsuario, setIDUsuario] = useState(0)
const [Usuario, setUsuario] = useState('') const [Usuario, setUsuario] = useState('')
const [Nombre, setNombre] = useState('')
const [TipoUsuario, setTipoUsuario] = useState(0) const [TipoUsuario, setTipoUsuario] = useState(0)
const [Search, setSearch] = useState('') const [Search, setSearch] = useState('')
const [SearchUser, setSearchUser] = useState('')
const columnsConcepts = [
{
name: 'id',
width: '80px',
selector: (row: ICatUsuarios) => row.id,
sortable: true,
},
{
name: 'Nombre',
width: '250px',
selector: (row: ICatUsuarios) => row.nombre,
sortable: true,
},
{
name: 'Usuario',
width: '250px',
selector: (row: ICatUsuarios) => row.usuario,
sortable: true,
},
{
name: 'Activo',
width: '90px',
selector: (row: ICatUsuarios) => (row.activo === 1 ? 'Si' : 'No'),
sortable: true,
},
{
name: 'Editar',
width: '100px',
cell: (row: ICatUsuarios) => (
<div
style={{ textAlign: 'center', cursor: 'pointer' }}
onClick={() => {
showInfo(row)
}}
>
<IconContext.Provider value={{ color: 'blue', size: '21px' }}>
<BsFillPencilFill />
</IconContext.Provider>
</div>
),
sortable: true,
},
]
const showInfo = (row: ICatUsuarios) => {
setUsuario(row.usuario)
setNombre(row.nombre)
setTipoUsuario(row.tipoUsuario)
setIDUsuario(row.id)
}
const saveForm = () => {
const data: ICatUsuarios = {
id: IDUsuario,
usuario: Usuario,
contrasena: '',
nombre: Nombre,
tipoUsuario: TipoUsuario,
idPerfil: 0,
activo: 1,
}
DSCatUsuarios.Append(data)
.then((response) => {
cleanForm()
loadUsers()
})
.catch((e: Error) => {
alert('Ocurrio un error' + e.message.toString())
})
}
const loadUsers = () => {
DSCatUsuarios.GetAll()
.then((response) => {
console.log(response.data)
setDataUsuarios(response.data)
})
.catch((e: Error) => {
alert('Ocurrio un error' + e.message.toString())
})
}
const cleanForm = () => {
setUsuario('')
setNombre('')
setTipoUsuario(0)
setIDUsuario(0)
}
useEffect(() => {
loadUsers()
}, [])
return ( return (
<div> <div>
@ -22,12 +124,19 @@ export const CatUsuarios: FC<IProps> = (props) => {
<Card style={{ backgroundColor: 'rgba(245, 245, 245, 0.4)' }}> <Card style={{ backgroundColor: 'rgba(245, 245, 245, 0.4)' }}>
<Card.Body> <Card.Body>
<Row> <Row>
<Col xs={8}> <Col xs={7}>
<FloatingLabel controlId='TxtNombre' label='Nombre' className='mb-3'> <FloatingLabel controlId='TxtNombre' label='Nombre' className='mb-3'>
<Form.Control type='text' placeholder='Nombre' value={Usuario} /> <Form.Control
type='text'
placeholder='Nombre'
value={Nombre}
onChange={(e) => {
setNombre(e.target.value)
}}
/>
</FloatingLabel> </FloatingLabel>
</Col> </Col>
<Col xs={4}> <Col xs={5}>
<FloatingLabel controlId='CmbTipoUsuario' label='Tipo de usuario'> <FloatingLabel controlId='CmbTipoUsuario' label='Tipo de usuario'>
<Form.Select <Form.Select
aria-label='Tipo usuario' aria-label='Tipo usuario'
@ -37,24 +146,47 @@ export const CatUsuarios: FC<IProps> = (props) => {
}} }}
> >
<option value='0'></option> <option value='0'></option>
<option value='1'>Usuario interno</option> <option value='1'>Cliente</option>
<option value='2'>Cliente</option> <option value='2'>Proveedor</option>
<option value='3'>Proveedor</option> <option value='3'>Usuario interno - Administrador</option>
<option value='4'>Usuario interno - Operaciones</option>
</Form.Select> </Form.Select>
</FloatingLabel> </FloatingLabel>
</Col> </Col>
</Row> </Row>
<Row> <Row>
<Col xs={6}> <Col style={{ paddingTop: '15px' }}>
<FloatingLabel controlId='floatingInput' label='Nombre de usuario' className='mb-3'> <img
<Form.Control type='text' placeholder='name@empresa.com' /> src={Clean}
</FloatingLabel> alt='Limpia formulario'
height='30'
style={{ cursor: 'pointer' }}
onClick={() => {
cleanForm()
}}
/>
</Col> </Col>
<Col xs={6}> <Col xs={9}>
<FloatingLabel controlId='floatingPassword' label='Contraseña'> <FloatingLabel controlId='floatingInput' label='Usuario (correo@empresa.com)' className='mb-3'>
<Form.Control type='password' placeholder='Password' /> <Form.Control
type='text'
placeholder='name@empresa.com'
value={Usuario}
onChange={(e) => {
setUsuario(e.target.value)
}}
/>
</FloatingLabel> </FloatingLabel>
</Col> </Col>
<Col xs={2} style={{ paddingTop: '10px' }}>
<Button
onClick={() => {
saveForm()
}}
>
Guardar
</Button>
</Col>
</Row> </Row>
</Card.Body> </Card.Body>
</Card> </Card>
@ -78,7 +210,7 @@ export const CatUsuarios: FC<IProps> = (props) => {
<Row style={{ paddingTop: '5px' }}> <Row style={{ paddingTop: '5px' }}>
<Col xs={12}> <Col xs={12}>
<div className='divTipoCatalogo'> <div className='divTipoCatalogo'>
{TipoUsuario === 2 {TipoUsuario === 1
? mCatClientes ? mCatClientes
.filter((c) => c.cliente.toLocaleLowerCase().includes(Search.toLocaleLowerCase())) .filter((c) => c.cliente.toLocaleLowerCase().includes(Search.toLocaleLowerCase()))
.map((c) => { .map((c) => {
@ -92,7 +224,7 @@ export const CatUsuarios: FC<IProps> = (props) => {
) )
}) })
: null} : null}
{TipoUsuario === 3 {TipoUsuario === 2
? mCatProveedores ? mCatProveedores
.filter((c) => c.proveedor.toLocaleLowerCase().includes(Search.toLocaleLowerCase())) .filter((c) => c.proveedor.toLocaleLowerCase().includes(Search.toLocaleLowerCase()))
.map((c) => { .map((c) => {
@ -113,6 +245,42 @@ export const CatUsuarios: FC<IProps> = (props) => {
</Card> </Card>
</Col> </Col>
</Row> </Row>
<Row style={{ paddingTop: '5px' }}>
<Col xs={12}>
<Form.Control
type='text'
size='sm'
placeholder='Search...'
onChange={(e: any) => {
setSearchUser(e.target.value)
}}
/>
</Col>
</Row>
<Row style={{ paddingTop: '5px' }}>
<Col xs={12}>
<Card>
<DataTable
noHeader
defaultSortFieldId={'id'}
defaultSortAsc={true}
striped={true}
dense={true}
paginationPerPage={10}
pagination
highlightOnHover
columns={columnsConcepts}
data={DataUsuarios.filter(function (row: ICatUsuarios) {
return (
row.usuario.toLocaleLowerCase().includes(SearchUser.toLocaleLowerCase()) ||
row.nombre.toLocaleLowerCase().includes(SearchUser.toLocaleLowerCase())
)
})}
pointerOnHover
/>
</Card>
</Col>
</Row>
</Card.Body> </Card.Body>
</Card> </Card>
</div> </div>

@ -1,5 +1,5 @@
import { FC, useEffect, useState } from 'react' import { FC, useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom' import { Link, Navigate, useNavigate } from 'react-router-dom'
import IAuth from '../../Interfaces/Auth/IAuth' import IAuth from '../../Interfaces/Auth/IAuth'
import DSAuth from '../../Services/Auth/Auth.Services' import DSAuth from '../../Services/Auth/Auth.Services'
import { useDispatch, useSelector } from 'react-redux' import { useDispatch, useSelector } from 'react-redux'
@ -148,6 +148,9 @@ export const Login: FC<IProps> = (props) => {
login login
</button> </button>
</div> </div>
<div className='d-grid gap-2 mt-3'>
<Link to='/reset'>Olvido contraseña</Link>
</div>
</div> </div>
</form> </form>
</div> </div>

@ -6,6 +6,7 @@ import {
BsChevronRight, BsChevronRight,
BsChevronUp, BsChevronUp,
BsFillPencilFill, BsFillPencilFill,
BsPaperclip,
BsPlusSquareFill, BsPlusSquareFill,
BsTruck, BsTruck,
BsXLg, BsXLg,
@ -34,6 +35,10 @@ import {
import { populateOpViajesEstatusSecuencia } from '../../store/features/Operaciones/OpViajes.Estatus.SecuenciaSlice' import { populateOpViajesEstatusSecuencia } from '../../store/features/Operaciones/OpViajes.Estatus.SecuenciaSlice'
import { ViajeEstatus } from './Viaje/ViajeEstatus' import { ViajeEstatus } from './Viaje/ViajeEstatus'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import DSCatUsuarios from '../../Services/Catalogos/CatUsuarios.Services'
import ICatUsuarios from '../../Interfaces/Catalogos/ICatUsuarios'
import { MFileManager } from '../Utils/MFileManager/MFileManager'
import '../../css/masterDetail.css'
interface IProps {} interface IProps {}
@ -52,6 +57,7 @@ export const OpMonitor: FC<IProps> = (props) => {
const [OpViajes, setOpViajes] = useState<DTOOpViajes[]>([]) const [OpViajes, setOpViajes] = useState<DTOOpViajes[]>([])
const [showTripDialog, setShowTripDialog] = useState(false) const [showTripDialog, setShowTripDialog] = useState(false)
const [ShowDeleteDialog, setShowDeleteDialog] = useState(false) const [ShowDeleteDialog, setShowDeleteDialog] = useState(false)
const [ShowDocumentsDialog, setShowDocumentsDialog] = useState(false)
const [Switch, setSwitch] = useState(false) const [Switch, setSwitch] = useState(false)
const [NoCaja, setNoCaja] = useState('') const [NoCaja, setNoCaja] = useState('')
const [IDViaje, setIDViaje] = useState(0) const [IDViaje, setIDViaje] = useState(0)
@ -66,6 +72,8 @@ export const OpMonitor: FC<IProps> = (props) => {
const [PickUpNumber, setPickUpNumber] = useState('') const [PickUpNumber, setPickUpNumber] = useState('')
const [Hazmat, setHazmat] = useState(0) const [Hazmat, setHazmat] = useState(0)
const [Search, setSearch] = useState('') const [Search, setSearch] = useState('')
const [DataUsuarios, setDataUsuarios] = useState<ICatUsuarios[]>([])
const [IDUsuario, setIDUsuario] = useState(0)
const showInfo = (row: DTOOpViajes) => { const showInfo = (row: DTOOpViajes) => {
setIDViaje(row.id) setIDViaje(row.id)
@ -118,6 +126,18 @@ export const OpMonitor: FC<IProps> = (props) => {
const loadEveryting = () => { const loadEveryting = () => {
loadStatus() loadStatus()
loadTrips() loadTrips()
loadUsers()
}
const loadUsers = () => {
DSCatUsuarios.GetAll()
.then((response) => {
console.log(response.data)
setDataUsuarios(response.data)
})
.catch((e: Error) => {
alert('Ocurrio un error' + e.message.toString())
})
} }
useEffect(() => { useEffect(() => {
@ -208,7 +228,30 @@ export const OpMonitor: FC<IProps> = (props) => {
</Alert> </Alert>
</Card> </Card>
<Row> <Row>
<Col xs={3}> <Col xs={2}>
<Form.Control
as='select'
onChange={(e) => {
setIDUsuario(parseInt(e.target.value))
}}
value={IDUsuario}
className='form-select form-select-sm dialogLabel'
>
<option value='0'>- Todos los usuarios -</option>
{DataUsuarios
? DataUsuarios.filter((row) => row.id > 1)
/* .sort((a, b) => a.nombre - b.nombre) */
.map((row) => {
return (
<option key={row.id} value={row.id}>
{row.nombre}
</option>
)
})
: null}
</Form.Control>
</Col>
<Col xs={8}>
<Form.Control <Form.Control
type='text' type='text'
size='sm' size='sm'
@ -239,6 +282,7 @@ export const OpMonitor: FC<IProps> = (props) => {
<th style={{ width: '185px' }}>Estatus</th> <th style={{ width: '185px' }}>Estatus</th>
<th>Hazmat</th> <th>Hazmat</th>
<th>Ref AA</th> <th>Ref AA</th>
<th></th>
<th>PickUp No</th> <th>PickUp No</th>
<th>Elimina</th> <th>Elimina</th>
<th>Editar</th> <th>Editar</th>
@ -248,7 +292,8 @@ export const OpMonitor: FC<IProps> = (props) => {
{AllTrips {AllTrips
? AllTrips.filter( ? AllTrips.filter(
(MasterData) => (MasterData) =>
MasterData.id.toString().toLowerCase().includes(Search.toLowerCase()) || (IDUsuario !== 0 ? MasterData.usuario === IDUsuario : 1 === 1) &&
(MasterData.id.toString().toLowerCase().includes(Search.toLowerCase()) ||
MasterData.sCliente.toLowerCase().includes(Search.toLowerCase()) || MasterData.sCliente.toLowerCase().includes(Search.toLowerCase()) ||
MasterData.sTipoOperacion.toLowerCase().includes(Search.toLowerCase()) || MasterData.sTipoOperacion.toLowerCase().includes(Search.toLowerCase()) ||
MasterData.sOrigen.toLowerCase().includes(Search.toLowerCase()) || MasterData.sOrigen.toLowerCase().includes(Search.toLowerCase()) ||
@ -256,7 +301,7 @@ export const OpMonitor: FC<IProps> = (props) => {
MasterData.sTipoUnidad.toLowerCase().includes(Search.toLowerCase()) || MasterData.sTipoUnidad.toLowerCase().includes(Search.toLowerCase()) ||
MasterData.noCaja.toLowerCase().includes(Search.toLowerCase()) || MasterData.noCaja.toLowerCase().includes(Search.toLowerCase()) ||
MasterData.refAgenciaAduanal.toLowerCase().includes(Search.toLowerCase()) || MasterData.refAgenciaAduanal.toLowerCase().includes(Search.toLowerCase()) ||
MasterData.pickUpNumber.toLowerCase().includes(Search.toLowerCase()) MasterData.pickUpNumber.toLowerCase().includes(Search.toLowerCase()))
).map((MasterData) => { ).map((MasterData) => {
return ( return (
<> <>
@ -347,6 +392,17 @@ export const OpMonitor: FC<IProps> = (props) => {
> >
{MasterData.refAgenciaAduanal} {MasterData.refAgenciaAduanal}
</td> </td>
<td
style={{ paddingTop: '15px' }}
onClick={() => {
setIDViaje(MasterData.id)
setShowDocumentsDialog(true)
}}
>
<IconContext.Provider value={{ color: 'green', size: '20px' }}>
<BsPaperclip />
</IconContext.Provider>
</td>
<td <td
style={{ textAlign: 'left' }} style={{ textAlign: 'left' }}
className={MasterData.max === true ? 'masterSelected' : 'normalSelected'} className={MasterData.max === true ? 'masterSelected' : 'normalSelected'}
@ -471,6 +527,79 @@ export const OpMonitor: FC<IProps> = (props) => {
</Row> </Row>
</Modal.Body> </Modal.Body>
</Modal> </Modal>
<Modal
show={ShowDocumentsDialog}
onHide={() => {
setShowDocumentsDialog(false)
}}
dialogClassName='modal-90w'
backdrop='static'
>
<Modal.Header closeButton className='tripHeader'>
Documentos del viaje
</Modal.Header>
<Modal.Body>
<Row>
<Col xs={4}>
<Card style={{ width: '28rem', textAlign: 'center' }}>
<Card.Body>
<MFileManager
IDTrafico={IDViaje}
Proceso={1}
canEdit={true}
fileType={'application/pdf'}
Leyenda={'Seleccione los archivos PDF: '}
showPreview={3}
/>
</Card.Body>
</Card>
</Col>
<Col xs={4}>
<Card style={{ width: '28rem', textAlign: 'center' }}>
<Card.Body>
<MFileManager
IDTrafico={IDViaje}
Proceso={2}
canEdit={true}
fileType={'image/gif, image/jpeg, image/png, image/gif'}
Leyenda={'Fotos de operaciones: '}
showPreview={3}
/>
</Card.Body>
</Card>
</Col>
<Col xs={4}>
<Card style={{ width: '28rem', textAlign: 'center' }}>
<Card.Body>
<MFileManager
IDTrafico={IDViaje}
Proceso={3}
canEdit={true}
fileType={'application/pdf'}
Leyenda={'Otros documentos: '}
showPreview={3}
/>
</Card.Body>
</Card>
</Col>
</Row>
<Row>
<Col xs={10}></Col>
<Col xs={2} style={{ textAlign: 'right' }}>
<Button
variant='secondary'
size='sm'
onClick={() => {
setShowDocumentsDialog(false)
}}
>
&nbsp;&nbsp;&nbsp;Cerrar&nbsp;&nbsp;&nbsp;
</Button>
</Col>
</Row>
</Modal.Body>
</Modal>
</div> </div>
) )
} }

@ -0,0 +1,123 @@
import { FC, useEffect, useState } from 'react'
import { Link, Navigate, useNavigate } from 'react-router-dom'
import IAuth from '../../Interfaces/Auth/IAuth'
import DSAuth from '../../Services/Auth/Auth.Services'
import DSUsers from '../../Services/Catalogos/CatUsuarios.Services'
import { useDispatch, useSelector } from 'react-redux'
import { populateUserProfile } from '../../store/features/Auth/UserProfileSlice'
import { populateMenuItems } from '../../store/features/Auth/MenuItemsSlice'
import { RootState } from '../../store/store'
import Leyend from '../../images/leyend.png'
import jwt_decode from 'jwt-decode'
interface IProps {}
export const ResetAccount: FC<IProps> = (props) => {
const navigate = useNavigate()
const dispatch = useDispatch()
const UserLogued = useSelector((state: RootState) => state.UserProfile.UserProfile.logueado)
const [Usuario, setUsuario] = useState('')
const [Contrasena, setContrasena] = useState('')
const [Contrasena2, setContrasena2] = useState('')
const [token, setToken] = useState<string>(
(window.localStorage.getItem('token') ? window.localStorage.getItem('token') : '')!
)
const [menuStr, setMenuStr] = useState<string>(
(window.localStorage.getItem('menu') ? window.localStorage.getItem('menu') : '')!
)
const Reset = async () => {
if (Contrasena !== Contrasena2) {
alert('Las contraseñas no coinciden entre si')
return false
}
const data: IAuth = {
usuario: Usuario,
contrasena: Contrasena,
}
DSAuth.ResetPassword(data)
.then((response) => {
console.log(response.data)
alert('El cambio de contraseña se realizo exitosamente!')
navigate('/', { replace: true })
})
.catch((e: Error) => {
alert('Credenciales invalidas! ')
})
}
const validateToken = () => {
DSAuth.Validate()
.then((response) => {
navigate('/login', { replace: true })
})
.catch((e: Error) => {
alert('Ocurrio un error!')
})
}
useEffect(() => {
if (token.length > 5) {
validateToken()
}
}, [token])
return (
<div hidden={token ? true : false}>
<div className='Auth-form-container'>
<form className='Auth-form'>
<div className='Auth-form-content'>
<h3 className='Auth-form-title'>
<img src={Leyend} alt='' height='50' />
</h3>
<div className='form-group mt-3'>
<label style={{ color: '#00719F', paddingLeft: '5px' }}>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 style={{ color: '#00719F' }}>Nueva contraseña</label>
<input
type='password'
className='form-control mt-1'
placeholder='Contraseña'
onChange={(e) => {
setContrasena(e.target.value)
}}
/>
</div>
<div className='form-group mt-3'>
<label style={{ color: '#00719F' }}>Confirme nueva contraseña</label>
<input
type='password'
className='form-control mt-1'
placeholder='Contraseña'
onChange={(e) => {
setContrasena2(e.target.value)
}}
/>
</div>
<div className='d-grid gap-2 mt-3'>
<button
type='button'
className='btn'
style={{ backgroundColor: '#00719F', color: '#FFFFFF' }}
onClick={() => {
Reset()
}}
>
reset password
</button>
</div>
</div>
</form>
</div>
</div>
)
}

@ -0,0 +1,333 @@
import React, { FC, useEffect, useState } from 'react'
import MFileManagerDS from '../../../Services/Utils/MFileManager.Service'
import IFileManager from '../../../Interfaces/Utils/IFileManager'
import { Alert, Button, Card, Col, ListGroup, Modal, Row } from 'react-bootstrap'
import { IconContext } from 'react-icons'
import { BsFillXCircleFill } from 'react-icons/bs'
import { MsgInformativo } from '../Toast/MsgInformativo'
import { TargetURL } from '../../../Constants/TargetURL'
interface IProps {
IDTrafico: number
Proceso: number
Leyenda?: string
showPreview: number
fileType: string
canEdit: boolean
}
export const MFileManager: FC<IProps> = (props) => {
const [UserId, setUserId] = useState(() => {
const stickyValue = window.localStorage.getItem('UserId')
return stickyValue !== null ? JSON.parse(stickyValue) : 0
})
const [IDTrafico, setIDTrafico] = useState<number>(props.IDTrafico ? props.IDTrafico : 0)
const [Proceso, setProceso] = useState<number>(props.Proceso ? props.Proceso : 0)
const [ListaArchivos, setListaArchivos] = useState<IFileManager[]>()
const [NombreArchivo, setNombreArchivo] = useState('')
const [MsgDialogDelete, setMsgDialogDelete] = useState(false)
const [IDArchivo, setIDArchivo] = useState(0)
const [header, setHeader] = useState('')
const [show, setShowMsg] = useState(false)
const [msg, setMsg] = useState('')
const URL = new TargetURL()
const msgColor = 'primary'
const selectedFiles = (selectorFiles: any) => {
var formData = new FormData()
for (let i = 0; i < selectorFiles.files.length; i++) {
formData.append('FileList', selectorFiles.files[i])
}
MFileManagerDS.Append(formData, IDTrafico, Proceso, UserId)
.then((response) => {
setListaArchivos(response.data)
})
.catch((e: Error) => {
alert('Ocurrio un error: ' + e)
return
})
return false
}
useEffect(() => {
setIDTrafico(props.IDTrafico)
setProceso(props.Proceso)
MFileManagerDS.Get(props.IDTrafico, props.Proceso)
.then((response) => {
setListaArchivos(response.data)
})
.catch((e: Error) => {
alert('Ocurrio un error: ' + e)
return
})
}, [props.IDTrafico, props.Proceso])
const confirmDelete = (row: IFileManager) => {
setIDArchivo(row.id)
setNombreArchivo(row.nombreArchivo)
setMsgDialogDelete(true)
}
const deleteItem = () => {
MFileManagerDS.DeleteFile(IDArchivo)
.then((response) => {
var arrArchivos = ListaArchivos!.filter(function (el) {
return el.id !== IDArchivo
})
setListaArchivos(arrArchivos)
setHeader('Informtivo')
setMsg(response.data.Respuesta)
setMsgDialogDelete(false)
setShowMsg(false)
return
})
.catch((e: Error) => {
setHeader('Error')
setMsg('Ocurrio un error, no se elimino el archivo')
setMsgDialogDelete(false)
setShowMsg(false)
return
})
return false
}
const getFileContent = (row: IFileManager) => {
MFileManagerDS.getFileContentById(row.id, row.proceso)
.then((response: any) => {
if (response.status === 200) {
if (row.nombreArchivo.toLowerCase().endsWith('.pdf')) {
// console.log(response.data)
const blob = new Blob([response.data], { type: 'application/pdf' })
const url = window.URL.createObjectURL(blob)
window.open(url)
} else if (
row.nombreArchivo.toLowerCase().endsWith('.png') ||
row.nombreArchivo.toLowerCase().endsWith('.jpg')
) {
const blob = new Blob([response.data], { type: 'image/png' })
const url = window.URL.createObjectURL(blob)
window.open(url)
} else {
const url = window.URL.createObjectURL(new Blob([response.data]))
const link = document.createElement('a')
link.href = url
link.setAttribute('download', NombreArchivo ? NombreArchivo : 'Archivo.zip')
document.body.appendChild(link)
link.click()
}
} else {
setHeader('Error')
setMsg('A este concepto no se le ha anexado PDF')
setShowMsg(true)
return
}
})
.catch((e: Error) => {
setHeader('Error')
setMsg('A este concepto no se le ha anexado PDF')
setShowMsg(true)
return
})
}
return (
<div>
<br />
<Card>
<Card.Body>
<Card.Title style={{ fontSize: '15px' }}>
{props.Leyenda ? props.Leyenda : ''}&nbsp;&nbsp;&nbsp;
{props.canEdit ? (
<input
type='file'
multiple
name='FileList'
accept={props.fileType}
onChange={(e) => selectedFiles(e.target)}
/>
) : (
''
)}
</Card.Title>
{ListaArchivos && props.showPreview === 1 ? (
<div>
<Row xs={1} md={3} className='g-1'>
{ListaArchivos
? ListaArchivos.map((rec) => {
return (
<Col key={rec.id}>
<Card style={{ width: '28rem', textAlign: 'center' }}>
<Card.Body>
<Row>
<Col xs={3}></Col>
<Col xs={5}>
<img
src={`${URL.get()}/Utils/MFileManager/GetFileContentById?id=${rec.id}&Proceso=${
rec.proceso
}`}
width={150}
height={200}
alt={'Imagen'}
onClick={() => {
getFileContent(rec)
}}
/>
</Col>
<Col
xs={1}
alt='De un click aqui para eliminar'
style={{ visibility: props.canEdit ? 'visible' : 'hidden' }}
>
<IconContext.Provider value={{ color: 'red', size: '20px' }}>
<BsFillXCircleFill
onClick={() => {
confirmDelete(rec)
}}
style={{ cursor: 'pointer' }}
/>
</IconContext.Provider>
</Col>
<Col xs={3}></Col>
</Row>
<Row>
<Col xs={12}>&nbsp;</Col>
</Row>
<Row>
<Col xs={12}>{rec.nombreArchivo}</Col>
</Row>
</Card.Body>
</Card>
</Col>
)
})
: ''}
</Row>
</div>
) : ListaArchivos && props.showPreview === 2 ? (
<div>
<Row xs={1} md={3} className='g-1'>
{ListaArchivos
? ListaArchivos.map((rec) => {
return (
<Col key={rec.id}>
<Card style={{ width: '28rem', textAlign: 'center' }}>
<Card.Body>
<Alert variant='primary'>
<Row>
<Col xs={11}>{rec.nombreArchivo}</Col>
<Col
xs={1}
alt='De un click aqui para eliminar'
style={{ visibility: props.canEdit ? 'visible' : 'hidden' }}
>
<IconContext.Provider value={{ color: 'red', size: '20px' }}>
<BsFillXCircleFill
onClick={() => {
confirmDelete(rec)
}}
style={{ cursor: 'pointer' }}
/>
</IconContext.Provider>
</Col>
</Row>
</Alert>
</Card.Body>
</Card>
</Col>
)
})
: ''}
</Row>
</div>
) : ListaArchivos && props.showPreview === 3 ? (
<div>
{ListaArchivos
? ListaArchivos.map((rec) => {
return (
<ListGroup style={{ width: '380px' }}>
<ListGroup.Item
key={rec.id}
style={{
paddingLeft: '5px',
backgroundColor: '#CFE2FF',
color: '#314EFA',
}}
>
<Row>
<Col>
<span
style={{ cursor: 'pointer' }}
onClick={() => {
getFileContent(rec)
}}
>
{rec.nombreArchivo.substring(0, 40)}
</span>
</Col>
<Col xs={1} style={{ visibility: props.canEdit ? 'visible' : 'hidden' }}>
<span>
<IconContext.Provider value={{ color: 'red', size: '20px' }}>
<BsFillXCircleFill
onClick={() => {
confirmDelete(rec)
}}
style={{ cursor: 'pointer' }}
/>
</IconContext.Provider>
</span>
</Col>
</Row>
</ListGroup.Item>
</ListGroup>
)
})
: ''}
</div>
) : (
''
)}
</Card.Body>
</Card>
<Modal show={MsgDialogDelete} onHide={() => setMsgDialogDelete(false)} size='lg'>
<Modal.Body>
<h5>
Favor de confirmar
<Row>
<Col xs={12}>&nbsp;</Col>
</Row>
<Alert variant='primary'>
¿Esta seguro de eliminar el archivo: <br />
<br /> {NombreArchivo}?
</Alert>
</h5>
</Modal.Body>
<Modal.Footer>
<Row>
<Col xs={1}>
<Button variant='secondary' onClick={() => setMsgDialogDelete(false)} size='sm'>
Cerrar
</Button>
</Col>
<Col xs={5} style={{ paddingLeft: '550px', paddingRight: '0px' }}>
&nbsp;
</Col>
<Col xs={1}>
<Button variant='danger' onClick={() => deleteItem()} size='sm'>
Eliminar
</Button>
</Col>
</Row>
</Modal.Footer>
</Modal>
<MsgInformativo
show={show}
msg={msg}
header={header}
msgColor={msgColor}
closeToast={() => {
setShowMsg(false)
}}
/>
</div>
)
}

@ -0,0 +1,51 @@
import React, { FC } from 'react'
import { Toast, ToastContainer } from 'react-bootstrap'
import { IconContext } from 'react-icons'
import { BsFillExclamationSquareFill, BsXOctagonFill } from 'react-icons/bs'
interface IProps {
show: boolean
msg: string
header: string
msgColor: string
time?: number
closeToast: (arg: boolean) => void
}
export const MsgInformativo: FC<IProps> = (props) => {
return (
<div>
<ToastContainer position={'middle-center'}>
<Toast
show={props.show}
delay={props.time}
bg={props.msgColor}
autohide
onClose={() => {
props.closeToast(false)
}}
>
<Toast.Header>
<strong className='me-auto'>
{props.header.toString().includes('Error') ? (
<IconContext.Provider value={{ color: 'red', size: '20px' }}>
<BsXOctagonFill />
</IconContext.Provider>
) : null}
{props.header.toString().includes('Informativo') ? (
<IconContext.Provider value={{ color: 'blue', size: '20px' }}>
<BsFillExclamationSquareFill />
</IconContext.Provider>
) : null}
&nbsp;
<span style={{ color: props.header == 'Error' ? 'red' : '' }}>{props.header}</span>
</strong>
</Toast.Header>
<Toast.Body style={{ backgroundColor: '#FFFFFF' }}>
<div className={props.msgColor == 'warning' ? 'alert alert-warning' : ''}>{props.msg}</div>
</Toast.Body>
</Toast>
</ToastContainer>
</div>
)
}

@ -0,0 +1,9 @@
export default interface ICatUsuarios {
id: number
usuario: string
nombre: string
contrasena: string,
tipoUsuario : number
activo: number
idPerfil: number
}

@ -0,0 +1,9 @@
export default interface IFileManager {
id: number,
idUsuario: number,
proceso: number,
nombreArchivo: string,
fechaRegistro: string,
tags: string,
size: number,
}

@ -2,7 +2,7 @@ import http from "../../Services/Auth/config/http-common";
import IAuth from "../../Interfaces/Auth/IAuth" import IAuth from "../../Interfaces/Auth/IAuth"
//import ItemMenuData from "../../Interfaces/Auth/IMenu"; //import ItemMenuData from "../../Interfaces/Auth/IMenu";
import IPermisos from "../../Interfaces/Auth/IPermisos"; import IPermisos from "../../Interfaces/Auth/IPermisos";
//import Token from '../../Interfaces/token' import IRespuesta from "../../Interfaces/Respuestas/IRespuesta";
class authDataService { class authDataService {
async login(data: IAuth) { async login(data: IAuth) {
@ -11,5 +11,8 @@ class authDataService {
async Validate() { async Validate() {
return await http.get<String>("Auth/Validate"); return await http.get<String>("Auth/Validate");
} }
ResetPassword(data: IAuth) {
return http.post<IRespuesta>(`Auth/ResetPassword`, data);
}
} }
export default new authDataService(); export default new authDataService();

@ -0,0 +1,17 @@
import http from "../../Services/Auth/config/http-common";
import ICatUsuarios from "../../Interfaces/Catalogos/ICatUsuarios";
import IRespuesta from "../../Interfaces/Respuestas/IRespuesta";
import IAuth from "../../Interfaces/Auth/IAuth";
class CatUsuariosDataService {
async GetAll() {
return await http.get<ICatUsuarios[]>("Catalogos/Usuarios/GetAll");
}
Append(data: ICatUsuarios) {
return http.post<ICatUsuarios>(`Catalogos/Usuarios/Append`,data);
}
Delete(id: number) {
return http.delete<IRespuesta>(`Catalogos/Usuarios/Delete/${id}`);
}
}
export default new CatUsuariosDataService();

@ -0,0 +1,26 @@
import http from "../Auth/config/http-common";
import IRespuesta from "../../Interfaces/Respuestas/IRespuesta"
import IFileManager from "../../Interfaces/Utils/IFileManager";
class MFileManagerDataService {
Append(formData: any, IDTrafico: number, Proceso: number, Usuario: number) {
return http.post<IFileManager[]>(`/Utils/MFileManager/Append?Tags=${IDTrafico}&Proceso=${Proceso}&Usuario=${Usuario}`, formData)
}
DeleteFile(id: number) {
return http.delete<IRespuesta>(`/FileManager/DeleteById/${id}`);
}
Get(IDTrafico: number, Proceso: number) {
return http.get<IFileManager[]>(`/Utils/MFileManager/GetFilesFromLog?Tags=${IDTrafico}&Proceso=${Proceso}`)
}
getFileContentById(id: number, Proceso: number) {
return http.get<ArrayBuffer>(`/Utils/MFileManager/GetFileContentById?id=${id}&Proceso=${Proceso}`, {responseType: 'arraybuffer'})
.then(function (response) {
return response
})
.catch(function (error) {
console.log(error)
})
}
}
export default new MFileManagerDataService();

@ -188,3 +188,9 @@
position: relative; */ position: relative; */
display: inline-block; display: inline-block;
} }
.modal-90w {
width: 90%;
max-width: none !important;
max-height: none !important;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 B

Loading…
Cancel
Save