yves.gugger 48368fe026 feat: Replace text logo with puma icon
Changes:
- Added pounce-logo.png to /public
- Updated Header.tsx: Replaced text logo with Image component
- Updated Footer.tsx: Replaced text logo with Image component
- Updated login/page.tsx: Replaced text logo with Image component
- Updated register/page.tsx: Replaced text logo with Image component

Logo sizing:
- Header: 32px (mobile) / 36px (desktop)
- Footer: 40px
- Login/Register: 48px

All logos use Next.js Image component for optimization
2025-12-08 10:47:16 +01:00

181 lines
6.7 KiB
TypeScript

'use client'
import { useState } from 'react'
import { useRouter } from 'next/navigation'
import Link from 'next/link'
import Image from 'next/image'
import { useStore } from '@/lib/store'
import { Loader2, ArrowRight, Check, Eye, EyeOff } from 'lucide-react'
// Logo Component - Puma Image
function Logo() {
return (
<Image
src="/pounce-logo.png"
alt="pounce"
width={48}
height={48}
className="w-12 h-12"
/>
)
}
const benefits = [
'Monitor up to 3 domains free',
'Daily availability checks',
'Instant email notifications',
'Track expiration dates',
]
export default function RegisterPage() {
const router = useRouter()
const { register } = useStore()
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [showPassword, setShowPassword] = useState(false)
const [error, setError] = useState<string | null>(null)
const [loading, setLoading] = useState(false)
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
setError(null)
setLoading(true)
try {
await register(email, password)
router.push('/dashboard')
} catch (err) {
setError(err instanceof Error ? err.message : 'Registration failed')
} finally {
setLoading(false)
}
}
return (
<div className="min-h-screen flex relative">
{/* Ambient glow */}
<div className="fixed inset-0 pointer-events-none">
<div className="absolute top-1/4 left-1/3 w-[400px] h-[300px] bg-accent/[0.02] rounded-full blur-3xl" />
</div>
{/* Left Panel - Form */}
<div className="flex-1 flex items-center justify-center px-4 sm:px-6 py-8 sm:py-12">
<div className="relative w-full max-w-sm animate-fade-in">
{/* Logo */}
<Link href="/" className="block mb-12 sm:mb-16 hover:opacity-80 transition-opacity duration-300">
<Logo />
</Link>
{/* Header */}
<div className="mb-8 sm:mb-10">
<h1 className="font-display text-[2rem] sm:text-[2.5rem] md:text-[3rem] leading-[1.1] tracking-[-0.03em] text-foreground mb-2 sm:mb-3">Create your account</h1>
<p className="text-body-sm sm:text-body text-foreground-muted">
Start monitoring domains in under a minute
</p>
</div>
{/* Form */}
<form onSubmit={handleSubmit} className="space-y-3 sm:space-y-4">
{error && (
<div className="p-3 sm:p-4 bg-danger-muted border border-danger/20 rounded-2xl">
<p className="text-danger text-body-xs sm:text-body-sm">{error}</p>
</div>
)}
<div className="space-y-2.5 sm:space-y-3">
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Email address"
required
className="input-elegant text-body-sm sm:text-body"
/>
<div className="relative">
<input
type={showPassword ? 'text' : 'password'}
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Create password (min. 8 characters)"
required
minLength={8}
className="input-elegant text-body-sm sm:text-body pr-12"
/>
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute right-3 sm:right-4 top-1/2 -translate-y-1/2 text-foreground-muted hover:text-foreground transition-colors duration-200"
aria-label={showPassword ? 'Hide password' : 'Show password'}
>
{showPassword ? (
<EyeOff className="w-4 h-4 sm:w-5 sm:h-5" />
) : (
<Eye className="w-4 h-4 sm:w-5 sm:h-5" />
)}
</button>
</div>
</div>
<button
type="submit"
disabled={loading}
className="w-full py-3 sm:py-4 bg-foreground text-background text-ui-sm sm:text-ui font-medium rounded-xl
hover:bg-foreground/90 disabled:opacity-50 disabled:cursor-not-allowed
transition-all duration-300 flex items-center justify-center gap-2 sm:gap-2.5"
>
{loading ? (
<Loader2 className="w-4 h-4 animate-spin" />
) : (
<>
Get Started
<ArrowRight className="w-3.5 sm:w-4 h-3.5 sm:h-4" />
</>
)}
</button>
</form>
{/* Login Link */}
<p className="mt-8 sm:mt-10 text-body-xs sm:text-body-sm text-foreground-muted">
Already have an account?{' '}
<Link href="/login" className="text-foreground hover:text-accent transition-colors duration-300">
Sign in
</Link>
</p>
</div>
</div>
{/* Right Panel - Benefits */}
<div className="hidden lg:flex flex-1 bg-background-secondary/50 items-center justify-center p-8 xl:p-12 border-l border-border-subtle">
<div className="max-w-sm animate-slide-up delay-200">
<div className="inline-flex items-center gap-2 sm:gap-2.5 px-3 sm:px-4 py-1.5 sm:py-2 bg-background-tertiary border border-border rounded-full mb-8 sm:mb-10">
<div className="w-1.5 h-1.5 rounded-full bg-accent" />
<span className="text-ui-sm sm:text-ui text-foreground-muted">Free Plan Included</span>
</div>
<h2 className="font-display text-[1.75rem] sm:text-[2.25rem] md:text-[2.75rem] leading-[1.15] tracking-[-0.025em] text-foreground mb-8 sm:mb-10">
Everything you need to get started
</h2>
<ul className="space-y-4 sm:space-y-5">
{benefits.map((item) => (
<li key={item} className="flex items-center gap-3 sm:gap-4">
<div className="w-8 sm:w-9 h-8 sm:h-9 rounded-lg bg-accent/10 flex items-center justify-center shrink-0">
<Check className="w-3.5 sm:w-4 h-3.5 sm:h-4 text-accent" strokeWidth={2.5} />
</div>
<span className="text-body-sm sm:text-body text-foreground-muted">{item}</span>
</li>
))}
</ul>
<div className="divider my-8 sm:my-10" />
<p className="text-body-xs sm:text-body-sm text-foreground-subtle">
No credit card required. Upgrade anytime.
</p>
</div>
</div>
</div>
)
}