'use client' import { useState } from 'react' import { Language, PitchFeature, PitchCompetitor } from '@/lib/types' import { t } from '@/lib/i18n' import { ChevronDown, ChevronRight, Globe, Building2, Users, TrendingUp, DollarSign, Cpu, Star, Check, X, Minus, Shield, } from 'lucide-react' import GradientText from '../ui/GradientText' import FadeInView from '../ui/FadeInView' import GlassCard from '../ui/GlassCard' import BrandName from '../ui/BrandName' import { type FeatureStatus, type ComparisonFeature, EXTENDED_COMPETITORS, ALL_FEATURES, DACH_NOTE, PRICING_COMPARISON, APPSEC_COMPETITORS, APPSEC_FEATURES, } from './CompetitionSlide.data' import { StatusIcon, AiBadge, ratio, CompetitorCard, FeatureTable, AppSecCard, AppSecFeatureTable } from './CompetitionSlide.parts' interface CompetitionSlideProps { lang: Language features: PitchFeature[] competitors: PitchCompetitor[] } // ─── Helpers ─────────────────────────────────────────────────────────────────── // ─── Section Accordion ───────────────────────────────────────────────────────── function SectionHeader({ label, count, open, onToggle, accent, }: { label: string count: number open: boolean onToggle: () => void accent?: string }) { return ( ) } // ─── Component ───────────────────────────────────────────────────────────────── type ViewTab = 'overview' | 'features' | 'pricing' | 'appsec' export default function CompetitionSlide({ lang, features, competitors }: CompetitionSlideProps) { const i = t(lang) const [activeTab, setActiveTab] = useState('overview') const [openSections, setOpenSections] = useState>(new Set(['top5'])) const toggleSection = (key: string) => { setOpenSections(prev => { const next = new Set(prev) if (next.has(key)) next.delete(key) else next.add(key) return next }) } const top5 = ALL_FEATURES.filter(f => f.isDiff) const usps = ALL_FEATURES.filter(f => f.isUSP) const allFeatures = ALL_FEATURES const competitorCols = ['bp', 'vanta', 'drata', 'sprinto', 'proliance', 'dataguard', 'heydata'] as const const competitorLabels = ['ComplAI', 'Vanta', 'Drata', 'Sprinto', 'Proliance', 'DataGuard', 'heyData'] const featureCount = ALL_FEATURES.length const uspCount = usps.length const subtitle = lang === 'de' ? `${featureCount} Features, ${uspCount} USPs — kein Anbieter kombiniert DSGVO + Code-Security + Self-Hosted KI` : `${featureCount} features, ${uspCount} USPs — no provider combines GDPR + code security + self-hosted AI` return (
{/* Header */}

{i.competition.title}

{subtitle}

