feat: update the contact page, add a modal box to display detailed information; refactor the header and footer components
This commit is contained in:
+48
-15
@@ -1,33 +1,66 @@
|
|||||||
import Link from "next/link";
|
"use client";
|
||||||
|
import { useState } from "react";
|
||||||
import { contacts } from "@/data/contacts";
|
import { contacts } from "@/data/contacts";
|
||||||
|
import Header from "@/components/header";
|
||||||
|
import Footer from "@/components/footer";
|
||||||
|
|
||||||
|
interface Contact {
|
||||||
|
name: string;
|
||||||
|
describe: string;
|
||||||
|
email?: string;
|
||||||
|
phone?: string;
|
||||||
|
qq?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
|
const [modalContent, setModalContent] = useState<Contact | null>(null);
|
||||||
|
|
||||||
|
const handleModal = (contact: Contact) => {
|
||||||
|
setModalContent(contact);
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeModal = () => {
|
||||||
|
setModalContent(null);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen flex flex-col bg-gray-50">
|
<div className="min-h-screen flex flex-col bg-gray-100">
|
||||||
<header className="w-full bg-white shadow p-4 flex justify-between items-center">
|
<Header />
|
||||||
<h1 className="text-2xl font-bold text-gray-900">联系人信息</h1>
|
|
||||||
<nav>
|
|
||||||
<Link href="/" className="text-blue-600 hover:underline">
|
|
||||||
返回主页
|
|
||||||
</Link>
|
|
||||||
</nav>
|
|
||||||
</header>
|
|
||||||
<main className="container mx-auto p-4 flex-grow">
|
<main className="container mx-auto p-4 flex-grow">
|
||||||
<section className="text-center mb-12">
|
<section className="text-center mb-12">
|
||||||
<h2 className="text-4xl font-extrabold text-gray-900">我们的联系人</h2>
|
<h2 className="text-4xl font-extrabold text-gray-900">我们的联系人</h2>
|
||||||
<p className="text-xl text-gray-600 mt-4">以下是我们的联系人的信息,您可以通过点击邮箱链接发送邮件。</p>
|
<p className="text-xl text-gray-600 mt-4">以下是我们的联系人的信息,您可以点击卡片查看全部联系方式。</p>
|
||||||
</section>
|
</section>
|
||||||
<section className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">
|
<section className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||||
{contacts.map((contact, index) => (
|
{contacts.map((contact, index) => (
|
||||||
<a key={index} href={`mailto:${contact.email}`}>
|
<div key={index} onClick={() => handleModal(contact)} className="bg-white shadow rounded-lg p-6 text-center hover:shadow-lg transition-shadow duration-300 cursor-pointer">
|
||||||
<div className="bg-white shadow rounded-lg p-6 text-center hover:shadow-lg transition-shadow duration-300">
|
|
||||||
<h3 className="text-xl font-semibold text-gray-900">{contact.name}</h3>
|
<h3 className="text-xl font-semibold text-gray-900">{contact.name}</h3>
|
||||||
<p className="text-gray-600 mt-2">{contact.email}</p>
|
<p className="text-gray-600">{contact.describe}</p>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
|
||||||
))}
|
))}
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
<Footer />
|
||||||
|
<div
|
||||||
|
className={`fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 transition-opacity duration-300 ${modalContent ? "opacity-100" : "opacity-0 pointer-events-none"}`}
|
||||||
|
onClick={closeModal}
|
||||||
|
>
|
||||||
|
{modalContent && (
|
||||||
|
<div
|
||||||
|
className={`bg-white p-6 rounded-lg shadow-lg transform transition-transform duration-300 ${modalContent ? "scale-100" : "scale-90"}`}
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
<h3 className="text-xl font-semibold text-gray-900">{modalContent.name}</h3>
|
||||||
|
<p className="text-gray-600">{modalContent.describe}</p>
|
||||||
|
{modalContent.email && <p>Email: {modalContent.email}</p>}
|
||||||
|
{modalContent.phone && <p>Phone: {modalContent.phone}</p>}
|
||||||
|
{modalContent.qq && <p>QQ: {modalContent.qq}</p>}
|
||||||
|
<button onClick={closeModal} className="mt-4 text-blue-600 hover:underline">
|
||||||
|
关闭
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
|
import Script from "next/script";
|
||||||
|
|
||||||
export default function Footer() {
|
export default function Footer() {
|
||||||
return (
|
return (
|
||||||
<footer className="w-full bg-white shadow p-4 text-left text-gray-500">
|
<footer className="container w-full bg-white shadow p-4 text-left text-gray-500 flex flex-row gap-2">
|
||||||
<p>© {new Date().getFullYear()} 智能计算实验室</p>
|
<div>© {new Date().getFullYear()} 智能计算实验室 </div>
|
||||||
|
<Script src="https://npm.onmicrosoft.cn/cloudflare-trace-info-on-web@0.0.5/cftiwo.min.js" strategy="afterInteractive" />
|
||||||
|
<div className="cloudflare-trace-info" data-template="[${colo}]${iata}">
|
||||||
|
[HKG]中国香港
|
||||||
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-3
@@ -2,10 +2,21 @@ import Link from "next/link";
|
|||||||
|
|
||||||
export default function Header() {
|
export default function Header() {
|
||||||
return (
|
return (
|
||||||
<header className="w-full bg-white shadow p-4 flex justify-between items-center">
|
<header className="home-header w-full bg-white shadow flex">
|
||||||
|
<nav className="container mx-auto flex justify-between items-center">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<Link href="/" className="hover:shadow">
|
||||||
<h1 className="text-2xl font-bold text-gray-900">智能计算实验室</h1>
|
<h1 className="text-2xl font-bold text-gray-900">智能计算实验室</h1>
|
||||||
<nav>
|
</Link>
|
||||||
<Link href="/contacts" className="text-blue-600 hover:underline">联系人</Link>
|
</div>
|
||||||
|
<div className="flex space-x-4">
|
||||||
|
<Link className="nav-link py-3 px-2" href="/">
|
||||||
|
首页
|
||||||
|
</Link>
|
||||||
|
<Link className="nav-link py-3 px-2" href="/contacts">
|
||||||
|
联系
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
);
|
);
|
||||||
|
|||||||
+11
-4
@@ -1,14 +1,21 @@
|
|||||||
export const contacts = [
|
export const contacts = [
|
||||||
{
|
{
|
||||||
name: "张三",
|
name: "张三",
|
||||||
email: "zhangsan@example.com"
|
describe: "实验室主任",
|
||||||
|
email: "zhangsan@example.com",
|
||||||
|
phone: "1234567890",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "李四",
|
name: "李四",
|
||||||
email: "lisi@example.com"
|
describe: "实验室副主任",
|
||||||
|
email: "lisi@example.com",
|
||||||
|
qq: "1234567890",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "王五",
|
name: "王五",
|
||||||
email: "wangwu@example.com"
|
describe: "实验室秘书",
|
||||||
}
|
email: "wangwu@example.com",
|
||||||
|
qq: "1234567890",
|
||||||
|
phone: "1234567890",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
+11
-11
@@ -1,22 +1,22 @@
|
|||||||
// data/websites.ts
|
// data/websites.ts
|
||||||
export const websites = [
|
export const websites = [
|
||||||
{
|
{
|
||||||
icon: "./globe.svg",
|
icon: "./gitea.svg",
|
||||||
title: "实验室网站1",
|
title: "Gitea",
|
||||||
description: "网站1的简介。",
|
description: "实验室 Git 服务。",
|
||||||
link: "https://website1.example.com",
|
link: "https://git.intcplab.cn",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: "./globe.svg",
|
icon: "./bbs.svg",
|
||||||
title: "实验室网站2",
|
title: "实验室论坛",
|
||||||
description: "网站2的简介。",
|
description: "只是一个假的论坛。",
|
||||||
link: "https://website2.example.com",
|
link: "https://website2.example.com",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: "./globe.svg",
|
icon: "./unknow.svg",
|
||||||
title: "实验室网站3",
|
title: "挑战赛排行榜",
|
||||||
description: "网站3的简介。",
|
description: "机器学习课程配套挑战赛排行榜。",
|
||||||
link: "https://website3.example.com",
|
link: "https://rank.intcplab.cn",
|
||||||
},
|
},
|
||||||
// 添加更多网站数据
|
// 添加更多网站数据
|
||||||
];
|
];
|
||||||
Reference in New Issue
Block a user