v1.0.1-beta
This commit is contained in:
parent
0f7a887d50
commit
e51c79d402
328
.deploy_last.json
Normal file
328
.deploy_last.json
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
{
|
||||||
|
"status": 0,
|
||||||
|
"result": {
|
||||||
|
"checkOnly": false,
|
||||||
|
"completedDate": "2025-09-07T02:50:58.000Z",
|
||||||
|
"createdBy": "005a3000000Uv2T",
|
||||||
|
"createdByName": "Property Master",
|
||||||
|
"createdDate": "2025-09-07T02:50:52.000Z",
|
||||||
|
"details": {
|
||||||
|
"componentSuccesses": [
|
||||||
|
{
|
||||||
|
"changed": false,
|
||||||
|
"componentType": "CustomField",
|
||||||
|
"created": false,
|
||||||
|
"createdDate": "2025-09-07T02:50:56.000Z",
|
||||||
|
"deleted": false,
|
||||||
|
"fileName": "objects/Property_Template__c.object",
|
||||||
|
"fullName": "Property_Template__c.Description__c",
|
||||||
|
"id": "00NFV000001x1kH2AQ",
|
||||||
|
"success": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"changed": false,
|
||||||
|
"componentType": "CustomField",
|
||||||
|
"created": false,
|
||||||
|
"createdDate": "2025-09-07T02:50:56.000Z",
|
||||||
|
"deleted": false,
|
||||||
|
"fileName": "objects/Property_Template__c.object",
|
||||||
|
"fullName": "Property_Template__c.Is_Active__c",
|
||||||
|
"id": "00NFV000001x1kI2AQ",
|
||||||
|
"success": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"changed": false,
|
||||||
|
"componentType": "CustomField",
|
||||||
|
"created": false,
|
||||||
|
"createdDate": "2025-09-07T02:50:56.000Z",
|
||||||
|
"deleted": false,
|
||||||
|
"fileName": "objects/Property_Template__c.object",
|
||||||
|
"fullName": "Property_Template__c.Preview_Image_URL__c",
|
||||||
|
"id": "00NFV000001x1kJ2AQ",
|
||||||
|
"success": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"changed": false,
|
||||||
|
"componentType": "CustomField",
|
||||||
|
"created": false,
|
||||||
|
"createdDate": "2025-09-07T02:50:56.000Z",
|
||||||
|
"deleted": false,
|
||||||
|
"fileName": "objects/Property_Template__c.object",
|
||||||
|
"fullName": "Property_Template__c.Tags__c",
|
||||||
|
"id": "00NFV000001x1kK2AQ",
|
||||||
|
"success": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"changed": false,
|
||||||
|
"componentType": "CustomField",
|
||||||
|
"created": false,
|
||||||
|
"createdDate": "2025-09-07T02:50:56.000Z",
|
||||||
|
"deleted": false,
|
||||||
|
"fileName": "objects/Property_Template__c.object",
|
||||||
|
"fullName": "Property_Template__c.Template_Definition__c",
|
||||||
|
"id": "00NFV000001x1kL2AQ",
|
||||||
|
"success": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"changed": false,
|
||||||
|
"componentType": "ApexClass",
|
||||||
|
"created": false,
|
||||||
|
"createdDate": "2025-09-07T02:50:57.000Z",
|
||||||
|
"deleted": false,
|
||||||
|
"fileName": "classes/PdfApiController.cls",
|
||||||
|
"fullName": "PdfApiController",
|
||||||
|
"id": "01pFV000001hBIzYAM",
|
||||||
|
"success": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"changed": false,
|
||||||
|
"componentType": "ApexClass",
|
||||||
|
"created": false,
|
||||||
|
"createdDate": "2025-09-07T02:50:57.000Z",
|
||||||
|
"deleted": false,
|
||||||
|
"fileName": "classes/PropertyDataController.cls",
|
||||||
|
"fullName": "PropertyDataController",
|
||||||
|
"id": "01pFV000001hATNYA2",
|
||||||
|
"success": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"changed": false,
|
||||||
|
"componentType": "ApexClass",
|
||||||
|
"created": false,
|
||||||
|
"createdDate": "2025-09-07T02:50:57.000Z",
|
||||||
|
"deleted": false,
|
||||||
|
"fileName": "classes/PropertyPdfGeneratorController.cls",
|
||||||
|
"fullName": "PropertyPdfGeneratorController",
|
||||||
|
"id": "01pFV000001hDhNYAU",
|
||||||
|
"success": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"changed": false,
|
||||||
|
"componentType": "ApexClass",
|
||||||
|
"created": false,
|
||||||
|
"createdDate": "2025-09-07T02:50:57.000Z",
|
||||||
|
"deleted": false,
|
||||||
|
"fileName": "classes/PropertyTemplateController.cls",
|
||||||
|
"fullName": "PropertyTemplateController",
|
||||||
|
"id": "01pFV000001hAA1YAM",
|
||||||
|
"success": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"changed": true,
|
||||||
|
"componentType": "LightningComponentBundle",
|
||||||
|
"created": false,
|
||||||
|
"createdDate": "2025-09-07T02:50:58.000Z",
|
||||||
|
"deleted": false,
|
||||||
|
"fileName": "lwc/propertyTemplateSelector",
|
||||||
|
"fullName": "propertyTemplateSelector",
|
||||||
|
"id": "0RbFV0000008L7J0AU",
|
||||||
|
"success": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"changed": true,
|
||||||
|
"componentType": "CustomObject",
|
||||||
|
"created": false,
|
||||||
|
"createdDate": "2025-09-07T02:50:58.000Z",
|
||||||
|
"deleted": false,
|
||||||
|
"fileName": "objects/Property_Template__c.object",
|
||||||
|
"fullName": "Property_Template__c",
|
||||||
|
"id": "01IFV000000CbQP2A0",
|
||||||
|
"success": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"changed": true,
|
||||||
|
"componentType": "CspTrustedSite",
|
||||||
|
"created": false,
|
||||||
|
"createdDate": "2025-09-07T02:50:58.000Z",
|
||||||
|
"deleted": false,
|
||||||
|
"fileName": "cspTrustedSites/PDF_API_Trusted_Site.cspTrustedSite",
|
||||||
|
"fullName": "PDF_API_Trusted_Site",
|
||||||
|
"id": "08yFV0000000U1JYAU",
|
||||||
|
"success": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"changed": true,
|
||||||
|
"componentType": "",
|
||||||
|
"created": false,
|
||||||
|
"createdDate": "2025-09-07T02:50:58.000Z",
|
||||||
|
"deleted": false,
|
||||||
|
"fileName": "package.xml",
|
||||||
|
"fullName": "package.xml",
|
||||||
|
"success": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"runTestResult": {
|
||||||
|
"numFailures": 0,
|
||||||
|
"numTestsRun": 0,
|
||||||
|
"totalTime": 0,
|
||||||
|
"codeCoverage": [],
|
||||||
|
"codeCoverageWarnings": [],
|
||||||
|
"failures": [],
|
||||||
|
"flowCoverage": [],
|
||||||
|
"flowCoverageWarnings": [],
|
||||||
|
"successes": []
|
||||||
|
},
|
||||||
|
"componentFailures": []
|
||||||
|
},
|
||||||
|
"done": true,
|
||||||
|
"id": "0AfFV000003mAxp0AE",
|
||||||
|
"ignoreWarnings": false,
|
||||||
|
"lastModifiedDate": "2025-09-07T02:50:58.000Z",
|
||||||
|
"numberComponentErrors": 0,
|
||||||
|
"numberComponentsDeployed": 12,
|
||||||
|
"numberComponentsTotal": 12,
|
||||||
|
"numberFiles": "24",
|
||||||
|
"numberTestErrors": 0,
|
||||||
|
"numberTestsCompleted": 0,
|
||||||
|
"numberTestsTotal": 0,
|
||||||
|
"rollbackOnError": true,
|
||||||
|
"runTestsEnabled": false,
|
||||||
|
"startDate": "2025-09-07T02:50:53.000Z",
|
||||||
|
"status": "Succeeded",
|
||||||
|
"success": true,
|
||||||
|
"zipSize": 286681,
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"fullName": "PdfApiController",
|
||||||
|
"type": "ApexClass",
|
||||||
|
"state": "Unchanged",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/classes/PdfApiController.cls"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "PdfApiController",
|
||||||
|
"type": "ApexClass",
|
||||||
|
"state": "Unchanged",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/classes/PdfApiController.cls-meta.xml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "PropertyDataController",
|
||||||
|
"type": "ApexClass",
|
||||||
|
"state": "Unchanged",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/classes/PropertyDataController.cls"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "PropertyDataController",
|
||||||
|
"type": "ApexClass",
|
||||||
|
"state": "Unchanged",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/classes/PropertyDataController.cls-meta.xml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "PropertyPdfGeneratorController",
|
||||||
|
"type": "ApexClass",
|
||||||
|
"state": "Unchanged",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/classes/PropertyPdfGeneratorController.cls"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "PropertyPdfGeneratorController",
|
||||||
|
"type": "ApexClass",
|
||||||
|
"state": "Unchanged",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/classes/PropertyPdfGeneratorController.cls-meta.xml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "PropertyTemplateController",
|
||||||
|
"type": "ApexClass",
|
||||||
|
"state": "Unchanged",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/classes/PropertyTemplateController.cls"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "PropertyTemplateController",
|
||||||
|
"type": "ApexClass",
|
||||||
|
"state": "Unchanged",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/classes/PropertyTemplateController.cls-meta.xml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "PDF_API_Trusted_Site",
|
||||||
|
"type": "CspTrustedSite",
|
||||||
|
"state": "Changed",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/cspTrustedSites/PDF_API_Trusted_Site.cspTrustedSite-meta.xml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "Property_Template__c.Description__c",
|
||||||
|
"type": "CustomField",
|
||||||
|
"state": "Unchanged",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/objects/Property_Template__c/fields/Description__c.field-meta.xml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "Property_Template__c.Is_Active__c",
|
||||||
|
"type": "CustomField",
|
||||||
|
"state": "Unchanged",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/objects/Property_Template__c/fields/Is_Active__c.field-meta.xml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "Property_Template__c.Preview_Image_URL__c",
|
||||||
|
"type": "CustomField",
|
||||||
|
"state": "Unchanged",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/objects/Property_Template__c/fields/Preview_Image_URL__c.field-meta.xml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "Property_Template__c.Tags__c",
|
||||||
|
"type": "CustomField",
|
||||||
|
"state": "Unchanged",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/objects/Property_Template__c/fields/Tags__c.field-meta.xml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "Property_Template__c.Template_Definition__c",
|
||||||
|
"type": "CustomField",
|
||||||
|
"state": "Unchanged",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/objects/Property_Template__c/fields/Template_Definition__c.field-meta.xml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "Property_Template__c",
|
||||||
|
"type": "CustomObject",
|
||||||
|
"state": "Changed",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/objects/Property_Template__c/Property_Template__c.object-meta.xml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "propertyTemplateSelector",
|
||||||
|
"type": "LightningComponentBundle",
|
||||||
|
"state": "Changed",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/lwc/propertyTemplateSelector/production-config.js"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "propertyTemplateSelector",
|
||||||
|
"type": "LightningComponentBundle",
|
||||||
|
"state": "Changed",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.css"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "propertyTemplateSelector",
|
||||||
|
"type": "LightningComponentBundle",
|
||||||
|
"state": "Changed",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.css.backup"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "propertyTemplateSelector",
|
||||||
|
"type": "LightningComponentBundle",
|
||||||
|
"state": "Changed",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "propertyTemplateSelector",
|
||||||
|
"type": "LightningComponentBundle",
|
||||||
|
"state": "Changed",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.html.backup"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "propertyTemplateSelector",
|
||||||
|
"type": "LightningComponentBundle",
|
||||||
|
"state": "Changed",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.js"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "propertyTemplateSelector",
|
||||||
|
"type": "LightningComponentBundle",
|
||||||
|
"state": "Changed",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.js-meta.xml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fullName": "propertyTemplateSelector",
|
||||||
|
"type": "LightningComponentBundle",
|
||||||
|
"state": "Changed",
|
||||||
|
"filePath": "/home/ubuntu/salesforce/PDF_Generation_and_Automation/force-app/main/default/lwc/propertyTemplateSelector/propertyTemplateSelector.js.backup"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"zipFileCount": 19,
|
||||||
|
"deployUrl": "https://tso3--r1.sandbox.my.salesforce.com/lightning/setup/DeployStatus/page?address=%2Fchangemgmt%2FmonitorDeploymentsDetails.apexp%3FasyncId%3D0AfFV000003mAxp0AE%26retURL%3D%252Fchangemgmt%252FmonitorDeployment.apexp"
|
||||||
|
},
|
||||||
|
"warnings": []
|
||||||
|
}
|
||||||
@ -8,9 +8,6 @@ public with sharing class PDFGenerationProxy {
|
|||||||
throw new AuraHandledException('HTML content cannot be empty. Please provide valid HTML content.');
|
throw new AuraHandledException('HTML content cannot be empty. Please provide valid HTML content.');
|
||||||
}
|
}
|
||||||
|
|
||||||
System.debug('=== PDF GENERATION DEBUG ===');
|
|
||||||
System.debug('HTML Content Length: ' + htmlContent.length());
|
|
||||||
System.debug('Page Size: ' + pageSize);
|
|
||||||
|
|
||||||
// Call the Node.js API with return_download_link: true
|
// Call the Node.js API with return_download_link: true
|
||||||
Http http = new Http();
|
Http http = new Http();
|
||||||
@ -22,24 +19,43 @@ public with sharing class PDFGenerationProxy {
|
|||||||
request.setHeader('Content-Type', 'application/json');
|
request.setHeader('Content-Type', 'application/json');
|
||||||
request.setTimeout(120000); // 2 minutes timeout
|
request.setTimeout(120000); // 2 minutes timeout
|
||||||
|
|
||||||
|
// Ensure relative resource URLs resolve to Salesforce domain by injecting <base>
|
||||||
|
String modifiedHtml = htmlContent;
|
||||||
|
String baseUrl = null;
|
||||||
|
try {
|
||||||
|
baseUrl = URL.getOrgDomainUrl().toExternalForm();
|
||||||
|
if (modifiedHtml != null && !modifiedHtml.toLowerCase().contains('<base ')) {
|
||||||
|
String lower = modifiedHtml.toLowerCase();
|
||||||
|
Integer headIdx = lower.indexOf('<head>');
|
||||||
|
if (headIdx >= 0) {
|
||||||
|
Integer insertPos = headIdx + 6; // after <head>
|
||||||
|
modifiedHtml = modifiedHtml.substring(0, insertPos) + '<base href=\'' + baseUrl + '/\' />' + modifiedHtml.substring(insertPos);
|
||||||
|
} else {
|
||||||
|
// Prepend base if no head tag found
|
||||||
|
modifiedHtml = '<head><base href=\'' + baseUrl + '/\' /></head>' + modifiedHtml;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// best-effort only
|
||||||
|
}
|
||||||
|
|
||||||
// Prepare the request body
|
// Prepare the request body
|
||||||
Map<String, Object> requestBody = new Map<String, Object>();
|
Map<String, Object> requestBody = new Map<String, Object>();
|
||||||
requestBody.put('input', htmlContent);
|
requestBody.put('input', modifiedHtml);
|
||||||
requestBody.put('return_download_link', true);
|
requestBody.put('return_download_link', true);
|
||||||
if (String.isNotBlank(pageSize)) {
|
// Use 'format' for the Node API, keep page_size for backward-compat
|
||||||
requestBody.put('page_size', pageSize);
|
String formatVal = String.isNotBlank(pageSize) ? pageSize : 'A4';
|
||||||
}
|
requestBody.put('format', formatVal);
|
||||||
|
requestBody.put('page_size', formatVal);
|
||||||
|
|
||||||
|
|
||||||
String jsonBody = JSON.serialize(requestBody);
|
String jsonBody = JSON.serialize(requestBody);
|
||||||
request.setBody(jsonBody);
|
request.setBody(jsonBody);
|
||||||
|
|
||||||
System.debug('Request body: ' + jsonBody);
|
|
||||||
|
|
||||||
// Make the HTTP call
|
// Make the HTTP call
|
||||||
HttpResponse response = http.send(request);
|
HttpResponse response = http.send(request);
|
||||||
|
|
||||||
System.debug('Response status: ' + response.getStatusCode());
|
|
||||||
System.debug('Response body: ' + response.getBody());
|
|
||||||
|
|
||||||
if (response.getStatusCode() == 200) {
|
if (response.getStatusCode() == 200) {
|
||||||
// Parse the response
|
// Parse the response
|
||||||
@ -63,8 +79,6 @@ public with sharing class PDFGenerationProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.debug('Exception in generatePDFFromHTML: ' + e.getMessage());
|
|
||||||
System.debug('Exception stack trace: ' + e.getStackTraceString());
|
|
||||||
|
|
||||||
Map<String, Object> errorResult = new Map<String, Object>();
|
Map<String, Object> errorResult = new Map<String, Object>();
|
||||||
errorResult.put('success', false);
|
errorResult.put('success', false);
|
||||||
@ -84,9 +98,6 @@ public with sharing class PDFGenerationProxy {
|
|||||||
throw new AuraHandledException('HTML content cannot be empty. Please provide valid HTML content.');
|
throw new AuraHandledException('HTML content cannot be empty. Please provide valid HTML content.');
|
||||||
}
|
}
|
||||||
|
|
||||||
System.debug('=== COMPRESSED PDF GENERATION DEBUG ===');
|
|
||||||
System.debug('HTML Content Length: ' + htmlContent.length());
|
|
||||||
System.debug('Page Size: ' + pageSize);
|
|
||||||
|
|
||||||
// Call the Node.js API with return_download_link: true
|
// Call the Node.js API with return_download_link: true
|
||||||
Http http = new Http();
|
Http http = new Http();
|
||||||
@ -109,13 +120,10 @@ public with sharing class PDFGenerationProxy {
|
|||||||
String jsonBody = JSON.serialize(requestBody);
|
String jsonBody = JSON.serialize(requestBody);
|
||||||
request.setBody(jsonBody);
|
request.setBody(jsonBody);
|
||||||
|
|
||||||
System.debug('Request body: ' + jsonBody);
|
|
||||||
|
|
||||||
// Make the HTTP call
|
// Make the HTTP call
|
||||||
HttpResponse response = http.send(request);
|
HttpResponse response = http.send(request);
|
||||||
|
|
||||||
System.debug('Response status: ' + response.getStatusCode());
|
|
||||||
System.debug('Response body: ' + response.getBody());
|
|
||||||
|
|
||||||
if (response.getStatusCode() == 200) {
|
if (response.getStatusCode() == 200) {
|
||||||
// Parse the response
|
// Parse the response
|
||||||
@ -142,8 +150,6 @@ public with sharing class PDFGenerationProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.debug('Exception in generateCompressedPDF: ' + e.getMessage());
|
|
||||||
System.debug('Exception stack trace: ' + e.getStackTraceString());
|
|
||||||
|
|
||||||
Map<String, Object> errorResult = new Map<String, Object>();
|
Map<String, Object> errorResult = new Map<String, Object>();
|
||||||
errorResult.put('success', false);
|
errorResult.put('success', false);
|
||||||
|
|||||||
234
force-app/main/default/lwc/developmentPage/developmentPage.css
Normal file
234
force-app/main/default/lwc/developmentPage/developmentPage.css
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
.development-page {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
|
||||||
|
z-index: 9999;
|
||||||
|
overflow-y: auto;
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-header {
|
||||||
|
background: rgba(0, 0, 0, 0.8);
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: 2px solid #ff6b6b;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 10000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-header h1 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 2.5rem;
|
||||||
|
color: #ff6b6b;
|
||||||
|
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-warning {
|
||||||
|
margin: 10px 0;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: #ffd93d;
|
||||||
|
font-weight: bold;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-instruction {
|
||||||
|
margin: 10px 0;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #74b9ff;
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-dev-btn {
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
background: #ff4757;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-dev-btn:hover {
|
||||||
|
background: #ff3742;
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-content {
|
||||||
|
padding: 30px;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-section {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
border-radius: 15px;
|
||||||
|
padding: 25px;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-section h2 {
|
||||||
|
margin: 0 0 20px 0;
|
||||||
|
color: #74b9ff;
|
||||||
|
font-size: 1.8rem;
|
||||||
|
border-bottom: 2px solid #74b9ff;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-tools {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-btn {
|
||||||
|
background: linear-gradient(45deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 15px 20px;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-btn:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-btn.primary {
|
||||||
|
background: linear-gradient(45deg, #00b894 0%, #00a085 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-btn.primary:hover {
|
||||||
|
box-shadow: 0 5px 15px rgba(0, 184, 148, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-btn.secondary {
|
||||||
|
background: linear-gradient(45deg, #6c5ce7 0%, #a29bfe 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-btn.secondary:hover {
|
||||||
|
box-shadow: 0 5px 15px rgba(108, 92, 231, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-btn.warning {
|
||||||
|
background: linear-gradient(45deg, #e17055 0%, #d63031 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-btn.warning:hover {
|
||||||
|
box-shadow: 0 5px 15px rgba(225, 112, 85, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-item {
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 15px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
border-left: 4px solid #74b9ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-label {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-value {
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 20px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-value.success {
|
||||||
|
background: rgba(0, 184, 148, 0.2);
|
||||||
|
color: #00b894;
|
||||||
|
border: 1px solid #00b894;
|
||||||
|
}
|
||||||
|
|
||||||
|
.debug-info {
|
||||||
|
background: rgba(0, 0, 0, 0.3);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.debug-info p {
|
||||||
|
margin: 8px 0;
|
||||||
|
color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.debug-info strong {
|
||||||
|
color: #74b9ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 15px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive design */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.dev-content {
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-header h1 {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-tools {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-actions {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animation for page entrance */
|
||||||
|
@keyframes slideInFromTop {
|
||||||
|
from {
|
||||||
|
transform: translateY(-100%);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateY(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.development-page {
|
||||||
|
animation: slideInFromTop 0.5s ease-out;
|
||||||
|
}
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
<template>
|
||||||
|
<div class="development-page" if:true={showDevPage}>
|
||||||
|
<div class="dev-header">
|
||||||
|
<h1>🚧 Development Area 🚧</h1>
|
||||||
|
<p class="dev-warning">UNDER DEVELOPMENT - DO NOT TEST</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dev-content">
|
||||||
|
|
||||||
|
<div class="dev-section">
|
||||||
|
<h2>📊 System Status</h2>
|
||||||
|
<div class="status-grid">
|
||||||
|
<div class="status-item">
|
||||||
|
<span class="status-label">LWC Status:</span>
|
||||||
|
<span class="status-value success">✅ Active</span>
|
||||||
|
</div>
|
||||||
|
<div class="status-item">
|
||||||
|
<span class="status-label">PDF Service:</span>
|
||||||
|
<span class="status-value success">✅ Connected</span>
|
||||||
|
</div>
|
||||||
|
<div class="status-item">
|
||||||
|
<span class="status-label">Templates:</span>
|
||||||
|
<span class="status-value success">✅ Loaded</span>
|
||||||
|
</div>
|
||||||
|
<div class="status-item">
|
||||||
|
<span class="status-label">Property Data:</span>
|
||||||
|
<span class="status-value success">✅ Available</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dev-section">
|
||||||
|
<h2>🐛 Debug Information</h2>
|
||||||
|
<div class="debug-info">
|
||||||
|
<p><strong>Current Step:</strong> {currentStep}</p>
|
||||||
|
<p><strong>Selected Template:</strong> {selectedTemplateId}</p>
|
||||||
|
<p><strong>Selected Property:</strong> {selectedPropertyId}</p>
|
||||||
|
<p><strong>Page Size:</strong> {selectedPageSize}</p>
|
||||||
|
<p><strong>Timestamp:</strong> {currentTimestamp}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dev-section">
|
||||||
|
<h2>⚙️ Quick Actions</h2>
|
||||||
|
<div class="quick-actions">
|
||||||
|
<button class="dev-btn primary" onclick={forceReload}>Force Reload</button>
|
||||||
|
<button class="dev-btn secondary" onclick={toggleDebugMode}>Toggle Debug Mode</button>
|
||||||
|
<button class="dev-btn warning" onclick={clearCache}>Clear Cache</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
162
force-app/main/default/lwc/developmentPage/developmentPage.js
Normal file
162
force-app/main/default/lwc/developmentPage/developmentPage.js
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
import { LightningElement, track } from 'lwc';
|
||||||
|
|
||||||
|
export default class DevelopmentPage extends LightningElement {
|
||||||
|
@track showDevPage = true;
|
||||||
|
@track currentStep = 1;
|
||||||
|
@track selectedTemplateId = '';
|
||||||
|
@track selectedPropertyId = '';
|
||||||
|
@track selectedPageSize = 'A4';
|
||||||
|
@track currentTimestamp = '';
|
||||||
|
@track debugMode = false;
|
||||||
|
|
||||||
|
// V-key click counter
|
||||||
|
vKeyCount = 0;
|
||||||
|
vKeyTimeout = null;
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
this.updateTimestamp();
|
||||||
|
this.addKeyListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnectedCallback() {
|
||||||
|
this.removeKeyListener();
|
||||||
|
if (this.vKeyTimeout) {
|
||||||
|
clearTimeout(this.vKeyTimeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addKeyListener() {
|
||||||
|
document.addEventListener('keydown', this.handleKeyPress.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
removeKeyListener() {
|
||||||
|
document.removeEventListener('keydown', this.handleKeyPress.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
handleKeyPress(event) {
|
||||||
|
// Only listen for 'V' key (case insensitive)
|
||||||
|
if (event.key.toLowerCase() === 'v') {
|
||||||
|
this.vKeyCount++;
|
||||||
|
|
||||||
|
// Clear any existing timeout
|
||||||
|
if (this.vKeyTimeout) {
|
||||||
|
clearTimeout(this.vKeyTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset counter after 3 seconds of inactivity
|
||||||
|
this.vKeyTimeout = setTimeout(() => {
|
||||||
|
this.vKeyCount = 0;
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
|
// Hide dev page after 4 V key presses
|
||||||
|
if (this.vKeyCount >= 4) {
|
||||||
|
this.showDevPage = false;
|
||||||
|
this.vKeyCount = 0; // Reset counter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closeDevPage() {
|
||||||
|
this.showDevPage = false;
|
||||||
|
this.vKeyCount = 0;
|
||||||
|
if (this.vKeyTimeout) {
|
||||||
|
clearTimeout(this.vKeyTimeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTimestamp() {
|
||||||
|
this.currentTimestamp = new Date().toLocaleString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Development actions
|
||||||
|
clearAllData() {
|
||||||
|
if (confirm('Are you sure you want to clear all data? This action cannot be undone.')) {
|
||||||
|
// Clear all component data
|
||||||
|
this.currentStep = 1;
|
||||||
|
this.selectedTemplateId = '';
|
||||||
|
this.selectedPropertyId = '';
|
||||||
|
this.selectedPageSize = 'A4';
|
||||||
|
this.updateTimestamp();
|
||||||
|
|
||||||
|
// Dispatch event to parent component
|
||||||
|
this.dispatchEvent(new CustomEvent('cleardata'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resetTemplates() {
|
||||||
|
if (confirm('Reset all templates to default state?')) {
|
||||||
|
// Dispatch event to parent component
|
||||||
|
this.dispatchEvent(new CustomEvent('resettemplates'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exportDebugInfo() {
|
||||||
|
const debugData = {
|
||||||
|
timestamp: this.currentTimestamp,
|
||||||
|
currentStep: this.currentStep,
|
||||||
|
selectedTemplateId: this.selectedTemplateId,
|
||||||
|
selectedPropertyId: this.selectedPropertyId,
|
||||||
|
selectedPageSize: this.selectedPageSize,
|
||||||
|
userAgent: navigator.userAgent,
|
||||||
|
url: window.location.href
|
||||||
|
};
|
||||||
|
|
||||||
|
const blob = new Blob([JSON.stringify(debugData, null, 2)], { type: 'application/json' });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = `debug-info-${Date.now()}.json`;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
testPdfGeneration() {
|
||||||
|
// Dispatch event to parent component
|
||||||
|
this.dispatchEvent(new CustomEvent('testpdf'));
|
||||||
|
}
|
||||||
|
|
||||||
|
forceReload() {
|
||||||
|
if (confirm('Force reload the entire application?')) {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleDebugMode() {
|
||||||
|
this.debugMode = !this.debugMode;
|
||||||
|
// Dispatch event to parent component
|
||||||
|
this.dispatchEvent(new CustomEvent('toggledebug', {
|
||||||
|
detail: { debugMode: this.debugMode }
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
clearCache() {
|
||||||
|
if (confirm('Clear browser cache and localStorage?')) {
|
||||||
|
// Clear localStorage
|
||||||
|
localStorage.clear();
|
||||||
|
sessionStorage.clear();
|
||||||
|
|
||||||
|
// Clear any cached data
|
||||||
|
if ('caches' in window) {
|
||||||
|
caches.keys().then(names => {
|
||||||
|
names.forEach(name => {
|
||||||
|
caches.delete(name);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
alert('Cache cleared successfully!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method to update data from parent component
|
||||||
|
updateData(data) {
|
||||||
|
if (data.currentStep !== undefined) this.currentStep = data.currentStep;
|
||||||
|
if (data.selectedTemplateId !== undefined) this.selectedTemplateId = data.selectedTemplateId;
|
||||||
|
if (data.selectedPropertyId !== undefined) this.selectedPropertyId = data.selectedPropertyId;
|
||||||
|
if (data.selectedPageSize !== undefined) this.selectedPageSize = data.selectedPageSize;
|
||||||
|
this.updateTimestamp();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
|
||||||
|
<apiVersion>58.0</apiVersion>
|
||||||
|
<isExposed>false</isExposed>
|
||||||
|
<targets>
|
||||||
|
<target>lightning__AppPage</target>
|
||||||
|
<target>lightning__RecordPage</target>
|
||||||
|
<target>lightning__HomePage</target>
|
||||||
|
</targets>
|
||||||
|
</LightningComponentBundle>
|
||||||
@ -0,0 +1,560 @@
|
|||||||
|
/* Professional Editor Styles */
|
||||||
|
.professional-editor-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Editor Header */
|
||||||
|
.editor-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 16px 24px;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-title h3 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||||
|
border-radius: 6px;
|
||||||
|
color: white;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-btn:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.3);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-btn.save {
|
||||||
|
background: rgba(46, 204, 113, 0.8);
|
||||||
|
border-color: rgba(46, 204, 113, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-btn.save:hover {
|
||||||
|
background: rgba(46, 204, 113, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Editor Layout */
|
||||||
|
.editor-layout {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Professional Sidebar */
|
||||||
|
.editor-sidebar {
|
||||||
|
width: 320px;
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-right: 1px solid #e9ecef;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
transition: width 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-sidebar.collapsed {
|
||||||
|
width: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 16px 20px;
|
||||||
|
background: #ffffff;
|
||||||
|
border-bottom: 1px solid #e9ecef;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-header h4 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #495057;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-toggle {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: #6c757d;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-toggle:hover {
|
||||||
|
background: #e9ecef;
|
||||||
|
color: #495057;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-content {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tool Sections */
|
||||||
|
.tool-section {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-bottom: 1px solid #e9ecef;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #495057;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-btn {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 12px 8px;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: #495057;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-btn:hover {
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-color: #667eea;
|
||||||
|
color: #667eea;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-btn.primary {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
border-color: #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-btn.primary:hover {
|
||||||
|
background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-btn.secondary {
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-color: #dee2e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-btn.secondary:hover {
|
||||||
|
background: #e9ecef;
|
||||||
|
border-color: #adb5bd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Formatting Controls */
|
||||||
|
.formatting-controls {
|
||||||
|
padding: 16px;
|
||||||
|
border-bottom: 1px solid #e9ecef;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-group {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-group:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-group label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #6c757d;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #ffffff;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: #495057;
|
||||||
|
transition: border-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-select:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #667eea;
|
||||||
|
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style Buttons */
|
||||||
|
.style-buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 16px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.style-btn {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: #495057;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.style-btn:hover {
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-color: #667eea;
|
||||||
|
color: #667eea;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.style-btn.active {
|
||||||
|
background: #667eea;
|
||||||
|
border-color: #667eea;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight-icon {
|
||||||
|
background: #ffd93d;
|
||||||
|
color: #333;
|
||||||
|
padding: 2px 4px;
|
||||||
|
border-radius: 2px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Alignment & List Buttons */
|
||||||
|
.alignment-buttons, .list-buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 16px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-btn, .list-btn {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: #495057;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-btn:hover, .list-btn:hover {
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-color: #667eea;
|
||||||
|
color: #667eea;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Media Buttons */
|
||||||
|
.media-buttons {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: #495057;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-btn:hover {
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-color: #667eea;
|
||||||
|
color: #667eea;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Action Buttons */
|
||||||
|
.action-buttons {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: #495057;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn:hover {
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-color: #667eea;
|
||||||
|
color: #667eea;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn.undo {
|
||||||
|
border-color: #ffc107;
|
||||||
|
color: #856404;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn.undo:hover {
|
||||||
|
background: #fff3cd;
|
||||||
|
border-color: #ffb300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn.redo {
|
||||||
|
border-color: #17a2b8;
|
||||||
|
color: #0c5460;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn.redo:hover {
|
||||||
|
background: #d1ecf1;
|
||||||
|
border-color: #138496;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn.save {
|
||||||
|
background: #28a745;
|
||||||
|
border-color: #28a745;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn.save:hover {
|
||||||
|
background: #218838;
|
||||||
|
border-color: #1e7e34;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn.reset {
|
||||||
|
border-color: #dc3545;
|
||||||
|
color: #721c24;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn.reset:hover {
|
||||||
|
background: #f8d7da;
|
||||||
|
border-color: #c82333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Professional Viewport */
|
||||||
|
.editor-viewport {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: #f8f9fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewport-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px 20px;
|
||||||
|
background: #ffffff;
|
||||||
|
border-bottom: 1px solid #e9ecef;
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewport-controls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewport-btn {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #495057;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewport-btn:hover {
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-color: #667eea;
|
||||||
|
color: #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zoom-level {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #495057;
|
||||||
|
min-width: 40px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewport-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-size {
|
||||||
|
padding: 4px 8px;
|
||||||
|
background: #e9ecef;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #495057;
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewport-content {
|
||||||
|
flex: 1;
|
||||||
|
padding: 20px;
|
||||||
|
overflow: auto;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-canvas {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow: hidden;
|
||||||
|
min-width: 800px;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.enhanced-editor-content {
|
||||||
|
min-height: 600px;
|
||||||
|
padding: 40px;
|
||||||
|
outline: none;
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
line-height: 1.6;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.enhanced-editor-content:focus {
|
||||||
|
box-shadow: inset 0 0 0 2px #667eea;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive Design */
|
||||||
|
@media (max-width: 1200px) {
|
||||||
|
.editor-sidebar {
|
||||||
|
width: 280px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.editor-layout {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-sidebar {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
max-height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-canvas {
|
||||||
|
min-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.enhanced-editor-content {
|
||||||
|
padding: 20px;
|
||||||
|
min-height: 400px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animation for smooth transitions */
|
||||||
|
.tool-section {
|
||||||
|
animation: slideInUp 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideInUp {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(20px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,231 @@
|
|||||||
|
<!-- Professional Editor Section -->
|
||||||
|
<div class="professional-editor-container">
|
||||||
|
<!-- Editor Header -->
|
||||||
|
<div class="editor-header">
|
||||||
|
<div class="editor-title">
|
||||||
|
<lightning-icon icon-name="utility:edit" size="small"></lightning-icon>
|
||||||
|
<h3>Template Editor</h3>
|
||||||
|
</div>
|
||||||
|
<div class="editor-actions">
|
||||||
|
<button class="header-btn preview" onclick={togglePreview} title="Toggle Preview">
|
||||||
|
<lightning-icon icon-name="utility:preview" size="x-small"></lightning-icon>
|
||||||
|
Preview
|
||||||
|
</button>
|
||||||
|
<button class="header-btn save" onclick={handleSave} title="Save Template">
|
||||||
|
<lightning-icon icon-name="utility:save" size="x-small"></lightning-icon>
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Editor Layout -->
|
||||||
|
<div class="editor-layout">
|
||||||
|
<!-- Professional Sidebar -->
|
||||||
|
<div class="editor-sidebar">
|
||||||
|
<div class="sidebar-header">
|
||||||
|
<h4>Tools</h4>
|
||||||
|
<button class="sidebar-toggle" onclick={toggleSidebar}>
|
||||||
|
<lightning-icon icon-name="utility:chevronleft" size="x-small"></lightning-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sidebar-content">
|
||||||
|
<!-- Property Data Insert -->
|
||||||
|
<div class="tool-section">
|
||||||
|
<div class="section-header">
|
||||||
|
<lightning-icon icon-name="utility:insert_template" size="x-small"></lightning-icon>
|
||||||
|
<span>Property Data</span>
|
||||||
|
</div>
|
||||||
|
<div class="tool-grid">
|
||||||
|
<button class="tool-btn primary" onclick={insertPropertyName} title="Property Name">
|
||||||
|
<lightning-icon icon-name="utility:home" size="x-small"></lightning-icon>
|
||||||
|
Name
|
||||||
|
</button>
|
||||||
|
<button class="tool-btn primary" onclick={insertPropertyLocation} title="Location">
|
||||||
|
<lightning-icon icon-name="utility:location" size="x-small"></lightning-icon>
|
||||||
|
Location
|
||||||
|
</button>
|
||||||
|
<button class="tool-btn primary" onclick={insertPropertyPrice} title="Price">
|
||||||
|
<lightning-icon icon-name="utility:currency" size="x-small"></lightning-icon>
|
||||||
|
Price
|
||||||
|
</button>
|
||||||
|
<button class="tool-btn primary" onclick={insertPropertyType} title="Type">
|
||||||
|
<lightning-icon icon-name="utility:building" size="x-small"></lightning-icon>
|
||||||
|
Type
|
||||||
|
</button>
|
||||||
|
<button class="tool-btn secondary" onclick={insertPropertyBedrooms} title="Bedrooms">
|
||||||
|
<lightning-icon icon-name="utility:bed" size="x-small"></lightning-icon>
|
||||||
|
Bedrooms
|
||||||
|
</button>
|
||||||
|
<button class="tool-btn secondary" onclick={insertPropertyBathrooms} title="Bathrooms">
|
||||||
|
<lightning-icon icon-name="utility:bath" size="x-small"></lightning-icon>
|
||||||
|
Bathrooms
|
||||||
|
</button>
|
||||||
|
<button class="tool-btn secondary" onclick={insertPropertyArea} title="Area">
|
||||||
|
<lightning-icon icon-name="utility:expand" size="x-small"></lightning-icon>
|
||||||
|
Area
|
||||||
|
</button>
|
||||||
|
<button class="tool-btn secondary" onclick={insertPropertyDescription} title="Description">
|
||||||
|
<lightning-icon icon-name="utility:text" size="x-small"></lightning-icon>
|
||||||
|
Description
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Text Formatting -->
|
||||||
|
<div class="tool-section">
|
||||||
|
<div class="section-header">
|
||||||
|
<lightning-icon icon-name="utility:text" size="x-small"></lightning-icon>
|
||||||
|
<span>Text Formatting</span>
|
||||||
|
</div>
|
||||||
|
<div class="formatting-controls">
|
||||||
|
<div class="control-group">
|
||||||
|
<label>Font Family</label>
|
||||||
|
<select class="control-select" onchange={handleFontFamilyChange}>
|
||||||
|
<option value="Arial">Arial</option>
|
||||||
|
<option value="Times New Roman">Times New Roman</option>
|
||||||
|
<option value="Helvetica">Helvetica</option>
|
||||||
|
<option value="Georgia">Georgia</option>
|
||||||
|
<option value="Verdana">Verdana</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label>Font Size</label>
|
||||||
|
<select class="control-select" onchange={handleFontSizeChange}>
|
||||||
|
<option value="12px">12px</option>
|
||||||
|
<option value="14px">14px</option>
|
||||||
|
<option value="16px">16px</option>
|
||||||
|
<option value="18px">18px</option>
|
||||||
|
<option value="20px">20px</option>
|
||||||
|
<option value="24px">24px</option>
|
||||||
|
<option value="28px">28px</option>
|
||||||
|
<option value="32px">32px</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="style-buttons">
|
||||||
|
<button class="style-btn" onclick={handleBold} title="Bold">
|
||||||
|
<strong>B</strong>
|
||||||
|
</button>
|
||||||
|
<button class="style-btn" onclick={handleItalic} title="Italic">
|
||||||
|
<em>I</em>
|
||||||
|
</button>
|
||||||
|
<button class="style-btn" onclick={handleUnderline} title="Underline">
|
||||||
|
<u>U</u>
|
||||||
|
</button>
|
||||||
|
<button class="style-btn" onclick={handleHighlight} title="Highlight">
|
||||||
|
<span class="highlight-icon">H</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Alignment & Lists -->
|
||||||
|
<div class="tool-section">
|
||||||
|
<div class="section-header">
|
||||||
|
<lightning-icon icon-name="utility:align" size="x-small"></lightning-icon>
|
||||||
|
<span>Alignment & Lists</span>
|
||||||
|
</div>
|
||||||
|
<div class="alignment-buttons">
|
||||||
|
<button class="align-btn" onclick={handleAlignLeft} title="Align Left">
|
||||||
|
<lightning-icon icon-name="utility:left_align_text" size="x-small"></lightning-icon>
|
||||||
|
</button>
|
||||||
|
<button class="align-btn" onclick={handleAlignCenter} title="Align Center">
|
||||||
|
<lightning-icon icon-name="utility:center_align_text" size="x-small"></lightning-icon>
|
||||||
|
</button>
|
||||||
|
<button class="align-btn" onclick={handleAlignRight} title="Align Right">
|
||||||
|
<lightning-icon icon-name="utility:right_align_text" size="x-small"></lightning-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="list-buttons">
|
||||||
|
<button class="list-btn" onclick={handleBulletList} title="Bullet List">
|
||||||
|
<lightning-icon icon-name="utility:bullet_list" size="x-small"></lightning-icon>
|
||||||
|
</button>
|
||||||
|
<button class="list-btn" onclick={handleNumberList} title="Numbered List">
|
||||||
|
<lightning-icon icon-name="utility:numbered_list" size="x-small"></lightning-icon>
|
||||||
|
</button>
|
||||||
|
<button class="list-btn" onclick={handleIndent} title="Indent">
|
||||||
|
<lightning-icon icon-name="utility:indent" size="x-small"></lightning-icon>
|
||||||
|
</button>
|
||||||
|
<button class="list-btn" onclick={handleOutdent} title="Outdent">
|
||||||
|
<lightning-icon icon-name="utility:outdent" size="x-small"></lightning-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Media & Tables -->
|
||||||
|
<div class="tool-section">
|
||||||
|
<div class="section-header">
|
||||||
|
<lightning-icon icon-name="utility:image" size="x-small"></lightning-icon>
|
||||||
|
<span>Media & Tables</span>
|
||||||
|
</div>
|
||||||
|
<div class="media-buttons">
|
||||||
|
<button class="media-btn" onclick={insertImage} title="Insert Image">
|
||||||
|
<lightning-icon icon-name="utility:image" size="x-small"></lightning-icon>
|
||||||
|
Image
|
||||||
|
</button>
|
||||||
|
<button class="media-btn" onclick={insertTable} title="Insert Table">
|
||||||
|
<lightning-icon icon-name="utility:table" size="x-small"></lightning-icon>
|
||||||
|
Table
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Document Actions -->
|
||||||
|
<div class="tool-section">
|
||||||
|
<div class="section-header">
|
||||||
|
<lightning-icon icon-name="utility:settings" size="x-small"></lightning-icon>
|
||||||
|
<span>Document Actions</span>
|
||||||
|
</div>
|
||||||
|
<div class="action-buttons">
|
||||||
|
<button class="action-btn undo" onclick={undo} title="Undo">
|
||||||
|
<lightning-icon icon-name="utility:undo" size="x-small"></lightning-icon>
|
||||||
|
Undo
|
||||||
|
</button>
|
||||||
|
<button class="action-btn redo" onclick={redo} title="Redo">
|
||||||
|
<lightning-icon icon-name="utility:redo" size="x-small"></lightning-icon>
|
||||||
|
Redo
|
||||||
|
</button>
|
||||||
|
<button class="action-btn save" onclick={handleSave} title="Save">
|
||||||
|
<lightning-icon icon-name="utility:save" size="x-small"></lightning-icon>
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
<button class="action-btn reset" onclick={handleReset} title="Reset">
|
||||||
|
<lightning-icon icon-name="utility:refresh" size="x-small"></lightning-icon>
|
||||||
|
Reset
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Professional Editor Viewport -->
|
||||||
|
<div class="editor-viewport">
|
||||||
|
<div class="viewport-header">
|
||||||
|
<div class="viewport-controls">
|
||||||
|
<button class="viewport-btn" onclick={zoomOut} title="Zoom Out">
|
||||||
|
<lightning-icon icon-name="utility:zoomout" size="x-small"></lightning-icon>
|
||||||
|
</button>
|
||||||
|
<span class="zoom-level">100%</span>
|
||||||
|
<button class="viewport-btn" onclick={zoomIn} title="Zoom In">
|
||||||
|
<lightning-icon icon-name="utility:zoomin" size="x-small"></lightning-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="viewport-info">
|
||||||
|
<span class="page-size">{selectedPageSize}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="viewport-content">
|
||||||
|
<div class="editor-canvas">
|
||||||
|
<div class="enhanced-editor-content" contenteditable="true"
|
||||||
|
onkeyup={handleContentChange}
|
||||||
|
onpaste={handleContentChange}
|
||||||
|
ondragover={handleEditorDragOver}
|
||||||
|
ondrop={handleEditorDrop}>
|
||||||
|
{htmlContent}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,14 @@
|
|||||||
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<!-- Development Page (Hidden) -->
|
||||||
|
<c-development-page
|
||||||
|
oncleardata={handleClearData}
|
||||||
|
onresettemplates={handleResetTemplates}
|
||||||
|
ontestpdf={handleTestPdf}
|
||||||
|
ontoggledebug={handleToggleDebug}>
|
||||||
|
</c-development-page>
|
||||||
|
|
||||||
<div class="property-brochure-generator">
|
<div class="property-brochure-generator">
|
||||||
<!-- Header Section - Editable -->
|
<!-- Header Section - Editable -->
|
||||||
<!-- <template if:true={showHeader}>
|
<!-- <template if:true={showHeader}>
|
||||||
@ -22,13 +30,34 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- Step Progress Stepper -->
|
||||||
|
<div class="step-stepper-container">
|
||||||
|
<div class="step-stepper">
|
||||||
|
<div class="step-item" data-step="1" onclick={goToStep}>
|
||||||
|
<div class="step-circle {step1NavClass}" style={step1NavStyle}>
|
||||||
|
<span class="step-number">1</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="step-connector"></div>
|
||||||
|
<div class="step-item" data-step="2" onclick={goToStep}>
|
||||||
|
<div class="step-circle {step2NavClass}" style={step2NavStyle}>
|
||||||
|
<span class="step-number">2</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="step-connector"></div>
|
||||||
|
<div class="step-item" data-step="3" onclick={goToStep}>
|
||||||
|
<div class="step-circle {step3NavClass}" style={step3NavStyle}>
|
||||||
|
<span class="step-number">3</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Step 1: Template Selection -->
|
<!-- Step 1: Template Selection -->
|
||||||
<div class={step1Class} data-step="1">
|
<div class={step1Class} data-step="1">
|
||||||
|
<div class="step-inner-container">
|
||||||
<!-- Template Grid - Professional Black & White Design -->
|
<!-- Template Grid - Professional Black & White Design -->
|
||||||
<div class="template-grid" id="all-templates">
|
<div class="template-grid" id="all-templates">
|
||||||
<!-- Blank Template -->
|
<!-- Blank Template -->
|
||||||
<div class="template-card template-blank template-medium" data-template-id="blank-template"
|
<div class="template-card template-blank template-medium" data-template-id="blank-template"
|
||||||
onclick={handleTemplateSelect}>
|
onclick={handleTemplateSelect}>
|
||||||
@ -46,7 +75,7 @@
|
|||||||
<p>Design every element from scratch. Perfect for unique branding, creative layouts, and
|
<p>Design every element from scratch. Perfect for unique branding, creative layouts, and
|
||||||
personalized property showcases with your own design vision.</p>
|
personalized property showcases with your own design vision.</p>
|
||||||
<div class="cta-buttons">
|
<div class="cta-buttons">
|
||||||
<button class="cta-btn">CREATE NOW</button>
|
<button class="cta-btn" style="background:#ffffff;color:#000000;">CREATE NOW</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -64,12 +93,12 @@
|
|||||||
onclick={handleTemplateSelect}>
|
onclick={handleTemplateSelect}>
|
||||||
<div class="template-content modern-home-preview">
|
<div class="template-content modern-home-preview">
|
||||||
<!-- Hero Section -->
|
<!-- Hero Section -->
|
||||||
<div class="hero">
|
<div class="hero" style="background-image: url('https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&q=85&fm=jpg&crop=entropy&cs=srgb&w=1200'); background-size: cover; background-position: center;">
|
||||||
<div class="hero-overlay">
|
<div class="hero-overlay">
|
||||||
<h1 class="property-name" style="color: white !important;">Modern Villa</h1>
|
<h1 class="property-name" style="color: white !important;">Modern Villa</h1>
|
||||||
<p class="property-address" style="color: white !important;">123 Luxury Lane, Prestige City, PC 45678</p>
|
<p class="property-address" style="color: white !important;">123 Luxury Lane, Prestige City, PC 45678</p>
|
||||||
<div class="hero-details">
|
<div class="hero-details">
|
||||||
<div class="price" style="color: white !important;">$2,500,000</div>
|
<div class="price" style="color: white !important;">AED 2,500,000</div>
|
||||||
<div class="stats">
|
<div class="stats">
|
||||||
<span class="stat-item" style="color: white !important;"><i class="fa-solid fa-bed"></i> 4 Beds</span>
|
<span class="stat-item" style="color: white !important;"><i class="fa-solid fa-bed"></i> 4 Beds</span>
|
||||||
<span class="stat-item" style="color: white !important;"><i class="fa-solid fa-bath"></i> 3 Baths</span>
|
<span class="stat-item" style="color: white !important;"><i class="fa-solid fa-bath"></i> 3 Baths</span>
|
||||||
@ -102,7 +131,7 @@
|
|||||||
|
|
||||||
<div class="agent-footer">
|
<div class="agent-footer">
|
||||||
<div class="agent-info">
|
<div class="agent-info">
|
||||||
<h3>Sarah Johnson</h3>
|
<h3 style="font-size: 0.95rem;">Sarah Johnson</h3>
|
||||||
<p>Your Real Estate Professional</p>
|
<p>Your Real Estate Professional</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="agent-contact-details">
|
<div class="agent-contact-details">
|
||||||
@ -114,7 +143,7 @@
|
|||||||
|
|
||||||
<footer class="page-footer">
|
<footer class="page-footer">
|
||||||
<div class="reference-id">
|
<div class="reference-id">
|
||||||
<strong>Reference ID:</strong> MH-2024-001
|
<strong>Property:</strong> Modern Villa
|
||||||
</div>
|
</div>
|
||||||
<div class="owner-info">
|
<div class="owner-info">
|
||||||
<strong>Owner Info:</strong> John Smith, (555) 987-6543
|
<strong>Owner Info:</strong> John Smith, (555) 987-6543
|
||||||
@ -131,10 +160,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- The Grand Oak Villa Template -->
|
<!-- The Grand Oak Villa Template -->
|
||||||
<div class="template-card template-asgar1 template-tall" data-template-id="asgar-1-template"
|
<div class="template-card template-grand-oak template-tall" data-template-id="grand-oak-villa-template"
|
||||||
onclick={handleTemplateSelect}>
|
onclick={handleTemplateSelect}>
|
||||||
<div class="template-content asgar1-preview">
|
<div class="template-content grand-oak-preview">
|
||||||
<!-- Cover Page -->
|
<!-- Static HTML Preview from preview-grand-oak.html -->
|
||||||
<div class="brochure-page cover-page">
|
<div class="brochure-page cover-page">
|
||||||
<div class="cover-overlay"></div>
|
<div class="cover-overlay"></div>
|
||||||
<header class="cover-header">
|
<header class="cover-header">
|
||||||
@ -142,8 +171,10 @@
|
|||||||
<div class="property-status">FOR SALE</div>
|
<div class="property-status">FOR SALE</div>
|
||||||
</header>
|
</header>
|
||||||
<main class="cover-content">
|
<main class="cover-content">
|
||||||
<h1 class="cover-title" style="color: #C0A062 !important;">The Grand Oak Villa</h1>
|
<h1 class="cover-title">The Grand Oak Villa</h1>
|
||||||
<p class="cover-address"><i class="fa-solid fa-location-dot"></i> 123 Luxury Lane, Prestige City, PC 45678</p>
|
<p class="cover-address">
|
||||||
|
<i class="fa-solid fa-location-dot"></i> 123 Luxury Lane, Prestige City, PC 45678
|
||||||
|
</p>
|
||||||
</main>
|
</main>
|
||||||
<footer class="cover-footer">
|
<footer class="cover-footer">
|
||||||
<div class="feature-item">
|
<div class="feature-item">
|
||||||
@ -165,51 +196,72 @@
|
|||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Content Page -->
|
|
||||||
<div class="brochure-page">
|
<div class="brochure-page">
|
||||||
<div class="content-body">
|
<div class="content-body">
|
||||||
<header class="page-header">
|
<header class="page-header">
|
||||||
<h1 class="title">Property <span>Overview</span></h1>
|
<h1 class="title">Property <span>Overview</span></h1>
|
||||||
<span class="property-name" style="color: #C0A062 !important;">The Grand Oak Villa</span>
|
<span class="property-name">The Grand Oak Villa</span>
|
||||||
</header>
|
</header>
|
||||||
<main class="main-content details-grid">
|
<main class="main-content details-grid">
|
||||||
<div>
|
<div>
|
||||||
<h2 class="section-title" style="color: white !important;">Description</h2>
|
<h2 class="section-title">Description</h2>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<p style="color: white !important;">Nestled in the heart of Prestige City, The Grand Oak Villa is a masterpiece of modern architecture and timeless elegance.</p>
|
<p>Nestled in the heart of Prestige City, The Grand Oak Villa is a masterpiece of modern architecture and timeless elegance. This expansive 6,200 sq. ft. residence offers unparalleled luxury and privacy.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="specs-and-amenities">
|
<div class="specs-and-amenities">
|
||||||
<div>
|
<div>
|
||||||
<h2 class="section-title" style="color: white !important;">Specifications</h2>
|
<h2 class="section-title">Specifications</h2>
|
||||||
<div class="spec-list">
|
<div class="spec-list">
|
||||||
<div class="item"><span class="key" style="color: white !important;">Status:</span> <span class="value" style="color: white !important;">For Sale</span></div>
|
<div class="item">
|
||||||
<div class="item"><span class="key" style="color: white !important;">Type:</span> <span class="value" style="color: white !important;">Villa</span></div>
|
<span class="key">Status:</span>
|
||||||
<div class="item"><span class="key" style="color: white !important;">Year Built:</span> <span class="value" style="color: white !important;">2023</span></div>
|
<span class="value">For Sale</span>
|
||||||
<div class="item"><span class="key" style="color: white !important;">Parking:</span> <span class="value" style="color: white !important;">3-Car</span></div>
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<span class="key">Type:</span>
|
||||||
|
<span class="value">Villa</span>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<span class="key">Year Built:</span>
|
||||||
|
<span class="value">2023</span>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<span class="key">Parking:</span>
|
||||||
|
<span class="value">3-Car</span>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<span class="key">Floor:</span>
|
||||||
|
<span class="value">2 Levels</span>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<span class="key">Furnishing:</span>
|
||||||
|
<span class="value">Partially</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2 class="section-title" style="color: white !important;">Amenities</h2>
|
<h2 class="section-title">Amenities</h2>
|
||||||
<ul class="amenities-list">
|
<ul class="amenities-list">
|
||||||
<li style="color: white !important;"><i class="fa-solid fa-check"></i> Infinity Pool</li>
|
<li><i class="fa-solid fa-check"></i> Infinity Pool</li>
|
||||||
<li style="color: white !important;"><i class="fa-solid fa-check"></i> Home Theater</li>
|
<li><i class="fa-solid fa-check"></i> Home Theater</li>
|
||||||
<li style="color: white !important;"><i class="fa-solid fa-check"></i> Wine Cellar</li>
|
<li><i class="fa-solid fa-check"></i> Wine Cellar</li>
|
||||||
<li style="color: white !important;"><i class="fa-solid fa-check"></i> Smart Home</li>
|
<li><i class="fa-solid fa-check"></i> Smart Home</li>
|
||||||
|
<li><i class="fa-solid fa-check"></i> Spa & Sauna</li>
|
||||||
|
<li><i class="fa-solid fa-check"></i> Landscaped Gardens</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
<footer class="page-footer">
|
<footer class="page-footer">
|
||||||
<div style="color: white !important;"><strong style="color: white !important;">Agent:</strong> Olivia Sterling | (555) 987-6543</div>
|
<div><strong>Agent:</strong> Olivia Sterling | (555) 987-6543</div>
|
||||||
<div style="color: white !important;"><strong style="color: white !important;">Owner:</strong> John & Jane Doe</div>
|
<div><strong>Owner:</strong> John & Jane Doe</div>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template if:true={isAsgar1TemplateSelected}>
|
<template if:true={isGrandOakVillaTemplateSelected}>
|
||||||
<div class="selected-indicator">
|
<div class="selected-indicator">
|
||||||
<span class="selected-icon">✓</span>
|
<span class="selected-icon">✓</span>
|
||||||
<span class="selected-text">Selected</span>
|
<span class="selected-text">Selected</span>
|
||||||
@ -217,11 +269,11 @@
|
|||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- The Serenity House Template -->
|
<!-- The Serenity House Template (4th Grid) -->
|
||||||
<div class="template-card template-sample template-medium" data-template-id="serenity-house-template"
|
<div class="template-card template-sample template-medium" data-template-id="serenity-house-template"
|
||||||
onclick={handleTemplateSelect}>
|
onclick={handleTemplateSelect}>
|
||||||
<div class="template-content sample-preview">
|
<div class="template-content serenity-preview">
|
||||||
<!-- Page 1: Cover -->
|
<!-- Static HTML Preview from preview-serenity-house.html -->
|
||||||
<div class="brochure-page">
|
<div class="brochure-page">
|
||||||
<div class="p1-container">
|
<div class="p1-container">
|
||||||
<div class="p1-image-side"></div>
|
<div class="p1-image-side"></div>
|
||||||
@ -237,12 +289,17 @@
|
|||||||
An architectural marvel of curated living space.
|
An architectural marvel of curated living space.
|
||||||
<br>
|
<br>
|
||||||
<strong>Offered at $4,500,000</strong>
|
<strong>Offered at $4,500,000</strong>
|
||||||
|
<div class="contact-info">
|
||||||
|
<div class="contact-name">Sarah Johnson</div>
|
||||||
|
<div class="contact-phone">(555) 123-4567</div>
|
||||||
|
<div class="contact-title">Your Real Estate Professional</div>
|
||||||
|
<div class="contact-email">sarah@realestate.com</div>
|
||||||
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Page 2: Content -->
|
|
||||||
<div class="brochure-page">
|
<div class="brochure-page">
|
||||||
<div class="page-layout">
|
<div class="page-layout">
|
||||||
<span class="page-number">02</span>
|
<span class="page-number">02</span>
|
||||||
@ -268,15 +325,16 @@
|
|||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- The Vertice Template -->
|
<!-- The Vertice Template (5th Grid) -->
|
||||||
<div class="template-card template-luxury template-tall" data-template-id="luxury-mansion-template"
|
<div class="template-card template-luxury template-tall" data-template-id="luxury-mansion-template"
|
||||||
onclick={handleTemplateSelect}>
|
onclick={handleTemplateSelect}>
|
||||||
<div class="template-content luxury-preview">
|
<div class="template-content vertice-preview">
|
||||||
|
<!-- Static HTML Preview from preview-vertice.html -->
|
||||||
<div class="brochure-page cover-page">
|
<div class="brochure-page cover-page">
|
||||||
<div class="cover-overlay"></div>
|
<div class="cover-overlay"></div>
|
||||||
<div class="cover-content">
|
<div class="cover-content">
|
||||||
<div class="subtitle">An Urban Oasis</div>
|
<div class="subtitle">An Urban Oasis</div>
|
||||||
<h1 class="main-title" style="color: white !important;">THE VERTICE</h1>
|
<h1 class="main-title">THE VERTICE</h1>
|
||||||
<div class="address">18 Skyline Avenue, Metropolis Centre, MC 90210</div>
|
<div class="address">18 Skyline Avenue, Metropolis Centre, MC 90210</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="cover-footer">
|
<div class="cover-footer">
|
||||||
@ -300,7 +358,7 @@
|
|||||||
<div class="vision-image"></div>
|
<div class="vision-image"></div>
|
||||||
</main>
|
</main>
|
||||||
<footer class="page-footer-bar">
|
<footer class="page-footer-bar">
|
||||||
<span class="property-name" style="color: white !important;">THE VERTICE</span>
|
<span class="property-name">THE VERTICE</span>
|
||||||
<span>Page 02 / 06</span>
|
<span>Page 02 / 06</span>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
@ -320,7 +378,7 @@
|
|||||||
<div class="gallery-item g-item-5"><span>Private Balcony Views</span></div>
|
<div class="gallery-item g-item-5"><span>Private Balcony Views</span></div>
|
||||||
</main>
|
</main>
|
||||||
<footer class="page-footer-bar">
|
<footer class="page-footer-bar">
|
||||||
<span class="property-name" style="color: white !important;">THE VERTICE</span>
|
<span class="property-name">THE VERTICE</span>
|
||||||
<span>Page 03 / 06</span>
|
<span>Page 03 / 06</span>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
@ -334,6 +392,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Step 1 Navigation -->
|
<!-- Step 1 Navigation -->
|
||||||
@ -369,7 +429,7 @@
|
|||||||
<option value="">-- Select a Property --</option>
|
<option value="">-- Select a Property --</option>
|
||||||
<template for:each={properties} for:item="property">
|
<template for:each={properties} for:item="property">
|
||||||
<option key={property.Id} value={property.Id}>
|
<option key={property.Id} value={property.Id}>
|
||||||
{property.Name} - {property.pcrm__Property_Type__c} -
|
{property.Name} - {property.pcrm__Title_English__c} - {property.pcrm__Property_Type__c} -
|
||||||
{property.pcrm__City_Bayut_Dubizzle__c}
|
{property.pcrm__City_Bayut_Dubizzle__c}
|
||||||
</option>
|
</option>
|
||||||
</template>
|
</template>
|
||||||
@ -449,10 +509,6 @@
|
|||||||
<span class="label">Status:</span>
|
<span class="label">Status:</span>
|
||||||
<span class="value">{propertyData.status}</span>
|
<span class="value">{propertyData.status}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="property-field">
|
|
||||||
<span class="label">Reference Number:</span>
|
|
||||||
<span class="value">{propertyData.referenceNumber}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -706,38 +762,15 @@
|
|||||||
<!-- Image Review Section -->
|
<!-- Image Review Section -->
|
||||||
<template if:true={selectedPropertyId}>
|
<template if:true={selectedPropertyId}>
|
||||||
<div class="image-review-section">
|
<div class="image-review-section">
|
||||||
<h3>Property Images by Category</h3>
|
<h3>Property Image</h3>
|
||||||
<p>Review and select images for your brochure by category</p>
|
<p>Review and select images for your brochure</p>
|
||||||
|
|
||||||
<!-- Category Navigation -->
|
<!-- Offering Type Display -->
|
||||||
<div class="category-navigation-step2">
|
<div class="offering-type-display">
|
||||||
<button class="category-btn-step2" onclick={selectCategory} data-category="None">
|
<div class="offering-type-badge">
|
||||||
None
|
<span class="offering-type-label">Offering Type:</span>
|
||||||
</button>
|
<span class="offering-type-value">{propertyData.offeringType}</span>
|
||||||
<button class="category-btn-step2" onclick={selectCategory} data-category="Interior">
|
</div>
|
||||||
Interior
|
|
||||||
</button>
|
|
||||||
<button class="category-btn-step2" onclick={selectCategory} data-category="Exterior">
|
|
||||||
Exterior
|
|
||||||
</button>
|
|
||||||
<button class="category-btn-step2" onclick={selectCategory} data-category="Kitchen">
|
|
||||||
Kitchen
|
|
||||||
</button>
|
|
||||||
<button class="category-btn-step2" onclick={selectCategory} data-category="Bedroom">
|
|
||||||
Bedroom
|
|
||||||
</button>
|
|
||||||
<button class="category-btn-step2" onclick={selectCategory} data-category="Living Area">
|
|
||||||
Living Area
|
|
||||||
</button>
|
|
||||||
<button class="category-btn-step2" onclick={selectCategory} data-category="Parking">
|
|
||||||
Parking
|
|
||||||
</button>
|
|
||||||
<button class="category-btn-step2" onclick={selectCategory} data-category="Anchor">
|
|
||||||
Anchor
|
|
||||||
</button>
|
|
||||||
<button class="category-btn-step2" onclick={selectCategory} data-category="Maps">
|
|
||||||
Maps
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Image Display Area -->
|
<!-- Image Display Area -->
|
||||||
@ -749,7 +782,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template if:false={currentImage}>
|
<template if:false={currentImage}>
|
||||||
<div class="no-image-message-step2">
|
<div class="no-image-message-step2">
|
||||||
<p>No images found for {selectedCategory}</p>
|
<p>No images found</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@ -784,9 +817,9 @@
|
|||||||
|
|
||||||
<!-- Step 3: HTML Editor -->
|
<!-- Step 3: HTML Editor -->
|
||||||
<div class={step3Class} data-step="3">
|
<div class={step3Class} data-step="3">
|
||||||
|
<div class="step-inner-container">
|
||||||
<!-- Editor Container with Sidebar Layout -->
|
<!-- Editor Container with Sidebar Layout -->
|
||||||
<div class="editor-container">
|
<div class="editor-container">
|
||||||
<!-- Left Sidebar: Toolbox -->
|
<!-- Left Sidebar: Toolbox -->
|
||||||
<div class="editor-left">
|
<div class="editor-left">
|
||||||
<div class="quill-editor-container">
|
<div class="quill-editor-container">
|
||||||
@ -1062,14 +1095,36 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Enhanced Content Editor -->
|
<!-- Viewport Toolbar - Removed for cleaner interface -->
|
||||||
<div class="enhanced-editor-content" contenteditable="true" onkeyup={handleContentChange}
|
|
||||||
onpaste={handleContentChange} ondragover={handleEditorDragOver} ondrop={handleEditorDrop}>
|
<!-- PDF Viewport -->
|
||||||
<!-- Template content will be loaded here -->
|
<div class="pdf-viewport">
|
||||||
{htmlContent}
|
<div class="pdf-canvas" style={pdfCanvasStyle} data-page-size={selectedPageSize}>
|
||||||
|
<!-- Pages will be dynamically generated here -->
|
||||||
|
<template if:true={previewPages}>
|
||||||
|
<template for:each={previewPages} for:item="page" for:index="pageIndex">
|
||||||
|
<div key={page.id} class="preview-page" data-page-size={selectedPageSize} data-page-number={pageIndex}>
|
||||||
|
<div class="enhanced-editor-content" contenteditable="true" onkeyup={handleContentChange}
|
||||||
|
onpaste={handleContentChange} ondragover={handleEditorDragOver} ondrop={handleEditorDrop}>
|
||||||
|
{page.content}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<template if:false={previewPages}>
|
||||||
|
<div class="preview-page" data-page-size={selectedPageSize} data-page-number="1">
|
||||||
|
<div class="enhanced-editor-content" contenteditable="true" onkeyup={handleContentChange}
|
||||||
|
onpaste={handleContentChange} ondragover={handleEditorDragOver} ondrop={handleEditorDrop}>
|
||||||
|
<!-- Template content will be loaded here -->
|
||||||
|
{htmlContent}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@ -1108,7 +1163,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template if:false={currentImage}>
|
<template if:false={currentImage}>
|
||||||
<div class="no-image-message">
|
<div class="no-image-message">
|
||||||
<p>No images found for {selectedCategory}</p>
|
<p>No images found</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@ -1178,9 +1233,16 @@
|
|||||||
|
|
||||||
<!-- Local Upload Tab -->
|
<!-- Local Upload Tab -->
|
||||||
<div if:true={showLocalUploadTab} class="local-upload-section">
|
<div if:true={showLocalUploadTab} class="local-upload-section">
|
||||||
<div class="upload-area">
|
<div class="upload-area"
|
||||||
|
ondragover={handleDragOver}
|
||||||
|
ondragleave={handleDragLeave}
|
||||||
|
ondrop={handleDrop}>
|
||||||
<input type="file" class="image-upload-input" accept="image/*" onchange={handleImageUpload} style="display: none;">
|
<input type="file" class="image-upload-input" accept="image/*" onchange={handleImageUpload} style="display: none;">
|
||||||
<div class="upload-dropzone" onclick={triggerFileUpload}>
|
<div class="upload-dropzone"
|
||||||
|
onclick={triggerImageReplacementFileUpload}
|
||||||
|
ondragover={handleDragOver}
|
||||||
|
ondragleave={handleDragLeave}
|
||||||
|
ondrop={handleDrop}>
|
||||||
<div class="upload-icon">📁</div>
|
<div class="upload-icon">📁</div>
|
||||||
<div class="upload-text">
|
<div class="upload-text">
|
||||||
<h4>Choose Image File</h4>
|
<h4>Choose Image File</h4>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -88,7 +88,14 @@
|
|||||||
}
|
}
|
||||||
.feature-item { border-right: 1px solid var(--color-border); }
|
.feature-item { border-right: 1px solid var(--color-border); }
|
||||||
.feature-item:last-child { border-right: none; }
|
.feature-item:last-child { border-right: none; }
|
||||||
|
.feature-item .value {
|
||||||
|
font-size: 1.2rem; font-weight: 600;
|
||||||
|
color: var(--color-white); margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
.feature-item .label {
|
||||||
|
font-size: 0.7rem; color: var(--color-text-secondary);
|
||||||
|
text-transform: uppercase; letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
.content-body {
|
.content-body {
|
||||||
background-color: var(--color-dark-charcoal); color: var(--color-text-primary);
|
background-color: var(--color-dark-charcoal); color: var(--color-text-primary);
|
||||||
@ -187,20 +194,20 @@
|
|||||||
<div class="cover-overlay"></div>
|
<div class="cover-overlay"></div>
|
||||||
<header class="cover-header"><div class="logo">Elysian</div><div class="property-status">FOR SALE</div></header>
|
<header class="cover-header"><div class="logo">Elysian</div><div class="property-status">FOR SALE</div></header>
|
||||||
<main class="cover-content">
|
<main class="cover-content">
|
||||||
<h1 class="cover-title" style="color: white;">Modern Villa</h1>
|
<h1 class="cover-title">The Grand Oak Villa</h1>
|
||||||
<p class="cover-address" style="color: white;"><i class="fa-solid fa-location-dot"></i> 123 Luxury Lane, Prestige City, PC 45678</p>
|
<p class="cover-address"><i class="fa-solid fa-location-dot"></i> 123 Luxury Lane, Prestige City, PC 45678</p>
|
||||||
</main>
|
</main>
|
||||||
<footer class="cover-footer">
|
<footer class="cover-footer">
|
||||||
<div class="feature-item"><div style="font-size: 1.2rem; font-weight: 600; color: white; margin-bottom: 4px;">4</div><div style="font-size: 0.7rem; color: #888888; text-transform: uppercase; letter-spacing: 0.5px;">Beds</div></div>
|
<div class="feature-item"><div class="value">5</div><div class="label">Bedrooms</div></div>
|
||||||
<div class="feature-item"><div style="font-size: 1.2rem; font-weight: 600; color: white; margin-bottom: 4px;">3</div><div style="font-size: 0.7rem; color: #888888; text-transform: uppercase; letter-spacing: 0.5px;">Baths</div></div>
|
<div class="feature-item"><div class="value">6</div><div class="label">Bathrooms</div></div>
|
||||||
<div class="feature-item"><div style="font-size: 1.2rem; font-weight: 600; color: white; margin-bottom: 4px;">6,200</div><div style="font-size: 0.7rem; color: #888888; text-transform: uppercase; letter-spacing: 0.5px;">Sq. Ft.</div></div>
|
<div class="feature-item"><div class="value">6,200</div><div class="label">Sq. Ft.</div></div>
|
||||||
<div class="feature-item"><div style="font-size: 1.2rem; font-weight: 600; color: white; margin-bottom: 4px;">$2,500,000</div><div style="font-size: 0.7rem; color: #888888; text-transform: uppercase; letter-spacing: 0.5px;">Price</div></div>
|
<div class="feature-item"><div class="value">$4.5M</div><div class="label">Price</div></div>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="brochure-page">
|
<div class="brochure-page">
|
||||||
<div class="content-body">
|
<div class="content-body">
|
||||||
<header class="page-header"><h1 class="title">Property <span>Overview</span></h1><span class="property-name" style="color: #C0A062;">The Grand Oak Villa</span></header>
|
<header class="page-header"><h1 class="title">Property <span>Overview</span></h1><span class="property-name">The Grand Oak Villa</span></header>
|
||||||
<main class="main-content details-grid">
|
<main class="main-content details-grid">
|
||||||
<div>
|
<div>
|
||||||
<h2 class="section-title">Description</h2>
|
<h2 class="section-title">Description</h2>
|
||||||
|
|||||||
401
template samples/the grand oak villa.html
Normal file
401
template samples/the grand oak villa.html
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Prestige Real Estate Brochure - 4 Page</title>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;600;700&family=Playfair+Display:wght@700&display=swap" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
||||||
|
<style>
|
||||||
|
/* --- DESIGN SYSTEM & VARIABLES --- */
|
||||||
|
:root {
|
||||||
|
/* Color Palette */
|
||||||
|
--color-dark-charcoal: #121212;
|
||||||
|
--color-light-gray: #F5F5F5;
|
||||||
|
--color-text-primary: #D1D1D1;
|
||||||
|
--color-text-secondary: #888888;
|
||||||
|
--color-accent-gold: #C0A062;
|
||||||
|
--color-white: #FFFFFF;
|
||||||
|
--color-border: #2a2a2a;
|
||||||
|
|
||||||
|
/* Typography */
|
||||||
|
--font-primary: 'Montserrat', sans-serif;
|
||||||
|
--font-secondary: 'Playfair Display', serif;
|
||||||
|
|
||||||
|
/* Spacing */
|
||||||
|
--padding-page: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- GLOBAL & BODY STYLES --- */
|
||||||
|
body {
|
||||||
|
font-family: var(--font-primary);
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 50px;
|
||||||
|
margin: 0;
|
||||||
|
gap: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brochure-page {
|
||||||
|
width: 210mm;
|
||||||
|
height: 297mm;
|
||||||
|
background-color: var(--color-white);
|
||||||
|
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.2);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- PAGE 1: FRONT COVER --- */
|
||||||
|
.cover-page {
|
||||||
|
position: relative;
|
||||||
|
background-image: url('https://images.unsplash.com/photo-1580587771525-78b9dba3b914?ixlib=rb-4.0.3&q=85&fm=jpg&crop=entropy&cs=srgb&w=1200');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
color: var(--color-white);
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.cover-overlay {
|
||||||
|
position: absolute; top: 0; left: 0; width: 100%; height: 100%;
|
||||||
|
background: linear-gradient(180deg, rgba(18, 18, 18, 0.8) 0%, rgba(18, 18, 18, 0.3) 100%);
|
||||||
|
}
|
||||||
|
.cover-header {
|
||||||
|
position: relative; padding: var(--padding-page); display: flex;
|
||||||
|
justify-content: space-between; align-items: center;
|
||||||
|
}
|
||||||
|
.logo {
|
||||||
|
font-family: var(--font-secondary); font-size: 1.5rem; font-weight: 700;
|
||||||
|
letter-spacing: 2px; border: 2px solid var(--color-white); padding: 8px 15px;
|
||||||
|
}
|
||||||
|
.property-status {
|
||||||
|
background-color: var(--color-accent-gold); color: var(--color-dark-charcoal);
|
||||||
|
padding: 10px 20px; font-weight: 600; font-size: 0.9rem; text-transform: uppercase;
|
||||||
|
}
|
||||||
|
.cover-content { position: relative; padding: var(--padding-page); max-width: 65%; }
|
||||||
|
.cover-title {
|
||||||
|
font-family: var(--font-secondary); font-size: 4.5rem; font-weight: 700;
|
||||||
|
line-height: 1.1; margin: 0 0 10px 0; color: var(--color-white);
|
||||||
|
}
|
||||||
|
.cover-address {
|
||||||
|
font-size: 1.2rem; font-weight: 400; display: flex;
|
||||||
|
align-items: center; gap: 10px; color: var(--color-text-primary);
|
||||||
|
}
|
||||||
|
.cover-address i { color: var(--color-accent-gold); }
|
||||||
|
.cover-footer {
|
||||||
|
position: relative; background-color: rgba(18, 18, 18, 0.9);
|
||||||
|
padding: 30px var(--padding-page); display: grid; grid-template-columns: repeat(4, 1fr);
|
||||||
|
gap: 20px; text-align: center;
|
||||||
|
}
|
||||||
|
.feature-item { border-right: 1px solid var(--color-border); }
|
||||||
|
.feature-item:last-child { border-right: none; }
|
||||||
|
.feature-item .value {
|
||||||
|
font-size: 1.5rem; font-weight: 600;
|
||||||
|
color: var(--color-white); margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.feature-item .label {
|
||||||
|
font-size: 0.8rem; color: var(--color-text-secondary);
|
||||||
|
text-transform: uppercase; letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- SHARED STYLES for Content Pages --- */
|
||||||
|
.content-body {
|
||||||
|
background-color: var(--color-dark-charcoal); color: var(--color-text-primary);
|
||||||
|
flex-grow: 1; padding: var(--padding-page); display: flex; flex-direction: column;
|
||||||
|
}
|
||||||
|
.page-header {
|
||||||
|
display: flex; justify-content: space-between; align-items: baseline;
|
||||||
|
padding-bottom: 20px; margin-bottom: 30px; border-bottom: 1px solid var(--color-border);
|
||||||
|
}
|
||||||
|
.page-header .title {
|
||||||
|
font-family: var(--font-secondary); font-size: 2.2rem; color: var(--color-white);
|
||||||
|
}
|
||||||
|
.page-header .title span { color: var(--color-accent-gold); }
|
||||||
|
.page-header .property-name {
|
||||||
|
font-size: 1rem; font-weight: 600; color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
.section-title {
|
||||||
|
font-weight: 600; font-size: 1rem; color: var(--color-white);
|
||||||
|
margin: 0 0 25px 0; text-transform: uppercase; letter-spacing: 2px;
|
||||||
|
position: relative; padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
.section-title::after {
|
||||||
|
content: ''; position: absolute; bottom: 0; left: 0;
|
||||||
|
width: 50px; height: 3px; background-color: var(--color-accent-gold);
|
||||||
|
}
|
||||||
|
.main-content { flex-grow: 1; }
|
||||||
|
.page-footer {
|
||||||
|
background-color: #0A0A0A;
|
||||||
|
padding: 20px var(--padding-page);
|
||||||
|
font-size: 0.9rem; color: var(--color-text-secondary);
|
||||||
|
border-top: 1px solid var(--color-border);
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.page-footer strong { color: var(--color-accent-gold); font-weight: 600; }
|
||||||
|
|
||||||
|
/* --- PAGE 2: DETAILS --- */
|
||||||
|
.details-grid {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
.description p {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
line-height: 1.8;
|
||||||
|
margin: 0 0 15px 0;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
}
|
||||||
|
.specs-and-amenities {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 50px;
|
||||||
|
}
|
||||||
|
.spec-list .item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
padding: 12px 0;
|
||||||
|
border-bottom: 1px solid var(--color-border);
|
||||||
|
}
|
||||||
|
.spec-list .item:first-child { padding-top: 0; }
|
||||||
|
.spec-list .item .key { font-weight: 600; color: var(--color-text-secondary); }
|
||||||
|
.spec-list .item .value { font-weight: 400; color: var(--color-white); }
|
||||||
|
.amenities-list { list-style: none; padding: 0; margin: 0; columns: 2; gap: 15px; }
|
||||||
|
.amenities-list li { font-size: 0.9rem; margin-bottom: 15px; display: flex; align-items: center; }
|
||||||
|
.amenities-list i { color: var(--color-accent-gold); margin-right: 12px; font-size: 1.1rem; }
|
||||||
|
|
||||||
|
/* --- PAGE 3: LOCATION (NEW LAYOUT) --- */
|
||||||
|
.location-body { padding: 0; } /* Override default padding */
|
||||||
|
.location-map-container {
|
||||||
|
height: 45%;
|
||||||
|
background-image: url('https://images.unsplash.com/photo-1549880181-56a44cf4a9a5?ixlib=rb-4.0.3&q=85&fm=jpg&crop=entropy&cs=srgb&w=1200');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center 75%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.location-map-container::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 70%;
|
||||||
|
background: linear-gradient(180deg, rgba(18, 18, 18, 0) 0%, var(--color-dark-charcoal) 90%);
|
||||||
|
}
|
||||||
|
.location-content { padding: var(--padding-page); }
|
||||||
|
.poi-grid {
|
||||||
|
display: grid; grid-template-columns: repeat(4, 1fr);
|
||||||
|
gap: 30px; margin-top: 40px;
|
||||||
|
}
|
||||||
|
.poi-item { text-align: center; }
|
||||||
|
.poi-item .icon {
|
||||||
|
font-size: 2.5rem; color: var(--color-accent-gold); margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.poi-item .title {
|
||||||
|
font-weight: 600; font-size: 1rem; color: var(--color-white); margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.poi-item .details { font-size: 0.9rem; color: var(--color-text-secondary); }
|
||||||
|
|
||||||
|
/* --- PAGE 4: LAYOUT & LIFESTYLE (REVISED) --- */
|
||||||
|
.page-split-layout {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1.6fr 1fr;
|
||||||
|
gap: 50px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.gallery-section, .additional-info-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.additional-info-section .spec-list {
|
||||||
|
margin-top: 25px;
|
||||||
|
}
|
||||||
|
.photo-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
grid-template-rows: 1fr 1fr;
|
||||||
|
gap: 20px;
|
||||||
|
margin-top: 25px;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
.photo-item {
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
.photo-item-1 {
|
||||||
|
grid-column: 1 / -1; /* Span full width */
|
||||||
|
background-image: url('https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&q=85&fm=jpg&crop=entropy&cs=srgb&w=1200');
|
||||||
|
}
|
||||||
|
.photo-item-2 {
|
||||||
|
background-image: url('https://images.unsplash.com/photo-1600585152225-3579fe9d7ae2?ixlib=rb-4.0.3&q=85&fm=jpg&crop=entropy&cs=srgb&w=1200');
|
||||||
|
}
|
||||||
|
.photo-item-3 {
|
||||||
|
background-image: url('https://images.unsplash.com/photo-1600585153325-1a75f8a4f631?ixlib=rb-4.0.3&q=85&fm=jpg&crop=entropy&cs=srgb&w=1200');
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="brochure-page cover-page">
|
||||||
|
<div class="cover-overlay"></div>
|
||||||
|
<header class="cover-header"><div class="logo">Elysian</div><div class="property-status">FOR SALE</div></header>
|
||||||
|
<main class="cover-content">
|
||||||
|
<h1 class="cover-title">The Grand Oak Villa</h1>
|
||||||
|
<p class="cover-address"><i class="fa-solid fa-location-dot"></i> 123 Luxury Lane, Prestige City, PC 45678</p>
|
||||||
|
</main>
|
||||||
|
<footer class="cover-footer">
|
||||||
|
<div class="feature-item"><div class="value">5</div><div class="label">Bedrooms</div></div>
|
||||||
|
<div class="feature-item"><div class="value">6</div><div class="label">Bathrooms</div></div>
|
||||||
|
<div class="feature-item"><div class="value">6,200</div><div class="label">Sq. Ft.</div></div>
|
||||||
|
<div class="feature-item"><div class="value">$4,500,000</div><div class="label">Price</div></div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="brochure-page">
|
||||||
|
<div class="content-body">
|
||||||
|
<header class="page-header"><h1 class="title">Property <span>Overview</span></h1><span class="property-name">The Grand Oak Villa</span></header>
|
||||||
|
<main class="main-content details-grid">
|
||||||
|
<div>
|
||||||
|
<h2 class="section-title">Description</h2>
|
||||||
|
<div class="description">
|
||||||
|
<p>Nestled in the heart of Prestige City, The Grand Oak Villa is a masterpiece of modern architecture and timeless elegance. This expansive 6,200 sq. ft. residence offers unparalleled luxury and privacy.</p>
|
||||||
|
<p>With soaring ceilings, bespoke finishes, and panoramic views from every room, this home is designed for those who appreciate the finer things in life. The open-plan living space is perfect for entertaining, featuring a gourmet chef's kitchen, a formal dining area, and a grand living room with a statement fireplace.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="specs-and-amenities">
|
||||||
|
<div>
|
||||||
|
<h2 class="section-title">Specifications</h2>
|
||||||
|
<div class="spec-list">
|
||||||
|
<div class="item"><span class="key">Reference ID:</span> <span class="value">[Reference ID]</span></div>
|
||||||
|
<div class="item"><span class="key">Status:</span> <span class="value">[Status]</span></div>
|
||||||
|
<div class="item"><span class="key">Type:</span> <span class="value">[Property Type]</span></div>
|
||||||
|
<div class="item"><span class="key">Year Built:</span> <span class="value">[Year Built]</span></div>
|
||||||
|
<div class="item"><span class="key">Floor:</span> <span class="value">[Floor]</span></div>
|
||||||
|
<div class="item"><span class="key">Parking:</span> <span class="value">[Parking]</span></div>
|
||||||
|
<div class="item"><span class="key">Furnishing:</span> <span class="value">[Furnishing]</span></div>
|
||||||
|
<div class="item"><span class="key">Maintenance Fee:</span> <span class="value">[Maintenance Fee]</span></div>
|
||||||
|
<div class="item"><span class="key">Service Charge:</span> <span class="value">[Service Charge]</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2 class="section-title">Amenities & Features</h2>
|
||||||
|
<ul class="amenities-list">
|
||||||
|
<li><i class="fa-solid fa-check"></i> Infinity Pool</li><li><i class="fa-solid fa-check"></i> Private Home Theater</li><li><i class="fa-solid fa-check"></i> Gourmet Chef's Kitchen</li><li><i class="fa-solid fa-check"></i> Wine Cellar</li><li><i class="fa-solid fa-check"></i> Smart Home Automation</li><li><i class="fa-solid fa-check"></i> Spa & Sauna Room</li><li><i class="fa-solid fa-check"></i> Landscaped Gardens</li><li><i class="fa-solid fa-check"></i> Outdoor Fire Pit</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
<footer class="page-footer">
|
||||||
|
<div><strong>Agent:</strong> [Agent Name] | [Agent Phone] | [Agent Email]</div>
|
||||||
|
<div><strong>Owner:</strong> [Owner Name] | [Owner Phone] | [Owner Email]</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="brochure-page">
|
||||||
|
<div class="content-body location-body">
|
||||||
|
<div class="location-map-container"></div>
|
||||||
|
<div class="location-content">
|
||||||
|
<header class="page-header" style="margin-bottom: 0;">
|
||||||
|
<h1 class="title">An Unrivaled <span>Setting</span></h1>
|
||||||
|
<span class="property-name">123 Luxury Lane, Prestige City</span>
|
||||||
|
</header>
|
||||||
|
<div class="poi-grid">
|
||||||
|
<div class="poi-item">
|
||||||
|
<div class="icon"><i class="fa-solid fa-school"></i></div>
|
||||||
|
<div class="title">Schools</div>
|
||||||
|
<div class="details">[Schools]</div>
|
||||||
|
</div>
|
||||||
|
<div class="poi-item">
|
||||||
|
<div class="icon"><i class="fa-solid fa-shopping-cart"></i></div>
|
||||||
|
<div class="title">Shopping</div>
|
||||||
|
<div class="details">[Shopping Centers]</div>
|
||||||
|
</div>
|
||||||
|
<div class="poi-item">
|
||||||
|
<div class="icon"><i class="fa-solid fa-plane"></i></div>
|
||||||
|
<div class="title">Airport</div>
|
||||||
|
<div class="details">[Airport Distance]</div>
|
||||||
|
</div>
|
||||||
|
<div class="poi-item">
|
||||||
|
<div class="icon"><i class="fa-solid fa-landmark"></i></div>
|
||||||
|
<div class="title">Landmarks</div>
|
||||||
|
<div class="details">[Nearby Landmarks]</div>
|
||||||
|
</div>
|
||||||
|
<div class="poi-item">
|
||||||
|
<div class="icon"><i class="fa-solid fa-bus"></i></div>
|
||||||
|
<div class="title">Transportation</div>
|
||||||
|
<div class="details">[Transportation]</div>
|
||||||
|
</div>
|
||||||
|
<div class="poi-item">
|
||||||
|
<div class="icon"><i class="fa-solid fa-hospital"></i></div>
|
||||||
|
<div class="title">Hospitals</div>
|
||||||
|
<div class="details">[Hospitals]</div>
|
||||||
|
</div>
|
||||||
|
<div class="poi-item">
|
||||||
|
<div class="icon"><i class="fa-solid fa-umbrella-beach"></i></div>
|
||||||
|
<div class="title">Beach</div>
|
||||||
|
<div class="details">[Beach Distance]</div>
|
||||||
|
</div>
|
||||||
|
<div class="poi-item">
|
||||||
|
<div class="icon"><i class="fa-solid fa-subway"></i></div>
|
||||||
|
<div class="title">Metro</div>
|
||||||
|
<div class="details">[Metro Distance]</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer class="page-footer">
|
||||||
|
<div><strong>Agent:</strong> [Agent Name] | [Agent Phone] | [Agent Email]</div>
|
||||||
|
<div><strong>Owner:</strong> [Owner Name] | [Owner Phone] | [Owner Email]</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="brochure-page">
|
||||||
|
<div class="content-body">
|
||||||
|
<header class="page-header">
|
||||||
|
<h1 class="title">Layout & <span>Lifestyle</span></h1>
|
||||||
|
<span class="property-name">The Grand Oak Villa</span>
|
||||||
|
</header>
|
||||||
|
<main class="main-content page-split-layout">
|
||||||
|
<section class="gallery-section">
|
||||||
|
<h2 class="section-title">A Glimpse Inside</h2>
|
||||||
|
<div class="photo-grid">
|
||||||
|
<div class="photo-item photo-item-1"></div>
|
||||||
|
<div class="photo-item photo-item-2"></div>
|
||||||
|
<div class="photo-item photo-item-3"></div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="additional-info-section">
|
||||||
|
<h2 class="section-title">Additional Information</h2>
|
||||||
|
<div class="spec-list">
|
||||||
|
<div class="item"><span class="key">Pet Friendly:</span> <span class="value">[Pet Friendly Status]</span></div>
|
||||||
|
<div class="item"><span class="key">Smoking:</span> <span class="value">[Smoking Allowed]</span></div>
|
||||||
|
<div class="item"><span class="key">Available From:</span> <span class="value">[Available From Date]</span></div>
|
||||||
|
<div class="item"><span class="key">Minimum Contract:</span> <span class="value">[Minimum Contract Duration]</span></div>
|
||||||
|
<div class="item"><span class="key">Security Deposit:</span> <span class="value">[Security Deposit]</span></div>
|
||||||
|
<div class="item"><span class="key">Utilities Included:</span> <span class="value">[Utilities Included]</span></div>
|
||||||
|
<div class="item"><span class="key">Internet Included:</span> <span class="value">[Internet Included]</span></div>
|
||||||
|
<div class="item"><span class="key">Cable Included:</span> <span class="value">[Cable Included]</span></div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
<footer class="page-footer">
|
||||||
|
<div><strong>Agent:</strong> [Agent Name] | [Agent Phone] | [Agent Email]</div>
|
||||||
|
<div><strong>Owner:</strong> [Owner Name] | [Owner Phone] | [Owner Email]</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
426
template samples/the serenity.html
Normal file
426
template samples/the serenity.html
Normal file
@ -0,0 +1,426 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Editorial Real Estate Brochure - Updated</title>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700&family=Cormorant+Garamond:wght@400;600;700&display=swap" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
||||||
|
<style>
|
||||||
|
/* --- DESIGN SYSTEM & VARIABLES --- */
|
||||||
|
:root {
|
||||||
|
/* Color Palette */
|
||||||
|
--color-bg: #FFFFFF;
|
||||||
|
--color-off-white: #F8F7F5;
|
||||||
|
--color-text-primary: #333333;
|
||||||
|
--color-text-secondary: #777777;
|
||||||
|
--color-accent-beige: #D4C7B8;
|
||||||
|
--color-border: #EAEAEA;
|
||||||
|
|
||||||
|
/* Typography */
|
||||||
|
--font-serif: 'Cormorant Garamond', serif;
|
||||||
|
--font-sans: 'Lato', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- GLOBAL & BODY STYLES --- */
|
||||||
|
body {
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
background-color: #d8d8d8;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 50px;
|
||||||
|
margin: 0;
|
||||||
|
gap: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brochure-page {
|
||||||
|
width: 210mm;
|
||||||
|
height: 297mm;
|
||||||
|
background-color: var(--color-bg);
|
||||||
|
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.15);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- PAGE 1: FRONT COVER --- */
|
||||||
|
.p1-container {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.p1-image-side {
|
||||||
|
flex: 1.2;
|
||||||
|
background-image: url('https://images.unsplash.com/photo-1600585154340-be6161a56a0c?ixlib=rb-4.0.3&q=85&fm=jpg&crop=entropy&cs=srgb&w=1200');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
.p1-content-side {
|
||||||
|
flex: 1;
|
||||||
|
padding: 70px 60px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.p1-header .collection {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
letter-spacing: 3px;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
.p1-main-title {
|
||||||
|
font-family: var(--font-serif);
|
||||||
|
font-size: 5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.1;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
.p1-address {
|
||||||
|
font-size: 1rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
border-left: 3px solid var(--color-accent-beige);
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
.p1-ref-id {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
margin-top: 15px;
|
||||||
|
padding-left: 23px;
|
||||||
|
}
|
||||||
|
.p1-footer {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
.p1-footer strong {
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
}
|
||||||
|
.p1-footer .area {
|
||||||
|
font-size: 1rem;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- SHARED STYLES for Content Pages --- */
|
||||||
|
.page-layout {
|
||||||
|
padding: 70px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.page-number {
|
||||||
|
position: absolute;
|
||||||
|
top: 70px; right: 70px;
|
||||||
|
font-family: var(--font-serif);
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
.page-title-main {
|
||||||
|
font-family: var(--font-serif);
|
||||||
|
font-size: 3.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
margin: 0 0 15px 0;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
.page-title-sub {
|
||||||
|
font-size: 1rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
margin-bottom: 50px;
|
||||||
|
}
|
||||||
|
.content-divider {
|
||||||
|
border: 0;
|
||||||
|
height: 1px;
|
||||||
|
background-color: var(--color-border);
|
||||||
|
margin: 30px 0;
|
||||||
|
}
|
||||||
|
.section-title {
|
||||||
|
font-family: var(--font-serif);
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- PAGE 2: INTRODUCTION & NARRATIVE --- */
|
||||||
|
.p2-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 60px;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
.p2-image {
|
||||||
|
background-image: url('https://images.unsplash.com/photo-1618221195710-dd6b41faaea6?ixlib=rb-4.0.3&q=85&fm=jpg&crop=entropy&cs=srgb&w=800');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
.p2-text p {
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.8;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
.p2-text p:first-of-type::first-letter {
|
||||||
|
font-family: var(--font-serif);
|
||||||
|
font-size: 4rem;
|
||||||
|
float: left;
|
||||||
|
line-height: 1;
|
||||||
|
margin-right: 15px;
|
||||||
|
color: var(--color-accent-beige);
|
||||||
|
}
|
||||||
|
.pull-quote {
|
||||||
|
border-left: 3px solid var(--color-accent-beige);
|
||||||
|
padding-left: 25px;
|
||||||
|
margin: 30px 0;
|
||||||
|
font-family: var(--font-serif);
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-style: italic;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- PAGE 3: DETAILS & AMENITIES --- */
|
||||||
|
.p3-main-content { flex-grow: 1; }
|
||||||
|
.spec-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
gap: 30px;
|
||||||
|
padding: 30px;
|
||||||
|
background-color: var(--color-off-white);
|
||||||
|
}
|
||||||
|
.spec-item { text-align: center; }
|
||||||
|
.spec-item .value {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
}
|
||||||
|
.spec-item .label {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
.details-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 15px 40px;
|
||||||
|
}
|
||||||
|
.details-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
border-bottom: 1px solid var(--color-border);
|
||||||
|
padding-bottom: 10px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
.details-item .label { color: var(--color-text-secondary); }
|
||||||
|
.details-item .value { color: var(--color-text-primary); font-weight: 700; }
|
||||||
|
.amenities-list { list-style: none; padding: 0; column-count: 2; column-gap: 40px;}
|
||||||
|
.amenities-list li {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
-webkit-column-break-inside: avoid;
|
||||||
|
page-break-inside: avoid;
|
||||||
|
break-inside: avoid;
|
||||||
|
}
|
||||||
|
.amenities-list li i { color: var(--color-accent-beige); margin-right: 12px; }
|
||||||
|
|
||||||
|
/* --- PAGE 4: REVISED LAYOUT --- */
|
||||||
|
.p4-section-title {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
margin: 0 0 20px 0;
|
||||||
|
}
|
||||||
|
.p4-floorplan-container {
|
||||||
|
height: 320px;
|
||||||
|
background-color: var(--color-off-white);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
background-image: url('https://cdn.shopify.com/s/files/1/0024/0495/3953/files/Architect_s_floor_plan_for_a_house_in_black_and_white_large.jpg');
|
||||||
|
background-size: contain;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
.p4-info-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 60px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
.info-list .info-item, .location-list .item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 10px 0;
|
||||||
|
border-bottom: 1px solid var(--color-border);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
.info-list .info-item strong, .location-list .item strong {
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
.p4-contact-row {
|
||||||
|
display: flex;
|
||||||
|
gap: 40px;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: auto;
|
||||||
|
}
|
||||||
|
.contact-card {
|
||||||
|
background-color: var(--color-off-white);
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
flex: 1;
|
||||||
|
max-width: 300px;
|
||||||
|
}
|
||||||
|
.contact-card .title {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
.contact-card .name { font-family: var(--font-serif); font-size: 1.5rem; font-weight: 600; }
|
||||||
|
.contact-card .phone, .contact-card .email { font-size: 0.9rem; margin: 4px 0; color: var(--color-text-secondary); }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="brochure-page">
|
||||||
|
<div class="p1-container">
|
||||||
|
<div class="p1-image-side"></div>
|
||||||
|
<div class="p1-content-side">
|
||||||
|
<header class="p1-header">
|
||||||
|
<div class="collection">Elysian Estates Collection</div>
|
||||||
|
<h1 class="p1-main-title">The Serenity House</h1>
|
||||||
|
<p class="p1-address">123 Luxury Lane, Prestige City, PC 45678</p>
|
||||||
|
<p class="p1-ref-id">Reference ID: ES-8821</p>
|
||||||
|
</header>
|
||||||
|
<footer class="p1-footer">
|
||||||
|
<div class="area">6,200 Sq. Ft. • 5 Bedrooms • 6 Bathrooms</div>
|
||||||
|
An architectural marvel of curated living space.
|
||||||
|
<br>
|
||||||
|
<strong>Offered at $4,500,000</strong>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="brochure-page">
|
||||||
|
<div class="page-layout">
|
||||||
|
<span class="page-number">02</span>
|
||||||
|
<h1 class="page-title-main">A Sanctuary of Modern Design</h1>
|
||||||
|
<p class="page-title-sub">Where light, space, and nature converge to create an unparalleled living experience.</p>
|
||||||
|
<div class="p2-grid">
|
||||||
|
<div class="p2-text">
|
||||||
|
<p>Designed by the world-renowned architect, Helena Vance, The Serenity House is more than a home; it is a living sculpture. Every line, material, and detail has been thoughtfully considered to evoke a sense of peace and connection with the surrounding landscape. Soaring ceilings and floor-to-ceiling glass walls dissolve the boundaries between inside and out, flooding the space with natural light.</p>
|
||||||
|
<p class="pull-quote">A timeless residence built not just for living, but for thriving.</p>
|
||||||
|
<p>The interior palette is a harmonious blend of natural oak, Italian travertine, and warm bronze accents, creating an atmosphere of understated luxury. This property represents a unique opportunity to own a piece of architectural history.</p>
|
||||||
|
</div>
|
||||||
|
<div class="p2-image"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="brochure-page">
|
||||||
|
<div class="page-layout">
|
||||||
|
<span class="page-number">03</span>
|
||||||
|
<h1 class="page-title-main">Property Specifications</h1>
|
||||||
|
<p class="page-title-sub">A comprehensive overview of the property’s features, details, and amenities.</p>
|
||||||
|
|
||||||
|
<div class="p3-main-content">
|
||||||
|
<div class="spec-grid">
|
||||||
|
<div class="spec-item"><div class="value">5</div><div class="label">Bedrooms</div></div>
|
||||||
|
<div class="spec-item"><div class="value">6</div><div class="label">Bathrooms</div></div>
|
||||||
|
<div class="spec-item"><div class="value">6,200</div><div class="label">Square Feet</div></div>
|
||||||
|
<div class="spec-item"><div class="value">0.75</div><div class="label">Acres</div></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="content-divider">
|
||||||
|
|
||||||
|
<h3 class="section-title">Property Details</h3>
|
||||||
|
<div class="details-grid">
|
||||||
|
<div class="details-item"><span class="label">Status</span><span class="value">For Sale</span></div>
|
||||||
|
<div class="details-item"><span class="label">Year Built</span><span class="value">2023</span></div>
|
||||||
|
<div class="details-item"><span class="label">Type</span><span class="value">Single-Family Home</span></div>
|
||||||
|
<div class="details-item"><span class="label">Furnishing</span><span class="value">Partially Furnished</span></div>
|
||||||
|
<div class="details-item"><span class="label">Floor</span><span class="value">2 Levels</span></div>
|
||||||
|
<div class="details-item"><span class="label">Maintenance Fee</span><span class="value">$1,200 / month</span></div>
|
||||||
|
<div class="details-item"><span class="label">Parking</span><span class="value">3-Car Garage</span></div>
|
||||||
|
<div class="details-item"><span class="label">Service Charge</span><span class="value">Included</span></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="content-divider">
|
||||||
|
|
||||||
|
<h3 class="section-title">Amenities & Features</h3>
|
||||||
|
<ul class="amenities-list">
|
||||||
|
<li><i class="fa-solid fa-check"></i> Primary Suite with Spa-Bath</li>
|
||||||
|
<li><i class="fa-solid fa-check"></i> Radiant Heated Flooring</li>
|
||||||
|
<li><i class="fa-solid fa-check"></i> Custom Walk-in Closets</li>
|
||||||
|
<li><i class="fa-solid fa-check"></i> Smart Home Automation</li>
|
||||||
|
<li><i class="fa-solid fa-check"></i> Infinity Edge Saline Pool</li>
|
||||||
|
<li><i class="fa-solid fa-check"></i> Private Cinema Room</li>
|
||||||
|
<li><i class="fa-solid fa-check"></i> Temperature-Controlled Wine Cellar</li>
|
||||||
|
<li><i class="fa-solid fa-check"></i> Landscaped Gardens & Terrace</li>
|
||||||
|
<li><i class="fa-solid fa-check"></i> Gourmet Chef's Kitchen</li>
|
||||||
|
<li><i class="fa-solid fa-check"></i> Floor-to-Ceiling Glass Walls</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="brochure-page">
|
||||||
|
<div class="page-layout">
|
||||||
|
<span class="page-number">04</span>
|
||||||
|
<h1 class="page-title-main" style="margin-bottom: 30px;">Floor Plan & Details</h1>
|
||||||
|
|
||||||
|
<div class="p4-info-grid">
|
||||||
|
<div class="location-list">
|
||||||
|
<h2 class="p4-section-title">Location & Nearby</h2>
|
||||||
|
<div class="item"><strong>Schools</strong> <span>5 min drive</span></div>
|
||||||
|
<div class="item"><strong>Shopping</strong> <span>10 min drive</span></div>
|
||||||
|
<div class="item"><strong>Hospitals</strong> <span>12 min drive</span></div>
|
||||||
|
<div class="item"><strong>Country Club</strong> <span>8 min drive</span></div>
|
||||||
|
<div class="item"><strong>Airport</strong> <span>20 min drive</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="info-list">
|
||||||
|
<h2 class="p4-section-title">Additional Information</h2>
|
||||||
|
<div class="info-item"><strong>Pet-Friendly</strong> <span>By Approval</span></div>
|
||||||
|
<div class="info-item"><strong>Smoking</strong> <span>Not Permitted</span></div>
|
||||||
|
<div class="info-item"><strong>Availability</strong> <span>Immediate</span></div>
|
||||||
|
<div class="info-item"><strong>Utilities</strong> <span>Not Included</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="content-divider">
|
||||||
|
|
||||||
|
<h2 class="p4-section-title">Floor Plan & Location</h2>
|
||||||
|
<div class="p4-floorplan-container"></div>
|
||||||
|
|
||||||
|
<div class="p4-contact-row">
|
||||||
|
<div class="contact-card">
|
||||||
|
<div class="title">Owner Information</div>
|
||||||
|
<div class="name">John & Jane Doe</div>
|
||||||
|
<p class="phone">(555) 111-2222</p>
|
||||||
|
<p class="email">owner.serenity@email.com</p>
|
||||||
|
</div>
|
||||||
|
<div class="contact-card">
|
||||||
|
<div class="title">Agent Information</div>
|
||||||
|
<div class="name">Olivia Sterling</div>
|
||||||
|
<p class="phone">(555) 987-6543</p>
|
||||||
|
<p class="email">olivia@elysianestates.com</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue
Block a user