Files
cloudrite/components/hero.tsx
T
v0andASOwnerYT 36a3a05596 fix: cleanup hero component and remove unused imports
Adjust title padding and replace fake stats; remove scroll indicator
and unused ChevronDown import.

Co-authored-by: ASOwnerYT <[email protected]>
2026-03-20 00:24:41 +00:00

200 lines
6.9 KiB
TypeScript

"use client"
import { useEffect, useRef, useState } from "react"
import { Button } from "@/components/ui/button"
import { ArrowRight } from "lucide-react"
import Link from "next/link"
function FloatingElement({ delay = 0, duration = 20, children, className = "" }: {
delay?: number
duration?: number
children: React.ReactNode
className?: string
}) {
return (
<div
className={`absolute pointer-events-none ${className}`}
style={{
animation: `float ${duration}s ease-in-out ${delay}s infinite`,
}}
>
{children}
</div>
)
}
function GridPattern() {
return (
<div className="absolute inset-0 overflow-hidden opacity-20">
<div className="absolute inset-0" style={{
backgroundImage: `
linear-gradient(rgba(74, 222, 128, 0.1) 1px, transparent 1px),
linear-gradient(90deg, rgba(74, 222, 128, 0.1) 1px, transparent 1px)
`,
backgroundSize: '60px 60px'
}} />
</div>
)
}
function AnimatedText({ text, className = "" }: { text: string; className?: string }) {
const [isVisible, setIsVisible] = useState(false)
const ref = useRef<HTMLDivElement>(null)
useEffect(() => {
const timer = setTimeout(() => setIsVisible(true), 300)
return () => clearTimeout(timer)
}, [])
return (
<div ref={ref} className={`overflow-hidden ${className}`}>
<div
className={`transition-all duration-1000 ease-out ${
isVisible ? "translate-y-0 opacity-100" : "translate-y-full opacity-0"
}`}
>
{text}
</div>
</div>
)
}
export function Hero() {
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 })
const containerRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
if (containerRef.current) {
const rect = containerRef.current.getBoundingClientRect()
setMousePosition({
x: (e.clientX - rect.left - rect.width / 2) / 50,
y: (e.clientY - rect.top - rect.height / 2) / 50,
})
}
}
window.addEventListener("mousemove", handleMouseMove)
return () => window.removeEventListener("mousemove", handleMouseMove)
}, [])
return (
<section
ref={containerRef}
className="relative min-h-screen flex items-center justify-center overflow-hidden pt-20"
>
{/* Background Elements */}
<GridPattern />
{/* Floating decorative elements */}
<FloatingElement delay={0} duration={25} className="top-[15%] left-[10%]">
<div className="w-32 h-32 border border-primary/20 rounded-full" />
</FloatingElement>
<FloatingElement delay={5} duration={30} className="top-[60%] right-[15%]">
<div className="w-24 h-24 border border-primary/30 rotate-45" />
</FloatingElement>
<FloatingElement delay={10} duration={22} className="bottom-[20%] left-[20%]">
<div className="w-16 h-16 bg-primary/10 rounded-lg" />
</FloatingElement>
{/* Glow effect */}
<div
className="absolute w-[600px] h-[600px] rounded-full bg-primary/10 blur-[120px] transition-transform duration-500 ease-out"
style={{
transform: `translate(${mousePosition.x * 2}px, ${mousePosition.y * 2}px)`,
}}
/>
<div className="relative z-10 mx-auto max-w-7xl px-6 lg:px-8 text-center">
{/* Badge */}
<div className="inline-flex items-center gap-2 px-4 py-2 mb-8 border border-border rounded-full bg-card/50 backdrop-blur-sm animate-fade-in">
<span className="w-2 h-2 bg-primary rounded-full animate-pulse" />
<span className="text-sm text-muted-foreground">Auckland, New Zealand</span>
</div>
{/* Main Heading */}
<h1 className="text-5xl md:text-7xl lg:text-8xl font-bold tracking-tight leading-[1.05] mb-8">
<AnimatedText text="Every Business" className="mb-2 pb-1" />
<AnimatedText text="Needs an" className="mb-2 pb-1" />
<span className="relative inline-block pb-2">
<AnimatedText
text="I.T Guy"
className="text-primary"
/>
<div className="absolute -inset-2 bg-primary/20 blur-2xl -z-10 animate-pulse" />
</span>
</h1>
{/* Subtitle */}
<p className="max-w-2xl mx-auto text-lg md:text-xl text-muted-foreground mb-12 animate-fade-in animation-delay-500">
From websites and cloud infrastructure to computer repairs and I.T support
we help small businesses thrive in the digital world.
</p>
{/* CTA Buttons */}
<div className="flex flex-col sm:flex-row items-center justify-center gap-4 animate-fade-in animation-delay-700">
<Button
asChild
size="lg"
className="group bg-primary text-primary-foreground hover:bg-primary/90 px-8 py-6 text-lg transition-all duration-300 hover:scale-105 hover:shadow-xl hover:shadow-primary/25"
>
<Link href="#contact">
Let&apos;s Talk
<ArrowRight className="ml-2 w-5 h-5 transition-transform duration-300 group-hover:translate-x-1" />
</Link>
</Button>
<Button
asChild
variant="outline"
size="lg"
className="px-8 py-6 text-lg border-border hover:bg-card hover:border-primary/50 transition-all duration-300"
>
<Link href="#services">Our Services</Link>
</Button>
</div>
{/* Stats */}
<div className="mt-20 grid grid-cols-3 gap-8 max-w-lg mx-auto animate-fade-in animation-delay-1000">
{[
{ value: "24/7", label: "Support Available" },
{ value: "NZ", label: "Hosted Locally" },
{ value: "Auckland", label: "Based Business" },
].map((stat, index) => (
<div
key={stat.label}
className="group cursor-default"
style={{ animationDelay: `${1200 + index * 100}ms` }}
>
<div className="text-3xl md:text-4xl font-bold text-foreground transition-colors duration-300 group-hover:text-primary">
{stat.value}
</div>
<div className="text-sm text-muted-foreground mt-1">{stat.label}</div>
</div>
))}
</div>
</div>
<style jsx>{`
@keyframes float {
0%, 100% { transform: translateY(0px) rotate(0deg); }
50% { transform: translateY(-20px) rotate(5deg); }
}
.animate-fade-in {
animation: fadeIn 0.8s ease-out forwards;
opacity: 0;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.animation-delay-500 { animation-delay: 500ms; }
.animation-delay-700 { animation-delay: 700ms; }
.animation-delay-1000 { animation-delay: 1000ms; }
`}</style>
</section>
)
}