"use client"; import CardList from "@/components/cardStack/CardList"; 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"; import type { ButtonConfig, ButtonAnimationType, TitleSegment, CardAnimationType } from "@/components/cardStack/types"; import type { TextboxLayout, InvertedBackground } from "@/providers/themeProvider/config/constants"; export type { PhoneApp, PhoneApps8, ChatExchange, TimelineItem, MediaStackItem, TaskItem, OrbitingItem }; 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; buttons?: ButtonConfig[]; }; export type FeatureCard = BaseFeatureCard & ( | { bentoComponent: "icon-info-cards"; items: BentoInfoItem[]; } | { bentoComponent: "3d-stack-cards"; items: [Bento3DItem, Bento3DItem, Bento3DItem]; } | { bentoComponent: "3d-task-list"; bentoTitle: 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"; } | { 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 FeatureTimelineBentoProps { features: FeatureCard[]; animationType: CardAnimationType; 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; textBoxDescriptionClassName?: string; textBoxClassName?: string; textBoxTagClassName?: string; textBoxButtonContainerClassName?: string; textBoxButtonClassName?: string; textBoxButtonTextClassName?: string; titleImageWrapperClassName?: string; titleImageClassName?: string; cardContentClassName?: string; stepNumberClassName?: string; cardTitleClassName?: string; cardDescriptionClassName?: string; bentoContainerClassName?: string; cardButtonClassName?: string; cardButtonTextClassName?: string; } const FeatureTimelineBento = ({ features, animationType, title, titleSegments, description, tag, tagIcon, tagAnimation, buttons, buttonAnimation, textboxLayout, useInvertedBackground, ariaLabel = "Feature section", className = "", containerClassName = "", cardClassName = "", textBoxTitleClassName = "", textBoxDescriptionClassName = "", textBoxClassName = "", textBoxTagClassName = "", textBoxButtonContainerClassName = "", textBoxButtonClassName = "", textBoxButtonTextClassName = "", titleImageWrapperClassName = "", titleImageClassName = "", cardContentClassName = "", stepNumberClassName = "", cardTitleClassName = "", cardDescriptionClassName = "", bentoContainerClassName = "", cardButtonClassName = "", cardButtonTextClassName = "", }: FeatureTimelineBentoProps) => { 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) => (

{index + 1}

{feature.title}

{feature.description}

{feature.buttons && feature.buttons.length > 0 && (
{feature.buttons.slice(0, 2).map((button, btnIndex) => (
)}
{getBentoComponent(feature)}
))}
); }; export default FeatureTimelineBento;