'use client'; import Link from 'next/link'; import { useRouter, useSearchParams } from 'next/navigation'; import { useState } from 'react'; import { Loader2 } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; export default function PortalLoginPage() { const router = useRouter(); const search = useSearchParams(); const next = search.get('next') ?? '/portal/dashboard'; const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); async function handleSubmit(e: React.FormEvent) { e.preventDefault(); setError(''); setLoading(true); try { const res = await fetch('/api/portal/auth/sign-in', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password }), }); if (!res.ok) { const data = await res.json().catch(() => ({})); setError((data as { error?: string }).error ?? 'Invalid email or password'); return; } // typedRoutes: `next` is a runtime string we can't statically check. router.replace(next as never); router.refresh(); } catch { setError('Unable to connect. Please try again.'); } finally { setLoading(false); } } return (

Client Portal

Sign in to your account

setEmail(e.target.value)} required autoFocus autoComplete="email" disabled={loading} />
Forgot password?
setPassword(e.target.value)} required autoComplete="current-password" disabled={loading} />
{error &&

{error}

}

This portal is for existing clients only.

); }