@burdenoff/microfe-housingvista 2026.930.1 → 2026.930.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/housingvista/components/PropertyCard.d.ts +5 -1
- package/dist/housingvista/components/PropertyCard.d.ts.map +1 -1
- package/dist/housingvista/components/PropertyCard.js +77 -67
- package/dist/housingvista/components/PropertyCard.js.map +1 -1
- package/dist/housingvista/components/maps/PropertyMapView.d.ts.map +1 -1
- package/dist/housingvista/components/maps/PropertyMapView.js +72 -65
- package/dist/housingvista/components/maps/PropertyMapView.js.map +1 -1
- package/dist/housingvista/pages/properties/PropertiesPage.d.ts.map +1 -1
- package/dist/housingvista/pages/properties/PropertiesPage.js +355 -324
- package/dist/housingvista/pages/properties/PropertiesPage.js.map +1 -1
- package/dist/housingvista/pages/properties/PropertyDetailPage.d.ts.map +1 -1
- package/dist/housingvista/pages/properties/PropertyDetailPage.js +220 -220
- package/dist/housingvista/pages/properties/PropertyDetailPage.js.map +1 -1
- package/dist/housingvista/pages/shortlist/ShortlistPage.d.ts.map +1 -1
- package/dist/housingvista/pages/shortlist/ShortlistPage.js +1 -0
- package/dist/housingvista/pages/shortlist/ShortlistPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PropertyDetailPage.js","names":[],"sources":["../../../../src/housingvista/pages/properties/PropertyDetailPage.tsx"],"sourcesContent":["/**\n * HousingVista Property Detail Page\n * Full property detail view backed by the single-item `housingvistaProperty(id)`\n * query, with the core buyer journey wired to real mutations: shortlist, book a\n * viewing, submit an offer, plus owner-side edit and delete.\n * @module housingvista\n */\n\nimport { useState, useMemo, type FormEvent } from 'react';\nimport { useParams, useNavigate, useLocation } from 'react-router';\nimport {\n ArrowLeft,\n MapPin,\n Bed,\n Bath,\n Square,\n Car,\n Heart,\n Share2,\n CheckCircle,\n Calendar,\n DollarSign,\n ChevronLeft,\n ChevronRight,\n Building,\n Pencil,\n Trash2,\n Calculator,\n Download,\n TrendingUp,\n MessageSquare,\n KeyRound,\n BadgeCheck,\n Compass,\n Waves,\n Dumbbell,\n Shield,\n TreePine,\n Wifi,\n Wind,\n Flame,\n Utensils,\n ParkingCircle,\n Navigation,\n type LucideIcon,\n} from 'lucide-react';\nimport { AreaChart, Area, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts';\nimport {\n EmphasisPanel,\n PagePurpose,\n NextSteps,\n Button,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Breadcrumbs,\n StatusBadge,\n EmptyState,\n LoadingSkeleton,\n ContactOwnerDialog,\n ReviewsSection,\n} from '../../components';\nimport type { BreadcrumbItem } from '../../components';\nimport {\n useProperty,\n useProperties,\n useShortlists,\n useSaveShortlist,\n useRemoveShortlist,\n useBookViewing,\n useSubmitOffer,\n useUpdateProperty,\n useDeleteProperty,\n useRentalUnits,\n useSubmitRentalApplication,\n useCreateInvestment,\n useUpdatePropertyReraStatus,\n type UpdatePropertyInput,\n} from '../../hooks';\nimport { notify } from '../../lib/toast';\nimport { useHousingVistaAnalytics, useTrackPageView } from '../../hooks/useHousingVistaAnalytics';\nimport { cn, formatCurrency, formatCompactCurrency, formatNumber, formatDate } from '../../utils/helpers';\nimport { amenityOptions } from '../../utils/amenities';\nimport {\n propertyTypeOptions,\n propertyCategoryOptions,\n currencyOptions,\n furnishingOptions,\n facingOptions,\n} from '../../utils/propertyOptions';\nimport { CoordinatePicker, type PickerCoordinates } from '../../components/maps/CoordinatePicker';\nimport type { Amenity, Property, PropertyCategory, PropertyStatus, PropertyType } from '../../types';\n\nconst statusVariantMap: Record<string, 'success' | 'warning' | 'error' | 'info' | 'default' | 'muted'> = {\n for_sale: 'success',\n for_rent: 'info',\n sold: 'muted',\n rented: 'muted',\n under_contract: 'warning',\n off_market: 'error',\n};\n\nconst statusOptions: { value: PropertyStatus; label: string }[] = [\n { value: 'for_sale', label: 'For Sale' },\n { value: 'for_rent', label: 'For Rent' },\n { value: 'under_contract', label: 'Under Contract' },\n { value: 'sold', label: 'Sold' },\n { value: 'rented', label: 'Rented' },\n { value: 'off_market', label: 'Off Market' },\n];\n\n// Edit-dialog choices come from the shared catalogs (utils/propertyOptions.ts,\n// utils/amenities.ts) so create and edit can never drift. priceType/pricePeriod\n// are edit-only selects (the wizard derives them from its listing-type radio).\nconst priceTypeOptions: { value: string; label: string }[] = [\n { value: 'sale', label: 'Sale' },\n { value: 'rent', label: 'Rent' },\n { value: 'lease', label: 'Lease' },\n];\n\nconst pricePeriodOptions: { value: string; label: string }[] = [\n { value: '', label: '— (one-time)' },\n { value: 'monthly', label: 'Monthly' },\n { value: 'quarterly', label: 'Quarterly' },\n { value: 'yearly', label: 'Yearly' },\n];\n\n/** Full edit form. All numeric fields are strings (controlled inputs). */\ninterface EditFormState {\n title: string;\n description: string;\n status: PropertyStatus;\n type: PropertyType;\n category: PropertyCategory;\n address: string;\n city: string;\n state: string;\n country: string;\n pincode: string;\n neighborhood: string;\n landmarks: string;\n coordinates: PickerCoordinates | null;\n bedrooms: string;\n bathrooms: string;\n /** Original amenity records whose name matches the shared catalog — their stored\n * category/availability must survive a chip toggle. */\n catalogAmenities: Amenity[];\n totalArea: string;\n carpetArea: string;\n builtUpArea: string;\n floors: string;\n totalFloors: string;\n parking: string;\n balconies: string;\n furnishingStatus: string;\n ageOfProperty: string;\n facing: string;\n price: string;\n currency: string;\n priceType: string;\n pricePeriod: string;\n negotiable: boolean;\n pricePerSqft: string;\n amenities: string[];\n /** Amenity records whose names fall outside the shared catalog; preserved verbatim. */\n extraAmenities: Amenity[];\n}\n\nconst EMPTY_EDIT_FORM: EditFormState = {\n title: '',\n description: '',\n status: 'for_sale',\n type: 'residential',\n category: 'apartment',\n address: '',\n city: '',\n state: '',\n country: '',\n pincode: '',\n neighborhood: '',\n landmarks: '',\n coordinates: null,\n bedrooms: '',\n bathrooms: '',\n catalogAmenities: [],\n totalArea: '',\n carpetArea: '',\n builtUpArea: '',\n floors: '',\n totalFloors: '',\n parking: '',\n balconies: '',\n furnishingStatus: 'unfurnished',\n ageOfProperty: '',\n facing: '',\n price: '',\n currency: 'USD',\n priceType: 'sale',\n pricePeriod: '',\n negotiable: true,\n pricePerSqft: '',\n amenities: [],\n extraAmenities: [],\n};\n\nconst toNumber = (value: string): number | null => {\n const trimmed = value.trim();\n if (trimmed === '') return null;\n const parsed = Number(trimmed);\n return Number.isFinite(parsed) ? parsed : null;\n};\n\nconst optionalNumber = (value: string): number | undefined => {\n const parsed = toNumber(value);\n return parsed === null ? undefined : parsed;\n};\n\nconst fieldText = (value: number | undefined): string => (value == null ? '' : String(value));\n\n// Landmarks are captured as a comma-separated list; normalize before comparing\n// so a no-op edit round-trip does not count as a change.\nconst normalizeLandmarks = (csv: string): string[] =>\n csv\n .split(',')\n .map((item) => item.trim())\n .filter(Boolean);\n\nconst numericFields = [\n { key: 'bedrooms', label: 'Bedrooms', required: false, step: '1' },\n { key: 'bathrooms', label: 'Bathrooms', required: false, step: '1' },\n { key: 'totalArea', label: 'Total area (sqft) *', required: true, step: '0.01' },\n { key: 'carpetArea', label: 'Carpet area', required: false, step: '0.01' },\n { key: 'builtUpArea', label: 'Built-up area', required: false, step: '0.01' },\n { key: 'floors', label: 'Floor', required: false, step: '1' },\n { key: 'totalFloors', label: 'Total floors', required: false, step: '1' },\n { key: 'parking', label: 'Parking spots', required: false, step: '1' },\n { key: 'balconies', label: 'Balconies', required: false, step: '1' },\n { key: 'ageOfProperty', label: 'Age (years)', required: false, step: '1' },\n] as const satisfies readonly {\n key: keyof EditFormState;\n label: string;\n required: boolean;\n step: string;\n}[];\n\n/** +7 days default for the offer \"Valid until\" picker — UI convenience only;\n * the backend stores no default (unset expiresAt = never expires, BOFF-8053). */\nfunction defaultOfferExpiry(): string {\n const date = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);\n return new Date(date.getTime() - date.getTimezoneOffset() * 60000).toISOString().slice(0, 16);\n}\n\ntype TabId = 'details' | 'amenities' | 'location';\nconst tabs: { id: TabId; label: string }[] = [\n { id: 'details', label: 'Details' },\n { id: 'amenities', label: 'Amenities' },\n { id: 'location', label: 'Location' },\n];\n\nconst inputClass =\n 'h-10 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]';\n\n// Map free-text amenity names to a recognisable icon (falls back to a tick).\nconst amenityIconRules: { match: RegExp; icon: LucideIcon }[] = [\n { match: /pool|swim/i, icon: Waves },\n { match: /gym|fitness/i, icon: Dumbbell },\n { match: /park/i, icon: ParkingCircle },\n { match: /garden|green|lawn|park/i, icon: TreePine },\n { match: /security|guard|cctv|gated/i, icon: Shield },\n { match: /wifi|internet|broadband/i, icon: Wifi },\n { match: /a\\/?c|air.?condition|central air|hvac/i, icon: Wind },\n { match: /fire|chimney|heat/i, icon: Flame },\n { match: /kitchen|modular|dining/i, icon: Utensils },\n { match: /car|garage/i, icon: Car },\n];\nconst amenityIcon = (name: string): LucideIcon => amenityIconRules.find((r) => r.match.test(name))?.icon ?? CheckCircle;\n\n// `RentalUnit.status` is a free-form String on the subgraph and is written in\n// lower_snake_case by the service — normalise at render rather than trusting\n// the TS union's casing.\nfunction rentalUnitStatusLabel(status: string): string {\n switch (status.toLowerCase()) {\n case 'vacant':\n return 'Vacant — accepting applications';\n case 'occupied':\n return 'Currently occupied';\n case 'notice_period':\n return 'On notice';\n case 'maintenance':\n return 'Under maintenance';\n default:\n return status.replace(/[-_]/g, ' ');\n }\n}\n\nfunction rentalUnitStatusVariant(status: string): 'success' | 'warning' | 'error' | 'info' | 'muted' {\n switch (status.toLowerCase()) {\n case 'vacant':\n return 'success';\n case 'occupied':\n return 'muted';\n case 'notice_period':\n return 'info';\n case 'maintenance':\n return 'error';\n default:\n return 'muted';\n }\n}\n\nexport const PropertyDetailPage = () => {\n const { id } = useParams<{ id: string }>();\n const navigate = useNavigate();\n const location = useLocation();\n const { emit, emitResource } = useHousingVistaAnalytics();\n useTrackPageView('housingvista.property.viewed', id);\n\n const { data: property, loading } = useProperty(id);\n const { data: allProperties } = useProperties({ pagination: { limit: 8, offset: 0 } });\n const { data: shortlists } = useShortlists();\n const { data: rentalUnits } = useRentalUnits({\n filter: id ? { propertyId: id } : undefined,\n pagination: { limit: 1, offset: 0 },\n });\n const { saveShortlist, loading: savingShortlist } = useSaveShortlist();\n const { removeShortlist, loading: removingShortlist } = useRemoveShortlist();\n const { bookViewing, loading: bookingViewing } = useBookViewing();\n const { submitOffer, loading: submittingOffer } = useSubmitOffer();\n const { updateProperty, loading: updatingProperty } = useUpdateProperty();\n const { deleteProperty, loading: deletingProperty } = useDeleteProperty();\n const { submitRentalApplication, loading: submittingRental } = useSubmitRentalApplication();\n const { createInvestment, loading: creatingInvestment } = useCreateInvestment();\n const { updatePropertyReraStatus, loading: reviewingRera } = useUpdatePropertyReraStatus();\n\n const similarProperties = useMemo(() => allProperties.filter((p) => p.id !== id).slice(0, 3), [allProperties, id]);\n const isShortlisted = useMemo(() => shortlists.some((s) => s.propertyId === id), [shortlists, id]);\n\n const [currentImageIndex, setCurrentImageIndex] = useState(0);\n const [activeTab, setActiveTab] = useState<TabId>('details');\n const [viewingOpen, setViewingOpen] = useState(false);\n const [offerOpen, setOfferOpen] = useState(false);\n const [editOpen, setEditOpen] = useState(false);\n const [deleteOpen, setDeleteOpen] = useState(false);\n const [rentalOpen, setRentalOpen] = useState(false);\n const [contactOpen, setContactOpen] = useState(false);\n\n // Rental application form state\n const [applicantName, setApplicantName] = useState('');\n const [applicantEmail, setApplicantEmail] = useState('');\n const [applicantPhone, setApplicantPhone] = useState('');\n const [monthlyIncome, setMonthlyIncome] = useState('');\n const [moveInDate, setMoveInDate] = useState('');\n\n // Investment-analysis calculator inputs (blank = use a price-derived default)\n const [rentInput, setRentInput] = useState('');\n const [costInput, setCostInput] = useState('');\n const [appreciationInput, setAppreciationInput] = useState('8');\n // BOFF-3928 — stamp duty/registration + financing toggles.\n const [includeStampDuty, setIncludeStampDuty] = useState(true);\n const [stampDutyPctInput, setStampDutyPctInput] = useState('6');\n const [includeFinancing, setIncludeFinancing] = useState(false);\n const [downPaymentPctInput, setDownPaymentPctInput] = useState('20');\n const [loanRateInput, setLoanRateInput] = useState('8.5');\n const [loanTenureInput, setLoanTenureInput] = useState('20');\n\n // Viewing form state\n const [viewingDate, setViewingDate] = useState('');\n const [viewingType, setViewingType] = useState<'in_person' | 'virtual'>('in_person');\n const [attendeeName, setAttendeeName] = useState('');\n const [attendeeEmail, setAttendeeEmail] = useState('');\n const [viewingNotes, setViewingNotes] = useState('');\n\n // Offer form state\n const [offerAmount, setOfferAmount] = useState('');\n const [offerNotes, setOfferNotes] = useState('');\n const [offerExpires, setOfferExpires] = useState('');\n\n // Edit form state (seeded on open; the seed is kept for change detection on\n // the collection fields — amenities/landmarks are only sent when modified so\n // non-catalog or legacy values are never silently dropped).\n const [editForm, setEditForm] = useState<EditFormState>(EMPTY_EDIT_FORM);\n const [editSeed, setEditSeed] = useState<EditFormState>(EMPTY_EDIT_FORM);\n\n if (loading) {\n return (\n <div className=\"space-y-6 p-6\">\n <LoadingSkeleton className=\"h-80\" />\n <LoadingSkeleton variant=\"detail\" />\n </div>\n );\n }\n\n if (!property) {\n return (\n <div className=\"p-6\">\n <EmptyState\n illustration=\"empty-search\"\n icon={<Building className=\"h-12 w-12\" />}\n title=\"Property Not Found\"\n description=\"The property you're looking for doesn't exist or has been removed.\"\n action={\n <button\n onClick={() => navigate('../properties')}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Properties\n </button>\n }\n />\n </div>\n );\n }\n\n const breadcrumbs: BreadcrumbItem[] = [{ label: 'Properties', href: '../' }, { label: property.title }];\n\n const formatPrice = (price: Property['price']) => {\n const amount = formatCurrency(price.amount, price.currency);\n if (price.type === 'rent' && price.period) return `${amount}/${price.period.replace('ly', '')}`;\n return amount;\n };\n\n const nextImage = () => setCurrentImageIndex((prev) => (prev === property.images.length - 1 ? 0 : prev + 1));\n const prevImage = () => setCurrentImageIndex((prev) => (prev === 0 ? property.images.length - 1 : prev - 1));\n\n const handleShare = () => {\n if (navigator.share) {\n navigator.share({ title: property.title, text: property.description, url: window.location.href });\n } else {\n navigator.clipboard.writeText(window.location.href);\n notify.info('Link copied', 'The property link is on your clipboard.');\n }\n };\n\n const toggleShortlist = async () => {\n try {\n if (isShortlisted) {\n await removeShortlist(property.id);\n notify.success('Removed from shortlist');\n } else {\n await saveShortlist(property.id);\n emitResource('housingvista.shortlist.property_added', property.id);\n notify.success('Saved to shortlist');\n }\n } catch (err) {\n notify.error('Could not update shortlist', (err as Error).message);\n }\n };\n\n const handleBookViewing = async (e: FormEvent) => {\n e.preventDefault();\n if (!viewingDate) return;\n try {\n await bookViewing({\n propertyId: property.id,\n scheduledAt: new Date(viewingDate).toISOString(),\n type: viewingType,\n attendeeName: attendeeName.trim() || undefined,\n attendeeEmail: attendeeEmail.trim() || undefined,\n notes: viewingNotes.trim() || undefined,\n });\n emitResource('housingvista.viewing.scheduled', property.id);\n notify.success('Viewing requested', 'The owner will confirm your slot shortly.');\n setViewingOpen(false);\n setViewingDate('');\n setAttendeeName('');\n setAttendeeEmail('');\n setViewingNotes('');\n } catch (err) {\n notify.error('Could not book viewing', (err as Error).message);\n }\n };\n\n const handleSubmitOffer = async (e: FormEvent) => {\n e.preventDefault();\n const amount = Number(offerAmount);\n if (!amount || amount <= 0) {\n notify.warning('Enter a valid offer amount');\n return;\n }\n try {\n await submitOffer({\n propertyId: property.id,\n amount,\n currency: property.price.currency,\n notes: offerNotes.trim() || undefined,\n expiresAt: offerExpires ? new Date(offerExpires).toISOString() : undefined,\n });\n emitResource('housingvista.offer.created', property.id);\n notify.success('Offer submitted', `Your offer of ${formatCurrency(amount, property.price.currency)} was sent.`);\n setOfferOpen(false);\n setOfferAmount('');\n setOfferNotes('');\n setOfferExpires('');\n } catch (err) {\n notify.error('Could not submit offer', (err as Error).message);\n }\n };\n\n const openEdit = () => {\n const coords = property.location.coordinates;\n const seed: EditFormState = {\n title: property.title,\n description: property.description,\n status: property.status,\n type: property.type,\n category: property.category,\n address: property.location.address,\n city: property.location.city,\n state: property.location.state,\n country: property.location.country,\n pincode: property.location.pincode,\n neighborhood: property.location.neighborhood,\n landmarks: property.location.landmarks.join(', '),\n coordinates:\n coords && (coords.latitude !== 0 || coords.longitude !== 0)\n ? { latitude: coords.latitude, longitude: coords.longitude }\n : null,\n bedrooms: fieldText(property.specifications.bedrooms),\n bathrooms: fieldText(property.specifications.bathrooms),\n totalArea: fieldText(property.specifications.totalArea),\n carpetArea: fieldText(property.specifications.carpetArea),\n builtUpArea: fieldText(property.specifications.builtUpArea),\n floors: fieldText(property.specifications.floors),\n totalFloors: fieldText(property.specifications.totalFloors),\n parking: fieldText(property.specifications.parking),\n balconies: fieldText(property.specifications.balconies),\n furnishingStatus: property.specifications.furnishingStatus,\n ageOfProperty: fieldText(property.specifications.ageOfProperty),\n facing: property.specifications.facing ?? '',\n price: fieldText(property.price.amount),\n currency: property.price.currency,\n priceType: property.price.type,\n pricePeriod: property.price.period ?? '',\n negotiable: property.price.negotiable,\n pricePerSqft: fieldText(property.price.pricePerSqft),\n amenities: property.amenities\n .filter((a) => a.available)\n .map((a) => amenityOptions.find((o) => o.label === a.name)?.id ?? '')\n .filter((entry) => entry !== ''),\n extraAmenities: property.amenities.filter((a) => !amenityOptions.some((o) => o.label === a.name)),\n catalogAmenities: property.amenities.filter((a) => amenityOptions.some((o) => o.label === a.name)),\n };\n setEditForm(seed);\n setEditSeed(seed);\n setEditOpen(true);\n };\n\n const updateEditForm = (patch: Partial<EditFormState>) => setEditForm((prev) => ({ ...prev, ...patch }));\n\n // Free-text scalars are sent as trimmed values even when empty so a host can\n // CLEAR a stored value (undefined would be indistinguishable from \"no change\"\n // in the update input); numeric/enum/coordinate fields keep their guards above.\n const clearableText = (value: string): string => value.trim();\n\n const handleEdit = async (e: FormEvent) => {\n e.preventDefault();\n const title = editForm.title.trim();\n const city = editForm.city.trim();\n const state = editForm.state.trim();\n const bedrooms = toNumber(editForm.bedrooms);\n const bathrooms = toNumber(editForm.bathrooms);\n const totalArea = toNumber(editForm.totalArea);\n const price = toNumber(editForm.price);\n if (!title || !city || !state) {\n notify.warning('Title, city and state are required');\n return;\n }\n // Bedrooms/bathrooms stay optional so legacy rows seeded with null can be\n // saved without inventing values; anything provided must be a real number.\n if (editForm.bedrooms.trim() !== '' && (bedrooms == null || bedrooms < 0)) {\n notify.warning('Bedrooms must be zero or greater');\n return;\n }\n if (editForm.bathrooms.trim() !== '' && (bathrooms == null || bathrooms < 0)) {\n notify.warning('Bathrooms must be zero or greater');\n return;\n }\n if (totalArea == null || totalArea < 0) {\n notify.warning('Total area must be zero or greater');\n return;\n }\n if (price == null || price <= 0) {\n notify.warning('Enter a price greater than zero');\n return;\n }\n const landmarksNow = normalizeLandmarks(editForm.landmarks);\n const landmarksChanged = landmarksNow.join('|') !== normalizeLandmarks(editSeed.landmarks).join('|');\n const amenitiesChanged = [...editForm.amenities].sort().join('|') !== [...editSeed.amenities].sort().join('|');\n const input: UpdatePropertyInput = {\n title,\n description: clearableText(editForm.description),\n status: editForm.status,\n type: editForm.type,\n category: editForm.category,\n address: clearableText(editForm.address),\n city,\n state,\n country: clearableText(editForm.country),\n pincode: clearableText(editForm.pincode),\n neighborhood: clearableText(editForm.neighborhood),\n coordinates: editForm.coordinates ?? undefined,\n bedrooms: bedrooms ?? undefined,\n bathrooms: bathrooms ?? undefined,\n totalArea,\n carpetArea: optionalNumber(editForm.carpetArea),\n builtUpArea: optionalNumber(editForm.builtUpArea),\n floors: optionalNumber(editForm.floors),\n totalFloors: optionalNumber(editForm.totalFloors),\n parking: optionalNumber(editForm.parking),\n balconies: optionalNumber(editForm.balconies),\n furnishingStatus: editForm.furnishingStatus,\n ageOfProperty: optionalNumber(editForm.ageOfProperty),\n facing: editForm.facing || undefined,\n price,\n currency: editForm.currency || undefined,\n priceType: editForm.priceType || undefined,\n // '' = the explicit \"— (one-time)\" choice: send null to CLEAR a stored\n // period (undefined would be indistinguishable from \"not provided\").\n pricePeriod: editForm.pricePeriod === '' ? null : editForm.pricePeriod,\n negotiable: editForm.negotiable,\n pricePerSqft: optionalNumber(editForm.pricePerSqft),\n };\n if (landmarksChanged) input.landmarks = landmarksNow;\n if (amenitiesChanged) {\n // Rebuild the collection keyed by name: non-catalog records are preserved\n // verbatim; catalog-matched records keep their stored category (a chip\n // switched on marks availability, never rewrites metadata); disabled\n // records the user did not enable stay as-is; previously-available chips\n // switched off are removed; brand-new chips are appended as general.\n const selectedLabels = new Set(\n editForm.amenities.map((id) => amenityOptions.find((a) => a.id === id)?.label ?? id)\n );\n const byName = new Map<string, { name: string; category: string; available: boolean }>();\n for (const record of editForm.extraAmenities) {\n byName.set(record.name, { name: record.name, category: record.category, available: record.available });\n }\n for (const record of editForm.catalogAmenities) {\n if (selectedLabels.has(record.name)) {\n byName.set(record.name, { name: record.name, category: record.category, available: true });\n } else if (!record.available) {\n byName.set(record.name, { name: record.name, category: record.category, available: record.available });\n }\n }\n for (const label of selectedLabels) {\n if (!byName.has(label)) {\n byName.set(label, { name: label, category: 'general', available: true });\n }\n }\n input.amenities = [...byName.values()];\n }\n try {\n await updateProperty(property.id, input);\n emitResource('housingvista.property.updated', property.id);\n notify.success('Property updated');\n setEditOpen(false);\n } catch (err) {\n notify.error('Could not update property', (err as Error).message);\n }\n };\n\n const handleDelete = async () => {\n try {\n await deleteProperty(property.id);\n emitResource('housingvista.property.deleted', property.id);\n notify.success('Property deleted');\n navigate('../properties');\n } catch (err) {\n notify.error('Could not delete property', (err as Error).message);\n }\n };\n\n // First available rental unit for this property (needed to submit an application).\n // The whole row — not just the id — backs the \"Rental summary\" panel in the\n // apply dialog: rent, deposit, unit number, occupancy status and lease dates\n // all ship in `GetRentalUnits` already.\n const rentalUnit = rentalUnits[0];\n const rentalUnitId = rentalUnit?.id;\n\n const handleSubmitRental = async (e: FormEvent) => {\n e.preventDefault();\n if (!rentalUnitId) {\n notify.warning('No rental unit is available for this property yet');\n return;\n }\n if (!applicantName.trim() || !applicantEmail.trim()) {\n notify.warning('Enter your name and email to apply');\n return;\n }\n try {\n await submitRentalApplication({\n rentalUnitId,\n applicantName: applicantName.trim(),\n applicantEmail: applicantEmail.trim(),\n applicantPhone: applicantPhone.trim() || undefined,\n monthlyIncome: monthlyIncome ? Number(monthlyIncome) : undefined,\n moveInDate: moveInDate ? new Date(moveInDate).toISOString() : undefined,\n });\n notify.success('Application submitted', 'The owner will review your rental application shortly.');\n setRentalOpen(false);\n setApplicantName('');\n setApplicantEmail('');\n setApplicantPhone('');\n setMonthlyIncome('');\n setMoveInDate('');\n } catch (err) {\n notify.error('Could not submit application', (err as Error).message);\n }\n };\n\n const handleTrackInvestment = async () => {\n try {\n await createInvestment({\n propertyId: property.id,\n title: `${property.title} — investment`,\n status: 'active',\n investmentType: 'full_ownership',\n riskLevel: 'medium',\n totalValue: property.price.amount,\n startDate: new Date().toISOString(),\n });\n notify.success('Tracking investment', `${property.title} was added to your portfolio.`);\n } catch (err) {\n notify.error('Could not track investment', (err as Error).message);\n }\n };\n\n /** RERA review workflow (BOFF-4132) — approve/reject the pending status. */\n const handleReraReview = async (nextStatus: 'verified' | 'rejected') => {\n try {\n await updatePropertyReraStatus(property.id, nextStatus);\n notify.success(\n nextStatus === 'verified' ? 'RERA registration verified' : 'RERA registration rejected',\n property.title\n );\n } catch (err) {\n notify.error('Could not update RERA status', (err as Error).message);\n }\n };\n\n // Investment analysis — modelled client-side from the listing price + user inputs.\n const price = property.price.amount;\n const monthlyRent = Number(rentInput) || Math.round(price * 0.005); // ~0.5%/mo default\n const monthlyHoldingCosts = Number(costInput) || Math.round(price * 0.0015); // ~0.15%/mo default\n const grossAnnualRent = monthlyRent * 12;\n const grossYield = price > 0 ? (grossAnnualRent / price) * 100 : 0;\n const annualHoldingCosts = monthlyHoldingCosts * 12;\n const netAnnualIncome = grossAnnualRent - annualHoldingCosts;\n const netYield = price > 0 ? (netAnnualIncome / price) * 100 : 0;\n // 5-year projected value growth at a user-adjustable appreciation rate + the\n // cumulative net rental income earned over the same window (total return).\n const appreciationRate = Math.max(0, Number(appreciationInput) || 0) / 100;\n const projection = Array.from({ length: 6 }, (_, year) => ({\n label: year === 0 ? 'Now' : `Yr ${year}`,\n value: Math.round(price * Math.pow(1 + appreciationRate, year)),\n }));\n const projectedValue5yr = projection[projection.length - 1].value;\n const totalReturn5yr = projectedValue5yr - price + netAnnualIncome * 5;\n const projectedRoi = price > 0 ? (totalReturn5yr / price) * 100 : 0;\n\n // Stamp duty / registration (BOFF-3928) — a one-time acquisition cost on\n // top of the listing price, toggled and rate-adjustable since it varies by\n // Indian state (roughly 5-8% combined in most states).\n const stampDutyPct = Math.max(0, Number(stampDutyPctInput) || 0);\n const stampDutyCost = includeStampDuty ? price * (stampDutyPct / 100) : 0;\n\n // Financing (BOFF-3928) — standard amortizing-loan EMI on the financed\n // portion; cash-on-cash return uses the actual cash outlaid (down payment\n // + stamp duty) rather than the full price when financing is on.\n const downPaymentPct = Math.min(100, Math.max(0, Number(downPaymentPctInput) || 0));\n const loanAnnualRate = Math.max(0, Number(loanRateInput) || 0) / 100;\n const loanTenureYears = Math.max(1, Number(loanTenureInput) || 1);\n const downPayment = includeFinancing ? price * (downPaymentPct / 100) : price;\n const loanAmount = includeFinancing ? price - downPayment : 0;\n const monthlyRatePct = loanAnnualRate / 12;\n const loanMonths = loanTenureYears * 12;\n const monthlyEmi =\n includeFinancing && loanAmount > 0\n ? monthlyRatePct > 0\n ? (loanAmount * monthlyRatePct * Math.pow(1 + monthlyRatePct, loanMonths)) /\n (Math.pow(1 + monthlyRatePct, loanMonths) - 1)\n : loanAmount / loanMonths\n : 0;\n const annualDebtService = monthlyEmi * 12;\n const netCashOutlay = downPayment + stampDutyCost;\n const cashFlowAfterDebtService = netAnnualIncome - annualDebtService;\n const cashOnCashReturn = netCashOutlay > 0 ? (cashFlowAfterDebtService / netCashOutlay) * 100 : 0;\n\n const handleDownloadInvestmentReport = () => {\n const lines = [\n `Investment Analysis Report — ${property.title}`,\n `Generated: ${new Date().toISOString().slice(0, 10)}`,\n '',\n `Listing price,${price}`,\n `Expected monthly rent,${monthlyRent}`,\n `Monthly holding costs,${monthlyHoldingCosts}`,\n `Gross rental yield,${grossYield.toFixed(2)}%`,\n `Net rental yield,${netYield.toFixed(2)}%`,\n `Appreciation rate (input),${(appreciationRate * 100).toFixed(2)}%`,\n `Projected value (5yr),${projectedValue5yr}`,\n `Projected ROI (5yr, unleveraged),${projectedRoi.toFixed(2)}%`,\n '',\n `Stamp duty & registration included,${includeStampDuty ? 'Yes' : 'No'}`,\n `Stamp duty rate,${stampDutyPct}%`,\n `Stamp duty & registration cost,${stampDutyCost.toFixed(0)}`,\n '',\n `Financing included,${includeFinancing ? 'Yes' : 'No'}`,\n ...(includeFinancing\n ? [\n `Down payment (${downPaymentPct}%),${downPayment.toFixed(0)}`,\n `Loan amount,${loanAmount.toFixed(0)}`,\n `Loan rate,${(loanAnnualRate * 100).toFixed(2)}%`,\n `Loan tenure (years),${loanTenureYears}`,\n `Monthly EMI,${monthlyEmi.toFixed(0)}`,\n `Annual debt service,${annualDebtService.toFixed(0)}`,\n ]\n : []),\n `Net cash outlay,${netCashOutlay.toFixed(0)}`,\n `Cash-on-cash return,${cashOnCashReturn.toFixed(2)}%`,\n '',\n 'This is not financial advice. Consult a licensed financial advisor before investing.',\n ];\n const blob = new Blob([lines.join('\\n')], { type: 'text/csv;charset=utf-8;' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = `${property.id}-investment-analysis.csv`;\n link.click();\n URL.revokeObjectURL(url);\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <Breadcrumbs items={breadcrumbs} />\n\n {/* Header */}\n <div className=\"flex flex-wrap items-center gap-3\">\n <button\n onClick={() => navigate('../properties')}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-1.5 text-sm text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n Back\n </button>\n <StatusBadge\n label={property.status.replace('_', ' ')}\n variant={statusVariantMap[property.status] ?? 'default'}\n dot\n />\n {property.verificationStatus === 'verified' && <StatusBadge label=\"Verified\" variant=\"success\" dot />}\n {property.price.negotiable && <StatusBadge label=\"Negotiable\" variant=\"info\" />}\n <div className=\"ml-auto flex items-center gap-2\">\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={openEdit}>\n <Pencil className=\"mr-1.5 h-4 w-4\" />\n Edit\n </Button>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => setDeleteOpen(true)}>\n <Trash2 className=\"mr-1.5 h-4 w-4\" />\n Delete\n </Button>\n </div>\n </div>\n\n <PagePurpose className=\"max-w-3xl\">\n Everything you need to evaluate this property in one place — photos, specifications, amenities, and location.\n Use it to shortlist the property, schedule a viewing, or make an offer.\n </PagePurpose>\n\n <NextSteps\n storageKey=\"housingvista-property-detail\"\n steps={[\n {\n id: 'schedule',\n label: 'Schedule a viewing',\n description: 'Book a time to see the property in person or virtually.',\n onClick: () => setViewingOpen(true),\n },\n {\n id: 'offer',\n label: 'Make an offer',\n description: 'Submit a price and let the owner respond.',\n onClick: () => {\n setOfferExpires(defaultOfferExpiry());\n setOfferOpen(true);\n },\n },\n {\n id: 'location',\n label: 'Explore the location',\n description: 'See the neighborhood, nearby landmarks, and map.',\n onClick: () => setActiveTab('location'),\n },\n ]}\n />\n\n {/* Image Gallery */}\n <div className=\"space-y-3\">\n <div className=\"relative overflow-hidden rounded-xl border border-border-subtle bg-bg-sunken\">\n {property.images.length > 0 ? (\n <img\n src={property.images[currentImageIndex]?.url}\n alt={property.images[currentImageIndex]?.title ?? property.title}\n className=\"h-80 w-full object-cover sm:h-[26rem]\"\n />\n ) : (\n <div className=\"flex h-80 w-full flex-col items-center justify-center gap-3 bg-gradient-to-br from-[var(--color-action-primary-bg)]/12 via-bg-sunken to-[var(--color-accent-blue)]/12 text-text-secondary/70 sm:h-[26rem]\">\n <Building className=\"h-12 w-12\" />\n <span className=\"text-sm font-medium tracking-wide\">No photos yet</span>\n </div>\n )}\n\n {property.images.length > 1 && (\n <>\n <button\n onClick={prevImage}\n aria-label=\"Previous photo\"\n className=\"absolute left-4 top-1/2 -translate-y-1/2 rounded-full bg-bg-overlay/70 p-2 text-text-inverse transition-colors hover:bg-bg-overlay\"\n >\n <ChevronLeft className=\"h-5 w-5\" />\n </button>\n <button\n onClick={nextImage}\n aria-label=\"Next photo\"\n className=\"absolute right-4 top-1/2 -translate-y-1/2 rounded-full bg-bg-overlay/70 p-2 text-text-inverse transition-colors hover:bg-bg-overlay\"\n >\n <ChevronRight className=\"h-5 w-5\" />\n </button>\n </>\n )}\n\n {/* Verified badge overlay */}\n {property.verificationStatus === 'verified' && (\n <div className=\"absolute left-4 top-4 inline-flex items-center gap-1.5 rounded-full bg-status-success-bg-subtle px-3 py-1 text-xs font-semibold text-status-success-text shadow-elevation-1 backdrop-blur-sm\">\n <BadgeCheck className=\"h-4 w-4\" />\n Verified listing\n </div>\n )}\n\n <div className=\"absolute right-4 top-4 flex gap-2\">\n <button\n onClick={toggleShortlist}\n disabled={savingShortlist || removingShortlist}\n aria-label={isShortlisted ? 'Remove from shortlist' : 'Save to shortlist'}\n className=\"rounded-full bg-bg-surface/85 p-2 shadow-elevation-1 backdrop-blur-sm transition-colors hover:bg-bg-surface disabled:opacity-60\"\n >\n <Heart\n className={cn(\n 'h-5 w-5',\n isShortlisted ? 'fill-status-error-text text-status-error-text' : 'text-text-secondary'\n )}\n />\n </button>\n <button\n onClick={handleShare}\n aria-label=\"Share this listing\"\n className=\"rounded-full bg-bg-surface/85 p-2 shadow-elevation-1 backdrop-blur-sm transition-colors hover:bg-bg-surface\"\n >\n <Share2 className=\"h-5 w-5 text-text-secondary\" />\n </button>\n </div>\n\n {property.images.length > 0 && (\n <div className=\"absolute bottom-4 right-4\">\n <span className=\"rounded-md bg-bg-overlay/70 px-2 py-1 text-xs font-medium text-text-inverse\">\n {currentImageIndex + 1} / {property.images.length}\n </span>\n </div>\n )}\n </div>\n\n {/* Thumbnail strip */}\n {property.images.length > 1 && (\n <div className=\"flex gap-3 overflow-x-auto pb-1\">\n {property.images.map((img, index) => (\n <button\n key={img.id}\n onClick={() => setCurrentImageIndex(index)}\n aria-label={`View photo ${index + 1}`}\n aria-current={index === currentImageIndex}\n className={cn(\n 'h-16 w-24 shrink-0 overflow-hidden rounded-lg border-2 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]',\n index === currentImageIndex\n ? 'border-action-primary-border'\n : 'border-transparent opacity-70 hover:opacity-100'\n )}\n >\n <img src={img.url} alt={img.title ?? `Photo ${index + 1}`} className=\"h-full w-full object-cover\" />\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Main Content Grid */}\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Left: Main content */}\n <div className=\"space-y-6 lg:col-span-2\">\n <EmphasisPanel>\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold text-text-primary\">{property.title}</h1>\n <div className=\"mt-2 flex items-center text-text-secondary\">\n <MapPin className=\"mr-1.5 h-4 w-4 shrink-0\" />\n <span className=\"text-sm\">\n {[property.location.address, property.location.neighborhood, property.location.city]\n .filter(Boolean)\n .join(', ')}\n </span>\n </div>\n </div>\n <div className=\"text-right\">\n <div className=\"text-2xl font-bold text-text-primary\">{formatPrice(property.price)}</div>\n {property.price.pricePerSqft && (\n <div className=\"text-sm text-text-secondary\">{formatCurrency(property.price.pricePerSqft)}/sqft</div>\n )}\n </div>\n </div>\n\n {/* Key Specs — spec cards */}\n <div className=\"mt-6 grid grid-cols-2 gap-3 border-t border-border-subtle pt-6 sm:grid-cols-4\">\n {[\n property.specifications.bedrooms != null && {\n icon: Bed,\n value: String(property.specifications.bedrooms),\n label: property.specifications.bedrooms === 1 ? 'Bedroom' : 'Bedrooms',\n },\n property.specifications.bathrooms != null && {\n icon: Bath,\n value: String(property.specifications.bathrooms),\n label: property.specifications.bathrooms === 1 ? 'Bathroom' : 'Bathrooms',\n },\n {\n icon: Square,\n value: formatNumber(property.specifications.totalArea),\n label: 'sq ft',\n },\n property.specifications.parking != null && property.specifications.parking > 0\n ? {\n icon: Car,\n value: String(property.specifications.parking),\n label: 'Parking',\n }\n : property.specifications.facing\n ? { icon: Compass, value: property.specifications.facing, label: 'Facing' }\n : false,\n ]\n .filter((spec): spec is { icon: LucideIcon; value: string; label: string } => Boolean(spec))\n .map((spec) => {\n const Icon = spec.icon;\n return (\n <div\n key={spec.label}\n className=\"flex flex-col items-center gap-1 rounded-lg border border-border-subtle bg-bg-sunken/40 p-3 text-center\"\n >\n <Icon className=\"h-5 w-5 text-text-secondary\" />\n <span className=\"text-base font-semibold text-text-primary\">{spec.value}</span>\n <span className=\"text-xs text-text-secondary\">{spec.label}</span>\n </div>\n );\n })}\n </div>\n\n {property.description && (\n <div className=\"mt-6 border-t border-border-subtle pt-6\">\n <h3 className=\"mb-3 text-base font-semibold text-text-primary\">Description</h3>\n <p className=\"text-sm leading-relaxed text-text-secondary\">{property.description}</p>\n </div>\n )}\n </EmphasisPanel>\n\n {/* Tabbed Content */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface\">\n <div className=\"border-b border-border-subtle\">\n <nav className=\"flex space-x-6 overflow-x-auto px-6\">\n {tabs.map((tab) => (\n <button\n key={tab.id}\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n 'whitespace-nowrap border-b-2 py-3 text-sm font-medium transition-colors',\n activeTab === tab.id\n ? 'border-action-primary-border text-text-primary'\n : 'border-transparent text-text-secondary hover:text-text-primary'\n )}\n >\n {tab.label}\n </button>\n ))}\n </nav>\n </div>\n\n <div className=\"p-6\">\n {activeTab === 'details' && (\n <div className=\"grid grid-cols-1 gap-6 sm:grid-cols-2\">\n <div>\n <h4 className=\"mb-3 text-sm font-semibold text-text-primary\">Property Information</h4>\n <dl className=\"space-y-2 text-sm\">\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Property Type</dt>\n <dd className=\"font-medium capitalize text-text-primary\">{property.type}</dd>\n </div>\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Category</dt>\n <dd className=\"font-medium capitalize text-text-primary\">{property.category}</dd>\n </div>\n {property.specifications.ageOfProperty != null && (\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Age of Property</dt>\n <dd className=\"font-medium text-text-primary\">\n {property.specifications.ageOfProperty} years\n </dd>\n </div>\n )}\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Furnishing</dt>\n <dd className=\"font-medium capitalize text-text-primary\">\n {property.specifications.furnishingStatus?.replace('_', ' ')}\n </dd>\n </div>\n {property.specifications.facing && (\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Facing</dt>\n <dd className=\"font-medium text-text-primary\">{property.specifications.facing}</dd>\n </div>\n )}\n {property.specifications.floors != null && (\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Floor</dt>\n <dd className=\"font-medium text-text-primary\">\n {property.specifications.floors} of {property.specifications.totalFloors}\n </dd>\n </div>\n )}\n </dl>\n </div>\n <div>\n <h4 className=\"mb-3 text-sm font-semibold text-text-primary\">Area Details</h4>\n <dl className=\"space-y-2 text-sm\">\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Total Area</dt>\n <dd className=\"font-medium text-text-primary\">\n {formatNumber(property.specifications.totalArea)} sqft\n </dd>\n </div>\n {property.specifications.carpetArea && (\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Carpet Area</dt>\n <dd className=\"font-medium text-text-primary\">\n {formatNumber(property.specifications.carpetArea)} sqft\n </dd>\n </div>\n )}\n {property.specifications.builtUpArea && (\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Built-up Area</dt>\n <dd className=\"font-medium text-text-primary\">\n {formatNumber(property.specifications.builtUpArea)} sqft\n </dd>\n </div>\n )}\n {property.price.pricePerSqft && (\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Price per sqft</dt>\n <dd className=\"font-medium text-text-primary\">\n {formatCurrency(property.price.pricePerSqft)}\n </dd>\n </div>\n )}\n </dl>\n </div>\n </div>\n )}\n\n {activeTab === 'amenities' && (\n <div>\n {property.amenities.length > 0 ? (\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-4\">\n {property.amenities.map((amenity) => {\n const Icon = amenityIcon(amenity.name);\n return (\n <div\n key={amenity.id}\n className=\"flex flex-col items-center gap-2 rounded-lg border border-border-subtle bg-bg-sunken/40 p-4 text-center\"\n >\n <span className=\"flex h-10 w-10 items-center justify-center rounded-full bg-status-success-bg-subtle text-status-success-text\">\n <Icon className=\"h-5 w-5\" />\n </span>\n <span className=\"text-sm font-medium text-text-primary\">{amenity.name}</span>\n </div>\n );\n })}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-generic\"\n title=\"No amenities listed\"\n description=\"This property has no amenities recorded yet.\"\n className=\"border-0 bg-transparent p-6\"\n />\n )}\n </div>\n )}\n\n {activeTab === 'location' && (\n <div className=\"space-y-4\">\n {/* Map card — styled placeholder pinned to the listing's locale */}\n <div className=\"relative h-56 overflow-hidden rounded-xl border border-border-subtle bg-bg-sunken\">\n <div\n className=\"absolute inset-0 opacity-60\"\n style={{\n backgroundImage:\n 'linear-gradient(var(--color-border-seam, rgba(120,120,120,.18)) 1px, transparent 1px), linear-gradient(90deg, var(--color-border-seam, rgba(120,120,120,.18)) 1px, transparent 1px)',\n backgroundSize: '32px 32px',\n }}\n />\n <div className=\"absolute left-1/2 top-1/2 flex -translate-x-1/2 -translate-y-1/2 flex-col items-center gap-1 text-center\">\n <span className=\"flex h-11 w-11 items-center justify-center rounded-full bg-action-primary-bg text-action-primary-text shadow-pop\">\n <MapPin className=\"h-5 w-5\" />\n </span>\n <span className=\"mt-1 rounded-md bg-bg-surface/90 px-2 py-0.5 text-sm font-semibold text-text-primary shadow-elevation-1 backdrop-blur-sm\">\n {property.location.neighborhood || property.location.city}\n </span>\n <span className=\"text-xs text-text-secondary\">\n {[property.location.city, property.location.state].filter(Boolean).join(', ')}\n </span>\n </div>\n {property.location.coordinates?.latitude != null &&\n property.location.coordinates?.longitude != null && (\n <a\n href={`https://www.google.com/maps/search/?api=1&query=${property.location.coordinates.latitude},${property.location.coordinates.longitude}`}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"absolute bottom-3 right-3 inline-flex items-center gap-1.5 rounded-md bg-bg-surface/90 px-2.5 py-1.5 text-xs font-medium text-text-primary shadow-elevation-1 backdrop-blur-sm transition-colors hover:bg-bg-surface\"\n >\n <Navigation className=\"h-3.5 w-3.5\" />\n Open in Maps\n </a>\n )}\n </div>\n {property.location.address && (\n <div>\n <div className=\"mb-1 text-xs text-text-secondary\">Full Address</div>\n <div className=\"text-sm font-medium text-text-primary\">{property.location.address}</div>\n </div>\n )}\n <div className=\"grid grid-cols-1 gap-4 text-sm sm:grid-cols-3\">\n <div>\n <div className=\"mb-1 text-xs text-text-secondary\">Neighborhood</div>\n <div className=\"font-medium text-text-primary\">{property.location.neighborhood || '—'}</div>\n </div>\n <div>\n <div className=\"mb-1 text-xs text-text-secondary\">City, State</div>\n <div className=\"font-medium text-text-primary\">\n {property.location.city}, {property.location.state}\n </div>\n </div>\n <div>\n <div className=\"mb-1 text-xs text-text-secondary\">PIN / ZIP</div>\n <div className=\"font-medium text-text-primary\">{property.location.pincode || '—'}</div>\n </div>\n </div>\n\n {property.location.landmarks.length > 0 && (\n <div className=\"border-t border-border-subtle pt-4\">\n <h4 className=\"mb-2 text-xs font-medium text-text-secondary\">Nearby Landmarks</h4>\n <div className=\"flex flex-wrap gap-2\">\n {property.location.landmarks.map((landmark) => (\n <span\n key={landmark}\n className=\"rounded-full bg-bg-sunken px-3 py-1 text-xs text-text-primary\"\n >\n {landmark}\n </span>\n ))}\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* Right Sidebar */}\n <div className=\"space-y-6\">\n {/* Price + Actions — lead panel (mirrors the listing hero) */}\n <div\n id=\"property-actions\"\n className=\"scroll-mt-6 rounded-lg border border-border-subtle bg-bg-surface p-5 shadow-elevation-1 lg:sticky lg:top-6\"\n >\n <div className=\"flex flex-wrap items-baseline gap-x-2 gap-y-1\">\n <span className=\"text-3xl font-bold text-text-primary\">{formatPrice(property.price)}</span>\n {property.price.negotiable && <span className=\"text-sm text-text-secondary\">· Negotiable</span>}\n </div>\n {property.price.pricePerSqft && (\n <p className=\"mt-1 text-sm text-text-secondary\">\n {formatCurrency(property.price.pricePerSqft, property.price.currency)}/sqft\n </p>\n )}\n\n <div className=\"mt-4 space-y-2\">\n <Button\n type=\"button\"\n className=\"w-full justify-center\"\n onClick={() => {\n setOfferExpires(defaultOfferExpiry());\n setOfferOpen(true);\n }}\n >\n <DollarSign className=\"mr-2 h-4 w-4\" />\n Make Offer\n </Button>\n {property.status === 'for_rent' && (\n <>\n <Button\n type=\"button\"\n className=\"w-full justify-center\"\n onClick={() => setRentalOpen(true)}\n disabled={!rentalUnitId}\n >\n <KeyRound className=\"mr-2 h-4 w-4\" />\n Apply to Rent\n </Button>\n {!rentalUnitId && (\n <p className=\"px-1 text-xs text-text-secondary\">\n No rental unit is listed for this property yet — applications open once a unit is added.\n </p>\n )}\n </>\n )}\n <div className=\"grid grid-cols-2 gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"w-full justify-center\"\n onClick={() => setViewingOpen(true)}\n >\n <Calendar className=\"mr-2 h-4 w-4\" />\n Viewing\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"w-full justify-center\"\n onClick={() => setContactOpen(true)}\n >\n <MessageSquare className=\"mr-2 h-4 w-4\" />\n Contact\n </Button>\n </div>\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"w-full justify-center\"\n onClick={toggleShortlist}\n disabled={savingShortlist || removingShortlist}\n >\n <Heart\n className={cn('mr-2 h-4 w-4', isShortlisted && 'fill-status-error-text text-status-error-text')}\n />\n {isShortlisted ? 'Saved to Shortlist' : 'Save to Shortlist'}\n </Button>\n </div>\n\n {property.verificationStatus === 'verified' && (\n <div className=\"mt-4 flex items-center gap-2 border-t border-border-subtle pt-4 text-sm font-medium text-status-success-text\">\n <BadgeCheck className=\"h-4 w-4\" />\n Verified listing\n </div>\n )}\n </div>\n\n {/* Investment analysis — modelled client-side from the listing price */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-5\">\n <div className=\"mb-4 flex items-center gap-2\">\n <Calculator className=\"h-5 w-5 text-text-secondary\" />\n <h3 className=\"text-base font-semibold text-text-primary\">Investment Analysis</h3>\n </div>\n\n {/* Deal parameters */}\n <div className=\"space-y-3\">\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n Expected monthly rent ({property.price.currency})\n </label>\n <input\n type=\"number\"\n min={0}\n value={rentInput}\n onChange={(e) => setRentInput(e.target.value)}\n placeholder={String(monthlyRent)}\n className={inputClass}\n />\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n Monthly costs ({property.price.currency})\n </label>\n <input\n type=\"number\"\n min={0}\n value={costInput}\n onChange={(e) => setCostInput(e.target.value)}\n placeholder={String(monthlyHoldingCosts)}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">Appreciation (%/yr)</label>\n <input\n type=\"number\"\n min={0}\n step={0.5}\n value={appreciationInput}\n onChange={(e) => setAppreciationInput(e.target.value)}\n className={inputClass}\n />\n </div>\n </div>\n <p className=\"text-[11px] text-text-secondary\">\n Costs cover maintenance, tax, insurance, and management.\n </p>\n </div>\n\n {/* Stamp duty / registration + financing toggles (BOFF-3928) */}\n <div className=\"mt-4 space-y-3 border-t border-border-subtle pt-4\">\n <div className=\"flex items-center justify-between gap-3\">\n <label className=\"flex items-center gap-2 text-xs font-medium text-text-secondary\">\n <input\n type=\"checkbox\"\n checked={includeStampDuty}\n onChange={(e) => setIncludeStampDuty(e.target.checked)}\n className=\"h-3.5 w-3.5 rounded border-border-subtle\"\n />\n Include stamp duty & registration\n </label>\n {includeStampDuty && (\n <input\n type=\"number\"\n min={0}\n step={0.5}\n value={stampDutyPctInput}\n onChange={(e) => setStampDutyPctInput(e.target.value)}\n aria-label=\"Stamp duty rate percent\"\n className=\"h-7 w-16 rounded-md border border-border-subtle bg-bg-surface px-2 text-right text-xs text-text-primary\"\n />\n )}\n </div>\n <div className=\"flex items-center justify-between gap-3\">\n <label className=\"flex items-center gap-2 text-xs font-medium text-text-secondary\">\n <input\n type=\"checkbox\"\n checked={includeFinancing}\n onChange={(e) => setIncludeFinancing(e.target.checked)}\n className=\"h-3.5 w-3.5 rounded border-border-subtle\"\n />\n Include financing (loan)\n </label>\n </div>\n {includeFinancing && (\n <div className=\"grid grid-cols-3 gap-2\">\n <div>\n <label className=\"mb-1 block text-[10px] text-text-secondary\">Down payment %</label>\n <input\n type=\"number\"\n min={0}\n max={100}\n value={downPaymentPctInput}\n onChange={(e) => setDownPaymentPctInput(e.target.value)}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1 block text-[10px] text-text-secondary\">Loan rate %</label>\n <input\n type=\"number\"\n min={0}\n step={0.1}\n value={loanRateInput}\n onChange={(e) => setLoanRateInput(e.target.value)}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1 block text-[10px] text-text-secondary\">Tenure (yrs)</label>\n <input\n type=\"number\"\n min={1}\n value={loanTenureInput}\n onChange={(e) => setLoanTenureInput(e.target.value)}\n className={inputClass}\n />\n </div>\n </div>\n )}\n {(includeStampDuty || includeFinancing) && (\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-[11px] text-text-secondary\">\n {includeStampDuty && (\n <span>\n Stamp duty:{' '}\n <span className=\"font-semibold text-text-primary\">\n {formatCompactCurrency(stampDutyCost, property.price.currency)}\n </span>\n </span>\n )}\n {includeFinancing && (\n <span>\n Monthly EMI:{' '}\n <span className=\"font-semibold text-text-primary\">\n {formatCompactCurrency(monthlyEmi, property.price.currency)}\n </span>\n </span>\n )}\n <span>\n Net cash outlay:{' '}\n <span className=\"font-semibold text-text-primary\">\n {formatCompactCurrency(netCashOutlay, property.price.currency)}\n </span>\n </span>\n </div>\n )}\n </div>\n\n {/* Financial projections — yield tiles */}\n <div className=\"mt-4 grid grid-cols-3 gap-2 border-t border-border-subtle pt-4\">\n <div className=\"rounded-lg border border-status-success-border bg-status-success-bg-subtle p-2.5 text-center\">\n <div className=\"text-[11px] font-medium text-status-success-text\">Gross Yield</div>\n <div className=\"mt-0.5 text-lg font-bold text-status-success-text\">{grossYield.toFixed(1)}%</div>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-sunken/40 p-2.5 text-center\">\n <div className=\"text-[11px] font-medium text-text-secondary\">Net Yield</div>\n <div className=\"mt-0.5 text-lg font-bold text-text-primary\">{netYield.toFixed(1)}%</div>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-sunken/40 p-2.5 text-center\">\n <div className=\"text-[11px] font-medium text-text-secondary\">\n {includeFinancing ? 'Cash-on-Cash' : '5-yr ROI'}\n </div>\n <div className=\"mt-0.5 text-lg font-bold text-text-primary\">\n {includeFinancing ? cashOnCashReturn.toFixed(1) : projectedRoi.toFixed(0)}%\n </div>\n </div>\n </div>\n\n {/* Projected value growth */}\n <div className=\"mt-4\">\n <div className=\"mb-1 flex items-center justify-between\">\n <span className=\"text-xs font-medium text-text-secondary\">Projected Value Growth</span>\n <span className=\"text-xs font-semibold text-text-primary\">\n {formatCompactCurrency(projectedValue5yr, property.price.currency)}\n </span>\n </div>\n <div className=\"h-32\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={projection} margin={{ top: 4, right: 4, bottom: 0, left: 0 }}>\n <defs>\n <linearGradient id=\"hvValueGrad\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"5%\" stopColor=\"var(--color-chart-2)\" stopOpacity={0.35} />\n <stop offset=\"95%\" stopColor=\"var(--color-chart-2)\" stopOpacity={0} />\n </linearGradient>\n </defs>\n <XAxis dataKey=\"label\" tick={{ fontSize: 10 }} axisLine={false} tickLine={false} />\n <YAxis hide domain={['dataMin', 'dataMax']} />\n <Tooltip\n formatter={(value: number) => [formatCompactCurrency(value, property.price.currency), 'Value']}\n labelClassName=\"text-text-primary\"\n />\n <Area\n type=\"monotone\"\n dataKey=\"value\"\n stroke=\"var(--color-chart-2)\"\n fill=\"url(#hvValueGrad)\"\n strokeWidth={2}\n />\n </AreaChart>\n </ResponsiveContainer>\n </div>\n <p className=\"mt-1 text-[11px] text-text-secondary\">\n Projection based on your inputs and market appreciation. Consult a financial advisor before investing.\n </p>\n </div>\n\n <div className=\"mt-4 flex gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"flex-1 justify-center\"\n onClick={handleTrackInvestment}\n disabled={creatingInvestment}\n >\n <TrendingUp className=\"mr-2 h-4 w-4\" />\n {creatingInvestment ? 'Adding…' : 'Track as Investment'}\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"justify-center\"\n onClick={handleDownloadInvestmentReport}\n aria-label=\"Download investment analysis report\"\n >\n <Download className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n\n {/* Property Stats (real, derived) */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-5\">\n <h3 className=\"mb-4 text-base font-semibold text-text-primary\">At a Glance</h3>\n <div className=\"space-y-3 text-sm\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-text-secondary\">Status</span>\n <StatusBadge\n label={property.status.replace('_', ' ')}\n variant={statusVariantMap[property.status] ?? 'default'}\n />\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-text-secondary\">Verification</span>\n <span className=\"font-medium capitalize text-text-primary\">{property.verificationStatus}</span>\n </div>\n {property.reraVerificationStatus !== 'not_applicable' && (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-text-secondary\">RERA status</span>\n <span className=\"flex items-center gap-1.5 font-medium capitalize text-text-primary\">\n {property.reraVerificationStatus === 'verified' && (\n <BadgeCheck className=\"h-4 w-4 text-status-success-text\" />\n )}\n {property.reraVerificationStatus.replace('_', ' ')}\n </span>\n </div>\n )}\n {property.reraRegistrationNo && (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-text-secondary\">RERA reg. no.</span>\n <span className=\"font-medium text-text-primary\">{property.reraRegistrationNo}</span>\n </div>\n )}\n <div className=\"flex items-center justify-between\">\n <span className=\"text-text-secondary\">Listed</span>\n <span className=\"font-medium text-text-primary\">{formatDate(String(property.createdAt))}</span>\n </div>\n </div>\n {property.reraVerificationStatus === 'pending' && (\n <div className=\"mt-4 flex gap-2 border-t border-border-subtle pt-4\">\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"flex-1 justify-center\"\n disabled={reviewingRera}\n onClick={() => handleReraReview('verified')}\n >\n Verify RERA\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"flex-1 justify-center\"\n disabled={reviewingRera}\n onClick={() => handleReraReview('rejected')}\n >\n Reject\n </Button>\n </div>\n )}\n </div>\n\n {/* Similar Properties */}\n {similarProperties.length > 0 && (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-5\">\n <h3 className=\"mb-4 text-base font-semibold text-text-primary\">Similar Properties</h3>\n <div className=\"space-y-3\">\n {similarProperties.map((sp) => (\n <button\n key={sp.id}\n onClick={() => navigate(`../properties/${sp.id}`)}\n className=\"flex w-full items-start gap-3 rounded-lg border border-border-subtle p-3 text-left transition-colors hover:bg-bg-sunken/50\"\n >\n {sp.images[0] && (\n <img src={sp.images[0].url} alt={sp.title} className=\"h-14 w-14 rounded object-cover\" />\n )}\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-medium text-text-primary\">{sp.title}</div>\n <div className=\"text-sm font-semibold text-text-primary\">{formatCurrency(sp.price.amount)}</div>\n <div className=\"truncate text-xs text-text-secondary\">\n {[sp.location.neighborhood, sp.location.city].filter(Boolean).join(', ')}\n </div>\n </div>\n </button>\n ))}\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Q&A / reviews — real EntityComments-backed thread */}\n <ReviewsSection entityId={property.id} entityType=\"housingvista-property\" />\n\n {/* Contact-owner conversation dialog — controlled at page root (same\n reliable pattern as the Make Offer dialog) */}\n <ContactOwnerDialog\n open={contactOpen}\n onOpenChange={setContactOpen}\n entityId={property.id}\n entityType=\"housingvista-property\"\n title={property.title}\n pagePath={location.pathname}\n heading=\"Contact owner\"\n description={`Ask a question or start a conversation about ${property.title}.`}\n />\n\n {/* Apply to Rent dialog */}\n <ResponsiveDialog open={rentalOpen} onOpenChange={setRentalOpen}>\n <ResponsiveDialogContent className=\"sm:max-w-2xl\">\n <form onSubmit={handleSubmitRental}>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Apply to rent</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Submit a rental application for {property.title}. The owner will review and respond.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"grid grid-cols-1 gap-4 py-2 sm:grid-cols-[1fr_16rem]\">\n <div className=\"space-y-3\">\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Full name *</label>\n <input\n type=\"text\"\n required\n value={applicantName}\n onChange={(e) => setApplicantName(e.target.value)}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Email *</label>\n <input\n type=\"email\"\n required\n value={applicantEmail}\n onChange={(e) => setApplicantEmail(e.target.value)}\n className={inputClass}\n />\n </div>\n </div>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Phone</label>\n <input\n type=\"tel\"\n value={applicantPhone}\n onChange={(e) => setApplicantPhone(e.target.value)}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">\n Monthly income ({property.price.currency})\n </label>\n <input\n type=\"number\"\n min={0}\n value={monthlyIncome}\n onChange={(e) => setMonthlyIncome(e.target.value)}\n className={inputClass}\n />\n </div>\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Preferred move-in date</label>\n <input\n type=\"date\"\n value={moveInDate}\n onChange={(e) => setMoveInDate(e.target.value)}\n className={inputClass}\n />\n </div>\n </div>\n\n {/* Rental summary — what you are actually applying for. Every value\n comes off the rental unit / listing rows this page already\n loaded; nothing here is estimated. */}\n <aside className=\"rounded-lg border border-border-subtle bg-bg-sunken/40 p-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Rental summary</h3>\n <div className=\"mt-3 flex items-start gap-3\">\n {property.images[0]?.url && (\n <img\n src={property.images[0].url}\n alt=\"\"\n aria-hidden\n className=\"h-14 w-14 shrink-0 rounded-md object-cover\"\n />\n )}\n <div className=\"min-w-0\">\n <p className=\"text-sm font-medium text-text-primary\">{property.title}</p>\n <p className=\"truncate text-xs text-text-secondary\">\n {[property.location.neighborhood, property.location.city].filter(Boolean).join(', ')}\n </p>\n </div>\n </div>\n\n {rentalUnit ? (\n <>\n <dl className=\"mt-3 grid grid-cols-2 gap-3 border-t border-border-subtle pt-3\">\n <div>\n <dt className=\"text-xs text-text-secondary\">Rent</dt>\n <dd className=\"text-sm font-semibold text-text-primary\">\n {formatCurrency(rentalUnit.monthlyRent)}/mo\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-secondary\">Deposit</dt>\n <dd className=\"text-sm font-semibold text-text-primary\">\n {rentalUnit.securityDeposit ? formatCurrency(rentalUnit.securityDeposit) : '—'}\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-secondary\">Unit</dt>\n <dd className=\"text-sm font-medium text-text-primary\">{rentalUnit.unitNumber}</dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-secondary\">Availability</dt>\n <dd className=\"mt-0.5\">\n <StatusBadge\n label={rentalUnitStatusLabel(rentalUnit.status)}\n variant={rentalUnitStatusVariant(rentalUnit.status)}\n />\n </dd>\n </div>\n </dl>\n {(rentalUnit.status === 'occupied' || rentalUnit.status === 'notice_period') &&\n rentalUnit.leaseEnd && (\n <p className=\"mt-2 text-xs text-text-secondary\">\n Current lease ends {formatDate(rentalUnit.leaseEnd)}\n </p>\n )}\n </>\n ) : (\n <p className=\"mt-3 border-t border-border-subtle pt-3 text-xs text-text-secondary\">\n No rental unit is listed for this property yet, so rent and deposit are not available.\n </p>\n )}\n\n {property.amenities.length > 0 && (\n <div className=\"mt-3 border-t border-border-subtle pt-3\">\n <p className=\"text-xs text-text-secondary\">Amenities</p>\n <ul className=\"mt-1.5 space-y-1.5\">\n {property.amenities.slice(0, 5).map((amenity) => {\n const Icon = amenityIcon(amenity.name);\n return (\n <li key={amenity.id} className=\"flex items-center gap-2 text-sm text-text-primary\">\n <Icon className=\"h-4 w-4 shrink-0 text-text-secondary\" />\n <span className=\"truncate\">{amenity.name}</span>\n </li>\n );\n })}\n </ul>\n {property.amenities.length > 5 && (\n <p className=\"mt-1.5 text-xs text-text-secondary\">\n +{property.amenities.length - 5} more on the listing\n </p>\n )}\n </div>\n )}\n </aside>\n </div>\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setRentalOpen(false)}>\n Cancel\n </Button>\n <Button type=\"submit\" disabled={submittingRental || !rentalUnitId}>\n {submittingRental ? 'Submitting…' : 'Submit application'}\n </Button>\n </ResponsiveDialogFooter>\n </form>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* Schedule Viewing dialog */}\n <ResponsiveDialog open={viewingOpen} onOpenChange={setViewingOpen}>\n <ResponsiveDialogContent className=\"sm:max-w-md\">\n <form onSubmit={handleBookViewing}>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Schedule a viewing</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>Pick a date and time to see {property.title}.</ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"space-y-3 py-2\">\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Date & time *</label>\n <input\n type=\"datetime-local\"\n required\n value={viewingDate}\n onChange={(e) => setViewingDate(e.target.value)}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Type</label>\n <select\n value={viewingType}\n onChange={(e) => setViewingType(e.target.value as 'in_person' | 'virtual')}\n className={inputClass}\n >\n <option value=\"in_person\">In person</option>\n <option value=\"virtual\">Virtual</option>\n </select>\n </div>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <input\n type=\"text\"\n placeholder=\"Your name\"\n value={attendeeName}\n onChange={(e) => setAttendeeName(e.target.value)}\n className={inputClass}\n />\n <input\n type=\"email\"\n placeholder=\"Your email\"\n value={attendeeEmail}\n onChange={(e) => setAttendeeEmail(e.target.value)}\n className={inputClass}\n />\n </div>\n <textarea\n placeholder=\"Notes (optional)\"\n rows={2}\n value={viewingNotes}\n onChange={(e) => setViewingNotes(e.target.value)}\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setViewingOpen(false)}>\n Cancel\n </Button>\n <Button type=\"submit\" disabled={bookingViewing || !viewingDate}>\n {bookingViewing ? 'Booking…' : 'Request viewing'}\n </Button>\n </ResponsiveDialogFooter>\n </form>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* Make Offer dialog */}\n <ResponsiveDialog open={offerOpen} onOpenChange={setOfferOpen}>\n <ResponsiveDialogContent className=\"sm:max-w-md\">\n <form onSubmit={handleSubmitOffer}>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Make an offer</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>Listing price is {formatPrice(property.price)}.</ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"space-y-3 py-2\">\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">\n Your offer ({property.price.currency}) *\n </label>\n <input\n type=\"number\"\n required\n min={1}\n value={offerAmount}\n onChange={(e) => setOfferAmount(e.target.value)}\n placeholder=\"Enter amount\"\n className={inputClass}\n />\n </div>\n <textarea\n placeholder=\"Message to the owner (optional)\"\n rows={3}\n value={offerNotes}\n onChange={(e) => setOfferNotes(e.target.value)}\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n <div>\n <label htmlFor=\"offer-expires\" className=\"mb-1.5 block text-sm font-medium text-text-primary\">\n Valid until (optional)\n </label>\n <input\n id=\"offer-expires\"\n type=\"datetime-local\"\n value={offerExpires}\n onChange={(e) => setOfferExpires(e.target.value)}\n className={inputClass}\n />\n <p className=\"mt-1 text-xs text-text-secondary\">\n The offer becomes non-actionable after this time. Clear the field for no expiry.\n </p>\n </div>\n </div>\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setOfferOpen(false)}>\n Cancel\n </Button>\n <Button type=\"submit\" disabled={submittingOffer}>\n {submittingOffer ? 'Submitting…' : 'Submit offer'}\n </Button>\n </ResponsiveDialogFooter>\n </form>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* Edit dialog */}\n <ResponsiveDialog open={editOpen} onOpenChange={(open) => !open && !updatingProperty && setEditOpen(false)}>\n <ResponsiveDialogContent className=\"sm:max-w-2xl\">\n <form onSubmit={handleEdit}>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Edit property</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Update the listing details — basics, location, specifications and pricing. Photos are managed separately\n from the gallery.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"max-h-[65vh] space-y-6 overflow-y-auto py-2 pr-1\">\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Basics</h3>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Title *</label>\n <input\n type=\"text\"\n required\n value={editForm.title}\n onChange={(e) => updateEditForm({ title: e.target.value })}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Description</label>\n <textarea\n rows={3}\n value={editForm.description}\n onChange={(e) => updateEditForm({ description: e.target.value })}\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Status</label>\n <select\n value={editForm.status}\n onChange={(e) => updateEditForm({ status: e.target.value as PropertyStatus })}\n className={inputClass}\n >\n {statusOptions.map((s) => (\n <option key={s.value} value={s.value}>\n {s.label}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Type</label>\n <select\n value={editForm.type}\n onChange={(e) => updateEditForm({ type: e.target.value as PropertyType })}\n className={inputClass}\n >\n {propertyTypeOptions.map((t) => (\n <option key={t.value} value={t.value}>\n {t.label}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Category</label>\n <select\n value={editForm.category}\n onChange={(e) => updateEditForm({ category: e.target.value as PropertyCategory })}\n className={inputClass}\n >\n {propertyCategoryOptions.map((c) => (\n <option key={c.value} value={c.value}>\n {c.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n </section>\n\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Location</h3>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <div className=\"sm:col-span-2\">\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Address</label>\n <input\n type=\"text\"\n value={editForm.address}\n onChange={(e) => updateEditForm({ address: e.target.value })}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">City *</label>\n <input\n type=\"text\"\n required\n value={editForm.city}\n onChange={(e) => updateEditForm({ city: e.target.value })}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">State *</label>\n <input\n type=\"text\"\n required\n value={editForm.state}\n onChange={(e) => updateEditForm({ state: e.target.value })}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Country</label>\n <input\n type=\"text\"\n value={editForm.country}\n onChange={(e) => updateEditForm({ country: e.target.value })}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Pincode</label>\n <input\n type=\"text\"\n value={editForm.pincode}\n onChange={(e) => updateEditForm({ pincode: e.target.value })}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Neighborhood</label>\n <input\n type=\"text\"\n value={editForm.neighborhood}\n onChange={(e) => updateEditForm({ neighborhood: e.target.value })}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Landmarks</label>\n <input\n type=\"text\"\n value={editForm.landmarks}\n onChange={(e) => updateEditForm({ landmarks: e.target.value })}\n placeholder=\"Comma-separated\"\n className={inputClass}\n />\n </div>\n </div>\n <div>\n <span className=\"mb-1.5 block text-sm font-medium text-text-primary\">Map location</span>\n <CoordinatePicker\n value={editForm.coordinates}\n onChange={(coords) => updateEditForm({ coordinates: coords })}\n />\n </div>\n </section>\n\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Specifications</h3>\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n {numericFields.map((field) => (\n <div key={field.key}>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">{field.label}</label>\n <input\n type=\"number\"\n min={0}\n step={field.step}\n required={field.required}\n value={editForm[field.key]}\n onChange={(e) => updateEditForm({ [field.key]: e.target.value })}\n className={inputClass}\n />\n </div>\n ))}\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Furnishing</label>\n <select\n value={editForm.furnishingStatus}\n onChange={(e) => updateEditForm({ furnishingStatus: e.target.value })}\n className={inputClass}\n >\n {furnishingOptions.map((f) => (\n <option key={f.value} value={f.value}>\n {f.label}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Facing</label>\n <select\n value={editForm.facing}\n onChange={(e) => updateEditForm({ facing: e.target.value })}\n className={inputClass}\n >\n <option value=\"\">— (unset)</option>\n {facingOptions.map((f) => (\n <option key={f} value={f}>\n {f}\n </option>\n ))}\n </select>\n </div>\n </div>\n </section>\n\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Pricing</h3>\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Price *</label>\n <input\n type=\"number\"\n min={0}\n required\n value={editForm.price}\n onChange={(e) => updateEditForm({ price: e.target.value })}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Price type</label>\n <select\n value={editForm.priceType}\n onChange={(e) => updateEditForm({ priceType: e.target.value })}\n className={inputClass}\n >\n {priceTypeOptions.map((t) => (\n <option key={t.value} value={t.value}>\n {t.label}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Price period</label>\n <select\n value={editForm.pricePeriod}\n onChange={(e) => updateEditForm({ pricePeriod: e.target.value })}\n className={inputClass}\n >\n {pricePeriodOptions.map((t) => (\n <option key={t.value} value={t.value}>\n {t.label}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Currency</label>\n <select\n value={editForm.currency}\n onChange={(e) => updateEditForm({ currency: e.target.value })}\n className={inputClass}\n >\n {currencyOptions.map((c) => (\n <option key={c.value} value={c.value}>\n {c.label}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Price / sqft</label>\n <input\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={editForm.pricePerSqft}\n onChange={(e) => updateEditForm({ pricePerSqft: e.target.value })}\n className={inputClass}\n />\n </div>\n <label className=\"flex items-end gap-2 pb-2.5 text-sm font-medium text-text-primary\">\n <input\n type=\"checkbox\"\n checked={editForm.negotiable}\n onChange={(e) => updateEditForm({ negotiable: e.target.checked })}\n className=\"h-4 w-4 rounded border-border-subtle\"\n />\n Negotiable\n </label>\n </div>\n </section>\n\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Amenities</h3>\n <div className=\"flex flex-wrap gap-2\">\n {amenityOptions.map((amenity) => {\n const Icon = amenity.icon;\n const selected = editForm.amenities.includes(amenity.id);\n return (\n <button\n key={amenity.id}\n type=\"button\"\n aria-pressed={selected}\n onClick={() =>\n updateEditForm({\n amenities: selected\n ? editForm.amenities.filter((a) => a !== amenity.id)\n : [...editForm.amenities, amenity.id],\n })\n }\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full border px-3 py-1.5 text-xs font-medium transition-colors',\n selected\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-surface text-text-secondary hover:bg-bg-sunken hover:text-text-primary'\n )}\n >\n <Icon className=\"h-3.5 w-3.5\" />\n {amenity.label}\n </button>\n );\n })}\n </div>\n </section>\n </div>\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setEditOpen(false)} disabled={updatingProperty}>\n Cancel\n </Button>\n <Button type=\"submit\" disabled={updatingProperty}>\n {updatingProperty ? 'Saving…' : 'Save changes'}\n </Button>\n </ResponsiveDialogFooter>\n </form>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* Delete confirm dialog */}\n <ResponsiveDialog open={deleteOpen} onOpenChange={setDeleteOpen}>\n <ResponsiveDialogContent className=\"sm:max-w-md\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Delete this property?</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n {property.title} will be permanently removed. This cannot be undone.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setDeleteOpen(false)}>\n Cancel\n </Button>\n <Button type=\"button\" variant=\"destructive\" onClick={handleDelete} disabled={deletingProperty}>\n {deletingProperty ? 'Deleting…' : 'Delete property'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PropertyDetailPage.js","names":[],"sources":["../../../../src/housingvista/pages/properties/PropertyDetailPage.tsx"],"sourcesContent":["/**\n * HousingVista Property Detail Page\n * Full property detail view backed by the single-item `housingvistaProperty(id)`\n * query, with the core buyer journey wired to real mutations: shortlist, book a\n * viewing, submit an offer, plus owner-side edit and delete.\n * @module housingvista\n */\n\nimport { useState, useMemo, type FormEvent } from 'react';\nimport { useParams, useNavigate, useLocation } from 'react-router';\nimport {\n ArrowLeft,\n MapPin,\n Bed,\n Bath,\n Square,\n Car,\n Heart,\n Share2,\n CheckCircle,\n Calendar,\n DollarSign,\n ChevronLeft,\n ChevronRight,\n Building,\n Pencil,\n Trash2,\n Calculator,\n Download,\n TrendingUp,\n MessageSquare,\n KeyRound,\n BadgeCheck,\n Compass,\n Waves,\n Dumbbell,\n Shield,\n TreePine,\n Wifi,\n Wind,\n Flame,\n Utensils,\n ParkingCircle,\n Navigation,\n type LucideIcon,\n} from 'lucide-react';\nimport { AreaChart, Area, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts';\nimport {\n EmphasisPanel,\n PagePurpose,\n NextSteps,\n Button,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Breadcrumbs,\n StatusBadge,\n EmptyState,\n LoadingSkeleton,\n ContactOwnerDialog,\n ReviewsSection,\n} from '../../components';\nimport type { BreadcrumbItem } from '../../components';\nimport {\n useProperty,\n useProperties,\n useShortlists,\n useSaveShortlist,\n useRemoveShortlist,\n useBookViewing,\n useSubmitOffer,\n useUpdateProperty,\n useDeleteProperty,\n useRentalUnits,\n useSubmitRentalApplication,\n useCreateInvestment,\n useUpdatePropertyReraStatus,\n type UpdatePropertyInput,\n} from '../../hooks';\nimport { notify } from '../../lib/toast';\nimport { useHousingVistaAnalytics, useTrackPageView } from '../../hooks/useHousingVistaAnalytics';\nimport { cn, formatCurrency, formatCompactCurrency, formatNumber, formatDate } from '../../utils/helpers';\nimport { amenityOptions } from '../../utils/amenities';\nimport {\n propertyTypeOptions,\n propertyCategoryOptions,\n currencyOptions,\n furnishingOptions,\n facingOptions,\n} from '../../utils/propertyOptions';\nimport { CoordinatePicker, type PickerCoordinates } from '../../components/maps/CoordinatePicker';\nimport type { Amenity, Property, PropertyCategory, PropertyStatus, PropertyType } from '../../types';\n\nconst statusVariantMap: Record<string, 'success' | 'warning' | 'error' | 'info' | 'default' | 'muted'> = {\n for_sale: 'success',\n for_rent: 'info',\n sold: 'muted',\n rented: 'muted',\n under_contract: 'warning',\n off_market: 'error',\n};\n\nconst statusOptions: { value: PropertyStatus; label: string }[] = [\n { value: 'for_sale', label: 'For Sale' },\n { value: 'for_rent', label: 'For Rent' },\n { value: 'under_contract', label: 'Under Contract' },\n { value: 'sold', label: 'Sold' },\n { value: 'rented', label: 'Rented' },\n { value: 'off_market', label: 'Off Market' },\n];\n\n// Edit-dialog choices come from the shared catalogs (utils/propertyOptions.ts,\n// utils/amenities.ts) so create and edit can never drift. priceType/pricePeriod\n// are edit-only selects (the wizard derives them from its listing-type radio).\nconst priceTypeOptions: { value: string; label: string }[] = [\n { value: 'sale', label: 'Sale' },\n { value: 'rent', label: 'Rent' },\n { value: 'lease', label: 'Lease' },\n];\n\nconst pricePeriodOptions: { value: string; label: string }[] = [\n { value: '', label: '— (one-time)' },\n { value: 'monthly', label: 'Monthly' },\n { value: 'quarterly', label: 'Quarterly' },\n { value: 'yearly', label: 'Yearly' },\n];\n\n/** Full edit form. All numeric fields are strings (controlled inputs). */\ninterface EditFormState {\n title: string;\n description: string;\n status: PropertyStatus;\n type: PropertyType;\n category: PropertyCategory;\n address: string;\n city: string;\n state: string;\n country: string;\n pincode: string;\n neighborhood: string;\n landmarks: string;\n coordinates: PickerCoordinates | null;\n bedrooms: string;\n bathrooms: string;\n /** Original amenity records whose name matches the shared catalog — their stored\n * category/availability must survive a chip toggle. */\n catalogAmenities: Amenity[];\n totalArea: string;\n carpetArea: string;\n builtUpArea: string;\n floors: string;\n totalFloors: string;\n parking: string;\n balconies: string;\n furnishingStatus: string;\n ageOfProperty: string;\n facing: string;\n price: string;\n currency: string;\n priceType: string;\n pricePeriod: string;\n negotiable: boolean;\n pricePerSqft: string;\n amenities: string[];\n /** Amenity records whose names fall outside the shared catalog; preserved verbatim. */\n extraAmenities: Amenity[];\n}\n\nconst EMPTY_EDIT_FORM: EditFormState = {\n title: '',\n description: '',\n status: 'for_sale',\n type: 'residential',\n category: 'apartment',\n address: '',\n city: '',\n state: '',\n country: '',\n pincode: '',\n neighborhood: '',\n landmarks: '',\n coordinates: null,\n bedrooms: '',\n bathrooms: '',\n catalogAmenities: [],\n totalArea: '',\n carpetArea: '',\n builtUpArea: '',\n floors: '',\n totalFloors: '',\n parking: '',\n balconies: '',\n furnishingStatus: 'unfurnished',\n ageOfProperty: '',\n facing: '',\n price: '',\n currency: 'USD',\n priceType: 'sale',\n pricePeriod: '',\n negotiable: true,\n pricePerSqft: '',\n amenities: [],\n extraAmenities: [],\n};\n\nconst toNumber = (value: string): number | null => {\n const trimmed = value.trim();\n if (trimmed === '') return null;\n const parsed = Number(trimmed);\n return Number.isFinite(parsed) ? parsed : null;\n};\n\nconst optionalNumber = (value: string): number | undefined => {\n const parsed = toNumber(value);\n return parsed === null ? undefined : parsed;\n};\n\nconst fieldText = (value: number | undefined): string => (value == null ? '' : String(value));\n\n/**\n * The subgraph still returns null for optional location strings the domain\n * type claims are non-null (the DB columns are nullable). The edit seed must\n * never carry nulls — the save path calls .trim() on every field.\n */\nconst seedStr = (value: string | null | undefined): string => value ?? '';\n\n// Landmarks are captured as a comma-separated list; normalize before comparing\n// so a no-op edit round-trip does not count as a change.\nconst normalizeLandmarks = (csv: string): string[] =>\n csv\n .split(',')\n .map((item) => item.trim())\n .filter(Boolean);\n\nconst numericFields = [\n { key: 'bedrooms', label: 'Bedrooms', required: false, step: '1' },\n { key: 'bathrooms', label: 'Bathrooms', required: false, step: '1' },\n { key: 'totalArea', label: 'Total area (sqft) *', required: true, step: '0.01' },\n { key: 'carpetArea', label: 'Carpet area', required: false, step: '0.01' },\n { key: 'builtUpArea', label: 'Built-up area', required: false, step: '0.01' },\n { key: 'floors', label: 'Floor', required: false, step: '1' },\n { key: 'totalFloors', label: 'Total floors', required: false, step: '1' },\n { key: 'parking', label: 'Parking spots', required: false, step: '1' },\n { key: 'balconies', label: 'Balconies', required: false, step: '1' },\n { key: 'ageOfProperty', label: 'Age (years)', required: false, step: '1' },\n] as const satisfies readonly {\n key: keyof EditFormState;\n label: string;\n required: boolean;\n step: string;\n}[];\n\n/** +7 days default for the offer \"Valid until\" picker — UI convenience only;\n * the backend stores no default (unset expiresAt = never expires, BOFF-8053). */\nfunction defaultOfferExpiry(): string {\n const date = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);\n return new Date(date.getTime() - date.getTimezoneOffset() * 60000).toISOString().slice(0, 16);\n}\n\ntype TabId = 'details' | 'amenities' | 'location';\nconst tabs: { id: TabId; label: string }[] = [\n { id: 'details', label: 'Details' },\n { id: 'amenities', label: 'Amenities' },\n { id: 'location', label: 'Location' },\n];\n\nconst inputClass =\n 'h-10 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]';\n\n// Map free-text amenity names to a recognisable icon (falls back to a tick).\nconst amenityIconRules: { match: RegExp; icon: LucideIcon }[] = [\n { match: /pool|swim/i, icon: Waves },\n { match: /gym|fitness/i, icon: Dumbbell },\n { match: /park/i, icon: ParkingCircle },\n { match: /garden|green|lawn|park/i, icon: TreePine },\n { match: /security|guard|cctv|gated/i, icon: Shield },\n { match: /wifi|internet|broadband/i, icon: Wifi },\n { match: /a\\/?c|air.?condition|central air|hvac/i, icon: Wind },\n { match: /fire|chimney|heat/i, icon: Flame },\n { match: /kitchen|modular|dining/i, icon: Utensils },\n { match: /car|garage/i, icon: Car },\n];\nconst amenityIcon = (name: string): LucideIcon => amenityIconRules.find((r) => r.match.test(name))?.icon ?? CheckCircle;\n\n// `RentalUnit.status` is a free-form String on the subgraph and is written in\n// lower_snake_case by the service — normalise at render rather than trusting\n// the TS union's casing.\nfunction rentalUnitStatusLabel(status: string): string {\n switch (status.toLowerCase()) {\n case 'vacant':\n return 'Vacant — accepting applications';\n case 'occupied':\n return 'Currently occupied';\n case 'notice_period':\n return 'On notice';\n case 'maintenance':\n return 'Under maintenance';\n default:\n return status.replace(/[-_]/g, ' ');\n }\n}\n\nfunction rentalUnitStatusVariant(status: string): 'success' | 'warning' | 'error' | 'info' | 'muted' {\n switch (status.toLowerCase()) {\n case 'vacant':\n return 'success';\n case 'occupied':\n return 'muted';\n case 'notice_period':\n return 'info';\n case 'maintenance':\n return 'error';\n default:\n return 'muted';\n }\n}\n\nexport const PropertyDetailPage = () => {\n const { id } = useParams<{ id: string }>();\n const navigate = useNavigate();\n const location = useLocation();\n const { emit, emitResource } = useHousingVistaAnalytics();\n useTrackPageView('housingvista.property.viewed', id);\n\n const { data: property, loading } = useProperty(id);\n const { data: allProperties } = useProperties({ pagination: { limit: 8, offset: 0 } });\n const { data: shortlists } = useShortlists();\n const { data: rentalUnits } = useRentalUnits({\n filter: id ? { propertyId: id } : undefined,\n pagination: { limit: 1, offset: 0 },\n });\n const { saveShortlist, loading: savingShortlist } = useSaveShortlist();\n const { removeShortlist, loading: removingShortlist } = useRemoveShortlist();\n const { bookViewing, loading: bookingViewing } = useBookViewing();\n const { submitOffer, loading: submittingOffer } = useSubmitOffer();\n const { updateProperty, loading: updatingProperty } = useUpdateProperty();\n const { deleteProperty, loading: deletingProperty } = useDeleteProperty();\n const { submitRentalApplication, loading: submittingRental } = useSubmitRentalApplication();\n const { createInvestment, loading: creatingInvestment } = useCreateInvestment();\n const { updatePropertyReraStatus, loading: reviewingRera } = useUpdatePropertyReraStatus();\n\n const similarProperties = useMemo(() => allProperties.filter((p) => p.id !== id).slice(0, 3), [allProperties, id]);\n const isShortlisted = useMemo(() => shortlists.some((s) => s.propertyId === id), [shortlists, id]);\n\n const [currentImageIndex, setCurrentImageIndex] = useState(0);\n const [activeTab, setActiveTab] = useState<TabId>('details');\n const [viewingOpen, setViewingOpen] = useState(false);\n const [offerOpen, setOfferOpen] = useState(false);\n const [editOpen, setEditOpen] = useState(false);\n const [deleteOpen, setDeleteOpen] = useState(false);\n const [rentalOpen, setRentalOpen] = useState(false);\n const [contactOpen, setContactOpen] = useState(false);\n\n // Rental application form state\n const [applicantName, setApplicantName] = useState('');\n const [applicantEmail, setApplicantEmail] = useState('');\n const [applicantPhone, setApplicantPhone] = useState('');\n const [monthlyIncome, setMonthlyIncome] = useState('');\n const [moveInDate, setMoveInDate] = useState('');\n\n // Investment-analysis calculator inputs (blank = use a price-derived default)\n const [rentInput, setRentInput] = useState('');\n const [costInput, setCostInput] = useState('');\n const [appreciationInput, setAppreciationInput] = useState('8');\n // BOFF-3928 — stamp duty/registration + financing toggles.\n const [includeStampDuty, setIncludeStampDuty] = useState(true);\n const [stampDutyPctInput, setStampDutyPctInput] = useState('6');\n const [includeFinancing, setIncludeFinancing] = useState(false);\n const [downPaymentPctInput, setDownPaymentPctInput] = useState('20');\n const [loanRateInput, setLoanRateInput] = useState('8.5');\n const [loanTenureInput, setLoanTenureInput] = useState('20');\n\n // Viewing form state\n const [viewingDate, setViewingDate] = useState('');\n const [viewingType, setViewingType] = useState<'in_person' | 'virtual'>('in_person');\n const [attendeeName, setAttendeeName] = useState('');\n const [attendeeEmail, setAttendeeEmail] = useState('');\n const [viewingNotes, setViewingNotes] = useState('');\n\n // Offer form state\n const [offerAmount, setOfferAmount] = useState('');\n const [offerNotes, setOfferNotes] = useState('');\n const [offerExpires, setOfferExpires] = useState('');\n\n // Edit form state (seeded on open; the seed is kept for change detection on\n // the collection fields — amenities/landmarks are only sent when modified so\n // non-catalog or legacy values are never silently dropped).\n const [editForm, setEditForm] = useState<EditFormState>(EMPTY_EDIT_FORM);\n const [editSeed, setEditSeed] = useState<EditFormState>(EMPTY_EDIT_FORM);\n\n if (loading) {\n return (\n <div className=\"space-y-6 p-6\">\n <LoadingSkeleton className=\"h-80\" />\n <LoadingSkeleton variant=\"detail\" />\n </div>\n );\n }\n\n if (!property) {\n return (\n <div className=\"p-6\">\n <EmptyState\n illustration=\"empty-search\"\n icon={<Building className=\"h-12 w-12\" />}\n title=\"Property Not Found\"\n description=\"The property you're looking for doesn't exist or has been removed.\"\n action={\n <button\n onClick={() => navigate('../properties')}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Properties\n </button>\n }\n />\n </div>\n );\n }\n\n const breadcrumbs: BreadcrumbItem[] = [{ label: 'Properties', href: '../' }, { label: property.title }];\n\n const formatPrice = (price: Property['price']) => {\n const amount = formatCurrency(price.amount, price.currency);\n if (price.type === 'rent' && price.period) return `${amount}/${price.period.replace('ly', '')}`;\n return amount;\n };\n\n const nextImage = () => setCurrentImageIndex((prev) => (prev === property.images.length - 1 ? 0 : prev + 1));\n const prevImage = () => setCurrentImageIndex((prev) => (prev === 0 ? property.images.length - 1 : prev - 1));\n\n const handleShare = () => {\n if (navigator.share) {\n navigator.share({ title: property.title, text: property.description, url: window.location.href });\n } else {\n navigator.clipboard.writeText(window.location.href);\n notify.info('Link copied', 'The property link is on your clipboard.');\n }\n };\n\n const toggleShortlist = async () => {\n try {\n if (isShortlisted) {\n await removeShortlist(property.id);\n notify.success('Removed from shortlist');\n } else {\n await saveShortlist(property.id);\n emitResource('housingvista.shortlist.property_added', property.id);\n notify.success('Saved to shortlist');\n }\n } catch (err) {\n notify.error('Could not update shortlist', (err as Error).message);\n }\n };\n\n const handleBookViewing = async (e: FormEvent) => {\n e.preventDefault();\n if (!viewingDate) return;\n try {\n await bookViewing({\n propertyId: property.id,\n scheduledAt: new Date(viewingDate).toISOString(),\n type: viewingType,\n attendeeName: attendeeName.trim() || undefined,\n attendeeEmail: attendeeEmail.trim() || undefined,\n notes: viewingNotes.trim() || undefined,\n });\n emitResource('housingvista.viewing.scheduled', property.id);\n notify.success('Viewing requested', 'The owner will confirm your slot shortly.');\n setViewingOpen(false);\n setViewingDate('');\n setAttendeeName('');\n setAttendeeEmail('');\n setViewingNotes('');\n } catch (err) {\n notify.error('Could not book viewing', (err as Error).message);\n }\n };\n\n const handleSubmitOffer = async (e: FormEvent) => {\n e.preventDefault();\n const amount = Number(offerAmount);\n if (!amount || amount <= 0) {\n notify.warning('Enter a valid offer amount');\n return;\n }\n try {\n await submitOffer({\n propertyId: property.id,\n amount,\n currency: property.price.currency,\n notes: offerNotes.trim() || undefined,\n expiresAt: offerExpires ? new Date(offerExpires).toISOString() : undefined,\n });\n emitResource('housingvista.offer.created', property.id);\n notify.success('Offer submitted', `Your offer of ${formatCurrency(amount, property.price.currency)} was sent.`);\n setOfferOpen(false);\n setOfferAmount('');\n setOfferNotes('');\n setOfferExpires('');\n } catch (err) {\n notify.error('Could not submit offer', (err as Error).message);\n }\n };\n\n const openEdit = () => {\n const coords = property.location.coordinates;\n const seed: EditFormState = {\n title: property.title,\n description: seedStr(property.description),\n status: property.status,\n type: property.type,\n category: property.category,\n address: seedStr(property.location.address),\n city: seedStr(property.location.city),\n state: seedStr(property.location.state),\n country: seedStr(property.location.country),\n pincode: seedStr(property.location.pincode),\n neighborhood: seedStr(property.location.neighborhood),\n landmarks: (property.location.landmarks ?? []).join(', '),\n coordinates:\n coords && (coords.latitude !== 0 || coords.longitude !== 0)\n ? { latitude: coords.latitude, longitude: coords.longitude }\n : null,\n bedrooms: fieldText(property.specifications.bedrooms),\n bathrooms: fieldText(property.specifications.bathrooms),\n totalArea: fieldText(property.specifications.totalArea),\n carpetArea: fieldText(property.specifications.carpetArea),\n builtUpArea: fieldText(property.specifications.builtUpArea),\n floors: fieldText(property.specifications.floors),\n totalFloors: fieldText(property.specifications.totalFloors),\n parking: fieldText(property.specifications.parking),\n balconies: fieldText(property.specifications.balconies),\n furnishingStatus: property.specifications.furnishingStatus,\n ageOfProperty: fieldText(property.specifications.ageOfProperty),\n facing: property.specifications.facing ?? '',\n price: fieldText(property.price.amount),\n currency: property.price.currency,\n priceType: property.price.type,\n pricePeriod: property.price.period ?? '',\n negotiable: property.price.negotiable,\n pricePerSqft: fieldText(property.price.pricePerSqft),\n amenities: property.amenities\n .filter((a) => a.available)\n .map((a) => amenityOptions.find((o) => o.label === a.name)?.id ?? '')\n .filter((entry) => entry !== ''),\n extraAmenities: property.amenities.filter((a) => !amenityOptions.some((o) => o.label === a.name)),\n catalogAmenities: property.amenities.filter((a) => amenityOptions.some((o) => o.label === a.name)),\n };\n setEditForm(seed);\n setEditSeed(seed);\n setEditOpen(true);\n };\n\n const updateEditForm = (patch: Partial<EditFormState>) => setEditForm((prev) => ({ ...prev, ...patch }));\n\n // Free-text scalars are sent as trimmed values even when empty so a host can\n // CLEAR a stored value (undefined would be indistinguishable from \"no change\"\n // in the update input); numeric/enum/coordinate fields keep their guards above.\n const clearableText = (value: string): string => value.trim();\n\n const handleEdit = async (e: FormEvent) => {\n e.preventDefault();\n const title = editForm.title.trim();\n const city = editForm.city.trim();\n const state = editForm.state.trim();\n const bedrooms = toNumber(editForm.bedrooms);\n const bathrooms = toNumber(editForm.bathrooms);\n const totalArea = toNumber(editForm.totalArea);\n const price = toNumber(editForm.price);\n if (!title || !city || !state) {\n notify.warning('Title, city and state are required');\n return;\n }\n // Bedrooms/bathrooms stay optional so legacy rows seeded with null can be\n // saved without inventing values; anything provided must be a real number.\n if (editForm.bedrooms.trim() !== '' && (bedrooms == null || bedrooms < 0)) {\n notify.warning('Bedrooms must be zero or greater');\n return;\n }\n if (editForm.bathrooms.trim() !== '' && (bathrooms == null || bathrooms < 0)) {\n notify.warning('Bathrooms must be zero or greater');\n return;\n }\n if (totalArea == null || totalArea < 0) {\n notify.warning('Total area must be zero or greater');\n return;\n }\n if (price == null || price <= 0) {\n notify.warning('Enter a price greater than zero');\n return;\n }\n const landmarksNow = normalizeLandmarks(editForm.landmarks);\n const landmarksChanged = landmarksNow.join('|') !== normalizeLandmarks(editSeed.landmarks).join('|');\n const amenitiesChanged = [...editForm.amenities].sort().join('|') !== [...editSeed.amenities].sort().join('|');\n const input: UpdatePropertyInput = {\n title,\n description: clearableText(editForm.description),\n status: editForm.status,\n type: editForm.type,\n category: editForm.category,\n address: clearableText(editForm.address),\n city,\n state,\n country: clearableText(editForm.country),\n pincode: clearableText(editForm.pincode),\n neighborhood: clearableText(editForm.neighborhood),\n coordinates: editForm.coordinates ?? undefined,\n bedrooms: bedrooms ?? undefined,\n bathrooms: bathrooms ?? undefined,\n totalArea,\n carpetArea: optionalNumber(editForm.carpetArea),\n builtUpArea: optionalNumber(editForm.builtUpArea),\n floors: optionalNumber(editForm.floors),\n totalFloors: optionalNumber(editForm.totalFloors),\n parking: optionalNumber(editForm.parking),\n balconies: optionalNumber(editForm.balconies),\n furnishingStatus: editForm.furnishingStatus,\n ageOfProperty: optionalNumber(editForm.ageOfProperty),\n facing: editForm.facing || undefined,\n price,\n currency: editForm.currency || undefined,\n priceType: editForm.priceType || undefined,\n // '' = the explicit \"— (one-time)\" choice: send null to CLEAR a stored\n // period (undefined would be indistinguishable from \"not provided\").\n pricePeriod: editForm.pricePeriod === '' ? null : editForm.pricePeriod,\n negotiable: editForm.negotiable,\n pricePerSqft: optionalNumber(editForm.pricePerSqft),\n };\n if (landmarksChanged) input.landmarks = landmarksNow;\n if (amenitiesChanged) {\n // Rebuild the collection keyed by name: non-catalog records are preserved\n // verbatim; catalog-matched records keep their stored category (a chip\n // switched on marks availability, never rewrites metadata); disabled\n // records the user did not enable stay as-is; previously-available chips\n // switched off are removed; brand-new chips are appended as general.\n const selectedLabels = new Set(\n editForm.amenities.map((id) => amenityOptions.find((a) => a.id === id)?.label ?? id)\n );\n const byName = new Map<string, { name: string; category: string; available: boolean }>();\n for (const record of editForm.extraAmenities) {\n byName.set(record.name, { name: record.name, category: record.category, available: record.available });\n }\n for (const record of editForm.catalogAmenities) {\n if (selectedLabels.has(record.name)) {\n byName.set(record.name, { name: record.name, category: record.category, available: true });\n } else if (!record.available) {\n byName.set(record.name, { name: record.name, category: record.category, available: record.available });\n }\n }\n for (const label of selectedLabels) {\n if (!byName.has(label)) {\n byName.set(label, { name: label, category: 'general', available: true });\n }\n }\n input.amenities = [...byName.values()];\n }\n try {\n await updateProperty(property.id, input);\n emitResource('housingvista.property.updated', property.id);\n notify.success('Property updated');\n setEditOpen(false);\n } catch (err) {\n notify.error('Could not update property', (err as Error).message);\n }\n };\n\n const handleDelete = async () => {\n try {\n await deleteProperty(property.id);\n emitResource('housingvista.property.deleted', property.id);\n notify.success('Property deleted');\n navigate('../properties');\n } catch (err) {\n notify.error('Could not delete property', (err as Error).message);\n }\n };\n\n // First available rental unit for this property (needed to submit an application).\n // The whole row — not just the id — backs the \"Rental summary\" panel in the\n // apply dialog: rent, deposit, unit number, occupancy status and lease dates\n // all ship in `GetRentalUnits` already.\n const rentalUnit = rentalUnits[0];\n const rentalUnitId = rentalUnit?.id;\n\n const handleSubmitRental = async (e: FormEvent) => {\n e.preventDefault();\n if (!rentalUnitId) {\n notify.warning('No rental unit is available for this property yet');\n return;\n }\n if (!applicantName.trim() || !applicantEmail.trim()) {\n notify.warning('Enter your name and email to apply');\n return;\n }\n try {\n await submitRentalApplication({\n rentalUnitId,\n applicantName: applicantName.trim(),\n applicantEmail: applicantEmail.trim(),\n applicantPhone: applicantPhone.trim() || undefined,\n monthlyIncome: monthlyIncome ? Number(monthlyIncome) : undefined,\n moveInDate: moveInDate ? new Date(moveInDate).toISOString() : undefined,\n });\n notify.success('Application submitted', 'The owner will review your rental application shortly.');\n setRentalOpen(false);\n setApplicantName('');\n setApplicantEmail('');\n setApplicantPhone('');\n setMonthlyIncome('');\n setMoveInDate('');\n } catch (err) {\n notify.error('Could not submit application', (err as Error).message);\n }\n };\n\n const handleTrackInvestment = async () => {\n try {\n await createInvestment({\n propertyId: property.id,\n title: `${property.title} — investment`,\n status: 'active',\n investmentType: 'full_ownership',\n riskLevel: 'medium',\n totalValue: property.price.amount,\n startDate: new Date().toISOString(),\n });\n notify.success('Tracking investment', `${property.title} was added to your portfolio.`);\n } catch (err) {\n notify.error('Could not track investment', (err as Error).message);\n }\n };\n\n /** RERA review workflow (BOFF-4132) — approve/reject the pending status. */\n const handleReraReview = async (nextStatus: 'verified' | 'rejected') => {\n try {\n await updatePropertyReraStatus(property.id, nextStatus);\n notify.success(\n nextStatus === 'verified' ? 'RERA registration verified' : 'RERA registration rejected',\n property.title\n );\n } catch (err) {\n notify.error('Could not update RERA status', (err as Error).message);\n }\n };\n\n // Investment analysis — modelled client-side from the listing price + user inputs.\n const price = property.price.amount;\n const monthlyRent = Number(rentInput) || Math.round(price * 0.005); // ~0.5%/mo default\n const monthlyHoldingCosts = Number(costInput) || Math.round(price * 0.0015); // ~0.15%/mo default\n const grossAnnualRent = monthlyRent * 12;\n const grossYield = price > 0 ? (grossAnnualRent / price) * 100 : 0;\n const annualHoldingCosts = monthlyHoldingCosts * 12;\n const netAnnualIncome = grossAnnualRent - annualHoldingCosts;\n const netYield = price > 0 ? (netAnnualIncome / price) * 100 : 0;\n // 5-year projected value growth at a user-adjustable appreciation rate + the\n // cumulative net rental income earned over the same window (total return).\n const appreciationRate = Math.max(0, Number(appreciationInput) || 0) / 100;\n const projection = Array.from({ length: 6 }, (_, year) => ({\n label: year === 0 ? 'Now' : `Yr ${year}`,\n value: Math.round(price * Math.pow(1 + appreciationRate, year)),\n }));\n const projectedValue5yr = projection[projection.length - 1].value;\n const totalReturn5yr = projectedValue5yr - price + netAnnualIncome * 5;\n const projectedRoi = price > 0 ? (totalReturn5yr / price) * 100 : 0;\n\n // Stamp duty / registration (BOFF-3928) — a one-time acquisition cost on\n // top of the listing price, toggled and rate-adjustable since it varies by\n // Indian state (roughly 5-8% combined in most states).\n const stampDutyPct = Math.max(0, Number(stampDutyPctInput) || 0);\n const stampDutyCost = includeStampDuty ? price * (stampDutyPct / 100) : 0;\n\n // Financing (BOFF-3928) — standard amortizing-loan EMI on the financed\n // portion; cash-on-cash return uses the actual cash outlaid (down payment\n // + stamp duty) rather than the full price when financing is on.\n const downPaymentPct = Math.min(100, Math.max(0, Number(downPaymentPctInput) || 0));\n const loanAnnualRate = Math.max(0, Number(loanRateInput) || 0) / 100;\n const loanTenureYears = Math.max(1, Number(loanTenureInput) || 1);\n const downPayment = includeFinancing ? price * (downPaymentPct / 100) : price;\n const loanAmount = includeFinancing ? price - downPayment : 0;\n const monthlyRatePct = loanAnnualRate / 12;\n const loanMonths = loanTenureYears * 12;\n const monthlyEmi =\n includeFinancing && loanAmount > 0\n ? monthlyRatePct > 0\n ? (loanAmount * monthlyRatePct * Math.pow(1 + monthlyRatePct, loanMonths)) /\n (Math.pow(1 + monthlyRatePct, loanMonths) - 1)\n : loanAmount / loanMonths\n : 0;\n const annualDebtService = monthlyEmi * 12;\n const netCashOutlay = downPayment + stampDutyCost;\n const cashFlowAfterDebtService = netAnnualIncome - annualDebtService;\n const cashOnCashReturn = netCashOutlay > 0 ? (cashFlowAfterDebtService / netCashOutlay) * 100 : 0;\n\n const handleDownloadInvestmentReport = () => {\n const lines = [\n `Investment Analysis Report — ${property.title}`,\n `Generated: ${new Date().toISOString().slice(0, 10)}`,\n '',\n `Listing price,${price}`,\n `Expected monthly rent,${monthlyRent}`,\n `Monthly holding costs,${monthlyHoldingCosts}`,\n `Gross rental yield,${grossYield.toFixed(2)}%`,\n `Net rental yield,${netYield.toFixed(2)}%`,\n `Appreciation rate (input),${(appreciationRate * 100).toFixed(2)}%`,\n `Projected value (5yr),${projectedValue5yr}`,\n `Projected ROI (5yr, unleveraged),${projectedRoi.toFixed(2)}%`,\n '',\n `Stamp duty & registration included,${includeStampDuty ? 'Yes' : 'No'}`,\n `Stamp duty rate,${stampDutyPct}%`,\n `Stamp duty & registration cost,${stampDutyCost.toFixed(0)}`,\n '',\n `Financing included,${includeFinancing ? 'Yes' : 'No'}`,\n ...(includeFinancing\n ? [\n `Down payment (${downPaymentPct}%),${downPayment.toFixed(0)}`,\n `Loan amount,${loanAmount.toFixed(0)}`,\n `Loan rate,${(loanAnnualRate * 100).toFixed(2)}%`,\n `Loan tenure (years),${loanTenureYears}`,\n `Monthly EMI,${monthlyEmi.toFixed(0)}`,\n `Annual debt service,${annualDebtService.toFixed(0)}`,\n ]\n : []),\n `Net cash outlay,${netCashOutlay.toFixed(0)}`,\n `Cash-on-cash return,${cashOnCashReturn.toFixed(2)}%`,\n '',\n 'This is not financial advice. Consult a licensed financial advisor before investing.',\n ];\n const blob = new Blob([lines.join('\\n')], { type: 'text/csv;charset=utf-8;' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = `${property.id}-investment-analysis.csv`;\n link.click();\n URL.revokeObjectURL(url);\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <Breadcrumbs items={breadcrumbs} />\n\n {/* Header */}\n <div className=\"flex flex-wrap items-center gap-3\">\n <button\n onClick={() => navigate('../properties')}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-1.5 text-sm text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n Back\n </button>\n <StatusBadge\n label={property.status.replace('_', ' ')}\n variant={statusVariantMap[property.status] ?? 'default'}\n dot\n />\n {property.verificationStatus === 'verified' && <StatusBadge label=\"Verified\" variant=\"success\" dot />}\n {property.price.negotiable && <StatusBadge label=\"Negotiable\" variant=\"info\" />}\n <div className=\"ml-auto flex items-center gap-2\">\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={openEdit}>\n <Pencil className=\"mr-1.5 h-4 w-4\" />\n Edit\n </Button>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => setDeleteOpen(true)}>\n <Trash2 className=\"mr-1.5 h-4 w-4\" />\n Delete\n </Button>\n </div>\n </div>\n\n <PagePurpose className=\"max-w-3xl\">\n Everything you need to evaluate this property in one place — photos, specifications, amenities, and location.\n Use it to shortlist the property, schedule a viewing, or make an offer.\n </PagePurpose>\n\n <NextSteps\n storageKey=\"housingvista-property-detail\"\n steps={[\n {\n id: 'schedule',\n label: 'Schedule a viewing',\n description: 'Book a time to see the property in person or virtually.',\n onClick: () => setViewingOpen(true),\n },\n {\n id: 'offer',\n label: 'Make an offer',\n description: 'Submit a price and let the owner respond.',\n onClick: () => {\n setOfferExpires(defaultOfferExpiry());\n setOfferOpen(true);\n },\n },\n {\n id: 'location',\n label: 'Explore the location',\n description: 'See the neighborhood, nearby landmarks, and map.',\n onClick: () => setActiveTab('location'),\n },\n ]}\n />\n\n {/* Image Gallery */}\n <div className=\"space-y-3\">\n <div className=\"relative overflow-hidden rounded-xl border border-border-subtle bg-bg-sunken\">\n {property.images.length > 0 ? (\n <img\n src={property.images[currentImageIndex]?.url}\n alt={property.images[currentImageIndex]?.title ?? property.title}\n className=\"h-80 w-full object-cover sm:h-[26rem]\"\n />\n ) : (\n <div className=\"flex h-80 w-full flex-col items-center justify-center gap-3 bg-gradient-to-br from-[var(--color-action-primary-bg)]/12 via-bg-sunken to-[var(--color-accent-blue)]/12 text-text-secondary/70 sm:h-[26rem]\">\n <Building className=\"h-12 w-12\" />\n <span className=\"text-sm font-medium tracking-wide\">No photos yet</span>\n </div>\n )}\n\n {property.images.length > 1 && (\n <>\n <button\n onClick={prevImage}\n aria-label=\"Previous photo\"\n className=\"absolute left-4 top-1/2 -translate-y-1/2 rounded-full bg-bg-overlay/70 p-2 text-text-inverse transition-colors hover:bg-bg-overlay\"\n >\n <ChevronLeft className=\"h-5 w-5\" />\n </button>\n <button\n onClick={nextImage}\n aria-label=\"Next photo\"\n className=\"absolute right-4 top-1/2 -translate-y-1/2 rounded-full bg-bg-overlay/70 p-2 text-text-inverse transition-colors hover:bg-bg-overlay\"\n >\n <ChevronRight className=\"h-5 w-5\" />\n </button>\n </>\n )}\n\n {/* Verified badge overlay */}\n {property.verificationStatus === 'verified' && (\n <div className=\"absolute left-4 top-4 inline-flex items-center gap-1.5 rounded-full bg-status-success-bg-subtle px-3 py-1 text-xs font-semibold text-status-success-text shadow-elevation-1 backdrop-blur-sm\">\n <BadgeCheck className=\"h-4 w-4\" />\n Verified listing\n </div>\n )}\n\n <div className=\"absolute right-4 top-4 flex gap-2\">\n <button\n onClick={toggleShortlist}\n disabled={savingShortlist || removingShortlist}\n aria-label={isShortlisted ? 'Remove from shortlist' : 'Save to shortlist'}\n className=\"rounded-full bg-bg-surface/85 p-2 shadow-elevation-1 backdrop-blur-sm transition-colors hover:bg-bg-surface disabled:opacity-60\"\n >\n <Heart\n className={cn(\n 'h-5 w-5',\n isShortlisted ? 'fill-status-error-text text-status-error-text' : 'text-text-secondary'\n )}\n />\n </button>\n <button\n onClick={handleShare}\n aria-label=\"Share this listing\"\n className=\"rounded-full bg-bg-surface/85 p-2 shadow-elevation-1 backdrop-blur-sm transition-colors hover:bg-bg-surface\"\n >\n <Share2 className=\"h-5 w-5 text-text-secondary\" />\n </button>\n </div>\n\n {property.images.length > 0 && (\n <div className=\"absolute bottom-4 right-4\">\n <span className=\"rounded-md bg-bg-overlay/70 px-2 py-1 text-xs font-medium text-text-inverse\">\n {currentImageIndex + 1} / {property.images.length}\n </span>\n </div>\n )}\n </div>\n\n {/* Thumbnail strip */}\n {property.images.length > 1 && (\n <div className=\"flex gap-3 overflow-x-auto pb-1\">\n {property.images.map((img, index) => (\n <button\n key={img.id}\n onClick={() => setCurrentImageIndex(index)}\n aria-label={`View photo ${index + 1}`}\n aria-current={index === currentImageIndex}\n className={cn(\n 'h-16 w-24 shrink-0 overflow-hidden rounded-lg border-2 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]',\n index === currentImageIndex\n ? 'border-action-primary-border'\n : 'border-transparent opacity-70 hover:opacity-100'\n )}\n >\n <img src={img.url} alt={img.title ?? `Photo ${index + 1}`} className=\"h-full w-full object-cover\" />\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Main Content Grid */}\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Left: Main content */}\n <div className=\"space-y-6 lg:col-span-2\">\n <EmphasisPanel>\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold text-text-primary\">{property.title}</h1>\n <div className=\"mt-2 flex items-center text-text-secondary\">\n <MapPin className=\"mr-1.5 h-4 w-4 shrink-0\" />\n <span className=\"text-sm\">\n {[property.location.address, property.location.neighborhood, property.location.city]\n .filter(Boolean)\n .join(', ')}\n </span>\n </div>\n </div>\n <div className=\"text-right\">\n <div className=\"text-2xl font-bold text-text-primary\">{formatPrice(property.price)}</div>\n {property.price.pricePerSqft && (\n <div className=\"text-sm text-text-secondary\">{formatCurrency(property.price.pricePerSqft)}/sqft</div>\n )}\n </div>\n </div>\n\n {/* Key Specs — spec cards */}\n <div className=\"mt-6 grid grid-cols-2 gap-3 border-t border-border-subtle pt-6 sm:grid-cols-4\">\n {[\n property.specifications.bedrooms != null && {\n icon: Bed,\n value: String(property.specifications.bedrooms),\n label: property.specifications.bedrooms === 1 ? 'Bedroom' : 'Bedrooms',\n },\n property.specifications.bathrooms != null && {\n icon: Bath,\n value: String(property.specifications.bathrooms),\n label: property.specifications.bathrooms === 1 ? 'Bathroom' : 'Bathrooms',\n },\n {\n icon: Square,\n value: formatNumber(property.specifications.totalArea),\n label: 'sq ft',\n },\n property.specifications.parking != null && property.specifications.parking > 0\n ? {\n icon: Car,\n value: String(property.specifications.parking),\n label: 'Parking',\n }\n : property.specifications.facing\n ? { icon: Compass, value: property.specifications.facing, label: 'Facing' }\n : false,\n ]\n .filter((spec): spec is { icon: LucideIcon; value: string; label: string } => Boolean(spec))\n .map((spec) => {\n const Icon = spec.icon;\n return (\n <div\n key={spec.label}\n className=\"flex flex-col items-center gap-1 rounded-lg border border-border-subtle bg-bg-sunken/40 p-3 text-center\"\n >\n <Icon className=\"h-5 w-5 text-text-secondary\" />\n <span className=\"text-base font-semibold text-text-primary\">{spec.value}</span>\n <span className=\"text-xs text-text-secondary\">{spec.label}</span>\n </div>\n );\n })}\n </div>\n\n {property.description && (\n <div className=\"mt-6 border-t border-border-subtle pt-6\">\n <h3 className=\"mb-3 text-base font-semibold text-text-primary\">Description</h3>\n <p className=\"text-sm leading-relaxed text-text-secondary\">{property.description}</p>\n </div>\n )}\n </EmphasisPanel>\n\n {/* Tabbed Content */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface\">\n <div className=\"border-b border-border-subtle\">\n <nav className=\"flex space-x-6 overflow-x-auto px-6\">\n {tabs.map((tab) => (\n <button\n key={tab.id}\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n 'whitespace-nowrap border-b-2 py-3 text-sm font-medium transition-colors',\n activeTab === tab.id\n ? 'border-action-primary-border text-text-primary'\n : 'border-transparent text-text-secondary hover:text-text-primary'\n )}\n >\n {tab.label}\n </button>\n ))}\n </nav>\n </div>\n\n <div className=\"p-6\">\n {activeTab === 'details' && (\n <div className=\"grid grid-cols-1 gap-6 sm:grid-cols-2\">\n <div>\n <h4 className=\"mb-3 text-sm font-semibold text-text-primary\">Property Information</h4>\n <dl className=\"space-y-2 text-sm\">\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Property Type</dt>\n <dd className=\"font-medium capitalize text-text-primary\">{property.type}</dd>\n </div>\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Category</dt>\n <dd className=\"font-medium capitalize text-text-primary\">{property.category}</dd>\n </div>\n {property.specifications.ageOfProperty != null && (\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Age of Property</dt>\n <dd className=\"font-medium text-text-primary\">\n {property.specifications.ageOfProperty} years\n </dd>\n </div>\n )}\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Furnishing</dt>\n <dd className=\"font-medium capitalize text-text-primary\">\n {property.specifications.furnishingStatus?.replace('_', ' ')}\n </dd>\n </div>\n {property.specifications.facing && (\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Facing</dt>\n <dd className=\"font-medium text-text-primary\">{property.specifications.facing}</dd>\n </div>\n )}\n {property.specifications.floors != null && (\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Floor</dt>\n <dd className=\"font-medium text-text-primary\">\n {property.specifications.floors} of {property.specifications.totalFloors}\n </dd>\n </div>\n )}\n </dl>\n </div>\n <div>\n <h4 className=\"mb-3 text-sm font-semibold text-text-primary\">Area Details</h4>\n <dl className=\"space-y-2 text-sm\">\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Total Area</dt>\n <dd className=\"font-medium text-text-primary\">\n {formatNumber(property.specifications.totalArea)} sqft\n </dd>\n </div>\n {property.specifications.carpetArea && (\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Carpet Area</dt>\n <dd className=\"font-medium text-text-primary\">\n {formatNumber(property.specifications.carpetArea)} sqft\n </dd>\n </div>\n )}\n {property.specifications.builtUpArea && (\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Built-up Area</dt>\n <dd className=\"font-medium text-text-primary\">\n {formatNumber(property.specifications.builtUpArea)} sqft\n </dd>\n </div>\n )}\n {property.price.pricePerSqft && (\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Price per sqft</dt>\n <dd className=\"font-medium text-text-primary\">\n {formatCurrency(property.price.pricePerSqft)}\n </dd>\n </div>\n )}\n </dl>\n </div>\n </div>\n )}\n\n {activeTab === 'amenities' && (\n <div>\n {property.amenities.length > 0 ? (\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-4\">\n {property.amenities.map((amenity) => {\n const Icon = amenityIcon(amenity.name);\n return (\n <div\n key={amenity.id}\n className=\"flex flex-col items-center gap-2 rounded-lg border border-border-subtle bg-bg-sunken/40 p-4 text-center\"\n >\n <span className=\"flex h-10 w-10 items-center justify-center rounded-full bg-status-success-bg-subtle text-status-success-text\">\n <Icon className=\"h-5 w-5\" />\n </span>\n <span className=\"text-sm font-medium text-text-primary\">{amenity.name}</span>\n </div>\n );\n })}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-generic\"\n title=\"No amenities listed\"\n description=\"This property has no amenities recorded yet.\"\n className=\"border-0 bg-transparent p-6\"\n />\n )}\n </div>\n )}\n\n {activeTab === 'location' && (\n <div className=\"space-y-4\">\n {/* Map card — styled placeholder pinned to the listing's locale */}\n <div className=\"relative h-56 overflow-hidden rounded-xl border border-border-subtle bg-bg-sunken\">\n <div\n className=\"absolute inset-0 opacity-60\"\n style={{\n backgroundImage:\n 'linear-gradient(var(--color-border-seam, rgba(120,120,120,.18)) 1px, transparent 1px), linear-gradient(90deg, var(--color-border-seam, rgba(120,120,120,.18)) 1px, transparent 1px)',\n backgroundSize: '32px 32px',\n }}\n />\n <div className=\"absolute left-1/2 top-1/2 flex -translate-x-1/2 -translate-y-1/2 flex-col items-center gap-1 text-center\">\n <span className=\"flex h-11 w-11 items-center justify-center rounded-full bg-action-primary-bg text-action-primary-text shadow-pop\">\n <MapPin className=\"h-5 w-5\" />\n </span>\n <span className=\"mt-1 rounded-md bg-bg-surface/90 px-2 py-0.5 text-sm font-semibold text-text-primary shadow-elevation-1 backdrop-blur-sm\">\n {property.location.neighborhood || property.location.city}\n </span>\n <span className=\"text-xs text-text-secondary\">\n {[property.location.city, property.location.state].filter(Boolean).join(', ')}\n </span>\n </div>\n {property.location.coordinates?.latitude != null &&\n property.location.coordinates?.longitude != null && (\n <a\n href={`https://www.google.com/maps/search/?api=1&query=${property.location.coordinates.latitude},${property.location.coordinates.longitude}`}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"absolute bottom-3 right-3 inline-flex items-center gap-1.5 rounded-md bg-bg-surface/90 px-2.5 py-1.5 text-xs font-medium text-text-primary shadow-elevation-1 backdrop-blur-sm transition-colors hover:bg-bg-surface\"\n >\n <Navigation className=\"h-3.5 w-3.5\" />\n Open in Maps\n </a>\n )}\n </div>\n {property.location.address && (\n <div>\n <div className=\"mb-1 text-xs text-text-secondary\">Full Address</div>\n <div className=\"text-sm font-medium text-text-primary\">{property.location.address}</div>\n </div>\n )}\n <div className=\"grid grid-cols-1 gap-4 text-sm sm:grid-cols-3\">\n <div>\n <div className=\"mb-1 text-xs text-text-secondary\">Neighborhood</div>\n <div className=\"font-medium text-text-primary\">{property.location.neighborhood || '—'}</div>\n </div>\n <div>\n <div className=\"mb-1 text-xs text-text-secondary\">City, State</div>\n <div className=\"font-medium text-text-primary\">\n {property.location.city}, {property.location.state}\n </div>\n </div>\n <div>\n <div className=\"mb-1 text-xs text-text-secondary\">PIN / ZIP</div>\n <div className=\"font-medium text-text-primary\">{property.location.pincode || '—'}</div>\n </div>\n </div>\n\n {property.location.landmarks.length > 0 && (\n <div className=\"border-t border-border-subtle pt-4\">\n <h4 className=\"mb-2 text-xs font-medium text-text-secondary\">Nearby Landmarks</h4>\n <div className=\"flex flex-wrap gap-2\">\n {property.location.landmarks.map((landmark) => (\n <span\n key={landmark}\n className=\"rounded-full bg-bg-sunken px-3 py-1 text-xs text-text-primary\"\n >\n {landmark}\n </span>\n ))}\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* Right Sidebar */}\n <div className=\"space-y-6\">\n {/* Price + Actions — lead panel (mirrors the listing hero) */}\n <div\n id=\"property-actions\"\n className=\"scroll-mt-6 rounded-lg border border-border-subtle bg-bg-surface p-5 shadow-elevation-1 lg:sticky lg:top-6\"\n >\n <div className=\"flex flex-wrap items-baseline gap-x-2 gap-y-1\">\n <span className=\"text-3xl font-bold text-text-primary\">{formatPrice(property.price)}</span>\n {property.price.negotiable && <span className=\"text-sm text-text-secondary\">· Negotiable</span>}\n </div>\n {property.price.pricePerSqft && (\n <p className=\"mt-1 text-sm text-text-secondary\">\n {formatCurrency(property.price.pricePerSqft, property.price.currency)}/sqft\n </p>\n )}\n\n <div className=\"mt-4 space-y-2\">\n <Button\n type=\"button\"\n className=\"w-full justify-center\"\n onClick={() => {\n setOfferExpires(defaultOfferExpiry());\n setOfferOpen(true);\n }}\n >\n <DollarSign className=\"mr-2 h-4 w-4\" />\n Make Offer\n </Button>\n {property.status === 'for_rent' && (\n <>\n <Button\n type=\"button\"\n className=\"w-full justify-center\"\n onClick={() => setRentalOpen(true)}\n disabled={!rentalUnitId}\n >\n <KeyRound className=\"mr-2 h-4 w-4\" />\n Apply to Rent\n </Button>\n {!rentalUnitId && (\n <p className=\"px-1 text-xs text-text-secondary\">\n No rental unit is listed for this property yet — applications open once a unit is added.\n </p>\n )}\n </>\n )}\n <div className=\"grid grid-cols-2 gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"w-full justify-center\"\n onClick={() => setViewingOpen(true)}\n >\n <Calendar className=\"mr-2 h-4 w-4\" />\n Viewing\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"w-full justify-center\"\n onClick={() => setContactOpen(true)}\n >\n <MessageSquare className=\"mr-2 h-4 w-4\" />\n Contact\n </Button>\n </div>\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"w-full justify-center\"\n onClick={toggleShortlist}\n disabled={savingShortlist || removingShortlist}\n >\n <Heart\n className={cn('mr-2 h-4 w-4', isShortlisted && 'fill-status-error-text text-status-error-text')}\n />\n {isShortlisted ? 'Saved to Shortlist' : 'Save to Shortlist'}\n </Button>\n </div>\n\n {property.verificationStatus === 'verified' && (\n <div className=\"mt-4 flex items-center gap-2 border-t border-border-subtle pt-4 text-sm font-medium text-status-success-text\">\n <BadgeCheck className=\"h-4 w-4\" />\n Verified listing\n </div>\n )}\n </div>\n\n {/* Investment analysis — modelled client-side from the listing price */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-5\">\n <div className=\"mb-4 flex items-center gap-2\">\n <Calculator className=\"h-5 w-5 text-text-secondary\" />\n <h3 className=\"text-base font-semibold text-text-primary\">Investment Analysis</h3>\n </div>\n\n {/* Deal parameters */}\n <div className=\"space-y-3\">\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n Expected monthly rent ({property.price.currency})\n </label>\n <input\n type=\"number\"\n min={0}\n value={rentInput}\n onChange={(e) => setRentInput(e.target.value)}\n placeholder={String(monthlyRent)}\n className={inputClass}\n />\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n Monthly costs ({property.price.currency})\n </label>\n <input\n type=\"number\"\n min={0}\n value={costInput}\n onChange={(e) => setCostInput(e.target.value)}\n placeholder={String(monthlyHoldingCosts)}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">Appreciation (%/yr)</label>\n <input\n type=\"number\"\n min={0}\n step={0.5}\n value={appreciationInput}\n onChange={(e) => setAppreciationInput(e.target.value)}\n className={inputClass}\n />\n </div>\n </div>\n <p className=\"text-[11px] text-text-secondary\">\n Costs cover maintenance, tax, insurance, and management.\n </p>\n </div>\n\n {/* Stamp duty / registration + financing toggles (BOFF-3928) */}\n <div className=\"mt-4 space-y-3 border-t border-border-subtle pt-4\">\n <div className=\"flex items-center justify-between gap-3\">\n <label className=\"flex items-center gap-2 text-xs font-medium text-text-secondary\">\n <input\n type=\"checkbox\"\n checked={includeStampDuty}\n onChange={(e) => setIncludeStampDuty(e.target.checked)}\n className=\"h-3.5 w-3.5 rounded border-border-subtle\"\n />\n Include stamp duty & registration\n </label>\n {includeStampDuty && (\n <input\n type=\"number\"\n min={0}\n step={0.5}\n value={stampDutyPctInput}\n onChange={(e) => setStampDutyPctInput(e.target.value)}\n aria-label=\"Stamp duty rate percent\"\n className=\"h-7 w-16 rounded-md border border-border-subtle bg-bg-surface px-2 text-right text-xs text-text-primary\"\n />\n )}\n </div>\n <div className=\"flex items-center justify-between gap-3\">\n <label className=\"flex items-center gap-2 text-xs font-medium text-text-secondary\">\n <input\n type=\"checkbox\"\n checked={includeFinancing}\n onChange={(e) => setIncludeFinancing(e.target.checked)}\n className=\"h-3.5 w-3.5 rounded border-border-subtle\"\n />\n Include financing (loan)\n </label>\n </div>\n {includeFinancing && (\n <div className=\"grid grid-cols-3 gap-2\">\n <div>\n <label className=\"mb-1 block text-[10px] text-text-secondary\">Down payment %</label>\n <input\n type=\"number\"\n min={0}\n max={100}\n value={downPaymentPctInput}\n onChange={(e) => setDownPaymentPctInput(e.target.value)}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1 block text-[10px] text-text-secondary\">Loan rate %</label>\n <input\n type=\"number\"\n min={0}\n step={0.1}\n value={loanRateInput}\n onChange={(e) => setLoanRateInput(e.target.value)}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1 block text-[10px] text-text-secondary\">Tenure (yrs)</label>\n <input\n type=\"number\"\n min={1}\n value={loanTenureInput}\n onChange={(e) => setLoanTenureInput(e.target.value)}\n className={inputClass}\n />\n </div>\n </div>\n )}\n {(includeStampDuty || includeFinancing) && (\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-[11px] text-text-secondary\">\n {includeStampDuty && (\n <span>\n Stamp duty:{' '}\n <span className=\"font-semibold text-text-primary\">\n {formatCompactCurrency(stampDutyCost, property.price.currency)}\n </span>\n </span>\n )}\n {includeFinancing && (\n <span>\n Monthly EMI:{' '}\n <span className=\"font-semibold text-text-primary\">\n {formatCompactCurrency(monthlyEmi, property.price.currency)}\n </span>\n </span>\n )}\n <span>\n Net cash outlay:{' '}\n <span className=\"font-semibold text-text-primary\">\n {formatCompactCurrency(netCashOutlay, property.price.currency)}\n </span>\n </span>\n </div>\n )}\n </div>\n\n {/* Financial projections — yield tiles */}\n <div className=\"mt-4 grid grid-cols-3 gap-2 border-t border-border-subtle pt-4\">\n <div className=\"rounded-lg border border-status-success-border bg-status-success-bg-subtle p-2.5 text-center\">\n <div className=\"text-[11px] font-medium text-status-success-text\">Gross Yield</div>\n <div className=\"mt-0.5 text-lg font-bold text-status-success-text\">{grossYield.toFixed(1)}%</div>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-sunken/40 p-2.5 text-center\">\n <div className=\"text-[11px] font-medium text-text-secondary\">Net Yield</div>\n <div className=\"mt-0.5 text-lg font-bold text-text-primary\">{netYield.toFixed(1)}%</div>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-sunken/40 p-2.5 text-center\">\n <div className=\"text-[11px] font-medium text-text-secondary\">\n {includeFinancing ? 'Cash-on-Cash' : '5-yr ROI'}\n </div>\n <div className=\"mt-0.5 text-lg font-bold text-text-primary\">\n {includeFinancing ? cashOnCashReturn.toFixed(1) : projectedRoi.toFixed(0)}%\n </div>\n </div>\n </div>\n\n {/* Projected value growth */}\n <div className=\"mt-4\">\n <div className=\"mb-1 flex items-center justify-between\">\n <span className=\"text-xs font-medium text-text-secondary\">Projected Value Growth</span>\n <span className=\"text-xs font-semibold text-text-primary\">\n {formatCompactCurrency(projectedValue5yr, property.price.currency)}\n </span>\n </div>\n <div className=\"h-32\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={projection} margin={{ top: 4, right: 4, bottom: 0, left: 0 }}>\n <defs>\n <linearGradient id=\"hvValueGrad\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"5%\" stopColor=\"var(--color-chart-2)\" stopOpacity={0.35} />\n <stop offset=\"95%\" stopColor=\"var(--color-chart-2)\" stopOpacity={0} />\n </linearGradient>\n </defs>\n <XAxis dataKey=\"label\" tick={{ fontSize: 10 }} axisLine={false} tickLine={false} />\n <YAxis hide domain={['dataMin', 'dataMax']} />\n <Tooltip\n formatter={(value: number) => [formatCompactCurrency(value, property.price.currency), 'Value']}\n labelClassName=\"text-text-primary\"\n />\n <Area\n type=\"monotone\"\n dataKey=\"value\"\n stroke=\"var(--color-chart-2)\"\n fill=\"url(#hvValueGrad)\"\n strokeWidth={2}\n />\n </AreaChart>\n </ResponsiveContainer>\n </div>\n <p className=\"mt-1 text-[11px] text-text-secondary\">\n Projection based on your inputs and market appreciation. Consult a financial advisor before investing.\n </p>\n </div>\n\n <div className=\"mt-4 flex gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"flex-1 justify-center\"\n onClick={handleTrackInvestment}\n disabled={creatingInvestment}\n >\n <TrendingUp className=\"mr-2 h-4 w-4\" />\n {creatingInvestment ? 'Adding…' : 'Track as Investment'}\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"justify-center\"\n onClick={handleDownloadInvestmentReport}\n aria-label=\"Download investment analysis report\"\n >\n <Download className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n\n {/* Property Stats (real, derived) */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-5\">\n <h3 className=\"mb-4 text-base font-semibold text-text-primary\">At a Glance</h3>\n <div className=\"space-y-3 text-sm\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-text-secondary\">Status</span>\n <StatusBadge\n label={property.status.replace('_', ' ')}\n variant={statusVariantMap[property.status] ?? 'default'}\n />\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-text-secondary\">Verification</span>\n <span className=\"font-medium capitalize text-text-primary\">{property.verificationStatus}</span>\n </div>\n {property.reraVerificationStatus !== 'not_applicable' && (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-text-secondary\">RERA status</span>\n <span className=\"flex items-center gap-1.5 font-medium capitalize text-text-primary\">\n {property.reraVerificationStatus === 'verified' && (\n <BadgeCheck className=\"h-4 w-4 text-status-success-text\" />\n )}\n {property.reraVerificationStatus.replace('_', ' ')}\n </span>\n </div>\n )}\n {property.reraRegistrationNo && (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-text-secondary\">RERA reg. no.</span>\n <span className=\"font-medium text-text-primary\">{property.reraRegistrationNo}</span>\n </div>\n )}\n <div className=\"flex items-center justify-between\">\n <span className=\"text-text-secondary\">Listed</span>\n <span className=\"font-medium text-text-primary\">{formatDate(String(property.createdAt))}</span>\n </div>\n </div>\n {property.reraVerificationStatus === 'pending' && (\n <div className=\"mt-4 flex gap-2 border-t border-border-subtle pt-4\">\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"flex-1 justify-center\"\n disabled={reviewingRera}\n onClick={() => handleReraReview('verified')}\n >\n Verify RERA\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"flex-1 justify-center\"\n disabled={reviewingRera}\n onClick={() => handleReraReview('rejected')}\n >\n Reject\n </Button>\n </div>\n )}\n </div>\n\n {/* Similar Properties */}\n {similarProperties.length > 0 && (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-5\">\n <h3 className=\"mb-4 text-base font-semibold text-text-primary\">Similar Properties</h3>\n <div className=\"space-y-3\">\n {similarProperties.map((sp) => (\n <button\n key={sp.id}\n onClick={() => navigate(`../properties/${sp.id}`)}\n className=\"flex w-full items-start gap-3 rounded-lg border border-border-subtle p-3 text-left transition-colors hover:bg-bg-sunken/50\"\n >\n {sp.images[0] && (\n <img src={sp.images[0].url} alt={sp.title} className=\"h-14 w-14 rounded object-cover\" />\n )}\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-sm font-medium text-text-primary\">{sp.title}</div>\n <div className=\"text-sm font-semibold text-text-primary\">{formatCurrency(sp.price.amount)}</div>\n <div className=\"truncate text-xs text-text-secondary\">\n {[sp.location.neighborhood, sp.location.city].filter(Boolean).join(', ')}\n </div>\n </div>\n </button>\n ))}\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Q&A / reviews — real EntityComments-backed thread */}\n <ReviewsSection entityId={property.id} entityType=\"housingvista-property\" />\n\n {/* Contact-owner conversation dialog — controlled at page root (same\n reliable pattern as the Make Offer dialog) */}\n <ContactOwnerDialog\n open={contactOpen}\n onOpenChange={setContactOpen}\n entityId={property.id}\n entityType=\"housingvista-property\"\n title={property.title}\n pagePath={location.pathname}\n heading=\"Contact owner\"\n description={`Ask a question or start a conversation about ${property.title}.`}\n />\n\n {/* Apply to Rent dialog */}\n <ResponsiveDialog open={rentalOpen} onOpenChange={setRentalOpen}>\n <ResponsiveDialogContent className=\"sm:max-w-2xl\">\n <form onSubmit={handleSubmitRental}>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Apply to rent</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Submit a rental application for {property.title}. The owner will review and respond.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"grid grid-cols-1 gap-4 py-2 sm:grid-cols-[1fr_16rem]\">\n <div className=\"space-y-3\">\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Full name *</label>\n <input\n type=\"text\"\n required\n value={applicantName}\n onChange={(e) => setApplicantName(e.target.value)}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Email *</label>\n <input\n type=\"email\"\n required\n value={applicantEmail}\n onChange={(e) => setApplicantEmail(e.target.value)}\n className={inputClass}\n />\n </div>\n </div>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Phone</label>\n <input\n type=\"tel\"\n value={applicantPhone}\n onChange={(e) => setApplicantPhone(e.target.value)}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">\n Monthly income ({property.price.currency})\n </label>\n <input\n type=\"number\"\n min={0}\n value={monthlyIncome}\n onChange={(e) => setMonthlyIncome(e.target.value)}\n className={inputClass}\n />\n </div>\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Preferred move-in date</label>\n <input\n type=\"date\"\n value={moveInDate}\n onChange={(e) => setMoveInDate(e.target.value)}\n className={inputClass}\n />\n </div>\n </div>\n\n {/* Rental summary — what you are actually applying for. Every value\n comes off the rental unit / listing rows this page already\n loaded; nothing here is estimated. */}\n <aside className=\"rounded-lg border border-border-subtle bg-bg-sunken/40 p-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Rental summary</h3>\n <div className=\"mt-3 flex items-start gap-3\">\n {property.images[0]?.url && (\n <img\n src={property.images[0].url}\n alt=\"\"\n aria-hidden\n className=\"h-14 w-14 shrink-0 rounded-md object-cover\"\n />\n )}\n <div className=\"min-w-0\">\n <p className=\"text-sm font-medium text-text-primary\">{property.title}</p>\n <p className=\"truncate text-xs text-text-secondary\">\n {[property.location.neighborhood, property.location.city].filter(Boolean).join(', ')}\n </p>\n </div>\n </div>\n\n {rentalUnit ? (\n <>\n <dl className=\"mt-3 grid grid-cols-2 gap-3 border-t border-border-subtle pt-3\">\n <div>\n <dt className=\"text-xs text-text-secondary\">Rent</dt>\n <dd className=\"text-sm font-semibold text-text-primary\">\n {formatCurrency(rentalUnit.monthlyRent)}/mo\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-secondary\">Deposit</dt>\n <dd className=\"text-sm font-semibold text-text-primary\">\n {rentalUnit.securityDeposit ? formatCurrency(rentalUnit.securityDeposit) : '—'}\n </dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-secondary\">Unit</dt>\n <dd className=\"text-sm font-medium text-text-primary\">{rentalUnit.unitNumber}</dd>\n </div>\n <div>\n <dt className=\"text-xs text-text-secondary\">Availability</dt>\n <dd className=\"mt-0.5\">\n <StatusBadge\n label={rentalUnitStatusLabel(rentalUnit.status)}\n variant={rentalUnitStatusVariant(rentalUnit.status)}\n />\n </dd>\n </div>\n </dl>\n {(rentalUnit.status === 'occupied' || rentalUnit.status === 'notice_period') &&\n rentalUnit.leaseEnd && (\n <p className=\"mt-2 text-xs text-text-secondary\">\n Current lease ends {formatDate(rentalUnit.leaseEnd)}\n </p>\n )}\n </>\n ) : (\n <p className=\"mt-3 border-t border-border-subtle pt-3 text-xs text-text-secondary\">\n No rental unit is listed for this property yet, so rent and deposit are not available.\n </p>\n )}\n\n {property.amenities.length > 0 && (\n <div className=\"mt-3 border-t border-border-subtle pt-3\">\n <p className=\"text-xs text-text-secondary\">Amenities</p>\n <ul className=\"mt-1.5 space-y-1.5\">\n {property.amenities.slice(0, 5).map((amenity) => {\n const Icon = amenityIcon(amenity.name);\n return (\n <li key={amenity.id} className=\"flex items-center gap-2 text-sm text-text-primary\">\n <Icon className=\"h-4 w-4 shrink-0 text-text-secondary\" />\n <span className=\"truncate\">{amenity.name}</span>\n </li>\n );\n })}\n </ul>\n {property.amenities.length > 5 && (\n <p className=\"mt-1.5 text-xs text-text-secondary\">\n +{property.amenities.length - 5} more on the listing\n </p>\n )}\n </div>\n )}\n </aside>\n </div>\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setRentalOpen(false)}>\n Cancel\n </Button>\n <Button type=\"submit\" disabled={submittingRental || !rentalUnitId}>\n {submittingRental ? 'Submitting…' : 'Submit application'}\n </Button>\n </ResponsiveDialogFooter>\n </form>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* Schedule Viewing dialog */}\n <ResponsiveDialog open={viewingOpen} onOpenChange={setViewingOpen}>\n <ResponsiveDialogContent className=\"sm:max-w-md\">\n <form onSubmit={handleBookViewing}>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Schedule a viewing</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>Pick a date and time to see {property.title}.</ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"space-y-3 py-2\">\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Date & time *</label>\n <input\n type=\"datetime-local\"\n required\n value={viewingDate}\n onChange={(e) => setViewingDate(e.target.value)}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Type</label>\n <select\n value={viewingType}\n onChange={(e) => setViewingType(e.target.value as 'in_person' | 'virtual')}\n className={inputClass}\n >\n <option value=\"in_person\">In person</option>\n <option value=\"virtual\">Virtual</option>\n </select>\n </div>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <input\n type=\"text\"\n placeholder=\"Your name\"\n value={attendeeName}\n onChange={(e) => setAttendeeName(e.target.value)}\n className={inputClass}\n />\n <input\n type=\"email\"\n placeholder=\"Your email\"\n value={attendeeEmail}\n onChange={(e) => setAttendeeEmail(e.target.value)}\n className={inputClass}\n />\n </div>\n <textarea\n placeholder=\"Notes (optional)\"\n rows={2}\n value={viewingNotes}\n onChange={(e) => setViewingNotes(e.target.value)}\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setViewingOpen(false)}>\n Cancel\n </Button>\n <Button type=\"submit\" disabled={bookingViewing || !viewingDate}>\n {bookingViewing ? 'Booking…' : 'Request viewing'}\n </Button>\n </ResponsiveDialogFooter>\n </form>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* Make Offer dialog */}\n <ResponsiveDialog open={offerOpen} onOpenChange={setOfferOpen}>\n <ResponsiveDialogContent className=\"sm:max-w-md\">\n <form onSubmit={handleSubmitOffer}>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Make an offer</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>Listing price is {formatPrice(property.price)}.</ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"space-y-3 py-2\">\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">\n Your offer ({property.price.currency}) *\n </label>\n <input\n type=\"number\"\n required\n min={1}\n value={offerAmount}\n onChange={(e) => setOfferAmount(e.target.value)}\n placeholder=\"Enter amount\"\n className={inputClass}\n />\n </div>\n <textarea\n placeholder=\"Message to the owner (optional)\"\n rows={3}\n value={offerNotes}\n onChange={(e) => setOfferNotes(e.target.value)}\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n <div>\n <label htmlFor=\"offer-expires\" className=\"mb-1.5 block text-sm font-medium text-text-primary\">\n Valid until (optional)\n </label>\n <input\n id=\"offer-expires\"\n type=\"datetime-local\"\n value={offerExpires}\n onChange={(e) => setOfferExpires(e.target.value)}\n className={inputClass}\n />\n <p className=\"mt-1 text-xs text-text-secondary\">\n The offer becomes non-actionable after this time. Clear the field for no expiry.\n </p>\n </div>\n </div>\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setOfferOpen(false)}>\n Cancel\n </Button>\n <Button type=\"submit\" disabled={submittingOffer}>\n {submittingOffer ? 'Submitting…' : 'Submit offer'}\n </Button>\n </ResponsiveDialogFooter>\n </form>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* Edit dialog */}\n <ResponsiveDialog open={editOpen} onOpenChange={(open) => !open && !updatingProperty && setEditOpen(false)}>\n <ResponsiveDialogContent className=\"sm:max-w-2xl\">\n <form onSubmit={handleEdit}>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Edit property</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Update the listing details — basics, location, specifications and pricing. Photos are managed separately\n from the gallery.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"max-h-[65vh] space-y-6 overflow-y-auto py-2 pr-1\">\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Basics</h3>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Title *</label>\n <input\n type=\"text\"\n required\n value={editForm.title}\n onChange={(e) => updateEditForm({ title: e.target.value })}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Description</label>\n <textarea\n rows={3}\n value={editForm.description}\n onChange={(e) => updateEditForm({ description: e.target.value })}\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Status</label>\n <select\n value={editForm.status}\n onChange={(e) => updateEditForm({ status: e.target.value as PropertyStatus })}\n className={inputClass}\n >\n {statusOptions.map((s) => (\n <option key={s.value} value={s.value}>\n {s.label}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Type</label>\n <select\n value={editForm.type}\n onChange={(e) => updateEditForm({ type: e.target.value as PropertyType })}\n className={inputClass}\n >\n {propertyTypeOptions.map((t) => (\n <option key={t.value} value={t.value}>\n {t.label}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Category</label>\n <select\n value={editForm.category}\n onChange={(e) => updateEditForm({ category: e.target.value as PropertyCategory })}\n className={inputClass}\n >\n {propertyCategoryOptions.map((c) => (\n <option key={c.value} value={c.value}>\n {c.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n </section>\n\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Location</h3>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <div className=\"sm:col-span-2\">\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Address</label>\n <input\n type=\"text\"\n value={editForm.address}\n onChange={(e) => updateEditForm({ address: e.target.value })}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">City *</label>\n <input\n type=\"text\"\n required\n value={editForm.city}\n onChange={(e) => updateEditForm({ city: e.target.value })}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">State *</label>\n <input\n type=\"text\"\n required\n value={editForm.state}\n onChange={(e) => updateEditForm({ state: e.target.value })}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Country</label>\n <input\n type=\"text\"\n value={editForm.country}\n onChange={(e) => updateEditForm({ country: e.target.value })}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Pincode</label>\n <input\n type=\"text\"\n value={editForm.pincode}\n onChange={(e) => updateEditForm({ pincode: e.target.value })}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Neighborhood</label>\n <input\n type=\"text\"\n value={editForm.neighborhood}\n onChange={(e) => updateEditForm({ neighborhood: e.target.value })}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Landmarks</label>\n <input\n type=\"text\"\n value={editForm.landmarks}\n onChange={(e) => updateEditForm({ landmarks: e.target.value })}\n placeholder=\"Comma-separated\"\n className={inputClass}\n />\n </div>\n </div>\n <div>\n <span className=\"mb-1.5 block text-sm font-medium text-text-primary\">Map location</span>\n <CoordinatePicker\n value={editForm.coordinates}\n onChange={(coords) => updateEditForm({ coordinates: coords })}\n />\n </div>\n </section>\n\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Specifications</h3>\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n {numericFields.map((field) => (\n <div key={field.key}>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">{field.label}</label>\n <input\n type=\"number\"\n min={0}\n step={field.step}\n required={field.required}\n value={editForm[field.key]}\n onChange={(e) => updateEditForm({ [field.key]: e.target.value })}\n className={inputClass}\n />\n </div>\n ))}\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Furnishing</label>\n <select\n value={editForm.furnishingStatus}\n onChange={(e) => updateEditForm({ furnishingStatus: e.target.value })}\n className={inputClass}\n >\n {furnishingOptions.map((f) => (\n <option key={f.value} value={f.value}>\n {f.label}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Facing</label>\n <select\n value={editForm.facing}\n onChange={(e) => updateEditForm({ facing: e.target.value })}\n className={inputClass}\n >\n <option value=\"\">— (unset)</option>\n {facingOptions.map((f) => (\n <option key={f} value={f}>\n {f}\n </option>\n ))}\n </select>\n </div>\n </div>\n </section>\n\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Pricing</h3>\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Price *</label>\n <input\n type=\"number\"\n min={0}\n required\n value={editForm.price}\n onChange={(e) => updateEditForm({ price: e.target.value })}\n className={inputClass}\n />\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Price type</label>\n <select\n value={editForm.priceType}\n onChange={(e) => updateEditForm({ priceType: e.target.value })}\n className={inputClass}\n >\n {priceTypeOptions.map((t) => (\n <option key={t.value} value={t.value}>\n {t.label}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Price period</label>\n <select\n value={editForm.pricePeriod}\n onChange={(e) => updateEditForm({ pricePeriod: e.target.value })}\n className={inputClass}\n >\n {pricePeriodOptions.map((t) => (\n <option key={t.value} value={t.value}>\n {t.label}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Currency</label>\n <select\n value={editForm.currency}\n onChange={(e) => updateEditForm({ currency: e.target.value })}\n className={inputClass}\n >\n {currencyOptions.map((c) => (\n <option key={c.value} value={c.value}>\n {c.label}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Price / sqft</label>\n <input\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={editForm.pricePerSqft}\n onChange={(e) => updateEditForm({ pricePerSqft: e.target.value })}\n className={inputClass}\n />\n </div>\n <label className=\"flex items-end gap-2 pb-2.5 text-sm font-medium text-text-primary\">\n <input\n type=\"checkbox\"\n checked={editForm.negotiable}\n onChange={(e) => updateEditForm({ negotiable: e.target.checked })}\n className=\"h-4 w-4 rounded border-border-subtle\"\n />\n Negotiable\n </label>\n </div>\n </section>\n\n <section className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Amenities</h3>\n <div className=\"flex flex-wrap gap-2\">\n {amenityOptions.map((amenity) => {\n const Icon = amenity.icon;\n const selected = editForm.amenities.includes(amenity.id);\n return (\n <button\n key={amenity.id}\n type=\"button\"\n aria-pressed={selected}\n onClick={() =>\n updateEditForm({\n amenities: selected\n ? editForm.amenities.filter((a) => a !== amenity.id)\n : [...editForm.amenities, amenity.id],\n })\n }\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full border px-3 py-1.5 text-xs font-medium transition-colors',\n selected\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-surface text-text-secondary hover:bg-bg-sunken hover:text-text-primary'\n )}\n >\n <Icon className=\"h-3.5 w-3.5\" />\n {amenity.label}\n </button>\n );\n })}\n </div>\n </section>\n </div>\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setEditOpen(false)} disabled={updatingProperty}>\n Cancel\n </Button>\n <Button type=\"submit\" disabled={updatingProperty}>\n {updatingProperty ? 'Saving…' : 'Save changes'}\n </Button>\n </ResponsiveDialogFooter>\n </form>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n\n {/* Delete confirm dialog */}\n <ResponsiveDialog open={deleteOpen} onOpenChange={setDeleteOpen}>\n <ResponsiveDialogContent className=\"sm:max-w-md\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Delete this property?</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n {property.title} will be permanently removed. This cannot be undone.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setDeleteOpen(false)}>\n Cancel\n </Button>\n <Button type=\"button\" variant=\"destructive\" onClick={handleDelete} disabled={deletingProperty}>\n {deletingProperty ? 'Deleting…' : 'Delete property'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </div>\n );\n};\n"],"mappings":"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"}
|