photum/frontend/pages/EventDetails.tsx
NANDO9322 943b4f6506 feat(financeiro): implementação do extrato financeiro do profissional e melhorias na agenda
- Backend:
  - Adicionado endpoint para extrato financeiro do profissional (/meus-pagamentos).
  - Atualizada query SQL para incluir nome da empresa e curso nos detalhes da transação.
  - Adicionado retorno de valores (Free, Extra, Descrição) na API.

- Frontend:
  - Nova página "Meus Pagamentos" com modal de detalhes da transação.
  - Removido componente antigo PhotographerFinance.
  - Ajustado filtro de motoristas na Logística para exibir apenas profissionais atribuídos e com carro.
  - Corrigida exibição da função do profissional na Escala (mostra a função atribuída no evento, ex: Cinegrafista).
  - Melhoria no botão de voltar na tela de detalhes do evento.
2026-01-16 16:07:49 -03:00

147 lines
8.3 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { ArrowLeft, MapPin, Calendar, Clock, DollarSign } from 'lucide-react';
import { useAuth } from '../contexts/AuthContext';
import { useData } from '../contexts/DataContext';
import { getAgendas } from '../services/apiService';
import EventScheduler from '../components/EventScheduler';
import EventLogistics from '../components/EventLogistics';
const EventDetails: React.FC = () => {
const { id } = useParams<{ id: string }>();
const navigate = useNavigate();
const { events, loading } = useData();
const [calculatedStats, setCalculatedStats] = useState({ studios: 0 });
const event = events.find(e => e.id === id);
// No local loading state needed if events are loaded globally, or check if events.length === 0 && loading
if (!event) return <div className="p-8 text-center text-red-500">Evento não encontrado ou carregando...</div>;
if (!event) return <div className="p-8 text-center text-red-500">Evento não encontrado.</div>;
// Use event.date which is already YYYY-MM-DD from DataContext
const formattedDate = new Date(event.date + "T00:00:00").toLocaleDateString();
return (
<div className="min-h-screen bg-gray-50 p-6">
<div className="max-w-7xl mx-auto space-y-6">
{/* Header */}
<div className="flex items-center gap-4">
<button onClick={() => navigate('/eventos')} className="flex items-center gap-2 px-3 py-2 hover:bg-gray-200 rounded-lg transition-colors text-gray-600">
<ArrowLeft className="w-5 h-5" />
<span className="font-medium">Voltar</span>
</button>
<div className="w-px h-8 bg-gray-300 mx-2 hidden sm:block"></div>
<div>
<h1 className="text-2xl font-bold text-gray-800 flex items-center gap-2">
{event.empresa_nome} - {event.tipo_evento_nome}
<span className={`text-xs px-2 py-1 rounded-full ${event.status === 'Confirmado' ? 'bg-green-100 text-green-800' : 'bg-yellow-100 text-yellow-800'}`}>
{event.status}
</span>
</h1>
<p className="text-sm text-gray-500">ID: {event.fot_id}</p>
</div>
</div>
{/* Event Info Card (Spreadsheet Header Style) */}
<div className="bg-white rounded-lg shadow p-4 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 border-l-4 border-brand-purple">
<div className="flex items-start gap-3">
<Calendar className="w-5 h-5 text-brand-purple mt-1" />
<div>
<p className="text-xs text-gray-500 uppercase font-bold">Data</p>
<p className="font-medium text-gray-800">{formattedDate}</p>
</div>
</div>
<div className="flex items-start gap-3">
<MapPin className="w-5 h-5 text-brand-purple mt-1" />
<div>
<p className="text-xs text-gray-500 uppercase font-bold">Local:</p>
{(() => {
const localVal = event['local_evento'] || event.local || event.local_evento;
const isUrl = localVal && String(localVal).startsWith('http');
if (isUrl) {
return (
<a
href={localVal}
target="_blank"
rel="noopener noreferrer"
className="font-medium text-brand-purple hover:underline truncate block"
title="Abrir no Mapa"
>
{event.locationName || "Ver Localização no Mapa"}
</a>
);
}
return <p className="font-medium text-gray-800">{localVal || "Não informado"}</p>;
})()}
<p className="text-xs text-gray-500">{event.endereco}</p>
</div>
</div>
<div className="flex items-start gap-3">
<Clock className="w-5 h-5 text-brand-purple mt-1" />
<div>
<p className="text-xs text-gray-500 uppercase font-bold">Horário</p>
<p className="font-medium text-gray-800">{event.horario || event.time || "Não definido"}</p>
</div>
</div>
<div className="flex items-start gap-3">
<div className="w-5 h-5 text-brand-purple mt-1 font-bold text-xs border border-brand-purple rounded flex items-center justify-center">?</div>
<div>
<p className="text-xs text-gray-500 uppercase font-bold">Observações</p>
<p className="text-xs text-gray-600 line-clamp-2">{event.observacoes_evento || "Nenhuma observação."}</p>
</div>
</div>
</div>
{/* Main Content: Scheduling & Logistics */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<EventScheduler
agendaId={id!}
dataEvento={event.date}
allowedProfessionals={event.assignments}
onUpdateStats={setCalculatedStats}
defaultTime={event.time}
/>
{/* Right: Logistics (Carros) */}
<div className="space-y-6">
<EventLogistics
agendaId={id!}
assignedProfessionals={event.assignments?.map((a: any) => a.professionalId)}
/>
{/* Equipment / Studios Section (Placeholder for now based on spreadsheet) */}
<div className="bg-white p-4 rounded-lg shadow">
<h3 className="text-lg font-semibold text-gray-800 mb-2 flex items-center">
<DollarSign className="w-5 h-5 mr-2 text-green-600" /> {/* Using DollarSign as generic icon for assets/inventory for now, map to Camera later */}
Equipamentos & Estúdios
</h3>
<div className="bg-gray-50 p-3 rounded text-sm space-y-2">
<div className="flex justify-between border-b pb-2">
<span className="text-gray-600">Qtd. Estúdios (Automático):</span>
<span className="font-bold text-indigo-600">{calculatedStats.studios}</span>
</div>
<div className="flex justify-between border-b pb-2">
<span className="text-gray-600">Ponto de Foto:</span>
<span className="font-bold">{event.qtd_ponto_foto || 0}</span>
</div>
<div className="mt-2">
<p className="text-xs text-gray-500 font-bold mb-1">Notas de Equipamento:</p>
<textarea
className="w-full text-xs p-2 rounded border bg-white"
placeholder="Ex: Levar 2 tripés extras..."
rows={3}
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
export default EventDetails;