import { Box, CircularProgress, Collapse, darken, IconButton, InputAdornment, Paper, SxProps, Table, TableBody, TableCell, TableContainer, TableHead, TablePagination, TableRow, TextField, Theme, Typography } from "@mui/material"; import { makeStyles } from "@mui/styles"; import { ChevronRight, Search } from "@mui/icons-material" import { useEffect, useState } from "react"; import React from "react"; const useStyles = makeStyles((theme: Theme) => { // const isMobile = useMobile() return ({ gutter: { backgroundColor: darken(theme.palette.background.paper, 0.03), border: "none" }, tableContainer: { margin: theme.spacing(1), [theme.breakpoints.up("sm")]: { margin: theme.spacing(2) }, width: "auto" }, title: { padding: theme.spacing(1) }, titleContainer: { border: "none", }, searchContainer: { border: "none", textAlign: "right", }, })}, ); export interface Column { title: string | JSX.Element; cellStyle?: SxProps | undefined render?: (row: T) => JSX.Element; } interface Props { rows: T[], columns?: Column[], title?: string; total: number, pageSize: number, page: number, setPage: (value: React.SetStateAction) => void, handleRowsPerPageChange: (event: any) => void, renderGutter?: (row: T) => JSX.Element, setSearchText?: React.Dispatch>, isLoading?: boolean; multiGutter?: boolean; } export default function ResponsiveTable(props: Props) { const { rows, total, page, pageSize, setPage, handleRowsPerPageChange, title, renderGutter, setSearchText, isLoading, multiGutter, columns } = props const classes = useStyles(); const [inputSearchText, setInputSearchText] = useState(""); const [openGutters, setOpenGutters] = useState([]) useEffect(() => { if (!setSearchText) return; if (inputSearchText === undefined) return; const handler = setTimeout(() => { setSearchText(inputSearchText); }, 750); // Delay of 750ms return () => clearTimeout(handler); // Cleanup on change }, [inputSearchText]); const handleCollapse = (index: number) => { if (multiGutter) { if (openGutters.includes(index)) { setOpenGutters(openGutters => openGutters.filter(num => num !== index)); } else { setOpenGutters(openGutters => [...openGutters, index]); } } else { if (openGutters.includes(index)) { setOpenGutters([]) } else { setOpenGutters([index]) } } } const handlePageChange = (page: number) => { setOpenGutters([]) setPage(page) } return ( {title && {typeof(title) === "string" ? {title} : title } } { setSearchText && setInputSearchText(e.currentTarget.value)} InputProps={{ startAdornment: ( ), }} /> } { renderGutter && } { columns ? columns.map((column, index) => { return ( {column.title} ) }) : rows.length > 0 && Object.keys(rows[0]).map((value, index) => { return( {value.toString()} ) }) } { isLoading ? { isLoading && } : rows.map((row, index) => { return ( {renderGutter && handleCollapse(index)}> } {columns ? columns.map((column, j) => { if (column.render) return ( {column.render(row)} ) return ( {Object.values(row)[j].toString()} ) }) : Object.values(row).map((value, j) => { return ( {value.toString()} ) }) } {renderGutter && {renderGutter(row)} } ) }) }
handlePageChange(page)} onRowsPerPageChange={handleRowsPerPageChange} />
) }