fix captcha show
This commit is contained in:
parent
fe4fbf0ea1
commit
f779a277a8
@ -58,7 +58,12 @@ function SignInContent() {
|
|||||||
|
|
||||||
const handleEmailSignInClick = (e: React.FormEvent) => {
|
const handleEmailSignInClick = (e: React.FormEvent) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (!email) return
|
if (!email.trim()) return
|
||||||
|
|
||||||
|
// 清除之前的消息
|
||||||
|
setMessage("")
|
||||||
|
|
||||||
|
// 显示验证码弹窗
|
||||||
setShowCaptcha(true)
|
setShowCaptcha(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +73,7 @@ function SignInContent() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await signIn("nodemailer", {
|
const result = await signIn("nodemailer", {
|
||||||
email,
|
email: email.trim(),
|
||||||
redirect: false,
|
redirect: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -78,6 +83,7 @@ function SignInContent() {
|
|||||||
setMessage("登录链接已发送到您的邮箱,请查收")
|
setMessage("登录链接已发送到您的邮箱,请查收")
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.error("Email sign in error:", error)
|
||||||
setMessage("登录失败,请重试")
|
setMessage("登录失败,请重试")
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false)
|
setIsLoading(false)
|
||||||
@ -86,14 +92,24 @@ function SignInContent() {
|
|||||||
|
|
||||||
const handleCaptchaCancel = () => {
|
const handleCaptchaCancel = () => {
|
||||||
setMessage("")
|
setMessage("")
|
||||||
|
setIsLoading(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCaptchaOpenChange = (open: boolean) => {
|
||||||
|
setShowCaptcha(open)
|
||||||
|
if (!open) {
|
||||||
|
setIsLoading(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleGoogleSignIn = async () => {
|
const handleGoogleSignIn = async () => {
|
||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
|
setMessage("")
|
||||||
try {
|
try {
|
||||||
const callbackUrl = searchParams.get("callbackUrl") || "/"
|
const callbackUrl = searchParams.get("callbackUrl") || "/"
|
||||||
await signIn("google", { callbackUrl })
|
await signIn("google", { callbackUrl })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.error("Google sign in error:", error)
|
||||||
setMessage("Google登录失败,请重试")
|
setMessage("Google登录失败,请重试")
|
||||||
setIsLoading(false)
|
setIsLoading(false)
|
||||||
}
|
}
|
||||||
@ -145,12 +161,13 @@ function SignInContent() {
|
|||||||
onChange={(e) => setEmail(e.target.value)}
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
required
|
required
|
||||||
className="bg-background border-input"
|
className="bg-background border-input"
|
||||||
|
disabled={isLoading}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="w-full"
|
className="w-full"
|
||||||
disabled={isLoading || !email}
|
disabled={isLoading || !email.trim()}
|
||||||
>
|
>
|
||||||
<Mail className="mr-2 h-4 w-4" />
|
<Mail className="mr-2 h-4 w-4" />
|
||||||
{isLoading ? "发送中..." : "发送登录链接"}
|
{isLoading ? "发送中..." : "发送登录链接"}
|
||||||
@ -169,7 +186,7 @@ function SignInContent() {
|
|||||||
{/* 验证码弹窗 */}
|
{/* 验证码弹窗 */}
|
||||||
<CaptchaDialog
|
<CaptchaDialog
|
||||||
open={showCaptcha}
|
open={showCaptcha}
|
||||||
onOpenChange={setShowCaptcha}
|
onOpenChange={handleCaptchaOpenChange}
|
||||||
onVerify={handleCaptchaVerify}
|
onVerify={handleCaptchaVerify}
|
||||||
onCancel={handleCaptchaCancel}
|
onCancel={handleCaptchaCancel}
|
||||||
/>
|
/>
|
||||||
|
@ -8,12 +8,15 @@ import {
|
|||||||
DialogFooter,
|
DialogFooter,
|
||||||
DialogHeader,
|
DialogHeader,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
|
DialogPortal,
|
||||||
|
DialogOverlay,
|
||||||
} from "@/components/ui/dialog"
|
} from "@/components/ui/dialog"
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import { Input } from "@/components/ui/input"
|
import { Input } from "@/components/ui/input"
|
||||||
import { Label } from "@/components/ui/label"
|
import { Label } from "@/components/ui/label"
|
||||||
import { Alert, AlertDescription } from "@/components/ui/alert"
|
import { Alert, AlertDescription } from "@/components/ui/alert"
|
||||||
import { Shield, RefreshCw, AlertCircle } from "lucide-react"
|
import { Shield, RefreshCw, AlertCircle } from "lucide-react"
|
||||||
|
import * as DialogPrimitive from "@radix-ui/react-dialog"
|
||||||
|
|
||||||
interface CaptchaDialogProps {
|
interface CaptchaDialogProps {
|
||||||
open: boolean
|
open: boolean
|
||||||
@ -76,88 +79,104 @@ export function CaptchaDialog({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 防止第一次打开时的遮罩层问题
|
||||||
|
const handleOpenChange = (newOpen: boolean) => {
|
||||||
|
if (!newOpen) {
|
||||||
|
setUserAnswer("")
|
||||||
|
setError("")
|
||||||
|
onCancel()
|
||||||
|
}
|
||||||
|
onOpenChange(newOpen)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
<Dialog open={open} onOpenChange={handleOpenChange}>
|
||||||
<DialogContent className="sm:max-w-md">
|
<DialogPortal>
|
||||||
<DialogHeader>
|
<DialogOverlay className="fixed inset-0 z-[100] bg-black/80" />
|
||||||
<DialogTitle className="flex items-center gap-2 text-foreground">
|
<DialogPrimitive.Content
|
||||||
<Shield className="h-5 w-5 text-blue-500 dark:text-blue-400" />
|
className="fixed left-[50%] top-[50%] z-[101] grid w-full max-w-md translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg focus:outline-none"
|
||||||
安全验证
|
onPointerDownOutside={(e) => e.preventDefault()}
|
||||||
</DialogTitle>
|
>
|
||||||
<DialogDescription>
|
<DialogHeader>
|
||||||
为了防止恶意使用,请完成以下验证码验证后再发送登录邮件
|
<DialogTitle className="flex items-center gap-2 text-foreground">
|
||||||
</DialogDescription>
|
<Shield className="h-5 w-5 text-blue-500 dark:text-blue-400" />
|
||||||
</DialogHeader>
|
安全验证
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
为了防止恶意使用,请完成以下验证码验证后再发送登录邮件
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<Alert className="border-blue-200 bg-blue-50 dark:border-blue-800 dark:bg-blue-950/50">
|
<Alert className="border-blue-200 bg-blue-50 dark:border-blue-800 dark:bg-blue-950/50">
|
||||||
<AlertCircle className="h-4 w-4" />
|
<AlertCircle className="h-4 w-4" />
|
||||||
<AlertDescription>
|
<AlertDescription>
|
||||||
<strong>提示:</strong>计算下面的数学题,输入答案完成验证
|
<strong>提示:</strong>计算下面的数学题,输入答案完成验证
|
||||||
</AlertDescription>
|
</AlertDescription>
|
||||||
</Alert>
|
</Alert>
|
||||||
|
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div className="flex items-center justify-center p-6 bg-muted/50 rounded-lg border">
|
<div className="flex items-center justify-center p-6 bg-muted/50 rounded-lg border">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<div className="text-2xl font-bold text-foreground mb-2">
|
<div className="text-2xl font-bold text-foreground mb-2">
|
||||||
{num1} + {num2} = ?
|
{num1} + {num2} = ?
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-center gap-2">
|
<div className="flex items-center justify-center gap-2">
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={generateCaptcha}
|
onClick={generateCaptcha}
|
||||||
className="text-muted-foreground hover:text-foreground"
|
className="text-muted-foreground hover:text-foreground"
|
||||||
>
|
>
|
||||||
<RefreshCw className="h-4 w-4 mr-1" />
|
<RefreshCw className="h-4 w-4 mr-1" />
|
||||||
换一题
|
换一题
|
||||||
</Button>
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="captcha-answer" className="text-foreground">
|
<Label htmlFor="captcha-answer" className="text-foreground">
|
||||||
请输入答案
|
请输入答案
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
id="captcha-answer"
|
id="captcha-answer"
|
||||||
type="number"
|
type="number"
|
||||||
placeholder="输入计算结果"
|
placeholder="输入计算结果"
|
||||||
value={userAnswer}
|
value={userAnswer}
|
||||||
onChange={(e) => setUserAnswer(e.target.value)}
|
onChange={(e) => setUserAnswer(e.target.value)}
|
||||||
onKeyPress={handleKeyPress}
|
onKeyDown={handleKeyPress}
|
||||||
className="text-center text-lg font-medium"
|
className="text-center text-lg font-medium"
|
||||||
autoFocus
|
autoFocus
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{error && (
|
{error && (
|
||||||
<Alert className="border-red-200 bg-red-50 text-red-800 dark:border-red-800 dark:bg-red-950 dark:text-red-200">
|
<Alert className="border-red-200 bg-red-50 text-red-800 dark:border-red-800 dark:bg-red-950 dark:text-red-200">
|
||||||
<AlertCircle className="h-4 w-4" />
|
<AlertCircle className="h-4 w-4" />
|
||||||
<AlertDescription>{error}</AlertDescription>
|
<AlertDescription>{error}</AlertDescription>
|
||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<DialogFooter className="flex justify-between">
|
<DialogFooter className="flex justify-between">
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={handleCancel}
|
onClick={handleCancel}
|
||||||
>
|
>
|
||||||
取消
|
取消
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={handleVerify}
|
onClick={handleVerify}
|
||||||
disabled={!userAnswer.trim()}
|
disabled={!userAnswer.trim()}
|
||||||
className="bg-blue-600 hover:bg-blue-700 dark:bg-blue-600 dark:hover:bg-blue-700"
|
className="bg-blue-600 hover:bg-blue-700 dark:bg-blue-600 dark:hover:bg-blue-700"
|
||||||
>
|
>
|
||||||
验证并发送邮件
|
验证并发送邮件
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</DialogContent>
|
</DialogPrimitive.Content>
|
||||||
|
</DialogPortal>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
)
|
)
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user