insert property data
This commit is contained in:
parent
9bb7f6a727
commit
2bb4747426
@ -247,7 +247,7 @@
|
||||
.draggable-table-container .resize-handle.resize-sw { bottom: -4px; left: -4px; cursor: sw-resize; }
|
||||
.draggable-table-container .resize-handle.resize-se { bottom: -4px; right: -4px; cursor: se-resize; }
|
||||
/* Draggable table container (mirrors images) */
|
||||
.draggable-table-container { position: absolute; cursor: move; user-select: none; z-index: 1000; border: 2px dashed #667eea; border-radius: 8px; background: #ffffff; }
|
||||
.draggable-table-container { position: absolute; cursor: move; user-select: none; z-index: 1000; border: 2px solid transparent; border-radius: 8px; background: #ffffff; }
|
||||
.draggable-table-container .resize-handle { opacity: 1; }
|
||||
.asgar1-preview .cover-hero { position: relative; height: 180px; overflow: hidden; border-radius: 10px; margin: 12px; background: #222; background-size: cover; background-position: center; }
|
||||
.asgar1-preview .cover-hero::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to bottom, rgba(0,0,0,0.15), rgba(0,0,0,0.35)); }
|
||||
@ -7679,7 +7679,7 @@ late particularay
|
||||
|
||||
.draggable-element:hover,
|
||||
.draggable-element.selected {
|
||||
border-color: #C0A062; /* Gold accent theme */
|
||||
border: 2px solid transparent !important; /* Keep transparent border */
|
||||
background: rgba(102, 126, 234, 0.1);
|
||||
box-shadow: 0 2px 10px rgba(102, 126, 234, 0.3);
|
||||
}
|
||||
@ -8536,20 +8536,27 @@ button, .btn, .toolbar-button, .export-pdf-btn {
|
||||
z-index: 1000;
|
||||
min-width: 100px;
|
||||
min-height: 100px;
|
||||
border: 2px dashed #667eea;
|
||||
border-radius: 8px;
|
||||
background: rgba(102, 126, 234, 0.1);
|
||||
padding: 5px;
|
||||
border: none !important;
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
transition: all 0.2s ease;
|
||||
transform: translate3d(0, 0, 0);
|
||||
box-shadow: none;
|
||||
}
|
||||
.draggable-image-container img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.draggable-image-container img { display: block; }
|
||||
|
||||
.draggable-image-container:hover {
|
||||
border-color: #764ba2;
|
||||
background: rgba(102, 126, 234, 0.15);
|
||||
transform: translate3d(0, -2px, 0);
|
||||
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.2);
|
||||
border: none !important;
|
||||
background: transparent;
|
||||
transform: translate3d(0, 0, 0);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* Minimal frame variant to avoid visual/positional shifts when wrapping existing images */
|
||||
@ -8558,9 +8565,9 @@ button, .btn, .toolbar-button, .export-pdf-btn {
|
||||
.draggable-image-container.no-frame.dragging { border: none; background: transparent; box-shadow: none; transform: none; }
|
||||
|
||||
.draggable-image-container.dragging {
|
||||
border-color: #764ba2;
|
||||
background: rgba(102, 126, 234, 0.2);
|
||||
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);
|
||||
border: none !important;
|
||||
background: transparent;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
transform: scale(1.02);
|
||||
transition: none;
|
||||
z-index: 1001;
|
||||
@ -8658,15 +8665,15 @@ button, .btn, .toolbar-button, .export-pdf-btn {
|
||||
|
||||
/* Dragging state */
|
||||
.draggable-image-container.dragging {
|
||||
border-color: #764ba2;
|
||||
background: rgba(102, 126, 234, 0.2);
|
||||
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);
|
||||
border: none !important;
|
||||
background: transparent;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* Resizing state */
|
||||
.draggable-image-container.resizing {
|
||||
border-color: #ff6b6b;
|
||||
background: rgba(255, 107, 107, 0.1);
|
||||
border: none !important;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Text Alignment Section - Fixed Width */
|
||||
@ -10431,8 +10438,8 @@ img[draggable="true"] {
|
||||
}
|
||||
|
||||
.draggable-image-container.selected {
|
||||
border-color: #C0A062; /* Gold accent theme */
|
||||
box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.2);
|
||||
border: none !important;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.draggable-image-container img {
|
||||
@ -10499,7 +10506,7 @@ img[draggable="true"] {
|
||||
overflow: hidden;
|
||||
}
|
||||
.draggable-table-container.selected {
|
||||
border-color: #C0A062; /* Gold accent theme */
|
||||
border: 2px solid transparent !important; /* Keep transparent border */
|
||||
box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.2);
|
||||
}
|
||||
|
||||
|
||||
@ -846,37 +846,76 @@
|
||||
<div class="toolbar-section">
|
||||
<div class="toolbar-section-title">Insert Property Data</div>
|
||||
<div class="property-insert-grid">
|
||||
<!-- Basic Information -->
|
||||
<button class="property-insert-btn" onclick={insertPropertyName}
|
||||
title="Insert Property Name">
|
||||
Name
|
||||
</button>
|
||||
<button class="property-insert-btn" onclick={insertPropertyPrice}
|
||||
title="Insert Property Price">
|
||||
Price
|
||||
<button class="property-insert-btn" onclick={insertPropertyTitle}
|
||||
title="Insert Property Title">
|
||||
Title
|
||||
</button>
|
||||
<button class="property-insert-btn" onclick={insertPropertyType}
|
||||
title="Insert Property Type">
|
||||
Type
|
||||
</button>
|
||||
<button class="property-insert-btn" onclick={insertPropertyBedrooms}
|
||||
title="Insert Bedrooms">
|
||||
Beds
|
||||
</button>
|
||||
<button class="property-insert-btn" onclick={insertPropertyBathrooms}
|
||||
title="Insert Bathrooms">
|
||||
Baths
|
||||
|
||||
|
||||
|
||||
<!-- Pricing Information -->
|
||||
<button class="property-insert-btn" onclick={insertPropertyPrice}
|
||||
title="Insert Property Price">
|
||||
Price
|
||||
</button>
|
||||
|
||||
|
||||
|
||||
|
||||
<button class="property-insert-btn" onclick={insertPropertySqft}
|
||||
title="Insert Square Footage">
|
||||
Sq Ft
|
||||
</button>
|
||||
<button class="property-insert-btn" onclick={insertPropertyAddress} title="Insert Address">
|
||||
Address
|
||||
<button class="property-insert-btn" onclick={insertPropertyFloor}
|
||||
title="Insert Floor">
|
||||
Floor
|
||||
</button>
|
||||
<button class="property-insert-btn" onclick={insertPropertyDescription}
|
||||
title="Insert Description">
|
||||
Description
|
||||
<button class="property-insert-btn" onclick={insertPropertyBuildYear}
|
||||
title="Insert Build Year">
|
||||
Year
|
||||
</button>
|
||||
<button class="property-insert-btn" onclick={insertPropertyParking}
|
||||
title="Insert Parking">
|
||||
Parking
|
||||
</button>
|
||||
<button class="property-insert-btn" onclick={insertPropertyFurnished}
|
||||
title="Insert Furnished Status">
|
||||
Furnished
|
||||
</button>
|
||||
<button class="property-insert-btn" onclick={insertPropertyOfferingType}
|
||||
title="Insert Offering Type">
|
||||
Offering
|
||||
</button>
|
||||
<!-- Location Information -->
|
||||
<button class="property-insert-btn" onclick={insertPropertyCity}
|
||||
title="Insert City">
|
||||
City
|
||||
</button>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<button class="property-insert-btn" onclick={insertPropertyContactEmail}
|
||||
title="Insert Contact Email">
|
||||
Email
|
||||
</button>
|
||||
<button class="property-insert-btn" onclick={insertPropertyContactPhone}
|
||||
title="Insert Contact Phone">
|
||||
Phone
|
||||
</button>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1399,6 +1399,16 @@ export default class PropertyTemplateSelector extends LightningElement {
|
||||
|
||||
if (editorFrame && editorFrame.innerHTML) {
|
||||
htmlContent = editorFrame.innerHTML;
|
||||
// Check if there are draggable elements - if so, don't regenerate template
|
||||
const tempDiv = document.createElement("div");
|
||||
tempDiv.innerHTML = htmlContent;
|
||||
const draggableElements = tempDiv.querySelectorAll(
|
||||
".draggable-element, .draggable-image-container, .draggable-table-container"
|
||||
);
|
||||
if (draggableElements.length === 0 && htmlContent.length < 100) {
|
||||
// Only regenerate if truly empty and no draggable elements
|
||||
htmlContent = this.createCompleteTemplateHTML();
|
||||
}
|
||||
} else {
|
||||
// Fallback: generate template HTML if editor is empty
|
||||
htmlContent = this.createCompleteTemplateHTML();
|
||||
@ -1502,15 +1512,92 @@ export default class PropertyTemplateSelector extends LightningElement {
|
||||
}
|
||||
// Clean HTML content for PDF generation by removing editor controls
|
||||
cleanHtmlForPdf(htmlContent) {
|
||||
// Wrap editor content so we can sanitize before PDF
|
||||
const tempDiv = document.createElement("div");
|
||||
tempDiv.innerHTML = htmlContent;
|
||||
// Use string manipulation to preserve inline styles better
|
||||
let cleanedHtml = htmlContent;
|
||||
|
||||
// Remove preview-only UI like no-image placeholders
|
||||
const previewOnly = tempDiv.querySelectorAll(
|
||||
'[data-preview-only="true"], .floating-placeholder, .placeholder-badge, .placeholder-bubble'
|
||||
// Remove preview-only UI elements using regex
|
||||
cleanedHtml = cleanedHtml.replace(
|
||||
/<[^>]*(?:data-preview-only="true"|class="[^"]*(?:floating-placeholder|placeholder-badge|placeholder-bubble)[^"]*")[^>]*>.*?<\/[^>]*>/gi,
|
||||
''
|
||||
);
|
||||
previewOnly.forEach((el) => el.remove());
|
||||
|
||||
// Remove resize handles using regex
|
||||
cleanedHtml = cleanedHtml.replace(
|
||||
/<div[^>]*class="[^"]*resize-handle[^"]*"[^>]*>.*?<\/div>/gi,
|
||||
''
|
||||
);
|
||||
|
||||
// Remove delete buttons using regex
|
||||
cleanedHtml = cleanedHtml.replace(
|
||||
/<button[^>]*class="[^"]*delete-btn[^"]*"[^>]*>.*?<\/button>/gi,
|
||||
''
|
||||
);
|
||||
|
||||
// Remove table controls using regex
|
||||
cleanedHtml = cleanedHtml.replace(
|
||||
/<div[^>]*class="[^"]*table-controls-overlay[^"]*"[^>]*>.*?<\/div>/gi,
|
||||
''
|
||||
);
|
||||
|
||||
// Remove editor-specific classes but preserve positioning
|
||||
cleanedHtml = cleanedHtml.replace(
|
||||
/class="([^"]*)(?:selected|dragging)([^"]*)"/gi,
|
||||
'class="$1$2"'
|
||||
);
|
||||
|
||||
// Clean up empty class attributes
|
||||
cleanedHtml = cleanedHtml.replace(/class="\s*"/gi, '');
|
||||
|
||||
// Now use DOM manipulation for more complex operations
|
||||
const tempDiv = document.createElement("div");
|
||||
tempDiv.innerHTML = cleanedHtml;
|
||||
|
||||
// Process draggable elements to ensure proper styling
|
||||
const draggableElements = tempDiv.querySelectorAll(
|
||||
".draggable-element, .draggable-image-container, .draggable-table-container"
|
||||
);
|
||||
draggableElements.forEach((el) => {
|
||||
// Ensure absolute positioning is maintained and properly formatted
|
||||
if (el.style.position === "absolute" || el.classList.contains('draggable-image-container') || el.classList.contains('draggable-element')) {
|
||||
el.style.position = "absolute";
|
||||
|
||||
// Ensure positioning values are properly set
|
||||
if (!el.style.left) el.style.left = "0px";
|
||||
if (!el.style.top) el.style.top = "0px";
|
||||
if (!el.style.zIndex) el.style.zIndex = "1000";
|
||||
|
||||
// Ensure proper box-sizing
|
||||
el.style.boxSizing = "border-box";
|
||||
|
||||
// Remove any borders that might interfere
|
||||
el.style.border = "none";
|
||||
el.style.outline = "none";
|
||||
}
|
||||
|
||||
// Ensure images inside draggable containers maintain proper styling
|
||||
const images = el.querySelectorAll("img");
|
||||
images.forEach(img => {
|
||||
img.style.width = "100%";
|
||||
img.style.height = "100%";
|
||||
img.style.objectFit = "cover";
|
||||
img.style.display = "block";
|
||||
img.style.border = "none";
|
||||
img.style.outline = "none";
|
||||
});
|
||||
|
||||
// Ensure tables maintain proper styling
|
||||
const tables = el.querySelectorAll("table");
|
||||
tables.forEach(table => {
|
||||
table.style.width = "100%";
|
||||
table.style.height = "100%";
|
||||
table.style.borderCollapse = "collapse";
|
||||
table.style.border = "none";
|
||||
table.style.outline = "none";
|
||||
});
|
||||
|
||||
// Remove any editor-specific classes that might interfere
|
||||
el.classList.remove('selected', 'dragging', 'resizing');
|
||||
});
|
||||
|
||||
// Ensure list styling is preserved in output
|
||||
const lists = tempDiv.querySelectorAll("ul, ol");
|
||||
@ -1577,29 +1664,54 @@ export default class PropertyTemplateSelector extends LightningElement {
|
||||
// First, ensure we have template content loaded
|
||||
let htmlContent = "";
|
||||
|
||||
// Check if preview frame has content
|
||||
const previewFrame = this.template.querySelector(
|
||||
// Check if preview frame has content - get from all editor elements
|
||||
const previewFrames = this.template.querySelectorAll(
|
||||
".enhanced-editor-content"
|
||||
);
|
||||
if (!previewFrame) {
|
||||
if (!previewFrames || previewFrames.length === 0) {
|
||||
throw new Error("Editor content not found");
|
||||
}
|
||||
|
||||
htmlContent = previewFrame.innerHTML;
|
||||
// Combine content from all editor frames
|
||||
htmlContent = "";
|
||||
previewFrames.forEach((frame, index) => {
|
||||
if (frame.innerHTML && frame.innerHTML.trim()) {
|
||||
if (htmlContent) {
|
||||
htmlContent += `<div class="page-break"></div>${frame.innerHTML}`;
|
||||
} else {
|
||||
htmlContent = frame.innerHTML;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Debug: Check if draggable elements are present
|
||||
// Debug: Check if draggable elements are present before cleaning
|
||||
const tempDiv = document.createElement("div");
|
||||
tempDiv.innerHTML = htmlContent;
|
||||
const draggableElements = tempDiv.querySelectorAll(
|
||||
".draggable-element, .draggable-image-container, .draggable-table-container"
|
||||
);
|
||||
draggableElements.forEach((el, index) => {});
|
||||
console.log(`Found ${draggableElements.length} draggable elements before cleaning`);
|
||||
|
||||
// Log detailed information about each draggable element
|
||||
draggableElements.forEach((el, index) => {
|
||||
console.log(`Before cleaning - Element ${index}:`, {
|
||||
tagName: el.tagName,
|
||||
className: el.className,
|
||||
position: el.style.position,
|
||||
left: el.style.left,
|
||||
top: el.style.top,
|
||||
width: el.style.width,
|
||||
height: el.style.height,
|
||||
zIndex: el.style.zIndex,
|
||||
outerHTML: el.outerHTML.substring(0, 300) + "..."
|
||||
});
|
||||
});
|
||||
|
||||
// If preview frame is empty, generate the template HTML first
|
||||
// Only regenerate template if there's truly no content (not just short content)
|
||||
if (
|
||||
!htmlContent ||
|
||||
htmlContent.trim() === "" ||
|
||||
htmlContent.length < 100
|
||||
(htmlContent.length < 100 && draggableElements.length === 0)
|
||||
) {
|
||||
this.showProgress("Generating template content...");
|
||||
|
||||
@ -1615,6 +1727,33 @@ export default class PropertyTemplateSelector extends LightningElement {
|
||||
}
|
||||
}
|
||||
|
||||
// Clean HTML content for PDF generation to preserve exact positioning
|
||||
htmlContent = this.cleanHtmlForPdf(htmlContent);
|
||||
|
||||
// Debug: Check if draggable elements are still present after cleaning
|
||||
const tempDivAfter = document.createElement("div");
|
||||
tempDivAfter.innerHTML = htmlContent;
|
||||
const draggableElementsAfter = tempDivAfter.querySelectorAll(
|
||||
".draggable-element, .draggable-image-container, .draggable-table-container"
|
||||
);
|
||||
console.log(`Found ${draggableElementsAfter.length} draggable elements after cleaning`);
|
||||
|
||||
// Log positioning information for debugging
|
||||
draggableElementsAfter.forEach((el, index) => {
|
||||
console.log(`Element ${index}:`, {
|
||||
position: el.style.position,
|
||||
left: el.style.left,
|
||||
top: el.style.top,
|
||||
width: el.style.width,
|
||||
height: el.style.height,
|
||||
className: el.className,
|
||||
outerHTML: el.outerHTML.substring(0, 200) + "..."
|
||||
});
|
||||
});
|
||||
|
||||
// Log the actual HTML being sent to PDF generation
|
||||
console.log("HTML Content being sent to PDF:", htmlContent.substring(0, 1000) + "...");
|
||||
|
||||
// Ensure we have a complete HTML document with page size information
|
||||
if (!htmlContent.includes("<!DOCTYPE html>")) {
|
||||
htmlContent = `<!DOCTYPE html>
|
||||
@ -1664,6 +1803,61 @@ export default class PropertyTemplateSelector extends LightningElement {
|
||||
`
|
||||
: ""
|
||||
}
|
||||
|
||||
/* Draggable elements positioning for PDF */
|
||||
.draggable-element, .draggable-image-container, .draggable-table-container {
|
||||
position: absolute !important;
|
||||
box-sizing: border-box !important;
|
||||
display: block !important;
|
||||
border: none !important;
|
||||
outline: none !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.draggable-element img, .draggable-image-container img {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
object-fit: cover !important;
|
||||
display: block !important;
|
||||
border: none !important;
|
||||
outline: none !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.draggable-table-container table {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
border-collapse: collapse !important;
|
||||
border: none !important;
|
||||
outline: none !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* Ensure absolute positioned elements are rendered correctly in PDF */
|
||||
*[style*="position: absolute"] {
|
||||
position: absolute !important;
|
||||
}
|
||||
|
||||
/* Force positioning for any element with inline styles */
|
||||
div[style*="left"], div[style*="top"] {
|
||||
position: absolute !important;
|
||||
}
|
||||
|
||||
/* Ensure images maintain their positioning */
|
||||
img[style*="left"], img[style*="top"] {
|
||||
position: absolute !important;
|
||||
}
|
||||
|
||||
/* Remove all borders and ensure clean positioning */
|
||||
.draggable-element, .draggable-image-container, .draggable-table-container,
|
||||
.draggable-element *, .draggable-image-container *, .draggable-table-container * {
|
||||
border: none !important;
|
||||
outline: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
</style>
|
||||
<meta name="page-size" content="${this.selectedPageSize}">
|
||||
</head>
|
||||
@ -1837,6 +2031,55 @@ export default class PropertyTemplateSelector extends LightningElement {
|
||||
body {
|
||||
overflow: visible !important;
|
||||
}
|
||||
/* Draggable elements positioning for PDF */
|
||||
.draggable-element, .draggable-image-container, .draggable-table-container {
|
||||
position: absolute !important;
|
||||
box-sizing: border-box !important;
|
||||
display: block !important;
|
||||
border: none !important;
|
||||
outline: none !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
.draggable-element img, .draggable-image-container img {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
object-fit: cover !important;
|
||||
display: block !important;
|
||||
border: none !important;
|
||||
outline: none !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
.draggable-table-container table {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
border-collapse: collapse !important;
|
||||
border: none !important;
|
||||
outline: none !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
/* Ensure absolute positioned elements are rendered correctly in PDF */
|
||||
*[style*="position: absolute"] {
|
||||
position: absolute !important;
|
||||
}
|
||||
/* Force positioning for any element with inline styles */
|
||||
div[style*="left"], div[style*="top"] {
|
||||
position: absolute !important;
|
||||
}
|
||||
/* Ensure images maintain their positioning */
|
||||
img[style*="left"], img[style*="top"] {
|
||||
position: absolute !important;
|
||||
}
|
||||
|
||||
/* Remove all borders and ensure clean positioning */
|
||||
.draggable-element, .draggable-image-container, .draggable-table-container,
|
||||
.draggable-element *, .draggable-image-container *, .draggable-table-container * {
|
||||
border: none !important;
|
||||
outline: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@ -2102,6 +2345,16 @@ export default class PropertyTemplateSelector extends LightningElement {
|
||||
|
||||
if (editorFrame && editorFrame.innerHTML) {
|
||||
htmlContent = editorFrame.innerHTML;
|
||||
// Check if there are draggable elements - if so, don't regenerate template
|
||||
const tempDiv = document.createElement("div");
|
||||
tempDiv.innerHTML = htmlContent;
|
||||
const draggableElements = tempDiv.querySelectorAll(
|
||||
".draggable-element, .draggable-image-container, .draggable-table-container"
|
||||
);
|
||||
if (draggableElements.length === 0 && htmlContent.length < 100) {
|
||||
// Only regenerate if truly empty and no draggable elements
|
||||
htmlContent = this.createCompleteTemplateHTML();
|
||||
}
|
||||
} else {
|
||||
htmlContent = this.createCompleteTemplateHTML();
|
||||
}
|
||||
@ -2452,13 +2705,17 @@ export default class PropertyTemplateSelector extends LightningElement {
|
||||
const buildYear = data.Build_Year__c || data.buildYear || "N/A";
|
||||
const titleEnglish =
|
||||
data.Title_English__c || data.titleEnglish || "Property Title";
|
||||
const descriptionEnglish =
|
||||
|
||||
const descriptionEnglish = this.formatDescriptionForPDF(
|
||||
data.Description_English__c ||
|
||||
data.descriptionEnglish ||
|
||||
"Property Description";
|
||||
data.descriptionEnglish ||
|
||||
data.description ||
|
||||
"please add your description here..."
|
||||
);
|
||||
|
||||
const rentPriceMin = data.Rent_Price_Min__c || data.rentPriceMin || "N/A";
|
||||
const salePriceMin = data.Sale_Price_Min__c || data.salePriceMin || "N/A";
|
||||
|
||||
|
||||
// Build gallery pages so ALL images render in the empty template
|
||||
const allImages = Array.isArray(this.realPropertyImages)
|
||||
? this.realPropertyImages
|
||||
@ -2470,185 +2727,182 @@ export default class PropertyTemplateSelector extends LightningElement {
|
||||
for (let i = imagesPerPage; i < allImages.length; i += imagesPerPage) {
|
||||
const chunk = allImages.slice(i, i + imagesPerPage);
|
||||
additionalGalleryPagesHTML += `
|
||||
<div class="brochure-page" style="font-family: Arial, sans-serif; padding: 20px; max-width: 800px; margin: 0 auto; page-break-before: always;">
|
||||
<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)}
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
<div class="brochure-page a4" style="page-break-before: always;">
|
||||
<h2>Property Gallery</h2>
|
||||
<div class="gallery-grid">
|
||||
${this.generatePropertyGalleryHTMLForImages(chunk)}
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
return `
|
||||
<div class="brochure-page" style="font-family: Arial, sans-serif; padding: 20px; max-width: 800px; margin: 0 auto;">
|
||||
<!-- Header Section -->
|
||||
<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%);">
|
||||
<img src="${this.getExteriorImageUrl()}" alt="Property Header Image"
|
||||
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1;">
|
||||
<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>
|
||||
<div style="position: relative; z-index: 3;">
|
||||
<h1 style="margin: 0; font-size: 2.5rem; text-shadow: 2px 2px 4px rgba(0,0,0,0.5);">${propertyName}</h1>
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Basic Information -->
|
||||
<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;">Basic Information</h2>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||
<div><strong>Property Type:</strong> ${propertyType}</div>
|
||||
<div><strong>Status:</strong> ${status}</div>
|
||||
<div><strong>City:</strong> ${city}</div>
|
||||
<div><strong>Community:</strong> ${community}</div>
|
||||
<div><strong>Sub Community:</strong> ${subCommunity}</div>
|
||||
<div><strong>Furnished:</strong> ${furnished}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contact Details -->
|
||||
<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;">Contact Details</h2>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||
<div><strong>Name:</strong> ${
|
||||
data.contactName || "N/A"
|
||||
}</div>
|
||||
<div><strong>Email:</strong> ${
|
||||
data.contactEmail || "N/A"
|
||||
}</div>
|
||||
<div><strong>Phone:</strong> ${
|
||||
data.contactPhone || "N/A"
|
||||
}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Location Details -->
|
||||
<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;">Location Details</h2>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||
<div><strong>City (Bayut):</strong> ${
|
||||
data.cityBayut || "N/A"
|
||||
}</div>
|
||||
<div><strong>City (Propertyfinder):</strong> ${
|
||||
data.cityPropertyfinder || "N/A"
|
||||
}</div>
|
||||
<div><strong>Community (Bayut):</strong> ${
|
||||
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>
|
||||
|
||||
<!-- Specifications -->
|
||||
<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;">Specifications</h2>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||
<div><strong>Bedrooms:</strong> ${bedrooms}</div>
|
||||
<div><strong>Bathrooms:</strong> ${bathrooms}</div>
|
||||
<div><strong>Size:</strong> ${size} ${sizeUnit}</div>
|
||||
<div><strong>Parking Spaces:</strong> ${parkingSpaces}</div>
|
||||
<div><strong>Build Year:</strong> ${buildYear}</div>
|
||||
<div><strong>Floor:</strong> ${
|
||||
data.floor || "N/A"
|
||||
}</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Pricing -->
|
||||
<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 -->
|
||||
<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;">Rent Availability</h2>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||
<div><strong>Rent Available From:</strong> ${
|
||||
data.rentAvailableFrom || "N/A"
|
||||
}</div>
|
||||
<div><strong>Rent Available To:</strong> ${
|
||||
data.rentAvailableTo || "N/A"
|
||||
}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 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 style="color: #0d6efd; border-bottom: 2px solid #0d6efd; padding-bottom: 10px; margin-bottom: 20px; font-size: 1.5rem;">Property Description</h2>
|
||||
<div style="margin-bottom: 20px;">
|
||||
<h3 style="color: #333; font-size: 1.2rem; margin-bottom: 10px;">${titleEnglish}</h3>
|
||||
</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 -->
|
||||
<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;">Amenities & Features</h2>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||
<div><strong>Parking Spaces:</strong> ${
|
||||
data.parkingSpaces || "N/A"
|
||||
}</div>
|
||||
<div><strong>Furnished:</strong> ${
|
||||
data.furnished || "N/A"
|
||||
}</div>
|
||||
<div><strong>Offering Type:</strong> ${
|
||||
data.offeringType || "N/A"
|
||||
}</div>
|
||||
<div><strong>Build Year:</strong> ${
|
||||
data.buildYear || "N/A"
|
||||
}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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;">
|
||||
${
|
||||
firstChunk.length > 0
|
||||
? this.generatePropertyGalleryHTMLForImages(
|
||||
firstChunk
|
||||
)
|
||||
: this.generatePropertyGalleryHTML()
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
${additionalGalleryPagesHTML}
|
||||
`;
|
||||
<style>
|
||||
.brochure-page.a4 {
|
||||
width: 190mm;
|
||||
min-height: 277mm;
|
||||
padding: 10mm;
|
||||
margin: auto;
|
||||
background: white;
|
||||
font-family: Arial, sans-serif;
|
||||
box-shadow: 0 0 0.5cm rgba(0,0,0,0.2);
|
||||
box-sizing: border-box;
|
||||
page-break-after: always;
|
||||
}
|
||||
|
||||
@media print {
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 10mm;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-webkit-print-color-adjust: exact;
|
||||
}
|
||||
|
||||
.brochure-page.a4 {
|
||||
box-shadow: none;
|
||||
page-break-inside: 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>
|
||||
|
||||
<!-- Basic Info -->
|
||||
<section>
|
||||
<h2>Basic Information</h2>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 5mm;">
|
||||
<div><strong>Property Type:</strong> ${propertyType}</div>
|
||||
<div><strong>Status:</strong> ${status}</div>
|
||||
<div><strong>City:</strong> ${city}</div>
|
||||
<div><strong>Community:</strong> ${community}</div>
|
||||
<div><strong>Sub Community:</strong> ${subCommunity}</div>
|
||||
<div><strong>Furnished:</strong> ${furnished}</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Contact Details -->
|
||||
<section>
|
||||
<h2>Contact Details</h2>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 5mm;">
|
||||
<div><strong>Name:</strong> ${data.contactName || "N/A"}</div>
|
||||
<div><strong>Email:</strong> ${data.contactEmail || "N/A"}</div>
|
||||
<div><strong>Phone:</strong> ${data.contactPhone || "N/A"}</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Location Details -->
|
||||
<section>
|
||||
<h2>Location Details</h2>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 5mm;">
|
||||
<div><strong>City (Bayut):</strong> ${data.cityBayut || "N/A"}</div>
|
||||
<div><strong>City (Propertyfinder):</strong> ${data.cityPropertyfinder || "N/A"}</div>
|
||||
<div><strong>Community (Bayut):</strong> ${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>
|
||||
</section>
|
||||
|
||||
<!-- Specifications -->
|
||||
<section>
|
||||
<h2>Specifications</h2>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 5mm;">
|
||||
<div><strong>Bedrooms:</strong> ${bedrooms}</div>
|
||||
<div><strong>Bathrooms:</strong> ${bathrooms}</div>
|
||||
<div><strong>Size:</strong> ${size} ${sizeUnit}</div>
|
||||
<div><strong>Parking Spaces:</strong> ${parkingSpaces}</div>
|
||||
<div><strong>Build Year:</strong> ${buildYear}</div>
|
||||
<div><strong>Floor:</strong> ${data.floor || "N/A"}</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Pricing -->
|
||||
<section>
|
||||
<h2>Pricing</h2>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 5mm;">
|
||||
<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>
|
||||
</section>
|
||||
|
||||
<!-- Rent Availability -->
|
||||
<section>
|
||||
<h2>Rent Availability</h2>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 5mm;">
|
||||
<div><strong>Available From:</strong> ${data.rentAvailableFrom || "N/A"}</div>
|
||||
<div><strong>Available To:</strong> ${data.rentAvailableTo || "N/A"}</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Description -->
|
||||
<section>
|
||||
<h2>Property Description</h2>
|
||||
<h3>${titleEnglish}</h3>
|
||||
<p style="line-height: 1.6; text-align: justify;">${descriptionEnglish}</p>
|
||||
</section>
|
||||
|
||||
<!-- Amenities -->
|
||||
<section>
|
||||
<h2>Amenities & Features</h2>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 5mm;">
|
||||
<div><strong>Parking Spaces:</strong> ${data.parkingSpaces || "N/A"}</div>
|
||||
<div><strong>Furnished:</strong> ${data.furnished || "N/A"}</div>
|
||||
<div><strong>Offering Type:</strong> ${data.offeringType || "N/A"}</div>
|
||||
<div><strong>Build Year:</strong> ${data.buildYear || "N/A"}</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Gallery -->
|
||||
<section>
|
||||
<h2>Property Gallery</h2>
|
||||
<div class="gallery-grid">
|
||||
${
|
||||
firstChunk.length > 0
|
||||
? this.generatePropertyGalleryHTMLForImages(firstChunk)
|
||||
: this.generatePropertyGalleryHTML()
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
${additionalGalleryPagesHTML}
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
createModernHomeTemplate() {
|
||||
const data = this.propertyData || {};
|
||||
@ -6687,49 +6941,152 @@ ${galleryPagesHTML}
|
||||
|
||||
// Property insertion functions
|
||||
insertPropertyName() {
|
||||
const propertyName = this.propertyData.Name || "Property Name";
|
||||
this.insertTextAtCursor(propertyName);
|
||||
const propertyName = this.propertyData.propertyName || this.propertyData.Name || "Property Name";
|
||||
this.insertTextAtCursor(`Name: ${propertyName}`);
|
||||
}
|
||||
|
||||
insertPropertyPrice() {
|
||||
const price = this.propertyData.Price__c || "$0";
|
||||
this.insertTextAtCursor(price);
|
||||
const price = this.propertyData.price || this.propertyData.rentPriceMin || this.propertyData.salePriceMin || "Price on Request";
|
||||
this.insertTextAtCursor(`Price: ${price}`);
|
||||
}
|
||||
|
||||
insertPropertyType() {
|
||||
const type = this.propertyData.Property_Type__c || "Property Type";
|
||||
this.insertTextAtCursor(type);
|
||||
const type = this.propertyData.propertyType || this.propertyData.Property_Type__c || "Property Type";
|
||||
this.insertTextAtCursor(`Type: ${type}`);
|
||||
}
|
||||
|
||||
insertPropertyBathrooms() {
|
||||
const bathrooms = this.propertyData.Bathrooms__c || "0";
|
||||
this.insertTextAtCursor(bathrooms + " Bathrooms");
|
||||
const bathrooms = this.propertyData.bathrooms || this.propertyData.Bathrooms__c || "0";
|
||||
this.insertTextAtCursor(`Bathrooms: ${bathrooms}`);
|
||||
}
|
||||
|
||||
insertPropertySqft() {
|
||||
const sqft = this.propertyData.Square_Footage__c || "0";
|
||||
this.insertTextAtCursor(sqft + " sq ft");
|
||||
const sqft = this.propertyData.area || this.propertyData.size || this.propertyData.Square_Footage__c || "0";
|
||||
this.insertTextAtCursor(`Square Footage: ${sqft}`);
|
||||
}
|
||||
|
||||
insertPropertyAddress() {
|
||||
const address = this.propertyData.Location__c || "Property Address";
|
||||
this.insertTextAtCursor(address);
|
||||
const address = this.propertyData.location || this.propertyData.Location__c || "Property Address";
|
||||
this.insertTextAtCursor(`Address: ${address}`);
|
||||
}
|
||||
|
||||
insertPropertyDescription() {
|
||||
const description =
|
||||
this.propertyData.Description_English__c ||
|
||||
this.propertyData.pcrm__Description_English__c ||
|
||||
this.propertyData.Description__c ||
|
||||
"Property Description";
|
||||
const description = this.propertyData.descriptionEnglish || this.propertyData.Description_English__c || this.propertyData.Description__c || "Property Description";
|
||||
// Wrap into paragraphs and basic formatting
|
||||
const lines = String(description)
|
||||
.split(/\n+/)
|
||||
.map((l) => l.trim())
|
||||
.filter(Boolean);
|
||||
const html = lines.map((l) => `<p>${l}</p>`).join("");
|
||||
const html = lines.map((l) => `<p><strong>Description:</strong> ${l}</p>`).join("");
|
||||
this.insertHtmlAtCursor(html);
|
||||
}
|
||||
|
||||
// Additional property insertion methods
|
||||
insertPropertyBedrooms() {
|
||||
const bedrooms = this.propertyData.bedrooms || this.propertyData.Bedrooms__c || "0";
|
||||
this.insertTextAtCursor(`Bedrooms: ${bedrooms}`);
|
||||
}
|
||||
|
||||
insertPropertyStatus() {
|
||||
const status = this.propertyData.status || this.propertyData.Status__c || "Available";
|
||||
this.insertTextAtCursor(`Status: ${status}`);
|
||||
}
|
||||
|
||||
insertPropertyCity() {
|
||||
const city = this.propertyData.city || this.propertyData.City__c || "City";
|
||||
this.insertTextAtCursor(`City: ${city}`);
|
||||
}
|
||||
|
||||
insertPropertyCommunity() {
|
||||
const community = this.propertyData.community || this.propertyData.Community__c || "Community";
|
||||
this.insertTextAtCursor(`Community: ${community}`);
|
||||
}
|
||||
|
||||
insertPropertyFloor() {
|
||||
const floor = this.propertyData.floor || this.propertyData.Floor__c || "N/A";
|
||||
this.insertTextAtCursor(`Floor: ${floor}`);
|
||||
}
|
||||
|
||||
insertPropertyBuildYear() {
|
||||
const buildYear = this.propertyData.buildYear || this.propertyData.yearBuilt || this.propertyData.Build_Year__c || "N/A";
|
||||
this.insertTextAtCursor(`Build Year: ${buildYear}`);
|
||||
}
|
||||
|
||||
insertPropertyParking() {
|
||||
const parking = this.propertyData.parking || this.propertyData.parkingSpaces || this.propertyData.Parking_Spaces__c || "N/A";
|
||||
this.insertTextAtCursor(`Parking: ${parking}`);
|
||||
}
|
||||
|
||||
insertPropertyFurnished() {
|
||||
const furnished = this.propertyData.furnished || this.propertyData.furnishing || this.propertyData.Furnished__c || "N/A";
|
||||
this.insertTextAtCursor(`Furnished: ${furnished}`);
|
||||
}
|
||||
|
||||
insertPropertyOfferingType() {
|
||||
const offeringType = this.propertyData.offeringType || this.propertyData.Offering_Type__c || "N/A";
|
||||
this.insertTextAtCursor(`Offering Type: ${offeringType}`);
|
||||
}
|
||||
|
||||
insertPropertyRentPrice() {
|
||||
const rentPrice = this.propertyData.rentPriceMin || this.propertyData.Rent_Price_min__c || "N/A";
|
||||
this.insertTextAtCursor(`Rent Price: ${rentPrice}`);
|
||||
}
|
||||
|
||||
insertPropertySalePrice() {
|
||||
const salePrice = this.propertyData.salePriceMin || this.propertyData.Sale_Price_min__c || "N/A";
|
||||
this.insertTextAtCursor(`Sale Price: ${salePrice}`);
|
||||
}
|
||||
|
||||
insertPropertyContactName() {
|
||||
const contactName = this.propertyData.contactName || this.propertyData.Contact_Name__c || "Contact Name";
|
||||
this.insertTextAtCursor(`Contact: ${contactName}`);
|
||||
}
|
||||
|
||||
insertPropertyContactEmail() {
|
||||
const contactEmail = this.propertyData.contactEmail || this.propertyData.Contact_Email__c || "contact@example.com";
|
||||
this.insertTextAtCursor(`Email: ${contactEmail}`);
|
||||
}
|
||||
|
||||
insertPropertyContactPhone() {
|
||||
const contactPhone = this.propertyData.contactPhone || this.propertyData.Contact_Phone__c || "N/A";
|
||||
this.insertTextAtCursor(`Phone: ${contactPhone}`);
|
||||
}
|
||||
|
||||
insertPropertyReferenceNumber() {
|
||||
const referenceNumber = this.propertyData.referenceNumber || this.propertyData.Reference_Number__c || "REF-001";
|
||||
this.insertTextAtCursor(`Reference: ${referenceNumber}`);
|
||||
}
|
||||
|
||||
insertPropertyTitle() {
|
||||
const title = this.propertyData.titleEnglish || this.propertyData.Title_English__c || "Property Title";
|
||||
this.insertTextAtCursor(`Title: ${title}`);
|
||||
}
|
||||
|
||||
insertPropertyLocality() {
|
||||
const locality = this.propertyData.locality || this.propertyData.Locality__c || "Locality";
|
||||
this.insertTextAtCursor(`Locality: ${locality}`);
|
||||
}
|
||||
|
||||
insertPropertyTower() {
|
||||
const tower = this.propertyData.tower || this.propertyData.Tower__c || "N/A";
|
||||
this.insertTextAtCursor(`Tower: ${tower}`);
|
||||
}
|
||||
|
||||
insertPropertyUnitNumber() {
|
||||
const unitNumber = this.propertyData.unitNumber || this.propertyData.Unit_Number__c || "N/A";
|
||||
this.insertTextAtCursor(`Unit Number: ${unitNumber}`);
|
||||
}
|
||||
|
||||
insertPropertyRentAvailableFrom() {
|
||||
const rentAvailableFrom = this.propertyData.rentAvailableFrom || this.propertyData.Rent_Available_From__c || "N/A";
|
||||
this.insertTextAtCursor(`Available From: ${rentAvailableFrom}`);
|
||||
}
|
||||
|
||||
insertPropertyRentAvailableTo() {
|
||||
const rentAvailableTo = this.propertyData.rentAvailableTo || this.propertyData.Rent_Available_To__c || "N/A";
|
||||
this.insertTextAtCursor(`Available To: ${rentAvailableTo}`);
|
||||
}
|
||||
|
||||
// Helper function to insert text at cursor position
|
||||
insertTextAtCursor(text) {
|
||||
const selection = window.getSelection();
|
||||
@ -7368,9 +7725,11 @@ ${galleryPagesHTML}
|
||||
imageContainer.style.zIndex = "1000";
|
||||
imageContainer.style.position = "absolute";
|
||||
imageContainer.style.overflow = "hidden";
|
||||
imageContainer.style.border = "2px solid transparent";
|
||||
imageContainer.style.border = "none";
|
||||
imageContainer.style.cursor = "move";
|
||||
imageContainer.style.userSelect = "none";
|
||||
imageContainer.style.boxSizing = "border-box";
|
||||
imageContainer.style.borderRadius = "4px";
|
||||
|
||||
// Create image element
|
||||
const img = document.createElement("img");
|
||||
@ -7380,6 +7739,9 @@ ${galleryPagesHTML}
|
||||
img.style.height = "100%";
|
||||
img.style.objectFit = "cover";
|
||||
img.style.display = "block";
|
||||
img.style.border = "none";
|
||||
img.style.outline = "none";
|
||||
img.style.borderRadius = "4px";
|
||||
|
||||
imageContainer.appendChild(img);
|
||||
|
||||
@ -7427,7 +7789,7 @@ ${galleryPagesHTML}
|
||||
this.saveUndoState();
|
||||
this.setupEditorClickHandler();
|
||||
const imageContainer = document.createElement("div");
|
||||
imageContainer.className = "draggable-element";
|
||||
imageContainer.className = "draggable-image-container";
|
||||
imageContainer.style.left = "50px";
|
||||
imageContainer.style.top = "50px";
|
||||
imageContainer.style.width = "200px";
|
||||
@ -7435,6 +7797,9 @@ ${galleryPagesHTML}
|
||||
imageContainer.style.zIndex = "1000";
|
||||
imageContainer.style.position = "absolute";
|
||||
imageContainer.style.overflow = "hidden";
|
||||
imageContainer.style.border = "none";
|
||||
imageContainer.style.boxSizing = "border-box";
|
||||
imageContainer.style.borderRadius = "4px";
|
||||
|
||||
const img = document.createElement("img");
|
||||
img.src = event.target.result;
|
||||
@ -7443,6 +7808,9 @@ ${galleryPagesHTML}
|
||||
img.style.width = "100%";
|
||||
img.style.height = "100%";
|
||||
img.style.objectFit = "cover";
|
||||
img.style.border = "none";
|
||||
img.style.outline = "none";
|
||||
img.style.borderRadius = "4px";
|
||||
|
||||
imageContainer.appendChild(img);
|
||||
|
||||
@ -8012,7 +8380,7 @@ ${galleryPagesHTML}
|
||||
imageContainer.style.height = "200px";
|
||||
imageContainer.style.cursor = "move";
|
||||
imageContainer.style.zIndex = "1000";
|
||||
imageContainer.style.border = "2px dashed #667eea";
|
||||
imageContainer.style.border = "2px solid transparent";
|
||||
imageContainer.style.borderRadius = "4px";
|
||||
imageContainer.style.overflow = "hidden";
|
||||
|
||||
@ -10316,7 +10684,7 @@ ${galleryPagesHTML}
|
||||
textElement.style.minWidth = "150px";
|
||||
textElement.style.minHeight = "30px";
|
||||
textElement.style.padding = "8px";
|
||||
textElement.style.border = "2px dashed #4f46e5";
|
||||
textElement.style.border = "2px solid transparent";
|
||||
textElement.style.borderRadius = "4px";
|
||||
textElement.style.backgroundColor = "rgba(255, 255, 255, 0.9)";
|
||||
textElement.style.zIndex = "1000";
|
||||
|
||||
Loading…
Reference in New Issue
Block a user