Some checks failed
ci/woodpecker/push/integration Pipeline failed
ci/woodpecker/push/main Pipeline failed
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
- Academy, Whistleblower, Incidents frontend pages with API proxies and types - Vendor compliance API proxy route - Go backend handlers and models for all new SDK modules - Investor pitch-deck app with interactive slides - Blog section with DSGVO, AI Act, NIS2, glossary articles - MkDocs documentation site - CI/CD pipelines (Woodpecker, GitHub Actions), security scanning config - Planning and implementation documentation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
105 lines
2.4 KiB
TypeScript
105 lines
2.4 KiB
TypeScript
'use client'
|
|
|
|
import { Language } from '@/lib/types'
|
|
import { t } from '@/lib/i18n'
|
|
|
|
interface FinancialSlidersProps {
|
|
growthRate: number
|
|
churnRate: number
|
|
arpu: number
|
|
onGrowthChange: (v: number) => void
|
|
onChurnChange: (v: number) => void
|
|
onArpuChange: (v: number) => void
|
|
lang: Language
|
|
}
|
|
|
|
function Slider({
|
|
label,
|
|
value,
|
|
min,
|
|
max,
|
|
step,
|
|
unit,
|
|
onChange,
|
|
}: {
|
|
label: string
|
|
value: number
|
|
min: number
|
|
max: number
|
|
step: number
|
|
unit: string
|
|
onChange: (v: number) => void
|
|
}) {
|
|
return (
|
|
<div className="space-y-2">
|
|
<div className="flex justify-between text-sm">
|
|
<span className="text-white/60">{label}</span>
|
|
<span className="font-mono text-white">{value}{unit}</span>
|
|
</div>
|
|
<input
|
|
type="range"
|
|
min={min}
|
|
max={max}
|
|
step={step}
|
|
value={value}
|
|
onChange={(e) => onChange(parseFloat(e.target.value))}
|
|
className="w-full h-1.5 bg-white/10 rounded-full appearance-none cursor-pointer
|
|
[&::-webkit-slider-thumb]:appearance-none
|
|
[&::-webkit-slider-thumb]:w-4
|
|
[&::-webkit-slider-thumb]:h-4
|
|
[&::-webkit-slider-thumb]:rounded-full
|
|
[&::-webkit-slider-thumb]:bg-indigo-500
|
|
[&::-webkit-slider-thumb]:shadow-lg
|
|
[&::-webkit-slider-thumb]:shadow-indigo-500/30
|
|
[&::-webkit-slider-thumb]:cursor-pointer
|
|
"
|
|
/>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default function FinancialSliders({
|
|
growthRate,
|
|
churnRate,
|
|
arpu,
|
|
onGrowthChange,
|
|
onChurnChange,
|
|
onArpuChange,
|
|
lang,
|
|
}: FinancialSlidersProps) {
|
|
const i = t(lang)
|
|
|
|
return (
|
|
<div className="space-y-5 p-5 bg-white/[0.05] rounded-2xl border border-white/10">
|
|
<h4 className="text-sm font-medium text-white/60">{i.financials.adjustAssumptions}</h4>
|
|
<Slider
|
|
label={i.financials.sliderGrowth}
|
|
value={growthRate}
|
|
min={50}
|
|
max={200}
|
|
step={10}
|
|
unit="%"
|
|
onChange={onGrowthChange}
|
|
/>
|
|
<Slider
|
|
label={i.financials.sliderChurn}
|
|
value={churnRate}
|
|
min={0}
|
|
max={15}
|
|
step={0.5}
|
|
unit="%"
|
|
onChange={onChurnChange}
|
|
/>
|
|
<Slider
|
|
label={i.financials.sliderArpu}
|
|
value={arpu}
|
|
min={200}
|
|
max={1500}
|
|
step={50}
|
|
unit=" EUR"
|
|
onChange={onArpuChange}
|
|
/>
|
|
</div>
|
|
)
|
|
}
|