new change
This commit is contained in:
@@ -6,6 +6,9 @@ import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { signIn } from 'next-auth/react';
|
||||
import { register } from '@/lib/api/actions';
|
||||
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
|
||||
import { Eye, EyeOff } from 'lucide-react';
|
||||
|
||||
interface AuthFormProps {
|
||||
type: 'login' | 'register';
|
||||
@@ -17,6 +20,9 @@ export default function AuthForm({ type }: AuthFormProps) {
|
||||
const [password, setPassword] = useState('');
|
||||
const [email, setEmail] = useState('');
|
||||
const [minecraftUsername, setMinecraftUsername] = useState('');
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [success, setSuccess] = useState<string | null>(null);
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
@@ -24,39 +30,108 @@ export default function AuthForm({ type }: AuthFormProps) {
|
||||
|
||||
try {
|
||||
if (type === 'login') {
|
||||
// 使用next-auth的signIn功能进行登录
|
||||
// 基本验证
|
||||
if (!password) {
|
||||
setError('请输入密码');
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const usernameField = username || email;
|
||||
if (!usernameField) {
|
||||
setError('请输入用户名或邮箱');
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用next-auth的signIn功能进行登录,设置redirect为false以便处理错误
|
||||
const result = await signIn('credentials', {
|
||||
username: username || email, // 使用username或email作为用户名字段
|
||||
username: usernameField, // 使用username或email作为用户名字段
|
||||
email: email, // 传递email字段
|
||||
password,
|
||||
redirect: true, // 登录成功后自动重定向
|
||||
redirect: false, // 不自动重定向,以便处理错误
|
||||
callbackUrl: '/user-home' // 指定重定向目标
|
||||
});
|
||||
|
||||
console.log('登录结果:', result);
|
||||
if (result?.error) {
|
||||
// 处理登录错误 - 根据错误类型显示不同的错误信息
|
||||
console.error('登录失败:', result.error);
|
||||
if (result.error.includes('CredentialsSignin')) {
|
||||
setError('用户名或密码错误,请重试');
|
||||
} else if (result.error.includes('Network')) {
|
||||
setError('网络连接失败,请检查您的网络设置');
|
||||
} else {
|
||||
setError('登录失败,请稍后再试');
|
||||
}
|
||||
} else if (result?.ok) {
|
||||
// 登录成功,手动重定向
|
||||
window.location.href = '/user-home';
|
||||
} else {
|
||||
setError('登录过程中发生未知错误');
|
||||
}
|
||||
} else {
|
||||
// 注册逻辑可以在这里实现
|
||||
console.log('注册信息', { username, password, email, minecraftUsername });
|
||||
// 模拟注册请求
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
// 调用注册API
|
||||
const result = await register({
|
||||
username,
|
||||
password,
|
||||
email,
|
||||
minecraftUsername
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
setSuccess('注册成功!即将跳转到登录页面...');
|
||||
// 注册成功后重定向到登录页面
|
||||
setTimeout(() => {
|
||||
window.location.href = '/login';
|
||||
}, 2000);
|
||||
} else {
|
||||
setError(result.error || '注册失败,请稍后再试');
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('认证失败:', error);
|
||||
// 这里可以添加错误处理逻辑
|
||||
setError('网络错误,请检查您的连接');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 重置错误和成功消息
|
||||
const resetMessages = () => {
|
||||
setError(null);
|
||||
setSuccess(null);
|
||||
};
|
||||
|
||||
// 监听输入变化,清除错误消息
|
||||
const handleInputChange = (setter: React.Dispatch<React.SetStateAction<string>>) => {
|
||||
return (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
resetMessages();
|
||||
setter(e.target.value);
|
||||
};
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit} className="space-y-4">
|
||||
{error && (
|
||||
<Alert variant="destructive" className="bg-red-50 border-red-200 text-red-800">
|
||||
<AlertTitle>错误</AlertTitle>
|
||||
<AlertDescription>{error}</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{success && (
|
||||
<Alert className="bg-green-50 border-green-200 text-green-800">
|
||||
<AlertTitle>成功</AlertTitle>
|
||||
<AlertDescription>{success}</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
<div>
|
||||
<Label htmlFor="username">用户名</Label>
|
||||
<Input
|
||||
id="username"
|
||||
type="text"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
onChange={handleInputChange(setUsername)}
|
||||
placeholder={type === 'login' ? "用户名或邮箱" : "输入用户名"}
|
||||
/>
|
||||
</div>
|
||||
@@ -68,20 +143,29 @@ export default function AuthForm({ type }: AuthFormProps) {
|
||||
id="email"
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
onChange={handleInputChange(setEmail)}
|
||||
placeholder="或直接输入邮箱登录"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<Label htmlFor="password">密码</Label>
|
||||
<Input
|
||||
id="password"
|
||||
type="password"
|
||||
required
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
<div className="relative">
|
||||
<Input
|
||||
id="password"
|
||||
type={showPassword ? "text" : "password"}
|
||||
required
|
||||
value={password}
|
||||
onChange={handleInputChange(setPassword)}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
className="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-500 hover:text-gray-700 focus:outline-none"
|
||||
onClick={() => setShowPassword(!showPassword)}
|
||||
>
|
||||
{showPassword ? <EyeOff size={18} /> : <Eye size={18} />}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{type === 'register' && (
|
||||
@@ -89,22 +173,23 @@ export default function AuthForm({ type }: AuthFormProps) {
|
||||
<div>
|
||||
<Label htmlFor="email">电子邮箱</Label>
|
||||
<Input
|
||||
id="email"
|
||||
type="email"
|
||||
required
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
/>
|
||||
id="email"
|
||||
type="email"
|
||||
required
|
||||
value={email}
|
||||
onChange={handleInputChange(setEmail)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="minecraftUsername">Minecraft 用户名</Label>
|
||||
<Input
|
||||
id="minecraftUsername"
|
||||
type="text"
|
||||
required
|
||||
value={minecraftUsername}
|
||||
onChange={(e) => setMinecraftUsername(e.target.value)}
|
||||
/>
|
||||
id="minecraftUsername"
|
||||
type="text"
|
||||
required
|
||||
value={minecraftUsername}
|
||||
onChange={handleInputChange(setMinecraftUsername)}
|
||||
placeholder="您的Minecraft游戏内用户名"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
51
src/components/ui/alert.tsx
Normal file
51
src/components/ui/alert.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
// src/components/ui/alert.tsx
|
||||
import React from 'react';
|
||||
|
||||
interface AlertProps {
|
||||
children: React.ReactNode;
|
||||
variant?: 'default' | 'destructive';
|
||||
className?: string;
|
||||
}
|
||||
|
||||
interface AlertTitleProps {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
interface AlertDescriptionProps {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
// 主Alert组件
|
||||
export function Alert({ children, variant = 'default', className = '' }: AlertProps) {
|
||||
const baseClasses = 'p-4 rounded-lg border flex items-start space-x-3';
|
||||
const variantClasses = {
|
||||
default: 'bg-green-50 border-green-200 text-green-800',
|
||||
destructive: 'bg-red-50 border-red-200 text-red-800'
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`${baseClasses} ${variantClasses[variant]} ${className}`}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Alert标题组件
|
||||
export function AlertTitle({ children, className = '' }: AlertTitleProps) {
|
||||
return (
|
||||
<h3 className={`font-medium text-sm ${className}`}>
|
||||
{children}
|
||||
</h3>
|
||||
);
|
||||
}
|
||||
|
||||
// Alert描述组件
|
||||
export function AlertDescription({ children, className = '' }: AlertDescriptionProps) {
|
||||
return (
|
||||
<p className={`text-sm ${className}`}>
|
||||
{children}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user