chore: clean up scratch files and apply remaining updates
This commit is contained in:
@@ -7,6 +7,8 @@ import { Link } from '@/i18n/routing'
|
||||
import { Phone, Globe, MapPin, Clock, Star, MessageSquare, Share2 } from 'lucide-react'
|
||||
import SaveButton from './SaveButton'
|
||||
import DetailTracker from './DetailTracker'
|
||||
import type { Metadata } from 'next'
|
||||
import { SITE_URL } from '@/lib/seo'
|
||||
|
||||
interface DetailPageProps {
|
||||
params: Promise<{ locale: string; category: string; slug: string }>
|
||||
@@ -14,14 +16,32 @@ interface DetailPageProps {
|
||||
|
||||
export const dynamic = 'force-dynamic'
|
||||
|
||||
export async function generateMetadata({ params }: DetailPageProps) {
|
||||
const { slug } = await params
|
||||
export async function generateMetadata({ params }: DetailPageProps): Promise<Metadata> {
|
||||
const { locale, slug } = await params
|
||||
const listing = await mockDb.getListingBySlug(slug)
|
||||
if (!listing) return {}
|
||||
|
||||
const name = locale === 'ru' ? listing.nameRu : locale === 'en' ? listing.nameEn : listing.nameTr
|
||||
const description = locale === 'ru' ? listing.descriptionRu : locale === 'en' ? listing.descriptionEn : listing.descriptionTr
|
||||
const title = `${name} — Marmaris Local`
|
||||
const image = listing.images?.[0]?.url
|
||||
|
||||
return {
|
||||
title: `${listing.nameTr} — Marmaris Local`,
|
||||
description: listing.descriptionTr
|
||||
title,
|
||||
description,
|
||||
openGraph: {
|
||||
title,
|
||||
description,
|
||||
url: `${SITE_URL}/${locale}/${listing.category?.slug || 'isletme'}/${listing.slug}`,
|
||||
siteName: 'Marmaris Local',
|
||||
type: 'website',
|
||||
...(image ? { images: [{ url: image }] } : {}),
|
||||
},
|
||||
twitter: {
|
||||
card: 'summary_large_image',
|
||||
title,
|
||||
description,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,8 +106,43 @@ export default async function ListingDetailPage({ params }: DetailPageProps) {
|
||||
return `https://wa.me/?text=${text}`
|
||||
}
|
||||
|
||||
// schema.org LocalBusiness structured data
|
||||
const schemaTypeByCategory: Record<string, string> = {
|
||||
restoran: 'Restaurant',
|
||||
apart: 'LodgingBusiness',
|
||||
isletme: 'LocalBusiness',
|
||||
}
|
||||
|
||||
const jsonLd = {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': schemaTypeByCategory[categorySlug] || 'LocalBusiness',
|
||||
name,
|
||||
description,
|
||||
image: listing.images?.map(img => img.url) || undefined,
|
||||
url: `https://marmarislocal.com/${locale}/${categorySlug}/${listing.slug}`,
|
||||
address: {
|
||||
'@type': 'PostalAddress',
|
||||
streetAddress: listing.address,
|
||||
addressLocality: 'Marmaris',
|
||||
addressCountry: 'TR',
|
||||
},
|
||||
...(listing.latitude && listing.longitude
|
||||
? { geo: { '@type': 'GeoCoordinates', latitude: listing.latitude, longitude: listing.longitude } }
|
||||
: {}),
|
||||
...(listing.phone ? { telephone: listing.phone } : {}),
|
||||
...(listing.website ? { sameAs: [listing.website] } : {}),
|
||||
priceRange: priceSymbols || undefined,
|
||||
...(listing.openingHours && (listing.openingHours as any).all
|
||||
? { openingHours: (listing.openingHours as any).all }
|
||||
: {}),
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex-1 flex flex-col min-h-screen bg-stone text-ink">
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
|
||||
/>
|
||||
<DetailTracker listingId={listing.id} />
|
||||
|
||||
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-10 flex-1 space-y-10">
|
||||
|
||||
@@ -5,6 +5,8 @@ import { Link } from '@/i18n/routing'
|
||||
import { notFound } from 'next/navigation'
|
||||
import { MapPin, SlidersHorizontal, Check } from 'lucide-react'
|
||||
import LiveFilterForm from '@/components/LiveFilterForm'
|
||||
import type { Metadata } from 'next'
|
||||
import { basicMetadata } from '@/lib/seo'
|
||||
|
||||
interface PageProps {
|
||||
params: Promise<{ locale: string, category: string }>
|
||||
@@ -18,6 +20,31 @@ interface PageProps {
|
||||
|
||||
export const dynamic = 'force-dynamic'
|
||||
|
||||
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
|
||||
const { locale, category: categorySlug } = await params
|
||||
const categories = await mockDb.getCategories()
|
||||
const category = categories.find(c => c.slug === categorySlug)
|
||||
if (!category) return {}
|
||||
|
||||
const name = locale === 'ru' ? category.nameRu : locale === 'en' ? category.nameEn : category.nameTr
|
||||
|
||||
const title =
|
||||
locale === 'en'
|
||||
? `${name} in Marmaris — Marmaris Local`
|
||||
: locale === 'ru'
|
||||
? `${name} в Мармарисе — Marmaris Local`
|
||||
: `Marmaris ${name} Rehberi — Marmaris Local`
|
||||
|
||||
const description =
|
||||
locale === 'en'
|
||||
? `Browse the best ${name.toLowerCase()} in Marmaris, filtered by neighborhood and price — curated and locally approved.`
|
||||
: locale === 'ru'
|
||||
? `Лучшие места категории «${name}» в Мармарисе — с фильтрами по районам и ценам, проверено местными.`
|
||||
: `Marmaris'teki en iyi ${name.toLowerCase()} listesi — mahalle ve fiyata göre filtrele, yerel onaylılardan seç.`
|
||||
|
||||
return basicMetadata(title, description)
|
||||
}
|
||||
|
||||
export default async function DynamicCategoryPage({ params, searchParams }: PageProps) {
|
||||
const { locale, category: categorySlug } = await params
|
||||
setRequestLocale(locale)
|
||||
|
||||
Reference in New Issue
Block a user