100 lines
3.5 KiB
TypeScript
100 lines
3.5 KiB
TypeScript
|
|
'use client';
|
|||
|
|
|
|||
|
|
import { useMemo } from 'react';
|
|||
|
|
import Box from '@mui/material/Box';
|
|||
|
|
import Typography from '@mui/material/Typography';
|
|||
|
|
import CircularProgress from '@mui/material/CircularProgress';
|
|||
|
|
import Alert from '@mui/material/Alert';
|
|||
|
|
import { DataGridPremium } from '@mui/x-data-grid-premium';
|
|||
|
|
import { useOrderItems } from '../../hooks/useOrderItems';
|
|||
|
|
import { createOrderItemsColumns } from '../OrderItemsTableColumns';
|
|||
|
|
import { OrderItem } from '../../schemas/order.item.schema';
|
|||
|
|
import { dataGridStyles } from '../../utils/dataGridStyles';
|
|||
|
|
|
|||
|
|
interface OrderItemsTableProps {
|
|||
|
|
orderId: number;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export const OrderItemsTable = ({ orderId }: OrderItemsTableProps) => {
|
|||
|
|
const { data: items, isLoading, error } = useOrderItems(orderId);
|
|||
|
|
|
|||
|
|
const columns = useMemo(() => createOrderItemsColumns(), []);
|
|||
|
|
|
|||
|
|
const rows = useMemo(() => {
|
|||
|
|
if (!Array.isArray(items) || items.length === 0) return [];
|
|||
|
|
return items.map((item: OrderItem, index: number) => ({
|
|||
|
|
id: `${orderId}-${item.productId}-${index}`,
|
|||
|
|
...item,
|
|||
|
|
}));
|
|||
|
|
}, [items, orderId]);
|
|||
|
|
|
|||
|
|
if (isLoading) {
|
|||
|
|
return (
|
|||
|
|
<Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', py: 4 }}>
|
|||
|
|
<CircularProgress size={40} />
|
|||
|
|
<Typography variant="body2" color="text.secondary" sx={{ ml: 2 }}>
|
|||
|
|
Carregando itens do pedido...
|
|||
|
|
</Typography>
|
|||
|
|
</Box>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (error) {
|
|||
|
|
return (
|
|||
|
|
<Box sx={{ mt: 2 }}>
|
|||
|
|
<Alert severity="error">
|
|||
|
|
{error instanceof Error
|
|||
|
|
? `Erro ao carregar itens: ${error.message}`
|
|||
|
|
: 'Erro ao carregar itens do pedido.'}
|
|||
|
|
</Alert>
|
|||
|
|
</Box>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!items || items.length === 0) {
|
|||
|
|
return (
|
|||
|
|
<Box sx={{ mt: 2 }}>
|
|||
|
|
<Alert severity="info">Nenhum item encontrado para este pedido.</Alert>
|
|||
|
|
</Box>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<DataGridPremium
|
|||
|
|
rows={rows}
|
|||
|
|
columns={columns}
|
|||
|
|
density="compact"
|
|||
|
|
autoHeight
|
|||
|
|
hideFooter={rows.length <= 10}
|
|||
|
|
initialState={{
|
|||
|
|
pagination: {
|
|||
|
|
paginationModel: {
|
|||
|
|
pageSize: 10,
|
|||
|
|
page: 0,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
}}
|
|||
|
|
pageSizeOptions={[10, 25, 50]}
|
|||
|
|
sx={dataGridStyles}
|
|||
|
|
localeText={{
|
|||
|
|
noRowsLabel: 'Nenhum item encontrado.',
|
|||
|
|
noResultsOverlayLabel: 'Nenhum resultado encontrado.',
|
|||
|
|
footerTotalRows: 'Total de itens:',
|
|||
|
|
footerTotalVisibleRows: (visibleCount, totalCount) =>
|
|||
|
|
`${visibleCount.toLocaleString()} de ${totalCount.toLocaleString()}`,
|
|||
|
|
}}
|
|||
|
|
slotProps={{
|
|||
|
|
pagination: {
|
|||
|
|
labelRowsPerPage: 'Itens por página:',
|
|||
|
|
labelDisplayedRows: ({ from, to, count }: { from: number; to: number; count: number }) => {
|
|||
|
|
const pageSize = to >= from ? to - from + 1 : 10;
|
|||
|
|
const currentPage = Math.floor((from - 1) / pageSize) + 1;
|
|||
|
|
const totalPages = Math.ceil(count / pageSize);
|
|||
|
|
return `${from}–${to} de ${count} | Página ${currentPage} de ${totalPages}`;
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
}}
|
|||
|
|
/>
|
|||
|
|
);
|
|||
|
|
};
|