diff --git a/build_log_sky.txt b/build_log_sky.txt new file mode 100644 index 0000000..8adda13 --- /dev/null +++ b/build_log_sky.txt @@ -0,0 +1,34 @@ + +> antigravity_dev@0.1.0 build +> next build && node script/copy-server-config.cjs + +[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` + ▲ Next.js 16.0.3 (Turbopack) + + Creating an optimized production build ... +[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` + ✓ Compiled successfully in 2.8s + Running TypeScript ... + Collecting page data using 11 workers ... +[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` +[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` +[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` +[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` +[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` +[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` +[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` +[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` +[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` +[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` +[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` + Generating static pages using 11 workers (0/17) ... +[baseline-browser-mapping] The data in this module is over two months old. To ensure accurate Baseline data, please update: `npm i baseline-browser-mapping@latest -D` + Generating static pages using 11 workers (4/17) + Generating static pages using 11 workers (8/17) +Error occurred prerendering page "/residential-real-estate/godrej-woods". Read more: https://nextjs.org/docs/messages/prerender-error +TypeError: Cannot read properties of undefined (reading 'id') + at q (C:\Users\start\sky-and-soil\.next\server\chunks\ssr\_997a77a8._.js:17:32367) { + digest: '1668255941' +} +Export encountered an error on /residential-real-estate/[slug]/page: /residential-real-estate/godrej-woods, exiting the build. + ⨯ Next.js build worker exited with code: 1 and signal: null diff --git a/package.json b/package.json index 131ac59..582fbc3 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "private": true, "scripts": { "dev": "next dev", - "build": "next build", + "build": "next build && node script/copy-server-config.cjs", "start": "next start", "lint": "eslint" }, @@ -21,7 +21,6 @@ "react-dom": "19.2.0", "react-google-recaptcha": "^3.1.0", "react-leaflet": "^5.0.0", - "selenium-webdriver": "^4.38.0", "sitemap": "^9.0.0", "tailwindcss-animate": "^1.0.7", "xml2js": "^0.6.2" @@ -34,6 +33,7 @@ "eslint": "^9", "eslint-config-next": "16.0.3", "tailwindcss": "^4", + "selenium-webdriver": "^4.38.0", "typescript": "^5" } -} +} \ No newline at end of file diff --git a/public/assets/images/map-placeholder.webp b/public/assets/images/map-placeholder.webp new file mode 100644 index 0000000..e0fc16c Binary files /dev/null and b/public/assets/images/map-placeholder.webp differ diff --git a/public/web.config b/public/web.config new file mode 100644 index 0000000..71ac777 --- /dev/null +++ b/public/web.config @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/script/copy-server-config.cjs b/script/copy-server-config.cjs new file mode 100644 index 0000000..a10734b --- /dev/null +++ b/script/copy-server-config.cjs @@ -0,0 +1,30 @@ +const fs = require('fs'); +const path = require('path'); + +// Configuration +const PUBLIC_DIR = path.join(__dirname, '..', 'public'); +const OUT_DIR = path.join(__dirname, '..', 'out'); +const FILES_TO_COPY = ['.htaccess', 'web.config']; + +// Ensure out directory exists +if (!fs.existsSync(OUT_DIR)) { + console.warn('⚠ out directory does not exist. Make sure "next build" (static export) has run.'); + process.exit(1); +} + +FILES_TO_COPY.forEach(filename => { + const source = path.join(PUBLIC_DIR, filename); + const destination = path.join(OUT_DIR, filename); + + try { + if (fs.existsSync(source)) { + fs.copyFileSync(source, destination); + console.log(`✓ ${filename} copied to out directory`); + } else { + console.warn(`⚠ ${filename} not found in public directory`); + } + } catch (error) { + console.error(`Error copying ${filename}:`, error.message); + process.exit(1); + } +}); diff --git a/src/app/loading.tsx b/src/app/loading.tsx new file mode 100644 index 0000000..db27343 --- /dev/null +++ b/src/app/loading.tsx @@ -0,0 +1,33 @@ +export default function Loading() { + return ( +
+
+ +
+ ); +} diff --git a/src/components/PropertyDetailClient.tsx b/src/components/PropertyDetailClient.tsx index 96a7548..b08968f 100644 --- a/src/components/PropertyDetailClient.tsx +++ b/src/components/PropertyDetailClient.tsx @@ -27,10 +27,10 @@ const AnimateSection = ({ children, className, id, direction = "left" }: { child const variants = { hidden: { opacity: 0, - x: direction === "left" ? -50 : direction === "right" ? 50 : 0, - y: direction === "up" ? 50 : direction === "down" ? -50 : 0 + scale: direction === "left" || direction === "right" ? 0.95 : 1, + y: direction === "up" ? 30 : direction === "down" ? -30 : 0 }, - visible: { opacity: 1, x: 0, y: 0 } + visible: { opacity: 1, scale: 1, y: 0 } }; return ( @@ -48,6 +48,49 @@ const AnimateSection = ({ children, className, id, direction = "left" }: { child ); }; +const getOverviewIcon = (type: string) => { + switch (type) { + case "land": + return ( + + + + ); + case "metro": + return ( + + + + ); + case "road": + return ( + + + + ); + case "openArea": + return ( + + + + ); + case "density": + return ( + + + + ); + case "clubhouse": + return ( + + + + ); + default: + return null; + } +}; + const ConnectivityMap = dynamic(() => import('./ConnectivityMap'), { @@ -154,7 +197,7 @@ export default function PropertyDetailClient({ property }: { property: Property const [isLightboxOpen, setIsLightboxOpen] = useState(false); - const [activeFloorPlan, setActiveFloorPlan] = useState("30 x 40"); + const [isAmenitiesModalOpen, setIsAmenitiesModalOpen] = useState(false); @@ -245,187 +288,72 @@ export default function PropertyDetailClient({ property }: { property: Property const handleCompareToggle = () => { - if (isCompared) { - removeFromCompare(property.id); - setAlert({ - show: true, - type: 'success', - message: 'Removed from compare list' - }); - } else { - addToCompare(property); - setAlert({ - show: true, - type: 'success', - message: 'Added to compare list' - }); - } - }; - - - const faqData: Record = { - - 'Project Details': [ - - { question: "What is the total land area?", answer: "The project is spread across 5 acres of prime land." }, - - { question: "How many units are there?", answer: "There are a total of 450 luxury units." }, - - { question: "What is the completion date?", answer: "The project is expected to be completed by Dec 2026." }, - - { question: "Is it RERA approved?", answer: "Yes, the project is fully RERA approved." }, - - ], - - 'Location & Connectivity': [ - - { question: "How far is the nearest metro station?", answer: "The nearest metro station is just 2km away." }, - - { question: "Are there schools nearby?", answer: "Yes, there are several international schools within a 3km radius." }, - - { question: "How is the road connectivity?", answer: "The project is well-connected to the Outer Ring Road and Whitefield." }, - - { question: "Is there a hospital nearby?", answer: "Manipal Hospital is located 1.5km from the project." }, - - ], - - 'Price & Booking': [ - - { question: "What is the booking amount?", answer: "The booking amount is 10% of the total sale value." }, - - { question: "Are there any bank offers?", answer: "Yes, we have tie-ups with SBI, HDFC, and ICICI for home loans." }, - - { question: "What are the additional charges?", answer: "Additional charges include GST, registration, and maintenance deposits." }, - - { question: "Is the price negotiable?", answer: "Prices are competitive, but we can discuss offers on table." }, - - ], - - 'Services': [ - - { question: "What is Service Guided Home Buying (GHB) and Peace of Mind (POM) service?", answer: "Service Guided Home Buying (GHB) and Peace of Mind (POM) service provide end-to-end assistance in your home buying journey, ensuring a hassle-free and transparent experience from selection to possession." }, - - { question: "Why should I get an advisor to help me buy a property?", answer: "An advisor acts as your unbiased partner, helping you navigate the complex real estate market, verify documents, negotiate prices, and avoid common pitfalls." }, - - { question: "Which type of properties do you help with?", answer: "We assist with all types of residential properties including apartments, villas, plots, and gated communities across various budget segments." }, - - { question: "Can I buy homes via Propsoch?", answer: "Yes, you can explore, shortlist, and book homes directly through Propsoch with the help of our expert advisors." }, - - { question: "How do I know I am seeing all possible options in the market?", answer: "Our database covers 99% of the market inventory, and our advisors provide unbiased recommendations based on your specific requirements, not just what we want to sell." }, - - { question: "How can I be assured that I am paying the right price?", answer: "We provide data-backed market analysis and comparative pricing reports to ensure you get the best value for your investment." }, - - { question: "What other services can Propsoch help me with after booking?", answer: "Post-booking, we assist with legal verification, loan processing, registration, and even interior design and property management services." }, - - { question: "What is the cost of the services?", answer: "Our basic advisory services are free for home buyers. We charge a nominal fee only for premium services like legal verification and dedicated relationship management." }, - - ] - + // Helper for icons + const getAmenityIcon = (name: string) => { + switch (name) { + case "Gym - Indoor": + return ; + case "Gym - Outdoor": + case "Running Track": + return ; + case "Kids Play Area": + return ; + case "Amphitheatre": + return ; + case "Cafe/Restaurant": + return ; + case "Badminton": + return ; + case "Basketball": + return ; + case "Cricket Ground": + return ; + case "Cricket Pitch": + return ; + default: + return ; + } }; + const faqData = property.faq || {}; + const floorPlans = property.floorPlans || []; + // Initialize activeFloorPlan with the first plan's ID if available + const [activeFloorPlan, setActiveFloorPlan] = useState(""); + + useEffect(() => { + if (floorPlans.length > 0 && !activeFloorPlan) { + setActiveFloorPlan(floorPlans[0].id); + } + }, [floorPlans, activeFloorPlan]); + + const activePlanDetails = floorPlans.find(plan => plan.id === activeFloorPlan) || (floorPlans.length > 0 ? floorPlans[0] : null); const handleSeeAllAmenities = () => { - setIsAmenitiesLoading(true); - setTimeout(() => { - setIsAmenitiesLoading(false); - setIsAmenitiesModalOpen(true); - }, 500); - }; - - - const floorPlans = [ - - { id: "30 x 40", price: "₹1.24 Crores", area: "1200 sqft", direction: "North West, South East, North" }, - - { id: "30 x 50", price: "₹1.55 Crores", area: "1500 sqft", direction: "North West, South East, East, West" }, - - { id: "30 x 60", price: "₹1.86 Crores", area: "1800 sqft", direction: "North, East, West" }, - - { id: "40 x 60", price: "₹2.48 Crores", area: "2400 sqft", direction: "East, West" }, - - { id: "50 x 60", price: "₹3.10 Crores", area: "3000 sqft", direction: "North" }, - - ]; - - - - const activePlanDetails = floorPlans.find(p => p.id === activeFloorPlan) || floorPlans[0]; - - - - const amenitiesData = { - - Lifestyle: [ - - { name: "Gym - Indoor", available: true, rare: true, icon: }, - - { name: "Gym - Outdoor", available: true, icon: }, - - { name: "Kids Play Area", available: true, rare: true, icon: }, - - { name: "Amphitheatre", available: false, icon: }, - - { name: "Cafe/Restaurant", available: false, icon: }, - - ], - - Sports: [ - - { name: "Running Track", available: true, rare: true, icon: }, - - { name: "Badminton", available: false, icon: }, - - { name: "Basketball", available: false, icon: }, - - { name: "Cricket Ground", available: false, icon: }, - - { name: "Cricket Pitch", available: false, icon: }, - - ], - - Natural: [ - - { name: "Army Land", available: false, icon: }, - - { name: "Forest", available: false, icon: }, - - { name: "Golf Course", available: false, icon: }, - - { name: "Lake", available: false, icon: }, - - { name: "Mountain/Hill", available: false, icon: }, - - ] - - }; - - - const handleChange = (e: ChangeEvent) => { const { name, value } = e.target; @@ -726,25 +654,21 @@ export default function PropertyDetailClient({ property }: { property: Property

- Ivy County by Modern Spaaces + {property.title} by {property.builder?.name || "Builder"}

-
- - - Better - - - - Average - - - - Subpar - +
+ {property.overview.badges?.map((badge, index) => ( + + {badge} + + ))}
@@ -756,7 +680,7 @@ export default function PropertyDetailClient({ property }: { property: Property

- Average is based on comparable projects in Varthur + Average is based on comparable projects in {property.locality?.name || "this area"}

@@ -765,173 +689,48 @@ export default function PropertyDetailClient({ property }: { property: Property {/* Info Grid - 2 rows x 3 columns */}
+ {property.overview.stats?.map((stat, index) => { + const getBgColor = (index: number) => { + const colors = [ + "bg-green-50 dark:bg-green-900/10 border-green-100 dark:border-green-800/30 text-green-600 dark:text-green-400", + "bg-blue-50 dark:bg-blue-900/10 border-blue-100 dark:border-blue-800/30 text-blue-600 dark:text-blue-400", + "bg-blue-50 dark:bg-blue-900/10 border-blue-100 dark:border-blue-800/30 text-blue-600 dark:text-blue-400", + "bg-red-50 dark:bg-red-900/10 border-red-100 dark:border-red-800/30 text-red-600 dark:text-red-400", + "bg-blue-50 dark:bg-blue-900/10 border-blue-100 dark:border-blue-800/30 text-blue-600 dark:text-blue-400", + "bg-blue-50 dark:bg-blue-900/10 border-blue-100 dark:border-blue-800/30 text-blue-600 dark:text-blue-400" + ]; + return colors[index % colors.length]; + }; - {/* Land Area */} + const bgColorClass = getBgColor(index).split(' ').slice(0, 2).join(' '); // Extract bg classes + const borderColorClass = getBgColor(index).split(' ').slice(2, 4).join(' '); // Extract border classes + const textColorClass = getBgColor(index).split(' ').slice(4).join(' '); // Extract text classes + // Simplified color logic to avoid complex parsing, just use alternating or specific based on type if needed. + // For now, let's use a simpler approach based on the original code + let bgClass = "bg-blue-50 dark:bg-blue-900/10 border border-blue-100 dark:border-blue-800/30"; + let textClass = "text-blue-600 dark:text-blue-400"; -
- -
- -
- - - - - - + if (stat.icon === 'land') { + bgClass = "bg-green-50 dark:bg-green-900/10 border border-green-100 dark:border-green-800/30"; + textClass = "text-orange-600 dark:text-orange-400"; + } else if (stat.icon === 'openArea') { + bgClass = "bg-red-50 dark:bg-red-900/10 border border-red-100 dark:border-red-800/30"; + textClass = "text-red-600 dark:text-red-400"; + } + return ( +
+
+
+ {getOverviewIcon(stat.icon)} +
+
+
{stat.value}
+
{stat.label}
+
{stat.subtext}
- -
- -
50.00 Acres
- -
Land Area
- -
Avg is 50.00 acres
- -
- - - - {/* Closest Metro */} - -
- -
- -
- - - - - - - -
- -
- -
3.62 kms
- -
Closest Metro
- -
Avg is 0.00 kms
- -
- - - - {/* Approach Road */} - -
- -
- -
- - - - - - - -
- -
- -
15 meters
- -
Approach Road
- -
Avg is 15 meters
- -
- - - - {/* Open Area */} - -
- -
- -
- - - - - - - -
- -
- -
45%
- -
Open Area
- -
Avg is 45%
- -
- - - - {/* Unit Density */} - -
- -
- -
- - - - - - - -
- -
- -
13 units/acre
- -
Unit Density
- -
Avg is 13 units/acre
- -
- - - - {/* Club House */} - -
- -
- -
- - - - - - - -
- -
- -
50000 sqft
- -
Club House
- -
Avg is 50000 sqft
- -
- + ); + })}
@@ -941,15 +740,9 @@ export default function PropertyDetailClient({ property }: { property: Property
-

- - - {property.title} is located in {property.location}. In its vicinity, the closest metro is Dommasandra Circle Metro Station. It takes approximately 84 mins to reach the Kempegowda Airport from this property. - - The area is well-connected to major IT hubs, schools, and hospitals, making it an ideal choice for families and professionals alike. - + {property.connectivity?.description || `${property.title} is located in ${property.location}.`}

{!isConnectivityExpanded && ( @@ -1103,69 +896,37 @@ export default function PropertyDetailClient({ property }: { property: Property
-
-
Total Range
- -
{property.price}
- +
{property.pricingDetails?.totalRange || property.price}
-
-
- Monthly EMI - - - -
- -
₹ 73K - ₹ 1.82 L
- +
{property.pricingDetails?.emi || "N/A"}
-
-
- Project's Avg. - - - -
- -
₹ 10326 psft.
- +
{property.pricingDetails?.projectAvg || "N/A"}
-
-
- Market Avg. - - - -
- -
₹ 9700 psft.
- +
{property.pricingDetails?.marketAvg || "N/A"}
-
@@ -1185,15 +946,9 @@ export default function PropertyDetailClient({ property }: { property: Property
-

- - - {property.title} is located in {property.location}. In its vicinity, the closest metro is Dommasandra Circle Metro Station. It takes approximately 84 mins to reach the Kempegowda Airport from this property. - - The area is well-connected to major IT hubs, schools, and hospitals, making it an ideal choice for families and professionals alike. - + {property.connectivity?.description || `${property.title} is located in ${property.location}.`}

{!isConnectivityExpanded && ( @@ -1239,18 +994,15 @@ export default function PropertyDetailClient({ property }: { property: Property

Master Plan

- - {property.title} is a plotted development with 658 plots. - + {property.masterPlan?.description || "Master plan details unavailable."}

- - Compare Sanction Plan - -
@@ -1267,13 +1019,9 @@ export default function PropertyDetailClient({ property }: { property: Property > Master Plan
@@ -1295,41 +1043,26 @@ export default function PropertyDetailClient({ property }: { property: Property
-
Total Units
- -
658
- +
{property.masterPlan?.totalUnits || "N/A"}
-
Water Source
-
- - Borewells - + {property.masterPlan?.waterSource || "N/A"} +1 -
-
-
Park Area
- -
8.00 Acres
- +
{property.masterPlan?.parkArea || "N/A"}
-
Land type
- -
Agricultural
- +
{property.masterPlan?.landType || "N/A"}
@@ -1421,9 +1154,7 @@ export default function PropertyDetailClient({ property }: { property: Property {/* Trusted Badge */}
- - TRUSTED BY 300+ FAMILIES - + TRUSTED BY {property.propsochClarity?.familiesHelped || "300+"} FAMILIES
@@ -1544,8 +1275,9 @@ export default function PropertyDetailClient({ property }: { property: Property

- {property.title} has plots ranging from 1200 sqft to 3000 sqft. - + {property.floorPlans && property.floorPlans.length > 0 + ? `${property.title} has configurations ranging from ${property.floorPlans[0].area} to ${property.floorPlans[property.floorPlans.length - 1].area}.` + : "Floor plans details coming soon."}

@@ -1648,41 +1380,43 @@ export default function PropertyDetailClient({ property }: { property: Property {/* Active Plan Details Card */} -
+ {activePlanDetails && ( +
-
+
-
+
-

{activePlanDetails.id}

+

{activePlanDetails.id}

- {activePlanDetails.price} + {activePlanDetails.price} -
+
-
+
-
Saleable Area
+
Saleable Area
-
{activePlanDetails.area}
+
{activePlanDetails.area}
-
+
-
+
-
Direction(s)
+
Direction(s)
-
{activePlanDetails.direction}
+
{activePlanDetails.direction}
+ +
- -
+ )} @@ -1708,13 +1442,18 @@ export default function PropertyDetailClient({ property }: { property: Property
    - {amenitiesData.Lifestyle.map((item, idx) => ( + {property.detailedAmenities?.Lifestyle?.map((item, idx) => (
  • - {item.icon} + {/* Icon rendering logic can be improved here if needed, for now assuming icons are handled or passed */} + {getOverviewIcon(item.name.toLowerCase().replace(" ", "")) || ( + + + + )}
    @@ -1742,13 +1481,18 @@ export default function PropertyDetailClient({ property }: { property: Property
      - {amenitiesData.Sports.map((item, idx) => ( + {property.detailedAmenities?.Sports?.map((item, idx) => (
    • - {item.icon} + {/* Icon rendering logic can be improved here if needed, for now assuming icons are handled or passed */} + {getOverviewIcon(item.name.toLowerCase().replace(" ", "")) || ( + + + + )}
      @@ -1776,13 +1520,17 @@ export default function PropertyDetailClient({ property }: { property: Property
        - {amenitiesData.Natural.map((item, idx) => ( + {property.detailedAmenities?.Natural?.map((item, idx) => (
      • - {item.icon} + {getOverviewIcon(item.name.toLowerCase().replace(" ", "")) || ( + + + + )}
        @@ -1861,107 +1609,18 @@ export default function PropertyDetailClient({ property }: { property: Property {/* Approvals List - Two Columns */}
        - - {/* Left Column */} - -
        - -
        - - - - - - - + {property.approvals?.map((approval, index) => ( +
        +
        + + + +
        +
        +

        {approval.name}

        +
        - -
        - -

        Approved by BBMP

        - - - -
        - -
        - - - - {/* Right Column */} - -
        - -
        - - - - - - - -
        - -
        - -

        Approved by BDA

        - - - -
        - -
        - - - - {/* Left Column */} - -
        - -
        - - - - - - - -
        - -
        - -

        Approved by BWSSB

        - -
        - -
        - - - - {/* Right Column */} - -
        - -
        - - - - - - - -
        - -
        - -

        Approved by MOEF

        - - - -
        - -
        - + ))}
        @@ -1971,145 +1630,33 @@ export default function PropertyDetailClient({ property }: { property: Property

        Documents

        - - Curated documents from various sources for {property.title} by Modern Spaaces - + Curated documents from various sources for {property.title} by {property.builder?.name || "Builder"}

        - - {/* City Development Plan */} - -
        - -
        - - - - - - - + {property.documents?.map((doc, index) => ( +
        +
        + + + +
        +
        + + + +
        +

        {doc.title}

        +

        + {doc.description} +

        +
        - -
        - - - - - - - -
        - -

        City Development Plan

        - -

        - - Used to identify land types, sensitive zones/flood risks, future developments etc. - -

        - - - -
        - - - - - - - - {/* Legal Opinion */} - -
        - -
        - - - - - - - -
        - -
        - - - - - - - -
        - -

        Legal Opinion

        - -

        - - Used to only declare any litigations by the builder. Do NOT mistake for a clean title. - -

        - - - -
        - - - - - - {/* Development Rights */} - -
        - -
        - - - - - - - -
        - -
        - - - - - - - -
        - -

        Development Rights

        - -

        - - Outlines the agreed terms of development between the land owner & the builder - -

        - - - -
        - + ))}
        @@ -2122,7 +1669,7 @@ export default function PropertyDetailClient({ property }: { property: Property

        About the builder

        -

        Modern Spaaces

        +

        {property.builder?.name || "Builder"}

        @@ -2131,14 +1678,12 @@ export default function PropertyDetailClient({ property }: { property: Property

        - - Established in 2012, Modern Spaces focuses on delivering thoughtfully designed residential and commercial developments. With over 1 million sq. ft. completed, the company caters to mid-segment and premium buyers in Bengaluru. Key projects like Modern Greens, Modern Heights, and Modern Meadows are recognized for their innovative layouts and contemporary features. Modern Spaces integrates green practices such as energy-efficient construction and landscaped open spaces into its developments. Known for timely delivery and quality construction, Modern Spaces continues to serve Bengaluru's growing real estate market. - + {property.builder?.description}

        - See all properties by Modern Spaaces + See all properties by {property.builder?.name || "this builder"} @@ -2150,7 +1695,7 @@ export default function PropertyDetailClient({ property }: { property: Property

        Established On

        -

        2012

        +

        {property.builder?.establishedYear || "N/A"}

        @@ -2158,7 +1703,7 @@ export default function PropertyDetailClient({ property }: { property: Property

        Completed Projects

        -

        No Data

        +

        {property.builder?.completedProjects || "N/A"}

        @@ -2180,7 +1725,7 @@ export default function PropertyDetailClient({ property }: { property: Property

        Locality

        -

        Varthur

        +

        {property.locality?.name || "Bangalore"}

        @@ -2190,9 +1735,9 @@ export default function PropertyDetailClient({ property }: { property: Property Varthur Locality -

        Varthur

        +

        {property.locality?.name || "Locality"}

        @@ -2209,9 +1754,7 @@ export default function PropertyDetailClient({ property }: { property: Property

        - - Varthur, located in East Bengaluru, is an upcoming residential locality that offers a serene living environment. The area is gaining popularity due to its proximity to tech parks and educational institutions. - + {property.locality?.description}

        @@ -2296,7 +1839,7 @@ export default function PropertyDetailClient({ property }: { property: Property

        - See properties similar to {property.title} by Modern Spaaces in the same neighbourhood + See properties similar to {property.title} by {property.builder?.name || "Builder"} in the same neighbourhood

        @@ -2310,7 +1853,7 @@ export default function PropertyDetailClient({ property }: { property: Property
        - Prestige Raintree Park + Prestige Raintree Park
        @@ -2362,7 +1905,7 @@ export default function PropertyDetailClient({ property }: { property: Property
        - Tru Aquapolis + Tru Aquapolis
        @@ -2424,7 +1967,7 @@ export default function PropertyDetailClient({ property }: { property: Property
        - {['Project Details', 'Location & Connectivity', 'Price & Booking', 'Services'].map((tab) => ( + {Object.keys(faqData).map((tab) => (