Skip to content

Commit f63f0cc

Browse files
authored
Merge pull request #69 from Lemoncode/feature/#68--Front-End]-Funcionalidad-editar-Usuario
Feature/#68 front end] funcionalidad editar usuario
2 parents 38b4850 + b154fd8 commit f63f0cc

32 files changed

+496
-66
lines changed

mock-server/.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
NODE_ENV=development
22
PORT=3000
3-
SIMULATED_DELAY=2000
3+
SIMULATED_DELAY=2000

mock-server/src/dals/mock.data.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export interface DB {
1111
export const db: DB = {
1212
users: [
1313
{
14-
_id: new ObjectId(),
14+
_id: new ObjectId('67e29f6498ec8fa00c141af1'),
1515
nombre: 'Carlos',
1616
apellido: 'González Pérez',
1717
@@ -33,7 +33,7 @@ export const db: DB = {
3333
},
3434
},
3535
{
36-
_id: new ObjectId(),
36+
_id: new ObjectId('67e2a2a01faec0c33a18c24a'),
3737
nombre: 'María',
3838
apellido: 'Martínez López',
3939
@@ -55,7 +55,7 @@ export const db: DB = {
5555
},
5656
},
5757
{
58-
_id: new ObjectId(),
58+
_id: new ObjectId('67e2a2a9bdf6ec804964701e'),
5959
nombre: 'Juan',
6060
apellido: 'Rodríguez Sánchez',
6161
@@ -77,7 +77,7 @@ export const db: DB = {
7777
},
7878
},
7979
{
80-
_id: new ObjectId(),
80+
_id: new ObjectId('67e2a2b17f7177a8b57ceed7'),
8181
nombre: 'Laura',
8282
apellido: 'García Ruiz',
8383
@@ -99,7 +99,7 @@ export const db: DB = {
9999
},
100100
},
101101
{
102-
_id: new ObjectId(),
102+
_id: new ObjectId('67e2a2bb61e3836ad14d746e'),
103103
nombre: 'Miguel',
104104
apellido: 'Fernández Gómez',
105105

mock-server/src/dals/user/user.model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ export interface Usuario {
1313
esProponente?: boolean;
1414
esAutorizante?: boolean;
1515
esContraseñaTemporal?: boolean;
16-
contraseña: string;
16+
contraseña?: string;
1717
unidad: Lookup;
1818
}

mock-server/src/dals/user/user.repository.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,12 @@ export const userRepository = {
1919
db.users.push(newUser);
2020
return true;
2121
},
22+
getUserById: async (id: string): Promise<model.Usuario> => db.users.find(user => user._id.toHexString() === id),
23+
actualizarUsuario: async (id: string, usuarioActualizado: model.Usuario): Promise<boolean> => {
24+
const index = db.users.findIndex(user => user._id.toHexString() === id);
25+
if (index !== -1) {
26+
db.users[index] = { ...db.users[index], ...usuarioActualizado };
27+
}
28+
return index !== -1;
29+
},
2230
};

mock-server/src/pods/user/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from './user.api.js';
1+
export * from './user.rest-api.js';

mock-server/src/pods/user/user.api-model.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,25 @@ export interface Usuario {
1313
contraseña?: string;
1414
unidad: string;
1515
}
16+
17+
export interface UsuarioSummary {
18+
id: string;
19+
nombre: string;
20+
apellido: string;
21+
email: string;
22+
unidad: string;
23+
}
24+
25+
export interface UsuarioActualizado {
26+
_id: string;
27+
nombre: string;
28+
apellido: string;
29+
email: string;
30+
telefono?: string;
31+
movil?: string;
32+
rol: string;
33+
esResponsable?: boolean;
34+
esProponente?: boolean;
35+
esAutorizante?: boolean;
36+
unidad: string;
37+
}

mock-server/src/pods/user/user.mappers.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,20 @@ import * as model from '#dals/user/user.model.js';
66
import * as apiModel from './user.api-model.js';
77

88
export const mapUserFromModelToApi = (user: model.Usuario): apiModel.Usuario => ({
9+
id: mapObjectIdToString(user._id),
10+
nombre: user.nombre,
11+
apellido: user.apellido,
12+
email: user.email,
13+
unidad: user.unidad.id,
14+
esAutorizante: user.esAutorizante,
15+
esProponente: user.esProponente,
16+
esResponsable: user.esResponsable,
17+
rol: user.rol.id,
18+
movil: user.movil,
19+
telefono: user.telefono,
20+
});
21+
22+
export const mapUserSummaryFromModelToApi = (user: model.Usuario): apiModel.UsuarioSummary => ({
923
id: mapObjectIdToString(user._id),
1024
nombre: user.nombre,
1125
apellido: user.apellido,
@@ -16,7 +30,7 @@ export const mapUserFromModelToApi = (user: model.Usuario): apiModel.Usuario =>
1630
export const mapUserListFromModelToApi = (
1731
userList: CollectionQuery<model.Usuario>
1832
): CollectionQuery<apiModel.Usuario> => ({
19-
data: mapToCollection(userList.data, mapUserFromModelToApi),
33+
data: mapToCollection(userList.data, mapUserSummaryFromModelToApi),
2034
pagination: {
2135
totalPages: userList.pagination.totalPages,
2236
},
@@ -42,3 +56,22 @@ export const mapUserFromApiToModel = (user: apiModel.Usuario): model.Usuario =>
4256
esAutorizante: user.esAutorizante,
4357
};
4458
};
59+
60+
export const mapUserFromApiToModelUpdate = (user: apiModel.UsuarioActualizado): model.Usuario => {
61+
const role = db.roles.find(role => role.id === user.rol);
62+
const unit = db.unidadProponentes.find(unit => unit.id === user.unidad);
63+
64+
return {
65+
_id: new ObjectId(),
66+
nombre: user.nombre,
67+
apellido: user.apellido,
68+
telefono: user.telefono,
69+
movil: user.movil,
70+
email: user.email,
71+
rol: role,
72+
unidad: unit,
73+
esResponsable: user.esResponsable,
74+
esProponente: user.esProponente,
75+
esAutorizante: user.esAutorizante,
76+
};
77+
};

mock-server/src/pods/user/user.api.ts renamed to mock-server/src/pods/user/user.rest-api.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import { Router } from 'express';
22
import { userRepository } from '#dals/user/user.repository.js';
3-
import { mapUserFromApiToModel, mapUserListFromModelToApi } from './user.mappers.js';
4-
import { Usuario } from './user.api-model.js';
3+
import {
4+
mapUserFromModelToApi,
5+
mapUserListFromModelToApi,
6+
mapUserFromApiToModel,
7+
mapUserFromApiToModelUpdate,
8+
} from './user.mappers.js';
9+
import { Usuario, UsuarioActualizado } from './user.api-model.js';
510

611
export const userApi = Router();
712

@@ -25,6 +30,7 @@ userApi
2530
next(error);
2631
}
2732
})
33+
2834
.post('/', async (req, res, next) => {
2935
try {
3036
const newUser: Usuario = req.body;
@@ -36,4 +42,25 @@ userApi
3642
} catch (error) {
3743
next(error);
3844
}
45+
})
46+
.get('/:id', async (req, res, next) => {
47+
try {
48+
const { id } = req.params;
49+
const user = await userRepository.getUserById(id);
50+
res.send(mapUserFromModelToApi(user));
51+
} catch (error) {
52+
next(error);
53+
}
54+
})
55+
.put('/:id', async (req, res, next) => {
56+
try {
57+
const { id } = req.params;
58+
const usuarioActualizado: UsuarioActualizado = req.body;
59+
const modelUser = mapUserFromApiToModelUpdate(usuarioActualizado);
60+
const estaActualizado = await userRepository.actualizarUsuario(id, modelUser);
61+
62+
res.status(201).send(estaActualizado);
63+
} catch (error) {
64+
next(error);
65+
}
3966
});

src/core/react-query/common-query-keys.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.

src/core/react-query/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
export * from './query';
2-
export * from './common-query-keys';
2+
export * from './query-keys';

src/core/react-query/query-keys.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export const commonQueryKeys = {
2+
all: ['common'],
3+
unidadRolList: () => ['common', 'unidadRolList'],
4+
};
5+
6+
export const usersQueryKeys = {
7+
all: ['users'],
8+
userCollection: (page?: number, pageSize?: number) => ['users', page, pageSize],
9+
user: (id: string) => ['user', id],
10+
};

src/core/theme/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from './theme-provider.component';
22
export * from './theme.hooks';
3+
export * from './theme';

src/modules/users/create/create.query.hook.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import { useMutation } from '@tanstack/react-query';
22
import { useNavigate } from '@tanstack/react-router';
3-
import { queryClient } from '#core/react-query';
3+
import { queryClient, usersQueryKeys } from '#core/react-query';
44
import { saveUserRepository } from './create.repository';
55
import { Usuario } from './create.vm';
6-
import { usersQueryKeys } from '../users-keys';
76

87
interface UseSaveUserMutationResult {
98
saveUser: (user: Usuario) => void;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export interface Usuario {
2+
id: string;
3+
nombre: string;
4+
apellido: string;
5+
email?: string;
6+
telefono?: string;
7+
movil?: string;
8+
unidad: string;
9+
rol?: string;
10+
esResponsable?: boolean;
11+
esProponente?: boolean;
12+
esAutorizante?: boolean;
13+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import axios from 'axios';
2+
import { Usuario } from './edit-user-sheet-api-model';
3+
4+
export const getUserById = async (id: string): Promise<Usuario> => {
5+
const response = await axios.get<Usuario>(`/api/user/${id}`);
6+
7+
return response.data;
8+
};
9+
10+
export const updateUser = async (usuario: Usuario): Promise<boolean> => {
11+
const response = await axios.put<boolean>(`/api/user/${usuario.id}`, usuario);
12+
13+
return response.data;
14+
};
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './edit-user-sheet-api';
2+
export * from './edit-user-sheet-api-model';

src/modules/users/edit-user-sheet/components/aditional-permissions.component.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import { Typography } from '@mui/material';
33
import { CheckboxForm } from '#common/components';
44
import { useWithTheme } from '#core/theme';
5-
import * as innerClasses from '../edit.styles';
5+
import * as innerClasses from '../edit-user-sheet.styles';
66

77
export const AditionalPermissions: React.FC = () => {
88
const classes = useWithTheme(innerClasses);

src/modules/users/edit-user-sheet/components/user-details.component.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Typography } from '@mui/material';
33
import { SelectForm, TextFieldForm } from '#common/components';
44
import { useWithTheme } from '#core/theme';
55
import { UnidadRolList } from '#core/api/lookups/unidad-rol';
6-
import * as innerClasses from '../edit.styles';
6+
import * as innerClasses from '../edit-user-sheet.styles';
77

88
interface Props {
99
unidadRolList: UnidadRolList;
@@ -27,7 +27,6 @@ export const UserDetails: React.FC<Props> = props => {
2727
<div className={classes.row}>
2828
<TextFieldForm name="telefono" label="Teléfono fijo" />
2929
<TextFieldForm name="movil" label="Teléfono móvil" />
30-
<TextFieldForm name="institucional" label="Teléfono Institucional" />
3130
<SelectForm label="Unidad" name="unidad" options={unidadRolList.unidades} />
3231
<SelectForm label="Rol" name="rol" options={unidadRolList.roles} />
3332
</div>

src/modules/users/edit-user-sheet/edit.component.tsx renamed to src/modules/users/edit-user-sheet/edit-user-sheet.component.tsx

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,33 @@
11
import React from 'react';
2-
32
import { Form, Formik } from 'formik';
4-
import { useWithTheme } from '#core/theme';
5-
import { UnidadRolList } from '#core/api/lookups/unidad-rol';
6-
import { Usuario, createEmptyUsuario } from './edit.vm';
73
import { Button } from '@mui/material';
8-
import { AditionalPermissions, UserDetails } from './components';
94
import { NavigationButton } from '#common/components';
10-
import * as innerClasses from './edit.styles';
5+
import { UnidadRolList } from '#core/api/lookups/unidad-rol';
6+
import { Usuario } from './edit-user-sheet.vm';
7+
import { AditionalPermissions, UserDetails } from './components';
8+
import { formValidation } from './validations';
9+
import * as classes from './edit-user-sheet.styles';
1110

1211
interface Props {
12+
usuario: Usuario;
1313
unidadRolList: UnidadRolList;
14-
onSubmit: (values: Usuario) => void;
14+
onSubmit: (usuario: Usuario) => void;
1515
}
1616

1717
export const EditUser: React.FC<Props> = (props: Props) => {
18-
const { unidadRolList, onSubmit } = props;
19-
const classes = useWithTheme(innerClasses);
18+
const { unidadRolList, onSubmit, usuario } = props;
2019
return (
2120
<>
2221
<div className={classes.root}>
2322
<Formik
24-
initialValues={createEmptyUsuario()}
23+
initialValues={usuario}
2524
enableReinitialize={true}
26-
/* TODO: implement Formik form Validation in the next steps */
27-
onSubmit={onSubmit}
25+
validate={formValidation.validateForm}
26+
onSubmit={usuario => onSubmit(usuario)}
2827
>
29-
{({ values }) => (
28+
{() => (
3029
<Form className={classes.form}>
31-
<UserDetails unidadRolList={unidadRolList} contraseña={values.contraseña} />
30+
<UserDetails unidadRolList={unidadRolList} contraseña={'admin'} />
3231
<AditionalPermissions />
3332
<div className={classes.buttonContainer}>
3433
<Button type="submit" variant="contained">

0 commit comments

Comments
 (0)