@php
$purposeIsRent = $property->listing_purpose === 'for_rent';
$purposeLabel = $purposeIsRent ? 'For Rent' : 'For Sale';
$typeLabel = $propertyTypes[$property->type] ?? ucfirst(str_replace('-', ' ', $property->type));
$bhk = \App\Models\Property::bhkDisplayNumber($property->type_details['bhk'] ?? null);
// Never `location` (the free-text "Full Address" field) — exact
// address must never reach a public page (PUB-12); it's excluded at
// the query level too (see PublicPropertySearchService::DETAIL_COLUMNS).
$localityCity = (string) $property->city;
$trimNumber = fn ($n) => rtrim(rtrim(number_format((float) $n, 2, '.', ''), '0'), '.');
$areaLabel = $trimNumber($property->area) . ' ' . $property->area_unit;
// The "second spec box" (alongside Area) is genuinely different data per
// property type, not a copy of Area — flat/bungalow have a real bhk
// count; plot has real width x depth dimensions (see
// PropertyFieldTemplateSeeder's 'width_ft'/'depth_ft'); every other type
// (agricultural_land, commercial, ...) has no such distinct field today,
// so only Area renders for those rather than showing the same value
// twice under two different labels.
$plotWidth = $property->type === 'plot' ? ($property->type_details['width_ft'] ?? null) : null;
$plotDepth = $property->type === 'plot' ? ($property->type_details['depth_ft'] ?? null) : null;
$plotSizeLabel = (filled($plotWidth) && filled($plotDepth))
? $trimNumber($plotWidth) . ' x ' . $trimNumber($plotDepth) . ' ft'
: null;
$specs = [['k' => 'Type', 'v' => $typeLabel]];
if ($bhk) {
$specs[] = ['k' => 'Configuration', 'v' => $bhk . ' BHK'];
} elseif ($plotSizeLabel) {
$specs[] = ['k' => 'Plot Size', 'v' => $plotSizeLabel];
}
$specs[] = ['k' => 'Area', 'v' => $areaLabel];
$specs[] = ['k' => 'Purpose', 'v' => $purposeLabel];
$images = $property->images;
$canonicalUrl = route('public.properties.show', ['slug' => $property->public_slug, 'id' => $property->id]);
$imageUrls = $images->map(fn ($image) => route('public.properties.photo', $image))->values();
$metaDescription = Str::limit(strip_tags((string) $property->description), 155) ?: ($typeLabel . ' ' . $purposeLabel . ' in ' . $localityCity);
// RealEstateListing JSON-LD — built from exactly the same public fields
// shown on this page (PUB-11). No owner/coordinates/notes/price-history,
// no field not already rendered above (PUB-12).
$jsonLd = [
'@context' => 'https://schema.org',
'@type' => 'RealEstateListing',
'name' => $property->title,
'description' => $metaDescription,
'url' => $canonicalUrl,
'datePosted' => optional($property->created_at)->toAtomString(),
];
if ($imageUrls->isNotEmpty()) {
$jsonLd['image'] = $imageUrls->all();
}
if ($localityCity) {
$jsonLd['address'] = [
'@type' => 'PostalAddress',
'addressLocality' => $property->city,
'addressCountry' => 'IN',
];
}
$offer = [
'@type' => 'Offer',
'priceCurrency' => 'INR',
'availability' => 'https://schema.org/InStock',
'businessFunction' => $purposeIsRent
? 'http://purl.org/goodrelations/v1#LeaseOut'
: 'http://purl.org/goodrelations/v1#Sell',
];
if (! $property->price_on_request && $property->price) {
$offer['price'] = (string) $property->price;
}
$jsonLd['offers'] = $offer;
if ($bhk) {
$jsonLd['numberOfRooms'] = (int) $bhk;
}
if ($property->area) {
$jsonLd['floorSize'] = [
'@type' => 'QuantitativeValue',
'value' => (float) $property->area,
'unitText' => $property->area_unit,
];
}
@endphp
@extends('layouts.public')
@section('title', $property->title . ' | Agrawal Properties')
@section('meta_description', $metaDescription)
@push('head')
@if ($imageUrls->isNotEmpty())
@endif
@endpush
@section('content')
{{ $property->description ?: 'No description provided yet.' }}
Enlarge
{{ $property->title }}
@if ($localityCity)
About this property
Amenities & features