diff --git a/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.css b/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.css
index 95e6a31..34fb323 100644
--- a/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.css
+++ b/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.css
@@ -638,12 +638,315 @@ late particularay
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.15);
border-color: #C0A062;
background: #ffffff;
+ animation: templateHoverPulse 0.6s ease-in-out;
+}
+
+/* Enhanced hover animation */
+@keyframes templateHoverPulse {
+ 0% {
+ box-shadow: 0 12px 40px rgba(0, 0, 0, 0.08);
+ }
+ 50% {
+ box-shadow: 0 25px 60px rgba(192, 160, 98, 0.25);
+ }
+ 100% {
+ box-shadow: 0 20px 50px rgba(0, 0, 0, 0.15);
+ }
+}
+
+/* Additional hover effects for template content */
+.template-card:hover .template-content {
+ transform: translateY(-2px);
+ transition: transform 0.3s ease;
+}
+
+/* Hover effect for template titles */
+.template-card:hover h1,
+.template-card:hover h2,
+.template-card:hover h3 {
+ color: #C0A062;
+ transition: color 0.3s ease;
+}
+
+/* Hover effect for template preview images */
+.template-card:hover .gallery-item,
+.template-card:hover .hero,
+.template-card:hover .p1-image-side,
+.template-card:hover .p2-image,
+.template-card:hover .vision-image {
+ transform: scale(1.05);
+ transition: transform 0.3s ease;
+ filter: brightness(1.1);
+}
+
+/* Hover effect for buttons within templates */
+.template-card:hover .cta-btn,
+.template-card:hover .btn {
+ background: #C0A062 !important;
+ color: white !important;
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(192, 160, 98, 0.3);
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for property stats */
+.template-card:hover .stat-item,
+.template-card:hover .feature-item {
+ color: #C0A062;
+ transform: translateX(5px);
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for amenities and lists */
+.template-card:hover .amenity-item,
+.template-card:hover .amenities-list li {
+ color: #C0A062;
+ transform: translateX(8px);
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for icons */
+.template-card:hover .fa-solid,
+.template-card:hover .fa-check {
+ color: #C0A062;
+ transform: scale(1.2);
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for property details */
+.template-card:hover .spec-item,
+.template-card:hover .item {
+ border-left: 3px solid #C0A062;
+ padding-left: 8px;
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for contact info */
+.template-card:hover .agent-info,
+.template-card:hover .contact-info {
+ background: rgba(192, 160, 98, 0.1);
+ border-radius: 8px;
+ padding: 8px;
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for cover elements */
+.template-card:hover .cover-title,
+.template-card:hover .main-title,
+.template-card:hover .p1-main-title {
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
+ transition: text-shadow 0.3s ease;
+}
+
+/* Hover effect for gallery items */
+.template-card:hover .gallery-item span {
+ background: rgba(192, 160, 98, 0.9);
+ color: white;
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for page numbers and footers */
+.template-card:hover .page-number,
+.template-card:hover .page-footer-bar {
+ color: #C0A062;
+ font-weight: 600;
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for newsletter-style template */
+.template-card:hover .newsletter-header h2 {
+ background: linear-gradient(135deg, #C0A062, #8B6914);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for modern home template elements */
+.template-card:hover .property-name,
+.template-card:hover .property-address {
+ text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1);
+ transition: text-shadow 0.3s ease;
+}
+
+/* Hover effect for grand oak template */
+.template-card:hover .cover-title,
+.template-card:hover .p1-main-title {
+ background: linear-gradient(135deg, #C0A062, #8B6914);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for vertice template */
+.template-card:hover .main-title {
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
+ transition: text-shadow 0.3s ease;
+}
+
+/* Hover effect for serenity template */
+.template-card:hover .p1-main-title {
+ color: #C0A062;
+ transform: translateY(-2px);
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for price displays */
+.template-card:hover .price,
+.template-card:hover .priceDisplay {
+ color: #C0A062;
+ font-weight: 700;
+ transform: scale(1.05);
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for reference IDs */
+.template-card:hover .reference-id,
+.template-card:hover .p1-ref-id {
+ background: rgba(192, 160, 98, 0.1);
+ padding: 4px 8px;
+ border-radius: 4px;
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for collection badges */
+.template-card:hover .collection {
+ background: #C0A062;
+ color: white;
+ padding: 4px 12px;
+ border-radius: 12px;
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for area displays */
+.template-card:hover .area {
+ color: #C0A062;
+ font-weight: 600;
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for section titles */
+.template-card:hover .section-title {
+ border-bottom: 2px solid #C0A062;
+ padding-bottom: 4px;
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for description text */
+.template-card:hover .description p,
+.template-card:hover .pull-quote {
+ color: #555;
+ line-height: 1.7;
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for pull quotes */
+.template-card:hover .pull-quote {
+ border-left: 4px solid #C0A062;
+ padding-left: 16px;
+ font-style: italic;
+ font-weight: 500;
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for floor plan stats */
+.template-card:hover .floorplan-stats-p5 .stat {
+ background: rgba(192, 160, 98, 0.1);
+ border-radius: 8px;
+ padding: 8px;
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for highlights list */
+.template-card:hover .highlights-list-p6 li {
+ background: rgba(192, 160, 98, 0.05);
+ padding: 4px 8px;
+ border-radius: 4px;
+ margin: 2px 0;
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for property field displays */
+.template-card:hover .property-field {
+ background: rgba(192, 160, 98, 0.05);
+ padding: 4px 8px;
+ border-radius: 4px;
+ transition: all 0.3s ease;
+}
+
+/* Hover effect for owner info */
+.template-card:hover .owner-info {
+ background: rgba(192, 160, 98, 0.1);
+ padding: 8px;
+ border-radius: 8px;
+ border-left: 3px solid #C0A062;
+ transition: all 0.3s ease;
}
.template-card.selected {
border: 3px solid #000000 !important; /* Black selected border */
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
transform: translateY(-6px);
+ animation: selectedPulse 2s ease-in-out infinite;
+}
+
+/* Selected state animation */
+@keyframes selectedPulse {
+ 0%, 100% {
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
+ }
+ 50% {
+ box-shadow: 0 15px 40px rgba(0, 0, 0, 0.3);
+ }
+}
+
+/* Enhanced selected indicator */
+.selected-indicator {
+ position: absolute;
+ top: 15px;
+ right: 15px;
+ background: linear-gradient(135deg, #C0A062, #8B6914);
+ color: white;
+ padding: 8px 16px;
+ border-radius: 20px;
+ font-size: 12px;
+ font-weight: 600;
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ box-shadow: 0 4px 12px rgba(192, 160, 98, 0.4);
+ animation: selectedIndicatorBounce 0.6s ease-out;
+ z-index: 10;
+}
+
+@keyframes selectedIndicatorBounce {
+ 0% {
+ transform: scale(0) rotate(-180deg);
+ opacity: 0;
+ }
+ 50% {
+ transform: scale(1.2) rotate(-90deg);
+ opacity: 0.8;
+ }
+ 100% {
+ transform: scale(1) rotate(0deg);
+ opacity: 1;
+ }
+}
+
+.selected-icon {
+ font-size: 14px;
+ animation: checkmarkPulse 1.5s ease-in-out infinite;
+}
+
+@keyframes checkmarkPulse {
+ 0%, 100% {
+ transform: scale(1);
+ }
+ 50% {
+ transform: scale(1.2);
+ }
}
/* Template Heights - Masonry Zigzag Layout */
diff --git a/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.js b/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.js
index a49ca80..fd3e9b1 100644
--- a/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.js
+++ b/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.js
@@ -1507,7 +1507,9 @@ export default class PropertyTemplateSelector extends LightningElement {
tempDiv.innerHTML = htmlContent;
// Remove preview-only UI like no-image placeholders
- const previewOnly = tempDiv.querySelectorAll('[data-preview-only="true"], .floating-placeholder, .placeholder-badge, .placeholder-bubble');
+ const previewOnly = tempDiv.querySelectorAll(
+ '[data-preview-only="true"], .floating-placeholder, .placeholder-badge, .placeholder-bubble'
+ );
previewOnly.forEach((el) => el.remove());
// Ensure list styling is preserved in output
@@ -2257,7 +2259,10 @@ export default class PropertyTemplateSelector extends LightningElement {
.replace(/\"/g, """)
.replace(/'/g, "'");
- const lines = raw.replace(/\r\n?/g, "\n").split("\n").map((l) => l.trim());
+ const lines = raw
+ .replace(/\r\n?/g, "\n")
+ .split("\n")
+ .map((l) => l.trim());
const bulletRe = /^\s*(?:[-*•]|\u2022)\s+(.*)$/; // -,*,• bullets
const numberedRe = /^\s*(\d+)[\.)]\s+(.*)$/; // 1. or 1)
@@ -2422,7 +2427,7 @@ export default class PropertyTemplateSelector extends LightningElement {
}
return amenities
- .map((a) => `
${a}`)
+ .map((a) => ` ${a}`)
.join("");
}
// Template methods
@@ -2647,15 +2652,15 @@ export default class PropertyTemplateSelector extends LightningElement {
createModernHomeTemplate() {
const data = this.propertyData || {};
- const propertyName = data.Name || data.propertyName || "Property Name";
- const propertyType =
- data.Property_Type__c || data.propertyType || "Property Type";
- const location = data.Address__c || data.location || "Location";
- const price = data.Price__c || data.price || "Price on Request";
- const bedrooms = data.Bedrooms__c || data.bedrooms || "N/A";
- const bathrooms = data.Bathrooms__c || data.bathrooms || "N/A";
- const area = data.Square_Feet__c || data.area || "N/A";
-
+ console.log("data-----------", data);
+ const propertyName = data.Name || data.propertyName;
+ const propertyType = data.Property_Type__c || data.propertyType;
+ const location = data.Address__c || data.location;
+ const price = data.Price__c || data.price;
+ const bedrooms = data.Bedrooms__c || data.bedrooms;
+ const bathrooms = data.Bathrooms__c || data.bathrooms;
+ const area = data.Square_Feet__c || data.area;
+
const description = this.formatDescriptionForPDF(
data.Description_English__c ||
data.descriptionEnglish ||
@@ -2687,37 +2692,37 @@ export default class PropertyTemplateSelector extends LightningElement {
const furnishing = data.Furnished__c || data.furnished || "N/A";
const maintenanceFee =
data.Maintenance_Fee__c || data.maintenanceFee || "N/A";
- const serviceCharge =
- data.Service_Charge__c || data.serviceCharge || "N/A";
+ const serviceCharge = data.Service_Charge__c || data.serviceCharge || "N/A";
const ownerName = data.Owner_Name__c || data.ownerName || "N/A";
const ownerPhone = data.Owner_Phone__c || data.ownerPhone || "N/A";
- const landmarks =
- data.Nearby_Landmarks__c || data.nearbyLandmarks || "N/A";
+ const landmarks = data.Nearby_Landmarks__c || data.nearbyLandmarks || "N/A";
const transportation =
data.Transportation__c || data.transportation || "N/A";
const schools = data.Schools__c || data.schools || "N/A";
const hospitals = data.Hospitals__c || data.hospitals || "N/A";
- const shopping =
- data.Shopping_Centers__c || data.shoppingCenters || "N/A";
+ const shopping = data.Shopping_Centers__c || data.shoppingCenters || "N/A";
const airportDistance =
data.Airport_Distance__c || data.airportDistance || "N/A";
const petFriendly =
- data.Pet_Friendly__c !== undefined
+ data.Pet_Friendly__c !== "N/A"
? data.Pet_Friendly__c
? "Yes"
: "No"
: data.petFriendly || "N/A";
const smokingAllowed =
- data.Smoking_Allowed__c !== undefined
+ data.Smoking_Allowed__c !== "N/A"
? data.Smoking_Allowed__c
? "Yes"
: "No"
: data.smokingAllowed || "N/A";
const availableFrom =
- data.Rent_Available_From__c || data.Available_From__c || data.availableFrom || "N/A";
+ data.Rent_Available_From__c ||
+ data.Available_From__c ||
+ data.availableFrom ||
+ "N/A";
const minimumContract =
data.Minimum_Contract__c || data.minimumContract || "N/A";
const securityDeposit =
@@ -2739,8 +2744,11 @@ export default class PropertyTemplateSelector extends LightningElement {
const chunkHTML = chunk
.map((img, idx) => {
const title =
- img.title || img.pcrm__Title__c || `Property Image ${i + idx + 1}`;
- const extraStyle = idx === chunk.length - 1 ? " grid-column: 1 / -1;" : "";
+ img.title ||
+ img.pcrm__Title__c ||
+ `Property Image ${i + idx + 1}`;
+ const extraStyle =
+ idx === chunk.length - 1 ? " grid-column: 1 / -1;" : "";
return `
`;
})
.join("");
@@ -3137,7 +3145,7 @@ export default class PropertyTemplateSelector extends LightningElement {
${bedrooms} Beds
${bathrooms} Baths
- ${area} sq. ft.
+ ${area}
@@ -3151,12 +3159,12 @@ export default class PropertyTemplateSelector extends LightningElement {
@@ -3205,7 +3213,9 @@ export default class PropertyTemplateSelector extends LightningElement {
Reference ID: ${referenceId}
- Owner Info: ${ownerName}, ${ownerPhone}
+ Owner Info: ${
+ this.propertyData.contactEmail
+ }, ${this.propertyData.contactPhone}
@@ -3215,27 +3225,49 @@ export default class PropertyTemplateSelector extends LightningElement {
Location & Nearby
-
-
Transportation: ${transportation}
-
-
-
-
Airport: ${airportDistance}
+
City: ${
+ this.propertyData.city
+ }
+
Community: ${
+ this.propertyData.community
+ }
+
Sub Community: ${
+ this.propertyData.subCommunity
+ }
+
Locality: ${
+ this.propertyData.locality
+ }
+
Tower: ${
+ this.propertyData.tower
+ }
+
Unit Number: ${
+ this.propertyData.unitNumber
+ }
-

+
Additional Information
-
Pet Friendly: ${petFriendly}
-
Smoking: ${smokingAllowed}
-
Available From: ${availableFrom}
-
Minimum Contract: ${minimumContract}
-
Security Deposit: ${securityDeposit}
+
Available From: ${
+ this.propertyData.rentAvailableFrom
+ }
+
Rent Available To: ${
+ this.propertyData.rentAvailableTo
+ }
+
Smoking: ${
+ this.propertyData.smokingAllowed
+ }
+
Minimum Contract: ${
+ this.propertyData.minimumContract
+ }
+
Security Deposit: ${
+ this.propertyData.securityDeposit
+ }
@@ -3244,7 +3276,9 @@ export default class PropertyTemplateSelector extends LightningElement {
Reference ID: ${referenceId}
- Owner Info: ${ownerName}, ${ownerPhone}
+ Owner Info: ${
+ this.propertyData.contactEmail
+ }, ${this.propertyData.contactPhone}
@@ -3382,12 +3416,8 @@ ${galleryPagesHTML}
// Enhanced property data extraction with better fallbacks
const propertyName =
- data.Name ||
- data.propertyName ||
- data.pcrm__Title_English__c;
- const location =
- data.Address__c ||
- data.location;
+ data.Name || data.propertyName || data.pcrm__Title_English__c;
+ const location = data.Address__c || data.location;
const price =
data.Sale_Price_Min__c ||
data.Rent_Price_Min__c ||
@@ -3397,15 +3427,13 @@ ${galleryPagesHTML}
data.pcrm__Title_English__c || data.Name || data.propertyName;
const bedrooms = data.Bedrooms__c || data.bedrooms;
const bathrooms = data.Bathrooms__c || data.bathrooms;
- const squareFeet =
- data.Square_Feet__c || data.squareFeet || data.area;
+ const squareFeet = data.Square_Feet__c || data.squareFeet || data.area;
const status = (data.Status__c || data.status).toString();
// Enhanced property details
const propertyType = data.Property_Type__c || data.propertyType;
const yearBuilt = data.Build_Year__c || data.yearBuilt;
- const furnishing =
- data.Furnished__c || data.furnishing;
+ const furnishing = data.Furnished__c || data.furnishing;
const parking = data.Parking_Spaces__c || data.parking;
const description = this.formatDescriptionForPDF(
data.Description_English__c ||
@@ -3413,9 +3441,8 @@ ${galleryPagesHTML}
data.description ||
"An exquisite villa offering unparalleled luxury and sophistication in one of the most prestigious locations."
);
- const floor = data.Floor__c || data.floor
- const maintenanceFee =
- data.Maintenance_Fee__c || data.maintenanceFee;
+ const floor = data.Floor__c || data.floor;
+ const maintenanceFee = data.Maintenance_Fee__c || data.maintenanceFee;
const serviceCharge = data.Service_Charge__c || data.serviceCharge;
// Additional property details
@@ -3430,10 +3457,9 @@ ${galleryPagesHTML}
const hoa = data.HOA__c || data.hoa;
const hoaFee = data.HOA_Fee__c || data.hoaFee;
const taxYear = data.Tax_Year__c || data.taxYear;
- const taxAmount = data.Tax_Amount__c || data.taxAmount ;
- const lastSold = data.Last_Sold__c || data.lastSold ;
- const lastSoldPrice =
- data.Last_Sold_Price__c || data.lastSoldPrice ;
+ const taxAmount = data.Tax_Amount__c || data.taxAmount;
+ const lastSold = data.Last_Sold__c || data.lastSold;
+ const lastSoldPrice = data.Last_Sold_Price__c || data.lastSoldPrice;
// Location and POI data
const schools = data.Schools__c || data.schools || "N/A";
@@ -3446,39 +3472,27 @@ ${galleryPagesHTML}
const transportation =
data.Transportation__c || data.transportation || "N/A";
const hospitals = data.Hospitals__c || data.hospitals || "N/A";
- const beachDistance =
- data.Beach_Distance__c || data.beachDistance || "N/A";
- const metroDistance =
- data.Metro_Distance__c || data.metroDistance || "N/A";
+ const beachDistance = data.Beach_Distance__c || data.beachDistance || "N/A";
+ const metroDistance = data.Metro_Distance__c || data.metroDistance || "N/A";
// Additional information
const petFriendly = data.Pet_Friendly__c || data.petFriendly;
- const smokingAllowed =
- data.Smoking_Allowed__c || data.smokingAllowed;
- const availableFrom =
- data.Available_From__c || data.availableFrom;
- const minimumContract =
- data.Minimum_Contract__c || data.minimumContract;
- const securityDeposit =
- data.Security_Deposit__c || data.securityDeposit;
+ const smokingAllowed = data.Smoking_Allowed__c || data.smokingAllowed;
+ const availableFrom = data.Available_From__c || data.availableFrom;
+ const minimumContract = data.Minimum_Contract__c || data.minimumContract;
+ const securityDeposit = data.Security_Deposit__c || data.securityDeposit;
const utilitiesIncluded =
- data.Utilities_Included__c ||
- data.utilitiesIncluded;
- const internetIncluded =
- data.Internet_Included__c || data.internetIncluded;
+ data.Utilities_Included__c || data.utilitiesIncluded;
+ const internetIncluded = data.Internet_Included__c || data.internetIncluded;
const cableIncluded = data.Cable_Included__c || data.cableIncluded;
// Agent and owner information
const agentName = data.Agent_Name__c || data.agentName;
- const agentPhone =
- data.Agent_Phone__c || data.agentPhone;
- const agentEmail =
- data.Agent_Email__c || data.agentEmail ;
- const ownerName = data.Owner_Name__c || data.ownerName ;
- const ownerPhone =
- data.Owner_Phone__c || data.ownerPhone ;
- const ownerEmail =
- data.Owner_Email__c || data.ownerEmail;
+ const agentPhone = data.Agent_Phone__c || data.agentPhone;
+ const agentEmail = data.Agent_Email__c || data.agentEmail;
+ const ownerName = data.Owner_Name__c || data.ownerName;
+ const ownerPhone = data.Owner_Phone__c || data.ownerPhone;
+ const ownerEmail = data.Owner_Email__c || data.ownerEmail;
// Get smart images
const exteriorImage = this.getExteriorImageUrl();
const interiorImage1 = this.getSmartImageForSection(
@@ -3516,8 +3530,11 @@ ${galleryPagesHTML}
const chunkHTML = chunk
.map((img, idx) => {
const title =
- img.title || img.pcrm__Title__c || `Property Image ${i + idx + 1}`;
- const extraStyle = idx === chunk.length - 1 ? " grid-column: 1 / -1;" : "";
+ img.title ||
+ img.pcrm__Title__c ||
+ `Property Image ${i + idx + 1}`;
+ const extraStyle =
+ idx === chunk.length - 1 ? " grid-column: 1 / -1;" : "";
return `
`;
})
.join("");
@@ -3538,7 +3555,7 @@ ${galleryPagesHTML}
}
// Return the complete Grand Oak Villa template with all dynamic data
- return `
+ return `
@@ -3708,8 +3725,8 @@ ${galleryPagesHTML}
}
.description p {
font-size: 0.95rem;
- line-height: 1.8;
- margin: 0 0 15px 0;
+ line-height: 1.2;
+ margin: 0 0 8px 0;
color: var(--color-text-primary);
}
.specs-and-amenities {
@@ -3833,30 +3850,13 @@ ${galleryPagesHTML}
-
-
-
Specifications
-
-
Reference ID: ${referenceId}
-
Status: ${status}
-
Type: ${propertyType}
-
Year Built: ${yearBuilt}
-
Floor: ${floor}
-
Parking: ${parking}
-
Furnishing: ${furnishing}
-
Maintenance Fee: ${maintenanceFee}
-
Service Charge: ${serviceCharge}
-
-
-
-
Amenities & Features
-
${this.generateAmenitiesListItems(data)}
-
-
+
@@ -3872,49 +3872,61 @@ ${galleryPagesHTML}
-
Schools
-
${schools}
+
City
+
${this.propertyData.city}
-
Shopping
-
${shoppingCenters}
+
Community
+
${
+ this.propertyData.community
+ }
-
Airport
-
${airportDistance}
+
Sub Community
+
${
+ this.propertyData.subCommunity
+ }
-
Landmarks
-
${nearbyLandmarks}
+
Locality
+
${this.propertyData.locality}
-
Transportation
-
${transportation}
+
Tower
+
${this.propertyData.tower}
-
Hospitals
-
${hospitals}
+
Unit Number
+
${
+ this.propertyData.unitNumber
+ }
-
Beach
-
${beachDistance}
+
Sale Price (Min):
+
${
+ this.propertyData.beachDistance
+ }
-
Metro
-
${metroDistance}
+
Sale Price (Max):
+
${
+ this.propertyData.salePriceMax
+ }
@@ -3926,31 +3938,33 @@ ${galleryPagesHTML}
${propertyName}
-
+
Additional Information
-
Pet Friendly: ${petFriendly}
-
Smoking: ${smokingAllowed}
-
Available From: ${availableFrom}
-
Minimum Contract: ${minimumContract}
-
Security Deposit: ${securityDeposit}
-
Utilities Included: ${utilitiesIncluded}
-
Internet Included: ${internetIncluded}
-
Cable Included: ${cableIncluded}
+
Parking Spaces: ${
+ this.propertyData.parkingSpaces
+ }
+
Offering Type: ${
+ this.propertyData.offeringType
+ }
+
Furnished: ${
+ this.propertyData.furnished
+ }
+
Available From: ${
+ this.propertyData.rentAvailableFrom
+ }
+
Available To: ${
+ this.propertyData.rentAvailableTo
+ }
@@ -3960,7 +3974,7 @@ ${galleryPagesHTML}
-`
+`;
}
createSerenityHouseTemplate() {
@@ -4040,7 +4054,8 @@ ${galleryPagesHTML}
// Additional dynamic fields
const floor = data.Floor__c || data.floor || "N/A";
- const maintenanceFee = data.Maintenance_Fee__c || data.maintenanceFee || "N/A";
+ const maintenanceFee =
+ data.Maintenance_Fee__c || data.maintenanceFee || "N/A";
const serviceCharge = data.Service_Charge__c || data.serviceCharge || "N/A";
const acres = data.Lot_Size__c || data.acres || "N/A";
@@ -4056,8 +4071,11 @@ ${galleryPagesHTML}
const chunkHTML = chunk
.map((img, idx) => {
const title =
- img.title || img.pcrm__Title__c || `Property Image ${i + idx + 1}`;
- const extraStyle = idx === chunk.length - 1 ? " grid-column: 1 / -1;" : "";
+ img.title ||
+ img.pcrm__Title__c ||
+ `Property Image ${i + idx + 1}`;
+ const extraStyle =
+ idx === chunk.length - 1 ? " grid-column: 1 / -1;" : "";
return `
`;
})
.join("");
@@ -4221,10 +4239,10 @@ ${galleryPagesHTML}
}
.page-title-main {
font-family: var(--font-serif);
- font-size: 3.5rem;
+ font-size: 3rem;
font-weight: 600;
color: var(--color-text-primary);
- margin: 0 0 15px 0;
+ margin: 0 0 1px 0;
line-height: 1;
}
.page-title-sub {
@@ -4398,14 +4416,11 @@ ${galleryPagesHTML}
@@ -4459,7 +4474,9 @@ ${galleryPagesHTML}
Amenities & Features
-
${this.generateAmenitiesListItems(data)}
+
${this.generateAmenitiesListItems(
+ data
+ )}
@@ -4472,15 +4489,30 @@ ${galleryPagesHTML}
Location & Nearby
-
Schools ${schools}
-
Shopping ${shopping}
-
Hospitals ${hospitals}
-
Country Club ${countryClub}
-
Airport ${airport}
-
-
+
City ${
+ this.propertyData.city
+ }
+
Community ${
+ this.propertyData.community
+ }
+
Sub community ${
+ this.propertyData.subCommunity
+ }
+
Locality ${
+ this.propertyData.locality
+ }
+
Tower ${
+ this.propertyData.tower
+ }
+
+
Additional Information
-
Pet-Friendly ${petFriendly}
+
Available from ${
+ this.propertyData.rentAvailableFrom
+ }
+
Available to ${
+ this.propertyData.rentAvailableTo
+ }
Smoking ${smoking}
Availability ${availability}
Utilities ${utilities}
@@ -4489,7 +4521,7 @@ ${galleryPagesHTML}
-
Floor Plan & Location
+
Owner and Agent Information
@@ -5036,7 +5079,6 @@ ${galleryPagesHTML}
${propertyType} • ${status} • ${squareFeet} sq ft
${description}
@@ -5044,7 +5086,6 @@ ${galleryPagesHTML}
@@ -5052,13 +5093,11 @@ ${galleryPagesHTML}
- ${propertyGallery}
+ ${propertyGallery}
@@ -5067,15 +5106,35 @@ ${galleryPagesHTML}
-
An unrivaled collection of amenities offers residents a resort-style living experience. From the serene rooftop pool to the state-of-the-art wellness center, every detail is crafted for comfort, convenience, and luxury.
-
+
+
+ Parking Spaces:
+ ${
+ this.propertyData
+ .parkingSpaces
+ }
+
+
+ Furnished:
+ ${
+ this.propertyData.furnished
+ }
+
+
+ Offering Type:
+ ${
+ this.propertyData.offeringType
+ }
+
+
Lifestyle Amenities
-
${this.generateAmenitiesListItems(data)}
+
${this.generateAmenitiesListItems(
+ data
+ )}
Key Specifications
@@ -5090,7 +5149,6 @@ ${galleryPagesHTML}
@@ -5108,23 +5166,30 @@ ${galleryPagesHTML}
Two-Bedroom Residence
-
1,450
+
${
+ this.propertyData.size
+ }
SQ. FT.
-
2
+
${
+ this.propertyData.bedrooms
+ }
BEDROOMS
-
2
+
${
+ this.propertyData.bathrooms
+ }
BATHROOMS
-
1
-
BALCONY
+
${
+ this.propertyData.floor
+ }
+
Floors
- A thoughtfully designed space perfect for urban professionals or small families, combining comfort with panoramic city views.
@@ -5133,33 +5198,40 @@ ${galleryPagesHTML}
Three-Bedroom Penthouse
-
3,200
+
${
+ this.propertyData.size
+ }
SQ. FT.
-
3
+
${
+ this.propertyData.bedrooms
+ }
BEDROOMS
-
3.5
+
${
+ this.propertyData.bathrooms
+ }
BATHROOMS
-
1
-
TERRACE
+
${
+ this.propertyData.floor
+ }
+
Floors
-
The pinnacle of luxury living, this penthouse offers expansive spaces, premium finishes, and exclusive access to a private rooftop terrace.
Additional Information
-
-
+
Available from
${this.propertyData.rentAvailableFrom}
+
Rent Available To
${this.propertyData.rentAvailableTo}
Availability
${availability}
-
-
Security Deposit
${securityDeposit}
+
Unit Number
${this.propertyData.unitNumber}
+
Offereing type
${this.propertyData.offeringType}
@@ -5178,32 +5250,32 @@ ${galleryPagesHTML}
Your Future Awaits
+
-
Schedule a Private Viewing
-
Experience The Vertice firsthand. Contact our sales executive to arrange an exclusive tour of the property and available residences.
-
-
-
-
Neighborhood Highlights
- - Landmarks: Central Park (5 min)
- - Transportation: Metro Line A (2 min walk)
- - Schools: Metropolis Intl. (10 min)
- - Shopping: The Galleria Mall (8 min)
- - Airport: 25 min drive
+ - City: ${
+ this.propertyData.city
+ }
+ - Community: ${
+ this.propertyData.community
+ }
+ - Sub Community: ${
+ this.propertyData.subCommunity
+ }
+ - Locality: ${
+ this.propertyData.locality
+ }
+ - Tower: ${
+ this.propertyData.tower
+ }
+ - Unit Number: ${
+ this.propertyData.unitNumber
+ }
@@ -5452,12 +5524,18 @@ ${galleryPagesHTML}
const currentList = this.findParentList(range.commonAncestorContainer);
- if (currentList && currentList.tagName.toLowerCase() === listType.toLowerCase()) {
+ if (
+ currentList &&
+ currentList.tagName.toLowerCase() === listType.toLowerCase()
+ ) {
this.convertListToParagraph(currentList);
return;
}
- if (currentList && currentList.tagName.toLowerCase() !== listType.toLowerCase()) {
+ if (
+ currentList &&
+ currentList.tagName.toLowerCase() !== listType.toLowerCase()
+ ) {
this.convertListType(currentList, listType);
return;
}
@@ -5470,7 +5548,8 @@ ${galleryPagesHTML}
let current = node;
while (current && current !== document.body) {
if (current.nodeType === Node.ELEMENT_NODE) {
- if (current.tagName === "UL" || current.tagName === "OL") return current;
+ if (current.tagName === "UL" || current.tagName === "OL")
+ return current;
if (current.tagName === "LI") return current.parentElement;
}
current = current.parentElement;
@@ -6501,10 +6580,7 @@ ${galleryPagesHTML}
// Otherwise add a visual tab (4 NBSP) at the start of the current block
const getBlock = (node) => {
let n = node.nodeType === Node.TEXT_NODE ? node.parentElement : node;
- while (
- n &&
- !/(P|DIV|LI|H1|H2|H3|H4|H5|H6)/i.test(n.tagName)
- ) {
+ while (n && !/(P|DIV|LI|H1|H2|H3|H4|H5|H6)/i.test(n.tagName)) {
n = n.parentElement;
}
return n || editor;
@@ -6553,10 +6629,7 @@ ${galleryPagesHTML}
// Otherwise, remove one indentation level (up to 4 NBSP/spaces) at start of the current block
const getBlock = (node) => {
let n = node.nodeType === Node.TEXT_NODE ? node.parentElement : node;
- while (
- n &&
- !/(P|DIV|LI|H1|H2|H3|H4|H5|H6)/i.test(n.tagName)
- ) {
+ while (n && !/(P|DIV|LI|H1|H2|H3|H4|H5|H6)/i.test(n.tagName)) {
n = n.parentElement;
}
return n || editor;
@@ -7552,7 +7625,9 @@ ${galleryPagesHTML}
// Remove selection from other elements
const editor = element.closest(".enhanced-editor-content");
if (editor) {
- const allDraggable = editor.querySelectorAll(".draggable-element, .draggable-image-container, .draggable-table-container");
+ const allDraggable = editor.querySelectorAll(
+ ".draggable-element, .draggable-image-container, .draggable-table-container"
+ );
allDraggable.forEach((el) => {
if (el !== element) el.classList.remove("selected");
});
@@ -10739,7 +10814,8 @@ ${galleryPagesHTML}
const placeholder = document.createElement("div");
placeholder.style.width = currentWidth + "px";
placeholder.style.height = currentHeight + "px";
- placeholder.style.display = window.getComputedStyle(element).display || "inline-block";
+ placeholder.style.display =
+ window.getComputedStyle(element).display || "inline-block";
const container = document.createElement("div");
container.className = "draggable-image-container";
@@ -10768,7 +10844,8 @@ ${galleryPagesHTML}
element.style.margin = "0";
element.style.display = "block";
element.style.boxSizing = "border-box";
- element.style.objectFit = window.getComputedStyle(element).objectFit || "cover";
+ element.style.objectFit =
+ window.getComputedStyle(element).objectFit || "cover";
// Replace the image in the flow with placeholder, then move image to absolute container
const originalParent = element.parentNode;
@@ -10899,7 +10976,48 @@ ${galleryPagesHTML}
this.logCurrentState();
}
+ // Global function to get a random image from available images
+ getRandomImage() {
+ const fallbackImage =
+ "https://plus.unsplash.com/premium_photo-1676467963268-5a20d7a7a448?q=80&w=687&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D";
+
+ // Get all available images from different sources
+ const allImages = [];
+
+ // Add real property images
+ if (
+ Array.isArray(this.realPropertyImages) &&
+ this.realPropertyImages.length > 0
+ ) {
+ allImages.push(...this.realPropertyImages);
+ }
+
+ // Add property images
+ if (Array.isArray(this.propertyImages) && this.propertyImages.length > 0) {
+ allImages.push(...this.propertyImages);
+ }
+
+ // Add images from all categories
+ Object.values(this.imagesByCategory).forEach((categoryImages) => {
+ if (Array.isArray(categoryImages) && categoryImages.length > 0) {
+ allImages.push(...categoryImages);
+ }
+ });
+
+ // If no images available, return fallback
+ if (allImages.length === 0) {
+ return fallbackImage;
+ }
+
+ // Get a random image from available images
+ const randomIndex = Math.floor(Math.random() * allImages.length);
+ const randomImage = allImages[randomIndex];
+
+ // Return the image URL, handling different possible structures
+ return randomImage?.url || randomImage?.src || randomImage || fallbackImage;
+ }
+
connectedCallback() {
this.loadSavedTemplates();
}
-}
\ No newline at end of file
+}