{/* Tab Bar */} {([ { key: 'overview' as ViewTab, de: 'Überblick & Vergleich', en: 'Overview & Comparison' }, { key: 'features' as ViewTab, de: 'Feature-Matrix (Detail)', en: 'Feature Matrix (Detail)' }, { key: 'pricing' as ViewTab, de: 'Pricing-Vergleich', en: 'Pricing Comparison' }, { key: 'appsec' as ViewTab, de: 'Pentesting & AppSec', en: 'Pentesting & AppSec' }, ]).map(tab => ( ))} {/* ─── Tab: Overview ─── */} {activeTab === 'overview' && ( {/* Competitor Profiles */}
{/* International */}
{lang === 'de' ? 'International' : 'International'}
{EXTENDED_COMPETITORS.filter(c => c.isInternational).map(c => ( ))}
{/* DACH */}
DACH
{EXTENDED_COMPETITORS.filter(c => !c.isInternational).map(c => ( ))}
{/* Efficiency Ratios */}

{lang === 'de' ? 'Effizienz-Kennzahlen' : 'Efficiency Ratios'}

{EXTENDED_COMPETITORS.map(c => ( ))} {EXTENDED_COMPETITORS.map(c => ( ))} {EXTENDED_COMPETITORS.map(c => ( ))} {EXTENDED_COMPETITORS.map(c => ( ))}
{lang === 'de' ? 'Kennzahl' : 'Metric'}{c.flag} {c.name}
{lang === 'de' ? 'Umsatz / Mitarbeiter' : 'Revenue / Employee'} ${ratio(c.revenueNum, c.employees)}
{lang === 'de' ? 'Kunden / Mitarbeiter' : 'Customers / Employee'} {(c.customers / c.employees).toFixed(0)}
{lang === 'de' ? 'Mitarbeiter' : 'Employees'} {c.employees.toLocaleString()}
{/* DACH Landscape Note */}
{DACH_NOTE[lang]}
)} {/* ─── Tab: Feature Matrix ─── */} {activeTab === 'features' && (
{/* All Features */}
toggleSection('all')} /> {openSections.has('all') && ( )}
{/* USPs */}
toggleSection('usp')} accent="text-indigo-400" /> {openSections.has('usp') && ( )}
{/* Score Summary */}
{[ { name: 'ComplAI', score: ALL_FEATURES.filter(f => f.bp === true).length, color: 'text-indigo-400' }, { name: 'Vanta', score: ALL_FEATURES.filter(f => f.vanta === true).length, color: 'text-white/50' }, { name: 'Drata', score: ALL_FEATURES.filter(f => f.drata === true).length, color: 'text-white/50' }, { name: 'Sprinto', score: ALL_FEATURES.filter(f => f.sprinto === true).length, color: 'text-white/50' }, { name: 'Proliance', score: ALL_FEATURES.filter(f => f.proliance === true).length, color: 'text-white/50' }, { name: 'DataGuard', score: ALL_FEATURES.filter(f => f.dataguard === true).length, color: 'text-white/50' }, { name: 'heyData', score: ALL_FEATURES.filter(f => f.heydata === true).length, color: 'text-white/50' }, ].map(item => (
{item.score}/{ALL_FEATURES.length}
{item.name}
))}
)} {/* ─── Tab: Pricing ─── */} {activeTab === 'pricing' && (
{PRICING_COMPARISON.map((cp) => ( {cp.tiers.map((tier, idx) => ( ))} ))}
{lang === 'de' ? 'Anbieter' : 'Provider'} {lang === 'de' ? 'Modell' : 'Model'} {lang === 'de' ? 'Einstieg' : 'Entry'} Mid Enterprise Setup {lang === 'de' ? 'Öffentlich' : 'Public'}
{cp.flag} {cp.isBP ? : cp.name}
{cp.model}
{tier.price}
{tier.annual}
{lang === 'de' ? tier.notes.de : tier.notes.en}
{cp.setupFee} {cp.publicPricing ? : }

{lang === 'de' ? '~ = geschätzte Preise (nicht öffentlich). Alle Preise ohne MwSt. Stand: Q1 2026.' : '~ = estimated pricing (not public). All prices excl. VAT. As of Q1 2026.'}

)} {/* ─── Tab: AppSec / Pentesting ─── */} {activeTab === 'appsec' && ( {/* Intro */}
{lang === 'de' ? 'Warum ein 2. Wettbewerbsvergleich?' : 'Why a 2nd competitive comparison?'}

{lang === 'de' ? 'Kein Compliance-Anbieter (Vanta, Drata, etc.) bietet DAST, SAST oder LLM-basierte Code-Fixes. Kein AppSec-Anbieter (Snyk, Veracode, etc.) bietet DSGVO/AI-Act-Compliance. COMPLAI ist die einzige Plattform, die beides kombiniert.' : 'No compliance vendor (Vanta, Drata, etc.) offers DAST, SAST, or LLM-based code fixes. No AppSec vendor (Snyk, Veracode, etc.) offers GDPR/AI Act compliance. COMPLAI is the only platform combining both.'}

{/* AppSec Competitor Cards */}
{lang === 'de' ? 'AppSec / Pentesting Anbieter' : 'AppSec / Pentesting Providers'}
{APPSEC_COMPETITORS.map(c => ( ))}
{/* Efficiency Ratios — AppSec */}

{lang === 'de' ? 'Effizienz-Kennzahlen' : 'Efficiency Ratios'}

{APPSEC_COMPETITORS.map(c => ( ))} {APPSEC_COMPETITORS.map(c => ( ))} {APPSEC_COMPETITORS.map(c => ( ))}
{lang === 'de' ? 'Kennzahl' : 'Metric'}{c.flag} {c.name}
{lang === 'de' ? 'Umsatz / Mitarbeiter' : 'Revenue / Employee'} ${ratio(c.revenueNum, c.employees)}
{lang === 'de' ? 'Mitarbeiter' : 'Employees'} {c.employees.toLocaleString()}
{/* AppSec Feature Matrix */}
toggleSection('appsec-all')} /> {openSections.has('appsec-all') && ( )}
{/* Score Summary */}
{[ { name: 'ComplAI', score: APPSEC_FEATURES.filter(f => f.bp === true).length, color: 'text-indigo-400' }, { name: 'Snyk', score: APPSEC_FEATURES.filter(f => f.snyk === true).length, color: 'text-white/50' }, { name: 'Veracode', score: APPSEC_FEATURES.filter(f => f.veracode === true).length, color: 'text-white/50' }, { name: 'Checkmarx', score: APPSEC_FEATURES.filter(f => f.checkmarx === true).length, color: 'text-white/50' }, { name: 'SonarSrc', score: APPSEC_FEATURES.filter(f => f.sonar === true).length, color: 'text-white/50' }, { name: 'Semgrep', score: APPSEC_FEATURES.filter(f => f.semgrep === true).length, color: 'text-white/50' }, { name: 'Pentera', score: APPSEC_FEATURES.filter(f => f.pentera === true).length, color: 'text-white/50' }, { name: 'Invicti', score: APPSEC_FEATURES.filter(f => f.invicti === true).length, color: 'text-white/50' }, { name: 'Intruder', score: APPSEC_FEATURES.filter(f => f.intruder === true).length, color: 'text-white/50' }, ].map(item => (
{item.score}/{APPSEC_FEATURES.length}
{item.name}
))}
)}
) }