From fc149801e6ff2c8959a6db707699ddc248e0867d Mon Sep 17 00:00:00 2001 From: Oscar Date: Wed, 26 Mar 2025 19:43:26 +0100 Subject: [PATCH] feat: add table component and modal for notas --- .../form/text-field/text-field.component.tsx | 1 + .../fileUpload/fileUpload.component.tsx | 36 +++++ .../fileUpload/fileUpload.styles.ts | 23 +++ .../crear-notas/crear-notas.component.tsx | 135 ++++++++++++++++++ .../crear-notas/crear-notas.pod.tsx | 14 ++ .../crear-notas/crear-notas.styles.ts | 58 ++++++++ src/modules/expedientes/crear-notas/index.ts | 1 + .../editar-notas/components/index.ts | 1 + .../components/table.component.tsx | 119 +++++++++++++++ .../editar-notas/components/table.styles.ts | 11 ++ .../editar-notas/editar.notas.columns.tsx | 36 +++++ .../editar-notas/editar.notas.pod.tsx | 79 +++++++++- .../editar-notas/editar.notas.styles.tsx | 19 +++ .../editar-notas/editar.notas.vm.ts | 18 +++ 14 files changed, 549 insertions(+), 2 deletions(-) create mode 100644 src/modules/expedientes/crear-notas/components/fileUpload/fileUpload.component.tsx create mode 100644 src/modules/expedientes/crear-notas/components/fileUpload/fileUpload.styles.ts create mode 100644 src/modules/expedientes/crear-notas/crear-notas.component.tsx create mode 100644 src/modules/expedientes/crear-notas/crear-notas.pod.tsx create mode 100644 src/modules/expedientes/crear-notas/crear-notas.styles.ts create mode 100644 src/modules/expedientes/crear-notas/index.ts create mode 100644 src/modules/expedientes/editar-notas/components/index.ts create mode 100644 src/modules/expedientes/editar-notas/components/table.component.tsx create mode 100644 src/modules/expedientes/editar-notas/components/table.styles.ts create mode 100644 src/modules/expedientes/editar-notas/editar.notas.columns.tsx create mode 100644 src/modules/expedientes/editar-notas/editar.notas.styles.tsx create mode 100644 src/modules/expedientes/editar-notas/editar.notas.vm.ts diff --git a/src/common/components/form/text-field/text-field.component.tsx b/src/common/components/form/text-field/text-field.component.tsx index addd3bd..e632438 100644 --- a/src/common/components/form/text-field/text-field.component.tsx +++ b/src/common/components/form/text-field/text-field.component.tsx @@ -33,6 +33,7 @@ export const TextFieldForm: React.FC = props => { }, }} margin="normal" + /> ); }; diff --git a/src/modules/expedientes/crear-notas/components/fileUpload/fileUpload.component.tsx b/src/modules/expedientes/crear-notas/components/fileUpload/fileUpload.component.tsx new file mode 100644 index 0000000..1982593 --- /dev/null +++ b/src/modules/expedientes/crear-notas/components/fileUpload/fileUpload.component.tsx @@ -0,0 +1,36 @@ +import { IconButton, LinearProgress } from "@mui/material" +import UploadFileIcon from '@mui/icons-material/UploadFile'; +import DeleteIcon from '@mui/icons-material/Delete'; +import { useWithTheme } from "#core/theme/theme.hooks.ts"; +import * as innerClasses from './fileUpload.styles'; + +export const FileUploaded = () => { + + // logica segun si el archivo se ha subido correctamente o no + // mostrar nombre del fichero o Upload failed + // motivo del error ejemplo: File to large + // mostrar de un color u otro según estado + + const classes = useWithTheme(innerClasses); + + return ( +
+
+ +
+ document_file_name.pdf +
+ 100kb + + Cargando +
+ +
+
+ + + +
+ + ) +} diff --git a/src/modules/expedientes/crear-notas/components/fileUpload/fileUpload.styles.ts b/src/modules/expedientes/crear-notas/components/fileUpload/fileUpload.styles.ts new file mode 100644 index 0000000..b3ad7af --- /dev/null +++ b/src/modules/expedientes/crear-notas/components/fileUpload/fileUpload.styles.ts @@ -0,0 +1,23 @@ +import { css } from '@emotion/css'; + +export const fileBoxLeft = css` + display: flex; + align-items: center; + gap: 20px; +`; +export const fileBox = css` + display: flex; + justify-content: space-between; +`; +export const uploadingState = css` + display: flex; + gap: 10px; + align-items: center; + color: gray; +`; +export const pointSeparation = css` + width: 3px; + height: 3px; + background-color: gray; + border-radius: 50%; +`; diff --git a/src/modules/expedientes/crear-notas/crear-notas.component.tsx b/src/modules/expedientes/crear-notas/crear-notas.component.tsx new file mode 100644 index 0000000..99773e3 --- /dev/null +++ b/src/modules/expedientes/crear-notas/crear-notas.component.tsx @@ -0,0 +1,135 @@ +import React from 'react'; +import { Button, createTheme, Dialog, DialogContent, DialogTitle, IconButton, styled, ThemeProvider } from "@mui/material" +import { useWithTheme } from '#core/theme/theme.hooks.ts'; +import * as innerClasses from './crear-notas.styles'; +import { Form, Formik } from 'formik'; +import { TextFieldForm } from '#common/components/index.ts'; +import UploadFileIcon from '@mui/icons-material/UploadFile'; +import { FileUploaded } from './components/fileUpload/fileUpload.component'; +import CloseIcon from '@mui/icons-material/Close'; + +const VisuallyHiddenInput = styled('input')({ + clip: 'rect(0 0 0 0)', + clipPath: 'inset(50%)', + height: 1, + overflow: 'hidden', + position: 'absolute', + bottom: 0, + left: 0, + whiteSpace: 'nowrap', + width: 1, +}); + +const theme = createTheme({ + components: { + MuiButton: { + styleOverrides: { + root: { + textTransform: "none", + }, + }, + variants: [ + { + props: { variant: "text" }, + style: { + borderWidth: "2px", + borderStyle: "dashed", + borderColor: '#E0E0E0', + transition: 'border-color 0.3s ease-in-out', + "&:hover": { + borderColor: '#1976D2' + } + } + } + ], + } + } +}) + +interface Props { + isOpen: boolean, + setOpen: React.Dispatch> +} + +export const CrearNota: React.FC = (props) => { + + // Sustituir por useState del contexto + // const isOpen = false; + const { isOpen, setOpen } = props; + + const classes = useWithTheme(innerClasses); + const handleSubmit = () => { + // Implementacion + } + + return ( + + +
+ Nueva Nota + setOpen(false)}> + + +
+
+ +
+ +
+
+ + +
+ + + + + +
+
+ + +
+
+ + +
+ +
+
+
+ ) +} diff --git a/src/modules/expedientes/crear-notas/crear-notas.pod.tsx b/src/modules/expedientes/crear-notas/crear-notas.pod.tsx new file mode 100644 index 0000000..2bd9a3f --- /dev/null +++ b/src/modules/expedientes/crear-notas/crear-notas.pod.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import { CrearNota } from "./crear-notas.component" + +interface Props { + isOpen: boolean + setNewNoteOpen: React.Dispatch> +} + +export const CrearNotaPod: React.FC = props => { + + const { isOpen, setNewNoteOpen } = props; + + return +} diff --git a/src/modules/expedientes/crear-notas/crear-notas.styles.ts b/src/modules/expedientes/crear-notas/crear-notas.styles.ts new file mode 100644 index 0000000..213ed90 --- /dev/null +++ b/src/modules/expedientes/crear-notas/crear-notas.styles.ts @@ -0,0 +1,58 @@ +import { theme } from './../../../core/theme/theme'; +import { css } from '@emotion/css'; +import { Theme } from '@mui/material'; + +export const root = (theme: Theme) => css` + display: flex; + flex-direction: column; +`; + +export const form = () => css` + display: flex; + flex-direction: column; + gap: 20px; +`; + +export const formHeader = (theme: Theme) => css` + display: flex; + gap: ${theme.spacing(4)}; +`; + +export const formAddFile = () => css` + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; + padding: 30px; +`; + +export const formAddFileTitle = () => css` + color: black; +`; +export const formAddFileTypes = () => css` + color: gray; +`; + +export const formAddFileTitleStart = () => css` + color: ${theme.palette.primary.main}; + text-decoration: underline; +`; + +export const filesBox = () => css` + margin-top: 30px; + display: flex; + flex-direction: column; + gap: 30px; +`; + +export const buttonsGroup = () => css` + display: flex; + justify-content: flex-end; + gap: 10px; + margin-top: 30px; +`; + +export const titleBox = () => css` + display: flex; + justify-content: space-between; +`; diff --git a/src/modules/expedientes/crear-notas/index.ts b/src/modules/expedientes/crear-notas/index.ts new file mode 100644 index 0000000..7b18365 --- /dev/null +++ b/src/modules/expedientes/crear-notas/index.ts @@ -0,0 +1 @@ +export * from './crear-notas.pod'; diff --git a/src/modules/expedientes/editar-notas/components/index.ts b/src/modules/expedientes/editar-notas/components/index.ts new file mode 100644 index 0000000..48fa2e1 --- /dev/null +++ b/src/modules/expedientes/editar-notas/components/index.ts @@ -0,0 +1 @@ +export * from './table.component'; diff --git a/src/modules/expedientes/editar-notas/components/table.component.tsx b/src/modules/expedientes/editar-notas/components/table.component.tsx new file mode 100644 index 0000000..d9d1ecf --- /dev/null +++ b/src/modules/expedientes/editar-notas/components/table.component.tsx @@ -0,0 +1,119 @@ +import { ColumnDef, flexRender, getCoreRowModel, getPaginationRowModel, useReactTable } from '@tanstack/react-table'; +import React, { useEffect } from 'react'; +import { Nota } from '../editar.notas.vm'; +import { Table, TableContainer, Paper, TableHead, TableCell, TableRow, TableBody, TablePagination, Typography, Box } from '@mui/material'; +import { useWithTheme } from '#core/theme/theme.hooks.ts'; +import * as innerClasses from './table.styles'; + +interface Props { + columns: ColumnDef[]; + notesCollection: Nota[]; + totalItems: number; + currentPage: number; + handlePageChange: (event: unknown, page: number) => void; + handleChangeRowsPerPage: (event: React.ChangeEvent) => void; +} + +export const TableComponent: React.FC = props => { + + const { columns, notesCollection: data, totalItems, currentPage, handlePageChange, handleChangeRowsPerPage } = props; + const classes = useWithTheme(innerClasses); + + const tableInstance = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + rowCount: totalItems, + }) + + const { getRowModel, getHeaderGroups, getPageCount } = tableInstance; + + useEffect(() => { + + getRowModel().rows.map(row => ( + row.getVisibleCells().map(cell => ( + console.log(cell.column.id) + )) + )) + + }) + + return ( + + + + { + getHeaderGroups().map(headerGroup => ( + + + {headerGroup.headers.map(header => ( + header.id == 'nota' ? + + {flexRender(header.column.columnDef.header, header.getContext())} + + : + + {flexRender(header.column.columnDef.header, header.getContext())} + + ))} + + )) + } + + + { + getRowModel().rows.map(row => ( + + {row.getVisibleCells().map(cell => ( + cell.column.id == 'nota' ? + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + : + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ))} + + )) + } + +
+ + Total de notas: + 4 + + + + +
+ ) + +} diff --git a/src/modules/expedientes/editar-notas/components/table.styles.ts b/src/modules/expedientes/editar-notas/components/table.styles.ts new file mode 100644 index 0000000..033882d --- /dev/null +++ b/src/modules/expedientes/editar-notas/components/table.styles.ts @@ -0,0 +1,11 @@ +import { css } from '@emotion/css'; + +export const table = css` + min-width: 1200px; +`; + +export const pagination = css` + display: flex; + justify-content: flex-end; + padding: 10px; +`; diff --git a/src/modules/expedientes/editar-notas/editar.notas.columns.tsx b/src/modules/expedientes/editar-notas/editar.notas.columns.tsx new file mode 100644 index 0000000..cd7e74f --- /dev/null +++ b/src/modules/expedientes/editar-notas/editar.notas.columns.tsx @@ -0,0 +1,36 @@ +import { Nota } from "./editar.notas.vm"; +import { Box, IconButton } from "@mui/material"; +import { Visibility as VisibilityIcon, Edit as EditIcon } from "@mui/icons-material"; +import { ColumnDef } from "@tanstack/react-table"; + +export const useColumns = (): ColumnDef[] => { + + return [ + { accessorKey: 'id', header: 'ID' }, + { accessorKey: 'nota', header: 'Nota' }, + { accessorKey: 'fecha', header: 'Fecha' }, + { accessorKey: 'autor', header: 'Autor' }, + { + accessorKey: 'acciones', + header: 'Acciones', + cell: () => ( + + + + + + + + + ), + } + ] +} diff --git a/src/modules/expedientes/editar-notas/editar.notas.pod.tsx b/src/modules/expedientes/editar-notas/editar.notas.pod.tsx index ba3a7c2..7e494ba 100644 --- a/src/modules/expedientes/editar-notas/editar.notas.pod.tsx +++ b/src/modules/expedientes/editar-notas/editar.notas.pod.tsx @@ -1,5 +1,80 @@ -import React from 'react'; +import React, { useState } from 'react'; +import { TableComponent } from './components'; +import { useWithTheme } from '#core/theme/theme.hooks.ts'; +import * as innerClasses from './editar.notas.styles'; +import { useColumns } from './editar.notas.columns'; +import { TextFieldForm } from '#common/components/form/index.ts'; +import { Form, Formik } from 'formik'; +import { Button, Card } from '@mui/material'; +import { CrearNotaPod } from '../crear-notas'; export const EditarNotasPod: React.FC = () => { - return

Notas

; + + const columns = useColumns(); + const classes = useWithTheme(innerClasses); + + const [newNoteOpen, setNewNoteOpen] = useState(false); + + const handleSubmit = () => { + //function + } + + return ( + +
+ + {() => ( +
+ + + )} +
+ +
+ + +
+ ) + ; }; diff --git a/src/modules/expedientes/editar-notas/editar.notas.styles.tsx b/src/modules/expedientes/editar-notas/editar.notas.styles.tsx new file mode 100644 index 0000000..c229bd6 --- /dev/null +++ b/src/modules/expedientes/editar-notas/editar.notas.styles.tsx @@ -0,0 +1,19 @@ +import { css } from '@emotion/css'; + +export const root = css` + display: flex; + flex-direction: column; + gap: 30px; + align-items: center; +`; + +export const notesSectionHeader = css` + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + padding: 20px; +` +export const addNote = css` + height: min-content; +` diff --git a/src/modules/expedientes/editar-notas/editar.notas.vm.ts b/src/modules/expedientes/editar-notas/editar.notas.vm.ts new file mode 100644 index 0000000..0b421b5 --- /dev/null +++ b/src/modules/expedientes/editar-notas/editar.notas.vm.ts @@ -0,0 +1,18 @@ +export interface Nota { + id: string; + nota: string; + fecha: string; + autor: string; +} + +export const createEmptyNota = (): Nota => ({ + id: '', + nota: '', + fecha: '', + autor: '', +}); + +export interface UserQueryFilter { + page: number; + pageSize: number; +}