'use client' import { useState } from 'react' import { motion, AnimatePresence } from 'framer-motion' import { MapPin, X, Calendar, User } from 'lucide-react' import { formatDate } from '@/lib/utils' type TimelineEntry = { id: number year: string month: string | null day: string | null title: string description: string | null location: string | null media_filenames: string | null source: 'official' | 'community' contributorName?: string } interface TimelineSectionProps { entries: TimelineEntry[] } export default function TimelineSection({ entries }: TimelineSectionProps) { const [selectedEntry, setSelectedEntry] = useState(null) // Find birth and death indices const birthIndex = entries.findIndex(e => e.title.toLowerCase().includes('geburt')) const deathIndex = entries.findIndex(e => e.title.toLowerCase().includes('tod') || e.title.toLowerCase().includes('verstorben')) return (

Lebensreise

{/* Timeline Path */}
{/* Desktop: centered vertical line — w-0.5 (2 px) for better visibility */}
{/* Mobile: left-side vertical line */}
{/* Entries */}
{entries.map((entry, index) => { const isLeft = index % 2 === 0 const isBirth = index === birthIndex const isDeath = index === deathIndex const isSpecial = isBirth || isDeath const photos = entry.media_filenames ? entry.media_filenames.split(',') : [] return ( {/* Content Card */} setSelectedEntry(entry)} whileHover={{ scale: 1.02, y: -2 }} whileTap={{ scale: 0.98 }} className={`group cursor-pointer text-left w-full bg-white/80 backdrop-blur-sm rounded-xl shadow-md border border-warm-border p-4 sm:p-5 hover:shadow-lg transition-all ${ isLeft ? 'sm:mr-auto' : 'sm:ml-auto' } ${isSpecial ? 'ring-2 ring-warm-gold/30' : ''}`} style={{ minWidth: 0 }} > {/* Photos */} {photos.length > 0 && (
{photos.slice(0, 2).map((filename, i) => ( ))}
)} {/* Date */}
{formatDate(entry.year, entry.month, entry.day)}
{/* Title */}

{entry.title}

{/* Location */} {entry.location && (
{entry.location}
)} {/* Description — no clamp, card grows with content */} {entry.description && (

{entry.description}

)} {/* Contributor */} {entry.source === 'community' && entry.contributorName && (
{entry.contributorName}
)}

{photos.length > 2 && `+${photos.length - 2} weitere · `}Details →

{/* Dot - Mobile (left-side line) */}
{/* Dot - Desktop (centred line) */}
) })}
{/* Detail Modal */} {selectedEntry && ( setSelectedEntry(null)} className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/60 backdrop-blur-sm" > e.stopPropagation()} className="bg-cream rounded-2xl shadow-2xl max-w-2xl w-full max-h-[85vh] overflow-y-auto" > {/* Header */}
{formatDate(selectedEntry.year, selectedEntry.month, selectedEntry.day)}

{selectedEntry.title}

{selectedEntry.location && (
{selectedEntry.location}
)}
{/* Content */}
{/* Photos */} {selectedEntry.media_filenames && (
{selectedEntry.media_filenames.split(',').map((filename, i) => ( ))}
)} {/* Description */} {selectedEntry.description && (

{selectedEntry.description}

)} {/* Contributor info */} {selectedEntry.source === 'community' && selectedEntry.contributorName && (

Beitrag von {selectedEntry.contributorName}

)}
)}
) }