feat: 更新错误页面和评论组件,优化用户体验

- 将NotFoundPage重命名为ErrorPage,并优化其布局和样式
- 在评论组件中添加toast配置,改善错误提示和成功反馈
- 移除不必要的ToastContainer,简化代码结构
- 更新简历页面样式,增强视觉效果
This commit is contained in:
宇阳
2025-08-27 22:58:21 +08:00
parent 403b253575
commit c54cc1bda6
6 changed files with 36 additions and 24 deletions

View File

@@ -3,7 +3,7 @@
import { useState, useEffect, useRef } from 'react';
import { useForm } from 'react-hook-form';
import { addCommentDataAPI } from '@/api/comment';
import { ToastContainer, toast } from 'react-toastify';
import { Bounce, ToastOptions, toast } from 'react-toastify';
import { Spinner } from '@heroui/react';
import HCaptchaType from '@hcaptcha/react-hcaptcha';
import List from './components/List';
@@ -24,6 +24,18 @@ interface CommentForm {
avatar: string;
}
const toastConfig: ToastOptions = {
position: 'top-right',
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: 'colored',
transition: Bounce,
};
const CommentForm = ({ articleId }: Props) => {
const contentRef = useRef<HTMLTextAreaElement>(null);
const [commentId, setCommentId] = useState(articleId);
@@ -80,10 +92,10 @@ const CommentForm = ({ articleId }: Props) => {
if (code !== 200) {
captchaRef.current?.resetCaptcha();
return toast.error('发布评论失败:' + message);
return toast.error('发布评论失败:' + message, toastConfig);
}
toast('🎉 提交成功, 请等待审核!');
toast.success('🎉 提交成功, 请等待审核!', toastConfig);
// 发布成功后初始化表单
setCommentId(articleId);
@@ -171,7 +183,6 @@ const CommentForm = ({ articleId }: Props) => {
<List ref={commentRef} id={articleId} reply={replyComment} />
</div>
<ToastContainer />
</div>
);
};

View File

@@ -226,7 +226,7 @@ const ContentMD = ({ data }: Props) => {
return (
<div className="ContentMdComponent">
<ToastContainer theme={isDark ? 'dark' : 'light'} autoClose={1000} hideProgressBar />
<ToastContainer autoClose={1000} hideProgressBar />
<PhotoProvider>
<div className="content markdown-body">

View File

@@ -6,17 +6,15 @@ interface Props {
error: Error & { digest?: string };
}
function NotFoundPage({ error }: Props) {
function ErrorPage({ error }: Props) {
return (
<html>
<body className="bg-white">
<div className="mt-24 mx-auto flex flex-col items-center">
<MdOutlineError className="text-[15vw] text-[#ff6262]" />
<h1 className="w-6/12 text-[2vw] text-[#888] font-medium mt-8 text-xl">{error.message}</h1>
</div>
</body>
</html>
<div className="min-h-screen bg-white dark:bg-black-a flex items-center justify-center">
<div className="mx-auto flex flex-col items-center">
<MdOutlineError className="text-[15vw] text-[#ff6262]" />
<h1 className="text-[2vw] text-[#888] dark:text-white font-medium mt-8 text-xl">{error.message}</h1>
</div>
</div>
);
}
export default NotFoundPage;
export default ErrorPage;

View File

@@ -212,7 +212,7 @@ export default ({ data }: { data: Resume }) => {
<div className="space-y-6">
{workExperience?.map((job, index) => (
<div key={index} className="relative pl-6 pb-6 border-l-2 border-blue-200 dark:border-blue-900">
<div className="absolute left-[-7px] top-0 w-3 h-3 rounded-full bg-blue-500"></div>
<div className="absolute left-[-7px] top-0 w-3 h-3 rounded-full bg-blue-500 ring-4 ring-blue-100 dark:ring-blue-900"></div>
<div className="flex flex-wrap justify-between items-start mb-1">
<h4 className="text-md font-bold text-gray-900 dark:text-white">{job.company}</h4>
<span className="text-xs font-medium text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/30 px-2 py-1 rounded mt-1 md:mt-0">{job.period}</span>

View File

@@ -32,7 +32,7 @@ export default function Encrypt({ id }: Props) {
// 验证访问密码
const handleVerifyPassword = async () => {
const res = await getArticleDataAPI(id, password);
if (res?.code === 200) {
router.push(`${pathname}?password=${password}`);
} else {
@@ -71,8 +71,12 @@ export default function Encrypt({ id }: Props) {
</ModalBody>
<ModalFooter>
<Button color="default" onPress={() => router.push('/')}></Button>
<Button color="primary" onPress={handleVerifyPassword}></Button>
<Button color="default" onPress={() => router.push('/')}>
</Button>
<Button color="primary" onPress={handleVerifyPassword}>
</Button>
</ModalFooter>
</>
)}

View File

@@ -70,15 +70,14 @@ const Header = () => {
// 手动切换主题
const toTheme = () => {
const html = document.querySelector('html');
if (html) {
setIsDark(html.classList.toggle('dark'));
}
setIsDark(!isDark);
};
// 判断当前主题
useEffect(() => {
const html = document.querySelector('html');
html?.classList.toggle('dark', isDark);
if (html && html.classList) {
html?.classList?.toggle('dark', isDark);
}
}, [isDark]);
// 是否打开侧边栏导航