feat: add policy pages
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
import type { Metadata } from "next";
|
||||
import Link from "next/link";
|
||||
import { notFound } from "next/navigation";
|
||||
import { getTranscriptionsByPlace } from "@/lib/transcriptions";
|
||||
import { buildOgMeta } from "@/lib/og";
|
||||
import { PageHeader } from "@/components/page-header";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Clock, MapPin } from "lucide-react";
|
||||
import { PlayAudioButton } from "@/app/(app)/transcriptions/[slug]/play-audio-button";
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ place: string }>;
|
||||
}): Promise<Metadata> {
|
||||
const { place: encodedPlace } = await params;
|
||||
const place = decodeURIComponent(encodedPlace);
|
||||
const transcriptions = await getTranscriptionsByPlace(place);
|
||||
return buildOgMeta({
|
||||
title: "Transcriptions",
|
||||
detail: `${transcriptions.length} transcriptions from ${place}`,
|
||||
quote: `Lectures and conversations of Śrīla Prabhupāda in ${place}.`,
|
||||
});
|
||||
}
|
||||
|
||||
export default async function TranscriptionsByPlacePage({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ place: string }>;
|
||||
}) {
|
||||
const { place: encodedPlace } = await params;
|
||||
const place = decodeURIComponent(encodedPlace);
|
||||
|
||||
const transcriptions = await getTranscriptionsByPlace(place);
|
||||
if (transcriptions.length === 0) notFound();
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
<PageHeader sticky>
|
||||
<Link
|
||||
href="/transcriptions?view=place"
|
||||
className="text-sm text-muted-foreground hover:text-foreground transition-colors"
|
||||
>
|
||||
← Transcriptions by Place
|
||||
</Link>
|
||||
<h1 className="mt-3 text-2xl font-bold text-foreground">
|
||||
Transcriptions in {place}
|
||||
</h1>
|
||||
<p className="mt-1 text-sm text-muted-foreground">
|
||||
{transcriptions.length} transcriptions
|
||||
</p>
|
||||
</PageHeader>
|
||||
|
||||
<main className="max-w-5xl mx-auto px-6 py-8">
|
||||
<Card className="overflow-hidden">
|
||||
<CardContent className="p-0 divide-y divide-border">
|
||||
{transcriptions.map((t) => (
|
||||
<Link
|
||||
key={t.slug}
|
||||
href={`/transcriptions/${t.slug}`}
|
||||
className="flex items-center px-5 py-3.5 gap-3 hover:bg-muted transition-colors"
|
||||
>
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
<p className="font-medium text-foreground text-sm">
|
||||
{t.name}
|
||||
</p>
|
||||
<Badge
|
||||
variant={t.type === "lecture" ? "default" : "secondary"}
|
||||
className="text-[10px] px-1.5 py-0"
|
||||
>
|
||||
{t.type === "lecture" ? "Lecture" : "Conversation"}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="flex items-center gap-3 mt-1 text-xs text-muted-foreground">
|
||||
{t.date && <span>{t.date}</span>}
|
||||
{t.reference && (
|
||||
<span className="text-primary/70">{t.reference}</span>
|
||||
)}
|
||||
{t.durationMinutes && t.durationMinutes > 0 && (
|
||||
<span className="flex items-center gap-1">
|
||||
<Clock className="size-3" />
|
||||
{t.durationMinutes} min
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{t.audioUrl && (
|
||||
<PlayAudioButton
|
||||
audioUrl={t.audioUrl}
|
||||
title={t.name}
|
||||
subtitle={[t.date, t.place].filter(Boolean).join(" · ")}
|
||||
sourceUrl={`/transcriptions/${t.slug}`}
|
||||
type={t.type}
|
||||
variant="compact"
|
||||
/>
|
||||
)}
|
||||
</Link>
|
||||
))}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user