Skip to content

Commit

Permalink
busqueda en admin usuarios, cambiar contraseña y fotos de perfil
Browse files Browse the repository at this point in the history
  • Loading branch information
MatiasBais committed Mar 4, 2024
1 parent da6c947 commit 46341a1
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 34 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
node_modules
package-lock.json
.vscode
.personal
.personal
/storage/img/*
!/storage/img/user.webp
61 changes: 55 additions & 6 deletions api/v1/router.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
import * as express from "express";
import * as bcrypt from "bcrypt";
import multer from "multer";
import path from "path"
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './storage/img')
},
filename: function (req, file, cb) {
cb(null, "imagenPerfil-" + req.session.usuario.DNI+".jpg")
},

})
var upload = multer({storage:storage,
fileFilter: function(req, file, cb){
const allowedExtensions = ['.jpg', '.png']; // Add more extensions as needed
const fileExtension = path.extname(file.originalname).toLowerCase();
if (allowedExtensions.includes(fileExtension)) {
cb(null, true); // Accept the file
} else {
cb(null, false); // Reject the file
}
}})
const router = express.Router();
import {
Usuario,
Expand Down Expand Up @@ -84,6 +105,14 @@ router.delete("/sesion", function (req, res) {

// usuario

router.get("/usuario/:DNI/foto", function(req, res){
res.sendFile("imagenPerfil-"+req.params.DNI+".jpg", {'root': './storage/img'}, (err)=>{
if (err) {
res.sendFile("user.webp", {'root': './storage/img'})
}
});
});

router.get("/usuario", function (req, res) {
if (!req.session.usuario) {
res.status(401).send("No se posee sesión válida activa");
Expand Down Expand Up @@ -164,6 +193,16 @@ router.get("/usuario", function (req, res) {
where.nombre = { [Sequelize.Op.substring]: filtro };
include.push(Carrera);
where["$carrera.legajo$"] = { [Sequelize.Op.substring]: filtro };
}else if( req.query.searchInput){

where = {
[Sequelize.Op.or]: [
{ DNI: { [Sequelize.Op.substring]: req.query.searchInput } },
{ nombre: { [Sequelize.Op.substring]: req.query.searchInput } },
{ '$perfil.nombre$': { [Sequelize.Op.startsWith]: req.query.searchInput } }
]
};
opciones.where = where;
}

if (include.length) {
Expand Down Expand Up @@ -419,18 +458,28 @@ router.delete("/usuario/:DNI/bloqueo", function (req, res) {
});
});

router.patch("/usuario", function (req, res) {
router.patch("/usuario", upload.single("image"), function (req, res) {
//req.file tiene la imagen
if (!req.session.usuario) {
res.status(401).send("Usuario no tiene sesión válida activa");
return;
}

if(!req.file){
//req.file solo existe si la imagen cumple con los formatos de arriba
//TODO esto no funcionaría si solo manda la contraseña
res.status(400).send("Petición mal formada")
}
Usuario.findByPk(req.session.usuario.DNI)
.then((usuario) => {
//TODO Feature: definir que mas puede cambiar y que constituye datos inválidos
usuario.contrasenia = req.body.contrasenia;
usuario.save();
res.status(200).send("Datos actualizados exitosamente");
})
if(bcrypt.compare(req.body.contraseniaAnterior, usuario.contrasenia)){
usuario.contrasenia = req.body.contraseniaNueva;
usuario.save();
res.status(200).send("Datos actualizados exitosamente");
return;
}
res.status(402).send("Contraseña anterior no válida")
})
.catch((err) => {
res.status(500).send(err);
});
Expand Down
4 changes: 2 additions & 2 deletions frontend/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -544,8 +544,8 @@ router.get("/administracion/usuarios", async (req, res) => {
res.send(pagina.render());
return;
}

let pagina = PantallaAdministracionUsuarios(req.path, req.session);
const query = req.query.searchInput;
let pagina = PantallaAdministracionUsuarios(req.path, req.session, query);
res.send(pagina.render());
});
// Ruta Para búsqueda
Expand Down
4 changes: 2 additions & 2 deletions frontend/static/componentes/chipusuario.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class ChipUsuario {
if (this.#esPerfil) {
return `
<div class="chip-usuario-perfil">
<img class="mr-3 img-usuario" src="../user.webp" ></img>
<img class="mr-3 img-usuario" src="/api/usuario/${this.#DNI}/foto" ></img>
<div class="contenido-perfil">
<div>DNI: <span>${this.#DNI}</span></div>
<div>Nombre: <span>${this.#nombreusuario}</span></div>
Expand All @@ -43,7 +43,7 @@ class ChipUsuario {
} else {
return `
<div class="chip-usuario is-vcentered">
<img class="mr-3 img-usuario" src="../user.webp" ></img>
<img class="mr-3 img-usuario" src="/api/usuario/${this.#DNI}/foto" ></img>
<a class="nombre-usuario" href="/perfil/${this.#DNI}">${
this.#nombreusuario
}</a>
Expand Down
46 changes: 29 additions & 17 deletions frontend/static/componentes/formulario.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,34 @@ class Formulario{
this.#alEnviar();
}


// Crear un objeto FormData para facilitar la obtención de datos del formulario
const formData = new FormData(e.target);

const fileInput = document.querySelector(`#${this.#id} input[type="file"]`);
let datos;
if(fileInput){
datos = formData;


// Crear un objeto para almacenar los datos
const datos = {};

// Iterar sobre las entradas de FormData y asignarlas al objeto de datos
formData.forEach((value, key) => {
// Reflect.has in favor of: object.hasOwnProperty(key)
if(!Reflect.has(datos, key)){
datos[key] = value;
return;
}
if(!Array.isArray(datos[key])){
datos[key] = [datos[key]];
}
datos[key].push(value);
});
}else{

// Crear un objeto para almacenar los datos
datos = {};

// Iterar sobre las entradas de FormData y asignarlas al objeto de datos
formData.forEach((value, key) => {
// Reflect.has in favor of: object.hasOwnProperty(key)
if(!Reflect.has(datos, key)){
datos[key] = value;
return;
}
if(!Array.isArray(datos[key])){
datos[key] = [datos[key]];
}
datos[key].push(value);
});
}
let ok,codigo;
superFetch(this.#endpoint,datos,{ method: this.verbo})
.then(res=>{
Expand All @@ -63,7 +72,7 @@ class Formulario{
}

render(){
return `<form id=${this.#id} class="" onsubmit="Formulario.instancias['${this.#id}'].enviar(event)">`
return `<form id=${this.#id} style="padding-top:32px;"class="" onsubmit="Formulario.instancias['${this.#id}'].enviar(event)" enctype="multipart/form-data" >`
+ this.campos.reduce((html,c)=>html+(new Campo(c)).render(),'')
// TODO Refactor: new Boton ??
+`<input class="button ${this.#clasesBotonEnviar}" type=submit value="${this.#textoEnviar}">`
Expand Down Expand Up @@ -148,6 +157,8 @@ class Campo{
html=html.replace('<label class="label">'+this.#textoEtiqueta,'');
html+=` type="${this.#type}"`;
break;
case 'file':
html+=' '+this.#extra;
case 'number':
// * min, max, step...
html+=' '+this.#extra;
Expand All @@ -158,8 +169,9 @@ class Campo{
}
if(this.#required)
html+=` required`;
if(this.#value)
if(this.#value){
html+=` value="${this.#value}"`;
}

return html+endTag+'</label>';
}
Expand Down
6 changes: 4 additions & 2 deletions frontend/static/pantallas/administracion-usuarios.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import {
Fecha,
ChipUsuario,
Modal,
Busqueda
} from "../componentes/todos.js";

function crearPantalla(ruta, sesion) {
let tabla = new Tabla("administrar-usuarios", "/api/usuario", [
function crearPantalla(ruta, sesion, query="") {
let tabla = new Tabla("administrar-usuarios", "/api/usuario?searchInput="+query, [
{
nombre: "DNI",
celda: (usuario) =>
Expand Down Expand Up @@ -47,6 +48,7 @@ import {
sesion: sesion,
partes: [
new Modal("Eliminar Usuario", "modal-eliminar-usuario"),
new Busqueda(),
tabla,
new Boton({
titulo: "Agregar",
Expand Down
42 changes: 40 additions & 2 deletions frontend/static/pantallas/perfil-propio-info.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,53 @@
import { ChipUsuario, Modal, Pagina } from '../componentes/todos.js'
import { ChipUsuario, Formulario, Modal, Pagina } from '../componentes/todos.js'

function crearPagina(ruta, sesion){
let titulo = 'Mi perfil'
let modal = new Modal('General','modal-general');
let form = new Formulario(
"administracion-perfil-editar",
`/api/usuario`,
[
{
name: "contraseniaNueva",
textoEtiqueta: "Contraseña nueva:",
type: "password",
},
{
name: "contraseniaAnterior",
textoEtiqueta: "Contraseña anterior:",
type: "password",
},
{
name: "image",
textoEtiqueta: "Imagen de Perfil: ",
type: "file",
extra: 'accept="image/jpeg, image/png'
},
],
(txt, info) => {
if (info.ok) {

window.location.reload();

} else {
// TODO UX: Mejores alertas
alert(`Error ${info.codigo}: ${txt}`);
}
},
{
verbo: "PATCH",
textoEnviar: "Editar usuario",
clasesBoton: "is-link is-rounded mt-3",
}
);
return new Pagina({
ruta:ruta,
titulo: titulo,
sesion:sesion,
partes:[
modal,
new ChipUsuario(sesion.usuario, true)
new ChipUsuario(sesion.usuario, true),
form
]
});

Expand Down
4 changes: 2 additions & 2 deletions frontend/static/scripts/administracion-usuarios.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { Modal } from "../componentes/todos.js";

let pagina = PantallaAdministracionUsuarios(location.pathname, {
usuario: window.usuarioActual,
});
}, location.search.split('=')[1]);
let modal = pagina.partes[0];
let tabla = pagina.partes[1];
let tabla = pagina.partes[2];
tabla /* ! Tabla */
.iniciar();

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"express": "4.18.2",
"express-session": "1.17.3",
"mocha": "^10.2.0",
"multer": "^1.4.5-lts.1",
"mysql2": "3.6.5",
"openai": "4.0.0",
"request": "2.88.2",
Expand Down
Binary file added storage/img/user.webp
Binary file not shown.

0 comments on commit 46341a1

Please sign in to comment.