Letschat / src /components /forms /LoginForm.tsx
HonzaH's picture
Upload 192 files
7447362 verified
Raw
History Blame Contribute Delete
4.21 kB
'use client'
import { useState } from 'react'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { useRouter } from 'next/navigation'
import { loginSchema, type LoginForm } from 'lib/validations/auth'
import { emitAuthChanged } from 'hooks/useAuth'
import { getSupabaseBrowserConfig, isSupabaseBrowserConfigured } from 'lib/supabase/publicEnv'
export function LoginForm() {
const [loading, setLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
const supabaseReady = isSupabaseBrowserConfigured()
const supabaseEnv = getSupabaseBrowserConfig()
const router = useRouter()
const {
register,
handleSubmit,
formState: { errors }
} = useForm<LoginForm>({
resolver: zodResolver(loginSchema)
})
const onSubmit = async (data: LoginForm) => {
console.info('[login] submit', { supabaseReady, email: data.email, supabaseUrl: supabaseEnv.url })
try {
setLoading(true)
setError(null)
const res = await fetch('/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
credentials: 'include'
})
const json = await res.json().catch(() => ({}))
if (!res.ok) {
setError(json?.error || 'Neplatné přihlašovací údaje')
return
}
// store token from public cookie as fallback for environments where HttpOnly cookie isn't sent
try {
if (typeof window !== 'undefined') {
const match = document.cookie.split(';').map(s => s.trim()).find(c => c.startsWith('letschat_session_pub='))
if (match) {
const token = match.split('=')[1]
window.localStorage.setItem('letschat_session', token)
}
}
} catch (e) {
// ignore
}
emitAuthChanged()
router.push('/dashboard')
} catch (e: any) {
console.error('Login error:', e)
setError(e?.message || 'Došlo k neočekávané chybě při přihlášení')
} finally {
setLoading(false)
}
}
return (
<form id="form-login" action="#" method="post" className="form" onSubmit={handleSubmit(onSubmit)}>
<div className="input">
<div className="text">E-mail</div>
<div className="insert">
<input
{...register('email')}
type="email"
maxLength={255}
placeholder="E-mailová adresa"
autoComplete="email"
/>
<div className="error">{errors.email?.message}</div>
</div>
</div>
<div className="input">
<div className="text">Heslo</div>
<div className="insert">
<input
{...register('password')}
type="password"
maxLength={255}
placeholder="Heslo k přihlášení"
autoComplete="current-password"
/>
<div className="error">{errors.password?.message}</div>
<div className="visible" data-input="password"></div>
</div>
</div>
<div className="input">
<div className="text"></div>
<div className="insert">
{error ? (
<div
className="error"
style={{
marginBottom: 12,
padding: '10px 12px',
background: '#FEE2E2',
color: '#991B1B',
borderRadius: 8,
fontWeight: 600
}}
>
{error}
</div>
) : null}
<input
type="submit"
value={loading ? 'Přihlašuji…' : 'Přihlásit'}
disabled={loading}
onClick={() => console.info('[login] button click', { supabaseReady, supabaseUrl: supabaseEnv.url })}
/>
{!supabaseReady ? (
<div className="error" style={{ marginTop: 8 }}>
Přidejte Supabase klíče do prostředí Space (NEXT_PUBLIC_SUPABASE_URL a NEXT_PUBLIC_SUPABASE_ANON_KEY) a znovu
spusťte build.
</div>
) : null}
</div>
</div>
</form>
)
}