187 lines
7.3 KiB
TypeScript
187 lines
7.3 KiB
TypeScript
"use client"
|
|
|
|
import { useEffect, useRef, useState } from "react"
|
|
import { MessageCircle, Search, Cog, Rocket } from "lucide-react"
|
|
|
|
const steps = [
|
|
{
|
|
icon: MessageCircle,
|
|
title: "Get in Touch",
|
|
description: "Tell us about your business and what you need. We'll have a friendly chat to understand your goals.",
|
|
color: "from-green-500/20 to-emerald-500/20"
|
|
},
|
|
{
|
|
icon: Search,
|
|
title: "We Assess",
|
|
description: "Our team reviews your current setup and identifies the best solutions for your specific needs.",
|
|
color: "from-emerald-500/20 to-teal-500/20"
|
|
},
|
|
{
|
|
icon: Cog,
|
|
title: "We Build",
|
|
description: "We implement your solution, whether it's a new website, cloud setup, or fixing that stubborn printer.",
|
|
color: "from-teal-500/20 to-cyan-500/20"
|
|
},
|
|
{
|
|
icon: Rocket,
|
|
title: "Launch & Support",
|
|
description: "Go live with confidence. We provide ongoing support to keep everything running smoothly.",
|
|
color: "from-cyan-500/20 to-green-500/20"
|
|
}
|
|
]
|
|
|
|
export function Process() {
|
|
const [activeStep, setActiveStep] = useState(0)
|
|
const [isVisible, setIsVisible] = useState(false)
|
|
const sectionRef = useRef<HTMLElement>(null)
|
|
|
|
useEffect(() => {
|
|
const observer = new IntersectionObserver(
|
|
([entry]) => {
|
|
if (entry.isIntersecting) {
|
|
setIsVisible(true)
|
|
}
|
|
},
|
|
{ threshold: 0.2 }
|
|
)
|
|
|
|
if (sectionRef.current) {
|
|
observer.observe(sectionRef.current)
|
|
}
|
|
|
|
return () => observer.disconnect()
|
|
}, [])
|
|
|
|
return (
|
|
<section
|
|
id="process"
|
|
ref={sectionRef}
|
|
className="relative py-32 overflow-hidden"
|
|
>
|
|
{/* Background */}
|
|
<div className="absolute inset-0 bg-gradient-to-b from-background via-card/30 to-background" />
|
|
|
|
<div className="relative z-10 mx-auto max-w-7xl px-6 lg:px-8">
|
|
{/* Section Header */}
|
|
<div className="text-center mb-20">
|
|
<div className="inline-flex items-center gap-2 px-4 py-2 mb-6 border border-border rounded-full bg-card/50">
|
|
<span className="text-sm text-muted-foreground">How It Works</span>
|
|
</div>
|
|
<h2 className="text-4xl md:text-5xl lg:text-6xl font-bold tracking-tight mb-6">
|
|
<span className="text-balance">Our Simple Process</span>
|
|
</h2>
|
|
<p className="max-w-2xl mx-auto text-lg text-muted-foreground">
|
|
Getting started with Cloudrite is easy. Here's how we work with you
|
|
to transform your business technology.
|
|
</p>
|
|
</div>
|
|
|
|
{/* Process Steps - Desktop */}
|
|
<div className="hidden lg:block">
|
|
{/* Step indicators */}
|
|
<div className="flex justify-between items-center mb-12 px-16">
|
|
{steps.map((step, index) => (
|
|
<div
|
|
key={step.title}
|
|
className="flex flex-col items-center cursor-pointer group"
|
|
onClick={() => setActiveStep(index)}
|
|
>
|
|
<div
|
|
className={`relative w-16 h-16 rounded-2xl flex items-center justify-center transition-all duration-500 ${
|
|
activeStep === index
|
|
? "bg-primary text-primary-foreground scale-110"
|
|
: "bg-card border border-border text-muted-foreground group-hover:border-primary/50"
|
|
}`}
|
|
style={{
|
|
transform: isVisible ? "translateY(0)" : "translateY(20px)",
|
|
opacity: isVisible ? 1 : 0,
|
|
transitionDelay: `${index * 100}ms`,
|
|
}}
|
|
>
|
|
<step.icon className="w-7 h-7" />
|
|
{activeStep === index && (
|
|
<div className="absolute inset-0 bg-primary/30 blur-xl -z-10 animate-pulse" />
|
|
)}
|
|
</div>
|
|
<span
|
|
className={`mt-4 text-sm font-medium transition-colors duration-300 ${
|
|
activeStep === index ? "text-primary" : "text-muted-foreground"
|
|
}`}
|
|
>
|
|
{step.title}
|
|
</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{/* Connecting line */}
|
|
<div className="relative h-1 mx-16 mb-12">
|
|
<div className="absolute inset-0 bg-border rounded-full" />
|
|
<div
|
|
className="absolute top-0 left-0 h-full bg-primary rounded-full transition-all duration-700"
|
|
style={{ width: `${(activeStep / (steps.length - 1)) * 100}%` }}
|
|
/>
|
|
</div>
|
|
|
|
{/* Active step content */}
|
|
<div className="relative bg-card border border-border rounded-3xl p-12 overflow-hidden min-h-[300px]">
|
|
<div className={`absolute inset-0 bg-gradient-to-br ${steps[activeStep].color} opacity-50`} />
|
|
<div className="relative z-10 grid lg:grid-cols-2 gap-12 items-center">
|
|
<div>
|
|
<div className="inline-flex items-center gap-2 px-3 py-1 mb-4 border border-border rounded-full bg-background/50">
|
|
<span className="text-sm text-muted-foreground">Step {activeStep + 1} of {steps.length}</span>
|
|
</div>
|
|
<h3 className="text-4xl font-bold mb-6">{steps[activeStep].title}</h3>
|
|
<p className="text-xl text-muted-foreground leading-relaxed">
|
|
{steps[activeStep].description}
|
|
</p>
|
|
</div>
|
|
<div className="flex justify-center">
|
|
<div className="relative">
|
|
<div className="w-48 h-48 rounded-3xl bg-primary/10 flex items-center justify-center">
|
|
{(() => {
|
|
const StepIcon = steps[activeStep].icon
|
|
return <StepIcon className="w-24 h-24 text-primary" />
|
|
})()}
|
|
</div>
|
|
<div className="absolute inset-0 bg-primary/20 blur-[60px] -z-10" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Process Steps - Mobile */}
|
|
<div className="lg:hidden space-y-6">
|
|
{steps.map((step, index) => {
|
|
const StepIcon = step.icon
|
|
return (
|
|
<div
|
|
key={step.title}
|
|
className={`relative bg-card border border-border rounded-2xl p-6 transition-all duration-500 ${
|
|
isVisible ? "translate-y-0 opacity-100" : "translate-y-8 opacity-0"
|
|
}`}
|
|
style={{ transitionDelay: `${index * 100}ms` }}
|
|
>
|
|
<div className={`absolute inset-0 bg-gradient-to-br ${step.color} opacity-30 rounded-2xl`} />
|
|
<div className="relative z-10">
|
|
<div className="flex items-start gap-4">
|
|
<div className="w-12 h-12 rounded-xl bg-primary/10 flex items-center justify-center flex-shrink-0">
|
|
<StepIcon className="w-6 h-6 text-primary" />
|
|
</div>
|
|
<div>
|
|
<div className="text-xs text-muted-foreground mb-1">Step {index + 1}</div>
|
|
<h3 className="text-xl font-bold mb-2">{step.title}</h3>
|
|
<p className="text-muted-foreground">{step.description}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
})}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
)
|
|
}
|