casualroom/apps/fenghuo/web/app/[locale]/sign-in/page.tsx

184 lines
7.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { client } from "@/lib/auth-client";
import { Button } from "@nice/ui/components/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@nice/ui/components/card";
import { Input } from "@nice/ui/components/input";
import { Label } from "@nice/ui/components/label";
import { toast } from "@nice/ui/components/sonner";
import { useState } from "react";
import { useRouter, useSearchParams } from "next/navigation";
export default function SignInPage() {
const [credentials, setCredentials] = useState({
email: "test@example.com",
password: "password123"
});
const [isLoading, setIsLoading] = useState(false);
const router = useRouter();
const searchParams = useSearchParams();
// 检查是否是从 OIDC Provider 重定向过来的
const isOIDCFlow = searchParams.get('response_type') === 'code' || searchParams.get('client_id');
const handleSignIn = async (e: React.FormEvent) => {
e.preventDefault();
setIsLoading(true);
try {
const result = await client.signIn.email({
email: credentials.email,
password: credentials.password,
});
if (result.data) {
toast.success("登录成功!");
// 如果是 OIDC 流程,重定向回原始请求
if (isOIDCFlow) {
// 获取所有查询参数并重建 URL
const params = new URLSearchParams(window.location.search);
const redirectUrl = `http://localhost:3001/api/auth/oauth2/authorize?${params.toString()}`;
window.location.href = redirectUrl;
} else {
router.push('/dashboard');
}
} else if (result.error) {
toast.error(`登录失败: ${result.error.message}`);
}
} catch (error: any) {
console.error("登录失败:", error);
toast.error(`登录失败: ${error.message || "未知错误"}`);
} finally {
setIsLoading(false);
}
};
const handleCreateTestUser = async () => {
setIsLoading(true);
try {
// 使用更详细的用户信息
const result = await client.signUp.email({
email: credentials.email,
password: credentials.password,
name: "Test User",
});
if (result.data) {
toast.success("测试用户创建成功!可以使用此账户登录");
} else if (result.error) {
// 显示更详细的错误信息
console.error("注册错误详情:", result.error);
// 检查是否是重定向URI错误这通常不应该出现在注册流程中
if (result.error.code === 'INVALID_REDIRECT_URI') {
toast.error("OAuth配置错误重定向URI无效请检查后端配置");
} else {
const errorMessage = result.error.message || "未知错误";
if (errorMessage.includes("already exists")) {
toast.error("该邮箱已被注册,请直接登录");
} else {
toast.error(`创建失败: ${errorMessage}`);
}
}
}
} catch (error: any) {
console.error("创建用户失败:", error);
// 显示更详细的错误信息
if (error.response) {
console.error("响应状态:", error.response.status);
console.error("响应数据:", error.response.data);
}
toast.error(`创建用户失败: ${error.message || "未知错误"}`);
} finally {
setIsLoading(false);
}
};
return (
<div className="container mx-auto p-6 max-w-md">
<Card>
<CardHeader className="text-center">
<CardTitle className="text-2xl"></CardTitle>
<CardDescription>
{isOIDCFlow ? (
<span>OIDC Provider </span>
) : (
<span></span>
)}
</CardDescription>
</CardHeader>
<CardContent>
{isOIDCFlow && (
<div className="mb-4 p-3 bg-blue-50 dark:bg-blue-950 rounded-md">
<p className="text-sm text-blue-800 dark:text-blue-200">
OIDC
</p>
</div>
)}
<form onSubmit={handleSignIn} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="email"></Label>
<Input
id="email"
type="email"
value={credentials.email}
onChange={(e) => setCredentials({ ...credentials, email: e.target.value })}
disabled={isLoading}
required
/>
</div>
<div className="space-y-2">
<Label htmlFor="password"></Label>
<Input
id="password"
type="password"
value={credentials.password}
onChange={(e) => setCredentials({ ...credentials, password: e.target.value })}
disabled={isLoading}
required
/>
</div>
<Button type="submit" className="w-full" disabled={isLoading}>
{isLoading ? "登录中..." : "登录"}
</Button>
</form>
<div className="mt-6 pt-4 border-t">
<p className="text-sm text-muted-foreground mb-2">:</p>
<div className="space-y-2">
<Button
onClick={handleCreateTestUser}
variant="outline"
className="w-full"
disabled={isLoading}
>
</Button>
</div>
</div>
{isOIDCFlow && (
<div className="mt-4">
<Button
onClick={() => router.push('/test')}
variant="ghost"
className="w-full"
>
</Button>
</div>
)}
</CardContent>
</Card>
</div>
);
}