| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- import React, { useEffect, useState } from 'react';
- import { API, copy, showError, showNotice, getLogo, getSystemName } from '../../helpers';
- import { useSearchParams, Link } from 'react-router-dom';
- import { Button, Card, Form, Typography } from '@douyinfe/semi-ui';
- import { IconMail, IconLock } from '@douyinfe/semi-icons';
- import { useTranslation } from 'react-i18next';
- import Background from '/example.png';
- const { Text, Title } = Typography;
- const PasswordResetConfirm = () => {
- const { t } = useTranslation();
- const [inputs, setInputs] = useState({
- email: '',
- token: '',
- });
- const { email, token } = inputs;
- const isValidResetLink = email && token;
- const [loading, setLoading] = useState(false);
- const [disableButton, setDisableButton] = useState(false);
- const [countdown, setCountdown] = useState(30);
- const [newPassword, setNewPassword] = useState('');
- const [searchParams, setSearchParams] = useSearchParams();
- const logo = getLogo();
- const systemName = getSystemName();
- useEffect(() => {
- let token = searchParams.get('token');
- let email = searchParams.get('email');
- setInputs({
- token: token || '',
- email: email || '',
- });
- }, [searchParams]);
- useEffect(() => {
- let countdownInterval = null;
- if (disableButton && countdown > 0) {
- countdownInterval = setInterval(() => {
- setCountdown(countdown - 1);
- }, 1000);
- } else if (countdown === 0) {
- setDisableButton(false);
- setCountdown(30);
- }
- return () => clearInterval(countdownInterval);
- }, [disableButton, countdown]);
- async function handleSubmit(e) {
- if (!email || !token) {
- showError(t('无效的重置链接,请重新发起密码重置请求'));
- return;
- }
- setDisableButton(true);
- setLoading(true);
- const res = await API.post(`/api/user/reset`, {
- email,
- token,
- });
- const { success, message } = res.data;
- if (success) {
- let password = res.data.data;
- setNewPassword(password);
- await copy(password);
- showNotice(`${t('密码已重置并已复制到剪贴板')}: ${password}`);
- } else {
- showError(message);
- }
- setLoading(false);
- }
- return (
- <div className="min-h-screen relative flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8 overflow-hidden">
- {/* 背景图片容器 - 放大并保持居中 */}
- <div
- className="absolute inset-0 z-0 bg-cover bg-center scale-125 opacity-100"
- style={{
- backgroundImage: `url(${Background})`
- }}
- ></div>
- {/* 半透明遮罩层 */}
- <div className="absolute inset-0 bg-gradient-to-br from-teal-500/30 via-blue-500/30 to-purple-500/30 backdrop-blur-sm z-0"></div>
- <div className="w-full max-w-sm relative z-10">
- <div className="flex flex-col items-center">
- <div className="w-full max-w-md">
- <div className="flex items-center justify-center mb-6 gap-2">
- <img src={logo} alt="Logo" className="h-10 rounded-full" />
- <Title heading={3} className='!text-white'>{systemName}</Title>
- </div>
- <Card className="shadow-xl border-0 !rounded-2xl overflow-hidden">
- <div className="flex justify-center pt-6 pb-2">
- <Title heading={3} className="text-gray-800 dark:text-gray-200">{t('密码重置确认')}</Title>
- </div>
- <div className="px-2 py-8">
- {!isValidResetLink && (
- <div className="mb-4 p-3 bg-red-100 border border-red-400 text-red-700 rounded">
- <Text>{t('无效的重置链接,请重新发起密码重置请求')}</Text>
- </div>
- )}
- <Form className="space-y-3">
- <Form.Input
- field="email"
- label={t('邮箱')}
- name="email"
- size="large"
- className="!rounded-md"
- value={email || ''}
- disabled={true}
- prefix={<IconMail />}
- placeholder={email ? '' : t('等待获取邮箱信息...')}
- />
- {newPassword && (
- <Form.Input
- field="newPassword"
- label={t('新密码')}
- name="newPassword"
- size="large"
- className="!rounded-md"
- value={newPassword}
- disabled={true}
- prefix={<IconLock />}
- onClick={(e) => {
- e.target.select();
- navigator.clipboard.writeText(newPassword);
- showNotice(`${t('密码已复制到剪贴板')}: ${newPassword}`);
- }}
- />
- )}
- <div className="space-y-2 pt-2">
- <Button
- theme="solid"
- className="w-full !rounded-full"
- type="primary"
- htmlType="submit"
- size="large"
- onClick={handleSubmit}
- loading={loading}
- disabled={disableButton || newPassword || !isValidResetLink}
- >
- {newPassword ? t('密码重置完成') : t('确认重置密码')}
- </Button>
- </div>
- </Form>
- <div className="mt-6 text-center text-sm">
- <Text><Link to="/login" className="text-blue-600 hover:text-blue-800 font-medium">{t('返回登录')}</Link></Text>
- </div>
- </div>
- </Card>
- </div>
- </div>
- </div>
- </div>
- );
- };
- export default PasswordResetConfirm;
|