import React, { useState, useEffect } from "react"; import { Users, Plus, Search, Filter, Trash2, Edit2, Star, Camera, Video, UserCheck, } from "lucide-react"; import { Button } from "../components/Button"; import { getFunctions, getProfessionals, deleteProfessional, } from "../services/apiService"; import { useAuth } from "../contexts/AuthContext"; import { Professional } from "../types"; import { ProfessionalDetailsModal } from "../components/ProfessionalDetailsModal"; import { ProfessionalModal } from "../components/ProfessionalModal"; export const TeamPage: React.FC = () => { const { token: contextToken } = useAuth(); const token = contextToken || ""; // Lists const [professionals, setProfessionals] = useState([]); const [roles, setRoles] = useState<{ id: string; nome: string }[]>([]); // Loading States const [isLoading, setIsLoading] = useState(true); // Filters const [searchTerm, setSearchTerm] = useState(""); const [roleFilter, setRoleFilter] = useState("all"); const [ratingFilter, setRatingFilter] = useState("all"); // Selection & Modals const [selectedProfessional, setSelectedProfessional] = useState(null); const [showModal, setShowModal] = useState(false); const [showDeleteModal, setShowDeleteModal] = useState(false); const [professionalToDelete, setProfessionalToDelete] = useState(null); const [viewProfessional, setViewProfessional] = useState(null); // Helper renderers const getRoleName = (id: string) => { return roles.find((r) => r.id === id)?.nome || "Desconhecido"; }; const getRoleIcon = (roleName: string) => { const lower = roleName.toLowerCase(); if (lower.includes("foto")) return Camera; if (lower.includes("video") || lower.includes("cine")) return Video; return UserCheck; }; const GenericAvatar = "https://ui-avatars.com/api/?background=random"; // Fetch Data useEffect(() => { fetchData(); }, [token]); const fetchData = async () => { setIsLoading(true); try { const [rolesData, prosData] = await Promise.all([ getFunctions(), getProfessionals(token), ]); if (rolesData.data) setRoles(rolesData.data); if (prosData.data) { setProfessionals(prosData.data); } } catch (error) { console.error("Error fetching data:", error); } finally { setIsLoading(false); } }; const handleDelete = async () => { if (!professionalToDelete) return; try { await deleteProfessional(professionalToDelete.id, token); setShowDeleteModal(false); setProfessionalToDelete(null); fetchData(); } catch (error) { console.error("Error deleting professional:", error); alert("Erro ao excluir profissional."); } }; const handleEditClick = (professional: Professional) => { setSelectedProfessional(professional); setShowModal(true); }; const handleViewClick = (professional: Professional) => { setViewProfessional(professional); }; // Optimized Filter const filteredProfessionals = React.useMemo(() => { return professionals.filter((p) => { const matchesSearch = p.nome.toLowerCase().includes(searchTerm.toLowerCase()) || (p.email && p.email.toLowerCase().includes(searchTerm.toLowerCase())); const roleName = getRoleName(p.funcao_profissional_id); const matchesRole = roleFilter === "all" || roleName === roleFilter; const matchesRating = (() => { if (ratingFilter === "all") return true; const rating = p.media || 0; switch (ratingFilter) { case "5": return rating >= 4.5; case "4": return rating >= 4 && rating < 4.5; case "3": return rating >= 3 && rating < 4; case "2": return rating >= 2 && rating < 3; case "1": return rating >= 1 && rating < 2; case "0": return rating < 1; default: return true; } })(); // if (roleName === "Desconhecido") return false; return matchesSearch && matchesRole && matchesRating; }); }, [professionals, searchTerm, roleFilter, ratingFilter, roles]); return (
{/* Header */}

Equipe

Gerencie sua equipe de profissionais

{/* Stats */}

Total de Profissionais

{professionals.length}

{roles.map(role => { const count = professionals.filter(p => p.funcao_profissional_id === role.id).length; const RoleIcon = getRoleIcon(role.nome); let iconColorClass = "text-brand-black"; if (role.nome.toLowerCase().includes("foto")) iconColorClass = "text-brand-gold"; else if (role.nome.toLowerCase().includes("video") || role.nome.toLowerCase().includes("cine")) iconColorClass = "text-blue-600"; else if (role.nome.toLowerCase().includes("recep")) iconColorClass = "text-purple-600"; return (

Total de {role.nome}s

{count}

); })}
{/* Filters and Search */}
setSearchTerm(e.target.value)} className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-brand-gold" />
Filtros:
{/* List */} {isLoading ? (
Carregando...
) : (
{filteredProfessionals.length === 0 ? (
Nenhum profissional encontrado.
) : ( {filteredProfessionals.map((p) => { return ( handleViewClick(p)}> ); })}
Profissional Função Contato Ações
{p.nome}
{p.nome}
{p.media ? p.media.toFixed(1) : "N/A"}
{p.functions && p.functions.length > 0 ? p.functions.map(f => f.nome).join(", ") : getRoleName(p.funcao_profissional_id)}
{p.whatsapp}
{p.email}
)}
)}
{/* Modals */} { setShowModal(false); setSelectedProfessional(null); }} professional={selectedProfessional} existingProfessionals={professionals} onSwitchToEdit={(prof) => { setSelectedProfessional(prof); // Modal automatically updates because 'professional' prop changes }} roles={roles} onSuccess={() => { fetchData(); }} /> {viewProfessional && ( setViewProfessional(null)} /> )} {showDeleteModal && (

Confirmar Exclusão

Tem certeza que deseja excluir o profissional {professionalToDelete?.nome}? Esta ação não pode ser desfeita.

)}
); };