Files
Momento/memento-note/components/notes-notebook-feed.tsx

70 lines
2.6 KiB
TypeScript

'use client'
import type { Note } from '@/lib/types'
import { getNoteFeedImage, getNotePlainExcerpt } from '@/lib/note-preview'
import { useLanguage } from '@/lib/i18n'
import { cn } from '@/lib/utils'
type NotesNotebookFeedProps = {
notes: Note[]
onOpen: (note: Note, readOnly?: boolean) => void
}
export function NotesNotebookFeed({ notes, onOpen }: NotesNotebookFeedProps) {
const { t } = useLanguage()
return (
<div className="mx-auto w-full max-w-3xl">
{notes.map((note) => {
const title = note.title?.trim() || t('notes.untitled')
const img = getNoteFeedImage(note)
const excerpt = getNotePlainExcerpt(note)
return (
<article
key={note.id}
className="mb-16 border-b border-foreground/10 pb-16 last:mb-0 last:border-0 last:pb-0"
>
<h2 className="font-memento-serif text-2xl font-normal tracking-tight text-foreground md:text-[1.65rem]">
{title}
</h2>
<button
type="button"
className="mt-7 w-full text-left outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded-sm"
onClick={() => onOpen(note)}
>
<div className="flex flex-col gap-8 md:flex-row md:items-start">
<div
className={cn(
'relative w-full shrink-0 overflow-hidden rounded-lg bg-muted/40 md:w-[clamp(11rem,32%,15rem)]',
'aspect-[4/3]'
)}
>
{img ? (
// eslint-disable-next-line @next/next/no-img-element -- note content may be any uploaded or external URL
<img src={img} alt="" className="h-full w-full object-cover" />
) : (
<div className="h-full w-full bg-muted/30" aria-hidden />
)}
</div>
<div className="min-w-0 flex-1 space-y-4 pt-0 md:pt-1">
{excerpt ? (
<p className="text-sm leading-relaxed text-foreground/85 line-clamp-5">
{excerpt}
</p>
) : (
<p className="text-sm italic text-muted-foreground">{t('notes.noContent')}</p>
)}
<span className="inline-block text-[11px] font-semibold uppercase tracking-[0.2em] text-muted-foreground">
{t('notes.readMore')}
</span>
</div>
</div>
</button>
</article>
)
})}
</div>
)
}