Files
xiaoxia-saas/apps/web/src/pages/auth/ForgotPassword.tsx
T
xiaoxia 0fcb77b991
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / Frontend Lint (push) Successful in 1m6s
CI Build & Deploy Pipeline / Build Staging Web Image (push) Successful in 1m49s
CI Build & Deploy Pipeline / Build Production API Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Production Web Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Production Worker Image (push) Has been skipped
CI Build & Deploy Pipeline / Deploy Production (push) Has been skipped
CI Build & Deploy Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Validate Code Quality And Tests (push) Successful in 3m1s
CI/CD Pipeline / Unit Tests (push) Successful in 3m20s
CI/CD Pipeline / Integration Tests (push) Successful in 1m29s
CI Build & Deploy Pipeline / Build Staging API Image (push) Successful in 7m4s
CI Build & Deploy Pipeline / Build Staging Worker Image (push) Successful in 7m54s
CI Build & Deploy Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 45s
CI Build & Deploy Pipeline / Staging E2E Tests (push) Failing after 2m50s
CI Build & Deploy Pipeline / Staging API Integration Tests (push) Successful in 3m28s
ci: Prettier纳入两层防御体系 (#520)
Co-authored-by: xiaoxia <dev@xiaoxiajianji.com>
Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
2026-07-18 18:08:19 +08:00

103 lines
2.9 KiB
TypeScript

/**
* 忘记密码页面 - V21 完全对标
*/
import React, { useState } from "react"
import { Form, Input, Button, Result, message } from "antd"
import { MailOutlined } from "@ant-design/icons"
import { Link } from "react-router-dom"
import { useMutation } from "@tanstack/react-query"
import { requestPasswordReset } from "@/api/auth"
import "./ForgotPassword.css"
const ForgotPassword: React.FC = () => {
const [form] = Form.useForm()
const [emailSent, setEmailSent] = useState(false)
const resetMutation = useMutation({
mutationFn: (email: string) => requestPasswordReset(email),
onSuccess: () => {
setEmailSent(true)
message.success("重置邮件已发送!")
},
onError: (error: unknown) => {
if (!(error as { __msgShown?: boolean })?.__msgShown) message.error("发送失败,请重试")
},
})
const onFinish = (values: { email: string }) => {
resetMutation.mutate(values.email)
}
if (emailSent) {
return (
<div className="xx-result-page">
<div className="xx-result-card">
<Result
status="success"
title="重置邮件已发送"
subTitle="请检查您的邮箱,点击邮件中的链接重置密码。"
extra={[
<Link to="/login" key="login">
<Button type="primary">返回登录</Button>
</Link>,
]}
/>
</div>
</div>
)
}
return (
<div className="xx-auth-page">
<div className="xx-auth-card">
<div className="xx-auth-header">
<div className="xx-logo-big">🦐</div>
<h1>小虾自动剪辑</h1>
<p>重置密码</p>
</div>
<p
style={{
marginBottom: "24px",
color: "#64748b",
fontSize: "14px",
textAlign: "center",
}}
>
请输入您的邮箱地址,我们将发送重置密码的链接到您的邮箱。
</p>
<Form form={form} name="forgot-password" onFinish={onFinish} layout="vertical">
<Form.Item
name="email"
label="邮箱"
rules={[
{ required: true, message: "请输入邮箱" },
{ type: "email", message: "请输入有效的邮箱地址" },
]}
>
<Input prefix={<MailOutlined />} placeholder="name@example.com" size="large" />
</Form.Item>
<Form.Item>
<button
type="submit"
className="btn primary"
style={{ width: "100%" }}
disabled={resetMutation.isPending}
>
{resetMutation.isPending ? "发送中..." : "发送重置邮件"}
</button>
</Form.Item>
<div className="xx-auth-footer">
<Link to="/login">返回登录</Link>
</div>
</Form>
</div>
</div>
)
}
export default ForgotPassword