sass-imobiliaria/frontend/src/pages/admin/AdminFavoritosPage.tsx

108 lines
5.4 KiB
TypeScript

import { useEffect, useState } from 'react';
import api from '../../services/api';
interface Favorito {
id: string;
user_id: string;
property_id?: string;
created_at: string;
user_name?: string;
property_title?: string;
}
export default function AdminFavoritosPage() {
const [favoritos, setFavoritos] = useState<Favorito[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [removing, setRemoving] = useState<Favorito | null>(null);
const [actionLoading, setActionLoading] = useState(false);
function fetchFavoritos() {
setLoading(true);
api.get('/admin/favoritos')
.then(res => setFavoritos(res.data))
.catch(() => setError('Erro ao carregar favoritos'))
.finally(() => setLoading(false));
}
useEffect(() => { fetchFavoritos(); }, []);
function handleRemove() {
if (!removing) return;
setActionLoading(true);
api.delete(`/admin/favoritos/${removing.id}`)
.then(() => { setRemoving(null); fetchFavoritos(); })
.catch(() => setError('Erro ao remover favorito'))
.finally(() => setActionLoading(false));
}
return (
<div className="p-6 md:p-8">
<div className="flex items-center justify-between mb-6">
<h2 className="text-xl font-bold text-textPrimary">Favoritos</h2>
</div>
{loading && <div className="text-textSecondary text-sm">Carregando...</div>}
{error && <div className="text-red-400 text-sm">{error}</div>}
<div className="overflow-x-auto rounded-xl border border-borderPrimary">
<table className="min-w-full bg-panel text-sm">
<thead>
<tr className="text-left text-textSecondary border-b border-borderSubtle">
<th className="py-3 px-4 font-medium">Cliente</th>
<th className="py-3 px-4 font-medium hidden sm:table-cell">Imóvel</th>
<th className="py-3 px-4 font-medium hidden md:table-cell">Adicionado em</th>
<th className="py-3 px-4 font-medium">Ações</th>
</tr>
</thead>
<tbody>
{favoritos.length === 0 && !loading && (
<tr>
<td colSpan={4} className="py-8 text-center text-textTertiary">
Nenhum favorito encontrado.
</td>
</tr>
)}
{favoritos.map(f => (
<tr key={f.id} className="border-t border-borderSubtle text-textPrimary hover:bg-surface/50 transition-colors">
<td className="py-3 px-4">{f.user_name || f.user_id || '—'}</td>
<td className="py-3 px-4 hidden sm:table-cell text-textSecondary">{f.property_title || '—'}</td>
<td className="py-3 px-4 hidden md:table-cell text-textSecondary">{f.created_at.slice(0, 10)}</td>
<td className="py-3 px-4">
<button
className="text-red-400 hover:text-red-300 text-xs font-medium transition-colors"
onClick={() => setRemoving(f)}
>Remover</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
{/* Modal remoção */}
{removing && (
<div className="fixed inset-0 bg-black/70 flex items-center justify-center z-50 p-4">
<div className="bg-panel border border-borderPrimary rounded-xl shadow-lg p-6 w-full max-w-md">
<h3 className="text-textPrimary font-semibold mb-2">Remover favorito</h3>
<p className="text-textSecondary text-sm mb-4">
Tem certeza que deseja remover o favorito de{' '}
<span className="text-textPrimary font-medium">{removing.user_name || removing.user_id}</span>
{' '}para o imóvel{' '}
<span className="text-textPrimary font-medium">{removing.property_title || '—'}</span>?
</p>
<div className="flex gap-2 justify-end">
<button
className="px-4 py-2 rounded border border-borderPrimary text-textSecondary hover:text-textPrimary hover:border-borderSecondary text-sm transition-colors"
onClick={() => setRemoving(null)}
>Cancelar</button>
<button
className="px-4 py-2 rounded bg-red-600 hover:bg-red-500 text-white text-sm font-medium transition-colors disabled:opacity-50"
onClick={handleRemove}
disabled={actionLoading}
>Remover</button>
</div>
</div>
</div>
)}
</div>
);
}