62 lines
1.6 KiB
TypeScript
62 lines
1.6 KiB
TypeScript
import { useAuth } from '../contexts/AuthContext'
|
|
import { useNavigate } from 'react-router-dom'
|
|
import { useEffect, useState } from 'react'
|
|
import { GoogleSignInButton } from '../components/GoogleSignInButton'
|
|
import { LoginCard } from '../components/LoginCard'
|
|
|
|
export default function LoginPage() {
|
|
const { user, loading, signInWithGoogle } = useAuth()
|
|
const navigate = useNavigate()
|
|
const [signingIn, setSigningIn] = useState(false)
|
|
const [error, setError] = useState<string | null>(null)
|
|
|
|
useEffect(() => {
|
|
if (loading) return
|
|
if (user) {
|
|
navigate('/', { replace: true })
|
|
}
|
|
}, [user, loading, navigate])
|
|
|
|
async function handleGoogleSignIn() {
|
|
setError(null)
|
|
setSigningIn(true)
|
|
try {
|
|
await signInWithGoogle()
|
|
} catch (e) {
|
|
setError(e instanceof Error ? e.message : 'Sign-in failed')
|
|
} finally {
|
|
setSigningIn(false)
|
|
}
|
|
}
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className="login-page">
|
|
<div className="login-page__loading" aria-live="polite">
|
|
<span className="login-page__spinner" aria-hidden />
|
|
<p>Loading…</p>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<div className="login-page">
|
|
<LoginCard
|
|
title="Grateful Journal"
|
|
tagline="A minimal, private space for gratitude and reflection. No feeds, no noise—just you and your thoughts."
|
|
>
|
|
<GoogleSignInButton
|
|
loading={signingIn}
|
|
onClick={handleGoogleSignIn}
|
|
/>
|
|
{error && (
|
|
<p className="login-card__error" role="alert">
|
|
{error}
|
|
</p>
|
|
)}
|
|
</LoginCard>
|
|
</div>
|
|
)
|
|
}
|