fix: Wrap useSearchParams in Suspense boundary
Next.js 15 requires useSearchParams() to be wrapped in a Suspense boundary for static page generation. - Split LoginForm into separate component - Add Suspense wrapper with loading skeleton - Fixes build error on /login page 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
56b919fe4a
commit
d21dc88812
|
|
@ -1,6 +1,6 @@
|
||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useState } from 'react'
|
import { Suspense, useState } from 'react'
|
||||||
import { useRouter, useSearchParams } from 'next/navigation'
|
import { useRouter, useSearchParams } from 'next/navigation'
|
||||||
import { signIn } from 'next-auth/react'
|
import { signIn } from 'next-auth/react'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
|
|
@ -15,7 +15,7 @@ import {
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from '@/components/ui/card'
|
} from '@/components/ui/card'
|
||||||
|
|
||||||
export default function LoginPage() {
|
function LoginForm() {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const searchParams = useSearchParams()
|
const searchParams = useSearchParams()
|
||||||
const callbackUrl = searchParams.get('callbackUrl') || '/'
|
const callbackUrl = searchParams.get('callbackUrl') || '/'
|
||||||
|
|
@ -55,7 +55,6 @@ export default function LoginPage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
|
|
||||||
<Card className="w-full max-w-md">
|
<Card className="w-full max-w-md">
|
||||||
<CardHeader className="space-y-1">
|
<CardHeader className="space-y-1">
|
||||||
<CardTitle className="text-2xl font-bold text-center">
|
<CardTitle className="text-2xl font-bold text-center">
|
||||||
|
|
@ -128,6 +127,35 @@ export default function LoginPage() {
|
||||||
</CardFooter>
|
</CardFooter>
|
||||||
</form>
|
</form>
|
||||||
</Card>
|
</Card>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function LoginFormSkeleton() {
|
||||||
|
return (
|
||||||
|
<Card className="w-full max-w-md">
|
||||||
|
<CardHeader className="space-y-1">
|
||||||
|
<CardTitle className="text-2xl font-bold text-center">
|
||||||
|
LetsBe Hub
|
||||||
|
</CardTitle>
|
||||||
|
<CardDescription className="text-center">
|
||||||
|
Loading...
|
||||||
|
</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="space-y-4">
|
||||||
|
<div className="h-10 bg-gray-200 rounded animate-pulse" />
|
||||||
|
<div className="h-10 bg-gray-200 rounded animate-pulse" />
|
||||||
|
<div className="h-10 bg-gray-200 rounded animate-pulse" />
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function LoginPage() {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
|
||||||
|
<Suspense fallback={<LoginFormSkeleton />}>
|
||||||
|
<LoginForm />
|
||||||
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue