201 lines
7.1 KiB
TypeScript
201 lines
7.1 KiB
TypeScript
import speaker1 from "../assets/speakers/speaker1.jpg";
|
|
import speaker2 from "../assets/speakers/speaker2.jpg";
|
|
import speaker3 from "../assets/speakers/speaker3.jpg";
|
|
import speaker4 from "../assets/speakers/speaker4.jpg";
|
|
import { BiLogoLinkedinSquare } from "react-icons/bi";
|
|
|
|
type ImageProps = {
|
|
src: string;
|
|
alt?: string;
|
|
};
|
|
|
|
type SocialLink = {
|
|
href: string;
|
|
icon: React.ReactNode;
|
|
};
|
|
|
|
type Talk = {
|
|
title: string;
|
|
type: "Talk" | "Workshop" | "Networking" | "AI and Future" | "Interaction";
|
|
};
|
|
|
|
export type TeamMember = {
|
|
image: ImageProps;
|
|
name: string;
|
|
role: string;
|
|
company: string;
|
|
companyUrl?: string;
|
|
description: string;
|
|
category: string;
|
|
talks: Talk[];
|
|
socialLinks: SocialLink[];
|
|
};
|
|
|
|
type Props = {
|
|
teamMembers: TeamMember[];
|
|
};
|
|
|
|
export type Team4Props = React.ComponentPropsWithoutRef<"section"> & Partial<Props>;
|
|
|
|
const talkBadgeClass = (type: Talk["type"]) => {
|
|
if (type === "Workshop") return "bg-acid-lime text-tech-navy";
|
|
if (type === "Networking") return "bg-acid-lime text-tech-navy";
|
|
return "bg-electric-violet text-cloud-white";
|
|
};
|
|
|
|
const MemberCard = ({ member }: { member: TeamMember }) => (
|
|
<div className="flex flex-col font-barlow">
|
|
<div className="relative mb-5 aspect-square w-full overflow-hidden">
|
|
<img
|
|
src={member.image.src}
|
|
alt={member.image.alt}
|
|
className="absolute inset-0 size-full object-cover"
|
|
/>
|
|
</div>
|
|
<h5 className="text-md font-bold md:text-lg">{member.name}</h5>
|
|
<p className="text-sm text-gray-600">{member.role}</p>
|
|
<a
|
|
href={member.companyUrl ?? "#"}
|
|
className="mb-3 text-sm underline underline-offset-2 text-tech-navy"
|
|
>
|
|
{member.company}
|
|
</a>
|
|
<p className="mb-4 text-sm leading-relaxed text-gray-700">{member.description}</p>
|
|
<div className="mb-4 flex flex-wrap gap-2">
|
|
{member.talks.map((talk, i) => (
|
|
<span
|
|
key={i}
|
|
className={`rounded-full px-3 py-1 text-xs font-semibold ${talkBadgeClass(talk.type)}`}
|
|
>
|
|
{talk.title}
|
|
</span>
|
|
))}
|
|
</div>
|
|
<div className="mt-auto flex gap-3">
|
|
{member.socialLinks.map((link, i) => (
|
|
<a key={i} href={link.href}>
|
|
{link.icon}
|
|
</a>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
export const Team4 = (props: Team4Props) => {
|
|
const { teamMembers } = { ...Team4Defaults, ...props };
|
|
|
|
return (
|
|
<section className="px-[5%] py-16 md:py-24 bg-cloud-white font-barlow">
|
|
<div className="container">
|
|
{teamMembers.length === 0 ? (
|
|
<p className="py-16 text-center text-gray-400">Keine Speaker gefunden.</p>
|
|
) : (
|
|
<div className="grid grid-cols-1 gap-x-8 gap-y-12 sm:grid-cols-2 lg:grid-cols-4">
|
|
{teamMembers.map((member, i) => (
|
|
<MemberCard key={i} member={member} />
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export const Team4Defaults: Props = {
|
|
teamMembers: [
|
|
{
|
|
image: { src: speaker1, alt: "Jens Riegelsberger" },
|
|
name: "Jens Riegelsberger",
|
|
role: "UX Director",
|
|
company: "Google",
|
|
description:
|
|
"Jens leitet die UX-Teams für Search und Maps sowie die globale UXR-Infrastruktur. Der HCI-Experte lehrte als Gastprofessor an der UdK Berlin und bringt Erfahrung von Stationen bei Microsoft Research, Amazon und Apple mit.",
|
|
category: "Research",
|
|
talks: [
|
|
{ title: "Talk: Scaling Research", type: "Talk" },
|
|
{ title: "Workshop: Skalierbare Research-Infrastruktur", type: "Workshop" },
|
|
],
|
|
socialLinks: [{ href: "#", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
|
},
|
|
{
|
|
image: { src: speaker2, alt: "Marcus J. Low" },
|
|
name: "Marcus J. Low",
|
|
role: "Principal Designer",
|
|
company: "Airbnb",
|
|
description:
|
|
"Als Mitentwickler des ersten Airbnb Design Systems spricht Marcus über die Balance zwischen Markenästhetik und funktionaler Logik.",
|
|
category: "Design / UX",
|
|
talks: [{ title: "Workshop: The Future of Tokens", type: "Workshop" }],
|
|
socialLinks: [{ href: "#", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
|
},
|
|
{
|
|
image: { src: speaker3, alt: "Reto Gwerder" },
|
|
name: "Reto Gwerder",
|
|
role: "Head of Product",
|
|
company: "Ginetta",
|
|
description:
|
|
"Reto steht für Schweizer Design-Qualität. Er analysiert, warum Simplizität oft die größte technische Herausforderung ist.",
|
|
category: "Strategie",
|
|
talks: [{ title: "Talk: Simplify or Die", type: "Talk" }],
|
|
socialLinks: [{ href: "#", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
|
},
|
|
{
|
|
image: { src: speaker4, alt: "Dr. Elena Rossi" },
|
|
name: "Dr. Elena Rossi",
|
|
role: "Cognitive Psychologist",
|
|
company: "University of Milan",
|
|
description:
|
|
"Elena verbindet Wissenschaft mit Design. Sie erklärt, wie unser Gehirn auf Micro-Interactions reagiert und wann wir uns manipuliert fühlen.",
|
|
category: "Psychologie",
|
|
talks: [{ title: "Deep Dive: Psychological UX", type: "Talk" }],
|
|
socialLinks: [{ href: "#", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
|
},
|
|
{
|
|
image: { src: speaker1, alt: "Liam O'Connor" },
|
|
name: "Liam O'Connor",
|
|
role: "Lead Product Designer",
|
|
company: "Spotify",
|
|
description:
|
|
"Liam gibt Einblicke, wie Spotify Personalisierung nutzt, ohne die Privatsphäre der Nutzer zu verletzen.",
|
|
category: "AI & Future",
|
|
talks: [{ title: "Talk: Trust in AI UX", type: "Talk" }],
|
|
socialLinks: [{ href: "#", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
|
},
|
|
{
|
|
image: { src: speaker2, alt: "Fabienne Keller" },
|
|
name: "Fabienne Keller",
|
|
role: "Gründerin",
|
|
company: "User-First Agency",
|
|
description:
|
|
"Fabienne ist Expertin für User Research in komplexen B2B-Umfeldern und wie man Stakeholder von Test-Ergebnissen überzeugt.",
|
|
category: "Research",
|
|
talks: [{ title: "Workshop: Research Repositories", type: "Workshop" }],
|
|
socialLinks: [{ href: "#", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
|
},
|
|
{
|
|
image: { src: speaker3, alt: "Thomas Meyer" },
|
|
name: 'Thomas "Tom" Meyer',
|
|
role: "Creative Director",
|
|
company: "Swisscom",
|
|
description:
|
|
"Tom zeigt, wie man in großen Konzernen eine Design-Kultur etabliert, die über das visuelle Layer hinausgeht.",
|
|
category: "Strategie",
|
|
talks: [{ title: "Networking: Leading Teams", type: "Networking" }],
|
|
socialLinks: [{ href: "#", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
|
},
|
|
{
|
|
image: { src: speaker4, alt: "Sarah M. Widmer" },
|
|
name: "Sarah M. Widmer",
|
|
role: "Senior UX Architect",
|
|
company: "SBB",
|
|
description:
|
|
"Sarah gestaltet die Mobilität von morgen. Sie zeigt, wie man Millionen von Nutzern barrierefrei durch den digitalen öV-Dschungel leitet.",
|
|
category: "Design / UX",
|
|
talks: [{ title: "Talk: Inclusive Design at Scale", type: "Talk" }],
|
|
socialLinks: [{ href: "#", icon: <BiLogoLinkedinSquare className="size-6" /> }],
|
|
},
|
|
],
|
|
};
|
|
|
|
export default Team4;
|