Some checks failed
Build pitch-deck / build-push-deploy (push) Failing after 1m13s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 49s
CI / test-python-voice (push) Successful in 38s
CI / test-bqas (push) Successful in 31s
# Conflicts: # pitch-deck/components/slides/MilestonesSlide.tsx # pitch-deck/lib/finanzplan/engine.ts
78 lines
2.4 KiB
TypeScript
78 lines
2.4 KiB
TypeScript
'use client'
|
|
|
|
import { useState, useEffect, useRef, useCallback } from 'react'
|
|
import { Language } from '@/lib/types'
|
|
import GradientText from '../ui/GradientText'
|
|
import FadeInView from '../ui/FadeInView'
|
|
import { type Milestone } from './MilestonesSlide.data'
|
|
import { THEMES, CSS_KF, useIsLight } from './MilestonesSlide.themes'
|
|
import { MilestonesInner } from './MilestonesSlide.parts'
|
|
|
|
interface MilestonesSlideProps { lang: Language }
|
|
|
|
const INNER_W = 1280
|
|
const INNER_H = 600
|
|
|
|
export default function MilestonesSlide({ lang }: MilestonesSlideProps) {
|
|
const de = lang === 'de'
|
|
const isLight = useIsLight()
|
|
const t = isLight ? THEMES.light : THEMES.dark
|
|
const [sel, setSel] = useState<Milestone | null>(null)
|
|
const [scale, setScale] = useState(1)
|
|
const containerRef = useRef<HTMLDivElement>(null)
|
|
|
|
const calcScale = useCallback(() => {
|
|
if (containerRef.current) {
|
|
const w = containerRef.current.offsetWidth
|
|
setScale(Math.min(w / INNER_W, 1))
|
|
}
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
calcScale()
|
|
const obs = new ResizeObserver(calcScale)
|
|
if (containerRef.current) obs.observe(containerRef.current)
|
|
return () => obs.disconnect()
|
|
}, [calcScale])
|
|
|
|
return (
|
|
<div>
|
|
<style>{CSS_KF}</style>
|
|
|
|
<FadeInView className="text-center mb-1">
|
|
<h2 className="text-5xl md:text-6xl font-bold mb-1">
|
|
<GradientText>{de ? 'Meilensteine' : 'Milestones'}</GradientText>
|
|
</h2>
|
|
<p className="text-lg text-white/50 max-w-2xl mx-auto">
|
|
{de ? 'Von der Idee zur GmbH — was wir bereits erreicht haben' : 'From idea to GmbH — what we have already achieved'}
|
|
</p>
|
|
</FadeInView>
|
|
|
|
<FadeInView delay={0.1}>
|
|
<div
|
|
ref={containerRef}
|
|
style={{
|
|
position: 'relative',
|
|
width: '100%',
|
|
height: INNER_H * scale,
|
|
overflow: 'hidden',
|
|
borderRadius: 16,
|
|
transform: 'scale(1.12)',
|
|
transformOrigin: 'top center',
|
|
marginBottom: -40,
|
|
}}
|
|
>
|
|
<div style={{
|
|
position: 'absolute', top: 0, left: 0,
|
|
width: INNER_W, height: INNER_H,
|
|
transform: `scale(${scale})`,
|
|
transformOrigin: 'top left',
|
|
}}>
|
|
<MilestonesInner t={t} de={de} sel={sel} setSel={setSel} />
|
|
</div>
|
|
</div>
|
|
</FadeInView>
|
|
</div>
|
|
)
|
|
}
|