From c2d998832ceb78b6ae5780944946e340a0412701 Mon Sep 17 00:00:00 2001 From: development Date: Fri, 23 Jan 2026 17:23:57 +0000 Subject: [PATCH] Update src/components/cardStack/layouts/timelines/TimelineBase.tsx --- .../layouts/timelines/TimelineBase.tsx | 216 +++++++----------- 1 file changed, 84 insertions(+), 132 deletions(-) diff --git a/src/components/cardStack/layouts/timelines/TimelineBase.tsx b/src/components/cardStack/layouts/timelines/TimelineBase.tsx index 4a34c66..fb548fa 100644 --- a/src/components/cardStack/layouts/timelines/TimelineBase.tsx +++ b/src/components/cardStack/layouts/timelines/TimelineBase.tsx @@ -1,143 +1,95 @@ -"use client"; +import React from 'react'; -import React, { Children, useCallback } from "react"; -import { cls } from "@/lib/utils"; -import CardStackTextBox from "../../CardStackTextBox"; -import { useCardAnimation } from "../../hooks/useCardAnimation"; -import type { LucideIcon } from "lucide-react"; -import type { ButtonConfig, CardAnimationType, TitleSegment } from "../../types"; -import type { TextboxLayout, InvertedBackground } from "@/providers/themeProvider/config/constants"; - -type TimelineVariant = "timeline"; - -interface TimelineBaseProps { - children: React.ReactNode; - variant?: TimelineVariant; - uniformGridCustomHeightClasses?: string; - animationType: CardAnimationType; - title?: string; - titleSegments?: TitleSegment[]; - description?: string; - tag?: string; - tagIcon?: LucideIcon; - buttons?: ButtonConfig[]; - textboxLayout?: TextboxLayout; - useInvertedBackground?: InvertedBackground; - className?: string; - containerClassName?: string; - textBoxClassName?: string; - titleClassName?: string; - titleImageWrapperClassName?: string; - titleImageClassName?: string; - descriptionClassName?: string; - tagClassName?: string; - buttonContainerClassName?: string; - buttonClassName?: string; - buttonTextClassName?: string; - ariaLabel?: string; +interface TimelineItem { + id: string; + title: string; + description: string; + date: string; + status: 'completed' | 'active' | 'pending'; } -const TimelineBase = ({ - children, - variant = "timeline", - uniformGridCustomHeightClasses = "min-h-80 2xl:min-h-90", - animationType, - title, - titleSegments, - description, - tag, - tagIcon, - buttons, - textboxLayout = "default", - useInvertedBackground, - className = "", - containerClassName = "", - textBoxClassName = "", - titleClassName = "", - titleImageWrapperClassName = "", - titleImageClassName = "", - descriptionClassName = "", - tagClassName = "", - buttonContainerClassName = "", - buttonClassName = "", - buttonTextClassName = "", - ariaLabel = "Timeline section", -}: TimelineBaseProps) => { - const childrenArray = Children.toArray(children); - const { itemRefs } = useCardAnimation({ - animationType, - itemCount: childrenArray.length, - isGrid: false - }); +interface TimelineBaseProps { + items: TimelineItem[]; + orientation?: 'vertical' | 'horizontal'; + variant?: 'default' | 'compact' | 'detailed'; + className?: string; +} - const getItemClasses = useCallback((index: number) => { - // Timeline variant - scattered/organic pattern - const alignmentClass = - index % 2 === 0 ? "self-start ml-0" : "self-end mr-0"; +export const TimelineBase: React.FC = ({ + items, + orientation = 'vertical', + className = '' +}) => { + const getStatusColor = (status: TimelineItem['status']) => { + switch (status) { + case 'completed': + return 'bg-green-500'; + case 'active': + return 'bg-blue-500'; + case 'pending': + return 'bg-gray-300'; + default: + return 'bg-gray-300'; + } + }; - const marginClasses = cls( - index % 4 === 0 && "md:ml-0", - index % 4 === 1 && "md:mr-20", - index % 4 === 2 && "md:ml-15", - index % 4 === 3 && "md:mr-30" + const getTextColor = (status: TimelineItem['status']) => { + switch (status) { + case 'completed': + return 'text-green-700'; + case 'active': + return 'text-blue-700'; + case 'pending': + return 'text-gray-500'; + default: + return 'text-gray-500'; + } + }; + + if (orientation === 'horizontal') { + return ( +
+ {items.map((item, index) => ( +
+
+
+
+
+ {item.title} +
+
{item.date}
+
+
+ {index < items.length - 1 && ( +
+ )} +
+ ))} +
); - - return cls(alignmentClass, marginClasses); - }, []); + } return ( -
-
- {(title || titleSegments || description) && ( - - )} -
- {Children.map(childrenArray, (child, index) => ( -
{ itemRefs.current[index] = el; }} - > - {child} +
+ {items.map((item, index) => ( +
+
+
+ {index < items.length - 1 && ( +
+ )} +
+
+
+ {item.title}
- ))} +
+ {item.description} +
+
{item.date}
+
-
-
+ ))} +
); -}; - -TimelineBase.displayName = "TimelineBase"; - -export default React.memo(TimelineBase); +}; \ No newline at end of file