Skip to content

Commit 907ebdd

Browse files
authored
Merge pull request #67 from Lemoncode/feature/#50-layout-editar-expediente-certificaciones
feature/#50 layout editar expediente certificaciones
2 parents 6d67e37 + 4d03623 commit 907ebdd

13 files changed

+291
-6
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,13 @@ export const usersQueryKeys = {
88
userCollection: (page?: number, pageSize?: number) => ['users', page, pageSize],
99
user: (id: string) => ['user', id],
1010
};
11+
12+
export const expedientesQueryKeys = {
13+
all: ['expedientes'],
14+
expedienteCollection: (page?: number, pageSize?: number) => ['expedientes', page, pageSize],
15+
};
16+
17+
export const certificacionesQueryKeys = {
18+
all: ['certificaciones'],
19+
certificacionCollection: (page?: number, pageSize?: number) => ['certificaciones', page, pageSize],
20+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './table.component';
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import React from 'react';
2+
import { Pagination, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@mui/material';
3+
import { ColumnDef, flexRender, getCoreRowModel, getPaginationRowModel, useReactTable } from '@tanstack/react-table';
4+
import { Certificacion } from '../editar-certificaciones.vm';
5+
import * as classes from './table.styles';
6+
7+
interface Props {
8+
columns: ColumnDef<Certificacion>[];
9+
certificacionCollection: Certificacion[];
10+
totalItems: number;
11+
currentPage: number;
12+
onPageChange: (event: React.ChangeEvent<unknown>, page: number) => void;
13+
}
14+
15+
export const TableComponent: React.FC<Props> = props => {
16+
const { columns, certificacionCollection: data, totalItems, currentPage, onPageChange } = props;
17+
const tableInstance = useReactTable({
18+
data,
19+
columns,
20+
getCoreRowModel: getCoreRowModel(),
21+
getPaginationRowModel: getPaginationRowModel(),
22+
rowCount: totalItems,
23+
});
24+
25+
const { getRowModel, getHeaderGroups, getPageCount } = tableInstance;
26+
27+
return (
28+
<TableContainer component={Paper}>
29+
<Table className={classes.table}>
30+
<TableHead>
31+
{getHeaderGroups().map(headerGroup => (
32+
<TableRow key={headerGroup.id}>
33+
{headerGroup.headers.map(header => (
34+
<TableCell key={header.id}>{flexRender(header.column.columnDef.header, header.getContext())}</TableCell>
35+
))}
36+
</TableRow>
37+
))}
38+
</TableHead>
39+
<TableBody>
40+
{getRowModel().rows.map(row => (
41+
<TableRow key={row.id}>
42+
{row.getVisibleCells().map(cell => (
43+
<TableCell key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</TableCell>
44+
))}
45+
</TableRow>
46+
))}
47+
</TableBody>
48+
</Table>
49+
<Pagination
50+
count={getPageCount()}
51+
page={currentPage + 1}
52+
onChange={onPageChange}
53+
className={classes.pagination}
54+
/>
55+
</TableContainer>
56+
);
57+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { css } from '@emotion/css';
2+
3+
export const table = css`
4+
min-width: 1200px;
5+
`;
6+
7+
export const pagination = css`
8+
display: flex;
9+
justify-content: center;
10+
padding: 10px;
11+
`;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { ColumnDef } from '@tanstack/react-table';
2+
import { Link } from '@tanstack/react-router';
3+
import { Box } from '@mui/material';
4+
import { Edit as EditIcon, Visibility as VisibilityIcon } from '@mui/icons-material';
5+
import { Certificacion } from './editar-certificaciones.vm';
6+
import * as classes from './editar-certificaciones.styles';
7+
8+
export const useColumns = (): ColumnDef<Certificacion>[] => {
9+
return [
10+
{ accessorKey: 'id', header: 'ID' },
11+
{ accessorKey: 'numeroFactura', header: 'Número de factura' },
12+
{ accessorKey: 'fechaFactura', header: 'Fecha de factura' },
13+
{ accessorKey: 'periodoGasto', header: 'Periodo de gasto' },
14+
{ accessorKey: 'importe', header: 'Importe' },
15+
{ accessorKey: 'fechaCertificacion', header: 'Fecha de certificación' },
16+
{ accessorKey: 'certifica', header: 'Certifica' },
17+
{
18+
accessorKey: 'acciones',
19+
header: 'Acciones',
20+
cell: ({ row }) => (
21+
<Box display="flex" alignItems="center" gap={2}>
22+
<Link to={`/certificaciones/${row.original.id}`} className={classes.link}>
23+
<VisibilityIcon sx={{ color: 'gray' }} />
24+
</Link>
25+
<Link to={`/editar-certificacion/${row.original.id}`} className={classes.link}>
26+
<EditIcon sx={{ color: 'gray' }} />
27+
</Link>
28+
</Box>
29+
),
30+
},
31+
];
32+
};
Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,46 @@
11
import React from 'react';
2+
import { Button, MenuItem, TextField } from '@mui/material';
3+
import { NavigationButton, Spinner } from '#common/components';
4+
import { usePagination } from './use-pagination-hook';
5+
import { TableComponent } from './components';
6+
import { useColumns } from './editar-certificaciones.columns';
7+
import * as classes from './editar-certificaciones.styles';
28

39
export const EditarCertificacionesPod: React.FC = () => {
4-
return <h2>Certificaciones</h2>;
10+
const { certificacionCollection, currentPage, totalPages, isLoading, onPageChange } = usePagination();
11+
const columns = useColumns();
12+
const [selectedOption, setSelectedOption] = React.useState('opcion1');
13+
14+
const handleSelectChange = (event: React.ChangeEvent<HTMLInputElement>) => {
15+
setSelectedOption(event.target.value);
16+
};
17+
18+
return (
19+
<div className={classes.root}>
20+
<Spinner isSpinnerShowing={isLoading} />
21+
<div className={classes.header}>
22+
<TextField select label="Ordenar" value={selectedOption} onChange={handleSelectChange} variant="outlined">
23+
<MenuItem value="opcion1">Fecha de creación</MenuItem>
24+
</TextField>
25+
<div className="newCertificacionButton">
26+
<Button variant="contained" color="primary">
27+
Nueva certificación
28+
</Button>
29+
</div>
30+
</div>
31+
<TableComponent
32+
columns={columns}
33+
certificacionCollection={certificacionCollection.data}
34+
totalItems={totalPages}
35+
currentPage={currentPage}
36+
onPageChange={onPageChange}
37+
/>
38+
<section className={classes.buttonContainer}>
39+
<NavigationButton path="/expedientes" text="Volver" variant="text" />
40+
<Button type="submit" variant="contained">
41+
Guardar
42+
</Button>
43+
</section>
44+
</div>
45+
);
546
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { useQuery } from '@tanstack/react-query';
2+
import { CollectionQuery, createEmptyCollectionQuery } from '#common/models';
3+
import { certificacionesQueryKeys } from '#core/react-query';
4+
import { getCertificacionesRepository } from './editar-certificaciones.repository';
5+
import { CertificacionQueryFilter, Certificacion } from './editar-certificaciones.vm';
6+
7+
interface UseCertificacionesQueryResult {
8+
certificacionCollection: CollectionQuery<Certificacion>;
9+
isLoading: boolean;
10+
}
11+
12+
export const useCertificacionesQuery = (
13+
certificacionFilter: CertificacionQueryFilter
14+
): UseCertificacionesQueryResult => {
15+
const { page, pageSize } = certificacionFilter;
16+
17+
const { data: certificacionCollection = createEmptyCollectionQuery(), isLoading } = useQuery({
18+
queryKey: certificacionesQueryKeys.certificacionCollection(page, pageSize),
19+
queryFn: () => getCertificacionesRepository(),
20+
});
21+
22+
return {
23+
certificacionCollection,
24+
isLoading,
25+
};
26+
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { CollectionQuery } from '#common/models';
2+
import { Certificacion } from './editar-certificaciones.vm';
3+
4+
export const getCertificacionesRepository = async (): Promise<CollectionQuery<Certificacion>> => ({
5+
data: [
6+
{
7+
id: '002',
8+
numeroFactura: '2213AF50',
9+
fechaFactura: '30/09/2019',
10+
periodoGasto: 'Del 01/09/2019 al 30/09/2019',
11+
importe: '15.0585.580 €',
12+
fechaCertificacion: '30/09/2019',
13+
certifica: 'Jesús Calvo',
14+
},
15+
{
16+
id: '052',
17+
numeroFactura: '2213AF51',
18+
fechaFactura: '30/09/2019',
19+
periodoGasto: 'Del 01/09/2019 al 30/09/2019',
20+
importe: '15.0585.580 €',
21+
fechaCertificacion: '30/09/2019',
22+
certifica: 'Jesús Calvo',
23+
},
24+
],
25+
pagination: {
26+
totalPages: 1,
27+
},
28+
});
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { css } from '@emotion/css';
2+
import { theme } from '#core/theme';
3+
4+
export const root = css`
5+
display: flex;
6+
flex-direction: column;
7+
gap: 30px;
8+
align-items: center;
9+
`;
10+
11+
export const header = css`
12+
display: flex;
13+
justify-content: space-between;
14+
width: 100%;
15+
padding: 0 ${theme.spacing(2)};
16+
`;
17+
18+
export const newCertificacionButton = () => css`
19+
display: 'flex';
20+
align-items: 'center';
21+
justify-content: 'space-between';
22+
gap: '1rem';
23+
`;
24+
25+
export const link = css`
26+
color: ${theme.palette.common.black};
27+
text-decoration: none;
28+
cursor: pointer;
29+
`;
30+
31+
export const buttonContainer = css`
32+
position: absolute;
33+
bottom: ${theme.spacing(2)};
34+
right: ${theme.spacing(2)};
35+
display: flex;
36+
justify-content: flex-end;
37+
gap: ${theme.spacing(4)};
38+
`;
39+
40+
export const volverButton = css`
41+
border-radius: ${theme.shape.borderRadius}px;
42+
`;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export interface Certificacion {
2+
id: string;
3+
numeroFactura: string;
4+
fechaFactura: string;
5+
periodoGasto: string;
6+
importe: string;
7+
fechaCertificacion: string;
8+
certifica: string;
9+
}
10+
11+
export const createEmptyCertificacion = (): Certificacion => ({
12+
id: '',
13+
numeroFactura: '',
14+
fechaFactura: '',
15+
periodoGasto: '',
16+
importe: '',
17+
fechaCertificacion: '',
18+
certifica: '',
19+
});
20+
21+
export interface CertificacionQueryFilter {
22+
page: number;
23+
pageSize: number;
24+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React from 'react';
2+
import { useCertificacionesQuery } from './editar-certificaciones.query.hook';
3+
4+
export const usePagination = (initialPage: number = 0, pageSize: number = 10) => {
5+
const [currentPage, setCurrentPage] = React.useState(initialPage);
6+
const { certificacionCollection, isLoading } = useCertificacionesQuery({ page: currentPage, pageSize });
7+
8+
const handleChangePage = (_: React.ChangeEvent<unknown>, newPage: number) => setCurrentPage(newPage - 1);
9+
10+
return {
11+
certificacionCollection,
12+
currentPage,
13+
totalPages: certificacionCollection.pagination.totalPages,
14+
isLoading,
15+
onPageChange: handleChangePage,
16+
};
17+
};

src/modules/expedientes/expedientes-keys.ts

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

src/modules/expedientes/list/expedientes.query.hook.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useQuery } from '@tanstack/react-query';
22
import { CollectionQuery, createEmptyCollectionQuery } from '#common/models';
3+
import { expedientesQueryKeys } from '#core/react-query';
34
import { getExpedienteRepository } from './expedientes.repository';
4-
import { expedientesQueryKeys } from '#modules/expedientes/expedientes-keys.ts';
55
import { ExpedienteQueryFilter, Expediente } from './expedientes.vm';
66

77
interface UseExpedientesQueryResult {

0 commit comments

Comments
 (0)