import { useState } from "react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { Link } from "wouter"; import { BrowserFrame } from "@/components/Browser/BrowserFrame"; import { Users, Building2, TrendingUp, MessageSquare, Ticket, Zap, LayoutGrid, ChevronRight, PlusCircle, Filter, Search, Bell, Calendar, Target, BarChart3, DollarSign, Clock, AlertCircle, Phone, Mail, ArrowUpRight, Activity, Hash, Shield } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Badge } from "@/components/ui/badge"; import { Avatar, AvatarFallback } from "@/components/ui/avatar"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; interface XosStats { total_contacts: number; total_leads: number; total_customers: number; total_companies: number; open_deals: number; won_deals: number; pipeline_value: number; won_value: number; open_conversations: number; open_tickets: number; overdue_activities: number; } interface Contact { id: number; name: string; email: string; phone: string; company: string; position: string; type: string; lead_status: string; source: string; created_at: string; } interface Deal { id: number; title: string; value: number; status: string; stage_name: string; stage_color: string; contact_name: string; company_name: string; created_at: string; } interface Activity { id: number; type: string; title: string; status: string; priority: string; due_at: string; contact_name: string; deal_title: string; } export default function XosCentral() { const [activeTab, setActiveTab] = useState("dashboard"); const [isNewContactOpen, setIsNewContactOpen] = useState(false); const [isNewActivityOpen, setIsNewActivityOpen] = useState(false); const [newContact, setNewContact] = useState({ name: "", email: "", phone: "", company: "", position: "" }); const [newActivity, setNewActivity] = useState({ type: "task", title: "", due_at: "", priority: "medium" }); const queryClient = useQueryClient(); const createContactMutation = useMutation({ mutationFn: async (data: typeof newContact) => { const res = await fetch("/api/xos/contacts", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data), }); if (!res.ok) throw new Error("Erro ao criar contato"); return res.json(); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["/api/xos/contacts"] }); queryClient.invalidateQueries({ queryKey: ["/api/xos/stats"] }); setIsNewContactOpen(false); setNewContact({ name: "", email: "", phone: "", company: "", position: "" }); }, }); const createActivityMutation = useMutation({ mutationFn: async (data: typeof newActivity) => { const res = await fetch("/api/xos/activities", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data), }); if (!res.ok) throw new Error("Erro ao criar atividade"); return res.json(); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["/api/xos/activities"] }); queryClient.invalidateQueries({ queryKey: ["/api/xos/stats"] }); setIsNewActivityOpen(false); setNewActivity({ type: "task", title: "", due_at: "", priority: "medium" }); }, }); const { data: stats } = useQuery({ queryKey: ["/api/xos/stats"], }); const { data: contacts = [] } = useQuery({ queryKey: ["/api/xos/contacts"], }); const { data: deals = [] } = useQuery({ queryKey: ["/api/xos/deals"], }); const { data: activities = [] } = useQuery({ queryKey: ["/api/xos/activities"], }); const formatCurrency = (value: number) => { return new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL", }).format(value || 0); }; const modules = [ { id: "crm", name: "CRM", icon: Users, href: "/xos/crm", color: "bg-blue-100 text-blue-600", description: "Gestão de leads e clientes" }, { id: "inbox", name: "Inbox", icon: MessageSquare, href: "/xos/inbox", color: "bg-green-100 text-green-600", description: "Central de atendimento" }, { id: "tickets", name: "Tickets", icon: Ticket, href: "/xos/tickets", color: "bg-orange-100 text-orange-600", description: "Suporte e chamados" }, { id: "automations", name: "Automações", icon: Zap, href: "/xos/automations", color: "bg-violet-100 text-violet-600", description: "Workflows automáticos" }, { id: "campaigns", name: "Campanhas", icon: Target, href: "/xos/campaigns", color: "bg-pink-100 text-pink-600", description: "Marketing automation" }, { id: "sites", name: "Sites", icon: LayoutGrid, href: "/xos/sites", color: "bg-cyan-100 text-cyan-600", description: "Site builder" }, { id: "supervisor", name: "Supervisor", icon: Activity, href: "/xos/supervisor", color: "bg-indigo-100 text-indigo-600", description: "Monitor em tempo real" }, { id: "reports", name: "Relatórios", icon: BarChart3, href: "/xos/reports", color: "bg-emerald-100 text-emerald-600", description: "CSAT, SLA e KPIs" }, { id: "protocols", name: "Protocolos", icon: Hash, href: "/xos/protocols", color: "bg-teal-100 text-teal-600", description: "Rastreamento de atendimentos" }, ]; const getStatusColor = (status: string) => { const colors: Record = { new: "bg-blue-100 text-blue-800", contacted: "bg-indigo-100 text-indigo-800", qualified: "bg-violet-100 text-violet-800", proposal: "bg-purple-100 text-purple-800", won: "bg-green-100 text-green-800", lost: "bg-red-100 text-red-800", pending: "bg-yellow-100 text-yellow-800", completed: "bg-green-100 text-green-800", }; return colors[status] || "bg-gray-100 text-gray-800"; }; const getStageColor = (color: string | null) => { const colorMap: Record = { blue: "bg-blue-500", green: "bg-green-500", yellow: "bg-yellow-500", red: "bg-red-500", purple: "bg-purple-500", indigo: "bg-indigo-500", pink: "bg-pink-500", orange: "bg-orange-500", cyan: "bg-cyan-500", emerald: "bg-emerald-500", violet: "bg-violet-500", slate: "bg-slate-500", }; return colorMap[color || 'slate'] || "bg-slate-500"; }; const getActivityIcon = (type: string) => { const icons: Record = { call: Phone, email: Mail, meeting: Calendar, task: Target, }; return icons[type] || Calendar; }; return (
{/* Header */}

XOS

Experience Operating System

Dashboard Contatos Negócios Atividades {/* Stats Cards */}

Contatos

{stats?.total_contacts || 0}

{stats?.total_leads || 0} leads {stats?.total_customers || 0} clientes

Pipeline

{formatCurrency(Number(stats?.pipeline_value) || 0)}

{stats?.open_deals || 0} negócios abertos

Conversas

{stats?.open_conversations || 0}

atendimentos em aberto

Tickets

{stats?.open_tickets || 0}

chamados pendentes
{/* Modules Grid */}

Módulos XOS

{modules.map((mod) => (

{mod.name}

{mod.description}

))}
{/* Recent Items */}
{/* Recent Contacts */}
Contatos Recentes
{contacts.slice(0, 5).map((contact) => (
{contact.name.slice(0, 2).toUpperCase()}

{contact.name}

{contact.company} • {contact.position}

{contact.lead_status}
))} {contacts.length === 0 && (

Nenhum contato ainda

)}
{/* Recent Deals */}
Negócios Recentes
{deals.slice(0, 5).map((deal) => (

{deal.title}

{deal.contact_name || deal.company_name}

{formatCurrency(deal.value)}

{deal.stage_name}

))} {deals.length === 0 && (

Nenhum negócio ainda

)}
{/* Activities */}
Atividades Pendentes
{activities.slice(0, 6).map((activity) => { const Icon = getActivityIcon(activity.type); return (

{activity.title}

{activity.contact_name}

{activity.due_at && (
{new Date(activity.due_at).toLocaleDateString("pt-BR")}
)}
{activity.priority}
); })}
{activities.length === 0 && (

Nenhuma atividade pendente

)}
Todos os Contatos
{contacts.map((contact) => (
{contact.name.slice(0, 2).toUpperCase()}

{contact.name}

{contact.company} • {contact.position}

{contact.email}

{contact.phone}

{contact.lead_status} {contact.source}
))}
Pipeline de Vendas
Visualize e gerencie todos os seus negócios no modo Kanban
{deals.map((deal) => (

{deal.title}

{deal.contact_name} • {deal.company_name}

{formatCurrency(deal.value)}

{deal.stage_name}

{deal.status}
))}
Atividades
{activities.map((activity) => { const Icon = getActivityIcon(activity.type); return (

{activity.title}

{activity.contact_name} {activity.deal_title && `• ${activity.deal_title}`}

{activity.due_at && (
{new Date(activity.due_at).toLocaleDateString("pt-BR")}
)} {activity.status} {activity.priority}
); })} {activities.length === 0 && (

Nenhuma atividade cadastrada

)}
{/* Modal: Novo Contato */} Novo Contato
setNewContact({ ...newContact, name: e.target.value })} placeholder="Nome do contato" />
setNewContact({ ...newContact, email: e.target.value })} placeholder="email@exemplo.com" />
setNewContact({ ...newContact, phone: e.target.value })} placeholder="(00) 00000-0000" />
setNewContact({ ...newContact, company: e.target.value })} placeholder="Empresa" />
setNewContact({ ...newContact, position: e.target.value })} placeholder="Cargo" />
{/* Modal: Nova Atividade */} Nova Atividade
setNewActivity({ ...newActivity, title: e.target.value })} placeholder="Descrição da atividade" />
setNewActivity({ ...newActivity, due_at: e.target.value })} />
); }