Skip to content

Commit 31e0623

Browse files
committed
Fix: wrap auth/signin client logic in Suspense; move useSearchParams to client component
1 parent bddae8a commit 31e0623

2 files changed

Lines changed: 63 additions & 53 deletions

File tree

app/auth/signin/SignInClient.tsx

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
"use client"
2+
3+
import * as React from "react"
4+
import { useSearchParams } from "next/navigation"
5+
import { signIn } from "next-auth/react"
6+
7+
export default function SignInClient() {
8+
const params = useSearchParams()
9+
const [loading, setLoading] = React.useState(false)
10+
11+
const cb = params.get("callbackUrl") || "/"
12+
const from = params.get("from") || undefined
13+
const mode = params.get("mode") || undefined
14+
15+
return (
16+
<main className="min-h-screen flex items-center justify-center p-6">
17+
<div className="w-full max-w-sm rounded-xl border bg-card p-6 shadow-sm">
18+
<div className="mb-4">
19+
<h1 className="text-xl font-semibold">Sign in</h1>
20+
<p className="text-sm text-muted-foreground">
21+
{mode === "org-invite"
22+
? "Continue to join the organization with your Google account."
23+
: "Continue with your Google account."}
24+
</p>
25+
</div>
26+
<button
27+
type="button"
28+
disabled={loading}
29+
onClick={async () => {
30+
setLoading(true)
31+
try {
32+
await signIn("google", { callbackUrl: cb })
33+
} finally {
34+
setLoading(false)
35+
}
36+
}}
37+
className="w-full inline-flex items-center justify-center gap-2 rounded-md bg-orange-500 px-4 py-2 text-white hover:bg-orange-600 disabled:opacity-50"
38+
>
39+
<span className="inline-flex h-4 w-4 items-center justify-center">
40+
<svg viewBox="0 0 24 24" fill="currentColor" className="h-4 w-4" aria-hidden>
41+
<path d="M21.35 11.1h-8.9v2.98h5.1c-.22 1.3-.93 2.4-1.98 3.14l3.2 2.48c1.87-1.73 2.95-4.28 2.95-7.38 0-.64-.06-1.25-.17-1.83z" />
42+
<path d="M12.45 22c2.67 0 4.91-.88 6.55-2.39l-3.2-2.48c-.89.6-2.02.95-3.35.95-2.57 0-4.75-1.73-5.53-4.06H3.59v2.55A9.55 9.55 0 0 0 12.45 22z" />
43+
<path d="M6.92 13.99a5.73 5.73 0 0 1 0-3.98V7.46H3.59a9.57 9.57 0 0 0 0 9.08l3.33-2.55z" />
44+
<path d="M12.45 5.52c1.45 0 2.74.5 3.76 1.47l2.82-2.82A9.52 9.52 0 0 0 12.45 2 9.55 9.55 0 0 0 3.59 7.46l3.33 2.55c.78-2.33 2.96-4.49 5.53-4.49z" />
45+
</svg>
46+
</span>
47+
{loading ? "Redirecting…" : "Continue with Google"}
48+
</button>
49+
{from && (
50+
<p className="mt-2 text-[11px] text-muted-foreground">After sign-in you’ll be returned to: {from}</p>
51+
)}
52+
<p className="mt-4 text-[11px] text-muted-foreground">
53+
By continuing, you agree to our Terms and acknowledge our Privacy Policy.
54+
</p>
55+
</div>
56+
</main>
57+
)
58+
}

app/auth/signin/page.tsx

Lines changed: 5 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,10 @@
1-
"use client"
2-
3-
import * as React from "react"
4-
import { useSearchParams } from "next/navigation"
5-
import { signIn } from "next-auth/react"
1+
import { Suspense } from "react"
2+
import SignInClient from "./SignInClient"
63

74
export default function SignInPage() {
8-
const params = useSearchParams()
9-
const [loading, setLoading] = React.useState(false)
10-
11-
const cb = params.get("callbackUrl") || "/"
12-
const from = params.get("from") || undefined
13-
const mode = params.get("mode") || undefined
14-
155
return (
16-
<main className="min-h-screen flex items-center justify-center p-6">
17-
<div className="w-full max-w-sm rounded-xl border bg-card p-6 shadow-sm">
18-
<div className="mb-4">
19-
<h1 className="text-xl font-semibold">Sign in</h1>
20-
<p className="text-sm text-muted-foreground">
21-
{mode === "org-invite"
22-
? "Continue to join the organization with your Google account."
23-
: "Continue with your Google account."}
24-
</p>
25-
</div>
26-
<button
27-
type="button"
28-
disabled={loading}
29-
onClick={async () => {
30-
setLoading(true)
31-
try {
32-
await signIn("google", { callbackUrl: cb })
33-
} finally {
34-
setLoading(false)
35-
}
36-
}}
37-
className="w-full inline-flex items-center justify-center gap-2 rounded-md bg-orange-500 px-4 py-2 text-white hover:bg-orange-600 disabled:opacity-50"
38-
>
39-
<span className="inline-flex h-4 w-4 items-center justify-center">
40-
<svg viewBox="0 0 24 24" fill="currentColor" className="h-4 w-4" aria-hidden>
41-
<path d="M21.35 11.1h-8.9v2.98h5.1c-.22 1.3-.93 2.4-1.98 3.14l3.2 2.48c1.87-1.73 2.95-4.28 2.95-7.38 0-.64-.06-1.25-.17-1.83z" />
42-
<path d="M12.45 22c2.67 0 4.91-.88 6.55-2.39l-3.2-2.48c-.89.6-2.02.95-3.35.95-2.57 0-4.75-1.73-5.53-4.06H3.59v2.55A9.55 9.55 0 0 0 12.45 22z" />
43-
<path d="M6.92 13.99a5.73 5.73 0 0 1 0-3.98V7.46H3.59a9.57 9.57 0 0 0 0 9.08l3.33-2.55z" />
44-
<path d="M12.45 5.52c1.45 0 2.74.5 3.76 1.47l2.82-2.82A9.52 9.52 0 0 0 12.45 2 9.55 9.55 0 0 0 3.59 7.46l3.33 2.55c.78-2.33 2.96-4.49 5.53-4.49z" />
45-
</svg>
46-
</span>
47-
{loading ? "Redirecting…" : "Continue with Google"}
48-
</button>
49-
{from && (
50-
<p className="mt-2 text-[11px] text-muted-foreground">After sign-in you’ll be returned to: {from}</p>
51-
)}
52-
<p className="mt-4 text-[11px] text-muted-foreground">
53-
By continuing, you agree to our Terms and acknowledge our Privacy Policy.
54-
</p>
55-
</div>
56-
</main>
6+
<Suspense fallback={<div className="min-h-screen flex items-center justify-center p-6"><div className="w-full max-w-sm rounded-xl border bg-card p-6 shadow-sm"><div className="h-5 w-24 bg-muted rounded" /></div></div>}>
7+
<SignInClient />
8+
</Suspense>
579
)
5810
}

0 commit comments

Comments
 (0)