Comparables Search

Loading Comparables...
Search Comparables
Show Search Form
@csrf
Location
mile(s) or Draw on Map
@php // Extract School District - same logic as property-detail.blade.php $schoolDistrict = null; if ($property) { $area = $property['area'] ?? []; // Try area.schoolDistrict first (most reliable source) $schoolDistrict = $property['area']['schoolDistrict'] ?? $area['schoolDistrict'] ?? $property['_IDENTIFICATION']['@SchoolDistrict_ext'] ?? $property['identification']['@SchoolDistrict_ext'] ?? $property['_identification']['@SchoolDistrict_ext'] ?? $property['_IDENTIFICATION']['@SchoolDistrict'] ?? $property['identification']['@SchoolDistrict'] ?? $property['_identification']['@SchoolDistrict'] ?? null; // Try to extract from geoIdV4.SB if (empty($schoolDistrict) && isset($property['location']['geoIdV4']['SB'])) { $sbCodes = $property['location']['geoIdV4']['SB']; // If it's a string with multiple codes, take the first one or format it if (is_string($sbCodes)) { $sbArray = explode(', ', $sbCodes); $schoolDistrict = !empty($sbArray[0]) ? $sbArray[0] : $sbCodes; } else { $schoolDistrict = $sbCodes; } } // Fallback to other locations if (empty($schoolDistrict)) { $address = $property['address'] ?? []; $schoolDistrict = $property['address']['schoolDistrict'] ?? $address['schoolDistrict'] ?? null; } if (!empty($schoolDistrict) && $schoolDistrict !== 'N/A') { $schoolDistrictUpper = strtoupper(trim((string) $schoolDistrict)); if (strlen($schoolDistrictUpper) > 20 || preg_match('/^[A-F0-9]{20,}$/', $schoolDistrictUpper)) { $schoolDistrict = null; } else { $schoolDistrict = $schoolDistrictUpper; } } else { $schoolDistrict = null; } } // Use pre-extracted values from controller, with fallback extraction $streetName = $formStreetName ?? ''; $zipCode = $formZipCode ?? ''; $city = $formCity ?? ''; // If controller didn't extract, try extraction here if (empty($streetName) && $property && !empty($property)) { $line1 = ''; if (isset($property['address']) && is_array($property['address'])) { $line1 = $property['address']['line1'] ?? $property['address']['@_StreetAddress'] ?? $property['address']['_StreetAddress'] ?? $property['address']['line'] ?? ''; } if (empty($line1) && isset($property['MAILING_ADDRESS_ext']) && is_array($property['MAILING_ADDRESS_ext'])) { $line1 = $property['MAILING_ADDRESS_ext']['@_StreetAddress'] ?? $property['MAILING_ADDRESS_ext']['_StreetAddress'] ?? ''; } // Try top level if (empty($line1)) { $line1 = $property['@_StreetAddress'] ?? $property['_StreetAddress'] ?? ''; } if (empty($line1) && isset($property['address'])) { $line1 = $property['address']['streetAddress'] ?? $property['address']['street'] ?? $property['address']['addressLine1'] ?? ''; } if (!empty($line1)) { $parts = explode(' ', trim($line1)); if (count($parts) > 1) { array_shift($parts); $streetName = implode(' ', $parts); } else { $streetName = $line1; } } } if (empty($zipCode) && $property && !empty($property)) { // Try MAILING_ADDRESS_ext first (from Elasticsearch structure) if (isset($property['MAILING_ADDRESS_ext']) && is_array($property['MAILING_ADDRESS_ext'])) { $zipCode = $property['MAILING_ADDRESS_ext']['@_PostalCode'] ?? $property['MAILING_ADDRESS_ext']['_PostalCode'] ?? ''; } // Try address object if (empty($zipCode)) { $address = $property['address'] ?? []; $location = $property['location'] ?? []; $fullAddress = $address['oneLine'] ?? trim(($address['line1'] ?? '') . ' ' . ($address['locality'] ?? '') . ' ' . ($address['countrySubd'] ?? '') . ' ' . ($address['postal1'] ?? '')); $zipCode = $property['address']['@_PostalCode'] ?? $property['address']['_PostalCode'] ?? $property['address']['postal1'] ?? $property['address']['postalCode'] ?? $property['address']['zip'] ?? $property['address']['zipCode'] ?? $property['@_PostalCode'] ?? $property['_PostalCode'] ?? $address['@_PostalCode'] ?? $address['_PostalCode'] ?? $address['postal1'] ?? $address['postalCode'] ?? $address['zip'] ?? $address['zipCode'] ?? $location['@_PostalCode'] ?? $location['_PostalCode'] ?? $location['postal1'] ?? $location['postalCode'] ?? $location['zip'] ?? $location['zipCode'] ?? null; if (empty($zipCode)) { $zipCode = $property['address']['postal'] ?? $property['postal'] ?? $address['postal'] ?? null; } if (empty($zipCode) || $zipCode === 'N/A') { if (!empty($fullAddress) && preg_match('/\b(\d{5}(-\d{4})?)\b/', $fullAddress, $matches)) { $zipCode = $matches[1]; } } } if (!empty($zipCode) && $zipCode !== 'N/A') { $zipCode = preg_replace('/[^\d-]/', '', $zipCode); if (strlen($zipCode) > 5) { $zipCode = substr($zipCode, 0, 5); } } } if (empty($city) && $property && !empty($property)) { // Try MAILING_ADDRESS_ext first (from Elasticsearch structure) if (isset($property['MAILING_ADDRESS_ext']) && is_array($property['MAILING_ADDRESS_ext'])) { $city = $property['MAILING_ADDRESS_ext']['@_City'] ?? $property['MAILING_ADDRESS_ext']['_City'] ?? ''; } // Try address object if (empty($city) && isset($property['address']) && is_array($property['address'])) { $city = $property['address']['@_City'] ?? $property['address']['_City'] ?? $property['address']['locality'] ?? $property['address']['city'] ?? ''; } // Try top level if (empty($city)) { $city = $property['@_City'] ?? $property['_City'] ?? ''; } if (empty($city) && isset($property['address'])) { $city = $property['address']['cityName'] ?? $property['address']['municipality'] ?? $property['city'] ?? ''; } } // Ensure school district always has a value if (empty($schoolDistrict)) { $schoolDistrict = ''; } // Ensure zip code is displayed if available if (empty($zipCode) || $zipCode === 'N/A') { $zipCode = ''; } @endphp
Date & Price
or
@php $fromDateValue = ''; if (isset($searchParams['txtNjSalDtFrm']) && $searchParams['txtNjSalDtFrm']) { try { $dateStr = $searchParams['txtNjSalDtFrm']; // Check if already in MM/DD/YYYY format if (preg_match('/^\d{1,2}\/\d{1,2}\/\d{4}$/', $dateStr)) { $fromDateValue = $dateStr; } else { // Parse YYYY-MM-DD or other formats and convert to MM/DD/YYYY $fromDateValue = \Carbon\Carbon::parse($dateStr)->format('m/d/Y'); } } catch (\Exception $e) { // If parsing fails, try to format if it's already in YYYY-MM-DD $dateStr = $searchParams['txtNjSalDtFrm']; if (preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $dateStr, $matches)) { $fromDateValue = $matches[2] . '/' . $matches[3] . '/' . $matches[1]; } else { $fromDateValue = $dateStr; } } } // Always set "To" date to today's date (ignore searchParams for To date) $toDateValue = date('m/d/Y'); @endphp
To
Attributes
@php $configClassifications = $classificationOptions ?? config('property_search_options.classification', []); $classificationOptions = []; foreach ($configClassifications as $value => $label) { $classificationOptions[] = ['value' => (string) $value, 'label' => (string) $label]; } $searchWasPerformed = !empty($searchPerformed); if (isset($searchParams['ddNJSalCls']) && is_array($searchParams['ddNJSalCls'])) { $selectedClassifications = $searchParams['ddNJSalCls']; } elseif (isset($searchParams['ddNJSalCls'])) { $selectedClassifications = [$searchParams['ddNJSalCls']]; } elseif ($searchWasPerformed) { $selectedClassifications = []; } else { $selectedClassifications = []; } @endphp @foreach($classificationOptions as $option)
@endforeach
To
To
@php $styleOptions = [ ['value' => '10', 'label' => 'A-Frame'], ['value' => '59', 'label' => 'Antique'], ['value' => '13', 'label' => 'Bungalow'], ['value' => '38', 'label' => 'Cabin'], ['value' => '14', 'label' => 'Cape Cod'], ['value' => '85', 'label' => 'Chalet'], ['value' => '7', 'label' => 'Colonial'], ['value' => '69', 'label' => 'Condo/Apartment'], ['value' => '8', 'label' => 'Contemporary'], ['value' => '1', 'label' => 'Conventional'], ['value' => '45', 'label' => 'Cottage'], ['value' => '78', 'label' => 'Cottage House'], ['value' => '86', 'label' => 'Custom Design'], ['value' => '30', 'label' => 'Dome'], ['value' => '31', 'label' => 'Duplex Single'], ['value' => '5', 'label' => 'English'], ['value' => '60', 'label' => 'European'], ['value' => '87', 'label' => 'Farm House'], ['value' => '77', 'label' => 'Federalist'], ['value' => '6', 'label' => 'French'], ['value' => '57', 'label' => 'Gambrel'], ['value' => '88', 'label' => 'Garage Apartment'], ['value' => '51', 'label' => 'Garrison'], ['value' => '68', 'label' => 'High Rise'], ['value' => '66', 'label' => 'Low Rise'], ['value' => '37', 'label' => 'Mansion'], ['value' => '90', 'label' => 'Mediterranean'], ['value' => '67', 'label' => 'Mid Rise'], ['value' => '19', 'label' => 'Mobile Home'], ['value' => '2', 'label' => 'Modern'], ['value' => '82', 'label' => 'Modular'], ['value' => '56', 'label' => 'Old Style'], ['value' => '12', 'label' => 'Other'], ['value' => '34', 'label' => 'Quadraplex'], ['value' => '27', 'label' => 'Rambler'], ['value' => '11', 'label' => 'Ranch'], ['value' => '53', 'label' => 'Row End or Row Middle'], ['value' => '83', 'label' => 'Salt Box'], ['value' => '4', 'label' => 'Spanish'], ['value' => '16', 'label' => 'Split Entry'], ['value' => '17', 'label' => 'Split Level'], ['value' => '89', 'label' => 'TLog Home'], ['value' => '36', 'label' => 'Townhouse'], ['value' => '50', 'label' => 'Traditional'], ['value' => '33', 'label' => 'Triplex'], ['value' => '52', 'label' => 'Tudor'], ['value' => '76', 'label' => 'Two Family'], ['value' => '18', 'label' => 'Victorian'], ]; $selectedStyles = isset($searchParams['ddCmaStyle']) && is_array($searchParams['ddCmaStyle']) ? $searchParams['ddCmaStyle'] : (isset($searchParams['ddCmaStyle']) ? [$searchParams['ddCmaStyle']] : []); @endphp @foreach($styleOptions as $option)
@endforeach
To
To
To

Note: Square Footage, Year Built, and Style may not be available in certain areas.

@php $comparablesCount = 0; $subjectPropertyRow = null; $nonSubjectComparables = []; if (isset($comparables) && is_array($comparables)) { foreach ($comparables as $compRow) { if (!empty($compRow['isSubject'])) { $subjectPropertyRow = $compRow; } else { $nonSubjectComparables[] = $compRow; $comparablesCount++; } } } $totalComparableRows = isset($comparables) && is_array($comparables) ? count($comparables) : 0; $searchPerformed = !empty($searchPerformed); $shouldShowResults = $totalComparableRows > 0 || $searchPerformed || !empty($isInitialLoad) || $subjectPropertyRow !== null; // Always keep the subject row visible when we have one -- including the very // first page load with zero comparables -- so it's never possible to land on // this page with a real subject property and have no way to see or export it. // Previously this required $searchPerformed, which hid the subject entirely on // initial load whenever ATTOM's comparables API had no sale comps to offer. $comparablesTableRows = array_merge($subjectPropertyRow ? [$subjectPropertyRow] : [], $nonSubjectComparables); @endphp @if($shouldShowResults) @if(isset($comparables) && is_array($comparables) && $totalComparableRows > 0)

Comparables Results

@if($comparablesCount === 0) No comparable sales @else {{ $comparablesCount }} comparable {{ $comparablesCount === 1 ? 'sale' : 'sales' }} @endif @if($subjectPropertyRow) · subject property in table (marked S, not a sale comp) @endif
@if(!empty($isInitialLoad) && $comparablesCount > 0)
Showing {{ $comparablesCount }} nearby sale{{ $comparablesCount === 1 ? '' : 's' }} loaded automatically (all property types). Use filters below to narrow results — some properties limit ATTOM search radius.
@endif @if(!empty($searchPerformed) && empty($isInitialLoad))
Showing {{ $comparablesCount }} comparables matching your search form (distance, sale date, classification, style, etc.). Reset to default (all nearby)
@endif @if(!empty($classificationFilterReduced) && $comparablesCount > 0)
Classification filter applied: {{ $compsBeforeClassificationFilter ?? 0 }} → {{ $comparablesCount }} comps remain.
@endif @if(!empty($classificationFilterUnchanged) && $comparablesCount > 0)
Classification filter is working — all {{ $comparablesCount }} nearby sales match your selection @if(!empty($nearbyClassStyles)) (mostly {{ implode(', ', array_slice($nearbyClassStyles, 0, 2)) }}). @endif Use Sales Price, Year Built, or Same Street to narrow further.
@endif @if(!empty($styleFilterReduced) && $comparablesCount > 0)
Style filter applied: {{ $compsBeforeStyleFilter ?? 0 }} → {{ $comparablesCount }} comps remain.
@endif @if(!empty($styleFilterUnchanged) && $comparablesCount > 0 && empty($classificationFilterUnchanged))
Style filter is working — all {{ $comparablesCount }} comps match your style selection.
@endif @if(!empty($styleFilterMiss))
No comparables matched the Style you selected. @if(!empty($nearbyStyles)) Nearby sales in this search are mostly: {{ implode(', ', array_slice($nearbyStyles, 0, 4)) }}. @endif @if(!empty($subjectFilterSuggestion['styleLabel'])) For this subject, try {{ $subjectFilterSuggestion['styleLabel'] }}. @endif Reset to default
@endif @if(!empty($classificationFilterMiss)) @php $typeSummaryParts = []; if (!empty($nearbyTypeSummary)) { $typeLabels = [ 'condo' => 'condominiums', 'townhouse' => 'townhouses', 'single_family' => 'single-family homes', 'apartment' => 'apartments', 'duplex' => 'duplexes', 'other' => 'other types', ]; foreach ($nearbyTypeSummary as $key => $count) { $typeSummaryParts[] = $count . ' ' . ($typeLabels[$key] ?? $key); } } @endphp
No comparables matched your selected Classification@if(!empty($searchParams['ddCmaStyle'])) and Style@endif. @if($typeSummaryParts !== []) In this search area there are {{ implode(', ', $typeSummaryParts) }} — not townhouses or single-family homes. @elseif(!empty($nearbyClassStyles)) Nearby sales are mostly: {{ implode(', ', array_slice($nearbyClassStyles, 0, 4)) }}. @endif @if(!empty($subjectFilterSuggestion)) For this subject property, use {{ $subjectFilterSuggestion['classificationLabel'] }} @if(!empty($subjectFilterSuggestion['styleLabel'])) + {{ $subjectFilterSuggestion['styleLabel'] }} @endif instead. @endif Reset to default
@endif @if($comparablesCount === 0 && $subjectPropertyRow) @php $spAddress = $subjectPropertyRow['address'] ?? 'N/A'; $spClass = $subjectPropertyRow['classStyle'] ?? $subjectPropertyRow['propertyClass'] ?? $subjectPropertyRow['standardUseDescription'] ?? '—'; $spPrice = (float) ($subjectPropertyRow['price'] ?? 0); $spSqft = (float) ($subjectPropertyRow['sqft'] ?? 0); @endphp
Subject property (not a comparable sale)
{{ $spAddress }}
{{ $spClass }} @if($spSqft > 0) · {{ number_format($spSqft, 0) }} sqft @endif @if($spPrice > 0) · ${{ number_format($spPrice, 0) }} @endif
@endif

Map View

Note: Sales highlighted in yellow are Potential Flips; green are Potential Distressed Sales.

@if($comparablesCount === 0) @endif @foreach($comparablesTableRows as $index => $comp) @php $saleDate = $comp['saleDate'] ?? $comp['sale_date'] ?? ''; if ($saleDate) { try { $date = new DateTime($saleDate); $saleDate = $date->format('m/d/Y'); } catch (Exception $e) { // Keep original format if parsing fails } } $distance = $comp['distance'] ?? 0; $distanceFormatted = number_format($distance, 2); $sqft = $comp['sqft'] ?? $comp['squareFeet'] ?? $comp['square_feet'] ?? 0; $price = $comp['price'] ?? $comp['salePrice'] ?? $comp['sale_price'] ?? 0; $pricePerSqft = $comp['pricePerSqft'] ?? $comp['price_per_sqft'] ?? ($sqft > 0 && $price > 0 ? round($price / $sqft) : 0); // Try multiple fields to get propertyId/attomId $propertyId = $comp['propertyId'] ?? $comp['property_id'] ?? $comp['attomId'] ?? $comp['identifier']['attomId'] ?? $comp['identifier']['Id'] ?? $comp['_id'] ?? ''; $address = $comp['address'] ?? $comp['fullAddress'] ?? 'N/A'; // Extract subdivision - try multiple paths $subdivision = $comp['subdivision'] ?? $comp['subdname'] ?? $comp['SubdivisionName_ext'] ?? $comp['@SubdivisionName_ext'] ?? ''; // Try nested paths if still empty if (empty($subdivision) && isset($comp['area']) && is_array($comp['area'])) { $subdivision = $comp['area']['subdname'] ?? $comp['area']['subdivision'] ?? $comp['area']['@subdname'] ?? ''; } if (empty($subdivision) && isset($comp['site']) && is_array($comp['site'])) { $subdivision = $comp['site']['subdname'] ?? $comp['site']['subdivision'] ?? $comp['site']['@subdname'] ?? ''; } if (empty($subdivision) && isset($comp['legal']) && is_array($comp['legal'])) { $subdivision = $comp['legal']['subdivision'] ?? $comp['legal']['subdname'] ?? $comp['legal']['@SubdivisionName'] ?? ''; } // Use classStyle from controller (already built from @StandardUseDescription_ext or combined propertyClass + style) $classStyle = $comp['classStyle'] ?? $comp['class_style'] ?? $comp['ClassStyle'] ?? ''; // Fallback: if classStyle not available, build from propertyClass and style if (empty($classStyle)) { $propertyClass = $comp['propertyClass'] ?? $comp['property_class'] ?? $comp['class'] ?? $comp['PropertyClass'] ?? $comp['@StandardUseCode_ext'] ?? $comp['StandardUseCode_ext'] ?? ''; $style = $comp['style'] ?? $comp['archStyle'] ?? $comp['Style'] ?? $comp['ArchitecturalStyle'] ?? ''; // Also try @StandardUseDescription_ext as it might contain full description if (empty($classStyle) && !empty($comp['@StandardUseDescription_ext'])) { $classStyle = $comp['@StandardUseDescription_ext']; } elseif (empty($classStyle) && !empty($comp['StandardUseDescription_ext'])) { $classStyle = $comp['StandardUseDescription_ext']; } elseif ($propertyClass && $style) { $classStyle = $propertyClass . ', ' . $style; } elseif ($propertyClass) { $classStyle = $propertyClass; } elseif ($style) { $classStyle = $style; } } // Extract School District - format it properly $schoolDistrict = $comp['schoolDistrict'] ?? $comp['school_district'] ?? $comp['munname'] ?? ''; if (!empty($schoolDistrict)) { $schoolDistrictUpper = strtoupper(trim($schoolDistrict)); if (strlen($schoolDistrictUpper) > 20 || preg_match('/^[A-F0-9]{20,}$/', $schoolDistrictUpper)) { $schoolDistrict = '—'; } else { $schoolDistrict = ucwords(strtolower($schoolDistrict)); } } else { $schoolDistrict = '—'; } $yearBuilt = $comp['yearBuilt'] ?? $comp['year_built'] ?? $comp['built'] ?? ''; $lot = $comp['lot'] ?? $comp['lotSize'] ?? $comp['lot_size'] ?? ''; $rooms = $comp['rooms'] ?? $comp['totalRooms'] ?? $comp['total_rooms'] ?? ''; $beds = $comp['beds'] ?? $comp['bedrooms'] ?? ''; $baths = $comp['baths'] ?? $comp['bathrooms'] ?? $comp['bathstotal'] ?? ''; $garage = $comp['garage'] ?? $comp['garageType'] ?? $comp['garage_type'] ?? ''; $buyer = $comp['buyer'] ?? $comp['buyerName'] ?? ''; $seller = $comp['seller'] ?? $comp['sellerName'] ?? ''; $parties = ''; if ($buyer || $seller) { $parties = ($buyer ? 'B: ' . $buyer : '') . ($buyer && $seller ? ', S: ' : ($seller ? 'S: ' : '')) . ($seller ?? ''); } // Check for potential flip or distressed sale $isPotentialFlip = $comp['isPotentialFlip'] ?? false; $isDistressed = $comp['isDistressed'] ?? false; $rowStyle = ''; if ($isPotentialFlip) { $rowStyle = 'background-color: #fef3c7;'; } elseif ($isDistressed) { $rowStyle = 'background-color: #d1fae5;'; } // Build address string for row data attribute (with comma format) $addressLine = $comp['address'] ?? $comp['fullAddress'] ?? $comp['line1'] ?? ''; $stateForAddress = $comp['state'] ?? $comp['countrySubd'] ?? ''; if ($addressLine && isset($comp['locality'])) { $addressLine .= ', ' . $comp['locality']; } elseif ($addressLine && isset($comp['city'])) { $addressLine .= ', ' . $comp['city']; } if ($addressLine && $stateForAddress) { $addressLine .= ', ' . $stateForAddress; } if ($addressLine && isset($comp['postal1'])) { $addressLine .= ' ' . $comp['postal1']; } elseif ($addressLine && isset($comp['zip'])) { $addressLine .= ' ' . $comp['zip']; } @endphp @php $isSubjectRow = $comp['isSubject'] ?? false; $subjectRowStyle = $isSubjectRow ? 'background-color: #e0f2fe;' : ''; @endphp @endforeach
# Photo Dist Address Subdivision Class/Style School District Sqft Built Lot Rms Beds Bths Garage Price PPSFT Sale Date Parties
No comparable sales matched your search. Adjust classification, distance, or sale date and search again.
@php $isSubject = $comp['isSubject'] ?? false; // Count non-subject comparables before this one for numbering $comparableNumber = 0; if (!$isSubject) { // Count how many non-subject comparables are before this one foreach ($comparablesTableRows as $i => $c) { if ($i < $index && !($c['isSubject'] ?? false)) { $comparableNumber++; } } $comparableNumber++; // This is the next comparable number } @endphp @if($isSubject) S @else {{ $comparableNumber }} @endif
@php // Get location data (needed for both image URL and display) $county = $comp['county'] ?? $comp['countyName'] ?? $comp['munname'] ?? ''; $state = $comp['state'] ?? $comp['countrySubd'] ?? ''; // Get coordinates $lat = $comp['latitude'] ?? $comp['lat'] ?? $comp['location']['latitude'] ?? $comp['location']['lat'] ?? null; $lng = $comp['longitude'] ?? $comp['lng'] ?? $comp['lon'] ?? $comp['location']['longitude'] ?? $comp['location']['lon'] ?? null; // Build address string for image URL (with comma format) $addressLine = $comp['address'] ?? $comp['fullAddress'] ?? $comp['line1'] ?? ''; if ($addressLine && isset($comp['locality'])) { $addressLine .= ', ' . $comp['locality']; } elseif ($addressLine && isset($comp['city'])) { $addressLine .= ', ' . $comp['city']; } if ($addressLine && $state) { $addressLine .= ', ' . $state; } if ($addressLine && isset($comp['postal1'])) { $addressLine .= ' ' . $comp['postal1']; } elseif ($addressLine && isset($comp['zip'])) { $addressLine .= ' ' . $comp['zip']; } $addressEncoded = urlencode($addressLine); // Build formatted address for display $displayAddressLine1 = $comp['address'] ?? $comp['fullAddress'] ?? $comp['line1'] ?? 'N/A'; $displayAddressLine2 = ''; if (isset($comp['locality']) || isset($comp['city'])) { $city = $comp['locality'] ?? $comp['city'] ?? ''; $stateDisplay = $comp['state'] ?? $comp['countrySubd'] ?? ''; $zip = $comp['postal1'] ?? $comp['zip'] ?? ''; $displayAddressLine2 = trim($city . ' ' . $stateDisplay . ' ' . $zip); } $displayAddressLine3 = $comp['subdivision'] ?? $comp['subdname'] ?? $comp['area']['subdname'] ?? ''; $apiKey = env('GOOGLE_MAPS_API_KEY', 'AIzaSyCXanBfpLSRebgnMRqISP9SJQ0OBXRMNJQ'); $imageUrl = ''; // Never call ATTOM from the Blade loop — that caused 500× HTTP calls and 60s/180s FatalErrors. // Prefer street view by coordinates when present, otherwise by address. if ($lat && $lng) { $imageUrl = "https://maps.googleapis.com/maps/api/streetview?" . "size=80x80" . "&location={$lat},{$lng}" . "&fov=90" . "&heading=235" . "&pitch=10" . "&source=outdoor" . "&key={$apiKey}"; } elseif ($addressEncoded !== '') { $imageUrl = "https://maps.googleapis.com/maps/api/streetview?" . "size=80x80" . "&location={$addressEncoded}" . "&fov=90" . "&heading=235" . "&pitch=10" . "&source=outdoor" . "&key={$apiKey}"; } @endphp @if($imageUrl) @php $detailUrl = route('property.show', ['attomId' => $propertyId ?? '']); @endphp Property @elseif($addressLine && $addressLine != 'N/A') @php $addressSearchUrl = route('property.by.address') . '?address=' . urlencode($addressLine); @endphp Property @else
No Image
@endif
{{ $distanceFormatted }} @if($propertyId && $propertyId != '') @php $detailUrl = route('property.show', ['attomId' => $propertyId]); @endphp {{ $displayAddressLine1 }}
@if($displayAddressLine2) {{ $displayAddressLine2 }}
@endif @if($displayAddressLine3) {{ $displayAddressLine3 }} @endif
@elseif($addressLine && $addressLine != 'N/A') @php $fullAddressForSearch = $addressLine; $addressSearchUrl = route('property.by.address') . '?address=' . urlencode($fullAddressForSearch); @endphp {{ $displayAddressLine1 }}
@if($displayAddressLine2) {{ $displayAddressLine2 }}
@endif @if($displayAddressLine3) {{ $displayAddressLine3 }} @endif
@else {{ $displayAddressLine1 }}
@if($displayAddressLine2) {{ $displayAddressLine2 }}
@endif @if($displayAddressLine3) {{ $displayAddressLine3 }} @endif
@endif
@if(!empty($subdivision)) {{ $subdivision }} @else - @endif @if(!empty($classStyle)) {{ $classStyle }} @else - @endif {{ $schoolDistrict ?: '-' }} {{ $sqft > 0 ? number_format($sqft, 0) : '-' }} {{ $yearBuilt ?: '-' }} {{ $lot ?: '-' }} {{ $rooms ?: '-' }} {{ $beds ?: '-' }} {{ $baths ?: '-' }} {{ $garage ?: '-' }} {{ $price > 0 ? '$' . number_format($price, 0) : '-' }} {{ $pricePerSqft > 0 ? '$' . number_format($pricePerSqft, 0) : '-' }} {{ $saleDate ?: '-' }} {{ $parties ?: '-' }}
@elseif($searchPerformed && $totalComparableRows === 0)

No Comparables Found

No comparables were found matching your search criteria. Try increasing distance, widening the sale date range, or adjusting classification filters.

@endif @endif