91 lines
2.7 KiB
TypeScript
91 lines
2.7 KiB
TypeScript
import { useEffect, useState } from 'react'
|
|
import { Link, useNavigate, useSearch } from '@tanstack/react-router'
|
|
import { MailCheck, MailWarning, Loader2 } from 'lucide-react'
|
|
import { authClient } from '../../lib/auth-client'
|
|
import { AuthShell } from './AuthShell'
|
|
|
|
type SearchParams = {
|
|
token?: string
|
|
email?: string
|
|
}
|
|
|
|
type Status = 'idle' | 'verifying' | 'success' | 'error'
|
|
|
|
export function VerifyEmailPage() {
|
|
const { token, email } = useSearch({ strict: false }) as SearchParams
|
|
const navigate = useNavigate()
|
|
const [status, setStatus] = useState<Status>(token ? 'verifying' : 'idle')
|
|
|
|
useEffect(() => {
|
|
if (!token || status !== 'verifying') return
|
|
let cancelled = false
|
|
authClient
|
|
.verifyEmail({ query: { token } })
|
|
.then(async ({ error }) => {
|
|
if (cancelled) return
|
|
if (error) {
|
|
setStatus('error')
|
|
return
|
|
}
|
|
await authClient.getSession()
|
|
navigate({ to: '/' })
|
|
})
|
|
.catch(() => {
|
|
if (!cancelled) setStatus('error')
|
|
})
|
|
return () => {
|
|
cancelled = true
|
|
}
|
|
}, [token, status, navigate])
|
|
|
|
const title =
|
|
status === 'success'
|
|
? 'Email verificado'
|
|
: status === 'error'
|
|
? 'Vínculo inválido'
|
|
: 'Verificá tu email'
|
|
|
|
return (
|
|
<AuthShell title={title}>
|
|
<div className="flex flex-col items-center gap-4 py-2 text-center">
|
|
{status === 'verifying' ? (
|
|
<Loader2 className="size-10 animate-spin text-accent" />
|
|
) : status === 'success' ? (
|
|
<MailCheck className="size-10 text-success" />
|
|
) : (
|
|
<MailWarning className="size-10 text-warning" />
|
|
)}
|
|
|
|
{status === 'success' ? (
|
|
<p className="text-sm text-foreground/60">
|
|
Tu cuenta quedó verificada. Te estamos llevando a Gruperly…
|
|
</p>
|
|
) : status === 'error' ? (
|
|
<p className="text-sm text-foreground/60">
|
|
El vínculo de verificación no es válido o expiró.
|
|
</p>
|
|
) : (
|
|
<p className="text-sm text-foreground/60">
|
|
Te enviamos un correo a <span className="font-medium text-primary">{email}</span> para
|
|
confirmar tu cuenta.
|
|
</p>
|
|
)}
|
|
|
|
{status === 'success' ? (
|
|
<Link
|
|
to="/"
|
|
className="w-full rounded-xl bg-accent py-2 text-center text-sm font-medium text-on-accent hover:bg-accent-strong"
|
|
>
|
|
Ir a Gruperly
|
|
</Link>
|
|
) : null}
|
|
|
|
{status === 'error' ? (
|
|
<Link to="/login" className="text-sm font-medium text-accent hover:underline">
|
|
Intentar iniciar sesión
|
|
</Link>
|
|
) : null}
|
|
</div>
|
|
</AuthShell>
|
|
)
|
|
} |