import Link from 'next/link'; import Image from 'next/image'; import type { Metadata } from 'next'; import { type JournalEntrySummary } from '@/lib/journal'; import { listJournalEntries } from '@/lib/admin/journal-service'; import { isAdminAuthenticated } from '@/lib/admin/auth'; import { immich } from '@/lib/immich'; import { imageUrl, assetPlaceholder } from '@/lib/urls'; import { BackLink } from '@/components/BackLink'; import { IconBook } from '@/components/Icons'; import { getServerDictionary } from '@/lib/i18n/server'; import './journal.css'; export const dynamic = 'force-dynamic'; export function generateMetadata(): Metadata { const t = getServerDictionary(); return { title: t.journal.title, description: t.journal.description }; } interface EnrichedJournalEntry extends JournalEntrySummary { coverUrl?: string; blurDataURL?: string; dominantColor?: string; } export default async function JournalIndexPage() { const t = getServerDictionary(); const isAuthedAdmin = await isAdminAuthenticated(); const allEntries = await listJournalEntries(); // Non-admins only see published entries const visibleEntries = isAuthedAdmin ? allEntries : allEntries.filter((e) => !e.frontmatter.draft); // Fetch cover image placeholders and URLs const enrichedEntries: EnrichedJournalEntry[] = await Promise.all( visibleEntries.map(async (entry) => { if (!entry.frontmatter.coverAssetId) { return entry; } try { const asset = await immich.getAssetInfo(entry.frontmatter.coverAssetId); const ph = asset ? assetPlaceholder(asset) : null; return { ...entry, coverUrl: imageUrl(entry.frontmatter.coverAssetId, 'preview'), blurDataURL: ph?.blurDataURL, dominantColor: ph?.dominantColor, }; } catch { return { ...entry, coverUrl: imageUrl(entry.frontmatter.coverAssetId, 'preview'), }; } }), ); return (
{t.journal.subtitle}
{t.journal.empty}
{entry.frontmatter.subtitle}
)} {/* extractExcerpt() falls back to the subtitle when there is one, so rendering both printed the same sentence twice. */} {entry.excerpt && entry.excerpt !== entry.frontmatter.subtitle && ({entry.excerpt}
)}