'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 (
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 (
| Feature |
{labels.map((l, idx) => (
{idx === 0 ? : l}
|
))}
{rowElements}
)
}
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.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 (
| Feature |
{labels.map((l, idx) => (
{idx === 0 ? : l}
|
))}
{features.map((f, i) => (
|
{f.isUSP && highlight && }
{lang === 'de' ? f.de : f.en}
|
{cols.map(col => (
|
))}
))}
)
}