From 114b9b81cd97d72b967c5de9e098426c5b5750ec Mon Sep 17 00:00:00 2001 From: Anthony Mackensen Date: Sat, 15 Apr 2023 08:49:19 -0400 Subject: [PATCH 1/2] refactor: from class to function component --- .../datatable-columns.ts | 127 +++++++ .../datatable-labels.ts | 20 ++ .../datatable-options.ts | 38 +++ .../datatable-theme.ts | 128 +++++++ .../cmyk-participation-datatable/index.tsx | 315 +++++------------- tsconfig.json | 5 +- 6 files changed, 393 insertions(+), 240 deletions(-) create mode 100644 plugins/cmyk-participation-datatable/datatable-columns.ts create mode 100644 plugins/cmyk-participation-datatable/datatable-labels.ts create mode 100644 plugins/cmyk-participation-datatable/datatable-options.ts create mode 100644 plugins/cmyk-participation-datatable/datatable-theme.ts diff --git a/plugins/cmyk-participation-datatable/datatable-columns.ts b/plugins/cmyk-participation-datatable/datatable-columns.ts new file mode 100644 index 0000000..cf44af8 --- /dev/null +++ b/plugins/cmyk-participation-datatable/datatable-columns.ts @@ -0,0 +1,127 @@ +import { + projectsLabels, + stackWantedLabels, + workExperienceLabels, +} from './datatable-labels'; +import { MUIDataTableProps } from 'mui-datatables'; + +export const columns: MUIDataTableProps['columns'] = [ + { + name: '_createdAt', + label: 'Fecha', + options: { + filter: false, + sort: true, + customBodyRender: (value) => new Date(value).toLocaleString(), + }, + }, + { + name: 'discordUser', + label: 'Usuario', + options: { + filter: false, + sort: true, + }, + }, + { + name: 'email', + label: 'Email', + options: { + filter: false, + sort: true, + }, + }, + { + name: 'timezone', + label: 'Zona Horaria', + options: { + filter: true, + sort: true, + }, + }, + { + name: 'timeAvailability', + label: 'Disponibilidad horaria (semanal)', + options: { + filter: false, + sort: true, + customBodyRender: (value) => + value === '>2<4hours' + ? 'Entre 2 y 4 horas' + : value === '>4<6hours' + ? 'Entre 4 y 6 horas' + : 'Más de 6 horas', + }, + }, + { + name: 'aboutParticipant', + label: 'Sobre mí', + options: { + filter: false, + sort: false, + }, + }, + { + name: 'participationType', + label: 'Form', + options: { + filter: true, + sort: true, + customBodyRender: (value) => + value === 'lider' ? 'Líder' : 'Participante', + }, + }, + { + name: 'workExperience', + label: 'Experiencia Laboral', + options: { + filter: true, + sort: true, + customBodyRender: (value) => workExperienceLabels[value], + }, + }, + { + name: 'stackWanted', + label: 'Front o Back', + options: { + filter: true, + sort: true, + customBodyRender: (value) => stackWantedLabels[value], + }, + }, + { + name: 'projects', + label: 'Proyecto', + options: { + filter: true, + sort: true, + customBodyRender: (value) => projectsLabels[value], + }, + }, + { + name: 'previousKnowledge', + label: 'Conocimientos', + options: { + filter: false, + sort: false, + }, + }, + { + name: 'otherQuestions', + label: 'Otras preguntas', + options: { + filter: false, + sort: false, + }, + }, + { + name: 'status', + label: 'Estado', + options: { + filter: true, + sort: true, + customBodyRender: (value) => + value === 'revision' ? '🟡' : value === 'approved' ? '🟢' : '🔴', + }, + }, +]; diff --git a/plugins/cmyk-participation-datatable/datatable-labels.ts b/plugins/cmyk-participation-datatable/datatable-labels.ts new file mode 100644 index 0000000..a9993da --- /dev/null +++ b/plugins/cmyk-participation-datatable/datatable-labels.ts @@ -0,0 +1,20 @@ +export const workExperienceLabels = { + level0: 'Hasta 6 meses', + level1: 'Entre 6 meses y 1 año', + level2: 'Más de un año', + level3: 'Hasta 1 año', + level4: 'Entre 1 año y 3 años', + level5: 'Más de 3 años', +} as const; + +export const stackWantedLabels = { + front: 'Frontend (React)', + back: 'Backend (Node/Express)', + both: 'Ambos', +} as const; + +export const projectsLabels = { + flashcards: 'App Flashcards', + callForPapers: 'App Administrador call for papars', + both: 'No tengo preferencias', +} as const; diff --git a/plugins/cmyk-participation-datatable/datatable-options.ts b/plugins/cmyk-participation-datatable/datatable-options.ts new file mode 100644 index 0000000..ca1d847 --- /dev/null +++ b/plugins/cmyk-participation-datatable/datatable-options.ts @@ -0,0 +1,38 @@ +import { MUIDataTableProps } from 'mui-datatables'; + +export const options: MUIDataTableProps['options'] = { + downloadOptions: { filename: 'cmypParticipantsList.csv', separator: ';' }, + selectableRowsHeader: false, + selectableRowsHideCheckboxes: true, + rowsPerPage: 15, + rowsPerPageOptions: [10, 15, 20, 30, 50], + textLabels: { + body: { + noMatch: 'No hay resultados', + toolTip: 'Sort', + columnHeaderTooltip: (column) => `Ordenar por ${column.label}`, + }, + pagination: { + next: 'Siguiente', + previous: 'Anterior', + rowsPerPage: 'Filas por página:', + displayRows: 'de', + }, + toolbar: { + search: 'Buscar', + downloadCsv: 'Descargar CSV', + print: 'Imprimir', + viewColumns: 'Ver Columnas', + filterTable: 'Filtrar Tabla', + }, + filter: { + all: 'Todos', + title: 'FILTROS', + reset: 'RESET', + }, + viewColumns: { + title: 'Ver Columnas', + titleAria: 'Mostrar/Ocultar Columnas', + }, + }, +}; diff --git a/plugins/cmyk-participation-datatable/datatable-theme.ts b/plugins/cmyk-participation-datatable/datatable-theme.ts new file mode 100644 index 0000000..7934173 --- /dev/null +++ b/plugins/cmyk-participation-datatable/datatable-theme.ts @@ -0,0 +1,128 @@ +import { createTheme } from '@material-ui/core'; + +export const datatableTheme = createTheme({ + overrides: { + MuiPaper: { + root: { + color: 'inherit', + backgroundColor: 'inherit', + display: 'flex', + flexDirection: 'column', + }, + }, + + MuiToolbar: { + root: { + '& [class*="actions"]': { + display: 'flex', + alignItems: 'center', + gap: '0.25rem', + flex: '0 1 auto', + }, + }, + }, + + MuiButton: { + root: { + color: 'inherit', + '&:hover': { + backgroundColor: 'rgb(128 128 128 / 15%) !important', + }, + '& [class*="sortActive"]': { + color: 'var(--card-focus-ring-color)', + }, + }, + }, + + MuiTableSortLabel: { + icon: { + color: 'var(--card-focus-ring-color) !important', + }, + }, + + MuiIconButton: { + root: { + padding: '.5rem', + color: 'inherit', + '&:hover': { + backgroundColor: 'rgb(128 128 128 / 15%) !important', + }, + '&.Mui-disabled': { + color: 'rgb(128 128 128 / 50%)', + }, + }, + }, + + MUIDataTableSearch: { + searchIcon: { + color: 'inherit', + }, + }, + MuiInputBase: { + root: { + color: 'inherit', + }, + }, + + MUIDataTableHeadCell: { + fixedHeader: { + color: 'inherit', + backgroundColor: 'inherit', + borderTop: '1px solid var(--card-border-color)', + borderBottom: '1px solid var(--card-border-color)', + whiteSpace: 'nowrap', + }, + }, + + MuiPopover: { + paper: { + backgroundColor: '#fafafa', + }, + }, + + MUIDataTableBodyRow: { + responsiveStacked: { + '&': { + borderColor: 'var(--card-border-color)', + }, + }, + }, + + MuiTableCell: { + body: { + color: 'inherit', + }, + footer: { + color: 'inherit', + }, + }, + MUIDataTableBodyCell: { + stackedParent: { + borderColor: 'var(--card-border-color)', + }, + }, + + MuiTableRow: { + root: { + '&.MuiTableRow-hover': { + '&:hover': { + backgroundColor: 'rgb(128 128 128 / 15%)', + }, + }, + }, + }, + + MuiTablePagination: { + root: { + color: 'inherit', + }, + }, + MuiSelect: { + icon: { + color: 'inherit', + }, + }, + }, +}); + +export default datatableTheme; diff --git a/plugins/cmyk-participation-datatable/index.tsx b/plugins/cmyk-participation-datatable/index.tsx index dc22b62..e906ab1 100644 --- a/plugins/cmyk-participation-datatable/index.tsx +++ b/plugins/cmyk-participation-datatable/index.tsx @@ -1,10 +1,12 @@ -import React from 'react'; +import { ThemeProvider } from '@material-ui/core/styles'; +import { Card, Flex, Select, Spinner, Text } from '@sanity/ui'; import MUIDataTable from 'mui-datatables'; -import styles from './Styles.css'; -import sanityClient from 'part:@sanity/base/client'; -import Spinner from 'part:@sanity/components/loading/spinner'; -import { FormControl, NativeSelect } from '@material-ui/core'; +import { ChangeEvent, useEffect, useState } from 'react'; +import { clientPreConfig } from '../../sanity.client'; import pepeJedi from './assets/images/pepe-jedi.gif'; +import { columns } from './datatable-columns'; +import { options } from './datatable-options'; +import datatableTheme from './datatable-theme'; const withConfig = (config) => { return typeof sanityClient.withConfig === 'function' @@ -12,249 +14,84 @@ const withConfig = (config) => { : sanityClient; }; -const workExperienceLabels = { - "level0": "Hasta 6 meses", - "level1": "Entre 6 meses y 1 año", - "level2": "Más de un año", - "level3": "Hasta 1 año", - "level4": "Entre 1 año y 3 años", - "level5": "Más de 3 años", -} - -const stackWantedLabels = { - "front": "Frontend (React)", - "back": "Backend (Node/Express)", - "both": "Ambos", -} - -const projectsLabels = { - "flashcards": "App Flashcards", - "callForPapers": "App Administrador call for papars", - "both": "No tengo preferencias", -} - -class CMYKParticipationDatatable extends React.Component { - state = { - loading: true, +function CMYKParticipationDatatable() { + const [{ cmykParticipantsList, cmykVersion, loading }, setState] = useState({ cmykParticipantsList: [], cmykVersion: '5', - }; + loading: true, + }); - componentDidMount() { - this.getCMYKParticipants(); - } + const getCMYKParticipants = (cmykVer: string) => { + const cmkykQuery = `*[_type == "cmykParticipant" && cmykVersion == "${cmykVer}"] { _createdAt, "discordUser": discordUser->username, "email": discordUser->email, aboutParticipant, "timezone":discordUser->timezone, participationType, isChix, workExperience, stackWanted, projects, experience, timeAvailability, otherQuestions, previousKnowledge, status}`; - getCMYKParticipants = (cmykVer = 4) => { - withConfig({ apiVersion: 'v1' }) - .fetch( - `*[_type == "cmykParticipant" && cmykVersion == "${cmykVer}"] { _createdAt, "discordUser": discordUser->username, "email": discordUser->email, aboutParticipant, "timezone":discordUser->timezone, participationType, isChix, workExperience, stackWanted, projects, experience, timeAvailability, otherQuestions, previousKnowledge, status}`, - {}, - ) - .then((cmykPart) => { - this.setState({ cmykParticipantsList: cmykPart, loading: false }); - }); + client.fetch(cmkykQuery, {}).then((cmykPart) => { + setState((prevState) => ({ + ...prevState, + cmykParticipantsList: cmykPart, + loading: false, + })); + }); }; - render() { - const handleSelectChange = (value) => { - this.setState({ cmykVersion: value.target.value, loading: true }); - this.getCMYKParticipants(parseInt(value.target.value, 10)); - }; - const columns = [ - { - name: '_createdAt', - label: 'Fecha', - options: { - filter: false, - sort: true, - customBodyRender: (value) => new Date(value).toLocaleString(), - }, - }, - { - name: 'discordUser', - label: 'Usuario', - options: { - filter: false, - sort: true, - }, - }, - { - name: 'email', - label: 'Email', - options: { - filter: false, - sort: true, - }, - }, - { - name: 'timezone', - label: 'Zona Horaria', - options: { - filter: true, - sort: true, - }, - }, - { - name: 'timeAvailability', - label: 'Disponibilidad horaria (semanal)', - options: { - filter: false, - sort: true, - customBodyRender: (value) => - value === '>2<4hours' - ? 'Entre 2 y 4 horas' - : value === '>4<6hours' - ? 'Entre 4 y 6 horas' - : 'Más de 6 horas', - }, - }, - { - name: 'aboutParticipant', - label: 'Sobre mí', - options: { - filter: false, - sort: false, - }, - }, - { - name: 'participationType', - label: 'Form', - options: { - filter: true, - sort: true, - customBodyRender: (value) => (value === 'lider' ? 'Líder' : 'Participante'), - }, - }, - { - name: 'workExperience', - label: 'Experiencia Laboral', - options: { - filter: true, - sort: true, - customBodyRender: (value) => (workExperienceLabels[value]), - }, - }, - { - name: 'stackWanted', - label: 'Front o Back', - options: { - filter: true, - sort: true, - customBodyRender: (value) => (stackWantedLabels[value]), - }, - }, - { - name: 'projects', - label: 'Proyecto', - options: { - filter: true, - sort: true, - customBodyRender: (value) => (projectsLabels[value]), - }, - }, - { - name: 'previousKnowledge', - label: 'Conocimientos', - options: { - filter: false, - sort: false, - }, - }, - { - name: 'otherQuestions', - label: 'Otras preguntas', - options: { - filter: false, - sort: false, - }, - }, - { - name: 'status', - label: 'Estado', - options: { - filter: true, - sort: true, - customBodyRender: (value) => - value === 'revision' ? '🟡' : value === 'approved' ? '🟢' : '🔴', - }, - }, - ]; + useEffect(() => { + getCMYKParticipants(cmykVersion); + }, []); - const CustomBtn = () => { - return ( - <> - - - - - - - - - - jedi pepe - - ); - }; + const handleSelectChange = (e: ChangeEvent) => { + const { value } = e.target; + + setState((prevState) => ({ + ...prevState, + cmykVersion: value, + loading: true, + })); + + getCMYKParticipants(value); + }; - const options = { - downloadOptions: { filename: 'cmypParticipantsList.csv', separator: ';' }, - selectableRowsHeader: false, - selectableRowsHideCheckboxes: true, - rowsPerPage: 15, - rowsPerPageOptions: [10, 15, 20, 30, 50], - customToolbar: () => , - textLabels: { - body: { - noMatch: 'No hay resultados', - toolTip: 'Sort', - columnHeaderTooltip: (column) => `Ordenar por ${column.label}`, - }, - pagination: { - next: 'Siguiente', - previous: 'Anterior', - rowsPerPage: 'Filas por página:', - displayRows: 'de', - }, - toolbar: { - search: 'Buscar', - downloadCsv: 'Descargar CSV', - print: 'Imprimir', - viewColumns: 'Ver Columnas', - filterTable: 'Filtrar Tabla', - }, - filter: { - all: 'Todos', - title: 'FILTROS', - reset: 'RESET', - }, - viewColumns: { - title: 'Ver Columnas', - titleAria: 'Mostrar/Ocultar Columnas', - }, - }, - }; + return !loading ? ( + + ( + <> + - return ( -
- {!this.state.loading ? ( - - ) : ( - - )} -
- ); - } + jedi pepe + + ), + }} + /> +
+ ) : ( + + + + + Cargando... + + + + ); } export default { diff --git a/tsconfig.json b/tsconfig.json index fe5c0c7..c96f8db 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,10 @@ "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "preserve" + "jsx": "preserve", + "paths": { + "react": ["./node_modules/@types/react"] + } }, "include": [ "./node_modules/@sanity/base/types/**/*.ts", From 7614d076f369394a0deae997366290b7dc8608db Mon Sep 17 00:00:00 2001 From: Anthony Mackensen Date: Sat, 15 Apr 2023 19:40:49 -0400 Subject: [PATCH 2/2] refactor: fetching logic --- .../cmyk-participation-datatable/index.tsx | 33 ++++++++----------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/plugins/cmyk-participation-datatable/index.tsx b/plugins/cmyk-participation-datatable/index.tsx index e9f09f3..dd6f87c 100644 --- a/plugins/cmyk-participation-datatable/index.tsx +++ b/plugins/cmyk-participation-datatable/index.tsx @@ -8,41 +8,34 @@ import { columns } from './datatable-columns'; import { options } from './datatable-options'; import datatableTheme from './datatable-theme'; +const currentCMYKVersion: number = 5; const client = clientPreConfig({ apiVersion: 'v1' }); function CMYKParticipationDatatable() { - const [{ cmykParticipantsList, cmykVersion, loading }, setState] = useState({ - cmykParticipantsList: [], - cmykVersion: '5', + const [{ participantsList, cmykVersion, loading }, setState] = useState({ + participantsList: [], + cmykVersion: currentCMYKVersion.toString(), loading: true, }); - const getCMYKParticipants = (cmykVer: string) => { - const cmkykQuery = `*[_type == "cmykParticipant" && cmykVersion == "${cmykVer}"] { _createdAt, "discordUser": discordUser->username, "email": discordUser->email, aboutParticipant, "timezone":discordUser->timezone, participationType, isChix, workExperience, stackWanted, projects, experience, timeAvailability, otherQuestions, previousKnowledge, status}`; + useEffect(() => { + const cmkykQuery = `*[_type == "cmykParticipant" && cmykVersion == "${cmykVersion}"] { _createdAt, "discordUser": discordUser->username, "email": discordUser->email, aboutParticipant, "timezone":discordUser->timezone, participationType, isChix, workExperience, stackWanted, projects, experience, timeAvailability, otherQuestions, previousKnowledge, status}`; - client.fetch(cmkykQuery, {}).then((cmykPart) => { + client.fetch(cmkykQuery, {}).then((participantsList) => { setState((prevState) => ({ ...prevState, - cmykParticipantsList: cmykPart, + participantsList, loading: false, })); }); - }; - - useEffect(() => { - getCMYKParticipants(cmykVersion); - }, []); + }, [cmykVersion]); const handleSelectChange = (e: ChangeEvent) => { - const { value } = e.target; - setState((prevState) => ({ ...prevState, - cmykVersion: value, + cmykVersion: e.target.value, loading: true, })); - - getCMYKParticipants(value); }; return !loading ? ( @@ -50,7 +43,7 @@ function CMYKParticipationDatatable() { ( @@ -61,8 +54,8 @@ function CMYKParticipationDatatable() { name="cmykVersion" aria-label="cmykVersion" > - {[...Array(+cmykVersion)].map((_, i) => ( - + {[...Array(currentCMYKVersion)].map((_, i) => ( + ))}