import React, { useState } from ‘react’; import { LayoutDashboard, Users, KanbanSquare, CheckCircle2, Circle, Calendar, PhoneCall, Mail, Plus, X, Search, Building, MapPin, ExternalLink, Briefcase, ChevronRight } from ‘lucide-react’; // — CONFIGURACIÓN Y CONSTANTES — const PIPELINE_STAGES = [ «Sin Contactar», «Contactado», «Reunión / Diagnóstico», «Propuesta Enviada», «Seguimiento / Negociación», «Cerrado – Ganado», «Cerrado – Perdido» ]; const SERVICES = [«ISO 9001», «ISO 14001», «ISO 45001», «Certificación de Producto», «Comercio Exterior»]; const SOURCES = [«LinkedIn», «Expo / Evento», «Google / Web», «Referido», «Base Fría»]; const INITIAL_COMPANIES = [ { id: 1, name: ‘Metalúrgica Sur S.A.’, contact: ‘Carlos Gómez’, role: ‘Gte. Calidad’, mail: ‘cgomez@metalsur.com’, phone: ‘341-555-0123’, city: ‘Rosario’, province: ‘Santa Fe’, industry: ‘Metalúrgica’, interest: ‘ISO 9001’, source: ‘LinkedIn’, stage: ‘Reunión / Diagnóstico’, notes: ‘Quieren certificar antes de diciembre.’ }, { id: 2, name: ‘Logística Avanzada’, contact: ‘María Silva’, role: ‘Directora’, mail: ‘msilva@logavanzada.com’, phone: ’11-444-9988′, city: ‘CABA’, province: ‘Buenos Aires’, industry: ‘Logística’, interest: ‘ISO 45001’, source: ‘Referido’, stage: ‘Propuesta Enviada’, notes: ‘Comparando presupuestos.’ }, { id: 3, name: ‘Agro Export SRL’, contact: ‘Diego López’, role: ‘Comercio Ext.’, mail: ‘dlopez@agroexport.com.ar’, phone: ‘351-222-3344’, city: ‘Córdoba’, province: ‘Córdoba’, industry: ‘Agro’, interest: ‘Comercio Exterior’, source: ‘Google’, stage: ‘Sin Contactar’, notes: ‘Dejaron consulta en la web.’ } ]; const getTodayDateString = () => new Date().toISOString().split(‘T’)[0]; const INITIAL_TASKS = [ { id: 1, companyId: 1, date: getTodayDateString(), type: ‘Reunión Virtual’, status: ‘Pendiente’, notes: ‘Relevar cantidad de empleados.’, assignedTo: ‘Vendedor 1’ }, { id: 2, companyId: 2, date: ‘2023-10-01’, type: ‘Llamada’, status: ‘Pendiente’, notes: ‘Seguimiento de presupuesto.’, assignedTo: ‘Vendedor 2’ } ]; // COMPONENTE PRINCIPAL (Debe llamarse App para la vista previa) export default function App() { const [activeTab, setActiveTab] = useState(‘dashboard’); const [companies, setCompanies] = useState(INITIAL_COMPANIES); const [tasks, setTasks] = useState(INITIAL_TASKS); // Filtros const [filterInterest, setFilterInterest] = useState(‘Todos’); const [filterStage, setFilterStage] = useState(‘Todos’); const [searchTerm, setSearchTerm] = useState(»); // Modales const [isCompanyModalOpen, setIsCompanyModalOpen] = useState(false); const [isTaskModalOpen, setIsTaskModalOpen] = useState(false); const [selectedCompanyId, setSelectedCompanyId] = useState(null); const today = getTodayDateString(); // — LÓGICA DE GOOGLE CALENDAR — const generateGoogleCalendarLink = (task) => { const company = companies.find(c => c.id === task.companyId); const title = encodeURIComponent(`${task.type}: ${company?.name || ‘Cliente’}`); const details = encodeURIComponent(`Acción: ${task.notes}nContacto: ${company?.contact}nTel: ${company?.phone}`); const date = task.date.replace(/-/g, »); // Formato YYYYMMDD/YYYYMMDD return `https://www.google.com/calendar/render?action=TEMPLATE&text=${title}&details=${details}&dates=${date}/${date}`; }; // — FILTRADO DE DATOS — const filteredCompanies = companies.filter(c => { const matchInterest = filterInterest === ‘Todos’ || c.interest === filterInterest; const matchStage = filterStage === ‘Todos’ || c.stage === filterStage; const searchLow = searchTerm.toLowerCase(); const matchSearch = c.name.toLowerCase().includes(searchLow) || c.city.toLowerCase().includes(searchLow) || c.province.toLowerCase().includes(searchLow); return matchInterest && matchStage && matchSearch; }); const toggleTaskStatus = (taskId) => { setTasks(tasks.map(t => t.id === taskId ? { …t, status: t.status === ‘Pendiente’ ? ‘Completada’ : ‘Pendiente’ } : t)); }; const changeCompanyStage = (companyId, newStage) => { setCompanies(companies.map(c => c.id === companyId ? { …c, stage: newStage } : c)); }; // — VISTAS INTERNAS — const DashboardView = () => { const pending = tasks.filter(t => t.status === ‘Pendiente’); const vencidas = pending.filter(t => t.date < today); const hoy = pending.filter(t => t.date === today); const futuras = pending.filter(t => t.date > today); return (

Panel de Control

); }; const TaskColumn = ({ title, tasks, color }) => { const colorClasses = { red: «bg-red-50 border-red-200 text-red-700», amber: «bg-amber-50 border-amber-200 text-amber-700», slate: «bg-slate-50 border-slate-200 text-slate-700» }; return (

{title} ({tasks.length})

{tasks.map(task => { const comp = companies.find(c => c.id === task.companyId); return (
{task.type}

{comp?.name || ‘Empresa eliminada’}

«{task.notes}»

{task.date} Google Cal
); })} {tasks.length === 0 &&

Sin tareas pendientes

}
); }; const PipelineView = () => (

Pipeline Comercial

{PIPELINE_STAGES.map(stage => { const stageCompanies = companies.filter(c => c.stage === stage); return (

{stage}

{stageCompanies.length}
{stageCompanies.map(c => (

{c.name}

{c.city}, {c.province}

{c.interest}

))} {stageCompanies.length === 0 &&
}
); })}
); const DirectorioView = () => (

Directorio de Empresas

{/* FILTROS MEJORADOS */}
setSearchTerm(e.target.value)} placeholder=»Nombre, ciudad o provincia…» className=»w-full pl-10 pr-4 py-2.5 bg-slate-50 border border-slate-200 rounded-xl text-sm outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all» />
{filteredCompanies.map(c => ( ))}
Empresa / Contacto Ubicación Servicio Etapa Comercial Gestión
{c.name}
{c.contact} • {c.mail}
{c.city}
{c.province}
{c.interest}
{filteredCompanies.length === 0 && (

No se encontraron empresas con los filtros actuales.

)}
); // — MODALES — const CompanyModal = () => { const handleSubmit = (e) => { e.preventDefault(); const fd = new FormData(e.target); const newC = { id: Date.now(), name: fd.get(‘name’), city: fd.get(‘city’), province: fd.get(‘province’), contact: fd.get(‘contact’), mail: fd.get(‘mail’), phone: fd.get(‘phone’), interest: fd.get(‘interest’), stage: ‘Sin Contactar’, source: fd.get(‘source’), notes: fd.get(‘notes’) }; setCompanies(prev => […prev, newC]); setIsCompanyModalOpen(false); }; return (

Nueva Empresa