fix: wrap login page in Suspense (useSearchParams prerender crash)
- /login page used useSearchParams() without Suspense boundary - Next.js 16 requires Suspense for useSearchParams during static prerender - Extracted LoginForm component, wrapped in <Suspense> - Removed --webpack flag (default Turbopack build now works) - Build passes cleanly: ✓ Compiled successfully
This commit is contained in:
1 parent
576a85cd50
commit
ece8626137
2 files changed
+32
-24
No files matched your search
+31
-23
@@ -1,13 +1,13 @@
|
||||
'use client'
|
||||
|
||||
import { useState } from 'react'
|
||||
import { Suspense, useState } from 'react'
|
||||
import { useRouter, useSearchParams } from 'next/navigation'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import { Loader2, Lock } from 'lucide-react'
|
||||
|
||||
export default function LoginPage() {
|
||||
function LoginForm() {
|
||||
const router = useRouter()
|
||||
const searchParams = useSearchParams()
|
||||
const redirect = searchParams.get('redirect') || '/'
|
||||
@@ -40,6 +40,32 @@ export default function LoginPage() {
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit} className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="password">Passwort</Label>
|
||||
<Input
|
||||
id="password"
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
placeholder="Admin-Passwort eingeben"
|
||||
autoFocus
|
||||
autoComplete="current-password"
|
||||
/>
|
||||
</div>
|
||||
{error && (
|
||||
<p className="text-sm text-red-600 dark:text-red-400">{error}</p>
|
||||
)}
|
||||
<Button type="submit" className="w-full gap-2" disabled={loading || !password}>
|
||||
{loading && <Loader2 className="size-4 animate-spin" />}
|
||||
Anmelden
|
||||
</Button>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
||||
export default function LoginPage() {
|
||||
return (
|
||||
<div className="flex min-h-screen items-center justify-center bg-background p-4">
|
||||
<div className="w-full max-w-sm space-y-6">
|
||||
@@ -53,27 +79,9 @@ export default function LoginPage() {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="password">Passwort</Label>
|
||||
<Input
|
||||
id="password"
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
placeholder="Admin-Passwort eingeben"
|
||||
autoFocus
|
||||
autoComplete="current-password"
|
||||
/>
|
||||
</div>
|
||||
{error && (
|
||||
<p className="text-sm text-red-600 dark:text-red-400">{error}</p>
|
||||
)}
|
||||
<Button type="submit" className="w-full gap-2" disabled={loading || !password}>
|
||||
{loading && <Loader2 className="size-4 animate-spin" />}
|
||||
Anmelden
|
||||
</Button>
|
||||
</form>
|
||||
<Suspense fallback={<div className="text-center text-sm text-muted-foreground">Laden…</div>}>
|
||||
<LoginForm />
|
||||
</Suspense>
|
||||
|
||||
<p className="text-center text-xs text-muted-foreground">
|
||||
Geschützter Bereich — nur für autorisierte Benutzer.
|
||||
|
||||
Reference in new issue
Block a user