142 lines
5.9 KiB
TypeScript
142 lines
5.9 KiB
TypeScript
import { mockDb } from '@/lib/mockDb'
|
||
import { getTranslations, setRequestLocale } from 'next-intl/server'
|
||
import { Link } from '@/i18n/routing'
|
||
import Image from 'next/image'
|
||
import { Calendar, MapPin, Zap } from 'lucide-react'
|
||
import type { Metadata } from 'next'
|
||
import { basicMetadata } from '@/lib/seo'
|
||
|
||
interface Props {
|
||
params: Promise<{ locale: string }>
|
||
}
|
||
|
||
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||
const { locale } = await params
|
||
|
||
const title =
|
||
locale === 'en'
|
||
? 'Events in Marmaris — Marmaris Local'
|
||
: locale === 'ru'
|
||
? 'События в Мармарисе — Marmaris Local'
|
||
: 'Marmaris Etkinlikleri — Marmaris Local'
|
||
|
||
const description =
|
||
locale === 'en'
|
||
? 'Upcoming local events, live music nights and pool parties in Marmaris.'
|
||
: locale === 'ru'
|
||
? 'Предстоящие местные события, живая музыка и вечеринки у бассейна в Мармарисе.'
|
||
: 'Marmaris\'teki yaklaşan yerel etkinlikler, canlı müzik geceleri ve havuz partileri.'
|
||
|
||
return basicMetadata(title, description)
|
||
}
|
||
|
||
export default async function EventsPage({ params }: Props) {
|
||
const { locale } = await params
|
||
setRequestLocale(locale)
|
||
const t = await getTranslations('events')
|
||
|
||
// Get active events from DB
|
||
const events = await mockDb.getEvents(true)
|
||
|
||
return (
|
||
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12 flex-1 space-y-8">
|
||
{/* Intro section */}
|
||
<div className="max-w-2xl space-y-2">
|
||
<h1 className="font-heading font-extrabold text-3xl sm:text-5xl text-pine lowercase">
|
||
{t('title')}
|
||
</h1>
|
||
<p className="text-ink/75 text-sm sm:text-base font-medium">
|
||
{t('subtitle')}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Events Grid */}
|
||
{events.length === 0 ? (
|
||
<div className="bg-paper border border-pine/8 rounded-3xl p-12 text-center max-w-lg mx-auto">
|
||
<p className="text-shutter text-sm font-semibold">{t('noEvents')}</p>
|
||
</div>
|
||
) : (
|
||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||
{events.map((event) => {
|
||
const title = locale === 'tr' ? event.titleTr : locale === 'ru' ? event.titleRu : event.titleEn
|
||
const desc = locale === 'tr' ? event.descriptionTr : locale === 'ru' ? event.descriptionRu : event.descriptionEn
|
||
const venueName = event.listing ? event.listing.nameTr : ''
|
||
|
||
return (
|
||
<div
|
||
key={event.id}
|
||
className="bg-paper border border-pine/8 rounded-3xl overflow-hidden shadow-sm flex flex-col group hover:border-turquoise/30 hover:shadow-md transition duration-200"
|
||
>
|
||
{/* Image Cover */}
|
||
<div className="relative aspect-video bg-stone/40 overflow-hidden">
|
||
{event.coverImage ? (
|
||
<Image
|
||
src={event.coverImage}
|
||
alt={title}
|
||
fill
|
||
className="object-cover group-hover:scale-[1.02] transition duration-300"
|
||
/>
|
||
) : (
|
||
<div className="w-full h-full flex items-center justify-center text-shutter">
|
||
<Calendar className="w-8 h-8" />
|
||
</div>
|
||
)}
|
||
|
||
{/* Sponsored badge */}
|
||
{event.isSponsored && (
|
||
<span className="absolute top-4 left-4 inline-flex items-center gap-1 rounded-full bg-paper px-2.5 py-0.5 text-[9px] font-mono font-bold text-turquoise border border-turquoise/20 uppercase tracking-wider shadow-sm">
|
||
<Zap className="w-3 h-3 fill-turquoise text-turquoise" />
|
||
{t('sponsored')}
|
||
</span>
|
||
)}
|
||
</div>
|
||
|
||
{/* Event Details */}
|
||
<div className="p-6 flex-1 flex flex-col justify-between space-y-4">
|
||
<div className="space-y-2">
|
||
{/* Date badge */}
|
||
<div className="flex items-center gap-1.5 text-[11px] font-mono text-shutter font-bold uppercase tracking-wider">
|
||
<Calendar className="w-3.5 h-3.5" />
|
||
<span>
|
||
{new Date(event.startDate).toLocaleDateString(locale, {
|
||
day: 'numeric',
|
||
month: 'long',
|
||
hour: '2-digit',
|
||
minute: '2-digit'
|
||
})}
|
||
</span>
|
||
</div>
|
||
|
||
<h3 className="font-heading font-extrabold text-lg text-pine lowercase group-hover:text-turquoise transition-colors leading-tight">
|
||
{title}
|
||
</h3>
|
||
<p className="text-ink/70 text-xs leading-relaxed font-medium line-clamp-3">
|
||
{desc}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Hosting Venue info */}
|
||
{event.listing && (
|
||
<div className="border-t border-dashed border-pine/8 pt-4 flex items-center justify-between text-xs">
|
||
<div className="flex items-center gap-1 text-ink/75 font-semibold">
|
||
<MapPin className="w-3.5 h-3.5 text-shutter/65" />
|
||
<span className="lowercase text-shutter">{t('venue')}:</span>
|
||
<Link
|
||
href={`/${event.listing.category?.slug || 'isletme'}/${event.listing.slug}`}
|
||
className="text-pine hover:text-turquoise transition-colors"
|
||
>
|
||
{venueName}
|
||
</Link>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
)
|
||
})}
|
||
</div>
|
||
)}
|
||
</main>
|
||
)
|
||
}
|