Initial commit
This commit is contained in:
190
src/components/sections/team/TeamCardEleven.tsx
Normal file
190
src/components/sections/team/TeamCardEleven.tsx
Normal file
@@ -0,0 +1,190 @@
|
||||
"use client";
|
||||
|
||||
import CardList from "@/components/cardStack/CardList";
|
||||
import MediaContent from "@/components/shared/MediaContent";
|
||||
import { cls, shouldUseInvertedText } from "@/lib/utils";
|
||||
import { useTheme } from "@/providers/themeProvider/ThemeProvider";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
import type { ButtonConfig, CardAnimationType, TitleSegment } from "@/components/cardStack/types";
|
||||
import type { TextboxLayout, InvertedBackground } from "@/providers/themeProvider/config/constants";
|
||||
|
||||
type TeamMember = {
|
||||
id: string;
|
||||
title: string;
|
||||
subtitle: string;
|
||||
detail: string;
|
||||
imageSrc?: string;
|
||||
imageAlt?: string;
|
||||
videoSrc?: string;
|
||||
videoAriaLabel?: string;
|
||||
};
|
||||
|
||||
type TeamGroup = {
|
||||
id: string;
|
||||
groupTitle: string;
|
||||
members: TeamMember[];
|
||||
};
|
||||
|
||||
interface TeamCardElevenProps {
|
||||
groups: TeamGroup[];
|
||||
animationType: CardAnimationType;
|
||||
title: string;
|
||||
titleSegments?: TitleSegment[];
|
||||
description: string;
|
||||
tag?: string;
|
||||
tagIcon?: LucideIcon;
|
||||
buttons?: ButtonConfig[];
|
||||
textboxLayout: TextboxLayout;
|
||||
useInvertedBackground: InvertedBackground;
|
||||
ariaLabel?: string;
|
||||
className?: string;
|
||||
containerClassName?: string;
|
||||
cardClassName?: string;
|
||||
textBoxClassName?: string;
|
||||
textBoxTitleClassName?: string;
|
||||
textBoxDescriptionClassName?: string;
|
||||
textBoxTagClassName?: string;
|
||||
textBoxButtonContainerClassName?: string;
|
||||
textBoxButtonClassName?: string;
|
||||
textBoxButtonTextClassName?: string;
|
||||
titleImageWrapperClassName?: string;
|
||||
titleImageClassName?: string;
|
||||
groupTitleClassName?: string;
|
||||
memberClassName?: string;
|
||||
memberImageClassName?: string;
|
||||
memberTitleClassName?: string;
|
||||
memberSubtitleClassName?: string;
|
||||
memberDetailClassName?: string;
|
||||
}
|
||||
|
||||
const TeamCardEleven = ({
|
||||
groups,
|
||||
animationType,
|
||||
title,
|
||||
titleSegments,
|
||||
description,
|
||||
tag,
|
||||
tagIcon,
|
||||
buttons,
|
||||
textboxLayout,
|
||||
useInvertedBackground,
|
||||
ariaLabel = "Team section",
|
||||
className = "",
|
||||
containerClassName = "",
|
||||
cardClassName = "",
|
||||
textBoxClassName = "",
|
||||
textBoxTitleClassName = "",
|
||||
textBoxDescriptionClassName = "",
|
||||
textBoxTagClassName = "",
|
||||
textBoxButtonContainerClassName = "",
|
||||
textBoxButtonClassName = "",
|
||||
textBoxButtonTextClassName = "",
|
||||
titleImageWrapperClassName = "",
|
||||
titleImageClassName = "",
|
||||
groupTitleClassName = "",
|
||||
memberClassName = "",
|
||||
memberImageClassName = "",
|
||||
memberTitleClassName = "",
|
||||
memberSubtitleClassName = "",
|
||||
memberDetailClassName = "",
|
||||
}: TeamCardElevenProps) => {
|
||||
const theme = useTheme();
|
||||
const shouldUseLightText = shouldUseInvertedText(useInvertedBackground, theme.cardStyle);
|
||||
|
||||
const renderMemberRow = (member: TeamMember) => (
|
||||
<div
|
||||
key={member.id}
|
||||
className={cls(
|
||||
"flex flex-col md:flex-row md:items-center gap-4 py-6",
|
||||
memberClassName
|
||||
)}
|
||||
>
|
||||
<div className="flex items-center gap-4 flex-1">
|
||||
<div className={cls(
|
||||
"relative h-14 w-auto md:h-16 aspect-square rounded-theme overflow-hidden shrink-0",
|
||||
memberImageClassName
|
||||
)}>
|
||||
<MediaContent
|
||||
imageSrc={member.imageSrc}
|
||||
imageAlt={member.imageAlt || member.title}
|
||||
videoSrc={member.videoSrc}
|
||||
videoAriaLabel={member.videoAriaLabel}
|
||||
imageClassName="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col">
|
||||
<p className={cls(
|
||||
"text-lg md:text-xl font-medium",
|
||||
shouldUseLightText ? "text-background" : "text-foreground",
|
||||
memberTitleClassName
|
||||
)}>
|
||||
{member.title}
|
||||
</p>
|
||||
<p className={cls(
|
||||
"text-base",
|
||||
shouldUseLightText ? "text-background/60" : "text-foreground/60",
|
||||
memberSubtitleClassName
|
||||
)}>
|
||||
{member.subtitle}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className={cls(
|
||||
"text-base md:text-lg font-medium",
|
||||
shouldUseLightText ? "text-background" : "text-foreground",
|
||||
memberDetailClassName
|
||||
)}>
|
||||
{member.detail}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<CardList
|
||||
title={title}
|
||||
titleSegments={titleSegments}
|
||||
description={description}
|
||||
tag={tag}
|
||||
tagIcon={tagIcon}
|
||||
buttons={buttons}
|
||||
textboxLayout={textboxLayout}
|
||||
animationType={animationType}
|
||||
useInvertedBackground={useInvertedBackground}
|
||||
className={className}
|
||||
containerClassName={containerClassName}
|
||||
cardClassName={cardClassName}
|
||||
titleClassName={textBoxTitleClassName}
|
||||
descriptionClassName={textBoxDescriptionClassName}
|
||||
textBoxClassName={textBoxClassName}
|
||||
tagClassName={textBoxTagClassName}
|
||||
buttonContainerClassName={textBoxButtonContainerClassName}
|
||||
buttonClassName={textBoxButtonClassName}
|
||||
buttonTextClassName={textBoxButtonTextClassName}
|
||||
titleImageWrapperClassName={titleImageWrapperClassName}
|
||||
titleImageClassName={titleImageClassName}
|
||||
ariaLabel={ariaLabel}
|
||||
>
|
||||
{groups.map((group) => (
|
||||
<div key={group.id} className="p-6 md:p-8">
|
||||
<h3 className={cls(
|
||||
"text-2xl md:text-3xl font-medium mb-2",
|
||||
shouldUseLightText ? "text-background" : "text-foreground",
|
||||
groupTitleClassName
|
||||
)}>
|
||||
{group.groupTitle}
|
||||
</h3>
|
||||
|
||||
<div className="flex flex-col divide-y divide-accent/40 border-y border-accent/40">
|
||||
{group.members.map(renderMemberRow)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</CardList>
|
||||
);
|
||||
};
|
||||
|
||||
TeamCardEleven.displayName = "TeamCardEleven";
|
||||
|
||||
export default TeamCardEleven;
|
||||
142
src/components/sections/team/TeamCardFive.tsx
Normal file
142
src/components/sections/team/TeamCardFive.tsx
Normal file
@@ -0,0 +1,142 @@
|
||||
"use client";
|
||||
|
||||
import CardStackTextBox from "@/components/cardStack/CardStackTextBox";
|
||||
import MediaContent from "@/components/shared/MediaContent";
|
||||
import { useCardAnimation } from "@/components/cardStack/hooks/useCardAnimation";
|
||||
import { cls } from "@/lib/utils";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
import type { ButtonConfig, CardAnimationType, TitleSegment } from "@/components/cardStack/types";
|
||||
import type { TextboxLayout, InvertedBackground } from "@/providers/themeProvider/config/constants";
|
||||
|
||||
type TeamMember = {
|
||||
id: string;
|
||||
name: string;
|
||||
role: string;
|
||||
imageSrc?: string;
|
||||
videoSrc?: string;
|
||||
imageAlt?: string;
|
||||
videoAriaLabel?: string;
|
||||
};
|
||||
|
||||
interface TeamCardFiveProps {
|
||||
team: TeamMember[];
|
||||
animationType: CardAnimationType;
|
||||
title: string;
|
||||
titleSegments?: TitleSegment[];
|
||||
description: string;
|
||||
textboxLayout: TextboxLayout;
|
||||
useInvertedBackground: InvertedBackground;
|
||||
tag?: string;
|
||||
tagIcon?: LucideIcon;
|
||||
buttons?: ButtonConfig[];
|
||||
ariaLabel?: string;
|
||||
className?: string;
|
||||
containerClassName?: string;
|
||||
textBoxTitleClassName?: string;
|
||||
textBoxTitleImageWrapperClassName?: string;
|
||||
textBoxTitleImageClassName?: string;
|
||||
textBoxDescriptionClassName?: string;
|
||||
textBoxClassName?: string;
|
||||
textBoxTagClassName?: string;
|
||||
textBoxButtonContainerClassName?: string;
|
||||
textBoxButtonClassName?: string;
|
||||
textBoxButtonTextClassName?: string;
|
||||
gridClassName?: string;
|
||||
cardClassName?: string;
|
||||
mediaWrapperClassName?: string;
|
||||
mediaClassName?: string;
|
||||
nameClassName?: string;
|
||||
roleClassName?: string;
|
||||
}
|
||||
|
||||
const TeamCardFive = ({
|
||||
team,
|
||||
animationType,
|
||||
title,
|
||||
titleSegments,
|
||||
description,
|
||||
textboxLayout,
|
||||
useInvertedBackground,
|
||||
tag,
|
||||
tagIcon,
|
||||
buttons,
|
||||
ariaLabel = "Team section",
|
||||
className = "",
|
||||
containerClassName = "",
|
||||
textBoxTitleClassName = "",
|
||||
textBoxTitleImageWrapperClassName = "",
|
||||
textBoxTitleImageClassName = "",
|
||||
textBoxDescriptionClassName = "",
|
||||
textBoxClassName = "",
|
||||
textBoxTagClassName = "",
|
||||
textBoxButtonContainerClassName = "",
|
||||
textBoxButtonClassName = "",
|
||||
textBoxButtonTextClassName = "",
|
||||
gridClassName = "",
|
||||
cardClassName = "",
|
||||
mediaWrapperClassName = "",
|
||||
mediaClassName = "",
|
||||
nameClassName = "",
|
||||
roleClassName = "",
|
||||
}: TeamCardFiveProps) => {
|
||||
const { itemRefs } = useCardAnimation({ animationType, itemCount: team.length });
|
||||
|
||||
return (
|
||||
<section
|
||||
aria-label={ariaLabel}
|
||||
className={cls("relative py-20 w-full", useInvertedBackground === "invertDefault" && "bg-foreground", className)}
|
||||
>
|
||||
<div className={cls("w-content-width mx-auto flex flex-col gap-8", containerClassName)}>
|
||||
<CardStackTextBox
|
||||
title={title}
|
||||
titleSegments={titleSegments}
|
||||
description={description}
|
||||
tag={tag}
|
||||
tagIcon={tagIcon}
|
||||
buttons={buttons}
|
||||
textboxLayout={textboxLayout}
|
||||
useInvertedBackground={useInvertedBackground}
|
||||
textBoxClassName={textBoxClassName}
|
||||
titleClassName={textBoxTitleClassName}
|
||||
titleImageWrapperClassName={textBoxTitleImageWrapperClassName}
|
||||
titleImageClassName={textBoxTitleImageClassName}
|
||||
descriptionClassName={textBoxDescriptionClassName}
|
||||
tagClassName={textBoxTagClassName}
|
||||
buttonContainerClassName={textBoxButtonContainerClassName}
|
||||
buttonClassName={textBoxButtonClassName}
|
||||
buttonTextClassName={textBoxButtonTextClassName}
|
||||
/>
|
||||
|
||||
<div className={cls("flex flex-row flex-wrap gap-y-6 md:gap-x-0 justify-center", gridClassName)}>
|
||||
{team.map((member, index) => (
|
||||
<div
|
||||
key={member.id}
|
||||
ref={(el) => { itemRefs.current[index] = el; }}
|
||||
className={cls("relative flex flex-col items-center text-center w-[55%] md:w-[28%] -mx-[4%] md:-mx-[2%]", cardClassName)}
|
||||
>
|
||||
<div className={cls("relative card w-full aspect-square rounded-theme overflow-hidden p-2 mb-4", mediaWrapperClassName)}>
|
||||
<MediaContent
|
||||
imageSrc={member.imageSrc}
|
||||
videoSrc={member.videoSrc}
|
||||
imageAlt={member.imageAlt || member.name}
|
||||
videoAriaLabel={member.videoAriaLabel || member.name}
|
||||
imageClassName={cls("relative z-1 w-full h-full object-cover rounded-theme!", mediaClassName)}
|
||||
/>
|
||||
</div>
|
||||
<h3 className={cls("relative z-1 w-8/10 text-2xl font-medium leading-tight truncate", useInvertedBackground === "invertDefault" ? "text-background" : "text-foreground", nameClassName)}>
|
||||
{member.name}
|
||||
</h3>
|
||||
<p className={cls("relative z-1 w-8/10 text-base leading-tight mt-1 truncate", useInvertedBackground === "invertDefault" ? "text-background/75" : "text-foreground/75", roleClassName)}>
|
||||
{member.role}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
TeamCardFive.displayName = "TeamCardFive";
|
||||
|
||||
export default TeamCardFive;
|
||||
185
src/components/sections/team/TeamCardOne.tsx
Normal file
185
src/components/sections/team/TeamCardOne.tsx
Normal file
@@ -0,0 +1,185 @@
|
||||
"use client";
|
||||
|
||||
import { memo } from "react";
|
||||
import Image from "next/image";
|
||||
import CardStack from "@/components/cardStack/CardStack";
|
||||
import { cls } from "@/lib/utils";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
import type { ButtonConfig, GridVariant, CardAnimationType, TitleSegment } from "@/components/cardStack/types";
|
||||
import type { TextboxLayout, InvertedBackground } from "@/providers/themeProvider/config/constants";
|
||||
|
||||
type TeamMember = {
|
||||
id: string;
|
||||
name: string;
|
||||
role: string;
|
||||
imageSrc: string;
|
||||
imageAlt?: string;
|
||||
};
|
||||
|
||||
interface TeamCardOneProps {
|
||||
members: TeamMember[];
|
||||
carouselMode?: "auto" | "buttons";
|
||||
gridVariant: GridVariant;
|
||||
uniformGridCustomHeightClasses?: string;
|
||||
animationType: CardAnimationType;
|
||||
title: string;
|
||||
titleSegments?: TitleSegment[];
|
||||
description: string;
|
||||
tag?: string;
|
||||
tagIcon?: LucideIcon;
|
||||
buttons?: ButtonConfig[];
|
||||
textboxLayout: TextboxLayout;
|
||||
useInvertedBackground: InvertedBackground;
|
||||
ariaLabel?: string;
|
||||
className?: string;
|
||||
containerClassName?: string;
|
||||
cardClassName?: string;
|
||||
textBoxTitleClassName?: string;
|
||||
textBoxTitleImageWrapperClassName?: string;
|
||||
textBoxTitleImageClassName?: string;
|
||||
textBoxDescriptionClassName?: string;
|
||||
imageClassName?: string;
|
||||
overlayClassName?: string;
|
||||
nameClassName?: string;
|
||||
roleClassName?: string;
|
||||
gridClassName?: string;
|
||||
carouselClassName?: string;
|
||||
controlsClassName?: string;
|
||||
textBoxClassName?: string;
|
||||
textBoxTagClassName?: string;
|
||||
textBoxButtonContainerClassName?: string;
|
||||
textBoxButtonClassName?: string;
|
||||
textBoxButtonTextClassName?: string;
|
||||
}
|
||||
|
||||
interface TeamMemberCardProps {
|
||||
member: TeamMember;
|
||||
cardClassName?: string;
|
||||
imageClassName?: string;
|
||||
overlayClassName?: string;
|
||||
nameClassName?: string;
|
||||
roleClassName?: string;
|
||||
}
|
||||
|
||||
const TeamMemberCard = memo(({
|
||||
member,
|
||||
cardClassName = "",
|
||||
imageClassName = "",
|
||||
overlayClassName = "",
|
||||
nameClassName = "",
|
||||
roleClassName = "",
|
||||
}: TeamMemberCardProps) => {
|
||||
return (
|
||||
<div className={cls("relative h-full card rounded-theme-capped p-4", cardClassName)}>
|
||||
<div className="relative z-1 w-full h-full rounded-theme-capped overflow-hidden">
|
||||
<Image
|
||||
src={member.imageSrc}
|
||||
alt={member.imageAlt || member.name}
|
||||
width={800}
|
||||
height={800}
|
||||
className={cls("w-full h-full object-cover ", imageClassName)}
|
||||
unoptimized={member.imageSrc.startsWith('http') || member.imageSrc.startsWith('//')}
|
||||
aria-hidden={member.imageAlt === ""}
|
||||
/>
|
||||
|
||||
<div className={cls("!absolute z-1 bottom-4 left-4 right-4 card backdrop-blur-xs p-4 rounded-theme-capped flex items-center justify-between gap-3", overlayClassName)}>
|
||||
<h3 className={cls("relative z-1 text-xl font-medium text-foreground leading-[1.1] truncate", nameClassName)}>
|
||||
{member.name}
|
||||
</h3>
|
||||
<div className="min-w-0 max-w-full w-fit primary-button px-3 py-2 rounded-theme">
|
||||
<p className={cls("text-sm text-background leading-[1.1] truncate", roleClassName)}>
|
||||
{member.role}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
TeamMemberCard.displayName = "TeamMemberCard";
|
||||
|
||||
const TeamCardOne = ({
|
||||
members,
|
||||
carouselMode = "buttons",
|
||||
gridVariant,
|
||||
uniformGridCustomHeightClasses = "min-h-95 2xl:min-h-105",
|
||||
animationType,
|
||||
title,
|
||||
titleSegments,
|
||||
description,
|
||||
tag,
|
||||
tagIcon,
|
||||
buttons,
|
||||
textboxLayout,
|
||||
useInvertedBackground,
|
||||
ariaLabel = "Team section",
|
||||
className = "",
|
||||
containerClassName = "",
|
||||
cardClassName = "",
|
||||
textBoxTitleClassName = "",
|
||||
textBoxTitleImageWrapperClassName = "",
|
||||
textBoxTitleImageClassName = "",
|
||||
textBoxDescriptionClassName = "",
|
||||
imageClassName = "",
|
||||
overlayClassName = "",
|
||||
nameClassName = "",
|
||||
roleClassName = "",
|
||||
gridClassName = "",
|
||||
carouselClassName = "",
|
||||
controlsClassName = "",
|
||||
textBoxClassName = "",
|
||||
textBoxTagClassName = "",
|
||||
textBoxButtonContainerClassName = "",
|
||||
textBoxButtonClassName = "",
|
||||
textBoxButtonTextClassName = "",
|
||||
}: TeamCardOneProps) => {
|
||||
return (
|
||||
<CardStack
|
||||
mode={carouselMode}
|
||||
gridVariant={gridVariant}
|
||||
uniformGridCustomHeightClasses={uniformGridCustomHeightClasses}
|
||||
animationType={animationType}
|
||||
|
||||
title={title}
|
||||
titleSegments={titleSegments}
|
||||
description={description}
|
||||
tag={tag}
|
||||
tagIcon={tagIcon}
|
||||
buttons={buttons}
|
||||
textboxLayout={textboxLayout}
|
||||
useInvertedBackground={useInvertedBackground}
|
||||
className={className}
|
||||
containerClassName={containerClassName}
|
||||
gridClassName={gridClassName}
|
||||
carouselClassName={carouselClassName}
|
||||
controlsClassName={controlsClassName}
|
||||
textBoxClassName={textBoxClassName}
|
||||
titleClassName={textBoxTitleClassName}
|
||||
titleImageWrapperClassName={textBoxTitleImageWrapperClassName}
|
||||
titleImageClassName={textBoxTitleImageClassName}
|
||||
descriptionClassName={textBoxDescriptionClassName}
|
||||
tagClassName={textBoxTagClassName}
|
||||
buttonContainerClassName={textBoxButtonContainerClassName}
|
||||
buttonClassName={textBoxButtonClassName}
|
||||
buttonTextClassName={textBoxButtonTextClassName}
|
||||
ariaLabel={ariaLabel}
|
||||
>
|
||||
{members.map((member, index) => (
|
||||
<TeamMemberCard
|
||||
key={`${member.id}-${index}`}
|
||||
member={member}
|
||||
cardClassName={cardClassName}
|
||||
imageClassName={imageClassName}
|
||||
overlayClassName={overlayClassName}
|
||||
nameClassName={nameClassName}
|
||||
roleClassName={roleClassName}
|
||||
/>
|
||||
))}
|
||||
</CardStack>
|
||||
);
|
||||
};
|
||||
|
||||
TeamCardOne.displayName = "TeamCardOne";
|
||||
|
||||
export default TeamCardOne;
|
||||
191
src/components/sections/team/TeamCardSix.tsx
Normal file
191
src/components/sections/team/TeamCardSix.tsx
Normal file
@@ -0,0 +1,191 @@
|
||||
"use client";
|
||||
|
||||
import { memo } from "react";
|
||||
import Image from "next/image";
|
||||
import CardStack from "@/components/cardStack/CardStack";
|
||||
import { cls } from "@/lib/utils";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
import type { ButtonConfig, GridVariant, CardAnimationType, TitleSegment } from "@/components/cardStack/types";
|
||||
import type { TextboxLayout, InvertedBackground } from "@/providers/themeProvider/config/constants";
|
||||
|
||||
const MASK_GRADIENT = "linear-gradient(to bottom, transparent, black 60%)";
|
||||
|
||||
type TeamMember = {
|
||||
id: string;
|
||||
name: string;
|
||||
role: string;
|
||||
imageSrc: string;
|
||||
imageAlt?: string;
|
||||
};
|
||||
|
||||
interface TeamCardSixProps {
|
||||
members: TeamMember[];
|
||||
carouselMode?: "auto" | "buttons";
|
||||
gridVariant: GridVariant;
|
||||
uniformGridCustomHeightClasses?: string;
|
||||
animationType: CardAnimationType;
|
||||
title: string;
|
||||
titleSegments?: TitleSegment[];
|
||||
description: string;
|
||||
tag?: string;
|
||||
tagIcon?: LucideIcon;
|
||||
buttons?: ButtonConfig[];
|
||||
textboxLayout: TextboxLayout;
|
||||
useInvertedBackground: InvertedBackground;
|
||||
ariaLabel?: string;
|
||||
className?: string;
|
||||
containerClassName?: string;
|
||||
cardClassName?: string;
|
||||
textBoxTitleClassName?: string;
|
||||
textBoxTitleImageWrapperClassName?: string;
|
||||
textBoxTitleImageClassName?: string;
|
||||
textBoxDescriptionClassName?: string;
|
||||
imageClassName?: string;
|
||||
overlayClassName?: string;
|
||||
nameClassName?: string;
|
||||
roleClassName?: string;
|
||||
gridClassName?: string;
|
||||
carouselClassName?: string;
|
||||
controlsClassName?: string;
|
||||
textBoxClassName?: string;
|
||||
textBoxTagClassName?: string;
|
||||
textBoxButtonContainerClassName?: string;
|
||||
textBoxButtonClassName?: string;
|
||||
textBoxButtonTextClassName?: string;
|
||||
}
|
||||
|
||||
interface TeamMemberCardProps {
|
||||
member: TeamMember;
|
||||
cardClassName?: string;
|
||||
imageClassName?: string;
|
||||
overlayClassName?: string;
|
||||
nameClassName?: string;
|
||||
roleClassName?: string;
|
||||
}
|
||||
|
||||
const TeamMemberCard = memo(({
|
||||
member,
|
||||
cardClassName = "",
|
||||
imageClassName = "",
|
||||
overlayClassName = "",
|
||||
nameClassName = "",
|
||||
roleClassName = "",
|
||||
}: TeamMemberCardProps) => {
|
||||
return (
|
||||
<div className={cls("relative h-full rounded-theme-capped", cardClassName)}>
|
||||
<div className="relative w-full h-full rounded-theme-capped overflow-hidden">
|
||||
<Image
|
||||
src={member.imageSrc}
|
||||
alt={member.imageAlt || member.name}
|
||||
width={800}
|
||||
height={800}
|
||||
className={cls("w-full h-full object-cover", imageClassName)}
|
||||
unoptimized={member.imageSrc.startsWith('http') || member.imageSrc.startsWith('//')}
|
||||
aria-hidden={member.imageAlt === ""}
|
||||
/>
|
||||
|
||||
<div className={cls("absolute z-10 bottom-4 left-4 right-4 p-4 flex flex-col gap-0 text-foreground", overlayClassName)}>
|
||||
<h3 className={cls("text-2xl font-medium leading-tight truncate", nameClassName)}>
|
||||
{member.name}
|
||||
</h3>
|
||||
<p className={cls("text-base leading-tight truncate", roleClassName)}>
|
||||
{member.role}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="absolute z-0 backdrop-blur-xl opacity-100 w-full h-1/3 left-0 bottom-0"
|
||||
style={{ maskImage: MASK_GRADIENT }}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
TeamMemberCard.displayName = "TeamMemberCard";
|
||||
|
||||
const TeamCardSix = ({
|
||||
members,
|
||||
carouselMode = "buttons",
|
||||
gridVariant,
|
||||
uniformGridCustomHeightClasses = "min-h-95 2xl:min-h-105",
|
||||
animationType,
|
||||
title,
|
||||
titleSegments,
|
||||
description,
|
||||
tag,
|
||||
tagIcon,
|
||||
buttons,
|
||||
textboxLayout,
|
||||
useInvertedBackground,
|
||||
ariaLabel = "Team section",
|
||||
className = "",
|
||||
containerClassName = "",
|
||||
cardClassName = "",
|
||||
textBoxTitleClassName = "",
|
||||
textBoxTitleImageWrapperClassName = "",
|
||||
textBoxTitleImageClassName = "",
|
||||
textBoxDescriptionClassName = "",
|
||||
imageClassName = "",
|
||||
overlayClassName = "",
|
||||
nameClassName = "",
|
||||
roleClassName = "",
|
||||
gridClassName = "",
|
||||
carouselClassName = "",
|
||||
controlsClassName = "",
|
||||
textBoxClassName = "",
|
||||
textBoxTagClassName = "",
|
||||
textBoxButtonContainerClassName = "",
|
||||
textBoxButtonClassName = "",
|
||||
textBoxButtonTextClassName = "",
|
||||
}: TeamCardSixProps) => {
|
||||
return (
|
||||
<CardStack
|
||||
mode={carouselMode}
|
||||
gridVariant={gridVariant}
|
||||
uniformGridCustomHeightClasses={uniformGridCustomHeightClasses}
|
||||
animationType={animationType}
|
||||
|
||||
title={title}
|
||||
titleSegments={titleSegments}
|
||||
description={description}
|
||||
tag={tag}
|
||||
tagIcon={tagIcon}
|
||||
buttons={buttons}
|
||||
textboxLayout={textboxLayout}
|
||||
useInvertedBackground={useInvertedBackground}
|
||||
className={className}
|
||||
containerClassName={containerClassName}
|
||||
gridClassName={gridClassName}
|
||||
carouselClassName={carouselClassName}
|
||||
controlsClassName={controlsClassName}
|
||||
textBoxClassName={textBoxClassName}
|
||||
titleClassName={textBoxTitleClassName}
|
||||
titleImageWrapperClassName={textBoxTitleImageWrapperClassName}
|
||||
titleImageClassName={textBoxTitleImageClassName}
|
||||
descriptionClassName={textBoxDescriptionClassName}
|
||||
tagClassName={textBoxTagClassName}
|
||||
buttonContainerClassName={textBoxButtonContainerClassName}
|
||||
buttonClassName={textBoxButtonClassName}
|
||||
buttonTextClassName={textBoxButtonTextClassName}
|
||||
ariaLabel={ariaLabel}
|
||||
>
|
||||
{members.map((member, index) => (
|
||||
<TeamMemberCard
|
||||
key={`${member.id}-${index}`}
|
||||
member={member}
|
||||
cardClassName={cardClassName}
|
||||
imageClassName={imageClassName}
|
||||
overlayClassName={overlayClassName}
|
||||
nameClassName={nameClassName}
|
||||
roleClassName={roleClassName}
|
||||
/>
|
||||
))}
|
||||
</CardStack>
|
||||
);
|
||||
};
|
||||
|
||||
TeamCardSix.displayName = "TeamCardSix";
|
||||
|
||||
export default TeamCardSix;
|
||||
128
src/components/sections/team/TeamCardTen.tsx
Normal file
128
src/components/sections/team/TeamCardTen.tsx
Normal file
@@ -0,0 +1,128 @@
|
||||
"use client";
|
||||
|
||||
import TextAnimation from "@/components/text/TextAnimation";
|
||||
import MediaContent from "@/components/shared/MediaContent";
|
||||
import Tag from "@/components/shared/Tag";
|
||||
import { cls, shouldUseInvertedText } from "@/lib/utils";
|
||||
import { useTheme } from "@/providers/themeProvider/ThemeProvider";
|
||||
import type { InvertedBackground } from "@/providers/themeProvider/config/constants";
|
||||
|
||||
type TeamMember = {
|
||||
id: string;
|
||||
name: string;
|
||||
imageSrc?: string;
|
||||
imageAlt?: string;
|
||||
videoSrc?: string;
|
||||
videoAriaLabel?: string;
|
||||
};
|
||||
|
||||
interface TeamCardTenProps {
|
||||
title: string;
|
||||
tag: string;
|
||||
members: TeamMember[];
|
||||
memberVariant: "default" | "card";
|
||||
useInvertedBackground: InvertedBackground;
|
||||
ariaLabel?: string;
|
||||
className?: string;
|
||||
containerClassName?: string;
|
||||
titleClassName?: string;
|
||||
tagClassName?: string;
|
||||
membersContainerClassName?: string;
|
||||
memberClassName?: string;
|
||||
mediaWrapperClassName?: string;
|
||||
mediaClassName?: string;
|
||||
nameClassName?: string;
|
||||
}
|
||||
|
||||
const TeamCardTen = ({
|
||||
title,
|
||||
tag,
|
||||
members,
|
||||
memberVariant,
|
||||
useInvertedBackground,
|
||||
ariaLabel = "Team section",
|
||||
className = "",
|
||||
containerClassName = "",
|
||||
titleClassName = "",
|
||||
tagClassName = "",
|
||||
membersContainerClassName = "",
|
||||
memberClassName = "",
|
||||
mediaWrapperClassName = "",
|
||||
mediaClassName = "",
|
||||
nameClassName = "",
|
||||
}: TeamCardTenProps) => {
|
||||
const theme = useTheme();
|
||||
const shouldUseLightText = shouldUseInvertedText(useInvertedBackground, theme.cardStyle);
|
||||
|
||||
return (
|
||||
<section
|
||||
aria-label={ariaLabel}
|
||||
className={cls("relative py-20 w-full", useInvertedBackground === "invertDefault" && "bg-foreground", className)}
|
||||
>
|
||||
<div className={cls("w-content-width mx-auto flex flex-col gap-10", containerClassName)}>
|
||||
<TextAnimation
|
||||
type={theme.defaultTextAnimation}
|
||||
text={title}
|
||||
variant="words-trigger"
|
||||
className={cls(
|
||||
"text-3xl md:text-5xl font-medium leading-tight",
|
||||
useInvertedBackground === "invertDefault" && "text-background",
|
||||
titleClassName
|
||||
)}
|
||||
/>
|
||||
|
||||
<div className="relative w-full h-px bg-accent/20" />
|
||||
|
||||
<div className="flex flex-col md:flex-row md:items-start gap-10 md:gap-8">
|
||||
<div className="w-fit md:w-15" >
|
||||
<Tag
|
||||
text={tag}
|
||||
useInvertedBackground={useInvertedBackground}
|
||||
className={cls("min-w-0 max-w-full text-xl px-6", tagClassName)}
|
||||
textClassName="truncate"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={cls(
|
||||
"w-full grid gap-8 flex-1",
|
||||
members.length === 1 && "grid-cols-1",
|
||||
members.length >= 2 && "grid-cols-2",
|
||||
membersContainerClassName
|
||||
)}>
|
||||
{members.map((member) => (
|
||||
<div
|
||||
key={member.id}
|
||||
className={cls(
|
||||
"flex flex-col gap-4",
|
||||
memberVariant === "card" && "card rounded-theme-capped p-4",
|
||||
memberClassName
|
||||
)}
|
||||
>
|
||||
<div className={cls("relative aspect-[3/3.5] rounded-theme-capped overflow-hidden", mediaWrapperClassName)}>
|
||||
<MediaContent
|
||||
imageSrc={member.imageSrc}
|
||||
imageAlt={member.imageAlt || member.name}
|
||||
videoSrc={member.videoSrc}
|
||||
videoAriaLabel={member.videoAriaLabel}
|
||||
imageClassName={cls("w-full h-full object-cover", mediaClassName)}
|
||||
/>
|
||||
</div>
|
||||
<p className={cls(
|
||||
"text-xl md:text-3xl font-medium truncate",
|
||||
shouldUseLightText ? "text-background" : "text-foreground",
|
||||
nameClassName
|
||||
)}>
|
||||
{member.name}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
TeamCardTen.displayName = "TeamCardTen";
|
||||
|
||||
export default TeamCardTen;
|
||||
227
src/components/sections/team/TeamCardTwo.tsx
Normal file
227
src/components/sections/team/TeamCardTwo.tsx
Normal file
@@ -0,0 +1,227 @@
|
||||
"use client";
|
||||
|
||||
import { memo } from "react";
|
||||
import Image from "next/image";
|
||||
import CardStack from "@/components/cardStack/CardStack";
|
||||
import { cls } from "@/lib/utils";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
import type { ButtonConfig, GridVariant, CardAnimationType, TitleSegment } from "@/components/cardStack/types";
|
||||
import type { TextboxLayout, InvertedBackground } from "@/providers/themeProvider/config/constants";
|
||||
|
||||
type SocialLink = {
|
||||
icon: LucideIcon;
|
||||
url: string;
|
||||
};
|
||||
|
||||
type TeamMember = {
|
||||
id: string;
|
||||
name: string;
|
||||
role: string;
|
||||
description: string;
|
||||
imageSrc: string;
|
||||
imageAlt?: string;
|
||||
socialLinks?: SocialLink[];
|
||||
};
|
||||
|
||||
interface TeamCardTwoProps {
|
||||
members: TeamMember[];
|
||||
carouselMode?: "auto" | "buttons";
|
||||
gridVariant: GridVariant;
|
||||
uniformGridCustomHeightClasses?: string;
|
||||
animationType: CardAnimationType;
|
||||
title: string;
|
||||
titleSegments?: TitleSegment[];
|
||||
description: string;
|
||||
tag?: string;
|
||||
tagIcon?: LucideIcon;
|
||||
buttons?: ButtonConfig[];
|
||||
textboxLayout: TextboxLayout;
|
||||
useInvertedBackground: InvertedBackground;
|
||||
ariaLabel?: string;
|
||||
className?: string;
|
||||
containerClassName?: string;
|
||||
cardClassName?: string;
|
||||
textBoxTitleClassName?: string;
|
||||
textBoxTitleImageWrapperClassName?: string;
|
||||
textBoxTitleImageClassName?: string;
|
||||
textBoxDescriptionClassName?: string;
|
||||
imageClassName?: string;
|
||||
overlayClassName?: string;
|
||||
nameClassName?: string;
|
||||
roleClassName?: string;
|
||||
memberDescriptionClassName?: string;
|
||||
socialLinksClassName?: string;
|
||||
socialIconClassName?: string;
|
||||
gridClassName?: string;
|
||||
carouselClassName?: string;
|
||||
controlsClassName?: string;
|
||||
textBoxClassName?: string;
|
||||
textBoxTagClassName?: string;
|
||||
textBoxButtonContainerClassName?: string;
|
||||
textBoxButtonClassName?: string;
|
||||
textBoxButtonTextClassName?: string;
|
||||
}
|
||||
|
||||
interface TeamMemberCardProps {
|
||||
member: TeamMember;
|
||||
cardClassName?: string;
|
||||
imageClassName?: string;
|
||||
overlayClassName?: string;
|
||||
nameClassName?: string;
|
||||
roleClassName?: string;
|
||||
memberDescriptionClassName?: string;
|
||||
socialLinksClassName?: string;
|
||||
socialIconClassName?: string;
|
||||
}
|
||||
|
||||
const TeamMemberCard = memo(({
|
||||
member,
|
||||
cardClassName = "",
|
||||
imageClassName = "",
|
||||
overlayClassName = "",
|
||||
nameClassName = "",
|
||||
roleClassName = "",
|
||||
memberDescriptionClassName = "",
|
||||
socialLinksClassName = "",
|
||||
socialIconClassName = "",
|
||||
}: TeamMemberCardProps) => {
|
||||
return (
|
||||
<div className={cls("relative h-full rounded-theme-capped overflow-hidden group", cardClassName)}>
|
||||
<Image
|
||||
src={member.imageSrc}
|
||||
alt={member.imageAlt || member.name}
|
||||
width={800}
|
||||
height={800}
|
||||
className={cls("relative z-1 w-full h-full object-cover", imageClassName)}
|
||||
unoptimized={member.imageSrc.startsWith('http') || member.imageSrc.startsWith('//')}
|
||||
aria-hidden={member.imageAlt === ""}
|
||||
/>
|
||||
|
||||
<div className={cls("!absolute z-10 bottom-6 left-6 right-6 card backdrop-blur-xs p-6 flex flex-col gap-2 rounded-theme-capped", overlayClassName)}>
|
||||
<div className="relative z-1 flex items-start justify-between">
|
||||
<h3 className={cls("text-2xl font-medium text-foreground leading-[1.1] truncate", nameClassName)}>
|
||||
{member.name}
|
||||
</h3>
|
||||
<div className="relative z-1 secondary-button px-3 py-1 rounded-theme" >
|
||||
<p className={cls("text-xs text-foreground leading-[1.1] truncate", roleClassName)}>
|
||||
{member.role}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className={cls("relative z-1 text-base text-foreground leading-[1.1]", memberDescriptionClassName)}>
|
||||
{member.description}
|
||||
</p>
|
||||
|
||||
{member.socialLinks && member.socialLinks.length > 0 && (
|
||||
<div className={cls("relative z-1 flex gap-3 mt-1", socialLinksClassName)}>
|
||||
{member.socialLinks.map((link, index) => (
|
||||
<a
|
||||
key={index}
|
||||
href={link.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className={cls("primary-button h-9 aspect-square w-auto flex items-center justify-center rounded-theme", socialIconClassName)}
|
||||
>
|
||||
<link.icon className="h-4/10 text-background" strokeWidth={1.5} />
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
TeamMemberCard.displayName = "TeamMemberCard";
|
||||
|
||||
const TeamCardTwo = ({
|
||||
members,
|
||||
carouselMode = "buttons",
|
||||
gridVariant,
|
||||
uniformGridCustomHeightClasses = "min-h-95 2xl:min-h-105",
|
||||
animationType,
|
||||
title,
|
||||
titleSegments,
|
||||
description,
|
||||
tag,
|
||||
tagIcon,
|
||||
buttons,
|
||||
textboxLayout,
|
||||
useInvertedBackground,
|
||||
ariaLabel = "Team section",
|
||||
className = "",
|
||||
containerClassName = "",
|
||||
cardClassName = "",
|
||||
textBoxTitleClassName = "",
|
||||
textBoxTitleImageWrapperClassName = "",
|
||||
textBoxTitleImageClassName = "",
|
||||
textBoxDescriptionClassName = "",
|
||||
imageClassName = "",
|
||||
overlayClassName = "",
|
||||
nameClassName = "",
|
||||
roleClassName = "",
|
||||
memberDescriptionClassName = "",
|
||||
socialLinksClassName = "",
|
||||
socialIconClassName = "",
|
||||
gridClassName = "",
|
||||
carouselClassName = "",
|
||||
controlsClassName = "",
|
||||
textBoxClassName = "",
|
||||
textBoxTagClassName = "",
|
||||
textBoxButtonContainerClassName = "",
|
||||
textBoxButtonClassName = "",
|
||||
textBoxButtonTextClassName = "",
|
||||
}: TeamCardTwoProps) => {
|
||||
return (
|
||||
<CardStack
|
||||
mode={carouselMode}
|
||||
gridVariant={gridVariant}
|
||||
uniformGridCustomHeightClasses={uniformGridCustomHeightClasses}
|
||||
animationType={animationType}
|
||||
|
||||
title={title}
|
||||
titleSegments={titleSegments}
|
||||
description={description}
|
||||
tag={tag}
|
||||
tagIcon={tagIcon}
|
||||
buttons={buttons}
|
||||
textboxLayout={textboxLayout}
|
||||
useInvertedBackground={useInvertedBackground}
|
||||
className={className}
|
||||
containerClassName={containerClassName}
|
||||
gridClassName={gridClassName}
|
||||
carouselClassName={carouselClassName}
|
||||
controlsClassName={controlsClassName}
|
||||
textBoxClassName={textBoxClassName}
|
||||
titleClassName={textBoxTitleClassName}
|
||||
titleImageWrapperClassName={textBoxTitleImageWrapperClassName}
|
||||
titleImageClassName={textBoxTitleImageClassName}
|
||||
descriptionClassName={textBoxDescriptionClassName}
|
||||
tagClassName={textBoxTagClassName}
|
||||
buttonContainerClassName={textBoxButtonContainerClassName}
|
||||
buttonClassName={textBoxButtonClassName}
|
||||
buttonTextClassName={textBoxButtonTextClassName}
|
||||
ariaLabel={ariaLabel}
|
||||
>
|
||||
{members.map((member, index) => (
|
||||
<TeamMemberCard
|
||||
key={`${member.id}-${index}`}
|
||||
member={member}
|
||||
cardClassName={cardClassName}
|
||||
imageClassName={imageClassName}
|
||||
overlayClassName={overlayClassName}
|
||||
nameClassName={nameClassName}
|
||||
roleClassName={roleClassName}
|
||||
memberDescriptionClassName={memberDescriptionClassName}
|
||||
socialLinksClassName={socialLinksClassName}
|
||||
socialIconClassName={socialIconClassName}
|
||||
/>
|
||||
))}
|
||||
</CardStack>
|
||||
);
|
||||
};
|
||||
|
||||
TeamCardTwo.displayName = "TeamCardTwo";
|
||||
|
||||
export default TeamCardTwo;
|
||||
Reference in New Issue
Block a user