Files
blog/src_generic/components/GenericTable.tsx

96 lines
2.5 KiB
TypeScript

import * as React from 'react';
import {
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Paper,
IconButton,
Typography,
Box,
Button
} from '@mui/material';
import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/Delete';
import { ResourceConfig } from '../types/config';
interface GenericTableProps {
config: ResourceConfig;
data: any[];
onEdit: (item: any) => void;
onDelete: (id: string) => void;
onCreate: () => void;
}
export default function GenericTable({
config,
data,
onEdit,
onDelete,
onCreate,
}: GenericTableProps) {
const fields = Object.entries(config.fields);
return (
<Box>
<Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 3, alignItems: 'center' }}>
<Typography variant="h5">{config.pluralLabel}</Typography>
<Button variant="contained" color="primary" onClick={onCreate}>
Add {config.label}
</Button>
</Box>
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }}>
<TableHead>
<TableRow>
{fields.map(([key, field]) => (
<TableCell key={key}>{field.label}</TableCell>
))}
<TableCell align="right">Actions</TableCell>
</TableRow>
</TableHead>
<TableBody>
{data.map((item) => (
<TableRow key={item[config.primaryKey]}>
{fields.map(([key, field]) => (
<TableCell key={key}>
{renderCellValue(item[key], field)}
</TableCell>
))}
<TableCell align="right">
<IconButton onClick={() => onEdit(item)}>
<EditIcon />
</IconButton>
<IconButton onClick={() => onDelete(item[config.primaryKey])}>
<DeleteIcon />
</IconButton>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</Box>
);
}
function renderCellValue(value: any, field: any) {
if (value === null || value === undefined) return '-';
switch (field.type) {
case 'boolean':
return value ? 'Yes' : 'No';
case 'date':
return new Date(value).toLocaleDateString();
case 'object':
return JSON.stringify(value);
case 'array':
return `${value.length} items`;
default:
return String(value);
}
}