import React, { useState, useEffect, useMemo } from "react"; import { UserRole, EventData, EventStatus, EventType, Professional } from "../types"; import { EventTable } from "../components/EventTable"; import { EventFiltersBar, EventFilters } from "../components/EventFiltersBar"; import { EventForm } from "../components/EventForm"; import { Button } from "../components/Button"; import { PlusCircle, Search, CheckCircle, Clock, Edit, Users, Map, Building2, Calendar, MapPin, X, UserCheck, UserX, } from "lucide-react"; import { useAuth } from "../contexts/AuthContext"; import { useData } from "../contexts/DataContext"; import { STATUS_COLORS } from "../constants"; interface DashboardProps { initialView?: "list" | "create"; } export const Dashboard: React.FC = ({ initialView = "list", }) => { const { user } = useAuth(); const { events, getEventsByRole, addEvent, updateEventStatus, assignPhotographer, professionals, getInstitutionById, getActiveCoursesByInstitutionId, respondToAssignment, } = useData(); const [view, setView] = useState<"list" | "create" | "edit" | "details">( initialView ); const [searchTerm, setSearchTerm] = useState(""); const [selectedEvent, setSelectedEvent] = useState(null); const [activeFilter, setActiveFilter] = useState("all"); const [advancedFilters, setAdvancedFilters] = useState({ date: "", fotId: "", type: "", }); const [isTeamModalOpen, setIsTeamModalOpen] = useState(false); // Reset view when initialView prop changes useEffect(() => { if (initialView) { setView(initialView); if (initialView === "create") setSelectedEvent(null); } }, [initialView]); // Guard Clause for basic security if (!user) return
Acesso Negado. Faça login.
; const myEvents = getEventsByRole(user.id, user.role); const currentProfessionalId = user.role === UserRole.PHOTOGRAPHER ? professionals.find((p) => p.usuarioId === user.id)?.id : undefined; // Extract unique values for filters const { availableTypes } = useMemo(() => { const types = [...new Set(myEvents.map((e) => e.type))].sort(); return { availableTypes: types, }; }, [myEvents]); // Filter Logic const filteredEvents = myEvents.filter((e) => { const matchesSearch = e.name .toLowerCase() .includes(searchTerm.toLowerCase()); const matchesStatus = activeFilter === "all" || (activeFilter === "pending" && e.status === EventStatus.PENDING_APPROVAL) || (activeFilter === "active" && e.status !== EventStatus.ARCHIVED && e.status !== EventStatus.PENDING_APPROVAL); // Advanced filters const matchesDate = !advancedFilters.date || e.date === advancedFilters.date; const matchesFot = !advancedFilters.fotId || String((e as any).fotId || "").includes(advancedFilters.fotId); const matchesType = !advancedFilters.type || e.type === advancedFilters.type; return ( matchesSearch && matchesStatus && matchesDate && matchesFot && matchesType ); }); const handleSaveEvent = (data: any) => { const isClient = user.role === UserRole.EVENT_OWNER; if (view === "edit" && selectedEvent) { const updatedEvent = { ...selectedEvent, ...data }; console.log("Updated", updatedEvent); setSelectedEvent(updatedEvent); setView("details"); } else { const initialStatus = isClient ? EventStatus.PENDING_APPROVAL : EventStatus.PLANNING; const newEvent: EventData = { ...data, id: Math.random().toString(36).substr(2, 9), status: initialStatus, checklist: [], ownerId: isClient ? user.id : "unknown", photographerIds: [], }; addEvent(newEvent); setView("list"); } }; // Keep selectedEvent in sync with global events state useEffect(() => { if (selectedEvent) { const updated = events.find((e) => e.id === selectedEvent.id); if (updated && updated !== selectedEvent) { setSelectedEvent(updated); } } }, [events, selectedEvent]); const handleApprove = (e: React.MouseEvent, eventId: string) => { e.stopPropagation(); updateEventStatus(eventId, EventStatus.CONFIRMED); }; const handleAssignmentResponse = async ( e: React.MouseEvent, eventId: string, status: string, reason?: string ) => { e.stopPropagation(); await respondToAssignment(eventId, status, reason); }; const handleOpenMaps = () => { if (!selectedEvent) return; if (selectedEvent.address.mapLink) { window.open(selectedEvent.address.mapLink, "_blank"); return; } const { street, number, city, state } = selectedEvent.address; const query = encodeURIComponent( `${street}, ${number}, ${city} - ${state}` ); window.open( `https://www.google.com/maps/search/?api=1&query=${query}`, "_blank" ); }; const handleManageTeam = () => { setIsTeamModalOpen(true); }; const togglePhotographer = (photographerId: string) => { if (!selectedEvent) return; assignPhotographer(selectedEvent.id, photographerId); }; // --- RENDERS PER ROLE --- const renderRoleSpecificHeader = () => { if (user.role === UserRole.EVENT_OWNER) { return (

Meus Eventos

Acompanhe seus eventos ou solicite novos orçamentos.

); } if (user.role === UserRole.PHOTOGRAPHER) { return (

Eventos Designados

Gerencie seus trabalhos e visualize detalhes.

); } return (

Gestão Geral

Controle total de eventos, aprovações e equipes.

); }; const renderRoleSpecificActions = () => { if (user.role === UserRole.PHOTOGRAPHER) return null; const label = user.role === UserRole.EVENT_OWNER ? "Solicitar Novo Evento" : "Novo Evento"; return ( ); }; // --- MAIN RENDER --- return (
{/* Header */} {view === "list" && (
{renderRoleSpecificHeader()} {renderRoleSpecificActions()}
)} {/* Content Switcher */} {view === "list" && (
{/* Search Bar */}
setSearchTerm(e.target.value)} />
{(user.role === UserRole.BUSINESS_OWNER || user.role === UserRole.SUPERADMIN) && (
)}
{/* Advanced Filters */} {/* Results Count */}
Exibindo{" "} {filteredEvents.length} {" "} de {myEvents.length} eventos
{/* Event Table */} { setSelectedEvent(event); setView("details"); }} onApprove={handleApprove} userRole={user.role} currentProfessionalId={currentProfessionalId} onAssignmentResponse={handleAssignmentResponse} />
)} {(view === "create" || view === "edit") && ( setView(view === "edit" ? "details" : "list")} onSubmit={handleSaveEvent} initialData={view === "edit" ? selectedEvent : undefined} /> )} {view === "details" && selectedEvent && (
{/* Status Banner */} {selectedEvent.status === EventStatus.PENDING_APPROVAL && user.role === UserRole.EVENT_OWNER && (

Solicitação em Análise

Seu evento foi enviado e está aguardando aprovação da equipe Photum.

)}
{/* Header Section - Sem foto */}

{selectedEvent.name}

{new Date( selectedEvent.date + "T00:00:00" ).toLocaleDateString("pt-BR")}{" "} às {selectedEvent.time} {selectedEvent.address.city},{" "} {selectedEvent.address.state}
{selectedEvent.status}
{/* Actions Toolbar */}
{(user.role === UserRole.BUSINESS_OWNER || user.role === UserRole.SUPERADMIN) && ( <> )} {user.role === UserRole.EVENT_OWNER && selectedEvent.status !== EventStatus.ARCHIVED && ( )}
{/* Quick Info Cards */}

Tipo

{selectedEvent.type}

Data

{new Date( selectedEvent.date + "T00:00:00" ).toLocaleDateString("pt-BR")}

Horário

{selectedEvent.time}

{/* FOT Information Table */}

Informações FOT

FOT {(selectedEvent as any).fot || "-"}
Data {new Date( selectedEvent.date + "T00:00:00" ).toLocaleDateString("pt-BR")}
Curso {selectedEvent.curso || "-"}
Instituição {selectedEvent.instituicao || "-"}
Ano Formatura {selectedEvent.anoFormatura || "-"}
Empresa {selectedEvent.empresa || "-"}
Tipo Evento {selectedEvent.type}
Observações {(selectedEvent as any).observacoes || "-"}
Local {selectedEvent.address.street},{" "} {selectedEvent.address.number}
Endereço {selectedEvent.address.city} -{" "} {selectedEvent.address.state} {selectedEvent.address.zip && ` | CEP: ${selectedEvent.address.zip}`}
Horário {selectedEvent.time}
Qtd Formandos {selectedEvent.attendees || "-"}
{/* Institution Information */} {selectedEvent.institutionId && (() => { const institution = getInstitutionById( selectedEvent.institutionId ); if (institution) { return (

{institution.name}

{institution.type}

{/* Course Information */} {selectedEvent.courseId && (() => { const course = getActiveCoursesByInstitutionId( selectedEvent.institutionId ).find( (c) => c.id === selectedEvent.courseId ); if (course) { return (

Curso/Turma

{course.name} -{" "} {course.graduationType} ( {course.year}/{course.semester}º sem)

); } return null; })()}

Contato

{institution.phone}

{institution.email}

{institution.address && (

Endereço

{institution.address.street},{" "} {institution.address.number}

{institution.address.city} -{" "} {institution.address.state}

)}
{institution.description && (

{institution.description}

)}
); } return null; })()}

Sobre o Evento

{selectedEvent.briefing || "Sem briefing detalhado."}

{selectedEvent.contacts.length > 0 && (

Contatos & Responsáveis

{selectedEvent.contacts.map((c, i) => (

{c.name}

{c.role}

{c.phone}

))}
)}
{/* Localização Card */}

Localização

{selectedEvent.address.street},{" "} {selectedEvent.address.number}

{selectedEvent.address.city} -{" "} {selectedEvent.address.state}

{selectedEvent.address.zip && (

CEP: {selectedEvent.address.zip}

)}
{/* Equipe Designada */} {(selectedEvent.photographerIds.length > 0 || user.role === UserRole.BUSINESS_OWNER || user.role === UserRole.SUPERADMIN) && (

Equipe ({selectedEvent.photographerIds.length})

{(user.role === UserRole.BUSINESS_OWNER || user.role === UserRole.SUPERADMIN) && ( )}
{selectedEvent.photographerIds.length > 0 ? (
{selectedEvent.photographerIds.map((id) => { const photographer = professionals.find( (p) => p.id === id ); return (
{photographer?.name || id}
); })}
) : (

Nenhum profissional atribuído

)}
)}
)} {/* Modal de Gerenciamento de Equipe */} {isTeamModalOpen && selectedEvent && (
{/* Header */}

Gerenciar Equipe

{selectedEvent.name} -{" "} {new Date( selectedEvent.date + "T00:00:00" ).toLocaleDateString("pt-BR")}

{/* Body */}

Profissionais disponíveis para a data{" "} {new Date( selectedEvent.date + "T00:00:00" ).toLocaleDateString("pt-BR")} . Clique em "Adicionar" para atribuir ao evento.

{/* Tabela de Profissionais */}
{professionals.map((photographer) => { const isAssigned = selectedEvent.photographerIds.includes( photographer.id ); const isAvailable = true; return ( {/* Profissional */} {/* Função */} {/* E-mail */} {/* Status */} {/* Ação */} ); })} {professionals.length === 0 && ( )}
Profissional Função E-mail Status Ação

{photographer.name}

ID: {photographer.id}

{photographer.role} {photographer.email} {isAssigned ? ( Atribuído ) : ( Disponível )}

Nenhum profissional disponível para esta data

Tente selecionar outra data ou entre em contato com a equipe

{/* Footer */}
)}
); };