import React, { useEffect, useState, useMemo } from 'react'; import { useParams, Link } from 'react-router-dom'; import { getAttendances, getUserById } from '../services/dataService'; import { Attendance, User, FunnelStage } from '../types'; import { ArrowLeft, Mail, Phone, Clock, MessageSquare, ChevronLeft, ChevronRight, Eye } from 'lucide-react'; const ITEMS_PER_PAGE = 10; export const UserDetail: React.FC = () => { const { id } = useParams<{ id: string }>(); const [user, setUser] = useState(); const [attendances, setAttendances] = useState([]); const [loading, setLoading] = useState(true); const [currentPage, setCurrentPage] = useState(1); useEffect(() => { if (id) { setLoading(true); const loadData = async () => { try { const tenantId = localStorage.getItem('ctms_tenant_id'); const u = await getUserById(id); setUser(u); if (u && tenantId) { const data = await getAttendances(tenantId, { userId: id, dateRange: { start: new Date(0), end: new Date() } // All time }); setAttendances(data); } } catch (error) { console.error("Error loading user details", error); } finally { setLoading(false); } }; loadData(); } }, [id]); const totalPages = Math.ceil(attendances.length / ITEMS_PER_PAGE); const currentData = useMemo(() => { const start = (currentPage - 1) * ITEMS_PER_PAGE; return attendances.slice(start, start + ITEMS_PER_PAGE); }, [attendances, currentPage]); const handlePageChange = (newPage: number) => { if (newPage >= 1 && newPage <= totalPages) { setCurrentPage(newPage); } }; const getStageBadgeColor = (stage: FunnelStage) => { switch (stage) { case FunnelStage.WON: return 'bg-green-100 text-green-700 border-green-200'; case FunnelStage.LOST: return 'bg-red-100 text-red-700 border-red-200'; case FunnelStage.NEGOTIATION: return 'bg-blue-100 text-blue-700 border-blue-200'; case FunnelStage.IDENTIFICATION: return 'bg-yellow-100 text-yellow-700 border-yellow-200'; default: return 'bg-slate-100 text-slate-700 border-slate-200'; } }; const getScoreColor = (score: number) => { if (score >= 80) return 'text-green-600 bg-green-50'; if (score >= 60) return 'text-yellow-600 bg-yellow-50'; return 'text-red-600 bg-red-50'; }; if (!loading && !user) return
Usuário não encontrado
; return (
{/* Header Section */}
{user && (
{user.name}

{user.name}

{user.email} {user.role}
)}
{/* KPI Cards */}
Total de Interações
{attendances.length}
Taxa de Conversão
{attendances.length ? ((attendances.filter(a => a.converted).length / attendances.length) * 100).toFixed(1) : 0}%
Nota Média
{attendances.length ? (attendances.reduce((acc, c) => acc + c.score, 0) / attendances.length).toFixed(1) : 0}
{/* Attendance Table */}

Histórico de Atendimentos

Página {currentPage} de {totalPages || 1}
{loading ? (
Carregando registros...
) : (
{currentData.map(att => ( ))}
Data / Hora Resumo Etapa Nota T. Resp. Ação
{new Date(att.created_at).toLocaleDateString()}
{new Date(att.created_at).toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}
{att.summary}
{att.origin}
{att.funnel_stage} {att.score}
{att.first_response_time_min}m
)} {/* Pagination Footer */} {totalPages > 1 && (
Mostrando {((currentPage - 1) * ITEMS_PER_PAGE) + 1} a {Math.min(currentPage * ITEMS_PER_PAGE, attendances.length)} de {attendances.length}
)}
); };