baveshraam's picture
FIX: SurrealDB 2.0 migration syntax and Frontend/CORS link
f871fed
'use client'
import { useState, useEffect } from 'react'
import { useRouter } from 'next/navigation'
import { useAuth } from '@/lib/hooks/use-auth'
import { useAuthStore } from '@/lib/stores/auth-store'
import { getConfig } from '@/lib/config'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { AlertCircle } from 'lucide-react'
import { LoadingSpinner } from '@/components/common/LoadingSpinner'
export function LoginForm() {
const [password, setPassword] = useState('')
const { login, isLoading, error } = useAuth()
const { authRequired, checkAuthRequired, hasHydrated, isAuthenticated } = useAuthStore()
const [isCheckingAuth, setIsCheckingAuth] = useState(true)
const [configInfo, setConfigInfo] = useState<{ apiUrl: string; version: string; buildTime: string } | null>(null)
const router = useRouter()
// Load config info for debugging
useEffect(() => {
getConfig().then(cfg => {
setConfigInfo({
apiUrl: cfg.apiUrl,
version: cfg.version,
buildTime: cfg.buildTime,
})
}).catch(err => {
console.error('Failed to load config:', err)
})
}, [])
// Check if authentication is required on mount
useEffect(() => {
if (!hasHydrated) {
return
}
const checkAuth = async () => {
try {
const required = await checkAuthRequired()
// If auth is not required, redirect to notebooks
if (!required) {
router.push('/notebooks')
}
} catch (error) {
console.error('Error checking auth requirement:', error)
// On error, assume auth is required to be safe
} finally {
setIsCheckingAuth(false)
}
}
// If we already know auth status, use it
if (authRequired !== null) {
if (!authRequired && isAuthenticated) {
router.push('/notebooks')
} else {
setIsCheckingAuth(false)
}
} else {
void checkAuth()
}
}, [hasHydrated, authRequired, checkAuthRequired, router, isAuthenticated])
// Show loading while checking if auth is required
if (!hasHydrated || isCheckingAuth) {
return (
<div className="min-h-screen flex items-center justify-center bg-background">
<LoadingSpinner />
</div>
)
}
// If we still don't know if auth is required (connection error), show error
if (authRequired === null) {
return (
<div className="min-h-screen flex items-center justify-center bg-background p-4">
<Card className="w-full max-w-md">
<CardHeader className="text-center">
<CardTitle>Connection Error</CardTitle>
<CardDescription>
Unable to connect to the API server
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
<div className="flex items-start gap-2 text-red-600 text-sm">
<AlertCircle className="h-4 w-4 mt-0.5 flex-shrink-0" />
<div className="flex-1">
{error || 'Unable to connect to server. Please check if the API is running.'}
</div>
</div>
{configInfo && (
<div className="space-y-2 text-xs text-muted-foreground border-t pt-3">
<div className="font-medium">Diagnostic Information:</div>
<div className="space-y-1 font-mono">
<div>Version: {configInfo.version}</div>
<div>Built: {new Date(configInfo.buildTime).toLocaleString()}</div>
<div className="break-all">API URL: {configInfo.apiUrl}</div>
<div className="break-all">Frontend: {typeof window !== 'undefined' ? window.location.href : 'N/A'}</div>
</div>
<div className="text-xs pt-2">
Check browser console for detailed logs (look for 🔧 [Config] messages)
</div>
</div>
)}
<Button
onClick={() => window.location.reload()}
className="w-full"
>
Retry Connection
</Button>
</div>
</CardContent>
</Card>
</div>
)
}
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (password.trim()) {
try {
await login(password)
} catch (error) {
console.error('Unhandled error during login:', error)
// The auth store should handle most errors, but this catches any unhandled ones
}
}
}
return (
<div className="min-h-screen flex items-center justify-center bg-background p-4">
<Card className="w-full max-w-md">
<CardHeader className="text-center">
<CardTitle>Open Notebook</CardTitle>
<CardDescription>
Enter your password to access the application
</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<Input
type="password"
placeholder="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
disabled={isLoading}
/>
</div>
{error && (
<div className="flex items-center gap-2 text-red-600 text-sm">
<AlertCircle className="h-4 w-4" />
{error}
</div>
)}
<Button
type="submit"
className="w-full"
disabled={isLoading || !password.trim()}
>
{isLoading ? 'Signing in...' : 'Sign In'}
</Button>
{configInfo && (
<div className="text-xs text-center text-muted-foreground pt-2 border-t">
<div>Version {configInfo.version}</div>
<div className="font-mono text-[10px]">{configInfo.apiUrl}</div>
</div>
)}
</form>
</CardContent>
</Card>
</div>
)
}