Yves Gugger 1f72f2664d
Some checks failed
CI / Frontend Lint & Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Backend Lint (push) Has been cancelled
CI / Backend Tests (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
Deploy / Build & Push Images (push) Has been cancelled
Deploy / Deploy to Server (push) Has been cancelled
Deploy / Notify (push) Has been cancelled
fix: Portfolio page redesign, unified DNS verification, fix API route conflicts
2025-12-14 21:44:40 +01:00

221 lines
8.2 KiB
TypeScript

'use client'
import { useEffect, useState } from 'react'
import { useRouter, useSearchParams } from 'next/navigation'
import { TerminalLayout } from '@/components/TerminalLayout'
import { PageContainer } from '@/components/PremiumTable'
import { useStore } from '@/lib/store'
import {
CheckCircle,
Zap,
Crown,
ArrowRight,
Eye,
Store,
Bell,
BarChart3,
Sparkles,
TrendingUp,
} from 'lucide-react'
import Link from 'next/link'
import clsx from 'clsx'
const planDetails = {
trader: {
name: 'Trader',
icon: TrendingUp,
color: 'text-accent',
bgColor: 'bg-accent/10',
features: [
{ icon: Eye, text: '50 domains in watchlist', description: 'Track up to 50 domains at once' },
{ icon: Zap, text: 'Hourly availability checks', description: '24x faster than Scout' },
{ icon: Store, text: '10 For Sale listings', description: 'List your domains on the marketplace' },
{ icon: Bell, text: '5 Sniper Alerts', description: 'Get notified when specific domains drop' },
{ icon: BarChart3, text: 'Deal scores & valuations', description: 'Know what domains are worth' },
],
nextSteps: [
{ href: '/terminal/watchlist', label: 'Add domains to watchlist', icon: Eye },
{ href: '/terminal/market', label: 'Browse the market', icon: Store },
{ href: '/terminal/intel', label: 'Check TLD pricing', icon: BarChart3 },
],
},
tycoon: {
name: 'Tycoon',
icon: Crown,
color: 'text-amber-400',
bgColor: 'bg-amber-400/10',
features: [
{ icon: Eye, text: '500 domains in watchlist', description: 'Massive tracking capacity' },
{ icon: Zap, text: 'Real-time checks (10 min)', description: 'Never miss a drop' },
{ icon: Store, text: '50 For Sale listings', description: 'Full marketplace access' },
{ icon: Bell, text: 'Unlimited Sniper Alerts', description: 'Set as many as you need' },
{ icon: Sparkles, text: 'SEO Juice Detector', description: 'Find domains with backlinks' },
],
nextSteps: [
{ href: '/terminal/watchlist', label: 'Add domains to watchlist', icon: Eye },
{ href: '/terminal/market', label: 'Browse the market', icon: Store },
{ href: '/terminal/listing', label: 'List your domains', icon: Sparkles },
],
},
}
export default function WelcomePage() {
const router = useRouter()
const searchParams = useSearchParams()
const { fetchSubscription, checkAuth } = useStore()
const [loading, setLoading] = useState(true)
const [showConfetti, setShowConfetti] = useState(true)
const planId = searchParams.get('plan') as 'trader' | 'tycoon' | null
const plan = planId && planDetails[planId] ? planDetails[planId] : planDetails.trader
useEffect(() => {
const init = async () => {
await checkAuth()
await fetchSubscription()
setLoading(false)
}
init()
// Hide confetti after animation
const timer = setTimeout(() => setShowConfetti(false), 3000)
return () => clearTimeout(timer)
}, [checkAuth, fetchSubscription])
if (loading) {
return (
<TerminalLayout title="Welcome" subtitle="Loading your new plan...">
<PageContainer>
<div className="flex items-center justify-center py-20">
<div className="w-8 h-8 border-2 border-accent border-t-transparent rounded-full animate-spin" />
</div>
</PageContainer>
</TerminalLayout>
)
}
return (
<TerminalLayout title="Welcome" subtitle="Your upgrade is complete">
<PageContainer>
{/* Confetti Effect */}
{showConfetti && (
<div className="fixed inset-0 pointer-events-none z-50 overflow-hidden">
{Array.from({ length: 50 }).map((_, i) => (
<div
key={i}
className="absolute w-2 h-2 rounded-full animate-[confetti_3s_ease-out_forwards]"
style={{
left: `${Math.random() * 100}%`,
top: '-10px',
backgroundColor: ['#10b981', '#f59e0b', '#3b82f6', '#ec4899', '#8b5cf6'][Math.floor(Math.random() * 5)],
animationDelay: `${Math.random() * 0.5}s`,
}}
/>
))}
</div>
)}
{/* Success Header */}
<div className="text-center mb-12">
<div className={clsx(
"inline-flex items-center justify-center w-20 h-20 rounded-full mb-6",
plan.bgColor
)}>
<CheckCircle className={clsx("w-10 h-10", plan.color)} />
</div>
<h1 className="text-3xl sm:text-4xl font-semibold text-foreground mb-3">
Welcome to {plan.name}!
</h1>
<p className="text-lg text-foreground-muted max-w-lg mx-auto">
Your payment was successful. You now have access to all {plan.name} features.
</p>
</div>
{/* Features Unlocked */}
<div className="mb-12">
<h2 className="text-lg font-semibold text-foreground mb-6 text-center">
Features Unlocked
</h2>
<div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-4">
{plan.features.map((feature, i) => (
<div
key={i}
className="p-5 bg-background-secondary/50 border border-border/50 rounded-xl
animate-slide-up"
style={{ animationDelay: `${i * 100}ms` }}
>
<div className="flex items-start gap-4">
<div className={clsx("w-10 h-10 rounded-xl flex items-center justify-center shrink-0", plan.bgColor)}>
<feature.icon className={clsx("w-5 h-5", plan.color)} />
</div>
<div>
<p className="font-medium text-foreground">{feature.text}</p>
<p className="text-sm text-foreground-muted mt-1">{feature.description}</p>
</div>
</div>
</div>
))}
</div>
</div>
{/* Next Steps */}
<div className="mb-12">
<h2 className="text-lg font-semibold text-foreground mb-6 text-center">
Next Steps
</h2>
<div className="max-w-2xl mx-auto space-y-3">
{plan.nextSteps.map((step, i) => (
<Link
key={i}
href={step.href}
className="flex items-center justify-between p-5 bg-background-secondary/50 border border-border/50 rounded-xl
hover:border-accent/30 hover:bg-background-secondary transition-all group"
>
<div className="flex items-center gap-4">
<div className="w-10 h-10 rounded-xl bg-foreground/5 flex items-center justify-center
group-hover:bg-accent/10 transition-colors">
<step.icon className="w-5 h-5 text-foreground-muted group-hover:text-accent transition-colors" />
</div>
<span className="font-medium text-foreground">{step.label}</span>
</div>
<ArrowRight className="w-5 h-5 text-foreground-subtle group-hover:text-accent transition-colors" />
</Link>
))}
</div>
</div>
{/* Go to Dashboard */}
<div className="text-center">
<Link
href="/terminal/radar"
className="inline-flex items-center gap-2 px-8 py-4 bg-accent text-background font-medium rounded-xl
hover:bg-accent-hover transition-all shadow-lg shadow-accent/20"
>
Go to Radar
<ArrowRight className="w-4 h-4" />
</Link>
<p className="text-sm text-foreground-muted mt-4">
Need help? <Link href="mailto:hello@pounce.ch" className="text-accent hover:underline">Contact support</Link>.
</p>
</div>
</PageContainer>
{/* Custom CSS for confetti animation */}
<style jsx>{`
@keyframes confetti {
0% {
transform: translateY(0) rotate(0deg);
opacity: 1;
}
100% {
transform: translateY(100vh) rotate(720deg);
opacity: 0;
}
}
`}</style>
</TerminalLayout>
)
}