testes/src_2/features/financeiro-cnab/views/FavorecidosView.jsx

169 lines
7.0 KiB
JavaScript

import React from 'react';
import {
Search,
Filter,
Download,
Edit2,
Trash2,
ChevronLeft,
ChevronRight,
UserPlus,
Loader2
} from 'lucide-react';
import { cn } from '@/lib/utils';
import { toast } from 'sonner';
import { AnimatePresence } from 'framer-motion';
import DetailsPanel from '../components/DetailsPanel';
import { useCnabStore } from '../hooks/useCnabStore';
import CnabExcelTable from '../components/CnabExcelTable';
/**
* Tela de Gestão de Favorecidos
*/
const FavorecidosView = () => {
const { paymentMode } = useCnabStore();
const {
favorecidos,
loading,
searchTerm,
setSearchTerm,
selectedFavorecido,
setSelectedFavorecido,
handleExport,
handleDelete
} = useFavorecidos();
// Definição de colunas baseada no Modo (TED/PIX)
const columns = paymentMode === 'TED' ? [
{ field: 'agencia', header: 'Agência Favorecida', width: '150px' },
{ field: 'banco', header: 'Banco Favorecido', width: '150px' },
{ field: 'conta', header: 'Conta Favorecida', width: '150px' },
{
field: 'dataPagamento',
header: 'Data Pagamento',
width: '180px',
render: () => <span className="text-[10px] text-zinc-500 font-mono">31/12/2025</span>
},
{ field: 'digitoAgencia', header: 'Díg. Agência', width: '100px', render: (row) => row.digitoAgencia || '---' },
{ field: 'digitoConta', header: 'Díg. Conta', width: '100px', render: (row) => row.digitoConta || '---' },
{ field: 'finalidade', header: 'Finalidade TED', width: '120px' },
{ field: 'nome', header: 'Nome Favorecido', width: '250px', render: (row) => (
<p className="font-bold text-zinc-200 group-hover:text-emerald-500 transition-colors uppercase text-xs truncate">
{row.nome}
</p>
)},
{ field: 'status', header: 'Status', width: '100px', render: (row) => (
<span className={cn(
"text-[9px] font-black uppercase tracking-widest",
row.status === 'Ativo' ? 'text-emerald-500' : 'text-zinc-600'
)}>
{row.status}
</span>
)},
{ field: 'documento', header: 'Tipo Documento', width: '120px', render: () => '2' },
{ field: 'valor', header: 'Valor Pagamento', width: '150px', render: () => '5000.00' }
] : [
{ field: 'pix', header: 'Chave PIX', width: '200px', render: (row) => row.pix || '---' },
{ field: 'documento', header: 'CPF/CNPJ Favorecido', width: '180px' },
{ field: 'nome', header: 'Nome Favorecido', width: '250px', render: (row) => (
<p className="font-bold text-zinc-200 group-hover:text-emerald-500 transition-colors uppercase text-xs truncate">
{row.nome}
</p>
)},
{ field: 'tipoPix', header: 'Tipo Chave PIX', width: '130px', render: (row) => row.tipoPix || '1' },
{ field: 'id', header: 'ID Favorecido', width: '120px' }
];
return (
<div className="space-y-6 animate-in slide-in-from-bottom-4 duration-500 relative h-full flex flex-col overflow-hidden">
<div className="flex justify-between items-end shrink-0">
<div>
<h2 className="text-3xl font-black text-white mb-2 tracking-tighter">
Gestão de <span className="text-emerald-500">Favorecidos</span>
<span className="ml-4 text-xs bg-zinc-800 text-zinc-500 px-3 py-1 rounded-full border border-zinc-700 font-mono uppercase tracking-widest">
MODO {paymentMode}
</span>
</h2>
<p className="text-zinc-500 text-sm">Gerencie os dados dos beneficiários para remessas bancárias.</p>
</div>
<div className="flex gap-3">
<button
onClick={handleExport}
className="flex items-center gap-2 px-5 py-2.5 bg-zinc-800 hover:bg-zinc-700 text-zinc-300 rounded-2xl text-xs font-black uppercase tracking-widest transition-all border border-zinc-700 active:scale-95 shadow-lg"
>
<Download size={16} />
Exportar
</button>
<button
onClick={() => toast.info('Funcionalidade de cadastro em desenvolvimento')}
className="flex items-center gap-2 px-6 py-2.5 bg-emerald-600 hover:bg-emerald-500 text-white rounded-2xl text-xs font-black uppercase tracking-widest transition-all shadow-xl shadow-emerald-900/20 active:scale-95"
>
<UserPlus size={18} />
Novo Favorecido
</button>
</div>
</div>
{/* Filters Area */}
<div className="bg-[#1b1b1b] border border-zinc-800 rounded-3xl p-5 flex flex-wrap gap-4 items-center shadow-xl shrink-0">
<div className="relative flex-1 min-w-[300px] group">
<Search size={18} className="absolute left-5 top-1/2 -translate-y-1/2 text-zinc-600 group-focus-within:text-emerald-500 transition-colors" />
<input
type="text"
placeholder={`Pesquisar por nome, documento ou ${paymentMode === 'PIX' ? 'chave PIX' : 'dados bancários'}...`}
className="w-full pl-14 pr-5 py-4 bg-[#151515] border border-zinc-800 rounded-2xl text-zinc-200 focus:outline-none focus:border-emerald-600 focus:ring-1 focus:ring-emerald-600/20 transition-all text-sm group-hover:bg-[#1a1a1a]"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
</div>
<button className="flex items-center gap-3 px-6 py-4 bg-zinc-800 hover:bg-zinc-700 text-zinc-300 rounded-2xl text-xs font-black uppercase tracking-widest transition-colors border border-zinc-700">
<Filter size={16} />
Filtros
</button>
</div>
{/* Table Section */}
<div className="flex-1 min-h-0">
{loading ? (
<div className="bg-[#1b1b1b] border border-zinc-800 rounded-3xl h-full flex flex-col items-center justify-center space-y-4 shadow-2xl">
<Loader2 className="w-10 h-10 text-emerald-500 animate-spin" />
<p className="text-zinc-500 font-bold text-xs uppercase tracking-widest">Sincronizando registros...</p>
</div>
) : (
<CnabExcelTable
data={favorecidos}
columns={columns}
onEdit={(row) => setSelectedFavorecido(row)}
onDelete={(ids) => {
if (ids.length === 1) handleDelete(ids[0]);
else toast.info(`Excluindo ${ids.length} registros...`);
}}
rowKey="id"
/>
)}
</div>
{/* Detailed Panel */}
<AnimatePresence>
{selectedFavorecido && (
<>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="fixed inset-0 bg-black/80 backdrop-blur-sm z-[60] transition-opacity"
onClick={() => setSelectedFavorecido(null)}
/>
<DetailsPanel
favorecido={selectedFavorecido}
onClose={() => setSelectedFavorecido(null)}
/>
</>
)}
</AnimatePresence>
</div>
);
};
export default FavorecidosView;