mirror of
https://github.com/LiuYuYang01/ThriveX-Blog.git
synced 2026-05-06 22:03:08 +08:00
feat: 更新错误页面和评论组件,优化用户体验
- 将NotFoundPage重命名为ErrorPage,并优化其布局和样式 - 在评论组件中添加toast配置,改善错误提示和成功反馈 - 移除不必要的ToastContainer,简化代码结构 - 更新简历页面样式,增强视觉效果
This commit is contained in:
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -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]);
|
||||
|
||||
// 是否打开侧边栏导航
|
||||
|
||||
Reference in New Issue
Block a user