'use client'; import { useState } from 'react'; import { Sparkles, TrendingUp, TrendingDown, Languages, Loader2, Star, Target, AlertTriangle, CheckCircle2, ChevronRight, Zap, Award, } from 'lucide-react'; import { useTranslation } from '@/hooks/useTranslation'; import type { Insights, WeaknessItem, OpportunitySpan, OpportunityMatrix, DomainScore, URTDomain } from '../types'; import { getSubcodeDefinition } from '@/lib/taxonomy/data'; interface ExecutiveSummaryProps { insights: Insights; avgRating: number | null; domainScores?: DomainScore[]; onDriverClick?: (subcode: string) => void; onDomainClick?: (domain: URTDomain) => void; } // User-friendly domain config const DOMAIN_CONFIG: Record = { P: { emoji: '👥', label: 'Staff & Service' }, V: { emoji: '💰', label: 'Pricing & Value' }, J: { emoji: '⏱️', label: 'Speed & Process' }, O: { emoji: '🛍️', label: 'Product Quality' }, A: { emoji: '📍', label: 'Availability' }, E: { emoji: '🏢', label: 'Facilities' }, R: { emoji: '🤝', label: 'Trust & Ethics' }, }; // Get rating emoji and label const getRatingDisplay = (rating: number | null) => { if (!rating) return { emoji: '❓', label: 'No rating', color: 'text-gray-500' }; if (rating >= 4.5) return { emoji: '🌟', label: 'Excellent', color: 'text-green-600' }; if (rating >= 4.0) return { emoji: '😊', label: 'Good', color: 'text-green-500' }; if (rating >= 3.5) return { emoji: '🙂', label: 'Average', color: 'text-yellow-600' }; if (rating >= 3.0) return { emoji: '😐', label: 'Fair', color: 'text-orange-500' }; return { emoji: '😟', label: 'Needs Work', color: 'text-red-500' }; }; // Domain complaints section function TopComplaintsSection({ domainScores, weaknesses, opportunityMatrix, onDomainClick, }: { domainScores: DomainScore[]; weaknesses: WeaknessItem[]; opportunityMatrix: OpportunityMatrix | null; onDomainClick?: (domain: URTDomain) => void; }) { const { translate, getState } = useTranslation('en'); // Get example quote for a domain const getQuoteForDomain = (domainKey: string): OpportunitySpan | null => { const weakness = weaknesses.find(w => w.domain === domainKey); if (weakness?.example_spans?.length) { return weakness.example_spans[0]; } if (opportunityMatrix) { const allOpportunities = [ ...opportunityMatrix.quick_wins, ...opportunityMatrix.critical, ...opportunityMatrix.nice_to_have, ...opportunityMatrix.strategic, ]; const opportunity = allOpportunities.find(o => o.domain === domainKey && o.spans?.length); if (opportunity?.spans?.length) { return opportunity.spans[0]; } } return null; }; // Calculate and sort by negative percentage const sorted = domainScores .map(d => ({ ...d, negativePercent: d.total_count > 0 ? Math.round((d.negative_count / d.total_count) * 100) : 0, quote: getQuoteForDomain(d.domain), config: DOMAIN_CONFIG[d.domain] || { emoji: '📊', label: d.name }, })) .sort((a, b) => b.negativePercent - a.negativePercent) .slice(0, 4); const handleTranslate = (e: React.MouseEvent, text: string, id: string) => { e.stopPropagation(); translate(text, id); }; return (
{sorted.map((domain) => { const quoteId = `domain-${domain.domain}`; const translationState = getState(quoteId); const displayText = translationState.isTranslated && domain.quote ? translationState.translated : domain.quote?.span_text; const severity = domain.negativePercent >= 40 ? 'critical' : domain.negativePercent >= 25 ? 'warning' : 'ok'; return (
onDomainClick?.(domain.domain as URTDomain)} onKeyDown={(e) => e.key === 'Enter' && onDomainClick?.(domain.domain as URTDomain)} className={`w-full p-3 rounded-xl border-2 transition-all hover:shadow-md text-left cursor-pointer ${ severity === 'critical' ? 'bg-red-50 border-red-200 hover:border-red-300' : severity === 'warning' ? 'bg-orange-50 border-orange-200 hover:border-orange-300' : 'bg-gray-50 border-gray-200 hover:border-gray-300' }`} >
{/* Emoji */} {domain.config.emoji} {/* Content */}
{domain.config.label} {domain.negativePercent}% complaints
{/* Progress bar */}
{/* Quote */} {domain.quote && displayText && (

"{displayText}"

)}
); })}
); } export function ExecutiveSummary({ insights, avgRating, domainScores, onDriverClick, onDomainClick, }: ExecutiveSummaryProps) { const { strengths, weaknesses, executive_summary, opportunity_matrix, rating_simulator } = insights; const [showFullSummary, setShowFullSummary] = useState(false); // Use the generated summary from insights const narrativeText = executive_summary; const topStrength = strengths[0]; const topWeakness = weaknesses[0]; const ratingDisplay = getRatingDisplay(avgRating); // Calculate potential rating improvement const potentialRating = rating_simulator?.if_fix_top_3 || (avgRating && topWeakness?.projected_rating_impact ? avgRating + topWeakness.projected_rating_impact : null); // If no insights, show minimal summary if (!executive_summary && !topStrength && !topWeakness) { return (

Executive Summary

AI-powered insights from your reviews

📊

More data needed

Continue collecting reviews to unlock actionable insights and recommendations.

); } return (
{/* Header */}

Executive Summary

AI-powered insights from your reviews

{/* Rating Badge */} {avgRating && (
{ratingDisplay.emoji}
{avgRating.toFixed(1)}
{ratingDisplay.label}
{potentialRating && potentialRating > avgRating && (
Potential
{potentialRating.toFixed(1)}
)}
)}
{/* Summary */} {narrativeText && (
💡

{narrativeText}

{narrativeText.length > 200 && ( )}
)} {/* Key Metrics Cards */}
{/* Top Problem */} {topWeakness && ( )} {/* Top Strength */} {topStrength && ( )}
{/* Complaint Breakdown */} {domainScores && domainScores.length > 0 && (
Where Customers Complain Most
)} {/* Quick Actions Footer */}
💡 Click any card to drill down into details
Powered by AI
); }