feat: manage testimonial labels via payload
This commit is contained in:
@@ -160,6 +160,11 @@ export const aboutFields: Field[] = [
|
|||||||
fields: [
|
fields: [
|
||||||
text('eyebrow', 'Eyebrow', aboutContent.testimonials.eyebrow),
|
text('eyebrow', 'Eyebrow', aboutContent.testimonials.eyebrow),
|
||||||
textarea('heading', 'Heading', aboutContent.testimonials.heading),
|
textarea('heading', 'Heading', aboutContent.testimonials.heading),
|
||||||
|
textarea('desktopHeading', 'Desktop heading', aboutContent.testimonials.desktopHeading),
|
||||||
|
text('yearPrefix', 'Award year prefix', aboutContent.testimonials.yearPrefix),
|
||||||
|
text('previousLabel', 'Previous button label', aboutContent.testimonials.previousLabel),
|
||||||
|
text('nextLabel', 'Next button label', aboutContent.testimonials.nextLabel),
|
||||||
|
text('slideLabelPrefix', 'Slide dot label prefix', aboutContent.testimonials.slideLabelPrefix),
|
||||||
{
|
{
|
||||||
name: 'items',
|
name: 'items',
|
||||||
label: 'Testimonials',
|
label: 'Testimonials',
|
||||||
|
|||||||
@@ -219,6 +219,11 @@ export const homeFields: Field[] = [
|
|||||||
fields: [
|
fields: [
|
||||||
text('eyebrow', 'Eyebrow', homeContent.testimonials.eyebrow),
|
text('eyebrow', 'Eyebrow', homeContent.testimonials.eyebrow),
|
||||||
textarea('heading', 'Heading', homeContent.testimonials.heading),
|
textarea('heading', 'Heading', homeContent.testimonials.heading),
|
||||||
|
textarea('desktopHeading', 'Desktop heading', homeContent.testimonials.desktopHeading),
|
||||||
|
text('yearPrefix', 'Award year prefix', homeContent.testimonials.yearPrefix),
|
||||||
|
text('previousLabel', 'Previous button label', homeContent.testimonials.previousLabel),
|
||||||
|
text('nextLabel', 'Next button label', homeContent.testimonials.nextLabel),
|
||||||
|
text('slideLabelPrefix', 'Slide dot label prefix', homeContent.testimonials.slideLabelPrefix),
|
||||||
{
|
{
|
||||||
name: 'items',
|
name: 'items',
|
||||||
label: 'Testimonials',
|
label: 'Testimonials',
|
||||||
|
|||||||
@@ -354,6 +354,11 @@ export interface Page {
|
|||||||
testimonials?: {
|
testimonials?: {
|
||||||
eyebrow?: string | null;
|
eyebrow?: string | null;
|
||||||
heading?: string | null;
|
heading?: string | null;
|
||||||
|
desktopHeading?: string | null;
|
||||||
|
yearPrefix?: string | null;
|
||||||
|
previousLabel?: string | null;
|
||||||
|
nextLabel?: string | null;
|
||||||
|
slideLabelPrefix?: string | null;
|
||||||
items?:
|
items?:
|
||||||
| {
|
| {
|
||||||
image?: (number | null) | Media;
|
image?: (number | null) | Media;
|
||||||
@@ -1228,6 +1233,11 @@ export interface Page {
|
|||||||
testimonials?: {
|
testimonials?: {
|
||||||
eyebrow?: string | null;
|
eyebrow?: string | null;
|
||||||
heading?: string | null;
|
heading?: string | null;
|
||||||
|
desktopHeading?: string | null;
|
||||||
|
yearPrefix?: string | null;
|
||||||
|
previousLabel?: string | null;
|
||||||
|
nextLabel?: string | null;
|
||||||
|
slideLabelPrefix?: string | null;
|
||||||
items?:
|
items?:
|
||||||
| {
|
| {
|
||||||
image?: (number | null) | Media;
|
image?: (number | null) | Media;
|
||||||
@@ -3339,6 +3349,11 @@ export interface PagesSelect<T extends boolean = true> {
|
|||||||
| {
|
| {
|
||||||
eyebrow?: T;
|
eyebrow?: T;
|
||||||
heading?: T;
|
heading?: T;
|
||||||
|
desktopHeading?: T;
|
||||||
|
yearPrefix?: T;
|
||||||
|
previousLabel?: T;
|
||||||
|
nextLabel?: T;
|
||||||
|
slideLabelPrefix?: T;
|
||||||
items?:
|
items?:
|
||||||
| T
|
| T
|
||||||
| {
|
| {
|
||||||
@@ -4069,6 +4084,11 @@ export interface PagesSelect<T extends boolean = true> {
|
|||||||
| {
|
| {
|
||||||
eyebrow?: T;
|
eyebrow?: T;
|
||||||
heading?: T;
|
heading?: T;
|
||||||
|
desktopHeading?: T;
|
||||||
|
yearPrefix?: T;
|
||||||
|
previousLabel?: T;
|
||||||
|
nextLabel?: T;
|
||||||
|
slideLabelPrefix?: T;
|
||||||
items?:
|
items?:
|
||||||
| T
|
| T
|
||||||
| {
|
| {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { testimonialsContent } from '@/spa/testimonialsContent'
|
||||||
|
|
||||||
export const aboutContent = {
|
export const aboutContent = {
|
||||||
hero: {
|
hero: {
|
||||||
backgroundImageFilename: 'saal-leer-atmosphaere.jpg',
|
backgroundImageFilename: 'saal-leer-atmosphaere.jpg',
|
||||||
@@ -49,52 +51,7 @@ export const aboutContent = {
|
|||||||
year: 2025,
|
year: 2025,
|
||||||
selectedWinners: [],
|
selectedWinners: [],
|
||||||
},
|
},
|
||||||
testimonials: {
|
testimonials: testimonialsContent,
|
||||||
eyebrow: 'Stimmen der Preisträger',
|
|
||||||
heading: 'DAS SAGEN UNSERE\nPREISTRÄGER.',
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
imageUrl: 'https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?auto=format&fit=crop&q=80&w=600',
|
|
||||||
name: 'Dr. Maria Huber',
|
|
||||||
role: 'Geschäftsführerin',
|
|
||||||
company: 'TechVision GmbH',
|
|
||||||
year: '2025',
|
|
||||||
quote: 'Der BMP hat uns neue Türen geöffnet. Die Auszeichnung ist ein wichtiges Qualitätssiegel für unser gesamtes Team.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageUrl: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?auto=format&fit=crop&q=80&w=600',
|
|
||||||
name: 'Hannes Weber',
|
|
||||||
role: 'Inhaber & CEO',
|
|
||||||
company: 'Weber Präzision GmbH',
|
|
||||||
year: '2023',
|
|
||||||
quote: 'Der Gewinn war ein Moment des Stolzes für die gesamte Belegschaft. Die höchste Anerkennung für unsere tägliche Arbeit.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageUrl: 'https://images.unsplash.com/photo-1580489944761-15a19d654956?auto=format&fit=crop&q=80&w=600',
|
|
||||||
name: 'Lisa Berger',
|
|
||||||
role: 'Gründerin & CEO',
|
|
||||||
company: 'EcoTech Bavaria',
|
|
||||||
year: '2024',
|
|
||||||
quote: 'Das Netzwerk, das wir durch den BMP gewonnen haben, ist unbezahlbar. Wir fanden Partner, die unsere Werte teilen.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageUrl: 'https://images.unsplash.com/photo-1560250097-0b93528c311a?auto=format&fit=crop&q=80&w=600',
|
|
||||||
name: 'Dr. Michael Schuh',
|
|
||||||
role: 'Vorstand',
|
|
||||||
company: 'Bayerischer Maschinenbau',
|
|
||||||
year: '2024',
|
|
||||||
quote: 'Der Preis hat unsere Sichtbarkeit weit über die bayerischen Grenzen hinaus gestärkt. Ein echtes Premium-Siegel.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageUrl: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?auto=format&fit=crop&q=80&w=600',
|
|
||||||
name: 'Anna Kellner',
|
|
||||||
role: 'Mitgründerin',
|
|
||||||
company: 'AlpinTech Solutions',
|
|
||||||
year: '2024',
|
|
||||||
quote: 'Der BMP hat unsere Employer Brand transformiert. Wir gewinnen heute die besten Talente, weil wir Preisträger sind.',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
history: {
|
history: {
|
||||||
eyebrow: 'Geschichte & Meilensteine',
|
eyebrow: 'Geschichte & Meilensteine',
|
||||||
heading: '20 JAHRE\nMITTELSTANDSEXZELLENZ',
|
heading: '20 JAHRE\nMITTELSTANDSEXZELLENZ',
|
||||||
|
|||||||
@@ -4,17 +4,10 @@ import MunichSkylineBg from '@/spa/components/ui/munich-skyline-bg';
|
|||||||
import { useIsMobile } from '@/spa/hooks/useIsMobile';
|
import { useIsMobile } from '@/spa/hooks/useIsMobile';
|
||||||
import Image from '@/spa/components/ui/UnoptimizedImage'
|
import Image from '@/spa/components/ui/UnoptimizedImage'
|
||||||
import { mediaUrl } from '@/spa/cmsMediaField'
|
import { mediaUrl } from '@/spa/cmsMediaField'
|
||||||
|
import { testimonialsContent } from '@/spa/testimonialsContent'
|
||||||
|
|
||||||
const FF = '"IBM Plex Sans", sans-serif';
|
const FF = '"IBM Plex Sans", sans-serif';
|
||||||
|
|
||||||
export const TESTIMONIALS = [
|
|
||||||
{ img: "https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?auto=format&fit=crop&q=80&w=600", name: "Dr. Maria Huber", role: "Geschäftsführerin", company: "TechVision GmbH", year: "2025", quote: "Der BMP hat uns neue Türen geöffnet. Die Auszeichnung ist ein wichtiges Qualitätssiegel für unser gesamtes Team." },
|
|
||||||
{ img: "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?auto=format&fit=crop&q=80&w=600", name: "Hannes Weber", role: "Inhaber & CEO", company: "Weber Präzision GmbH", year: "2023", quote: "Der Gewinn war ein Moment des Stolzes für die gesamte Belegschaft. Die höchste Anerkennung für unsere tägliche Arbeit." },
|
|
||||||
{ img: "https://images.unsplash.com/photo-1580489944761-15a19d654956?auto=format&fit=crop&q=80&w=600", name: "Lisa Berger", role: "Gründerin & CEO", company: "EcoTech Bavaria", year: "2024", quote: "Das Netzwerk, das wir durch den BMP gewonnen haben, ist unbezahlbar. Wir fanden Partner, die unsere Werte teilen." },
|
|
||||||
{ img: "https://images.unsplash.com/photo-1560250097-0b93528c311a?auto=format&fit=crop&q=80&w=600", name: "Dr. Michael Schuh", role: "Vorstand", company: "Bayerischer Maschinenbau", year: "2024", quote: "Der Preis hat unsere Sichtbarkeit weit über die bayerischen Grenzen hinaus gestärkt. Ein echtes Premium-Siegel." },
|
|
||||||
{ img: "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?auto=format&fit=crop&q=80&w=600", name: "Anna Kellner", role: "Mitgründerin", company: "AlpinTech Solutions", year: "2024", quote: "Der BMP hat unsere Employer Brand transformiert. Wir gewinnen heute die besten Talente, weil wir Preisträger sind." },
|
|
||||||
];
|
|
||||||
|
|
||||||
type TestimonialItem = {
|
type TestimonialItem = {
|
||||||
img: string
|
img: string
|
||||||
name: string
|
name: string
|
||||||
@@ -27,7 +20,12 @@ type TestimonialItem = {
|
|||||||
type TestimonialsCms = {
|
type TestimonialsCms = {
|
||||||
eyebrow?: string | null
|
eyebrow?: string | null
|
||||||
heading?: string | null
|
heading?: string | null
|
||||||
items?: Array<Record<string, any>> | null
|
desktopHeading?: string | null
|
||||||
|
yearPrefix?: string | null
|
||||||
|
previousLabel?: string | null
|
||||||
|
nextLabel?: string | null
|
||||||
|
slideLabelPrefix?: string | null
|
||||||
|
items?: Array<Record<string, unknown>> | null
|
||||||
}
|
}
|
||||||
|
|
||||||
const fallbackText = (value: unknown, fallback: string) =>
|
const fallbackText = (value: unknown, fallback: string) =>
|
||||||
@@ -40,15 +38,29 @@ function Lines({ text }: { text: string }) {
|
|||||||
export default function TestimonialsSection({ data }: { data?: TestimonialsCms }) {
|
export default function TestimonialsSection({ data }: { data?: TestimonialsCms }) {
|
||||||
const [active, setActive] = useState(0);
|
const [active, setActive] = useState(0);
|
||||||
const testimonials: TestimonialItem[] = data?.items?.length ? data.items.map((item) => ({
|
const testimonials: TestimonialItem[] = data?.items?.length ? data.items.map((item) => ({
|
||||||
img: mediaUrl(item.image, item.imageUrl || item.img || ''),
|
img: mediaUrl(item.image, fallbackText(item.imageUrl, fallbackText(item.img, ''))),
|
||||||
name: fallbackText(item.name, ''),
|
name: fallbackText(item.name, ''),
|
||||||
role: fallbackText(item.role, ''),
|
role: fallbackText(item.role, ''),
|
||||||
company: fallbackText(item.company, ''),
|
company: fallbackText(item.company, ''),
|
||||||
year: fallbackText(item.year, ''),
|
year: fallbackText(item.year, ''),
|
||||||
quote: fallbackText(item.quote, ''),
|
quote: fallbackText(item.quote, ''),
|
||||||
})) : TESTIMONIALS;
|
})) : testimonialsContent.items.map((item) => ({
|
||||||
|
img: item.imageUrl,
|
||||||
|
name: item.name,
|
||||||
|
role: item.role,
|
||||||
|
company: item.company,
|
||||||
|
year: item.year,
|
||||||
|
quote: item.quote,
|
||||||
|
}));
|
||||||
const t = testimonials[active] || testimonials[0];
|
const t = testimonials[active] || testimonials[0];
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
|
const eyebrow = fallbackText(data?.eyebrow, testimonialsContent.eyebrow);
|
||||||
|
const heading = fallbackText(data?.heading, testimonialsContent.heading);
|
||||||
|
const desktopHeading = fallbackText(data?.desktopHeading, testimonialsContent.desktopHeading);
|
||||||
|
const yearPrefix = fallbackText(data?.yearPrefix, testimonialsContent.yearPrefix);
|
||||||
|
const previousLabel = fallbackText(data?.previousLabel, testimonialsContent.previousLabel);
|
||||||
|
const nextLabel = fallbackText(data?.nextLabel, testimonialsContent.nextLabel);
|
||||||
|
const slideLabelPrefix = fallbackText(data?.slideLabelPrefix, testimonialsContent.slideLabelPrefix);
|
||||||
|
|
||||||
const prev = () => setActive(i => (i - 1 + testimonials.length) % testimonials.length);
|
const prev = () => setActive(i => (i - 1 + testimonials.length) % testimonials.length);
|
||||||
const next = () => setActive(i => (i + 1) % testimonials.length);
|
const next = () => setActive(i => (i + 1) % testimonials.length);
|
||||||
@@ -60,9 +72,9 @@ export default function TestimonialsSection({ data }: { data?: TestimonialsCms }
|
|||||||
{isMobile && (
|
{isMobile && (
|
||||||
<div style={{ padding: '48px 24px 52px', position: 'relative', zIndex: 1 }}>
|
<div style={{ padding: '48px 24px 52px', position: 'relative', zIndex: 1 }}>
|
||||||
{/* Section header */}
|
{/* Section header */}
|
||||||
<span style={{ fontFamily: FF, fontSize: 10, color: '#4A8FC9', textTransform: 'uppercase', letterSpacing: '0.3em', fontWeight: 700, display: 'block', marginBottom: 14 }}>{fallbackText(data?.eyebrow, 'Stimmen der Preisträger')}</span>
|
<span style={{ fontFamily: FF, fontSize: 10, color: '#4A8FC9', textTransform: 'uppercase', letterSpacing: '0.3em', fontWeight: 700, display: 'block', marginBottom: 14 }}>{eyebrow}</span>
|
||||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(1.8rem, 8vw, 2.3rem)', fontWeight: 900, color: '#101828', textTransform: 'uppercase', letterSpacing: '-0.025em', lineHeight: 1.04, margin: '0 0 16px' }}>
|
<h2 style={{ fontFamily: FF, fontSize: 'clamp(1.8rem, 8vw, 2.3rem)', fontWeight: 900, color: '#101828', textTransform: 'uppercase', letterSpacing: '-0.025em', lineHeight: 1.04, margin: '0 0 16px' }}>
|
||||||
<Lines text={fallbackText(data?.heading, 'DAS SAGEN UNSERE\nPREISTRÄGER.')} />
|
<Lines text={heading} />
|
||||||
</h2>
|
</h2>
|
||||||
<div style={{ width: 40, height: 2, background: '#EFBF04', marginBottom: 28 }} />
|
<div style={{ width: 40, height: 2, background: '#EFBF04', marginBottom: 28 }} />
|
||||||
|
|
||||||
@@ -72,7 +84,7 @@ export default function TestimonialsSection({ data }: { data?: TestimonialsCms }
|
|||||||
<div style={{ position: 'relative', height: 240, overflow: 'hidden' }}>
|
<div style={{ position: 'relative', height: 240, overflow: 'hidden' }}>
|
||||||
<Image unoptimized key={t.img} src={t.img} alt={t.name} style={{ width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'top', display: 'block' }} />
|
<Image unoptimized key={t.img} src={t.img} alt={t.name} style={{ width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'top', display: 'block' }} />
|
||||||
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to top, rgba(3,9,58,0.28) 0%, transparent 45%)' }} />
|
<div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to top, rgba(3,9,58,0.28) 0%, transparent 45%)' }} />
|
||||||
<span style={{ position: 'absolute', top: 14, left: 14, fontFamily: FF, fontSize: 9, fontWeight: 700, letterSpacing: '0.16em', textTransform: 'uppercase', color: '#101828', background: '#EFBF04', padding: '5px 10px', borderRadius: 100 }}>Preisträger {t.year}</span>
|
<span style={{ position: 'absolute', top: 14, left: 14, fontFamily: FF, fontSize: 9, fontWeight: 700, letterSpacing: '0.16em', textTransform: 'uppercase', color: '#101828', background: '#EFBF04', padding: '5px 10px', borderRadius: 100 }}>{yearPrefix} {t.year}</span>
|
||||||
</div>
|
</div>
|
||||||
{/* Body */}
|
{/* Body */}
|
||||||
<div style={{ padding: '22px 22px 24px' }}>
|
<div style={{ padding: '22px 22px 24px' }}>
|
||||||
@@ -86,15 +98,15 @@ export default function TestimonialsSection({ data }: { data?: TestimonialsCms }
|
|||||||
|
|
||||||
{/* Controls */}
|
{/* Controls */}
|
||||||
<div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 24 }}>
|
<div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 24 }}>
|
||||||
<button onClick={prev} aria-label="Vorheriges" style={{ width: 46, height: 46, borderRadius: 12, border: '1.5px solid #D0D5DD', background: 'transparent', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
|
<button onClick={prev} aria-label={previousLabel} style={{ width: 46, height: 46, borderRadius: 12, border: '1.5px solid #D0D5DD', background: 'transparent', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
|
||||||
<ChevronRight size={16} style={{ transform: 'rotate(180deg)' }} />
|
<ChevronRight size={16} style={{ transform: 'rotate(180deg)' }} />
|
||||||
</button>
|
</button>
|
||||||
<button onClick={next} aria-label="Nächstes" style={{ width: 46, height: 46, borderRadius: 12, border: '1.5px solid #111D55', background: '#111D55', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', flexShrink: 0 }}>
|
<button onClick={next} aria-label={nextLabel} style={{ width: 46, height: 46, borderRadius: 12, border: '1.5px solid #111D55', background: '#111D55', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', flexShrink: 0 }}>
|
||||||
<ChevronRight size={16} />
|
<ChevronRight size={16} />
|
||||||
</button>
|
</button>
|
||||||
<div style={{ display: 'flex', gap: 6, marginLeft: 6 }}>
|
<div style={{ display: 'flex', gap: 6, marginLeft: 6 }}>
|
||||||
{testimonials.map((_, i) => (
|
{testimonials.map((_, i) => (
|
||||||
<button key={i} onClick={() => setActive(i)} aria-label={`Stimme ${i + 1}`} style={{ width: i === active ? 22 : 7, height: 7, borderRadius: 100, background: i === active ? '#EFBF04' : '#D0D5DD', border: 'none', cursor: 'pointer', padding: 0, transition: 'all 0.2s' }} />
|
<button key={i} onClick={() => setActive(i)} aria-label={`${slideLabelPrefix} ${i + 1}`} style={{ width: i === active ? 22 : 7, height: 7, borderRadius: 100, background: i === active ? '#EFBF04' : '#D0D5DD', border: 'none', cursor: 'pointer', padding: 0, transition: 'all 0.2s' }} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -117,10 +129,10 @@ export default function TestimonialsSection({ data }: { data?: TestimonialsCms }
|
|||||||
|
|
||||||
{/* Right – quote */}
|
{/* Right – quote */}
|
||||||
<div style={{ padding: isMobile ? '40px 22px 56px' : '80px 72px 80px 56px', display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
|
<div style={{ padding: isMobile ? '40px 22px 56px' : '80px 72px 80px 56px', display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
|
||||||
<span style={{ fontFamily: FF, fontSize: 10, color: '#4A8FC9', textTransform: 'uppercase', letterSpacing: '0.3em', fontWeight: 700, display: 'block', marginBottom: 14 }}>{fallbackText(data?.eyebrow, 'Stimmen der Preisträger')}</span>
|
<span style={{ fontFamily: FF, fontSize: 10, color: '#4A8FC9', textTransform: 'uppercase', letterSpacing: '0.3em', fontWeight: 700, display: 'block', marginBottom: 14 }}>{eyebrow}</span>
|
||||||
|
|
||||||
<h2 style={{ fontFamily: FF, fontSize: 'clamp(1.8rem, 2.6vw, 2.6rem)', fontWeight: 900, color: '#101828', textTransform: 'uppercase', letterSpacing: '-0.025em', lineHeight: 1.04, margin: '0 0 36px' }}>
|
<h2 style={{ fontFamily: FF, fontSize: 'clamp(1.8rem, 2.6vw, 2.6rem)', fontWeight: 900, color: '#101828', textTransform: 'uppercase', letterSpacing: '-0.025em', lineHeight: 1.04, margin: '0 0 36px' }}>
|
||||||
<Lines text={fallbackText(data?.heading, 'DAS SAGEN UNSERE PREISTRÄGER.')} />
|
<Lines text={desktopHeading} />
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p style={{ fontFamily: FF, fontSize: 'clamp(1.4rem, 2.2vw, 2rem)', fontWeight: 300, color: '#101828', lineHeight: 1.55, margin: '0 0 40px' }}>
|
<p style={{ fontFamily: FF, fontSize: 'clamp(1.4rem, 2.2vw, 2rem)', fontWeight: 300, color: '#101828', lineHeight: 1.55, margin: '0 0 40px' }}>
|
||||||
@@ -131,17 +143,17 @@ export default function TestimonialsSection({ data }: { data?: TestimonialsCms }
|
|||||||
<div>
|
<div>
|
||||||
<div style={{ fontFamily: FF, fontSize: 15, fontWeight: 700, color: '#101828', marginBottom: 4 }}>{t.name}</div>
|
<div style={{ fontFamily: FF, fontSize: 15, fontWeight: 700, color: '#101828', marginBottom: 4 }}>{t.name}</div>
|
||||||
<div style={{ fontFamily: FF, fontSize: 12, color: 'rgba(16,24,40,0.5)' }}>{t.role} · {t.company}</div>
|
<div style={{ fontFamily: FF, fontSize: 12, color: 'rgba(16,24,40,0.5)' }}>{t.role} · {t.company}</div>
|
||||||
<div style={{ fontFamily: FF, fontSize: 11, fontWeight: 700, color: '#4A8FC9', letterSpacing: '0.1em', textTransform: 'uppercase', marginTop: 4 }}>Preisträger {t.year}</div>
|
<div style={{ fontFamily: FF, fontSize: 11, fontWeight: 700, color: '#4A8FC9', letterSpacing: '0.1em', textTransform: 'uppercase', marginTop: 4 }}>{yearPrefix} {t.year}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 40 }}>
|
<div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 40 }}>
|
||||||
<button onClick={prev} style={{ width: isMobile ? 44 : 40, height: isMobile ? 44 : 40, border: '1.5px solid #D0D5DD', background: 'transparent', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'all 0.15s' }}
|
<button onClick={prev} aria-label={previousLabel} style={{ width: isMobile ? 44 : 40, height: isMobile ? 44 : 40, border: '1.5px solid #D0D5DD', background: 'transparent', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'all 0.15s' }}
|
||||||
onMouseEnter={e => { (e.currentTarget as HTMLElement).style.borderColor = '#111D55'; (e.currentTarget as HTMLElement).style.background = '#111D55'; (e.currentTarget as HTMLElement).style.color = '#fff'; }}
|
onMouseEnter={e => { (e.currentTarget as HTMLElement).style.borderColor = '#111D55'; (e.currentTarget as HTMLElement).style.background = '#111D55'; (e.currentTarget as HTMLElement).style.color = '#fff'; }}
|
||||||
onMouseLeave={e => { (e.currentTarget as HTMLElement).style.borderColor = '#D0D5DD'; (e.currentTarget as HTMLElement).style.background = 'transparent'; (e.currentTarget as HTMLElement).style.color = 'inherit'; }}
|
onMouseLeave={e => { (e.currentTarget as HTMLElement).style.borderColor = '#D0D5DD'; (e.currentTarget as HTMLElement).style.background = 'transparent'; (e.currentTarget as HTMLElement).style.color = 'inherit'; }}
|
||||||
>
|
>
|
||||||
<ChevronRight size={16} style={{ transform: 'rotate(180deg)' }} />
|
<ChevronRight size={16} style={{ transform: 'rotate(180deg)' }} />
|
||||||
</button>
|
</button>
|
||||||
<button onClick={next} style={{ width: isMobile ? 44 : 40, height: isMobile ? 44 : 40, border: '1.5px solid #111D55', background: '#111D55', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'all 0.15s', color: '#fff' }}
|
<button onClick={next} aria-label={nextLabel} style={{ width: isMobile ? 44 : 40, height: isMobile ? 44 : 40, border: '1.5px solid #111D55', background: '#111D55', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'all 0.15s', color: '#fff' }}
|
||||||
onMouseEnter={e => { (e.currentTarget as HTMLElement).style.background = '#EFBF04'; (e.currentTarget as HTMLElement).style.borderColor = '#EFBF04'; }}
|
onMouseEnter={e => { (e.currentTarget as HTMLElement).style.background = '#EFBF04'; (e.currentTarget as HTMLElement).style.borderColor = '#EFBF04'; }}
|
||||||
onMouseLeave={e => { (e.currentTarget as HTMLElement).style.background = '#111D55'; (e.currentTarget as HTMLElement).style.borderColor = '#111D55'; }}
|
onMouseLeave={e => { (e.currentTarget as HTMLElement).style.background = '#111D55'; (e.currentTarget as HTMLElement).style.borderColor = '#111D55'; }}
|
||||||
>
|
>
|
||||||
@@ -149,7 +161,7 @@ export default function TestimonialsSection({ data }: { data?: TestimonialsCms }
|
|||||||
</button>
|
</button>
|
||||||
<div style={{ display: 'flex', gap: 6, marginLeft: 8 }}>
|
<div style={{ display: 'flex', gap: 6, marginLeft: 8 }}>
|
||||||
{testimonials.map((_, i) => (
|
{testimonials.map((_, i) => (
|
||||||
<button key={i} onClick={() => setActive(i)} style={{ width: i === active ? 20 : 6, height: 6, background: i === active ? '#EFBF04' : '#D0D5DD', border: 'none', cursor: 'pointer', padding: 0, transition: 'all 0.2s' }} />
|
<button key={i} onClick={() => setActive(i)} aria-label={`${slideLabelPrefix} ${i + 1}`} style={{ width: i === active ? 20 : 6, height: 6, background: i === active ? '#EFBF04' : '#D0D5DD', border: 'none', cursor: 'pointer', padding: 0, transition: 'all 0.2s' }} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { participationContent } from '@/spa/participationContent'
|
import { participationContent } from '@/spa/participationContent'
|
||||||
|
import { testimonialsContent } from '@/spa/testimonialsContent'
|
||||||
|
|
||||||
export const homeContent = {
|
export const homeContent = {
|
||||||
hero: {
|
hero: {
|
||||||
@@ -122,53 +123,7 @@ export const homeContent = {
|
|||||||
cardFallbackTitle: 'Preisträger',
|
cardFallbackTitle: 'Preisträger',
|
||||||
hoverLabel: 'Detail →',
|
hoverLabel: 'Detail →',
|
||||||
},
|
},
|
||||||
testimonials: {
|
testimonials: testimonialsContent,
|
||||||
eyebrow: 'Stimmen der Preisträger',
|
|
||||||
heading: 'DAS SAGEN UNSERE\nPREISTRÄGER.',
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
imageUrl: 'https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?auto=format&fit=crop&q=80&w=600',
|
|
||||||
name: 'Dr. Maria Huber',
|
|
||||||
role: 'Geschäftsführerin',
|
|
||||||
company: 'TechVision GmbH',
|
|
||||||
year: '2025',
|
|
||||||
quote: 'Der BMP hat uns neue Türen geöffnet. Die Auszeichnung ist ein wichtiges Qualitätssiegel für unser gesamtes Team.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageUrl: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?auto=format&fit=crop&q=80&w=600',
|
|
||||||
name: 'Hannes Weber',
|
|
||||||
role: 'Inhaber & CEO',
|
|
||||||
company: 'Weber Präzision GmbH',
|
|
||||||
year: '2023',
|
|
||||||
quote: 'Der Gewinn war ein Moment des Stolzes für die gesamte Belegschaft. Die höchste Anerkennung für unsere tägliche Arbeit.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageUrl: 'https://images.unsplash.com/photo-1580489944761-15a19d654956?auto=format&fit=crop&q=80&w=600',
|
|
||||||
name: 'Lisa Berger',
|
|
||||||
role: 'Gründerin & CEO',
|
|
||||||
company: 'EcoTech Bavaria',
|
|
||||||
year: '2024',
|
|
||||||
quote: 'Das Netzwerk, das wir durch den BMP gewonnen haben, ist unbezahlbar. Wir fanden Partner, die unsere Werte teilen.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageUrl: 'https://images.unsplash.com/photo-1560250097-0b93528c311a?auto=format&fit=crop&q=80&w=600',
|
|
||||||
name: 'Dr. Michael Schuh',
|
|
||||||
role: 'Vorstand',
|
|
||||||
company: 'Bayerischer Maschinenbau',
|
|
||||||
year: '2024',
|
|
||||||
quote: 'Der Preis hat unsere Sichtbarkeit weit über die bayerischen Grenzen hinaus gestärkt. Ein echtes Premium-Siegel.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
imageUrl: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?auto=format&fit=crop&q=80&w=600',
|
|
||||||
name: 'Anna Kellner',
|
|
||||||
role: 'Mitgründerin',
|
|
||||||
company: 'AlpinTech Solutions',
|
|
||||||
year: '2024',
|
|
||||||
quote:
|
|
||||||
'Der BMP hat unsere Employer Brand transformiert. Wir gewinnen heute die besten Talente, weil wir Preisträger sind.',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
benefits: {
|
benefits: {
|
||||||
eyebrow: 'Mehr als nur ein Preis',
|
eyebrow: 'Mehr als nur ein Preis',
|
||||||
heading: 'WARUM SICH DIE\nTEILNAHME LOHNT.',
|
heading: 'WARUM SICH DIE\nTEILNAHME LOHNT.',
|
||||||
|
|||||||
53
src/spa/testimonialsContent.ts
Normal file
53
src/spa/testimonialsContent.ts
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
export const testimonialsContent = {
|
||||||
|
eyebrow: 'Stimmen der Preisträger',
|
||||||
|
heading: 'DAS SAGEN UNSERE\nPREISTRÄGER.',
|
||||||
|
desktopHeading: 'DAS SAGEN UNSERE PREISTRÄGER.',
|
||||||
|
yearPrefix: 'Preisträger',
|
||||||
|
previousLabel: 'Vorheriges',
|
||||||
|
nextLabel: 'Nächstes',
|
||||||
|
slideLabelPrefix: 'Stimme',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
imageUrl: 'https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?auto=format&fit=crop&q=80&w=600',
|
||||||
|
name: 'Dr. Maria Huber',
|
||||||
|
role: 'Geschäftsführerin',
|
||||||
|
company: 'TechVision GmbH',
|
||||||
|
year: '2025',
|
||||||
|
quote: 'Der BMP hat uns neue Türen geöffnet. Die Auszeichnung ist ein wichtiges Qualitätssiegel für unser gesamtes Team.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
imageUrl: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?auto=format&fit=crop&q=80&w=600',
|
||||||
|
name: 'Hannes Weber',
|
||||||
|
role: 'Inhaber & CEO',
|
||||||
|
company: 'Weber Präzision GmbH',
|
||||||
|
year: '2023',
|
||||||
|
quote: 'Der Gewinn war ein Moment des Stolzes für die gesamte Belegschaft. Die höchste Anerkennung für unsere tägliche Arbeit.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
imageUrl: 'https://images.unsplash.com/photo-1580489944761-15a19d654956?auto=format&fit=crop&q=80&w=600',
|
||||||
|
name: 'Lisa Berger',
|
||||||
|
role: 'Gründerin & CEO',
|
||||||
|
company: 'EcoTech Bavaria',
|
||||||
|
year: '2024',
|
||||||
|
quote: 'Das Netzwerk, das wir durch den BMP gewonnen haben, ist unbezahlbar. Wir fanden Partner, die unsere Werte teilen.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
imageUrl: 'https://images.unsplash.com/photo-1560250097-0b93528c311a?auto=format&fit=crop&q=80&w=600',
|
||||||
|
name: 'Dr. Michael Schuh',
|
||||||
|
role: 'Vorstand',
|
||||||
|
company: 'Bayerischer Maschinenbau',
|
||||||
|
year: '2024',
|
||||||
|
quote: 'Der Preis hat unsere Sichtbarkeit weit über die bayerischen Grenzen hinaus gestärkt. Ein echtes Premium-Siegel.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
imageUrl: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?auto=format&fit=crop&q=80&w=600',
|
||||||
|
name: 'Anna Kellner',
|
||||||
|
role: 'Mitgründerin',
|
||||||
|
company: 'AlpinTech Solutions',
|
||||||
|
year: '2024',
|
||||||
|
quote:
|
||||||
|
'Der BMP hat unsere Employer Brand transformiert. Wir gewinnen heute die besten Talente, weil wir Preisträger sind.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user