import React, { useState, useMemo } from "react"; import { base44 } from "@/api/base44Client"; import { useQuery } from "@tanstack/react-query"; import { Link } from "react-router-dom"; import { createPageUrl } from "@/utils"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Badge } from "@/components/ui/badge"; import { Briefcase, Plus, Search, MapPin, DollarSign, Edit, Building2, TrendingUp, AlertTriangle, CheckCircle2, Users, Target, LayoutGrid, List } from "lucide-react"; import PageHeader from "../components/common/PageHeader"; export default function PartnerManagement() { const [searchTerm, setSearchTerm] = useState(""); const [viewMode, setViewMode] = useState("grid"); // New state for view mode const { data: partners = [], isLoading: partnersLoading } = useQuery({ queryKey: ['partners'], queryFn: () => base44.entities.Partner.list('-created_date'), initialData: [], }); const { data: businesses = [], isLoading: businessesLoading } = useQuery({ queryKey: ['businesses'], queryFn: () => base44.entities.Business.list('-created_date'), initialData: [], }); const { data: sectors = [] } = useQuery({ queryKey: ['sectors'], queryFn: () => base44.entities.Sector.list('-created_date'), initialData: [], }); const { data: enterprises = [] } = useQuery({ queryKey: ['enterprises'], queryFn: () => base44.entities.Enterprise.list('-created_date'), initialData: [], }); // Consolidate businesses by company name const consolidatedBusinesses = useMemo(() => { const grouped = {}; businesses.forEach(business => { let companyName = business.business_name; // Extract company name (remove hub suffix if present) const dashIndex = companyName.indexOf(' - '); if (dashIndex > 0) { companyName = companyName.substring(0, dashIndex).trim(); } if (!grouped[companyName]) { grouped[companyName] = { company_name: companyName, partner_type: "Corporate", hubs: [], primary_contact: business.contact_name, primary_email: business.email, primary_phone: business.phone, sector: business.sector || business.area || '', total_hubs: 0, company_logo: business.company_logo || null, }; } grouped[companyName].hubs.push({ id: business.id, hub_name: business.business_name, contact_name: business.contact_name, email: business.email, phone: business.phone, address: business.address, city: business.city, area: business.area, rate_group: business.rate_group, company_logo: business.company_logo, }); grouped[companyName].total_hubs++; // Use the first hub's logo if available if (business.company_logo && !grouped[companyName].company_logo) { grouped[companyName].company_logo = business.company_logo; } }); return Object.values(grouped); }, [businesses]); // Operator coverage data const operatorMetrics = { totalCoverage: 94, activeIncidents: 2, clientSatisfaction: 4.8, forecastAccuracy: 91 }; const hubCoverageData = [ { hub: 'San Jose', enterprise: 'Compass', sector: 'Bon Appétit', coverage: 97, incidents: 0, satisfaction: 4.9, partners: 12 }, { hub: 'San Francisco', enterprise: 'Compass', sector: 'Eurest', coverage: 92, incidents: 1, satisfaction: 4.7, partners: 8 }, { hub: 'Oakland', enterprise: 'Compass', sector: 'Bon Appétit', coverage: 89, incidents: 2, satisfaction: 4.5, partners: 6 }, { hub: 'Sacramento', enterprise: 'Compass', sector: 'Chartwells', coverage: 95, incidents: 1, satisfaction: 4.8, partners: 10 }, ]; const filteredPartners = partners.filter(p => !searchTerm || p.partner_name?.toLowerCase().includes(searchTerm.toLowerCase()) || p.partner_number?.toLowerCase().includes(searchTerm.toLowerCase()) ); const filteredBusinesses = consolidatedBusinesses.filter(b => !searchTerm || b.company_name?.toLowerCase().includes(searchTerm.toLowerCase()) || b.primary_contact?.toLowerCase().includes(searchTerm.toLowerCase()) ); const totalPartnerCount = filteredPartners.length + filteredBusinesses.length; const totalHubCount = filteredBusinesses.reduce((sum, b) => sum + b.total_hubs, 0) + filteredPartners.reduce((sum, p) => sum + (p.sites?.length || 0), 0); const isLoading = partnersLoading || businessesLoading; return (
} /> {/* Operator Key Metrics */}
+5%

