Complete visual overhaul with distinctive editorial aesthetic: Design System: - New fonts: Fraunces (display) + DM Sans (body) - Color palette: Cream background, ink text, coral accents - Custom CSS variables and utility classes - Sharp edges (no rounded corners) for editorial feel Components: - Updated Button with new variants and colors - Updated Input with editorial styling - New card-editorial class with accent bar Pages: - Homepage: Full redesign with hero, features, CTA - Auth layout: Split screen with branding side - Login/Register: Editorial styling with tags - Dashboard: Cards with accent bars - Subscription: Clean feature comparison table Typography: - Fraunces for all headings (serif, characterful) - DM Sans for body text (clean, readable) - Editorial tags (uppercase, accent color) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
97 lines
2.7 KiB
TypeScript
97 lines
2.7 KiB
TypeScript
'use client'
|
|
|
|
import { Button } from '@/components/ui/button'
|
|
import { Input } from '@/components/ui/input'
|
|
import Link from 'next/link'
|
|
import { useState } from 'react'
|
|
import { createClient } from '@/lib/supabase/client'
|
|
import { useRouter } from 'next/navigation'
|
|
|
|
export function LoginForm() {
|
|
const [email, setEmail] = useState('')
|
|
const [password, setPassword] = useState('')
|
|
const [error, setError] = useState<string | null>(null)
|
|
const [loading, setLoading] = useState(false)
|
|
const router = useRouter()
|
|
const supabase = createClient()
|
|
|
|
async function handleSubmit(e: React.FormEvent) {
|
|
e.preventDefault()
|
|
setError(null)
|
|
setLoading(true)
|
|
|
|
const { error: signInError } = await supabase.auth.signInWithPassword({
|
|
email,
|
|
password,
|
|
})
|
|
|
|
if (signInError) {
|
|
// SPECIFIC error messages per user requirement
|
|
if (signInError.message.includes('Invalid login credentials')) {
|
|
setError('Email o password errata')
|
|
} else if (signInError.message.includes('Email not confirmed')) {
|
|
setError('Devi confermare la tua email prima di accedere')
|
|
} else {
|
|
setError(signInError.message)
|
|
}
|
|
setLoading(false)
|
|
return
|
|
}
|
|
|
|
router.push('/dashboard')
|
|
router.refresh()
|
|
}
|
|
|
|
return (
|
|
<form onSubmit={handleSubmit} className="space-y-5">
|
|
{error && (
|
|
<div className="p-4 bg-error-light border-l-4 border-error">
|
|
<p className="text-error text-sm">{error}</p>
|
|
</div>
|
|
)}
|
|
|
|
<div>
|
|
<label htmlFor="email" className="block text-sm font-medium text-ink mb-2">
|
|
Email
|
|
</label>
|
|
<Input
|
|
id="email"
|
|
name="email"
|
|
type="email"
|
|
autoComplete="email"
|
|
required
|
|
placeholder="tu@esempio.com"
|
|
value={email}
|
|
onChange={(e) => setEmail(e.target.value)}
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label htmlFor="password" className="block text-sm font-medium text-ink mb-2">
|
|
Password
|
|
</label>
|
|
<Input
|
|
id="password"
|
|
name="password"
|
|
type="password"
|
|
autoComplete="current-password"
|
|
required
|
|
placeholder="La tua password"
|
|
value={password}
|
|
onChange={(e) => setPassword(e.target.value)}
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex items-center justify-end">
|
|
<Link href="/reset-password/" className="text-sm text-accent hover:underline">
|
|
Password dimenticata?
|
|
</Link>
|
|
</div>
|
|
|
|
<Button type="submit" className="w-full h-12 text-base" disabled={loading}>
|
|
{loading ? 'Accesso in corso...' : 'Accedi'}
|
|
</Button>
|
|
</form>
|
|
)
|
|
}
|