photum/frontend/components/EventTable.tsx
2025-12-05 10:43:48 -03:00

174 lines
7.3 KiB
TypeScript

import React from 'react';
import { EventData, EventStatus, UserRole } from '../types';
import { Calendar, MapPin, Users, CheckCircle, Clock } from 'lucide-react';
import { STATUS_COLORS } from '../constants';
interface EventTableProps {
events: EventData[];
onEventClick: (event: EventData) => void;
onApprove?: (e: React.MouseEvent, eventId: string) => void;
userRole: UserRole;
}
export const EventTable: React.FC<EventTableProps> = ({
events,
onEventClick,
onApprove,
userRole
}) => {
const canApprove = (userRole === UserRole.BUSINESS_OWNER || userRole === UserRole.SUPERADMIN);
const formatDate = (date: string) => {
const eventDate = new Date(date + 'T00:00:00');
return eventDate.toLocaleDateString('pt-BR', {
day: '2-digit',
month: '2-digit',
year: 'numeric'
});
};
const getStatusDisplay = (status: EventStatus) => {
const statusLabels: Record<EventStatus, string> = {
[EventStatus.PENDING_APPROVAL]: 'Pendente',
[EventStatus.CONFIRMED]: 'Confirmado',
[EventStatus.PLANNING]: 'Planejamento',
[EventStatus.IN_PROGRESS]: 'Em Andamento',
[EventStatus.COMPLETED]: 'Concluído',
[EventStatus.ARCHIVED]: 'Arquivado',
};
return statusLabels[status] || status;
};
return (
<div className="bg-white rounded-lg border border-gray-200 overflow-hidden shadow-sm">
<div className="overflow-x-auto">
<table className="w-full">
<thead className="bg-gray-50 border-b border-gray-200">
<tr>
{canApprove && (
<th className="px-4 py-3 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider w-20">
Ações
</th>
)}
<th className="px-4 py-3 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">
Nome do Evento
</th>
<th className="px-4 py-3 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">
Tipo
</th>
<th className="px-4 py-3 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">
Data
</th>
<th className="px-4 py-3 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">
Horário
</th>
<th className="px-4 py-3 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">
Local
</th>
<th className="px-4 py-3 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">
Contatos
</th>
<th className="px-4 py-3 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">
Equipe
</th>
<th className="px-4 py-3 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider">
Status
</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-100">
{events.map((event) => (
<tr
key={event.id}
onClick={() => onEventClick(event)}
className="hover:bg-gray-50 cursor-pointer transition-colors"
>
{canApprove && (
<td className="px-4 py-3" onClick={(e) => e.stopPropagation()}>
{event.status === EventStatus.PENDING_APPROVAL && (
<button
onClick={(e) => onApprove?.(e, event.id)}
className="bg-green-500 text-white px-2 py-1 rounded text-xs font-semibold hover:bg-green-600 transition-colors flex items-center gap-1 whitespace-nowrap"
title="Aprovar evento"
>
<CheckCircle size={12} />
Aprovar
</button>
)}
</td>
)}
<td className="px-4 py-3">
<div className="font-medium text-gray-900 text-sm">{event.name}</div>
</td>
<td className="px-4 py-3">
<span className="text-xs text-gray-600 uppercase tracking-wide">{event.type}</span>
</td>
<td className="px-4 py-3">
<div className="flex items-center text-sm text-gray-700">
<Calendar size={14} className="mr-1.5 text-brand-gold flex-shrink-0" />
{formatDate(event.date)}
</div>
</td>
<td className="px-4 py-3">
<div className="flex items-center text-sm text-gray-700">
<Clock size={14} className="mr-1.5 text-gray-400 flex-shrink-0" />
{event.time}
</div>
</td>
<td className="px-4 py-3">
<div className="flex items-center text-sm text-gray-700">
<MapPin size={14} className="mr-1.5 text-brand-gold flex-shrink-0" />
<span className="truncate max-w-[200px]" title={`${event.address.street}, ${event.address.number} - ${event.address.city}/${event.address.state}`}>
{event.address.city}, {event.address.state}
</span>
</div>
</td>
<td className="px-4 py-3">
<div className="flex items-center text-sm text-gray-700">
<Users size={14} className="mr-1.5 text-gray-400 flex-shrink-0" />
{event.contacts.length}
</div>
</td>
<td className="px-4 py-3">
{event.photographerIds.length > 0 ? (
<div className="flex -space-x-1">
{event.photographerIds.slice(0, 3).map((id, idx) => (
<div
key={id}
className="w-6 h-6 rounded-full border-2 border-white bg-gray-300"
style={{
backgroundImage: `url(https://i.pravatar.cc/100?u=${id})`,
backgroundSize: 'cover',
}}
title={id}
/>
))}
{event.photographerIds.length > 3 && (
<div className="w-6 h-6 rounded-full border-2 border-white bg-gray-100 flex items-center justify-center text-[10px] text-gray-600 font-medium">
+{event.photographerIds.length - 3}
</div>
)}
</div>
) : (
<span className="text-xs text-gray-400">-</span>
)}
</td>
<td className="px-4 py-3">
<span className={`inline-flex items-center px-2 py-1 rounded text-xs font-semibold ${STATUS_COLORS[event.status]}`}>
{getStatusDisplay(event.status)}
</span>
</td>
</tr>
))}
</tbody>
</table>
</div>
{events.length === 0 && (
<div className="text-center py-12 text-gray-500">
<p>Nenhum evento encontrado.</p>
</div>
)}
</div>
);
};