feat: 将“隐私政策”、“使用条款”、“关于我们”页面修改为弹窗模式
This commit is contained in:
1 parent
85eb721888
commit
f8878bfb98
4 files changed
+119
-18
No files matched your search
@@ -3,9 +3,6 @@ import { Routes, Route } from 'react-router-dom';
|
||||
import Layout from './components/Layout';
|
||||
import HomePage from './pages/HomePage';
|
||||
import NotFoundPage from './pages/NotFoundPage';
|
||||
import PrivacyPolicyPage from './pages/PrivacyPolicyPage';
|
||||
import TermsPage from './pages/TermsPage';
|
||||
import AboutPage from './pages/AboutPage';
|
||||
import { MailboxProvider } from './contexts/MailboxContext';
|
||||
|
||||
const App: React.FC = () => {
|
||||
@@ -16,9 +13,7 @@ const App: React.FC = () => {
|
||||
<Routes>
|
||||
<Route path="/" element={<Layout />}>
|
||||
<Route index element={<HomePage />} />
|
||||
<Route path="privacy-policy" element={<PrivacyPolicyPage />} />
|
||||
<Route path="terms" element={<TermsPage />} />
|
||||
<Route path="about" element={<AboutPage />} />
|
||||
{/* 移除了 privacy-policy, terms, 和 about 的路由 */}
|
||||
<Route path="*" element={<NotFoundPage />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import Container from "./Container";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
const Footer: React.FC = () => {
|
||||
// 定义 props 类型,允许父组件传递控制弹窗显示的函数
|
||||
interface FooterProps {
|
||||
onShowInfo: (infoType: 'privacy' | 'terms' | 'about') => void;
|
||||
}
|
||||
|
||||
const Footer: React.FC<FooterProps> = ({ onShowInfo }) => {
|
||||
const { t } = useTranslation();
|
||||
const year = new Date().getFullYear();
|
||||
|
||||
@@ -15,18 +19,25 @@ const Footer: React.FC = () => {
|
||||
© {year} {t("app.title")}
|
||||
</p>
|
||||
<div className="flex flex-wrap justify-center items-center space-x-4 mb-2">
|
||||
<Link
|
||||
to="/privacy-policy"
|
||||
{/* 将 Link 组件修改为 button,点击时调用 onShowInfo 函数显示弹窗 */}
|
||||
<button
|
||||
onClick={() => onShowInfo('privacy')}
|
||||
className="hover:text-primary transition-colors"
|
||||
>
|
||||
{t("common.privacyPolicy", "隐私政策")}
|
||||
</Link>
|
||||
<Link to="/terms" className="hover:text-primary transition-colors">
|
||||
</button>
|
||||
<button
|
||||
onClick={() => onShowInfo('terms')}
|
||||
className="hover:text-primary transition-colors"
|
||||
>
|
||||
{t("common.terms", "使用条款")}
|
||||
</Link>
|
||||
<Link to="/about" className="hover:text-primary transition-colors">
|
||||
</button>
|
||||
<button
|
||||
onClick={() => onShowInfo('about')}
|
||||
className="hover:text-primary transition-colors"
|
||||
>
|
||||
{t("common.about", "关于我们")}
|
||||
</Link>
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex justify-center items-center space-x-4">
|
||||
<a
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import PrivacyPolicyPage from '../pages/PrivacyPolicyPage';
|
||||
import TermsPage from '../pages/TermsPage';
|
||||
import AboutPage from '../pages/AboutPage';
|
||||
|
||||
// 定义 props 类型
|
||||
interface InfoModalProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
type: 'privacy' | 'terms' | 'about' | null;
|
||||
}
|
||||
|
||||
const InfoModal: React.FC<InfoModalProps> = ({ isOpen, onClose, type }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (!isOpen || !type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 根据类型获取标题和内容组件
|
||||
const getContent = () => {
|
||||
switch (type) {
|
||||
case 'privacy':
|
||||
return {
|
||||
title: t('common.privacyPolicy'),
|
||||
content: <PrivacyPolicyPage />,
|
||||
};
|
||||
case 'terms':
|
||||
return {
|
||||
title: t('common.terms'),
|
||||
content: <TermsPage />,
|
||||
};
|
||||
case 'about':
|
||||
return {
|
||||
title: t('common.about'),
|
||||
content: <AboutPage />,
|
||||
};
|
||||
default:
|
||||
return {
|
||||
title: '',
|
||||
content: null,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { title, content } = getContent();
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4">
|
||||
<div className="bg-card rounded-lg shadow-xl w-full max-w-3xl max-h-[80vh] flex flex-col">
|
||||
{/* 弹窗头部 */}
|
||||
<div className="flex justify-between items-center p-4 border-b">
|
||||
<h2 className="text-xl font-semibold">{title}</h2>
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="w-8 h-8 flex items-center justify-center rounded-full hover:bg-muted"
|
||||
>
|
||||
<i className="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
{/* 弹窗内容 */}
|
||||
<div className="p-6 overflow-y-auto">
|
||||
{content}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default InfoModal;
|
||||
@@ -1,16 +1,33 @@
|
||||
import React, { useContext } from 'react';
|
||||
import React, { useContext, useState } from 'react'; // 导入 useState
|
||||
import { Outlet, useLocation } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Header from './Header';
|
||||
import Footer from './Footer';
|
||||
import SEO from './SEO';
|
||||
import { MailboxContext } from '../contexts/MailboxContext';
|
||||
import InfoModal from './InfoModal'; // 导入弹窗组件
|
||||
|
||||
const Layout: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const { mailbox, setMailbox, isLoading } = useContext(MailboxContext);
|
||||
const location = useLocation();
|
||||
|
||||
// 添加状态来管理弹窗的显示和内容
|
||||
const [infoModal, setInfoModal] = useState<{
|
||||
isOpen: boolean;
|
||||
type: 'privacy' | 'terms' | 'about' | null;
|
||||
}>({ isOpen: false, type: null });
|
||||
|
||||
// 打开弹窗的函数
|
||||
const handleShowInfo = (type: 'privacy' | 'terms' | 'about') => {
|
||||
setInfoModal({ isOpen: true, type });
|
||||
};
|
||||
|
||||
// 关闭弹窗的函数
|
||||
const handleCloseInfo = () => {
|
||||
setInfoModal({ isOpen: false, type: null });
|
||||
};
|
||||
|
||||
// 根据当前路径设置不同的SEO信息
|
||||
const getSEOProps = () => {
|
||||
const path = location.pathname;
|
||||
@@ -27,7 +44,7 @@ const Layout: React.FC = () => {
|
||||
return {
|
||||
...defaultProps,
|
||||
title: `ZMAIL-24小时匿名邮箱`,
|
||||
description: `查看 ${mailbox} 的临时邮箱收件箱,接收邮件,无需注册,保护您的隐私安全`,
|
||||
description: `查看 ${mailbox.address} 的临时邮箱收件箱,接收邮件,无需注册,保护您的隐私安全`,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -45,7 +62,14 @@ const Layout: React.FC = () => {
|
||||
<main className="flex-1 py-6">
|
||||
<Outlet />
|
||||
</main>
|
||||
<Footer />
|
||||
{/* 传递 onShowInfo 函数给 Footer 组件 */}
|
||||
<Footer onShowInfo={handleShowInfo} />
|
||||
{/* 渲染弹窗组件 */}
|
||||
<InfoModal
|
||||
isOpen={infoModal.isOpen}
|
||||
onClose={handleCloseInfo}
|
||||
type={infoModal.type}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user