'use client' import { Language } from '@/lib/types' import { Users, DollarSign, Globe, Cpu, Star, Check, X, Minus } from 'lucide-react' import BrandName from '../ui/BrandName' import { type FeatureStatus, type ExtendedCompetitor, type ComparisonFeature, type AppSecCompetitor, type AppSecFeature, GROUP_LABELS, } from './CompetitionSlide.data' export function StatusIcon({ value }: { value: FeatureStatus }) { if (value === true) return if (value === 'partial') return return } export function AiBadge({ level, lang }: { level: 'full' | 'partial' | 'none'; lang: Language }) { const colors = { full: 'bg-green-500/15 text-green-400', partial: 'bg-yellow-500/15 text-yellow-400', none: 'bg-white/5 text-white/30' } const labels = { full: { de: 'KI', en: 'AI' }, partial: { de: 'Basis', en: 'Basic' }, none: { de: 'Keine', en: 'None' } } return ( {labels[level][lang]} ) } export function ratio(a: number, b: number): string { if (b === 0) return '\u2014' const r = a / b if (r >= 1_000_000) return `${(r / 1_000_000).toFixed(1)}M` if (r >= 1_000) return `${(r / 1_000).toFixed(0)}k` return r.toFixed(0) } export function CompetitorCard({ competitor: c, lang }: { competitor: ExtendedCompetitor; lang: Language }) { return (
{c.flag} {c.name}
1 ? ` | Offices: ${c.offices.join(', ')}` : '')}> {c.hq}, {c.hqCountry} {c.offices.length > 1 && ( + {c.offices.join(', ')} )}
{lang === 'de' ? 'Gr.' : 'Est.'} {c.founded}
{c.employees.toLocaleString()}
{c.revenue}
{c.customers.toLocaleString()} {lang === 'de' ? 'Kd.' : 'cust.'} ({c.customerCountries})
{c.fundingTotal} {c.fundingRound}
{c.investors.length > 0 && (
{c.investors.slice(0, 3).join(', ')}{c.investors.length > 3 ? ' +' + (c.investors.length - 3) : ''}
)}
{c.market[lang]}
) } export function FeatureTable({ features, lang, cols, labels, }: { features: ComparisonFeature[] lang: Language cols: readonly string[] labels: string[] highlight?: boolean }) { const rowElements: React.ReactNode[] = [] let lastGroup = '' features.forEach((f, i) => { const grp = f.group || '' if (grp && grp !== lastGroup) { const gl = GROUP_LABELS[grp] if (gl) { rowElements.push( {lang === 'de' ? gl.de : gl.en} ) } lastGroup = grp } rowElements.push( {f.isDiff && } {lang === 'de' ? f.de : f.en} {cols.map(col => ( ))} ) }) return (
{labels.map((l, idx) => ( ))} {rowElements}
Feature {idx === 0 ? : l}
) } export function AppSecCard({ competitor: c, lang }: { competitor: AppSecCompetitor; lang: Language }) { return (
{c.flag} {c.name}
{c.hq} ยท {c.founded}
{c.employees.toLocaleString()}
{c.revenue}
{c.funding}
{c.pricing}
{c.focus[lang]}
) } export function AppSecFeatureTable({ features, lang, highlight }: { features: AppSecFeature[]; lang: Language; highlight?: boolean }) { const cols = ['bp', 'snyk', 'veracode', 'checkmarx', 'sonar', 'semgrep', 'pentera', 'invicti', 'intruder'] as const const labels = ['ComplAI', 'Snyk', 'Veracode', 'Checkmarx', 'Sonar', 'Semgrep', 'Pentera', 'Invicti', 'Intruder'] return (
{labels.map((l, idx) => ( ))} {features.map((f, i) => ( {cols.map(col => ( ))} ))}
Feature {idx === 0 ? : l}
{f.isUSP && highlight && } {lang === 'de' ? f.de : f.en}
) }