169 lines
7.0 KiB
JavaScript
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;
|