Coverage Rate

{operatorMetrics.totalCoverage}%

Low

Active Incidents

{operatorMetrics.activeIncidents}

{operatorMetrics.clientSatisfaction}/5.0

Client Satisfaction

{operatorMetrics.clientSatisfaction}

{operatorMetrics.forecastAccuracy}%

Forecast Accuracy

{operatorMetrics.forecastAccuracy}%

{/* Search */}
setSearchTerm(e.target.value)} className="pl-10" />
{/* Live Operator Coverage Map */} Live Operator Coverage Map

Real-time coverage across all hubs and sectors

{hubCoverageData.map((hub, index) => (
= 95 ? 'bg-emerald-100' : hub.coverage >= 90 ? 'bg-blue-100' : 'bg-amber-100' }`}> = 95 ? 'text-emerald-600' : hub.coverage >= 90 ? 'text-blue-600' : 'text-amber-600' }`} />

{hub.hub}

{hub.enterprise} • {hub.sector}

= 95 ? 'bg-emerald-100 text-emerald-700' : hub.coverage >= 90 ? 'bg-blue-100 text-blue-700' : 'bg-amber-100 text-amber-700' } text-lg px-3 py-1 font-bold`}> {hub.coverage}%

Partners

{hub.partners}

Incidents

0 ? 'text-red-600' : 'text-emerald-600'}`}> {hub.incidents}

Rating

{hub.satisfaction}/5.0

= 95 ? 'bg-gradient-to-r from-emerald-500 to-emerald-600' : hub.coverage >= 90 ? 'bg-gradient-to-r from-blue-500 to-blue-600' : 'bg-gradient-to-r from-amber-500 to-amber-600' }`} style={{ width: `${hub.coverage}%` }} />
))}
{/* Organizational Hierarchy */}

Enterprise & Sector Overview

Enterprises

{enterprises.length}

Sectors

{sectors.length}

Partners

{totalPartnerCount}

{/* Partners Grid/List */}

Partner Directory

{isLoading ? (
{[...Array(6)].map((_, i) => (
))}
) : (filteredPartners.length > 0 || filteredBusinesses.length > 0) ? ( <> {/* Grid View */} {viewMode === "grid" && (
{/* Display Businesses from Business Directory */} {filteredBusinesses.map((business, idx) => (
{business.company_logo ? ( {business.company_name} ) : (
{business.company_name?.charAt(0) || 'B'}
)}

{business.company_name}

PN-{String(idx + 1000).padStart(4, '0')}

Type {business.partner_type}
Sector {business.sector || '—'}
Sites {business.total_hubs}
Terms Net 30
Active
))} {/* Display Traditional Partners */} {filteredPartners.map((partner) => (

{partner.partner_name}

{partner.partner_number}

Type {partner.partner_type}
Sector {partner.sector_name || '—'}
Sites {partner.sites?.length || 0}
Terms {partner.payment_terms || 'Net 30'}
{partner.is_active ? "Active" : "Inactive"}
))}
)} {/* List View */} {viewMode === "list" && (
{/* Display Businesses from Business Directory */} {filteredBusinesses.map((business, idx) => ( ))} {/* Display Traditional Partners */} {filteredPartners.map((partner) => ( ))}
Partner Name Type Sector Hubs/Sites Contact Status Actions
{business.company_logo ? ( {business.company_name} ) : (
{business.company_name?.charAt(0) || 'B'}
)}

{business.company_name}

From Business Directory
{business.partner_type} {business.sector || '—'} {business.total_hubs} {business.primary_contact || '—'} Active

{partner.partner_name}

{partner.partner_number}

{partner.partner_type} {partner.sector_name || '—'} {partner.sites?.length || 0} {partner.primary_contact_name || '—'} {partner.is_active ? "Active" : "Inactive"}
)} ) : (

No Partners Found

Add your first partner client

)}
); }