This commit is contained in:
2026-05-03 08:26:15 +08:00
Unverified
parent cc40ff3a38
commit 4d7802348b
3 changed files with 179 additions and 4 deletions
+19
View File
@@ -8,6 +8,25 @@ export const site = {
footer: "高三 X 班毕业一周年纪念网站 · 初版"
};
export const contactLinks = [
{
label: "邮箱",
href: "mailto:hello@example.com",
icon: "fa-solid fa-envelope"
},
{
label: "GitHub",
href: "https://github.com/yourname",
icon: "fa-brands fa-github"
},
{
label: "微信公众号",
href: "#",
icon: "fa-brands fa-weixin",
qrImage: "/assets/wechat-qr.png"
}
];
export const navItems = [
{ label: "首页", href: "/" },
{ label: "三年时间线", href: "/timeline/" },
+45 -2
View File
@@ -1,12 +1,23 @@
---
import "../styles/global.css";
import { navItems, site } from "../data/site";
import packageJson from "../../package.json";
import { contactLinks, navItems, site } from "../data/site";
interface Props {
title?: string;
}
const { title = site.title } = Astro.props;
const buildTime = new Intl.DateTimeFormat("zh-CN", {
timeZone: "Asia/Shanghai",
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false
}).format(new Date());
---
<!doctype html>
@@ -19,6 +30,10 @@ const { title = site.title } = Astro.props;
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.css"
/>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css"
/>
</head>
<body>
<header class="site-header" aria-label="网站导航">
@@ -41,7 +56,35 @@ const { title = site.title } = Astro.props;
<slot />
<footer>{site.footer}</footer>
<footer class="site-footer">
<p>{site.footer}</p>
<p class="footer-meta">v{packageJson.version} · 构建于 {buildTime}</p>
<nav class="footer-contacts" aria-label="联系方式">
{
contactLinks.map((item) => (
<a
href={item.href}
class:list={[item.qrImage && "has-qr"]}
aria-label={item.label}
title={item.label}
target={item.href.startsWith("http") ? "_blank" : undefined}
rel={item.href.startsWith("http") ? "noreferrer" : undefined}
>
<i class={item.icon} aria-hidden="true"></i>
<span>{item.label}</span>
{
item.qrImage && (
<span class="contact-qr" aria-hidden="true">
<img src={item.qrImage} alt="" loading="lazy" />
<small>{item.label}</small>
</span>
)
}
</a>
))
}
</nav>
</footer>
<script>
const header = document.querySelector(".site-header");
const toggle = document.querySelector(".nav-toggle");
+115 -2
View File
@@ -814,14 +814,127 @@ h2 {
color: rgba(255, 253, 247, 0.78);
}
footer {
padding: 24px;
.site-footer {
display: grid;
justify-items: center;
gap: 14px;
padding: 28px 24px;
color: rgba(255, 253, 247, 0.58);
background: #1f2b2a;
text-align: center;
font-size: 14px;
}
.site-footer p {
margin: 0;
}
.footer-meta {
color: rgba(255, 253, 247, 0.42);
font-size: 12px;
}
.footer-contacts {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 10px;
}
.footer-contacts a {
position: relative;
min-width: 42px;
min-height: 42px;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 8px 12px;
border: 1px solid rgba(255, 253, 247, 0.18);
border-radius: 8px;
color: #fffdf7;
background: rgba(255, 253, 247, 0.06);
transition:
background 180ms ease,
border-color 180ms ease,
transform 180ms ease;
}
.footer-contacts .has-qr {
cursor: default;
}
.footer-contacts a:hover {
transform: translateY(-2px);
border-color: rgba(241, 201, 121, 0.58);
background: rgba(255, 253, 247, 0.12);
}
.footer-contacts i {
font-size: 18px;
}
.footer-contacts span {
font-size: 13px;
font-weight: 700;
}
.contact-qr {
position: absolute;
left: 50%;
bottom: calc(100% + 12px);
z-index: 5;
width: 156px;
display: grid;
gap: 8px;
justify-items: center;
padding: 12px;
border: 1px solid rgba(31, 43, 42, 0.12);
border-radius: 8px;
background: #fffdf7;
color: var(--ink);
box-shadow: 0 18px 44px rgba(13, 20, 19, 0.28);
opacity: 0;
pointer-events: none;
transform: translate(-50%, 8px);
transition:
opacity 180ms ease,
transform 180ms ease;
}
.contact-qr::after {
content: "";
position: absolute;
left: 50%;
bottom: -7px;
width: 14px;
height: 14px;
background: #fffdf7;
border-right: 1px solid rgba(31, 43, 42, 0.12);
border-bottom: 1px solid rgba(31, 43, 42, 0.12);
transform: translateX(-50%) rotate(45deg);
}
.contact-qr img {
width: 132px;
height: 132px;
object-fit: contain;
border-radius: 4px;
background: #f4f7ee;
}
.contact-qr small {
color: var(--muted);
font-size: 12px;
line-height: 1.3;
}
.footer-contacts a:hover .contact-qr,
.footer-contacts a:focus-visible .contact-qr {
opacity: 1;
transform: translate(-50%, 0);
}
@media (max-width: 820px) {
.site-header {
position: absolute;