arbritage/pages/Suppliers.tsx

144 lines
8.3 KiB
TypeScript
Raw Permalink Normal View History

2026-01-26 14:20:25 +00:00
import React, { useState } from 'react';
import { Store, Plus, Edit2, Trash2, Truck, Phone, Star } from 'lucide-react';
import { useCRM } from '../context/CRMContext';
import { Supplier } from '../types';
const Suppliers: React.FC = () => {
const { suppliers, addSupplier, updateSupplier, deleteSupplier } = useCRM();
const [isModalOpen, setIsModalOpen] = useState(false);
const [editingId, setEditingId] = useState<string | null>(null);
const [formData, setFormData] = useState<Partial<Supplier>>({
name: '', contact: '', rating: 5
});
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (editingId) {
updateSupplier(editingId, formData);
} else {
addSupplier(formData as any);
}
closeModal();
};
const openModal = (supplier?: Supplier) => {
if (supplier) {
setEditingId(supplier.id);
setFormData(supplier);
} else {
setEditingId(null);
setFormData({ name: '', contact: '', rating: 5 });
}
setIsModalOpen(true);
};
const closeModal = () => {
setIsModalOpen(false);
setEditingId(null);
};
return (
<div className="space-y-8 animate-in fade-in duration-500">
{/* HEADER */}
<div className="flex justify-between items-center glass-card p-6 rounded-2xl border border-white/5 shadow-sm">
<div>
<h2 className="text-xl font-bold text-white tracking-tight">Parceiros Logísticos</h2>
<p className="text-xs text-slate-500 tracking-wide mt-1">Gestão de Transporte e Fornecedores</p>
</div>
<button
onClick={() => openModal()}
className="flex items-center gap-2 bg-indigo-600 hover:bg-indigo-500 text-white px-5 py-2.5 rounded-lg font-bold text-sm transition-all shadow-lg shadow-indigo-600/20 active:scale-95"
>
<Plus size={16} /> Novo Parceiro
</button>
</div>
{/* LIST */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{suppliers.map(s => (
<div key={s.id} className="glass-card p-6 rounded-2xl border border-white/5 shadow-sm flex flex-col justify-between group hover:border-indigo-500/50 transition-all min-h-[160px] relative overflow-hidden">
{/* Watermark Icon */}
<div className="absolute -bottom-4 -right-4 text-white/[0.02] transform -rotate-12 group-hover:scale-110 transition-transform duration-500">
<Truck size={100} />
</div>
<div className="flex items-start justify-between mb-4 relative z-10">
<div className="flex items-center gap-4">
<div className="w-12 h-12 bg-indigo-500/10 text-indigo-400 rounded-xl flex items-center justify-center border border-indigo-500/20 group-hover:bg-indigo-600 group-hover:text-white transition-all shadow-lg">
<Truck size={20} />
</div>
<div>
<h4 className="text-base font-bold text-white max-w-[150px] truncate leading-tight" title={s.name}>{s.name}</h4>
<p className="text-[10px] text-slate-500 font-bold uppercase tracking-widest mt-0.5">Parceiro</p>
</div>
</div>
<div className="flex gap-0.5">
{[1, 2, 3, 4, 5].map(star => (
<div key={star} className={`w-1 h-1 rounded-full ${star <= s.rating ? 'bg-amber-400' : 'bg-slate-700/50'}`}></div>
))}
</div>
</div>
<div className="space-y-2 mb-4 relative z-10">
{s.contact && (
<div className="flex items-center gap-2 text-slate-400 text-xs font-mono bg-black/20 p-2 rounded-lg border border-white/5">
<Phone size={12} className="text-emerald-400" />
{s.contact}
</div>
)}
</div>
<div className="pt-3 border-t border-white/5 flex justify-end gap-2 relative z-10">
<button onClick={() => openModal(s)} className="p-1.5 text-slate-500 hover:text-white hover:bg-white/10 rounded transition-all"><Edit2 size={14} /></button>
<button onClick={() => deleteSupplier(s.id)} className="p-1.5 text-slate-500 hover:text-rose-400 hover:bg-rose-500/10 rounded transition-all"><Trash2 size={14} /></button>
</div>
</div>
))}
</div>
{/* MODAL */}
{isModalOpen && (
<div className="fixed inset-0 bg-black/80 backdrop-blur-sm z-50 flex items-center justify-center p-4">
<div className="bg-[#0F1115] border border-white/10 w-full max-w-md rounded-2xl p-6 shadow-2xl animate-in zoom-in-95 duration-200">
<h3 className="text-lg font-bold text-white mb-6 border-b border-white/5 pb-4">{editingId ? 'Editar Parceiro' : 'Novo Parceiro'}</h3>
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Nome / Apelido</label>
<input required type="text" value={formData.name} onChange={e => setFormData({ ...formData, name: e.target.value })} className="w-full bg-black/40 border border-white/10 rounded-lg px-3 py-2 text-sm text-white focus:border-indigo-500 outline-none transition-all" placeholder="Ex: João Freteiro" />
</div>
<div>
<label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Contato (WhatsApp)</label>
<input type="text" value={formData.contact} onChange={e => setFormData({ ...formData, contact: e.target.value })} className="w-full bg-black/40 border border-white/10 rounded-lg px-3 py-2 text-sm text-white focus:border-indigo-500 outline-none transition-all" placeholder="+55 45 9..." />
</div>
<div>
<label className="block text-[10px] font-bold text-slate-500 uppercase mb-1">Avaliação / Confiança (1-5)</label>
<div className="flex gap-4 mt-2">
{[1, 2, 3, 4, 5].map(star => (
<button
type="button"
key={star}
onClick={() => setFormData({ ...formData, rating: star })}
className={`p-2 rounded-lg transition-all ${star <= (formData.rating || 0) ? 'text-amber-400 bg-amber-400/10' : 'text-slate-600 bg-slate-800'}`}
>
<Star size={16} fill={star <= (formData.rating || 0) ? "currentColor" : "none"} />
</button>
))}
</div>
</div>
<div className="flex gap-3 mt-8 pt-4 border-t border-white/5">
<button type="button" onClick={closeModal} className="flex-1 py-2 text-xs font-bold text-slate-400 hover:text-white transition-colors uppercase tracking-wide">Cancelar</button>
<button type="submit" className="flex-1 bg-indigo-600 hover:bg-indigo-500 text-white py-2 rounded-lg font-bold shadow-lg transition-all text-sm">Salvar</button>
</div>
</form>
</div>
</div>
)}
</div>
);
};
export default Suppliers;