Krok 1 z dwóch: przenosi stringi, nie tłumaczy ich. en.ts dostaje komplet kluczy z polską treścią — angielskie wartości wchodzą osobnym commitem, żeby diff tłumaczeń dało się czytać zdanie po zdaniu. - data/content.ts: zostaje sama struktura (id, icon, href). Ikony to komponenty Reacta i nie mogą wejść do słowników; kolejność i liczba kart są przez to zdefiniowane raz, a nie duplikowane per język. - i18n/types.ts + RichText: akapity z <strong>/<em> w środku zdania trzymamy jako listę przebiegów. Bez dangerouslySetInnerHTML — tłumaczenie nie może wstrzyknąć znaczników. - en.ts typowane jako `typeof pl`, więc rozjazd kluczy to błąd builda. Przy ~150 kluczach to główne ryzyko tej zmiany. - privacy.backToHome -> common.backToHome (używane przez obie podstrony). Weryfikacja: renderowany tekst porównany z produkcją na wszystkich sześciu trasach — identyczny, poza linkiem powrotnym na /en/platforma, który był zahardkodowany po polsku i teraz zgadza się z /en/privacy. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
import React from 'react';
|
|
import { motion } from 'framer-motion';
|
|
import { CheckCircle2 } from 'lucide-react';
|
|
import { useT } from '../i18n';
|
|
|
|
const About = () => {
|
|
const t = useT();
|
|
|
|
return (
|
|
<section id="about" className="py-24 relative overflow-hidden">
|
|
<div className="container mx-auto px-6">
|
|
<div className="max-w-3xl mx-auto text-center">
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 20 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
transition={{ duration: 0.6 }}
|
|
>
|
|
<h2 className="text-3xl md:text-4xl font-bold mb-8">{t.about.title}</h2>
|
|
<p className="text-xl text-muted leading-relaxed mb-12">{t.about.lead}</p>
|
|
|
|
<div className="grid md:grid-cols-3 gap-6">
|
|
{t.about.points.map((point, index) => (
|
|
<motion.div
|
|
key={index}
|
|
initial={{ opacity: 0, y: 10 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
transition={{ duration: 0.4, delay: index * 0.1 }}
|
|
className="flex flex-col items-center p-6 glass-card border-primary/10"
|
|
>
|
|
<CheckCircle2 className="text-primary mb-4" size={32} />
|
|
<span className="font-medium text-lg leading-tight">{point}</span>
|
|
</motion.div>
|
|
))}
|
|
</div>
|
|
</motion.div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export default About;
|