feat(salas): melhora visual e distribuição de Minhas Salas / Alugar / Marketplace
- Abas viram segmented control: no mobile ocupam a largura toda e distribuem igual; no desktop encolhem ao conteúdo (some quando há só 1 aba). - "Cadastrar Sala" ganha toolbar (contagem à esquerda, botão à direita no desktop, largura cheia no mobile) em vez de botão solto. - Filtros do marketplace: grid 2/3/6 colunas (distribui uniforme) e BUSCAR full-width no mobile. - Cards de sala: 3 colunas em telas largas (xl). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -641,23 +641,26 @@ export const SalasPlugin: React.FC<{ view?: 'minhas' | 'alugar' }> = ({ view })
|
||||
: 'Alugue salas equipadas ou disponibilize as suas para outros profissionais.'}
|
||||
/>
|
||||
|
||||
{/* Tabs */}
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
{TABS.map(t => {
|
||||
const Icon = t.icon;
|
||||
const active = tab === t.id;
|
||||
return (
|
||||
<button key={t.id} onClick={() => setTab(t.id)}
|
||||
className={`flex items-center gap-2 px-5 py-2.5 rounded-xl text-[11px] font-black uppercase tracking-wider transition-all ${active ? 'text-white shadow-md' : 'bg-white text-gray-500 border border-gray-200 hover:bg-gray-50'}`}
|
||||
style={active ? { backgroundColor: COLOR } : {}}>
|
||||
<Icon size={14} /> {t.label}
|
||||
{t.id === 'reservas' && pendentesRecebidas > 0 && (
|
||||
<span className={`text-[9px] font-black px-1.5 py-0.5 rounded-full ${active ? 'bg-white/25' : 'bg-amber-100 text-amber-700'}`}>{pendentesRecebidas}</span>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
{/* Tabs — segmented control: no mobile ocupa a largura toda e distribui igual;
|
||||
no desktop encolhe ao conteúdo. */}
|
||||
{TABS.length > 1 && (
|
||||
<div className="flex gap-1 bg-gray-100/80 p-1 rounded-2xl w-full sm:w-fit">
|
||||
{TABS.map(t => {
|
||||
const Icon = t.icon;
|
||||
const active = tab === t.id;
|
||||
return (
|
||||
<button key={t.id} onClick={() => setTab(t.id)}
|
||||
className={`flex-1 sm:flex-none flex items-center justify-center gap-2 px-3 sm:px-5 py-2.5 rounded-xl text-[11px] font-black uppercase tracking-wider transition-all ${active ? 'bg-white shadow-sm' : 'text-gray-500 hover:text-gray-700'}`}
|
||||
style={active ? { color: COLOR } : {}}>
|
||||
<Icon size={14} className="shrink-0" /> <span className="truncate">{t.label}</span>
|
||||
{t.id === 'reservas' && pendentesRecebidas > 0 && (
|
||||
<span className="text-[9px] font-black px-1.5 py-0.5 rounded-full text-white" style={{ backgroundColor: COLOR }}>{pendentesRecebidas}</span>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* MARKETPLACE */}
|
||||
{tab === 'marketplace' && enderecoOk === false && (
|
||||
@@ -666,7 +669,7 @@ export const SalasPlugin: React.FC<{ view?: 'minhas' | 'alugar' }> = ({ view })
|
||||
{tab === 'marketplace' && enderecoOk !== false && (
|
||||
<>
|
||||
<div className="bg-white rounded-2xl border border-gray-100 shadow-sm p-5">
|
||||
<div className="grid grid-cols-2 md:grid-cols-5 gap-3 mb-4">
|
||||
<div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-3 mb-4">
|
||||
<div>
|
||||
<label className={labelCls}>Área</label>
|
||||
<select className={inputCls} value={fArea} onChange={e => setFArea(e.target.value)}>
|
||||
@@ -703,7 +706,7 @@ export const SalasPlugin: React.FC<{ view?: 'minhas' | 'alugar' }> = ({ view })
|
||||
</div>
|
||||
</div>
|
||||
<button onClick={fetchMarketplace} disabled={loading}
|
||||
className="flex items-center gap-2 px-5 py-2.5 text-white rounded-xl text-xs font-black uppercase tracking-widest transition-colors disabled:opacity-60 hover:opacity-90" style={{ backgroundColor: COLOR }}>
|
||||
className="w-full sm:w-auto flex items-center justify-center gap-2 px-6 py-2.5 text-white rounded-xl text-xs font-black uppercase tracking-widest transition-opacity disabled:opacity-60 hover:opacity-90 shadow-sm" style={{ backgroundColor: COLOR }}>
|
||||
{loading ? <RefreshCw size={14} className="animate-spin" /> : <Search size={14} />} BUSCAR
|
||||
</button>
|
||||
</div>
|
||||
@@ -716,7 +719,7 @@ export const SalasPlugin: React.FC<{ view?: 'minhas' | 'alugar' }> = ({ view })
|
||||
<p className="text-xs mt-1">Ajuste os filtros ou aguarde novos anúncios</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
|
||||
{salas.map(s => <SalaCard key={s.id} sala={s} onReserve={() => setReservingSala(s)} />)}
|
||||
</div>
|
||||
)}
|
||||
@@ -726,10 +729,15 @@ export const SalasPlugin: React.FC<{ view?: 'minhas' | 'alugar' }> = ({ view })
|
||||
{/* MINHAS SALAS */}
|
||||
{tab === 'minhas' && (
|
||||
<>
|
||||
<button onClick={() => setEditingSala('new')}
|
||||
className="flex items-center gap-2 px-5 py-2.5 text-white rounded-xl text-xs font-black uppercase tracking-widest transition-colors hover:opacity-90" style={{ backgroundColor: COLOR }}>
|
||||
<Plus size={14} /> CADASTRAR SALA
|
||||
</button>
|
||||
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
|
||||
<h3 className="text-sm font-black text-gray-800 uppercase tracking-tight">
|
||||
{minhas.length > 0 ? `${minhas.length} sala${minhas.length > 1 ? 's' : ''} cadastrada${minhas.length > 1 ? 's' : ''}` : 'Suas salas'}
|
||||
</h3>
|
||||
<button onClick={() => setEditingSala('new')}
|
||||
className="w-full sm:w-auto flex items-center justify-center gap-2 px-5 py-2.5 text-white rounded-xl text-xs font-black uppercase tracking-widest transition-opacity hover:opacity-90 shadow-sm" style={{ backgroundColor: COLOR }}>
|
||||
<Plus size={16} /> CADASTRAR SALA
|
||||
</button>
|
||||
</div>
|
||||
{loading ? (
|
||||
<div className="flex justify-center py-12"><RefreshCw size={24} className="animate-spin" style={{ color: COLOR }} /></div>
|
||||
) : minhas.length === 0 ? (
|
||||
@@ -739,7 +747,7 @@ export const SalasPlugin: React.FC<{ view?: 'minhas' | 'alugar' }> = ({ view })
|
||||
<p className="text-xs mt-1">Disponibilize uma sala e receba solicitações de reserva</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
|
||||
{minhas.map(s => <SalaCard key={s.id} sala={s} mine onEdit={() => setEditingSala(s)} onDelete={() => handleDelete(s)} />)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user