saveinmed/frontend/src/components/PagamentoList.tsx

134 lines
3.7 KiB
TypeScript

import React from 'react';
import { Models } from '@/lib/appwrite';
import RefreshButton from './RefreshButton';
import ListHeader from './ListHeader';
import DataTable, { Column } from './DataTable';
import Pagination from './Pagination';
import TableActions from './TableActions';
import SearchBar from './SearchBar';
interface PagamentoListProps {
pagamentos: Models.Document[];
loading: boolean;
error: string | null;
totalPagamentos: number;
currentPage: number;
pageSize: number;
onEdit: (p: Models.Document) => void;
onDelete: (id: string) => Promise<boolean>;
onRefresh: () => void;
onPrevPage: () => void;
onNextPage: () => void;
onSearch: (term: string) => void;
}
type PagamentoDocument = Models.Document & {
pedidos?: string[] | { $id?: string } | string | null;
valor?: number | string;
};
const PagamentoList: React.FC<PagamentoListProps> = ({
pagamentos,
loading,
error,
totalPagamentos,
currentPage,
pageSize,
onEdit,
onDelete,
onRefresh,
onPrevPage,
onNextPage,
onSearch,
}) => {
const totalPages = Math.ceil(totalPagamentos / pageSize);
const startItem = (currentPage - 1) * pageSize + 1;
const endItem = Math.min(currentPage * pageSize, totalPagamentos);
const [search, setSearch] = React.useState('');
const columns: Column<PagamentoDocument>[] = [
{
key: 'pedidos',
header: 'Pedido',
render: row => {
const pedidos = row.pedidos;
if (Array.isArray(pedidos)) return pedidos.join(', ');
if (pedidos && typeof pedidos === 'object') return pedidos.$id || 'N/A';
return pedidos ?? 'N/A';
},
},
{ key: 'status', header: 'Status' },
{ key: 'metodo', header: 'Método' },
{ key: 'valor', header: 'Valor', render: row =>
Number(row.valor).toLocaleString('pt-BR', { style: 'currency', currency: 'BRL' }) },
{ key: '$id', header: 'ID' },
{ key: '$createdAt', header: 'Data de Criação', render: row =>
new Date(row.$createdAt).toLocaleDateString('pt-BR') },
];
const handleDelete = async (id: string) => {
if (confirm('Tem certeza que deseja deletar este pagamento?')) {
await onDelete(id);
}
};
return (
<div className="container mx-auto px-4 py-8">
<ListHeader title="Lista de Pagamentos">
<SearchBar
value={search}
onChange={setSearch}
onSearch={() => onSearch(search)}
placeholder="Buscar status"
/>
<RefreshButton onClick={onRefresh} loading={loading} />
</ListHeader>
{error && (
<div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4">
{error}
</div>
)}
{loading ? (
<div className="flex justify-center items-center min-h-screen">
<div className="text-lg">Carregando pagamentos...</div>
</div>
) : (
<>
<DataTable
columns={columns}
data={pagamentos}
actions={(pag) => (
<TableActions
onEdit={() => onEdit(pag)}
onDelete={() => handleDelete(pag.$id)}
/>
)}
/>
<div className="mt-4 flex justify-between items-center">
<div className="text-sm text-gray-600">
{totalPagamentos > 0 ? (
<>Mostrando {startItem} - {endItem} de {totalPagamentos} pagamentos</>
) : (
'Total de pagamentos: 0'
)}
</div>
<Pagination
page={currentPage}
total={totalPages}
onPrev={onPrevPage}
onNext={onNextPage}
/>
</div>
</>
)}
</div>
);
};
export default PagamentoList;