export const dynamic = "force-dynamic"; import { notFound } from "next/navigation"; import Link from "next/link"; import { ArrowLeft } from "lucide-react"; import { Query } from "node-appwrite"; import { requireTenant } from "@/lib/appwrite/tenant-guard"; import { listCustomers } from "@/lib/appwrite/customer-queries"; import { DATABASE_ID, TABLES, PROPERTY_TYPE_LABELS, LISTING_TYPE_LABELS, PROPERTY_STATUS_LABELS, ACTIVITY_TYPE_LABELS, type Property, type PropertyMatch, type Activity, } from "@/lib/appwrite/schema"; import { createAdminClient } from "@/lib/appwrite/server"; import { getPropertyImagePreviewUrl, parseImageIds } from "@/lib/appwrite/storage-utils"; import { Badge } from "@/components/ui/badge"; interface Props { params: Promise<{ id: string }>; } export default async function PropertyDetailPage({ params }: Props) { const { id } = await params; const ctx = await requireTenant(); const { tablesDB } = createAdminClient(); let property: Property; try { const row = await tablesDB.getRow(DATABASE_ID, TABLES.properties, id); property = JSON.parse(JSON.stringify(row)) as Property; } catch { notFound(); } if (property.tenantId !== ctx.tenantId) notFound(); const [customers, matchesResult, activitiesResult] = await Promise.all([ listCustomers(ctx.tenantId), tablesDB.listRows({ databaseId: DATABASE_ID, tableId: TABLES.propertyMatches, queries: [ Query.equal("propertyId", id), Query.equal("tenantId", ctx.tenantId), Query.orderDesc("score"), Query.limit(50), ], }), tablesDB.listRows({ databaseId: DATABASE_ID, tableId: TABLES.activities, queries: [ Query.equal("propertyId", id), Query.equal("tenantId", ctx.tenantId), Query.orderDesc("$createdAt"), Query.limit(20), ], }), ]); const matches = JSON.parse(JSON.stringify(matchesResult.rows)) as PropertyMatch[]; const activities = JSON.parse(JSON.stringify(activitiesResult.rows)) as Activity[]; const customerMap = Object.fromEntries(customers.map((c) => [c.$id, c.name])); const imageIds = parseImageIds(property.imageIds); const statusColor: Record = { aktif: "bg-green-100 text-green-700", pasif: "bg-gray-100 text-gray-600", satildi: "bg-orange-100 text-orange-700", kiralandit: "bg-blue-100 text-blue-700", }; return (
{/* Header */}
İlanlar

{property.title}

{[property.neighborhood, property.district, property.city].filter(Boolean).join(", ")}

{PROPERTY_STATUS_LABELS[property.status] ?? property.status}
{/* Photo gallery */} {imageIds.length > 0 && (
{imageIds.map((fileId, i) => (
2 ? "col-span-2 row-span-2" : ""}`} > {/* eslint-disable-next-line @next/next/no-img-element */} {`${property.title} 2 ? "480px" : "240px" }} />
))}
)}
{/* Price */}
{property.price.toLocaleString("tr-TR")} {property.currency ?? "TRY"}
{property.roomCount && } {property.netM2 && } {property.grossM2 && } {property.floor != null && } {property.totalFloors != null && ( )} {property.buildingAge != null && ( )}
{property.address && (
Adres: {property.address}
)}
{property.description && (

Açıklama

{property.description}

)} {/* Activities */} {activities.length > 0 && (

Aktiviteler

{activities.map((a) => (
{ACTIVITY_TYPE_LABELS[a.type] ?? a.type}

{a.title}

{a.description && (

{a.description}

)}
{new Date(a.$createdAt).toLocaleDateString("tr-TR")}
))}
)}
{/* Matches sidebar */}

İlgili Müşteriler {matches.length > 0 && ( ({matches.length}) )}

{matches.length === 0 ? (

Eşleşme yok.

) : (
{matches.map((m) => (
{customerMap[m.customerId] ?? m.customerId}
))}
)}
); } function Detail({ label, value }: { label: string; value: string }) { return (
{label}: {value}
); } function ScoreBadge({ score }: { score?: number | null }) { const s = score ?? 0; const color = s >= 80 ? "bg-green-100 text-green-700" : s >= 60 ? "bg-blue-100 text-blue-700" : s >= 40 ? "bg-yellow-100 text-yellow-700" : "bg-gray-100 text-gray-500"; return ( {s} ); }