"use client";
import Image from "next/image";
import { useEffect, useRef, useState } from "react";
import { Icons } from "@/components/icons";
import { Button } from "@/components/ui/button";
const steps = [
{
card: "features",
description:
"Minimal, organized structure to help you manage, sort, and access every task.",
number: 1,
title: "Smarter Task Management Flow",
},
{
card: "workflow",
description:
"Minimal, organized structure to help you manage, sort, and access every task.",
number: 2,
title: "Smarter Task Management Flow",
},
{
card: "analytics",
description:
"Minimal, organized structure to help you manage, sort, and access every task.",
number: 3,
title: "Smarter Task Management Flow",
},
];
const featuresList = [
{ icon: Icons.inbox, label: "Streamlined Organization", number: "#01" },
{ dot: true, icon: null, label: "Powerful Integrations", number: "#02" },
{ dot: true, icon: null, label: "Real-Time Updates", number: "#03" },
{ dot: true, icon: null, label: "Seamless Collaboration", number: "#04" },
];
const workflowTabs = ["Design", "Edit", "Publish", "Manage"];
export default function Component() {
const sectionRef = useRef<HTMLElement>(null);
const timelineRef = useRef<HTMLDivElement>(null);
const [progress, setProgress] = useState(0);
useEffect(() => {
const handleScroll = () => {
if (!sectionRef.current || !timelineRef.current) return;
const section = sectionRef.current;
const rect = section.getBoundingClientRect();
const sectionTop = rect.top;
const sectionHeight = rect.height;
const windowHeight = window.innerHeight;
// Calculate progress based on scroll position
const scrollStart = windowHeight * 0.3;
const scrollEnd = -sectionHeight + windowHeight * 0.7;
if (sectionTop > scrollStart) {
setProgress(0);
} else if (sectionTop < scrollEnd) {
setProgress(100);
} else {
const totalScroll = scrollStart - scrollEnd;
const currentScroll = scrollStart - sectionTop;
const percentage = (currentScroll / totalScroll) * 100;
setProgress(Math.min(100, Math.max(0, percentage)));
}
};
window.addEventListener("scroll", handleScroll);
handleScroll();
return () => window.removeEventListener("scroll", handleScroll);
}, []);
return (
<section
className="relative w-full overflow-hidden bg-white py-24 dark:bg-background"
ref={sectionRef}
>
<div className="relative z-10 mx-auto max-w-5xl px-6 lg:px-0">
{/* Header */}
<div className="mb-16 text-center">
<p className="mb-4 font-medium text-neutral-500 text-sm uppercase tracking-wide dark:text-neutral-400">
OVERLINE TEXT
</p>
<h1 className="mb-4 font-medium text-4xl text-neutral-900 tracking-tight sm:text-5xl dark:text-neutral-100">
Learn how it works
</h1>
<p className="text-neutral-600 dark:text-neutral-400">
A short and simple subheading can be added here
</p>
</div>
{/* Timeline Container */}
<div className="relative">
{/* Timeline Line */}
<div
className="absolute top-0 left-1/2 h-full w-px -translate-x-1/2"
ref={timelineRef}
>
{/* Background line */}
<div className="absolute inset-0 bg-neutral-200 dark:bg-neutral-800" />
{/* Progress line */}
<div
className="absolute top-0 left-0 w-full bg-blue-600 transition-all duration-100"
style={{ height: `${progress}%` }}
/>
</div>
{/* Steps */}
<div className="space-y-24">
{steps.map((step, index) => (
<div
className="relative grid grid-cols-1 gap-8 md:grid-cols-2"
key={step.number}
>
{/* Left Content */}
<div className="flex flex-col pr-12">
{/* Step Number */}
<div
className={`mb-6 flex h-12 w-12 items-center justify-center rounded-full font-semibold text-lg transition-colors duration-300 ${
progress >= (index / steps.length) * 100
? "bg-blue-600 text-white"
: "bg-neutral-100 text-neutral-900 dark:bg-neutral-800 dark:text-neutral-100"
}`}
>
{step.number}
</div>
{/* Title & Description */}
<h3 className="mb-3 font-semibold text-2xl text-neutral-900 tracking-tight dark:text-neutral-100">
{step.title}
</h3>
<p className="mb-6 max-w-sm text-neutral-600 dark:text-neutral-400">
{step.description}
</p>
<Button
className="w-fit rounded-lg border border-neutral-200 bg-white px-4 py-2 font-medium text-neutral-900 text-sm hover:bg-neutral-100 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-100 dark:hover:bg-neutral-800"
variant="outline"
>
Learn more
</Button>
</div>
{/* Right Content - Card */}
<div className="relative pl-12">
{/* Step Number Label */}
<div className="absolute top-0 left-16 text-neutral-400 text-sm">
0{step.number}
</div>
{/* Card */}
<div className="mt-8 rounded-2xl border border-neutral-200 bg-white p-6 dark:border-neutral-800 dark:bg-neutral-900">
{step.card === "features" && (
<div className="space-y-4">
{featuresList.map((feature, idx) => (
<div
className="flex items-center justify-between"
key={feature.label}
>
<div className="flex items-center gap-3">
{idx === 0 ? (
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-blue-600">
<Icons.inbox className="size-4 text-white" />
</div>
) : (
<div className="flex h-3 w-3 items-center justify-center">
<div className="h-2 w-2 rounded-full bg-blue-600" />
</div>
)}
<span className="rounded-full border border-neutral-200 bg-white px-3 py-1 text-neutral-900 text-sm dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-100">
{feature.label}
</span>
</div>
<span className="text-neutral-400 text-sm">
{feature.number}
</span>
</div>
))}
</div>
)}
{step.card === "workflow" && (
<div className="flex flex-col items-center">
{/* Top Icons */}
<div className="mb-4 flex items-center gap-2">
<div className="flex h-10 w-10 items-center justify-center rounded-xl border border-neutral-200 bg-white dark:border-neutral-700 dark:bg-neutral-800">
<Icons.targetArrow className="size-5 text-neutral-600 dark:text-neutral-400" />
</div>
<div className="flex h-10 w-10 items-center justify-center rounded-xl border border-neutral-200 bg-white dark:border-neutral-700 dark:bg-neutral-800">
<Icons.archive className="size-5 text-neutral-600 dark:text-neutral-400" />
</div>
<div className="flex h-10 w-10 items-center justify-center rounded-xl border border-neutral-200 bg-white dark:border-neutral-700 dark:bg-neutral-800">
<Icons.user className="size-5 text-neutral-600 dark:text-neutral-400" />
</div>
</div>
{/* Connecting Line */}
<div className="mb-4 h-8 w-px bg-neutral-200 dark:bg-neutral-700" />
{/* Logo */}
<div className="mb-4 flex h-16 w-16 items-center justify-center rounded-2xl bg-blue-600 shadow-lg">
<svg
className="h-8 w-8 text-white"
fill="currentColor"
viewBox="0 0 24 24"
>
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z" />
</svg>
</div>
{/* Tabs */}
<div className="flex flex-wrap items-center justify-center gap-2">
{workflowTabs.map((tab) => (
<span
className="rounded-full border border-neutral-200 bg-white px-4 py-2 text-neutral-900 text-sm dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-100"
key={tab}
>
{tab}
</span>
))}
</div>
</div>
)}
{step.card === "analytics" && (
<div>
{/* Header */}
<div className="mb-4 flex items-center justify-between">
<div>
<h4 className="font-semibold text-neutral-900 dark:text-neutral-100">
Sarah Jones
</h4>
<p className="text-neutral-500 text-sm">
Beam Technology
</p>
</div>
<div className="h-10 w-10 overflow-hidden rounded-full bg-neutral-200 dark:bg-neutral-700">
<Image
alt="Sarah Jones"
className="h-full w-full object-cover"
height={40}
src="https://res.cloudinary.com/dvwtcsh5v/image/upload/v1770279333/a1.jpg"
width={40}
/>
</div>
</div>
{/* Legend */}
<div className="mb-4 flex items-center gap-4">
<div className="flex items-center gap-2">
<div className="h-3 w-3 rounded-sm bg-neutral-300 dark:bg-neutral-600" />
<span className="text-neutral-600 text-sm dark:text-neutral-400">
Free
</span>
</div>
<div className="flex items-center gap-2">
<div className="h-3 w-3 rounded-sm bg-blue-600" />
<span className="text-neutral-600 text-sm dark:text-neutral-400">
Premium
</span>
</div>
</div>
{/* Chart */}
<div className="relative h-24">
<svg
className="h-full w-full"
preserveAspectRatio="none"
viewBox="0 0 200 60"
>
{/* Free line */}
<path
d="M0,50 Q30,45 50,40 T100,35 T150,30 T200,40"
fill="none"
stroke="#d1d5db"
strokeWidth="2"
/>
{/* Premium line */}
<path
d="M0,55 Q30,50 50,45 T100,20 T150,15 T200,35"
fill="none"
stroke="#2563eb"
strokeWidth="2"
/>
</svg>
</div>
{/* X-axis labels */}
<div className="mt-2 flex justify-between text-neutral-400 text-xs">
<span>0</span>
<span>2k</span>
<span>3k</span>
<span>4k</span>
<span>5k</span>
<span>9K</span>
</div>
</div>
)}
</div>
</div>
</div>
))}
</div>
</div>
</div>
</section>
);
}