2026-05-07 15:28:48 +02:00

120 lines
5.0 KiB
TypeScript

'use client'
import { useEffect, useState } from 'react'
import Image from 'next/image'
import Link from 'next/link'
import { useRouter } from 'next/navigation'
import { useVisitor } from '@/context/VisitorContext'
import { t, tPlain } from '@/lib/i18n'
import type { SectionDTO } from '@/lib/api/types'
import AppBar from '@/components/ui/AppBar'
import { trackEvent } from '@/lib/stats'
interface Props {
section: SectionDTO
slug: string
configId: string
languages: string[]
}
export default function MenuSection({ section, slug, configId, languages }: Props) {
const { language, setAvailableLanguages, instanceId } = useVisitor()
const router = useRouter()
const [search, setSearch] = useState('')
function handleItemClick(sub: SectionDTO) {
if (!instanceId) return
trackEvent({
instanceId, configurationId: configId, sectionId: section.id,
eventType: 'MenuItemTap', language,
metadata: JSON.stringify({ targetSectionId: sub.id, title: tPlain(sub.title, language) }),
})
}
useEffect(() => { setAvailableLanguages(languages) }, [languages])
const subsections = [...(section.menu?.sections ?? [])]
.filter((s) => s.isActive !== false)
.sort((a, b) => (a.order ?? 0) - (b.order ?? 0))
const filtered = subsections.filter((s) => {
if (!search) return true
const title = tPlain(s.title, language).toLowerCase()
return title.includes(search.toLowerCase())
})
return (
<div className="min-h-screen flex flex-col" style={{ background: 'var(--color-background)' }}>
<AppBar title={tPlain(section.title, language)} onBack={() => router.back()} />
{/* Search */}
<div className="px-4 pt-3 pb-2">
<div
className="flex items-center gap-2 rounded-xl px-3 py-2"
style={{ background: 'var(--color-surface)', border: '1px solid var(--color-border)' }}
>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" style={{ color: 'var(--color-text-muted)' }}>
<path d="M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>
</svg>
<input
type="text"
value={search}
onChange={(e) => setSearch(e.target.value)}
placeholder="Rechercher..."
className="flex-1 bg-transparent text-sm outline-none"
style={{ color: 'var(--color-text)' }}
/>
{search && (
<button onClick={() => setSearch('')} style={{ color: 'var(--color-text-muted)' }}>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
)}
</div>
</div>
{/* Grid */}
<main className="flex-1 overflow-y-auto p-4 grid grid-cols-2 gap-3">
{filtered.length === 0 && (
<p className="col-span-2 text-center py-12 text-sm" style={{ color: 'var(--color-text-muted)' }}>
Aucun résultat
</p>
)}
{filtered.map((sub) => (
<Link
key={sub.id}
href={`/${slug}/${configId}/sections/${sub.id}`}
onClick={() => handleItemClick(sub)}
className="rounded-2xl overflow-hidden block relative"
style={{ background: 'var(--color-surface)', minHeight: 120 }}
>
{sub.imageSource ? (
<div className="relative w-full h-32">
<Image src={sub.imageSource} alt={tPlain(sub.title, language)} fill className="object-cover" sizes="50vw" />
<div className="absolute inset-0" style={{ background: 'linear-gradient(to top, rgba(0,0,0,0.6) 0%, transparent 60%)' }} />
<div
className="absolute bottom-2 left-3 right-7 text-white text-sm font-semibold leading-tight [&_p]:m-0 [&_p]:leading-tight"
dangerouslySetInnerHTML={{ __html: t(sub.title, language) }}
/>
<svg className="absolute bottom-2 right-2" width="15" height="15" viewBox="0 0 24 24" fill="white">
<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" />
</svg>
</div>
) : (
<div className="p-4 relative" style={{ minHeight: 80 }}>
<div
className="text-sm font-semibold pr-6 [&_p]:m-0"
style={{ color: 'var(--color-text)' }}
dangerouslySetInnerHTML={{ __html: t(sub.title, language) }}
/>
<svg className="absolute bottom-2 right-2" width="15" height="15" viewBox="0 0 24 24" fill="currentColor" style={{ color: 'var(--color-text-muted)' }}>
<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" />
</svg>
</div>
)}
</Link>
))}
</main>
</div>
)
}