feat: Add admin redirect and refactor authentication layout and components

This commit is contained in:
wood chen 2025-02-21 22:28:02 +08:00
parent 01ce107b70
commit 1050a8f6af
6 changed files with 74 additions and 82 deletions

View File

@ -1,6 +0,0 @@
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Auth Q58论坛",
description: "Sign in to your account",
};

View File

@ -1,11 +1,20 @@
"use client";
import { Suspense } from "react";
import { Metadata } from "next";
import Link from "next/link";
import { MessageCircleCode } from "lucide-react";
import { UserAuthForm } from "@/components/auth/user-auth-form";
import { UserAuthorize } from "@/components/auth/user-authorize";
export default function AuthPage() {
type Props = {
searchParams: { [key: string]: string | string[] | undefined };
};
export const metadata: Metadata = {
title: `Auth  Q58论坛`,
description: "Sign in to your account",
};
export default function AuthPage({ searchParams }: Props) {
return (
<div className="mx-auto flex w-full flex-col justify-center space-y-6 sm:w-[350px]">
<div className="flex flex-col space-y-2 text-center">
@ -15,7 +24,11 @@ export default function AuthPage() {
<span style={{ fontFamily: "Bahamas Bold" }}>Q58论坛</span>
</div>
</div>
<UserAuthForm />
<div>
<Suspense>
<UserAuthorize data={searchParams} />
</Suspense>
</div>
<p className="px-8 text-center text-sm text-muted-foreground">
By clicking continue, you agree to our{" "}
<Link

View File

@ -10,6 +10,7 @@ export default async function AuthLayout({
const user = await getCurrentUser();
if (user) {
if (user.role === "ADMIN") redirect("/admin");
redirect("/dashboard");
}

View File

@ -1,6 +0,0 @@
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Login",
description: "Login to your account",
};

View File

@ -8,6 +8,10 @@ import { cn } from "@/lib/utils";
import { useToast } from "@/hooks/use-toast";
import { buttonVariants } from "@/components/ui/button";
interface DiscourseData {
sso_url: string;
}
export function UserAuthForm({
className,
...props
@ -16,39 +20,32 @@ export function UserAuthForm({
const router = useRouter();
const { toast } = useToast();
async function handleSignIn() {
try {
setIsLoading(true);
const response = await fetch("/api/auth/q58", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
});
if (!response.ok) {
throw new Error("登录请求失败");
const signIn = () => {
React.startTransition(async () => {
const response = await fetch("/api/auth/q58", { method: "POST" });
if (!response.ok || response.status !== 200) {
setIsLoading(false);
toast({
variant: "destructive",
title: "内部服务异常",
description: response.statusText,
});
} else {
let data: DiscourseData = await response.json();
router.push(data.sso_url);
}
const data = await response.json();
window.location.href = data.sso_url;
} catch (error) {
console.error("登录错误:", error);
toast({
title: "登录失败",
description: "登录过程中发生错误,请稍后重试",
variant: "destructive",
});
setIsLoading(false);
}
}
});
};
return (
<div className={cn("grid gap-3", className)} {...props}>
<button
type="button"
className={cn(buttonVariants({ variant: "outline" }))}
onClick={handleSignIn}
onClick={() => {
setIsLoading(true);
signIn();
}}
disabled={isLoading}
>
{isLoading ? (

View File

@ -23,57 +23,50 @@ export function UserAuthorize({
}
setIsLoading(true);
try {
await signIn(data);
await signIn({ ...data, redirectTo: "/dashboard" });
setIsLoading(false);
} catch (error) {
console.error("登录过程出错:", error);
setError(error);
setIsLoading(false);
}
}, [data, isLoading]);
}, []);
useEffect(() => {
const timer = setTimeout(signInCallback, 5);
return () => {
clearTimeout(timer);
};
}, [signInCallback]);
if (error) {
return (
<Card className="w-full">
<CardHeader className="space-y-4 text-center">
<div className="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-red-100">
<div className="h-8 w-8 text-red-600"></div>
</div>
<CardTitle className="text-2xl font-semibold text-red-600">
</CardTitle>
</CardHeader>
<CardContent>
<p className="text-center text-gray-500">
{error instanceof Error
? error.message
: "登录异常,授权失败!请稍后重试。"}
</p>
</CardContent>
</Card>
);
}
}, []);
return (
<Card className="w-full">
<CardHeader className="space-y-4 text-center">
<div className="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-blue-100">
<div className="h-8 w-8 animate-spin rounded-full border-4 border-blue-600 border-t-transparent"></div>
</div>
<CardTitle className="text-2xl font-semibold"></CardTitle>
</CardHeader>
<CardContent>
<p className="text-center text-gray-500">
{isLoading ? "请稍候,我们正在处理您的授权请求" : "正在跳转..."}
</p>
</CardContent>
</Card>
<>
{error ? (
<Card className="w-full">
<CardHeader className="space-y-4 text-center">
<div className="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-red-100">
<div className="h-8 w-8 text-red-600"></div>
</div>
<CardTitle className="text-2xl font-semibold text-red-600">
</CardTitle>
</CardHeader>
<CardContent>
<p className="text-center text-gray-500"></p>
</CardContent>
</Card>
) : (
<Card className="w-full">
<CardHeader className="space-y-4 text-center">
<div className="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-blue-100">
<div className="h-8 w-8 animate-spin rounded-full border-4 border-blue-600 border-t-transparent"></div>
</div>
<CardTitle className="text-2xl font-semibold">
</CardTitle>
</CardHeader>
<CardContent>...</CardContent>
</Card>
)}
</>
);
}