alterações design
This commit is contained in:
@@ -141,6 +141,7 @@ function DashboardInner({ shop }: { shop: BarberShop }) {
|
||||
|
||||
const [barberName, setBarberName] = useState('');
|
||||
const [barberSpecs, setBarberSpecs] = useState('');
|
||||
const [barberSearchQuery, setBarberSearchQuery] = useState('');
|
||||
|
||||
// Settings states
|
||||
const [editShopName, setEditShopName] = useState(shop.name);
|
||||
@@ -249,12 +250,11 @@ function DashboardInner({ shop }: { shop: BarberShop }) {
|
||||
if (!barberName.trim()) return;
|
||||
addBarber(shop.id, {
|
||||
name: barberName,
|
||||
imageUrl: '', // Foto será adicionada depois
|
||||
specialties: barberSpecs.split(',').map((s) => s.trim()).filter(Boolean),
|
||||
imageUrl: '',
|
||||
specialties: [],
|
||||
schedule: [],
|
||||
});
|
||||
setBarberName('');
|
||||
setBarberSpecs('');
|
||||
};
|
||||
|
||||
const [uploadingBarberId, setUploadingBarberId] = useState<string | null>(null);
|
||||
@@ -349,7 +349,7 @@ function DashboardInner({ shop }: { shop: BarberShop }) {
|
||||
{ id: 'orders', label: 'Pedidos', icon: ShoppingBag, badge: pendingOrders > 0 ? pendingOrders : undefined },
|
||||
{ id: 'services', label: 'Serviços', icon: Scissors },
|
||||
{ id: 'products', label: 'Produtos', icon: Package },
|
||||
{ id: 'barbers', label: 'Barbeiros', icon: Users },
|
||||
{ id: 'barbers', label: 'Profissionais', icon: Users },
|
||||
{ id: 'settings', label: 'Definições', icon: Settings },
|
||||
];
|
||||
|
||||
@@ -897,82 +897,104 @@ function DashboardInner({ shop }: { shop: BarberShop }) {
|
||||
|
||||
{activeTab === 'barbers' && (
|
||||
<div className="space-y-6">
|
||||
<Card className="p-6">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h2 className="text-lg font-bold text-slate-900">Barbeiros</h2>
|
||||
<Badge color="slate" variant="soft">{shop.barbers.length} barbeiros</Badge>
|
||||
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4">
|
||||
<h2 className="text-2xl font-bold text-slate-900">Profissionais</h2>
|
||||
</div>
|
||||
|
||||
{/* Barra de Pesquisa Estilo Screenshot */}
|
||||
<div className="relative group">
|
||||
<div className="absolute left-4 top-1/2 -translate-y-1/2 text-slate-400 group-focus-within:text-indigo-500 transition-colors">
|
||||
<Search size={20} />
|
||||
</div>
|
||||
<div className="space-y-3 mb-6">
|
||||
{shop.barbers.map((b) => (
|
||||
<div key={b.id} className="p-4 border border-slate-200 rounded-lg">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="relative group/avatar">
|
||||
<div className="w-16 h-16 rounded-2xl overflow-hidden border-2 border-slate-100 bg-slate-50 flex items-center justify-center">
|
||||
{b.imageUrl ? (
|
||||
<img src={b.imageUrl} alt={b.name} className="w-full h-full object-cover" />
|
||||
) : (
|
||||
<Users size={24} className="text-slate-400" />
|
||||
)}
|
||||
</div>
|
||||
<input
|
||||
type="file"
|
||||
id={`barber-img-${b.id}`}
|
||||
className="hidden"
|
||||
accept="image/*"
|
||||
onChange={(e) => handleBarberImageUpload(b.id, e)}
|
||||
/>
|
||||
<label
|
||||
htmlFor={`barber-img-${b.id}`}
|
||||
className="absolute inset-0 bg-black/40 text-white flex items-center justify-center rounded-2xl opacity-0 group-hover/avatar:opacity-100 cursor-pointer transition-opacity"
|
||||
>
|
||||
{uploadingBarberId === b.id ? <RefreshCw size={14} className="animate-spin" /> : <Plus size={14} />}
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-bold text-slate-900 text-lg">{b.name}</p>
|
||||
<p className="text-sm text-slate-600">
|
||||
{b.specialties.length > 0 ? b.specialties.join(', ') : 'Sem especialidades'}
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Pesquisar"
|
||||
value={barberSearchQuery}
|
||||
onChange={(e) => setBarberSearchQuery(e.target.value)}
|
||||
className="w-full h-14 pl-12 pr-4 bg-[#0d0d0d] border border-white/5 rounded-xl text-white placeholder:text-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 transition-all font-medium"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Grelha de Profissionais */}
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
{shop.barbers
|
||||
.filter(b => b.name.toLowerCase().includes(barberSearchQuery.toLowerCase()))
|
||||
.map((b) => (
|
||||
<div key={b.id} className="group relative flex items-center gap-4 p-4 bg-[#0d0d0d] border border-white/5 rounded-[2rem] hover:border-indigo-500/30 transition-all duration-300 shadow-xl">
|
||||
{/* Avatar squircle robusto */}
|
||||
<div className="relative">
|
||||
<div className="w-24 h-24 rounded-[1.5rem] overflow-hidden border-2 border-white/5 bg-slate-900 flex items-center justify-center transition-transform group-hover:scale-105 duration-500">
|
||||
{b.imageUrl ? (
|
||||
<img src={b.imageUrl} alt={b.name} className="w-full h-full object-cover" />
|
||||
) : (
|
||||
<Users size={32} className="text-slate-700" />
|
||||
)}
|
||||
</div>
|
||||
<Button variant="danger" size="sm" onClick={() => deleteBarber(shop.id, b.id)}>
|
||||
|
||||
{/* Botão de Upload Escondido */}
|
||||
<input
|
||||
type="file"
|
||||
id={`barber-img-${b.id}`}
|
||||
className="hidden"
|
||||
accept="image/*"
|
||||
onChange={(e) => handleBarberImageUpload(b.id, e)}
|
||||
/>
|
||||
<label
|
||||
htmlFor={`barber-img-${b.id}`}
|
||||
className="absolute inset-0 bg-black/40 text-white flex items-center justify-center rounded-[1.5rem] opacity-0 group-hover:opacity-100 cursor-pointer transition-opacity"
|
||||
>
|
||||
{uploadingBarberId === b.id ? <RefreshCw size={20} className="animate-spin" /> : <Plus size={20} />}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/* Info Profissional */}
|
||||
<div className="flex-1">
|
||||
<h3 className="text-xl font-bold text-white tracking-tight leading-tight">{b.name}</h3>
|
||||
{/* O utilizador pediu para ignorar observações/especialidades, removido para o look "mais limpo" do screenshot */}
|
||||
</div>
|
||||
|
||||
{/* Ações Rápidas */}
|
||||
<div className="flex flex-col gap-2 opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
<Button
|
||||
variant="danger"
|
||||
size="sm"
|
||||
className="rounded-xl h-10 w-10 p-0 flex items-center justify-center bg-transparent border-white/10 hover:bg-red-500/20"
|
||||
onClick={() => deleteBarber(shop.id, b.id)}
|
||||
>
|
||||
<Trash2 size={16} />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
{shop.barbers.length === 0 && (
|
||||
<div className="text-center py-12">
|
||||
<Users size={48} className="mx-auto text-slate-300 mb-3" />
|
||||
<p className="text-slate-600 font-medium">Nenhum barbeiro registado</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="border-t border-slate-200 pt-4">
|
||||
<h3 className="text-base font-semibold text-slate-900 mb-3">Adicionar novo barbeiro</h3>
|
||||
<div className="grid md:grid-cols-3 gap-3">
|
||||
|
||||
{shop.barbers.filter(b => b.name.toLowerCase().includes(barberSearchQuery.toLowerCase())).length === 0 && (
|
||||
<div className="col-span-full py-12 text-center bg-[#0d0d0d] border border-white/5 rounded-[2rem]">
|
||||
<Users size={48} className="mx-auto text-slate-800 mb-3" />
|
||||
<p className="text-slate-500 font-medium italic">Nenhum profissional encontrado com esse nome.</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Formulário de Adição (Mantido mas modernizado) */}
|
||||
<div className="pt-8 mt-4 border-t border-slate-200">
|
||||
<h3 className="text-base font-semibold text-slate-900 mb-4">Novo Profissional</h3>
|
||||
<div className="grid md:grid-cols-3 gap-3">
|
||||
<div className="md:col-span-2">
|
||||
<Input
|
||||
label="Nome"
|
||||
label="Nome do Profissional"
|
||||
placeholder="Ex: João Silva"
|
||||
value={barberName}
|
||||
onChange={(e) => setBarberName(e.target.value)}
|
||||
/>
|
||||
<Input
|
||||
label="Especialidades"
|
||||
placeholder="Fade, Navalha, Barba"
|
||||
value={barberSpecs}
|
||||
onChange={(e) => setBarberSpecs(e.target.value)}
|
||||
/>
|
||||
<div className="flex items-end">
|
||||
<Button onClick={addNewBarber} className="w-full">
|
||||
<PlusIcon size={16} className="mr-2" />
|
||||
Adicionar
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-end">
|
||||
<Button onClick={addNewBarber} className="w-full bg-indigo-600 hover:bg-indigo-700 h-11">
|
||||
<PlusIcon size={16} className="mr-2" />
|
||||
Adicionar
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user