diff --git a/src/components/sections/feature/FeatureBento.tsx b/src/components/sections/feature/FeatureBento.tsx index 258c9c1..462ddb5 100644 --- a/src/components/sections/feature/FeatureBento.tsx +++ b/src/components/sections/feature/FeatureBento.tsx @@ -1,28 +1,300 @@ -import React from "react"; -import { CardStack } from "@/components/cardStack/CardStack"; +"use client"; + +import CardStack from "@/components/cardStack/CardStack"; +import Button from "@/components/button/Button"; +import { cls, shouldUseInvertedText } from "@/lib/utils"; +import { getButtonProps } from "@/lib/buttonUtils"; +import { useTheme } from "@/providers/themeProvider/ThemeProvider"; +import { BentoGlobe } from "@/components/bento/BentoGlobe"; +import BentoIconInfoCards from "@/components/bento/BentoIconInfoCards"; +import BentoAnimatedBarChart from "@/components/bento/BentoAnimatedBarChart"; +import Bento3DStackCards from "@/components/bento/Bento3DStackCards"; +import Bento3DTaskList, { type TaskItem } from "@/components/bento/Bento3DTaskList"; +import BentoOrbitingIcons, { type OrbitingItem } from "@/components/bento/BentoOrbitingIcons"; +import BentoMap from "@/components/bento/BentoMap"; +import BentoMarquee from "@/components/bento/BentoMarquee"; +import BentoLineChart from "@/components/bento/BentoLineChart/BentoLineChart"; +import BentoPhoneAnimation, { type PhoneApp, type PhoneApps8 } from "@/components/bento/BentoPhoneAnimation"; +import BentoChatAnimation, { type ChatExchange } from "@/components/bento/BentoChatAnimation"; +import Bento3DCardGrid from "@/components/bento/Bento3DCardGrid"; +import BentoRevealIcon from "@/components/bento/BentoRevealIcon"; +import BentoTimeline, { type TimelineItem } from "@/components/bento/BentoTimeline"; +import BentoMediaStack, { type MediaStackItem } from "@/components/bento/BentoMediaStack"; +import type { LucideIcon } from "lucide-react"; + +export type { PhoneApp, PhoneApps8, ChatExchange, TimelineItem, MediaStackItem }; +import type { ButtonConfig, CardAnimationTypeWith3D, TitleSegment, ButtonAnimationType } from "@/components/cardStack/types"; + +import type { TextboxLayout, InvertedBackground } from "@/providers/themeProvider/config/constants"; + +type BentoAnimationType = Exclude; + +export type BentoInfoItem = { + icon: LucideIcon; + label: string; + value: string; +}; + +export type Bento3DItem = { + icon: LucideIcon; + title: string; + subtitle: string; + detail: string; +}; + +type BaseFeatureCard = { + title: string; + description: string; + button?: ButtonConfig; +}; + +export type FeatureCard = BaseFeatureCard & ( + | { + bentoComponent: "icon-info-cards"; + items: BentoInfoItem[]; + } + | { + bentoComponent: "3d-stack-cards"; + items: [Bento3DItem, Bento3DItem, Bento3DItem]; + } + | { + bentoComponent: "3d-task-list"; + title: string; + items: TaskItem[]; + } + | { + bentoComponent: "orbiting-icons"; + centerIcon: LucideIcon; + items: OrbitingItem[]; + } + | ({ + bentoComponent: "marquee"; + centerIcon: LucideIcon; + } & ( + | { variant: "text"; texts: string[] } + | { variant: "icon"; icons: LucideIcon[] } + )) + | { + bentoComponent: "globe" | "animated-bar-chart" | "map" | "line-chart"; + items?: never; + } + | { + bentoComponent: "3d-card-grid"; + items: [{ name: string; icon: LucideIcon }, { name: string; icon: LucideIcon }, { name: string; icon: LucideIcon }, { name: string; icon: LucideIcon }]; + centerIcon: LucideIcon; + } + | { + bentoComponent: "phone"; + statusIcon: LucideIcon; + alertIcon: LucideIcon; + alertTitle: string; + alertMessage: string; + apps: PhoneApps8; + } + | { + bentoComponent: "chat"; + aiIcon: LucideIcon; + userIcon: LucideIcon; + exchanges: ChatExchange[]; + placeholder: string; + } + | { + bentoComponent: "reveal-icon"; + icon: LucideIcon; + } + | { + bentoComponent: "timeline"; + heading: string; + subheading: string; + items: [TimelineItem, TimelineItem, TimelineItem]; + completedLabel: string; + } + | { + bentoComponent: "media-stack"; + items: [MediaStackItem, MediaStackItem, MediaStackItem]; + } +); interface FeatureBentoProps { - features?: any[]; - title?: string; - description?: string; - animationType?: string; - textboxLayout?: string; - useInvertedBackground?: boolean; + features: FeatureCard[]; + carouselMode?: "auto" | "buttons"; + animationType: BentoAnimationType; + title: string; + titleSegments?: TitleSegment[]; + description: string; + tag?: string; + tagIcon?: LucideIcon; + tagAnimation?: ButtonAnimationType; + buttons?: ButtonConfig[]; + buttonAnimation?: ButtonAnimationType; + textboxLayout: TextboxLayout; + useInvertedBackground: InvertedBackground; + ariaLabel?: string; + className?: string; + containerClassName?: string; + cardClassName?: string; + textBoxTitleClassName?: string; + textBoxTitleImageWrapperClassName?: string; + textBoxTitleImageClassName?: string; + textBoxDescriptionClassName?: string; + cardTitleClassName?: string; + cardDescriptionClassName?: string; + cardButtonClassName?: string; + cardButtonTextClassName?: string; + gridClassName?: string; + carouselClassName?: string; + controlsClassName?: string; + textBoxClassName?: string; + textBoxTagClassName?: string; + textBoxButtonContainerClassName?: string; + textBoxButtonClassName?: string; + textBoxButtonTextClassName?: string; } -export default function FeatureBento({ - features = [], - title = "Features", description = "Our features", animationType = "slide-up", textboxLayout = "default", useInvertedBackground = false, -}: FeatureBentoProps) { - const items = features.map((feature) => ({ - id: feature.id, - label: feature.title, - detail: feature.description, - })); +const FeatureBento = ({ + features, + carouselMode = "buttons", + animationType, + title, + titleSegments, + description, + tag, + tagIcon, + tagAnimation, + buttons, + buttonAnimation, + textboxLayout, + useInvertedBackground, + ariaLabel = "Feature section", + className = "", + containerClassName = "", + cardClassName = "", + textBoxTitleClassName = "", + textBoxTitleImageWrapperClassName = "", + textBoxTitleImageClassName = "", + textBoxDescriptionClassName = "", + cardTitleClassName = "", + cardDescriptionClassName = "", + cardButtonClassName = "", + cardButtonTextClassName = "", + gridClassName = "", + carouselClassName = "", + controlsClassName = "", + textBoxClassName = "", + textBoxTagClassName = "", + textBoxButtonContainerClassName = "", + textBoxButtonClassName = "", + textBoxButtonTextClassName = "", +}: FeatureBentoProps) => { + const theme = useTheme(); + const shouldUseLightText = shouldUseInvertedText(useInvertedBackground, theme.cardStyle); + + const getBentoComponent = (feature: FeatureCard) => { + switch (feature.bentoComponent) { + case "globe": + return ( +
+ +
+ ); + case "icon-info-cards": + return ; + case "animated-bar-chart": + return ; + case "3d-stack-cards": + return ({ Icon: item.icon, title: item.title, subtitle: item.subtitle, detail: item.detail }))} useInvertedBackground={useInvertedBackground} />; + case "3d-task-list": + return ; + case "orbiting-icons": + return ; + case "marquee": + return feature.variant === "text" + ? + : ; + case "map": + return ; + case "line-chart": + return ; + case "3d-card-grid": + return ; + case "phone": + return ; + case "chat": + return ; + case "reveal-icon": + return ; + case "timeline": + return ; + case "media-stack": + return ; + } + }; return ( -
- -
+ + {features.map((feature, index) => ( +
+
+ {getBentoComponent(feature)} +
+
+

+ {feature.title} +

+

+ {feature.description} +

+
+ {feature.button && ( +
+ ))} +
); -} +}; + +FeatureBento.displayName = "FeatureBento"; + +export default FeatureBento;