v1.0.0-rc
This commit is contained in:
parent
eab0d41a64
commit
17a89486e0
@ -85,6 +85,25 @@
|
|||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dev-close-btn {
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
background: #ff6b6b;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 600;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-close-btn:hover {
|
||||||
|
background: #ff5252;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.dev-content {
|
.dev-content {
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
|
|||||||
@ -10,7 +10,9 @@
|
|||||||
value={tbizzInput}
|
value={tbizzInput}
|
||||||
onchange={handleTbizzInputChange}
|
onchange={handleTbizzInputChange}
|
||||||
onkeydown={handleKeyPress}
|
onkeydown={handleKeyPress}
|
||||||
|
placeholder="Enter 'bweixx' to show/hide dev mode"
|
||||||
/>
|
/>
|
||||||
|
<button class="dev-close-btn" onclick={hideDevPage}>✕ Close</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { LightningElement, track } from 'lwc';
|
import { LightningElement, track } from 'lwc';
|
||||||
|
|
||||||
export default class DevelopmentPage extends LightningElement {
|
export default class DevelopmentPage extends LightningElement {
|
||||||
@track showDevPage = true; // Visible by default, hidden when tbizz is entered
|
@track showDevPage = false; // Hidden by default, can be shown by entering bweixx
|
||||||
@track currentStep = 1;
|
@track currentStep = 1;
|
||||||
@track selectedTemplateId = '';
|
@track selectedTemplateId = '';
|
||||||
@track selectedPropertyId = '';
|
@track selectedPropertyId = '';
|
||||||
@ -38,7 +38,7 @@ export default class DevelopmentPage extends LightningElement {
|
|||||||
// Listen for Enter key to check bweixx input
|
// Listen for Enter key to check bweixx input
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
if (this.tbizzInput.toLowerCase() === 'bweixx') {
|
if (this.tbizzInput.toLowerCase() === 'bweixx') {
|
||||||
this.showDevPage = false;
|
this.showDevPage = true; // Show development page when bweixx is entered
|
||||||
this.tbizzInput = ''; // Clear input
|
this.tbizzInput = ''; // Clear input
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -49,6 +49,11 @@ export default class DevelopmentPage extends LightningElement {
|
|||||||
this.tbizzInput = event.target.value;
|
this.tbizzInput = event.target.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hide development page
|
||||||
|
hideDevPage() {
|
||||||
|
this.showDevPage = false;
|
||||||
|
}
|
||||||
|
|
||||||
updateTimestamp() {
|
updateTimestamp() {
|
||||||
this.currentTimestamp = new Date().toLocaleString();
|
this.currentTimestamp = new Date().toLocaleString();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1318,10 +1318,11 @@ export default class PropertyTemplateSelector extends LightningElement {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.forceHTMLRendering();
|
this.forceHTMLRendering();
|
||||||
|
|
||||||
// Add pencil icon to hero section for modern home template, serenity house template, and luxury mansion template
|
// Add pencil icon to hero section for modern home template, serenity house template, luxury mansion template, and grand oak villa template
|
||||||
if (this.selectedTemplateId === 'modern-home-template' || this.selectedTemplateId === 'modern-home-a3-template' ||
|
if (this.selectedTemplateId === 'modern-home-template' || this.selectedTemplateId === 'modern-home-a3-template' ||
|
||||||
this.selectedTemplateId === 'serenity-house-template' || this.selectedTemplateId === 'serenity-house-a3-template' ||
|
this.selectedTemplateId === 'serenity-house-template' || this.selectedTemplateId === 'serenity-house-a3-template' ||
|
||||||
this.selectedTemplateId === 'luxury-mansion-template' || this.selectedTemplateId === 'luxury-mansion-a3-template') {
|
this.selectedTemplateId === 'luxury-mansion-template' || this.selectedTemplateId === 'luxury-mansion-a3-template' ||
|
||||||
|
this.selectedTemplateId === 'grand-oak-villa-template' || this.selectedTemplateId === 'grand-oak-villa-a3-template') {
|
||||||
this.addPencilIconToHeroSection();
|
this.addPencilIconToHeroSection();
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
@ -1693,10 +1694,11 @@ export default class PropertyTemplateSelector extends LightningElement {
|
|||||||
// Force proper HTML rendering to match PDF exactly
|
// Force proper HTML rendering to match PDF exactly
|
||||||
this.forceHTMLRendering();
|
this.forceHTMLRendering();
|
||||||
|
|
||||||
// Add pencil icon to hero section for modern home template, serenity house template, and luxury mansion template
|
// Add pencil icon to hero section for modern home template, serenity house template, luxury mansion template, and grand oak villa template
|
||||||
if (this.selectedTemplateId === 'modern-home-template' || this.selectedTemplateId === 'modern-home-a3-template' ||
|
if (this.selectedTemplateId === 'modern-home-template' || this.selectedTemplateId === 'modern-home-a3-template' ||
|
||||||
this.selectedTemplateId === 'serenity-house-template' || this.selectedTemplateId === 'serenity-house-a3-template' ||
|
this.selectedTemplateId === 'serenity-house-template' || this.selectedTemplateId === 'serenity-house-a3-template' ||
|
||||||
this.selectedTemplateId === 'luxury-mansion-template' || this.selectedTemplateId === 'luxury-mansion-a3-template') {
|
this.selectedTemplateId === 'luxury-mansion-template' || this.selectedTemplateId === 'luxury-mansion-a3-template' ||
|
||||||
|
this.selectedTemplateId === 'grand-oak-villa-template' || this.selectedTemplateId === 'grand-oak-villa-a3-template') {
|
||||||
this.addPencilIconToHeroSection();
|
this.addPencilIconToHeroSection();
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
@ -1766,10 +1768,11 @@ export default class PropertyTemplateSelector extends LightningElement {
|
|||||||
// Force proper HTML rendering to match PDF exactly
|
// Force proper HTML rendering to match PDF exactly
|
||||||
this.forceHTMLRendering();
|
this.forceHTMLRendering();
|
||||||
|
|
||||||
// Add pencil icon to hero section for modern home template, serenity house template, and luxury mansion template
|
// Add pencil icon to hero section for modern home template, serenity house template, luxury mansion template, and grand oak villa template
|
||||||
if (this.selectedTemplateId === 'modern-home-template' || this.selectedTemplateId === 'modern-home-a3-template' ||
|
if (this.selectedTemplateId === 'modern-home-template' || this.selectedTemplateId === 'modern-home-a3-template' ||
|
||||||
this.selectedTemplateId === 'serenity-house-template' || this.selectedTemplateId === 'serenity-house-a3-template' ||
|
this.selectedTemplateId === 'serenity-house-template' || this.selectedTemplateId === 'serenity-house-a3-template' ||
|
||||||
this.selectedTemplateId === 'luxury-mansion-template' || this.selectedTemplateId === 'luxury-mansion-a3-template') {
|
this.selectedTemplateId === 'luxury-mansion-template' || this.selectedTemplateId === 'luxury-mansion-a3-template' ||
|
||||||
|
this.selectedTemplateId === 'grand-oak-villa-template' || this.selectedTemplateId === 'grand-oak-villa-a3-template') {
|
||||||
this.addPencilIconToHeroSection();
|
this.addPencilIconToHeroSection();
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
@ -4545,12 +4548,19 @@ export default class PropertyTemplateSelector extends LightningElement {
|
|||||||
.join("");
|
.join("");
|
||||||
}
|
}
|
||||||
// Template methods
|
// Template methods
|
||||||
|
// Helper method to escape HTML and prevent injection
|
||||||
|
escapeHtml(text) {
|
||||||
|
if (!text) return '';
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.textContent = text;
|
||||||
|
return div.innerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
createBlankTemplate() {
|
createBlankTemplate() {
|
||||||
const data = this.propertyData || {};
|
const data = this.propertyData || {};
|
||||||
const propertyName = data.Name || data.propertyName || "Property Name";
|
const propertyName = data.Name || data.propertyName || "Property Name";
|
||||||
const location = data.Address__c || data.location || "Location";
|
const location = data.Address__c || data.location || "Location";
|
||||||
// Use price toggle to determine what to display
|
const price = data.Price__c || data.price || "Price";
|
||||||
const price = this.showPrice ? (data.Price__c || data.price || "Price") : "Price on Request";
|
|
||||||
const bedrooms = data.Bedrooms__c || data.bedrooms || "N/A";
|
const bedrooms = data.Bedrooms__c || data.bedrooms || "N/A";
|
||||||
const bathrooms = data.Bathrooms__c || data.bathrooms || "N/A";
|
const bathrooms = data.Bathrooms__c || data.bathrooms || "N/A";
|
||||||
const size = data.Square_Feet__c || data.size || "N/A";
|
const size = data.Square_Feet__c || data.size || "N/A";
|
||||||
@ -4567,20 +4577,21 @@ export default class PropertyTemplateSelector extends LightningElement {
|
|||||||
const buildYear = data.Build_Year__c || data.buildYear || "N/A";
|
const buildYear = data.Build_Year__c || data.buildYear || "N/A";
|
||||||
const titleEnglish =
|
const titleEnglish =
|
||||||
data.Title_English__c || data.titleEnglish || "Property Title";
|
data.Title_English__c || data.titleEnglish || "Property Title";
|
||||||
|
let descriptionEnglish =
|
||||||
const descriptionEnglish = this.formatDescriptionForPDF(
|
|
||||||
data.Description_English__c ||
|
data.Description_English__c ||
|
||||||
data.descriptionEnglish ||
|
data.descriptionEnglish ||
|
||||||
data.description ||
|
"Property Description";
|
||||||
"please add your description here..."
|
|
||||||
);
|
|
||||||
|
|
||||||
|
const rawDescription = data.Description_English__c ||
|
||||||
|
data.descriptionEnglish ||
|
||||||
|
data.description ||
|
||||||
|
"This beautiful property offers exceptional value and modern amenities. Located in a prime area, it represents an excellent investment opportunity.";
|
||||||
|
|
||||||
|
const description = this.formatDescriptionForPDF(rawDescription);
|
||||||
|
descriptionEnglish = description;
|
||||||
const rentPriceMin = data.Rent_Price_Min__c || data.rentPriceMin || "N/A";
|
const rentPriceMin = data.Rent_Price_Min__c || data.rentPriceMin || "N/A";
|
||||||
const salePriceMin = data.Sale_Price_Min__c || data.salePriceMin || "N/A";
|
const salePriceMin = data.Sale_Price_Min__c || data.salePriceMin || "N/A";
|
||||||
|
|
||||||
// Define logoUrl for template usage
|
|
||||||
const logoUrl = this.logoUrl;
|
|
||||||
|
|
||||||
// Build gallery pages so ALL images render in the empty template
|
// Build gallery pages so ALL images render in the empty template
|
||||||
const allImages = Array.isArray(this.realPropertyImages)
|
const allImages = Array.isArray(this.realPropertyImages)
|
||||||
? this.realPropertyImages
|
? this.realPropertyImages
|
||||||
@ -4592,86 +4603,39 @@ export default class PropertyTemplateSelector extends LightningElement {
|
|||||||
for (let i = imagesPerPage; i < allImages.length; i += imagesPerPage) {
|
for (let i = imagesPerPage; i < allImages.length; i += imagesPerPage) {
|
||||||
const chunk = allImages.slice(i, i + imagesPerPage);
|
const chunk = allImages.slice(i, i + imagesPerPage);
|
||||||
additionalGalleryPagesHTML += `
|
additionalGalleryPagesHTML += `
|
||||||
<div class="brochure-page a4" style="page-break-before: always;">
|
<div class="brochure-page" style="font-family: Arial, sans-serif; padding: 20px; max-width: 800px; margin: 0 auto; page-break-before: always;">
|
||||||
<div class="gallery-grid">
|
<div style="background: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); margin-bottom: 20px;">
|
||||||
|
<h2 style="color: #0d6efd; border-bottom: 2px solid #0d6efd; padding-bottom: 10px; margin-bottom: 20px; font-size: 1.5rem;">Property Gallery</h2>
|
||||||
|
<div class="gallery-grid" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px;">
|
||||||
${this.generatePropertyGalleryHTMLForImages(chunk)}
|
${this.generatePropertyGalleryHTMLForImages(chunk)}
|
||||||
</div>
|
</div>
|
||||||
|
const rawDescription = data.Description_English__c ||
|
||||||
|
data.descriptionEnglish ||
|
||||||
|
data.description ||
|
||||||
|
"This beautiful property offers exceptional value and modern amenities. Located in a prime area, it represents an excellent investment opportunity.";
|
||||||
|
|
||||||
|
const description = this.formatDescriptionForPDF(rawDescription); </div>
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<style>
|
<div class="brochure-page" style="font-family: Arial, sans-serif; padding: 20px; max-width: 800px; margin: 0 auto;">
|
||||||
.brochure-page.a4 {
|
<!-- Header Section -->
|
||||||
width: 190mm;
|
<div style="position: relative; color: white; padding: 20px; text-align: center; border-radius: 10px; margin-bottom: 20px; overflow: hidden; background: linear-gradient(135deg, #0d6efd 0%, #0b5ed7 100%);">
|
||||||
min-height: 277mm;
|
<img src="${this.getExteriorImageUrl()}" alt="Property Header Image"
|
||||||
padding: 10mm;
|
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1;">
|
||||||
margin: auto;
|
<div style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(135deg, rgba(13, 110, 253, 0.82), rgba(11, 94, 215, 0.82)); z-index: 2;"></div>
|
||||||
background: white;
|
<div style="position: relative; z-index: 3;">
|
||||||
font-family: Arial, sans-serif;
|
<h1 style="margin: 0; font-size: 2.5rem; text-shadow: 2px 2px 4px rgba(0,0,0,0.5);">${propertyName}</h1>
|
||||||
box-shadow: 0 0 0.5cm rgba(0,0,0,0.2);
|
<p style="margin: 10px 0 0 0; font-size: 1.2rem; opacity: 0.9; text-shadow: 1px 1px 2px rgba(0,0,0,0.5);">${location}</p>
|
||||||
box-sizing: border-box;
|
<p style="margin: 5px 0 0 0; font-size: 1.5rem; font-weight: bold; text-shadow: 1px 1px 2px rgba(0,0,0,0.5);">${price}</p>
|
||||||
page-break-after: always;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media print {
|
|
||||||
@page {
|
|
||||||
size: A4;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
background: white;
|
|
||||||
-webkit-print-color-adjust: exact;
|
|
||||||
}
|
|
||||||
|
|
||||||
.brochure {
|
|
||||||
width: 210mm !important;
|
|
||||||
height: 297mm !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
page-break-after: always;
|
|
||||||
}
|
|
||||||
|
|
||||||
.brochure:last-child {
|
|
||||||
page-break-after: avoid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.gallery-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fit, minmax(60mm, 1fr));
|
|
||||||
gap: 10mm;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1, h2, h3, p {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div class="brochure-page a4">
|
|
||||||
<!-- Header -->
|
|
||||||
<div style="position: relative; color: white; text-align: center; border-radius: 6mm; overflow: hidden; margin-bottom: 10mm;">
|
|
||||||
<img src="${this.getExteriorImageUrl()}" alt="Header Image"
|
|
||||||
style="position: absolute; top: 0; left: 0; width: 100%; height: auto; object-fit: cover; z-index: 1;">
|
|
||||||
<div style="position: relative; z-index: 2; padding: 20mm 10mm;">
|
|
||||||
<h1>${propertyName}</h1>
|
|
||||||
<p>${location}</p>
|
|
||||||
<p style="font-weight: bold; font-size: 1.2rem;">${price}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Basic Info -->
|
<!-- Basic Information -->
|
||||||
<section>
|
<div style="background: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); margin-bottom: 20px;">
|
||||||
<h2>Basic Information</h2>
|
<h2 style="color: #0d6efd; border-bottom: 2px solid #0d6efd; padding-bottom: 10px;">Basic Information</h2>
|
||||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 5mm;">
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||||
<div><strong>Property Type:</strong> ${propertyType}</div>
|
<div><strong>Property Type:</strong> ${propertyType}</div>
|
||||||
<div><strong>Status:</strong> ${status}</div>
|
<div><strong>Status:</strong> ${status}</div>
|
||||||
<div><strong>City:</strong> ${city}</div>
|
<div><strong>City:</strong> ${city}</div>
|
||||||
@ -4679,98 +4643,137 @@ export default class PropertyTemplateSelector extends LightningElement {
|
|||||||
<div><strong>Sub Community:</strong> ${subCommunity}</div>
|
<div><strong>Sub Community:</strong> ${subCommunity}</div>
|
||||||
<div><strong>Furnished:</strong> ${furnished}</div>
|
<div><strong>Furnished:</strong> ${furnished}</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</div>
|
||||||
|
|
||||||
<!-- Contact Details -->
|
<!-- Contact Details -->
|
||||||
<section>
|
<div style="background: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); margin-bottom: 20px;">
|
||||||
<h2>Contact Details</h2>
|
<h2 style="color: #0d6efd; border-bottom: 2px solid #0d6efd; padding-bottom: 10px;">Contact Details</h2>
|
||||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 5mm;">
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||||
<div><strong>Name:</strong> ${data.contactName || "N/A"}</div>
|
<div><strong>Name:</strong> ${
|
||||||
<div><strong>Email:</strong> ${data.contactEmail || "N/A"}</div>
|
data.contactName || "N/A"
|
||||||
<div><strong>Phone:</strong> ${data.contactPhone || "N/A"}</div>
|
}</div>
|
||||||
|
<div><strong>Email:</strong> ${
|
||||||
|
data.contactEmail || "N/A"
|
||||||
|
}</div>
|
||||||
|
<div><strong>Phone:</strong> ${
|
||||||
|
data.contactPhone || "N/A"
|
||||||
|
}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Location Details -->
|
<!-- Location Details -->
|
||||||
<section>
|
<div style="background: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); margin-bottom: 20px;">
|
||||||
<h2>Location Details</h2>
|
<h2 style="color: #0d6efd; border-bottom: 2px solid #0d6efd; padding-bottom: 10px;">Location Details</h2>
|
||||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 5mm;">
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||||
<div><strong>City (Bayut):</strong> ${data.cityBayut || "N/A"}</div>
|
<div><strong>City (Bayut):</strong> ${
|
||||||
<div><strong>City (Propertyfinder):</strong> ${data.cityPropertyfinder || "N/A"}</div>
|
data.cityBayut || "N/A"
|
||||||
<div><strong>Community (Bayut):</strong> ${data.communityBayut || "N/A"}</div>
|
}</div>
|
||||||
<div><strong>Sub Community (Bayut):</strong> ${data.subCommunityBayut || "N/A"}</div>
|
<div><strong>City (Propertyfinder):</strong> ${
|
||||||
<div><strong>Locality (Bayut):</strong> ${data.localityBayut || "N/A"}</div>
|
data.cityPropertyfinder || "N/A"
|
||||||
<div><strong>Sub Locality (Bayut):</strong> ${data.subLocalityBayut || "N/A"}</div>
|
}</div>
|
||||||
<div><strong>Tower (Bayut):</strong> ${data.towerBayut || "N/A"}</div>
|
<div><strong>Community (Bayut):</strong> ${
|
||||||
<div><strong>Unit Number:</strong> ${data.unitNumber || "N/A"}</div>
|
data.communityBayut || "N/A"
|
||||||
|
}</div>
|
||||||
|
<div><strong>Sub Community (Bayut):</strong> ${
|
||||||
|
data.subCommunityBayut || "N/A"
|
||||||
|
}</div>
|
||||||
|
<div><strong>Locality (Bayut):</strong> ${
|
||||||
|
data.localityBayut || "N/A"
|
||||||
|
}</div>
|
||||||
|
<div><strong>Sub Locality (Bayut):</strong> ${
|
||||||
|
data.subLocalityBayut || "N/A"
|
||||||
|
}</div>
|
||||||
|
<div><strong>Tower (Bayut):</strong> ${
|
||||||
|
data.towerBayut || "N/A"
|
||||||
|
}</div>
|
||||||
|
<div><strong>Unit Number:</strong> ${
|
||||||
|
data.unitNumber || "N/A"
|
||||||
|
}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Specifications -->
|
<!-- Specifications -->
|
||||||
<section>
|
<div style="background: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); margin-bottom: 20px;">
|
||||||
<h2>Specifications</h2>
|
<h2 style="color: #0d6efd; border-bottom: 2px solid #0d6efd; padding-bottom: 10px;">Specifications</h2>
|
||||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 5mm;">
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||||
<div><strong>Bedrooms:</strong> ${bedrooms}</div>
|
<div><strong>Bedrooms:</strong> ${bedrooms}</div>
|
||||||
<div><strong>Bathrooms:</strong> ${bathrooms}</div>
|
<div><strong>Bathrooms:</strong> ${bathrooms}</div>
|
||||||
<div><strong>Size:</strong> ${size} ${sizeUnit}</div>
|
<div><strong>Size:</strong> ${size} ${sizeUnit}</div>
|
||||||
<div><strong>Parking Spaces:</strong> ${parkingSpaces}</div>
|
<div><strong>Parking Spaces:</strong> ${parkingSpaces}</div>
|
||||||
<div><strong>Build Year:</strong> ${buildYear}</div>
|
<div><strong>Build Year:</strong> ${buildYear}</div>
|
||||||
<div><strong>Floor:</strong> ${data.floor || "N/A"}</div>
|
<div><strong>Floor:</strong> ${
|
||||||
|
data.floor || "N/A"
|
||||||
|
}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Pricing -->
|
<!-- Pricing -->
|
||||||
${this.generatePricingSection()}
|
<div style="background: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); margin-bottom: 20px;">
|
||||||
|
<h2 style="color: #0d6efd; border-bottom: 2px solid #0d6efd; padding-bottom: 10px;">Pricing Information</h2>
|
||||||
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||||
|
<div><strong>Rent Price:</strong> ${rentPriceMin}</div>
|
||||||
|
<div><strong>Sale Price:</strong> ${salePriceMin}</div>
|
||||||
|
<div><strong>Rent Price (Max):</strong> ${
|
||||||
|
data.rentPriceMax || "N/A"
|
||||||
|
}</div>
|
||||||
|
<div><strong>Sale Price (Max):</strong> ${
|
||||||
|
data.salePriceMax || "N/A"
|
||||||
|
}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Rent Availability -->
|
<!-- Rent Availability -->
|
||||||
<section>
|
<div style="background: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); margin-bottom: 20px;">
|
||||||
<h2>Rent Availability</h2>
|
<h2 style="color: #0d6efd; border-bottom: 2px solid #0d6efd; padding-bottom: 10px;">Rent Availability</h2>
|
||||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 5mm;">
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||||
<div><strong>Available From:</strong> ${data.rentAvailableFrom || "N/A"}</div>
|
<div><strong>Rent Available From:</strong> ${
|
||||||
<div><strong>Available To:</strong> ${data.rentAvailableTo || "N/A"}</div>
|
data.rentAvailableFrom || "N/A"
|
||||||
|
}</div>
|
||||||
|
<div><strong>Rent Available To:</strong> ${
|
||||||
|
data.rentAvailableTo || "N/A"
|
||||||
|
}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Description -->
|
<!-- Description -->
|
||||||
<section class="description">
|
<div style="background: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); margin-bottom: 20px;">
|
||||||
<h2>Property Description</h2>
|
<h2 style="color: #0d6efd; border-bottom: 2px solid #0d6efd; padding-bottom: 10px; margin-bottom: 20px; font-size: 1.5rem;">Property Description</h2>
|
||||||
<h3>${titleEnglish}</h3>
|
<div style="margin-bottom: 20px;">
|
||||||
<p>${descriptionEnglish}</p>
|
<h3 style="color: #333; font-size: 1.2rem; margin-bottom: 10px;">${titleEnglish}</h3>
|
||||||
</section>
|
</div>
|
||||||
|
<div style="line-height: 1.8; color: #555; font-size: 1rem; text-align: justify; margin-bottom: 20px;">
|
||||||
|
${descriptionEnglish}
|
||||||
|
</div>
|
||||||
|
<div style="border-top: 1px solid #eee; padding-top: 15px;">
|
||||||
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px; font-size: 0.9rem;">
|
||||||
|
<div><strong style="color: #0d6efd;">Property Type:</strong> ${propertyType}</div>
|
||||||
|
<div><strong style="color: #0d6efd;">Status:</strong> ${status}</div>
|
||||||
|
<div><strong style="color: #0d6efd;">Furnished:</strong> ${furnished}</div>
|
||||||
|
<div><strong style="color: #0d6efd;">Build Year:</strong> ${buildYear}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<!-- Amenities -->
|
<!-- Amenities -->
|
||||||
<section>
|
<div style="background: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); margin-bottom: 20px;">
|
||||||
<h2>Amenities & Features</h2>
|
<h2 style="color: #0d6efd; border-bottom: 2px solid #0d6efd; padding-bottom: 10px;">Amenities & Features</h2>
|
||||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 5mm;">
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||||
<div><strong>Parking Spaces:</strong> ${data.parkingSpaces || "N/A"}</div>
|
<div><strong>Parking Spaces:</strong> ${
|
||||||
<div><strong>Furnished:</strong> ${data.furnished || "N/A"}</div>
|
data.parkingSpaces || "N/A"
|
||||||
<div><strong>Offering Type:</strong> ${data.offeringType || "N/A"}</div>
|
}</div>
|
||||||
<div><strong>Build Year:</strong> ${data.buildYear || "N/A"}</div>
|
<div><strong>Furnished:</strong> ${
|
||||||
${data.privateAmenities && data.privateAmenities !== 'N/A' ?
|
data.furnished || "N/A"
|
||||||
`<div style="grid-column: 1 / -1; margin-top: 10px;">
|
}</div>
|
||||||
<strong>Private Amenities:</strong><br>
|
<div><strong>Offering Type:</strong> ${
|
||||||
<div style="margin-top: 5px; display: flex; flex-wrap: wrap; gap: 8px;">
|
data.offeringType || "N/A"
|
||||||
${this.mapAmenityCodes(data.privateAmenities).map(amenity =>
|
}</div>
|
||||||
`<span style="background: #f0f0f0; padding: 4px 8px; border-radius: 4px; font-size: 0.9em;">${amenity}</span>`
|
<div><strong>Build Year:</strong> ${
|
||||||
).join('')}
|
data.buildYear || "N/A"
|
||||||
|
}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>` : ''
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- Gallery -->
|
|
||||||
<section>
|
|
||||||
<div class="gallery-grid">
|
|
||||||
${firstChunk.length > 0
|
|
||||||
? this.generatePropertyGalleryHTMLForImages(firstChunk)
|
|
||||||
: this.generatePropertyGalleryHTML()
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
${additionalGalleryPagesHTML}
|
|
||||||
|
</div>
|
||||||
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7890,9 +7893,10 @@ ${galleryPagesHTML}
|
|||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 15px;
|
gap: 20px;
|
||||||
height: calc(100% - 120px);
|
height: calc(100% - 120px);
|
||||||
overflow: hidden;
|
overflow: visible;
|
||||||
|
padding: 0 10px;
|
||||||
}
|
}
|
||||||
.floorplan-showcase {
|
.floorplan-showcase {
|
||||||
display: grid;
|
display: grid;
|
||||||
@ -7903,11 +7907,14 @@ ${galleryPagesHTML}
|
|||||||
border-left: 5px solid var(--color-accent-green);
|
border-left: 5px solid var(--color-accent-green);
|
||||||
page-break-inside: avoid;
|
page-break-inside: avoid;
|
||||||
break-inside: avoid;
|
break-inside: avoid;
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
.floorplan-image-p5 {
|
.floorplan-image-p5 {
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
min-height: 200px;
|
min-height: 200px;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
.floorplan-image-p5.residence {
|
.floorplan-image-p5.residence {
|
||||||
background-image: url('https://images.unsplash.com/photo-1740446568651-1d31966b228a?q=80&w=1600&h=1066&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D');
|
background-image: url('https://images.unsplash.com/photo-1740446568651-1d31966b228a?q=80&w=1600&h=1066&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D');
|
||||||
@ -7948,22 +7955,37 @@ ${galleryPagesHTML}
|
|||||||
gap: 15px;
|
gap: 15px;
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
}
|
}
|
||||||
.spec-item {
|
.additional-specs-grid .spec-item {
|
||||||
background-color: var(--color-grey-bg);
|
background-color: var(--color-grey-bg);
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
}
|
}
|
||||||
.spec-item .label {
|
.additional-specs-grid .spec-item .label {
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
color: var(--color-text-muted);
|
color: var(--color-text-muted);
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
.spec-item .value {
|
.additional-specs-grid .spec-item .value {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
color: var(--color-dark);
|
color: var(--color-dark);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Additional Information Section for Luxury Mansion */
|
||||||
|
.additional-info-section-luxury {
|
||||||
|
margin-top: 25px;
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.additional-info-section-luxury .section-title {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-dark);
|
||||||
|
margin-bottom: 15px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
/* --- PAGE 6: LOCATION & CONTACT (REVISED V3) --- */
|
/* --- PAGE 6: LOCATION & CONTACT (REVISED V3) --- */
|
||||||
.page6-main {
|
.page6-main {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
@ -8196,8 +8218,8 @@ ${galleryPagesHTML}
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="margin-top: 10px;">
|
<div class="additional-info-section-luxury">
|
||||||
<h3 class="section-title" >Additional Information</h3>
|
<h3 class="section-title">Additional Information</h3>
|
||||||
<div class="additional-specs-grid">
|
<div class="additional-specs-grid">
|
||||||
<div class="spec-item"><div class="label">Available from</div><div class="value">${this.propertyData.rentAvailableFrom}</div></div>
|
<div class="spec-item"><div class="label">Available from</div><div class="value">${this.propertyData.rentAvailableFrom}</div></div>
|
||||||
<div class="spec-item"><div class="label">Rent Available To</div><div class="value">${this.propertyData.rentAvailableTo}</div></div>
|
<div class="spec-item"><div class="label">Rent Available To</div><div class="value">${this.propertyData.rentAvailableTo}</div></div>
|
||||||
@ -16930,14 +16952,14 @@ ${galleryPagesHTML}
|
|||||||
style.textContent = `
|
style.textContent = `
|
||||||
.hero-edit-icon, .visual-header-edit-icon {
|
.hero-edit-icon, .visual-header-edit-icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 20px;
|
top: 10px;
|
||||||
right: 20px;
|
right: 10px;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
background: rgba(0,0,0,0.7);
|
background: rgba(0,0,0,0.7);
|
||||||
color: white;
|
color: white;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
width: 40px;
|
width: 35px;
|
||||||
height: 40px;
|
height: 35px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -16978,6 +17000,12 @@ ${galleryPagesHTML}
|
|||||||
heroSection = editorContent.querySelector('.cover-page');
|
heroSection = editorContent.querySelector('.cover-page');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For grand oak villa template, look for .cover-page instead
|
||||||
|
if (!heroSection && (this.selectedTemplateId === 'grand-oak-villa-template' || this.selectedTemplateId === 'grand-oak-villa-a3-template')) {
|
||||||
|
console.log('Looking for grand oak villa template cover page...');
|
||||||
|
heroSection = editorContent.querySelector('.cover-page');
|
||||||
|
}
|
||||||
|
|
||||||
if (heroSection) {
|
if (heroSection) {
|
||||||
console.log('Hero section found');
|
console.log('Hero section found');
|
||||||
if (!heroSection.querySelector('.hero-edit-icon')) {
|
if (!heroSection.querySelector('.hero-edit-icon')) {
|
||||||
@ -17003,32 +17031,39 @@ ${galleryPagesHTML}
|
|||||||
console.log('Hero section not found in editor content');
|
console.log('Hero section not found in editor content');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add pencil icon to visual header (page 2)
|
// Add pencil icon to visual header (page 2) or location map container (page 3 for Grand Oak Villa)
|
||||||
console.log('Looking for visual header...');
|
console.log('Looking for visual header or location map container...');
|
||||||
const visualHeader = editorContent.querySelector('.visual-header');
|
let visualHeader = editorContent.querySelector('.visual-header');
|
||||||
|
|
||||||
|
// For Grand Oak Villa template, look for location map container instead
|
||||||
|
if (!visualHeader && (this.selectedTemplateId === 'grand-oak-villa-template' || this.selectedTemplateId === 'grand-oak-villa-a3-template')) {
|
||||||
|
console.log('Looking for Grand Oak Villa location map container...');
|
||||||
|
visualHeader = editorContent.querySelector('.location-map-container');
|
||||||
|
}
|
||||||
|
|
||||||
if (visualHeader) {
|
if (visualHeader) {
|
||||||
console.log('Visual header found');
|
console.log('Visual header or location map container found');
|
||||||
if (!visualHeader.querySelector('.visual-header-edit-icon')) {
|
if (!visualHeader.querySelector('.visual-header-edit-icon')) {
|
||||||
console.log('Creating pencil icon for visual header...');
|
console.log('Creating pencil icon for visual header or location map container...');
|
||||||
// Create pencil icon element
|
// Create pencil icon element
|
||||||
const pencilIcon = document.createElement('div');
|
const pencilIcon = document.createElement('div');
|
||||||
pencilIcon.className = 'visual-header-edit-icon';
|
pencilIcon.className = 'visual-header-edit-icon';
|
||||||
pencilIcon.innerHTML = '<i class="fa-solid fa-pencil" style="font-size: 16px;"></i>';
|
pencilIcon.innerHTML = '<i class="fa-solid fa-pencil" style="font-size: 16px;"></i>';
|
||||||
pencilIcon.title = 'Replace Page 2 Image';
|
pencilIcon.title = 'Replace Page 2 Image';
|
||||||
pencilIcon.onclick = () => {
|
pencilIcon.onclick = () => {
|
||||||
console.log('Visual header pencil icon clicked');
|
console.log('Visual header or location map pencil icon clicked');
|
||||||
// Trigger image replacement for visual header
|
// Trigger image replacement for visual header or location map
|
||||||
this.handleVisualHeaderImageReplacement();
|
this.handleVisualHeaderImageReplacement();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add the pencil icon to the visual header
|
// Add the pencil icon to the visual header or location map container
|
||||||
visualHeader.appendChild(pencilIcon);
|
visualHeader.appendChild(pencilIcon);
|
||||||
console.log('Pencil icon added to visual header successfully');
|
console.log('Pencil icon added to visual header or location map container successfully');
|
||||||
} else {
|
} else {
|
||||||
console.log('Visual header pencil icon already exists');
|
console.log('Visual header or location map container pencil icon already exists');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('Visual header not found in editor content');
|
console.log('Visual header or location map container not found in editor content');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add pencil icon to floor plans section for luxury mansion template
|
// Add pencil icon to floor plans section for luxury mansion template
|
||||||
@ -17085,6 +17120,12 @@ ${galleryPagesHTML}
|
|||||||
heroSection = editorContent.querySelector('.cover-page');
|
heroSection = editorContent.querySelector('.cover-page');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For grand oak villa template, look for .cover-page instead
|
||||||
|
if (!heroSection && (this.selectedTemplateId === 'grand-oak-villa-template' || this.selectedTemplateId === 'grand-oak-villa-a3-template')) {
|
||||||
|
console.log('Looking for grand oak villa template cover page for replacement...');
|
||||||
|
heroSection = editorContent.querySelector('.cover-page');
|
||||||
|
}
|
||||||
|
|
||||||
if (heroSection) {
|
if (heroSection) {
|
||||||
// Get the computed background image
|
// Get the computed background image
|
||||||
const computedStyle = window.getComputedStyle(heroSection);
|
const computedStyle = window.getComputedStyle(heroSection);
|
||||||
@ -17110,19 +17151,26 @@ ${galleryPagesHTML}
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle visual header image replacement (page 2)
|
// Handle visual header image replacement (page 2) or location map container (page 3 for Grand Oak Villa)
|
||||||
handleVisualHeaderImageReplacement() {
|
handleVisualHeaderImageReplacement() {
|
||||||
// Find the visual header background image
|
// Find the visual header background image or location map container
|
||||||
const editorContent = this.template.querySelector('.enhanced-editor-content');
|
const editorContent = this.template.querySelector('.enhanced-editor-content');
|
||||||
if (editorContent) {
|
if (editorContent) {
|
||||||
const visualHeader = editorContent.querySelector('.visual-header');
|
let visualHeader = editorContent.querySelector('.visual-header');
|
||||||
|
|
||||||
|
// For Grand Oak Villa template, look for location map container instead
|
||||||
|
if (!visualHeader && (this.selectedTemplateId === 'grand-oak-villa-template' || this.selectedTemplateId === 'grand-oak-villa-a3-template')) {
|
||||||
|
console.log('Looking for Grand Oak Villa location map container for replacement...');
|
||||||
|
visualHeader = editorContent.querySelector('.location-map-container');
|
||||||
|
}
|
||||||
|
|
||||||
if (visualHeader) {
|
if (visualHeader) {
|
||||||
// Get the computed background image
|
// Get the computed background image
|
||||||
const computedStyle = window.getComputedStyle(visualHeader);
|
const computedStyle = window.getComputedStyle(visualHeader);
|
||||||
const backgroundImage = computedStyle.backgroundImage;
|
const backgroundImage = computedStyle.backgroundImage;
|
||||||
|
|
||||||
if (backgroundImage && backgroundImage !== 'none') {
|
if (backgroundImage && backgroundImage !== 'none') {
|
||||||
// Create a virtual image element for the visual header background
|
// Create a virtual image element for the visual header or location map background
|
||||||
const virtualImg = document.createElement('img');
|
const virtualImg = document.createElement('img');
|
||||||
virtualImg.src = backgroundImage.replace(/url\(['"]?(.+?)['"]?\)/, '$1');
|
virtualImg.src = backgroundImage.replace(/url\(['"]?(.+?)['"]?\)/, '$1');
|
||||||
virtualImg.isBackgroundImage = true;
|
virtualImg.isBackgroundImage = true;
|
||||||
@ -17131,10 +17179,10 @@ ${galleryPagesHTML}
|
|||||||
// Open image replacement for this virtual image
|
// Open image replacement for this virtual image
|
||||||
this.openImageReplacement(virtualImg);
|
this.openImageReplacement(virtualImg);
|
||||||
} else {
|
} else {
|
||||||
console.log('No background image found on visual header');
|
console.log('No background image found on visual header or location map container');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('Visual header not found');
|
console.log('Visual header or location map container not found');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('Enhanced editor content not found');
|
console.log('Enhanced editor content not found');
|
||||||
@ -17421,39 +17469,47 @@ ${galleryPagesHTML}
|
|||||||
// Generate Property Gallery HTML for uncategorized images
|
// Generate Property Gallery HTML for uncategorized images
|
||||||
generatePropertyGalleryHTML() {
|
generatePropertyGalleryHTML() {
|
||||||
if (!this.realPropertyImages || this.realPropertyImages.length === 0) {
|
if (!this.realPropertyImages || this.realPropertyImages.length === 0) {
|
||||||
return "";
|
return `<div class="gallery-item"><div class="gallery-placeholder">No images available</div></div>`.repeat(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
let galleryHTML = "";
|
let galleryHTML = "";
|
||||||
this.realPropertyImages.forEach((image, index) => {
|
this.realPropertyImages.forEach((image, index) => {
|
||||||
const title =
|
const title = this.escapeHtml(image.title || image.pcrm__Title__c || `Property Image ${index + 1}`);
|
||||||
image.title || image.pcrm__Title__c || `Property Image ${index + 1}`;
|
const imageUrl = this.escapeHtml(image.url || '');
|
||||||
galleryHTML += `<div class="gallery-item" style="position: relative; overflow: hidden; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); margin-bottom: 15px; height: 100%; min-height: 300px;">
|
galleryHTML += `<div class="gallery-item">
|
||||||
<img src="${image.url}" alt="${title}" style="width:100%; height:100%; object-fit: cover; display:block; break-inside: avoid; page-break-inside: avoid;"/>
|
<img src="${imageUrl}" alt="${title}" onerror="this.parentElement.innerHTML='<div class=\\"gallery-placeholder\\">Image not available</div>'"/>
|
||||||
<div style="position: absolute; bottom: 0; left: 0; right: 0; background: linear-gradient(transparent, rgba(0,0,0,0.7)); color: white; padding: 10px; font-size: 12px;">
|
|
||||||
${title}
|
|
||||||
</div>
|
|
||||||
</div>`;
|
</div>`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Fill remaining slots with placeholders if needed (6 images per page)
|
||||||
|
const remainingSlots = 6 - this.realPropertyImages.length;
|
||||||
|
for (let i = 0; i < remainingSlots; i++) {
|
||||||
|
galleryHTML += `<div class="gallery-item"><div class="gallery-placeholder">No image</div></div>`;
|
||||||
|
}
|
||||||
|
|
||||||
return galleryHTML;
|
return galleryHTML;
|
||||||
}
|
}
|
||||||
// Generate gallery HTML for a provided subset of images
|
// Generate gallery HTML for a provided subset of images
|
||||||
generatePropertyGalleryHTMLForImages(imagesSubset) {
|
generatePropertyGalleryHTMLForImages(imagesSubset) {
|
||||||
if (!imagesSubset || imagesSubset.length === 0) {
|
if (!imagesSubset || imagesSubset.length === 0) {
|
||||||
return "";
|
return `<div class="gallery-item"><div class="gallery-placeholder">No images available</div></div>`.repeat(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
let galleryHTML = "";
|
let galleryHTML = "";
|
||||||
imagesSubset.forEach((image, index) => {
|
imagesSubset.forEach((image, index) => {
|
||||||
const title =
|
const title = this.escapeHtml(image.title || image.pcrm__Title__c || `Property Image ${index + 1}`);
|
||||||
image.title || image.pcrm__Title__c || `Property Image ${index + 1}`;
|
const imageUrl = this.escapeHtml(image.url || '');
|
||||||
galleryHTML += `<div class="gallery-item" style="position: relative; overflow: hidden; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); margin-bottom: 15px; height: 100%; min-height: 300px;">
|
galleryHTML += `<div class="gallery-item">
|
||||||
<img src="${image.url}" alt="${title}" style="width:100%; height:100%; object-fit: cover; display:block; break-inside: avoid; page-break-inside: avoid;"/>
|
<img src="${imageUrl}" alt="${title}" onerror="this.parentElement.innerHTML='<div class=\\"gallery-placeholder\\">Image not available</div>'"/>
|
||||||
<div style="position: absolute; bottom: 0; left: 0; right: 0; background: linear-gradient(transparent, rgba(0,0,0,0.7)); color: white; padding: 10px; font-size: 12px;">
|
|
||||||
${title}
|
|
||||||
</div>
|
|
||||||
</div>`;
|
</div>`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Fill remaining slots with placeholders if needed (6 images per page)
|
||||||
|
const remainingSlots = 6 - imagesSubset.length;
|
||||||
|
for (let i = 0; i < remainingSlots; i++) {
|
||||||
|
galleryHTML += `<div class="gallery-item"><div class="gallery-placeholder">No image</div></div>`;
|
||||||
|
}
|
||||||
|
|
||||||
return galleryHTML;
|
return galleryHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user