107 lines
3.5 KiB
TypeScript
107 lines
3.5 KiB
TypeScript
'use client';
|
|
|
|
import * as React from 'react';
|
|
import { motion, Variants } from 'framer-motion';
|
|
import Image from 'next/image';
|
|
import Link from 'next/link';
|
|
|
|
interface SubCompanyTilesProps {
|
|
badge?: string;
|
|
title?: string;
|
|
companies?: {
|
|
title?: string;
|
|
description?: string;
|
|
icon?: string;
|
|
url?: string;
|
|
backgroundImage?: {
|
|
url?: string;
|
|
alt?: string;
|
|
} | any;
|
|
}[];
|
|
data?: any;
|
|
}
|
|
|
|
const defaultCompanies = [
|
|
{
|
|
title: 'E-TIB GmbH',
|
|
icon: 'M13 10V3L4 14h7v7l9-11h-7z',
|
|
url: 'https://www.e-tib.com/',
|
|
},
|
|
{
|
|
title: 'E-TIB Ingenieurgesellschaft mbH',
|
|
icon: 'M14 2H6a2 2 0 0 0-2 2v16c0 1.1.9 2 2 2h12a2 2 0 0 0 2-2V8l-6-6z M14 3v5h5 M16 13H8 M16 17H8 M10 9H8',
|
|
url: 'https://www.etib-ing.com/',
|
|
},
|
|
{
|
|
title: 'NEMO GmbH',
|
|
icon: 'M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z',
|
|
url: 'https://www.nemo-gmbh.de/',
|
|
}
|
|
];
|
|
|
|
const containerVariants: Variants = {
|
|
hidden: { opacity: 0 },
|
|
visible: {
|
|
opacity: 1,
|
|
transition: {
|
|
staggerChildren: 0.1,
|
|
},
|
|
},
|
|
};
|
|
|
|
const itemVariants: Variants = {
|
|
hidden: { opacity: 0, y: 15 },
|
|
visible: { opacity: 1, y: 0, transition: { duration: 0.5, ease: [0.16, 1, 0.3, 1] } },
|
|
};
|
|
|
|
export function SubCompanyTiles(props: SubCompanyTilesProps) {
|
|
const { data } = props;
|
|
const rawCompanies = props.companies || data?.companies;
|
|
const companiesData = rawCompanies?.map((c: any) => ({
|
|
title: c.title,
|
|
url: c.url,
|
|
icon: c.icon || 'M13 10V3L4 14h7v7l9-11h-7z',
|
|
})) || defaultCompanies;
|
|
|
|
return (
|
|
<section id="unternehmen" className="py-8 bg-neutral-50 border-b border-neutral-100">
|
|
<div className="container relative z-10">
|
|
<motion.div
|
|
className="grid grid-cols-1 md:grid-cols-3 gap-6"
|
|
variants={containerVariants}
|
|
initial="hidden"
|
|
whileInView="visible"
|
|
viewport={{ once: true, margin: "-50px" }}
|
|
>
|
|
{companiesData.map((company: any, index: number) => {
|
|
const CardWrapper = company.url ? 'a' : 'div';
|
|
const wrapperProps = company.url ? { href: company.url, target: "_blank", rel: "noopener noreferrer" } : {};
|
|
|
|
return (
|
|
<motion.div
|
|
key={index}
|
|
variants={itemVariants}
|
|
className="h-full"
|
|
>
|
|
<CardWrapper
|
|
{...wrapperProps}
|
|
className="group flex items-center justify-center gap-4 bg-white rounded-xl p-6 shadow-sm border border-neutral-100 transition-all duration-300 hover:shadow-md hover:border-primary/30 cursor-pointer h-full"
|
|
>
|
|
<div className="w-10 h-10 shrink-0 text-primary group-hover:scale-110 transition-transform duration-300 flex items-center justify-center">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
|
<path d={company.icon} />
|
|
</svg>
|
|
</div>
|
|
<h4 className="font-heading font-bold text-lg text-neutral-dark group-hover:text-primary transition-colors">
|
|
{company.title}
|
|
</h4>
|
|
</CardWrapper>
|
|
</motion.div>
|
|
);
|
|
})}
|
|
</motion.div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|