435 lines
21 KiB
TypeScript
435 lines
21 KiB
TypeScript
'use client'
|
|
|
|
import { useEffect, useState } from 'react'
|
|
import Link from 'next/link'
|
|
import { isAuthenticated } from '@/lib/auth'
|
|
import { Button } from '@/components/ui/button'
|
|
import { HeroSection, UseCaseShowcase, HowItWorks, Differentiators, SocialProof, FinalCTA } from '@/components/landing/LandingSections'
|
|
import { LiveStatsBar } from '@/components/landing/LiveStatsBar'
|
|
import { PricingComparison } from '@/components/landing/PricingComparison'
|
|
import { SectionDivider } from '@/components/landing/MagneticElements'
|
|
import { motion, AnimatePresence } from 'framer-motion'
|
|
import { Check, ChevronDown, Monitor, Globe, Shield, Clock, Zap, Menu } from 'lucide-react'
|
|
|
|
export default function Home() {
|
|
const [loading, setLoading] = useState(true)
|
|
const [isAuth, setIsAuth] = useState(false)
|
|
const [openFaq, setOpenFaq] = useState<number | null>(null)
|
|
const [billingPeriod, setBillingPeriod] = useState<'monthly' | 'yearly'>('monthly')
|
|
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
|
|
const [scrollProgress, setScrollProgress] = useState(0)
|
|
|
|
useEffect(() => {
|
|
// Check auth status but DO NOT redirect
|
|
const auth = isAuthenticated()
|
|
setIsAuth(auth)
|
|
setLoading(false)
|
|
}, [])
|
|
|
|
// Scroll progress tracking
|
|
useEffect(() => {
|
|
const handleScroll = () => {
|
|
const totalScroll = document.documentElement.scrollHeight - window.innerHeight
|
|
const progress = totalScroll > 0 ? (window.scrollY / totalScroll) * 100 : 0
|
|
setScrollProgress(progress)
|
|
}
|
|
|
|
window.addEventListener('scroll', handleScroll, { passive: true })
|
|
return () => window.removeEventListener('scroll', handleScroll)
|
|
}, [])
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className="flex min-h-screen items-center justify-center bg-background">
|
|
<div className="flex flex-col items-center gap-4">
|
|
<div className="h-8 w-8 animate-spin rounded-full border-2 border-primary border-t-transparent" />
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
const faqs = [
|
|
{
|
|
question: 'What is website monitoring?',
|
|
answer: 'Website monitoring is the process of testing and verifying that end-users can interact with a website or web application as expected. It continuously checks your website for changes, downtime, or performance issues.'
|
|
},
|
|
{
|
|
question: 'How fast are the alerts?',
|
|
answer: 'Our alerts are sent within seconds of detecting a change. You can configure notifications via email, webhook, Slack, or other integrations.'
|
|
},
|
|
{
|
|
question: 'Can I monitor SSL certificates?',
|
|
answer: 'Yes! We automatically monitor SSL certificate expiration and will alert you before your certificate expires.'
|
|
},
|
|
{
|
|
question: 'Do you offer a free trial?',
|
|
answer: 'Yes, we offer a free Starter plan that includes 3 monitors with hourly checks. No credit card required.'
|
|
}
|
|
]
|
|
|
|
return (
|
|
<div className="min-h-screen bg-background text-foreground font-sans selection:bg-primary/20 selection:text-primary">
|
|
{/* Header */}
|
|
<header className="fixed top-0 z-50 w-full border-b border-border/40 bg-background/80 backdrop-blur-xl supports-[backdrop-filter]:bg-background/60">
|
|
<div className="mx-auto flex h-16 max-w-7xl items-center justify-between px-6 transition-all duration-200">
|
|
<div className="flex items-center gap-8">
|
|
<Link href="/" className="flex items-center gap-2 group">
|
|
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary transition-transform group-hover:scale-110 shadow-lg shadow-primary/20">
|
|
<Monitor className="h-5 w-5 text-primary-foreground" />
|
|
</div>
|
|
<span className="text-lg font-bold tracking-tight text-foreground">MonitorTool</span>
|
|
</Link>
|
|
<nav className="hidden items-center gap-6 md:flex">
|
|
<Link href="#features" className="text-sm font-medium text-muted-foreground hover:text-foreground transition-colors">Features</Link>
|
|
<Link href="#pricing" className="text-sm font-medium text-muted-foreground hover:text-foreground transition-colors">Pricing</Link>
|
|
</nav>
|
|
</div>
|
|
<div className="flex items-center gap-3">
|
|
{isAuth ? (
|
|
<Link href="/dashboard">
|
|
<Button size="sm" className="bg-primary hover:bg-primary/90 text-primary-foreground rounded-full px-5 transition-transform hover:scale-105 active:scale-95 shadow-md shadow-primary/20">
|
|
Dashboard
|
|
</Button>
|
|
</Link>
|
|
) : (
|
|
<Link href="/register">
|
|
<Button size="sm" className="bg-primary hover:bg-primary/90 text-primary-foreground rounded-full px-5 transition-transform hover:scale-105 active:scale-95 shadow-md shadow-primary/20">
|
|
Get Started
|
|
</Button>
|
|
</Link>
|
|
)}
|
|
|
|
{/* Mobile Menu Button */}
|
|
<button
|
|
className="md:hidden p-2 text-muted-foreground hover:text-foreground"
|
|
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
|
>
|
|
<Menu className="h-6 w-6" />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Mobile Menu */}
|
|
<AnimatePresence>
|
|
{mobileMenuOpen && (
|
|
<motion.div
|
|
initial={{ height: 0, opacity: 0 }}
|
|
animate={{ height: "auto", opacity: 1 }}
|
|
exit={{ height: 0, opacity: 0 }}
|
|
className="md:hidden border-t border-border bg-background px-6 py-4 shadow-lg overflow-hidden"
|
|
>
|
|
<div className="flex flex-col gap-4">
|
|
<Link href="#features" onClick={() => setMobileMenuOpen(false)} className="text-sm font-medium text-muted-foreground hover:text-foreground">Features</Link>
|
|
<Link href="#pricing" onClick={() => setMobileMenuOpen(false)} className="text-sm font-medium text-muted-foreground hover:text-foreground">Pricing</Link>
|
|
{!isAuth && (
|
|
<>
|
|
<Link href="/register" onClick={() => setMobileMenuOpen(false)} className="text-sm font-medium text-primary font-bold">Get Started</Link>
|
|
</>
|
|
)}
|
|
</div>
|
|
</motion.div>
|
|
)}
|
|
</AnimatePresence>
|
|
</header >
|
|
|
|
{/* Scroll Progress Indicator */}
|
|
<motion.div
|
|
className="fixed top-16 left-0 right-0 h-1 bg-[hsl(var(--teal))] z-50 origin-left"
|
|
style={{ scaleX: scrollProgress / 100 }}
|
|
initial={{ scaleX: 0 }}
|
|
/>
|
|
|
|
{/* Hero Section */}
|
|
<HeroSection isAuthenticated={isAuth} />
|
|
|
|
{/* Live Stats Bar */}
|
|
<LiveStatsBar />
|
|
|
|
{/* Use Case Showcase */}
|
|
<UseCaseShowcase />
|
|
|
|
{/* Section Divider: Use Cases -> How It Works */}
|
|
<SectionDivider variant="wave" toColor="section-bg-4" />
|
|
|
|
{/* How It Works */}
|
|
<HowItWorks />
|
|
|
|
{/* Differentiators */}
|
|
<Differentiators />
|
|
|
|
{/* Section Divider: Differentiators -> Pricing */}
|
|
<SectionDivider variant="curve" toColor="section-bg-6" />
|
|
|
|
{/* Pricing Comparison */}
|
|
<PricingComparison />
|
|
|
|
{/* Social Proof */}
|
|
<SocialProof />
|
|
|
|
{/* Pricing Section */}
|
|
< section id="pricing" className="border-t border-border/40 bg-[hsl(var(--section-bg-2))] py-24" >
|
|
<div className="mx-auto max-w-7xl px-6">
|
|
<div className="mb-16 text-center">
|
|
<h2 className="mb-4 text-3xl font-bold sm:text-4xl text-foreground">
|
|
Simple pricing, no hidden fees
|
|
</h2>
|
|
<p className="mb-8 text-lg text-muted-foreground">
|
|
Start for free and scale as you grow. Change plans anytime.
|
|
</p>
|
|
<div className="inline-flex items-center rounded-full bg-background p-1.5 shadow-sm border border-border">
|
|
<button
|
|
onClick={() => setBillingPeriod('monthly')}
|
|
className={`rounded-full px-6 py-2 text-sm font-medium transition-all duration-200 ${billingPeriod === 'monthly' ? 'bg-foreground text-background shadow' : 'text-muted-foreground hover:bg-secondary/50'
|
|
}`}
|
|
>
|
|
Monthly
|
|
</button>
|
|
<button
|
|
onClick={() => setBillingPeriod('yearly')}
|
|
className={`rounded-full px-6 py-2 text-sm font-medium transition-all duration-200 ${billingPeriod === 'yearly' ? 'bg-foreground text-background shadow' : 'text-muted-foreground hover:bg-secondary/50'
|
|
}`}
|
|
>
|
|
Yearly <span className="ml-1 text-[10px] opacity-80">(Save 20%)</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid gap-8 md:grid-cols-3 max-w-6xl mx-auto">
|
|
{/* Starter Plan */}
|
|
<motion.div
|
|
whileHover={{ y: -5 }}
|
|
transition={{ duration: 0.2 }}
|
|
className="rounded-3xl border border-border bg-card p-8 shadow-sm hover:shadow-xl hover:border-primary/20 transition-all"
|
|
>
|
|
<h3 className="mb-2 text-xl font-bold text-foreground">Starter</h3>
|
|
<p className="text-sm text-muted-foreground mb-6">Perfect for side projects</p>
|
|
<div className="mb-8">
|
|
<span className="text-5xl font-bold tracking-tight text-foreground">$0</span>
|
|
<span className="text-muted-foreground ml-2">/mo</span>
|
|
</div>
|
|
<ul className="mb-8 space-y-4">
|
|
<li className="flex items-center gap-3 text-sm text-foreground">
|
|
<div className="h-5 w-5 rounded-full bg-secondary flex items-center justify-center text-primary">
|
|
<Check className="h-3 w-3" />
|
|
</div>
|
|
3 monitors
|
|
</li>
|
|
<li className="flex items-center gap-3 text-sm text-foreground">
|
|
<div className="h-5 w-5 rounded-full bg-secondary flex items-center justify-center text-primary">
|
|
<Check className="h-3 w-3" />
|
|
</div>
|
|
Hourly checks
|
|
</li>
|
|
<li className="flex items-center gap-3 text-sm text-foreground">
|
|
<div className="h-5 w-5 rounded-full bg-secondary flex items-center justify-center text-primary">
|
|
<Check className="h-3 w-3" />
|
|
</div>
|
|
Email alerts
|
|
</li>
|
|
</ul>
|
|
<Button variant="outline" className="w-full rounded-xl h-11 border-border hover:bg-secondary/50 hover:text-foreground">
|
|
Get Started
|
|
</Button>
|
|
</motion.div>
|
|
|
|
{/* Pro Plan */}
|
|
<motion.div
|
|
whileHover={{ y: -5 }}
|
|
transition={{ duration: 0.2 }}
|
|
className="relative rounded-3xl border-2 border-primary bg-card p-8 shadow-2xl shadow-primary/10 z-10 scale-105"
|
|
>
|
|
<div className="absolute -top-4 left-1/2 -translate-x-1/2 rounded-full bg-primary px-4 py-1 text-xs font-bold text-primary-foreground shadow-lg">
|
|
MOST POPULAR
|
|
</div>
|
|
<h3 className="mb-2 text-xl font-bold text-foreground">Pro</h3>
|
|
<p className="text-sm text-muted-foreground mb-6">For serious businesses</p>
|
|
<div className="mb-8">
|
|
<span className="text-5xl font-bold tracking-tight text-foreground">${billingPeriod === 'monthly' ? '29' : '24'}</span>
|
|
<span className="text-muted-foreground ml-2">/mo</span>
|
|
</div>
|
|
<ul className="mb-8 space-y-4">
|
|
<li className="flex items-center gap-3 text-sm text-foreground">
|
|
<div className="h-5 w-5 rounded-full bg-primary/20 flex items-center justify-center text-primary">
|
|
<Check className="h-3 w-3" />
|
|
</div>
|
|
50 monitors
|
|
</li>
|
|
<li className="flex items-center gap-3 text-sm text-foreground">
|
|
<div className="h-5 w-5 rounded-full bg-primary/20 flex items-center justify-center text-primary">
|
|
<Check className="h-3 w-3" />
|
|
</div>
|
|
1-minute checks
|
|
</li>
|
|
<li className="flex items-center gap-3 text-sm text-foreground">
|
|
<div className="h-5 w-5 rounded-full bg-primary/20 flex items-center justify-center text-primary">
|
|
<Check className="h-3 w-3" />
|
|
</div>
|
|
All alert channels (Slack/SMS)
|
|
</li>
|
|
<li className="flex items-center gap-3 text-sm text-foreground">
|
|
<div className="h-5 w-5 rounded-full bg-primary/20 flex items-center justify-center text-primary">
|
|
<Check className="h-3 w-3" />
|
|
</div>
|
|
SSL monitoring
|
|
</li>
|
|
</ul>
|
|
<Button className="w-full bg-primary hover:bg-primary/90 text-primary-foreground rounded-xl h-11 shadow-lg shadow-primary/20 font-semibold">
|
|
Get Started
|
|
</Button>
|
|
</motion.div>
|
|
|
|
{/* Enterprise Plan */}
|
|
<motion.div
|
|
whileHover={{ y: -5 }}
|
|
transition={{ duration: 0.2 }}
|
|
className="rounded-3xl border border-border bg-card p-8 shadow-sm hover:shadow-xl hover:border-border transition-all"
|
|
>
|
|
<h3 className="mb-2 text-xl font-bold text-foreground">Enterprise</h3>
|
|
<p className="text-sm text-muted-foreground mb-6">Custom solutions</p>
|
|
<div className="mb-8">
|
|
<span className="text-4xl font-bold tracking-tight text-foreground">Custom</span>
|
|
</div>
|
|
<ul className="mb-8 space-y-4">
|
|
<li className="flex items-center gap-3 text-sm text-foreground">
|
|
<div className="h-5 w-5 rounded-full bg-secondary flex items-center justify-center text-muted-foreground">
|
|
<Check className="h-3 w-3" />
|
|
</div>
|
|
Unlimited monitors
|
|
</li>
|
|
<li className="flex items-center gap-3 text-sm text-foreground">
|
|
<div className="h-5 w-5 rounded-full bg-secondary flex items-center justify-center text-muted-foreground">
|
|
<Check className="h-3 w-3" />
|
|
</div>
|
|
30-second checks
|
|
</li>
|
|
<li className="flex items-center gap-3 text-sm text-foreground">
|
|
<div className="h-5 w-5 rounded-full bg-secondary flex items-center justify-center text-muted-foreground">
|
|
<Check className="h-3 w-3" />
|
|
</div>
|
|
SSO & SAML
|
|
</li>
|
|
<li className="flex items-center gap-3 text-sm text-foreground">
|
|
<div className="h-5 w-5 rounded-full bg-secondary flex items-center justify-center text-muted-foreground">
|
|
<Check className="h-3 w-3" />
|
|
</div>
|
|
Dedicated support
|
|
</li>
|
|
</ul>
|
|
<Button variant="outline" className="w-full rounded-xl h-11 border-border hover:bg-secondary/50 hover:text-foreground">
|
|
Contact Sales
|
|
</Button>
|
|
</motion.div>
|
|
</div>
|
|
</div>
|
|
</section >
|
|
|
|
{/* FAQ Section */}
|
|
< section id="faq" className="border-t border-border/40 py-24 bg-background" >
|
|
<div className="mx-auto max-w-3xl px-6">
|
|
<h2 className="mb-12 text-center text-3xl font-bold sm:text-4xl text-foreground">
|
|
Frequently Asked Questions
|
|
</h2>
|
|
|
|
<div className="space-y-4">
|
|
{faqs.map((faq, index) => (
|
|
<motion.div
|
|
key={index}
|
|
className="rounded-2xl border border-border bg-card overflow-hidden"
|
|
initial={false}
|
|
>
|
|
<button
|
|
onClick={() => setOpenFaq(openFaq === index ? null : index)}
|
|
className="flex w-full items-center justify-between p-6 text-left hover:bg-secondary/30 transition-colors"
|
|
>
|
|
<span className="font-medium text-foreground">{faq.question}</span>
|
|
<ChevronDown
|
|
className={`h-5 w-5 text-muted-foreground transition-transform duration-300 ${openFaq === index ? 'rotate-180' : ''}`}
|
|
/>
|
|
</button>
|
|
<AnimatePresence>
|
|
{openFaq === index && (
|
|
<motion.div
|
|
initial={{ height: 0, opacity: 0 }}
|
|
animate={{ height: "auto", opacity: 1 }}
|
|
exit={{ height: 0, opacity: 0 }}
|
|
className="border-t border-border px-6 pb-6 pt-4 text-muted-foreground bg-secondary/5"
|
|
>
|
|
{faq.answer}
|
|
</motion.div>
|
|
)}
|
|
</AnimatePresence>
|
|
</motion.div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section >
|
|
|
|
{/* Final CTA */}
|
|
<FinalCTA isAuthenticated={isAuth} />
|
|
|
|
{/* Footer */}
|
|
< footer className="border-t border-border bg-background py-12 text-sm" >
|
|
<div className="mx-auto max-w-7xl px-6">
|
|
<div className="grid gap-12 md:grid-cols-4 lg:grid-cols-5">
|
|
<div className="md:col-span-2">
|
|
<div className="mb-6 flex items-center gap-2">
|
|
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary">
|
|
<Monitor className="h-5 w-5 text-primary-foreground" />
|
|
</div>
|
|
<span className="text-lg font-bold text-foreground">MonitorTool</span>
|
|
</div>
|
|
<p className="text-muted-foreground max-w-xs mb-6">
|
|
The modern platform for uptime monitoring, change detection, and performance tracking.
|
|
</p>
|
|
<div className="flex gap-4">
|
|
{/* Social icons placeholders */}
|
|
<div className="h-8 w-8 rounded-full bg-secondary hover:bg-border transition-colors cursor-pointer flex items-center justify-center text-muted-foreground hover:text-foreground">
|
|
<Globe className="h-4 w-4" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<h4 className="mb-4 font-semibold text-foreground">Product</h4>
|
|
<ul className="space-y-3 text-muted-foreground">
|
|
<li><Link href="#features" className="hover:text-primary transition-colors">Features</Link></li>
|
|
<li><Link href="#pricing" className="hover:text-primary transition-colors">Pricing</Link></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div>
|
|
<h4 className="mb-4 font-semibold text-foreground">Company</h4>
|
|
<ul className="space-y-3 text-muted-foreground">
|
|
<li><Link href="#" className="hover:text-primary transition-colors">About</Link></li>
|
|
<li><Link href="#" className="hover:text-primary transition-colors">Blog</Link></li>
|
|
<li><Link href="#" className="hover:text-primary transition-colors">Careers</Link></li>
|
|
<li><Link href="#" className="hover:text-primary transition-colors">Contact</Link></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div>
|
|
<h4 className="mb-4 font-semibold text-foreground">Legal</h4>
|
|
<ul className="space-y-3 text-muted-foreground">
|
|
<li><Link href="#" className="hover:text-primary transition-colors">Privacy</Link></li>
|
|
<li><Link href="#" className="hover:text-primary transition-colors">Terms</Link></li>
|
|
<li><Link href="#" className="hover:text-primary transition-colors">Cookie Policy</Link></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mt-12 flex flex-col items-center justify-between gap-4 border-t border-border pt-8 text-sm text-muted-foreground sm:flex-row">
|
|
<p>© 2026 MonitorTool. All rights reserved.</p>
|
|
<div className="flex items-center gap-2">
|
|
<span className="relative flex h-2 w-2">
|
|
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"></span>
|
|
<span className="relative inline-flex rounded-full h-2 w-2 bg-green-500"></span>
|
|
</span>
|
|
System Operational
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</footer >
|
|
</div >
|
|
)
|
|
}
|