70 lines
2.6 KiB
TypeScript
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>
|
|
)
|
|
}
|