'use client' import { useMemo } from 'react' import { Note } from '@/lib/types' import { cn } from '@/lib/utils' import { formatDistanceToNow, Locale } from 'date-fns' import { enUS } from 'date-fns/locale/en-US' import { fr } from 'date-fns/locale/fr' import { useLanguage } from '@/lib/i18n' import { Users, FileText, ImageIcon } from 'lucide-react' import { useSession } from 'next-auth/react' const localeMap: Record = { en: enUS, fr, } function stripHtml(html: string): string { return html.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim() } function firstImageFromContent(html: string): string | null { const m = html.match(/]+src=["']([^"']+)["']/i) return m ? m[1] : null } function previewText(note: Note): string { if (note.type === 'richtext') { return stripHtml(note.content || '').slice(0, 280) } if (note.type === 'markdown') { return (note.content || '') .replace(/^#{1,6}\s+/gm, '') .replace(/[*`_~]/g, '') .replace(/\[(.*?)\]\([^)]*\)/g, '$1') .slice(0, 280) } if (note.type === 'checklist') { const items = (note.checkItems || []).map((i) => i.text).join(' · ') return items.slice(0, 280) } return (note.content || '').slice(0, 280) } function thumbUrl(note: Note): string | null { if (note.images?.length) return note.images[0]! if (note.type === 'richtext' && note.content) { return firstImageFromContent(note.content) } return null } interface NotesListViewProps { notes: Note[] onEdit?: (note: Note, readOnly?: boolean) => void } export function NotesListView({ notes, onEdit, }: NotesListViewProps) { const { t, language } = useLanguage() const { data: session } = useSession() const currentUserId = session?.user?.id const locale = localeMap[language] || enUS const sorted = useMemo( () => [...notes].sort( (a, b) => new Date(b.contentUpdatedAt || b.updatedAt).getTime() - new Date(a.contentUpdatedAt || a.updatedAt).getTime() ), [notes] ) if (sorted.length === 0) { return (

{t('notes.emptyState')}

) } return (
{sorted.map((note) => { const thumb = thumbUrl(note) const preview = previewText(note) const title = note.title?.trim() || t('notes.untitled') const edited = new Date(note.contentUpdatedAt || note.updatedAt) const sharedCount = note.sharedWith?.length ?? 0 const isShared = sharedCount > 0 || (note as any)._isShared const isSharedNote = !!(currentUserId && note.userId && currentUserId !== note.userId) return ( ) })}
) }