103 lines
3.9 KiB
TypeScript
103 lines
3.9 KiB
TypeScript
import { prisma } from "@/lib/db";
|
|
import { Download, Calendar, Tag } from "lucide-react";
|
|
|
|
export const metadata = {
|
|
title: "版本历史",
|
|
description: "Nanami 启动器版本更新日志",
|
|
};
|
|
|
|
export const revalidate = 120;
|
|
|
|
export default async function ChangelogPage() {
|
|
const software = await prisma.software.findUnique({
|
|
where: { slug: "nanami-launcher" },
|
|
include: {
|
|
versions: {
|
|
orderBy: { versionCode: "desc" },
|
|
},
|
|
},
|
|
});
|
|
|
|
const versions = software?.versions ?? [];
|
|
|
|
return (
|
|
<section className="mx-auto max-w-3xl px-3 py-10 sm:px-4 sm:py-16">
|
|
<h1 className="mb-2 text-2xl font-bold text-amber-100 sm:text-3xl">
|
|
版本历史
|
|
</h1>
|
|
<p className="mb-8 text-sm text-gray-400 sm:mb-12 sm:text-base">
|
|
Nanami 启动器更新日志
|
|
</p>
|
|
|
|
{versions.length === 0 ? (
|
|
<p className="py-16 text-center text-gray-500">暂无版本记录</p>
|
|
) : (
|
|
<div className="relative">
|
|
{/* Timeline line */}
|
|
<div className="absolute left-[15px] top-2 bottom-0 w-px bg-amber-500/20 sm:left-[19px]" />
|
|
|
|
<div className="space-y-8 sm:space-y-10">
|
|
{versions.map((v, idx) => (
|
|
<div key={v.id} className="relative pl-10 sm:pl-12">
|
|
{/* Timeline dot */}
|
|
<div
|
|
className={`absolute left-[10px] top-1.5 h-3 w-3 rounded-full border-2 sm:left-[13px] sm:h-3.5 sm:w-3.5 ${
|
|
idx === 0
|
|
? "border-amber-400 bg-amber-400 shadow-[0_0_8px_rgba(251,191,36,0.5)]"
|
|
: "border-amber-500/40 bg-[#0d0b15]"
|
|
}`}
|
|
/>
|
|
|
|
<div className="rounded-lg border border-amber-500/10 bg-white/[0.03] p-4 sm:p-5">
|
|
{/* Header */}
|
|
<div className="mb-3 flex flex-wrap items-center gap-2 sm:gap-3">
|
|
<h2 className="text-lg font-semibold text-amber-100 sm:text-xl">
|
|
v{v.version}
|
|
</h2>
|
|
{v.isLatest && (
|
|
<span className="rounded-full bg-amber-500/15 px-2 py-0.5 text-[10px] font-medium text-amber-300 sm:text-xs">
|
|
最新版本
|
|
</span>
|
|
)}
|
|
{v.forceUpdate && (
|
|
<span className="rounded-full bg-red-500/15 px-2 py-0.5 text-[10px] font-medium text-red-400 sm:text-xs">
|
|
强制更新
|
|
</span>
|
|
)}
|
|
</div>
|
|
|
|
{/* Meta */}
|
|
<div className="mb-3 flex flex-wrap items-center gap-3 text-xs text-gray-500 sm:gap-4 sm:text-sm">
|
|
<span className="flex items-center gap-1">
|
|
<Calendar className="h-3 w-3 sm:h-3.5 sm:w-3.5" />
|
|
{new Date(v.createdAt).toLocaleDateString("zh-CN")}
|
|
</span>
|
|
<span className="flex items-center gap-1">
|
|
<Tag className="h-3 w-3 sm:h-3.5 sm:w-3.5" />
|
|
Build {v.versionCode}
|
|
</span>
|
|
<span className="flex items-center gap-1">
|
|
<Download className="h-3 w-3 sm:h-3.5 sm:w-3.5" />
|
|
{v.downloadCount.toLocaleString()} 次下载
|
|
</span>
|
|
{v.fileSize > 0 && (
|
|
<span className="text-gray-600">
|
|
{(v.fileSize / 1024 / 1024).toFixed(1)} MB
|
|
</span>
|
|
)}
|
|
</div>
|
|
|
|
{/* Changelog */}
|
|
<div className="whitespace-pre-wrap text-sm leading-relaxed text-gray-300 sm:text-[15px]">
|
|
{v.changelog || "无更新说明"}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</section>
|
|
);
|
|
}
|