mirror of
https://github.com/woodchen-ink/Q58Connect.git
synced 2025-07-18 05:51:55 +08:00
feat: Add admin redirect and refactor authentication layout and components
This commit is contained in:
parent
01ce107b70
commit
1050a8f6af
@ -1,6 +0,0 @@
|
|||||||
import { Metadata } from "next";
|
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
|
||||||
title: "Auth – Q58论坛",
|
|
||||||
description: "Sign in to your account",
|
|
||||||
};
|
|
@ -1,11 +1,20 @@
|
|||||||
"use client";
|
import { Suspense } from "react";
|
||||||
|
import { Metadata } from "next";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { MessageCircleCode } from "lucide-react";
|
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 (
|
return (
|
||||||
<div className="mx-auto flex w-full flex-col justify-center space-y-6 sm:w-[350px]">
|
<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">
|
<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>
|
<span style={{ fontFamily: "Bahamas Bold" }}>Q58论坛</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<UserAuthForm />
|
<div>
|
||||||
|
<Suspense>
|
||||||
|
<UserAuthorize data={searchParams} />
|
||||||
|
</Suspense>
|
||||||
|
</div>
|
||||||
<p className="px-8 text-center text-sm text-muted-foreground">
|
<p className="px-8 text-center text-sm text-muted-foreground">
|
||||||
By clicking continue, you agree to our{" "}
|
By clicking continue, you agree to our{" "}
|
||||||
<Link
|
<Link
|
||||||
|
@ -10,6 +10,7 @@ export default async function AuthLayout({
|
|||||||
const user = await getCurrentUser();
|
const user = await getCurrentUser();
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
|
if (user.role === "ADMIN") redirect("/admin");
|
||||||
redirect("/dashboard");
|
redirect("/dashboard");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
import { Metadata } from "next";
|
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
|
||||||
title: "Login",
|
|
||||||
description: "Login to your account",
|
|
||||||
};
|
|
@ -8,6 +8,10 @@ import { cn } from "@/lib/utils";
|
|||||||
import { useToast } from "@/hooks/use-toast";
|
import { useToast } from "@/hooks/use-toast";
|
||||||
import { buttonVariants } from "@/components/ui/button";
|
import { buttonVariants } from "@/components/ui/button";
|
||||||
|
|
||||||
|
interface DiscourseData {
|
||||||
|
sso_url: string;
|
||||||
|
}
|
||||||
|
|
||||||
export function UserAuthForm({
|
export function UserAuthForm({
|
||||||
className,
|
className,
|
||||||
...props
|
...props
|
||||||
@ -16,39 +20,32 @@ export function UserAuthForm({
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
|
|
||||||
async function handleSignIn() {
|
const signIn = () => {
|
||||||
try {
|
React.startTransition(async () => {
|
||||||
setIsLoading(true);
|
const response = await fetch("/api/auth/q58", { method: "POST" });
|
||||||
const response = await fetch("/api/auth/q58", {
|
if (!response.ok || response.status !== 200) {
|
||||||
method: "POST",
|
setIsLoading(false);
|
||||||
headers: {
|
toast({
|
||||||
"Content-Type": "application/json",
|
variant: "destructive",
|
||||||
},
|
title: "内部服务异常",
|
||||||
});
|
description: response.statusText,
|
||||||
|
});
|
||||||
if (!response.ok) {
|
} else {
|
||||||
throw new Error("登录请求失败");
|
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 (
|
return (
|
||||||
<div className={cn("grid gap-3", className)} {...props}>
|
<div className={cn("grid gap-3", className)} {...props}>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={cn(buttonVariants({ variant: "outline" }))}
|
className={cn(buttonVariants({ variant: "outline" }))}
|
||||||
onClick={handleSignIn}
|
onClick={() => {
|
||||||
|
setIsLoading(true);
|
||||||
|
signIn();
|
||||||
|
}}
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
>
|
>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
|
@ -23,57 +23,50 @@ export function UserAuthorize({
|
|||||||
}
|
}
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
await signIn(data);
|
await signIn({ ...data, redirectTo: "/dashboard" });
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("登录过程出错:", error);
|
|
||||||
setError(error);
|
setError(error);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
}, [data, isLoading]);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timer = setTimeout(signInCallback, 5);
|
const timer = setTimeout(signInCallback, 5);
|
||||||
return () => {
|
return () => {
|
||||||
clearTimeout(timer);
|
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 (
|
return (
|
||||||
<Card className="w-full">
|
<>
|
||||||
<CardHeader className="space-y-4 text-center">
|
{error ? (
|
||||||
<div className="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-blue-100">
|
<Card className="w-full">
|
||||||
<div className="h-8 w-8 animate-spin rounded-full border-4 border-blue-600 border-t-transparent"></div>
|
<CardHeader className="space-y-4 text-center">
|
||||||
</div>
|
<div className="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-red-100">
|
||||||
<CardTitle className="text-2xl font-semibold">正在处理授权</CardTitle>
|
<div className="h-8 w-8 text-red-600">❌</div>
|
||||||
</CardHeader>
|
</div>
|
||||||
<CardContent>
|
<CardTitle className="text-2xl font-semibold text-red-600">
|
||||||
<p className="text-center text-gray-500">
|
授权失败
|
||||||
{isLoading ? "请稍候,我们正在处理您的授权请求" : "正在跳转..."}
|
</CardTitle>
|
||||||
</p>
|
</CardHeader>
|
||||||
</CardContent>
|
<CardContent>
|
||||||
</Card>
|
<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>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user