feat: 成功和错误弹窗从顶部弹出
This commit is contained in:
11
src/App.js
11
src/App.js
@@ -238,7 +238,16 @@ export default function App() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ChakraProvider theme={theme}>
|
<ChakraProvider
|
||||||
|
theme={theme}
|
||||||
|
toastOptions={{
|
||||||
|
defaultOptions: {
|
||||||
|
position: 'top',
|
||||||
|
duration: 3000,
|
||||||
|
isClosable: true,
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<AuthProvider>
|
<AuthProvider>
|
||||||
<AuthModalProvider>
|
<AuthModalProvider>
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import {
|
|||||||
import { FaLock, FaWeixin } from "react-icons/fa";
|
import { FaLock, FaWeixin } from "react-icons/fa";
|
||||||
import { useAuth } from "../../contexts/AuthContext";
|
import { useAuth } from "../../contexts/AuthContext";
|
||||||
import { useAuthModal } from "../../contexts/AuthModalContext";
|
import { useAuthModal } from "../../contexts/AuthModalContext";
|
||||||
|
import { useNotification } from "../../contexts/NotificationContext";
|
||||||
import { authService } from "../../services/authService";
|
import { authService } from "../../services/authService";
|
||||||
import AuthHeader from './AuthHeader';
|
import AuthHeader from './AuthHeader';
|
||||||
import VerificationCodeInput from './VerificationCodeInput';
|
import VerificationCodeInput from './VerificationCodeInput';
|
||||||
@@ -66,6 +67,7 @@ export default function AuthFormContent() {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { checkSession } = useAuth();
|
const { checkSession } = useAuth();
|
||||||
const { handleLoginSuccess } = useAuthModal();
|
const { handleLoginSuccess } = useAuthModal();
|
||||||
|
const { showWelcomeGuide } = useNotification();
|
||||||
|
|
||||||
// 使用统一配置
|
// 使用统一配置
|
||||||
const config = AUTH_CONFIG;
|
const config = AUTH_CONFIG;
|
||||||
@@ -85,7 +87,7 @@ export default function AuthFormContent() {
|
|||||||
// 响应式布局配置
|
// 响应式布局配置
|
||||||
const isMobile = useBreakpointValue({ base: true, md: false });
|
const isMobile = useBreakpointValue({ base: true, md: false });
|
||||||
const stackDirection = useBreakpointValue({ base: "column", md: "row" });
|
const stackDirection = useBreakpointValue({ base: "column", md: "row" });
|
||||||
const stackSpacing = useBreakpointValue({ base: 4, md: 8 });
|
const stackSpacing = useBreakpointValue({ base: 4, md: 2 }); // ✅ 桌面端从32px减至8px,更紧凑
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
@@ -202,10 +204,23 @@ export default function AuthFormContent() {
|
|||||||
throw new Error(data.error || '发送验证码失败');
|
throw new Error(data.error || '发送验证码失败');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// ❌ 移除错误 toast,仅 console 输出
|
|
||||||
logger.api.error('POST', '/api/auth/send-verification-code', error, {
|
logger.api.error('POST', '/api/auth/send-verification-code', error, {
|
||||||
credential: credential.substring(0, 3) + '****' + credential.substring(7)
|
credential: credential.substring(0, 3) + '****' + credential.substring(7)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ✅ 显示错误提示给用户
|
||||||
|
toast({
|
||||||
|
id: 'send-code-error',
|
||||||
|
title: "发送验证码失败",
|
||||||
|
description: error.message || "请稍后重试",
|
||||||
|
status: "error",
|
||||||
|
duration: 3000,
|
||||||
|
isClosable: true,
|
||||||
|
position: 'top',
|
||||||
|
containerStyle: {
|
||||||
|
zIndex: 10000,
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
if (isMountedRef.current) {
|
if (isMountedRef.current) {
|
||||||
setSendingCode(false);
|
setSendingCode(false);
|
||||||
@@ -219,7 +234,7 @@ export default function AuthFormContent() {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { phone, verificationCode, nickname } = formData;
|
const { phone, verificationCode } = formData;
|
||||||
|
|
||||||
// 表单验证
|
// 表单验证
|
||||||
if (!phone || !verificationCode) {
|
if (!phone || !verificationCode) {
|
||||||
@@ -321,16 +336,37 @@ export default function AuthFormContent() {
|
|||||||
handleLoginSuccess({ phone });
|
handleLoginSuccess({ phone });
|
||||||
}, config.features.successDelay);
|
}, config.features.successDelay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ⚡ 延迟 10 秒显示权限引导(温和、非侵入)
|
||||||
|
setTimeout(() => {
|
||||||
|
if (showWelcomeGuide) {
|
||||||
|
logger.info('AuthFormContent', '显示欢迎引导');
|
||||||
|
showWelcomeGuide();
|
||||||
|
}
|
||||||
|
}, 10000);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(data.error || `${config.errorTitle}`);
|
throw new Error(data.error || `${config.errorTitle}`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// ❌ 移除错误 toast,仅 console 输出
|
|
||||||
const { phone, verificationCode } = formData;
|
const { phone, verificationCode } = formData;
|
||||||
logger.error('AuthFormContent', 'handleSubmit', error, {
|
logger.error('AuthFormContent', 'handleSubmit', error, {
|
||||||
phone: phone ? phone.substring(0, 3) + '****' + phone.substring(7) : 'N/A',
|
phone: phone ? phone.substring(0, 3) + '****' + phone.substring(7) : 'N/A',
|
||||||
hasVerificationCode: !!verificationCode
|
hasVerificationCode: !!verificationCode
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ✅ 显示错误提示给用户
|
||||||
|
toast({
|
||||||
|
id: 'auth-verification-error',
|
||||||
|
title: config.errorTitle,
|
||||||
|
description: error.message || "请检查验证码是否正确",
|
||||||
|
status: "error",
|
||||||
|
duration: 3000,
|
||||||
|
isClosable: true,
|
||||||
|
position: 'top',
|
||||||
|
containerStyle: {
|
||||||
|
zIndex: 10000,
|
||||||
|
}
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
if (isMountedRef.current) {
|
if (isMountedRef.current) {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
@@ -465,8 +501,8 @@ export default function AuthFormContent() {
|
|||||||
|
|
||||||
{/* 桌面端:右侧二维码扫描 */}
|
{/* 桌面端:右侧二维码扫描 */}
|
||||||
{!isMobile && (
|
{!isMobile && (
|
||||||
<Box flex="1">
|
<Box flex={{ base: "1", md: "0 0 auto" }}> {/* ✅ 桌面端让右侧自适应宽度 */}
|
||||||
<Center width="100%" bg="gray.50" borderRadius="lg" p={8}>
|
<Center width="100%" bg="gray.50" borderRadius="lg" p={0}> {/* ✅ 完全移除padding,最大化空间利用 */}
|
||||||
<WechatRegister />
|
<WechatRegister />
|
||||||
</Center>
|
</Center>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
Reference in New Issue
Block a user