Files
logbuch/src/components/archive/SideEntries.tsx
T
Matthias G c95db3a044 Give the archive its signature back
- the plate carries project colour on the lead image, in the cards and in
  every row, not only when an entry lacks an image
- entries no longer fade in one after another, the page is readable at once
- detail pages lead on: previous, next and more from the project
- the month band shows from the first month, the nav item hides without one
- side cards and row teasers get room instead of ellipsis
- admin opens on drafts, scheduled and published plus what was edited last,
  and its tables use the full width
2026-08-01 13:04:08 +02:00

84 lines
2.7 KiB
TypeScript

import Link from 'next/link'
import { useTranslations } from 'next-intl'
import { Badge } from '~/components/ui/Badge'
import { Cover, type CoverMedia } from '~/components/ui/Cover'
import { EntryDate } from '~/components/ui/EntryDate'
import { Plate, projectStyle } from '~/components/ui/Plate'
import { SectionLabel } from '~/components/ui/SectionLabel'
import { postPath } from '~/lib/routes'
import type { PostListItem } from '~/data/repositories/posts'
export type SideEntriesProps = {
items: PostListItem[]
covers?: Map<string, CoverMedia>
label?: string
layout?: 'column' | 'grid'
className?: string
}
const coverSizes = '(min-width: 64rem) 22rem, 40vw'
export function SideEntries({ items, covers, label, layout = 'column', className }: SideEntriesProps) {
const t = useTranslations('entry')
if (items.length === 0) {
return null
}
return (
<aside className={`flex flex-col gap-3 ${className ?? ''}`}>
<SectionLabel as="h3">{label ?? t('next')}</SectionLabel>
<ul className={`m-0 grid list-none gap-3 p-0 ${layout === 'grid' ? 'md:grid-cols-3' : 'md:grid-cols-2 lg:grid-cols-1'}`}>
{items.map(item => {
const source = { code: item.projectCode, slug: item.projectSlug }
return (
<li key={item.id}>
<Link
href={postPath(item.projectSlug, item.slug)}
style={projectStyle(item.projectColor)}
className="group flex flex-col gap-2 border border-rule bg-surface p-3 no-underline transition-colors duration-120 hover:border-ink-3 motion-reduce:transition-none"
>
<Cover
media={covers?.get(item.id)}
sizes={coverSizes}
className="aspect-shot w-full"
fallback={
<Plate
project={source}
color={item.projectColor}
number={item.number}
size="card"
className="w-full"
/>
}
/>
<span className="flex min-w-0 flex-col gap-1.5">
<span className="flex flex-wrap items-center gap-x-3 gap-y-1">
<Plate
project={source}
color={item.projectColor}
number={item.number}
size="row"
/>
<Badge type={item.type} />
</span>
<span className="font-display text-base font-semibold leading-snug text-balance text-ink">
{item.title}
</span>
{item.teaser ? (
<span className="line-clamp-2 text-small leading-snug text-ink-2">{item.teaser}</span>
) : null}
{item.publishAt ? (
<EntryDate date={item.publishAt} className="font-mono text-micro text-ink-3" />
) : null}
</span>
</Link>
</li>
)
})}
</ul>
</aside>
)
}