Files
role-user/src/app/(app)/announcements/[id]/page.tsx
T
2026-06-02 14:46:39 +08:00

69 lines
2.2 KiB
TypeScript

import Link from "next/link";
import { notFound } from "next/navigation";
import { ArrowLeft, Bell } from "lucide-react";
import { AnnouncementReadMarker } from "@/components/announcement-read-marker";
import { PageHeader } from "@/components/page-header";
import { StatusPill } from "@/components/status-pill";
import { BackendError } from "@/lib/backend";
import { formatDateTime } from "@/lib/format";
import { getAnnouncementDetail } from "@/lib/mobile-data";
import type { AnnouncementSummary } from "@/lib/types";
type AnnouncementDetailPageProps = {
params: Promise<{ id: string }>;
};
const levelText: Record<AnnouncementSummary["level"], string> = {
normal: "普通",
important: "重要",
urgent: "紧急"
};
const levelTone: Record<AnnouncementSummary["level"], "default" | "warning" | "danger"> = {
normal: "default",
important: "warning",
urgent: "danger"
};
export default async function AnnouncementDetailPage({ params }: AnnouncementDetailPageProps) {
const { id } = await params;
let announcement: Awaited<ReturnType<typeof getAnnouncementDetail>>;
try {
announcement = await getAnnouncementDetail(id);
} catch (error) {
if (error instanceof BackendError && error.status === 404) {
notFound();
}
throw error;
}
return (
<div className="page-stack">
<Link className="inline-link" href="/announcements">
<ArrowLeft aria-hidden size={16} />
</Link>
<PageHeader
eyebrow={formatDateTime(announcement.publishedAt)}
title={announcement.title}
description={announcement.summary}
/>
<AnnouncementReadMarker id={announcement.id} read={announcement.read} />
<section className="detail-card">
<div className="detail-meta">
<span>
<Bell aria-hidden size={16} />
</span>
<StatusPill tone={levelTone[announcement.level]}>{levelText[announcement.level]}</StatusPill>
<StatusPill tone={announcement.read ? "default" : "warning"}>{announcement.read ? "已读" : "未读"}</StatusPill>
</div>
<article className="long-copy">{announcement.content}</article>
</section>
</div>
);
}