Initial commit
This commit is contained in:
127
src/components/sections/about/TestimonialAboutCard.tsx
Normal file
127
src/components/sections/about/TestimonialAboutCard.tsx
Normal file
@@ -0,0 +1,127 @@
|
||||
"use client";
|
||||
|
||||
import MediaContent from "@/components/shared/MediaContent";
|
||||
import Tag from "@/components/shared/Tag";
|
||||
import { cls } from "@/lib/utils";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
import type { InvertedBackground } from "@/providers/themeProvider/config/constants";
|
||||
|
||||
type MediaProps =
|
||||
| {
|
||||
imageSrc: string;
|
||||
imageAlt?: string;
|
||||
videoSrc?: never;
|
||||
videoAriaLabel?: never;
|
||||
}
|
||||
| {
|
||||
videoSrc: string;
|
||||
videoAriaLabel?: string;
|
||||
imageSrc?: never;
|
||||
imageAlt?: never;
|
||||
};
|
||||
|
||||
type TestimonialAboutCardProps = MediaProps & {
|
||||
tag: string;
|
||||
tagIcon?: LucideIcon;
|
||||
title: string;
|
||||
description: string;
|
||||
subdescription: string;
|
||||
icon: LucideIcon;
|
||||
useInvertedBackground: InvertedBackground;
|
||||
ariaLabel?: string;
|
||||
className?: string;
|
||||
containerClassName?: string;
|
||||
cardClassName?: string;
|
||||
contentClassName?: string;
|
||||
tagClassName?: string;
|
||||
titleClassName?: string;
|
||||
descriptionClassName?: string;
|
||||
subdescriptionClassName?: string;
|
||||
footerClassName?: string;
|
||||
iconBoxClassName?: string;
|
||||
iconClassName?: string;
|
||||
mediaWrapperClassName?: string;
|
||||
mediaClassName?: string;
|
||||
};
|
||||
|
||||
const TestimonialAboutCard = ({
|
||||
tag,
|
||||
tagIcon,
|
||||
title,
|
||||
description,
|
||||
subdescription,
|
||||
icon: Icon,
|
||||
imageSrc,
|
||||
videoSrc,
|
||||
imageAlt = "",
|
||||
videoAriaLabel = "Testimonial video",
|
||||
useInvertedBackground,
|
||||
ariaLabel = "Testimonial section",
|
||||
className = "",
|
||||
containerClassName = "",
|
||||
cardClassName = "",
|
||||
contentClassName = "",
|
||||
tagClassName = "",
|
||||
titleClassName = "",
|
||||
descriptionClassName = "",
|
||||
subdescriptionClassName = "",
|
||||
footerClassName = "",
|
||||
iconBoxClassName = "",
|
||||
iconClassName = "",
|
||||
mediaWrapperClassName = "",
|
||||
mediaClassName = "",
|
||||
}: TestimonialAboutCardProps) => {
|
||||
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 grid grid-cols-1 md:grid-cols-5 gap-6", containerClassName)}>
|
||||
<div className={cls("relative md:col-span-3 card rounded-theme-capped p-8 md:p-12", cardClassName)}>
|
||||
<div className={cls(
|
||||
"absolute -top-7 -left-7 md:-top-8 md:-left-8 primary-button rounded-theme-capped h-14 md:h-16 w-auto aspect-square flex items-center justify-center",
|
||||
iconBoxClassName
|
||||
)}>
|
||||
<Icon className={cls("h-5/10 text-background", iconClassName)} strokeWidth={1.5} />
|
||||
</div>
|
||||
|
||||
<div className={cls("relative h-full flex flex-col justify-center gap-4 md:gap-6 py-8 md:py-4", contentClassName)}>
|
||||
<Tag
|
||||
text={tag}
|
||||
icon={tagIcon}
|
||||
className={cls("mb-1", tagClassName)}
|
||||
/>
|
||||
|
||||
<h2 className={cls("text-3xl md:text-4xl font-medium text-foreground leading-tight", titleClassName)}>
|
||||
{title}
|
||||
</h2>
|
||||
|
||||
<div className={cls("flex items-center gap-2", footerClassName)}>
|
||||
<span className={cls("text-base text-foreground", descriptionClassName)}>
|
||||
{description}
|
||||
</span>
|
||||
<span className="text-accent">•</span>
|
||||
<span className={cls("text-base text-foreground/75", subdescriptionClassName)}>
|
||||
{subdescription}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={cls("md:col-span-2 card aspect-square rounded-theme-capped overflow-hidden", mediaWrapperClassName)}>
|
||||
<MediaContent
|
||||
imageSrc={imageSrc}
|
||||
videoSrc={videoSrc}
|
||||
imageAlt={imageAlt}
|
||||
videoAriaLabel={videoAriaLabel}
|
||||
imageClassName={cls("w-full h-full object-cover", mediaClassName)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
TestimonialAboutCard.displayName = "TestimonialAboutCard";
|
||||
|
||||
export default TestimonialAboutCard;
|
||||
Reference in New Issue
Block a user