sitebuilder
This commit is contained in:
		
							parent
							
								
									0137a30e7b
								
							
						
					
					
						commit
						2caa796523
					
				
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							@ -50,6 +50,9 @@
 | 
				
			|||||||
        </ng-container></clr-dg-column>
 | 
					        </ng-container></clr-dg-column>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <clr-dg-column [clrDgField]="'html'"> <ng-container *clrDgHideableColumn="{hidden: false}"> Html
 | 
				
			||||||
 | 
					        </ng-container></clr-dg-column>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      <clr-dg-column [clrDgField]="'Json'"> <ng-container *clrDgHideableColumn="{hidden: false}"> htmljson
 | 
					      <clr-dg-column [clrDgField]="'Json'"> <ng-container *clrDgHideableColumn="{hidden: false}"> htmljson
 | 
				
			||||||
        </ng-container></clr-dg-column>
 | 
					        </ng-container></clr-dg-column>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -91,7 +94,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <clr-dg-cell (click)="goToReplaceStringhtmljson (user.html)"
 | 
				
			||||||
 | 
					          style="cursor: pointer; align-items: center;"><clr-icon shape="details"></clr-icon>
 | 
				
			||||||
 | 
					        </clr-dg-cell>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <clr-dg-cell (click)="goToReplaceStringhtmljson (user.htmljson)"
 | 
					        <clr-dg-cell (click)="goToReplaceStringhtmljson (user.htmljson)"
 | 
				
			||||||
          style="cursor: pointer; align-items: center;"><clr-icon shape="details"></clr-icon>
 | 
					          style="cursor: pointer; align-items: center;"><clr-icon shape="details"></clr-icon>
 | 
				
			||||||
@ -128,8 +133,8 @@
 | 
				
			|||||||
              </clr-signpost-content>
 | 
					              </clr-signpost-content>
 | 
				
			||||||
            </clr-signpost>
 | 
					            </clr-signpost>
 | 
				
			||||||
            <!-- View HTML Button -->
 | 
					            <!-- View HTML Button -->
 | 
				
			||||||
            <button class="btn btn-sm btn-outline" (click)="openHtmlPreview(user.id)">
 | 
					            <button class="btn btn-sm btn-outline" (click)="openHtmlPreview(user.id)" title="Open Preview in New Page">
 | 
				
			||||||
              <clr-icon shape="eye"></clr-icon>
 | 
					              <clr-icon shape="eye"></clr-icon> Preview
 | 
				
			||||||
            </button>
 | 
					            </button>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </clr-dg-cell>
 | 
					        </clr-dg-cell>
 | 
				
			||||||
@ -359,6 +364,10 @@
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <div class="clr-col-sm-12">
 | 
				
			||||||
 | 
					          <label> Html</label>
 | 
				
			||||||
 | 
					          <textarea cols="10" rows="2" [(ngModel)]="rowSelected.html" name="html " placeholder="Textarea">  </textarea>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
        <div class="clr-col-sm-12">
 | 
					        <div class="clr-col-sm-12">
 | 
				
			||||||
          <label> Json</label>
 | 
					          <label> Json</label>
 | 
				
			||||||
          <textarea cols="10" rows="2" [(ngModel)]="rowSelected.htmljson" name="htmljson "
 | 
					          <textarea cols="10" rows="2" [(ngModel)]="rowSelected.htmljson" name="htmljson "
 | 
				
			||||||
@ -482,6 +491,10 @@
 | 
				
			|||||||
          <input type="checkbox" formControlName="active" clrToggle />
 | 
					          <input type="checkbox" formControlName="active" clrToggle />
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <div class="clr-col-sm-12">
 | 
				
			||||||
 | 
					          <label> Html</label>
 | 
				
			||||||
 | 
					          <textarea cols="15" rows="3" formControlName="html" placeholder="Textarea">  </textarea>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
        <div class="clr-col-sm-12">
 | 
					        <div class="clr-col-sm-12">
 | 
				
			||||||
          <label> Json</label>
 | 
					          <label> Json</label>
 | 
				
			||||||
          <textarea cols="15" rows="3" formControlName="htmljson" placeholder="Textarea">  </textarea>
 | 
					          <textarea cols="15" rows="3" formControlName="htmljson" placeholder="Textarea">  </textarea>
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,8 @@ import { Design_lbrarycardvariable } from './Design_lbrary_cardvariable';
 | 
				
			|||||||
import { UserInfoService } from 'src/app/services/user-info.service';
 | 
					import { UserInfoService } from 'src/app/services/user-info.service';
 | 
				
			||||||
import { SiteTreeservice } from '../SiteBuilderGrid/SiteTree.service';
 | 
					import { SiteTreeservice } from '../SiteBuilderGrid/SiteTree.service';
 | 
				
			||||||
import { COMMON_CSS } from '../WireframesUi/common-css';
 | 
					import { COMMON_CSS } from '../WireframesUi/common-css';
 | 
				
			||||||
 | 
					import { Download_Css } from '../WireframesUi/download-css';
 | 
				
			||||||
 | 
					// import { Download_Css } from '../WireframesUi/download-css';
 | 
				
			||||||
declare var JsBarcode: any;
 | 
					declare var JsBarcode: any;
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
  selector: 'app-Design_lbrary',
 | 
					  selector: 'app-Design_lbrary',
 | 
				
			||||||
@ -79,11 +81,13 @@ export class Design_lbraryComponent implements OnInit {
 | 
				
			|||||||
      htmljson: [null],
 | 
					      htmljson: [null],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      css: [null],
 | 
					      css: [null],
 | 
				
			||||||
      templatetype:[null],
 | 
					      templatetype: [null],
 | 
				
			||||||
      uitype:[null],
 | 
					      uitype: [null],
 | 
				
			||||||
      javacode: [null],
 | 
					      javacode: [null],
 | 
				
			||||||
      typerender: [null],
 | 
					      typerender: [null],
 | 
				
			||||||
      techstack: [null],
 | 
					      techstack: [null],
 | 
				
			||||||
 | 
					      html: [null],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -352,12 +356,16 @@ export class Design_lbraryComponent implements OnInit {
 | 
				
			|||||||
  //     this.modalHtmlPreview = true;
 | 
					  //     this.modalHtmlPreview = true;
 | 
				
			||||||
  //   });
 | 
					  //   });
 | 
				
			||||||
  // }
 | 
					  // }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  openHtmlPreview(id: number): void {
 | 
					  openHtmlPreview(id: number): void {
 | 
				
			||||||
    console.log('preview html start..');
 | 
					    console.log('preview html start..');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.siteTreeService.generateHtmlwithcss(id).subscribe((response: any) => {
 | 
					    this.siteTreeService.generateHtmlwithcss(id).subscribe((response: any) => {
 | 
				
			||||||
      const bodyContent = response.msg || '<div>Empty</div>'; // fallback
 | 
					      const bodyContent = response.msg || '<div>Empty</div>'; // fallback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Store raw content for download/copy
 | 
				
			||||||
 | 
					      const rawHtmlContent = bodyContent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Full HTML with styles and controls
 | 
				
			||||||
      const fullHtml = `
 | 
					      const fullHtml = `
 | 
				
			||||||
        <!DOCTYPE html>
 | 
					        <!DOCTYPE html>
 | 
				
			||||||
        <html lang="en">
 | 
					        <html lang="en">
 | 
				
			||||||
@ -366,38 +374,204 @@ export class Design_lbraryComponent implements OnInit {
 | 
				
			|||||||
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
					          <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
				
			||||||
          <title>HTML Preview</title>
 | 
					          <title>HTML Preview</title>
 | 
				
			||||||
          <style>
 | 
					          <style>
 | 
				
			||||||
            ${COMMON_CSS}
 | 
					        ${Download_Css}
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /* Additional styles for controls */
 | 
				
			||||||
 | 
					        .preview-controls {
 | 
				
			||||||
 | 
					          position: fixed !important;
 | 
				
			||||||
 | 
					          top: 10px !important;
 | 
				
			||||||
 | 
					          right: 10px !important;
 | 
				
			||||||
 | 
					          background-color: rgba(255, 255, 255, 0.9) !important;
 | 
				
			||||||
 | 
					          border: 1px solid #ccc !important;
 | 
				
			||||||
 | 
					          border-radius: 4px !important;
 | 
				
			||||||
 | 
					          padding: 10px;
 | 
				
			||||||
 | 
					          box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2) !important;
 | 
				
			||||||
 | 
					          z-index: 1000 !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .preview-controls button {
 | 
				
			||||||
 | 
					          margin: 5px !important;
 | 
				
			||||||
 | 
					          padding: 8px 12px !important;
 | 
				
			||||||
 | 
					          background-color: #0072a3 !important;
 | 
				
			||||||
 | 
					          color: white !important;
 | 
				
			||||||
 | 
					          border: none !important;
 | 
				
			||||||
 | 
					          border-radius: 3px !important; 
 | 
				
			||||||
 | 
					          cursor: pointer !important;
 | 
				
			||||||
 | 
					          font-size: 14px !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .preview-controls button:hover {
 | 
				
			||||||
 | 
					          background-color: #005a80 !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .toast {
 | 
				
			||||||
 | 
					          position: fixed !important;
 | 
				
			||||||
 | 
					          top: 70px !important;
 | 
				
			||||||
 | 
					          right: 10px !important;
 | 
				
			||||||
 | 
					          padding: 10px 20px !important;
 | 
				
			||||||
 | 
					          background-color: #4CAF50 !important;
 | 
				
			||||||
 | 
					          color: white !important;
 | 
				
			||||||
 | 
					          border-radius: 4px !important;
 | 
				
			||||||
 | 
					          box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2) !important;
 | 
				
			||||||
 | 
					          opacity: 0 !important;
 | 
				
			||||||
 | 
					          transition: opacity 0.3s !important;
 | 
				
			||||||
 | 
					          z-index: 1001 !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .toast.show {
 | 
				
			||||||
 | 
					          opacity: 1 !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .html-source {
 | 
				
			||||||
 | 
					          display: none !important;
 | 
				
			||||||
 | 
					          margin-top: 20px !important;
 | 
				
			||||||
 | 
					          width: 100% !important;
 | 
				
			||||||
 | 
					          height: 300px !important;
 | 
				
			||||||
 | 
					          font-family: monospace !important;
 | 
				
			||||||
 | 
					          resize: vertical !important;
 | 
				
			||||||
 | 
					          white-space: pre !important;
 | 
				
			||||||
 | 
					          overflow: auto !important;
 | 
				
			||||||
 | 
					          background-color: #f5f5f5 !important;
 | 
				
			||||||
 | 
					          border: 1px solid #ddd !important;
 | 
				
			||||||
 | 
					          padding: 10px !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .show-source {
 | 
				
			||||||
 | 
					          display: block !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
          </style>
 | 
					          </style>
 | 
				
			||||||
        </head>
 | 
					        </head>
 | 
				
			||||||
        <body>
 | 
					        <body>
 | 
				
			||||||
 | 
					          <div class="preview-controls">
 | 
				
			||||||
 | 
					        <button id="download-btn">Download HTML</button>
 | 
				
			||||||
 | 
					        <button id="copy-btn">Copy to Clipboard</button>
 | 
				
			||||||
 | 
					        <button id="toggle-source-btn">View Source</button>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          <div id="toast" class="toast">Copied to clipboard!</div>
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          <div id="content-preview">
 | 
				
			||||||
        ${bodyContent}
 | 
					        ${bodyContent}
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          <pre id="html-source" class="html-source"></pre>
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          <script>
 | 
				
			||||||
 | 
					        // Format HTML for display in the source view
 | 
				
			||||||
 | 
					        function formatHtml(html) {
 | 
				
			||||||
 | 
					          return html.replace(/&/g, '&')
 | 
				
			||||||
 | 
					             .replace(/</g, '<')
 | 
				
			||||||
 | 
					             .replace(/>/g, '>');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // Store the raw HTML content
 | 
				
			||||||
 | 
					        const rawHtml = \`${rawHtmlContent.replace(/`/g, '\\`')}\`;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // Download functionality with full HTML and CSS
 | 
				
			||||||
 | 
					        document.getElementById('download-btn').addEventListener('click', function() {
 | 
				
			||||||
 | 
					          const fullHtmlContent = \`
 | 
				
			||||||
 | 
					            <!DOCTYPE html>
 | 
				
			||||||
 | 
					            <html lang="en">
 | 
				
			||||||
 | 
					            <head>
 | 
				
			||||||
 | 
					          <meta charset="UTF-8">
 | 
				
			||||||
 | 
					          <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
				
			||||||
 | 
					          <title>Downloaded HTML</title>
 | 
				
			||||||
 | 
					          <style>
 | 
				
			||||||
 | 
					            ${Download_Css}
 | 
				
			||||||
 | 
					          </style>
 | 
				
			||||||
 | 
					            </head>
 | 
				
			||||||
 | 
					            <body>
 | 
				
			||||||
 | 
					          \${rawHtml}
 | 
				
			||||||
 | 
					            </body>
 | 
				
			||||||
 | 
					            </html>
 | 
				
			||||||
 | 
					          \`;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					          const blob = new Blob([fullHtmlContent], { type: 'text/html' });
 | 
				
			||||||
 | 
					          const url = URL.createObjectURL(blob);
 | 
				
			||||||
 | 
					          const a = document.createElement('a');
 | 
				
			||||||
 | 
					          a.href = url;
 | 
				
			||||||
 | 
					          a.download = 'preview-' + new Date().toISOString().slice(0, 10) + '.html';
 | 
				
			||||||
 | 
					          document.body.appendChild(a);
 | 
				
			||||||
 | 
					          a.click();
 | 
				
			||||||
 | 
					          document.body.removeChild(a);
 | 
				
			||||||
 | 
					          URL.revokeObjectURL(url);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // Copy to clipboard functionality
 | 
				
			||||||
 | 
					        document.getElementById('copy-btn').addEventListener('click', function() {
 | 
				
			||||||
 | 
					          navigator.clipboard.writeText(rawHtml).then(function() {
 | 
				
			||||||
 | 
					            const toast = document.getElementById('toast');
 | 
				
			||||||
 | 
					            toast.textContent = 'Copied to clipboard!';
 | 
				
			||||||
 | 
					            toast.classList.add('show');
 | 
				
			||||||
 | 
					            setTimeout(function() {
 | 
				
			||||||
 | 
					          toast.classList.remove('show');
 | 
				
			||||||
 | 
					            }, 2000);
 | 
				
			||||||
 | 
					          }).catch(function(err) {
 | 
				
			||||||
 | 
					            console.error('Could not copy text: ', err);
 | 
				
			||||||
 | 
					            const toast = document.getElementById('toast');
 | 
				
			||||||
 | 
					            toast.textContent = 'Failed to copy to clipboard';
 | 
				
			||||||
 | 
					            toast.style.backgroundColor = '#f44336';
 | 
				
			||||||
 | 
					            toast.classList.add('show');
 | 
				
			||||||
 | 
					            setTimeout(function() {
 | 
				
			||||||
 | 
					          toast.classList.remove('show');
 | 
				
			||||||
 | 
					            }, 2000);
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // Toggle source view
 | 
				
			||||||
 | 
					        document.getElementById('toggle-source-btn').addEventListener('click', function() {
 | 
				
			||||||
 | 
					          const sourceElem = document.getElementById('html-source');
 | 
				
			||||||
 | 
					          if (!sourceElem.classList.contains('show-source')) {
 | 
				
			||||||
 | 
					            sourceElem.textContent = rawHtml;
 | 
				
			||||||
 | 
					            sourceElem.innerHTML = formatHtml(rawHtml);
 | 
				
			||||||
 | 
					            sourceElem.classList.add('show-source');
 | 
				
			||||||
 | 
					            this.textContent = 'Hide Source';
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            sourceElem.classList.remove('show-source');
 | 
				
			||||||
 | 
					            this.textContent = 'View Source';
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					          </script>
 | 
				
			||||||
        </body>
 | 
					        </body>
 | 
				
			||||||
        </html>
 | 
					        </html>
 | 
				
			||||||
      `;
 | 
					      `;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      this.htmlContent = fullHtml;
 | 
					      // Open the HTML in a new window/tab
 | 
				
			||||||
      console.log('html code ..', this.htmlContent);
 | 
					      const newWindow = window.open('', '_blank');
 | 
				
			||||||
      this.modalHtmlPreview = true;
 | 
					      if (newWindow) {
 | 
				
			||||||
 | 
					        newWindow.document.write(fullHtml);
 | 
				
			||||||
 | 
					        newWindow.document.close();
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        // If popup is blocked, inform the user
 | 
				
			||||||
 | 
					        this.toastr.warning('Pop-up blocked. Please allow pop-ups for this site to see the preview.');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }, error => {
 | 
					    }, error => {
 | 
				
			||||||
      this.htmlContent = `
 | 
					      // Handle error by opening a new window with error message
 | 
				
			||||||
 | 
					      const errorHtml = `
 | 
				
			||||||
        <!DOCTYPE html>
 | 
					        <!DOCTYPE html>
 | 
				
			||||||
        <html><head><style>${COMMON_CSS}</style></head>
 | 
					        <html>
 | 
				
			||||||
        <body><p style="color:red;">Error loading HTML.</p></body></html>
 | 
					        <head>
 | 
				
			||||||
 | 
					          <meta charset="UTF-8">
 | 
				
			||||||
 | 
					          <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
				
			||||||
 | 
					          <title>Error Preview</title>
 | 
				
			||||||
 | 
					          <style>${COMMON_CSS}</style>
 | 
				
			||||||
 | 
					        </head>
 | 
				
			||||||
 | 
					        <body>
 | 
				
			||||||
 | 
					          <div style="padding: 20px; text-align: center;">
 | 
				
			||||||
 | 
					            <h2 style="color:red;">Error Loading Preview</h2>
 | 
				
			||||||
 | 
					            <p>The preview content could not be loaded. Error details:</p>
 | 
				
			||||||
 | 
					            <pre style="background-color: #f8f8f8; padding: 10px; border-radius: 5px; text-align: left;">${error ? JSON.stringify(error, null, 2) : 'Unknown error'}</pre>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </body>
 | 
				
			||||||
 | 
					        </html>
 | 
				
			||||||
      `;
 | 
					      `;
 | 
				
			||||||
      this.modalHtmlPreview = true;
 | 
					
 | 
				
			||||||
 | 
					      const newWindow = window.open('', '_blank');
 | 
				
			||||||
 | 
					      if (newWindow) {
 | 
				
			||||||
 | 
					        newWindow.document.write(errorHtml);
 | 
				
			||||||
 | 
					        newWindow.document.close();
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        this.toastr.error('Error loading preview. Pop-up blocked. Please allow pop-ups for this site.');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -64,7 +64,18 @@ export class SiteTreeservice {
 | 
				
			|||||||
    return this.apiRequest.post(`sureops/deploy?projId=` + projId, data);
 | 
					    return this.apiRequest.post(`sureops/deploy?projId=` + projId, data);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  createHtmlfile(siteNmae: String, data: any): Observable<any> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const _http = this.baseURL + "/createFile?siteBuilderName=" + siteNmae;
 | 
				
			||||||
 | 
					    return this.apiRequest.post(_http, data);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // updateaction
 | 
					  readPages(siteNmae: String, pageNmae: String): Observable<any> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const _http = this.baseURL + "/read?siteBuilderName=" + siteNmae + '&filename=' + pageNmae;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return this.apiRequest.get(_http, undefined, 'text');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // updateactionƒ
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -198,7 +198,15 @@
 | 
				
			|||||||
  margin-bottom: 8px;
 | 
					  margin-bottom: 8px;
 | 
				
			||||||
  color: #333;
 | 
					  color: #333;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					.offcanvas-backdrop {
 | 
				
			||||||
 | 
					  position: fixed;
 | 
				
			||||||
 | 
					  top: 0;
 | 
				
			||||||
 | 
					  left: 0;
 | 
				
			||||||
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					  height: 100%;
 | 
				
			||||||
 | 
					  background-color: rgba(0,0,0,0.3);
 | 
				
			||||||
 | 
					  z-index: 1040;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
.section-content {
 | 
					.section-content {
 | 
				
			||||||
  font-size: 13px;
 | 
					  font-size: 13px;
 | 
				
			||||||
  color: #555;
 | 
					  color: #555;
 | 
				
			||||||
@ -385,12 +393,15 @@
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.btn {
 | 
					.btn {
 | 
				
			||||||
  padding: 8px 15px;
 | 
					  padding: 10px 16px;
 | 
				
			||||||
  border-radius: 4px;
 | 
					  border-radius: 6px;
 | 
				
			||||||
  cursor: pointer;
 | 
					  cursor: pointer;
 | 
				
			||||||
  font-weight: 500;
 | 
					  font-weight: 500;
 | 
				
			||||||
  border: 1px solid transparent;
 | 
					  border: 1px solid transparent;
 | 
				
			||||||
  transition: all 0.2s ease;
 | 
					  transition: all 0.2s ease;
 | 
				
			||||||
 | 
					  display: inline-flex;
 | 
				
			||||||
 | 
					  align-items: center;
 | 
				
			||||||
 | 
					  justify-content: center;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.btn-primary {
 | 
					.btn-primary {
 | 
				
			||||||
@ -398,10 +409,19 @@
 | 
				
			|||||||
  color: white;
 | 
					  color: white;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.btn-primary:hover {
 | 
					.btn-primary:hover:not([disabled]) {
 | 
				
			||||||
  background-color: #0069d9;
 | 
					  background-color: #0069d9;
 | 
				
			||||||
 | 
					  transform: translateY(-1px);
 | 
				
			||||||
 | 
					  box-shadow: 0 2px 5px rgba(0,0,0,0.1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.btn-primary[disabled] {
 | 
				
			||||||
 | 
					  background-color: #7fb6ff;
 | 
				
			||||||
 | 
					  cursor: not-allowed;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.btn-secondary {
 | 
					.btn-secondary {
 | 
				
			||||||
  background-color: #6c757d;
 | 
					  background-color: #6c757d;
 | 
				
			||||||
  color: white;
 | 
					  color: white;
 | 
				
			||||||
@ -409,20 +429,70 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
.btn-secondary:hover {
 | 
					.btn-secondary:hover {
 | 
				
			||||||
  background-color: #5a6268;
 | 
					  background-color: #5a6268;
 | 
				
			||||||
 | 
					  transform: translateY(-1px);
 | 
				
			||||||
 | 
					  box-shadow: 0 2px 5px rgba(0,0,0,0.1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.form-actions {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  justify-content: flex-end;
 | 
				
			||||||
 | 
					  gap: 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.mt-3 {
 | 
				
			||||||
 | 
					  margin-top: 1rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.mt-4 {
 | 
				
			||||||
 | 
					  margin-top: 1.5rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@keyframes slideIn {
 | 
				
			||||||
 | 
					  from { right: -400px; }
 | 
				
			||||||
 | 
					  to { right: 0; }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@keyframes slideOut {
 | 
				
			||||||
 | 
					  from { right: 0; }
 | 
				
			||||||
 | 
					  to { right: -400px; }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.offcanvas.show {
 | 
				
			||||||
 | 
					  animation: slideIn 0.3s forwards;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.offcanvas:not(.show) {
 | 
				
			||||||
 | 
					  animation: slideOut 0.3s forwards;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.form-control {
 | 
					.form-control {
 | 
				
			||||||
  display: block;
 | 
					  border-radius: 6px;
 | 
				
			||||||
  width: 100%;
 | 
					 | 
				
			||||||
  padding: 0.375rem 0.75rem;
 | 
					 | 
				
			||||||
  font-size: 1rem;
 | 
					 | 
				
			||||||
  line-height: 1.5;
 | 
					 | 
				
			||||||
  color: #495057;
 | 
					 | 
				
			||||||
  background-color: #fff;
 | 
					 | 
				
			||||||
  background-clip: padding-box;
 | 
					 | 
				
			||||||
  border: 1px solid #ced4da;
 | 
					  border: 1px solid #ced4da;
 | 
				
			||||||
  border-radius: 0.25rem;
 | 
					  padding: 10px 12px;
 | 
				
			||||||
  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
 | 
					  transition: all 0.2s ease;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.form-control:focus {
 | 
				
			||||||
 | 
					  border-color: #80bdff;
 | 
				
			||||||
 | 
					  box-shadow: 0 0 0 0.2rem rgba(0,123,255,.25);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					textarea.form-control {
 | 
				
			||||||
 | 
					  min-height: 120px;
 | 
				
			||||||
 | 
					  resize: vertical;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.custom-section-form {
 | 
				
			||||||
 | 
					  margin-top: 30px;
 | 
				
			||||||
 | 
					  padding-top: 20px;
 | 
				
			||||||
 | 
					  border-top: 1px dashed #ddd;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.custom-section-form h4 {
 | 
				
			||||||
 | 
					  margin-bottom: 15px;
 | 
				
			||||||
 | 
					  color: #444;
 | 
				
			||||||
 | 
					  font-size: 16px;
 | 
				
			||||||
 | 
					  font-weight: 600;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.mb-3 {
 | 
					.mb-3 {
 | 
				
			||||||
@ -438,7 +508,7 @@
 | 
				
			|||||||
  background-color: white;
 | 
					  background-color: white;
 | 
				
			||||||
  box-shadow: -5px 0 15px rgba(0,0,0,0.1);
 | 
					  box-shadow: -5px 0 15px rgba(0,0,0,0.1);
 | 
				
			||||||
  z-index: 1050;
 | 
					  z-index: 1050;
 | 
				
			||||||
  transition: right 0.3s ease;
 | 
					  transition: all 0.3s cubic-bezier(0.25, 1, 0.5, 1);
 | 
				
			||||||
  overflow-y: auto;
 | 
					  overflow-y: auto;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -450,27 +520,47 @@
 | 
				
			|||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  align-items: center;
 | 
					  align-items: center;
 | 
				
			||||||
  justify-content: space-between;
 | 
					  justify-content: space-between;
 | 
				
			||||||
  padding: 15px 20px;
 | 
					  padding: 18px 20px;
 | 
				
			||||||
  border-bottom: 1px solid #ddd;
 | 
					  border-bottom: 1px solid #eaeaea;
 | 
				
			||||||
 | 
					  background-color: #f8f9fa;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.offcanvas-title {
 | 
					.offcanvas-title {
 | 
				
			||||||
  font-size: 18px;
 | 
					  font-size: 18px;
 | 
				
			||||||
  font-weight: 600;
 | 
					  font-weight: 600;
 | 
				
			||||||
 | 
					  color: #333;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.close-btn {
 | 
					.close-btn {
 | 
				
			||||||
  background: none;
 | 
					  background: none;
 | 
				
			||||||
  border: none;
 | 
					  border: none;
 | 
				
			||||||
  font-size: 24px;
 | 
					 | 
				
			||||||
  cursor: pointer;
 | 
					  cursor: pointer;
 | 
				
			||||||
  color: #666;
 | 
					  color: #666;
 | 
				
			||||||
 | 
					  width: 32px;
 | 
				
			||||||
 | 
					  height: 32px;
 | 
				
			||||||
 | 
					  border-radius: 50%;
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  align-items: center;
 | 
				
			||||||
 | 
					  justify-content: center;
 | 
				
			||||||
 | 
					  transition: all 0.2s ease;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.close-btn:hover {
 | 
				
			||||||
 | 
					  background-color: #f1f1f1;
 | 
				
			||||||
 | 
					  color: #333;
 | 
				
			||||||
 | 
					  transform: rotate(90deg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.offcanvas-body {
 | 
					.offcanvas-body {
 | 
				
			||||||
  padding: 20px;
 | 
					  padding: 20px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.section-templates-container {
 | 
				
			||||||
 | 
					  max-height: 50vh;
 | 
				
			||||||
 | 
					  overflow-y: auto;
 | 
				
			||||||
 | 
					  padding-right: 5px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.section-template {
 | 
					.section-template {
 | 
				
			||||||
  padding: 15px;
 | 
					  padding: 15px;
 | 
				
			||||||
  border: 1px solid #ddd;
 | 
					  border: 1px solid #ddd;
 | 
				
			||||||
@ -478,11 +568,30 @@
 | 
				
			|||||||
  margin-bottom: 15px;
 | 
					  margin-bottom: 15px;
 | 
				
			||||||
  cursor: pointer;
 | 
					  cursor: pointer;
 | 
				
			||||||
  transition: all 0.2s ease;
 | 
					  transition: all 0.2s ease;
 | 
				
			||||||
 | 
					  position: relative;
 | 
				
			||||||
 | 
					  overflow: hidden;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.section-template:before {
 | 
				
			||||||
 | 
					  content: '';
 | 
				
			||||||
 | 
					  position: absolute;
 | 
				
			||||||
 | 
					  top: 0;
 | 
				
			||||||
 | 
					  left: 0;
 | 
				
			||||||
 | 
					  width: 4px;
 | 
				
			||||||
 | 
					  height: 0;
 | 
				
			||||||
 | 
					  background-color: #007bff;
 | 
				
			||||||
 | 
					  transition: height 0.3s ease;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.section-template:hover {
 | 
					.section-template:hover {
 | 
				
			||||||
  background-color: #f8f9fa;
 | 
					  background-color: #f8f9fa;
 | 
				
			||||||
  border-color: #007bff;
 | 
					  border-color: #007bff;
 | 
				
			||||||
 | 
					  transform: translateY(-2px);
 | 
				
			||||||
 | 
					  box-shadow: 0 4px 8px rgba(0,0,0,0.05);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.section-template:hover:before {
 | 
				
			||||||
 | 
					  height: 100%;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.section-template-title {
 | 
					.section-template-title {
 | 
				
			||||||
 | 
				
			|||||||
@ -47,31 +47,40 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
  <div class="editor-form" *ngIf="editMode">
 | 
					  <!-- <div class="editor-form" *ngIf="editMode">
 | 
				
			||||||
    <div *ngIf="editMode === 'section' && selectedSection && selectedPage">
 | 
					    <div *ngIf="editMode === 'section' && selectedSection && selectedPage">
 | 
				
			||||||
      <div class="editor-title">Edit Section: {{ selectedSection.type }}</div>
 | 
					      <div class="editor-title">Edit Section: {{ selectedSection.type }}</div>
 | 
				
			||||||
      <div class="form-group">
 | 
					      <div class="form-group">
 | 
				
			||||||
        <label class="form-label">Content</label>
 | 
					        <label class="form-label">Content</label>
 | 
				
			||||||
        <textarea class="form-textarea" [(ngModel)]="selectedSection.content"></textarea>
 | 
					        <textarea 
 | 
				
			||||||
 | 
					          class="form-textarea" 
 | 
				
			||||||
 | 
					          [(ngModel)]="selectedSection.content"></textarea>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div class="form-actions">
 | 
					      <div class="form-actions">
 | 
				
			||||||
        <button class="btn btn-secondary" (click)="cancelEdit()">Cancel</button>
 | 
					        <button class="btn btn-secondary" (click)="cancelEdit()">Cancel</button>
 | 
				
			||||||
        <button class="btn btn-primary" (click)="saveEdit()">Save Changes</button>
 | 
					        <button class="btn btn-primary" (click)="saveEdit()">Save Changes</button>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div> -->
 | 
				
			||||||
  <div class="offcanvas" [class.show]="showOffcanvas">
 | 
					  <!-- Replace your current offcanvas with these two separate ones -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <!-- Add Section Offcanvas -->
 | 
				
			||||||
 | 
					  <div class="offcanvas add-section" [class.show]="showAddSectionOffcanvas">
 | 
				
			||||||
    <div class="offcanvas-header">
 | 
					    <div class="offcanvas-header">
 | 
				
			||||||
      <div class="offcanvas-title">Add Section</div>
 | 
					      <div class="offcanvas-title">Add Section</div>
 | 
				
			||||||
      <button class="close-btn" (click)="closeOffcanvas()">×</button>
 | 
					      <button class="close-btn" (click)="closeAddSectionOffcanvas()">
 | 
				
			||||||
 | 
					        <i class="fas fa-times"></i>
 | 
				
			||||||
 | 
					      </button>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div class="offcanvas-body">
 | 
					    <div class="offcanvas-body">
 | 
				
			||||||
 | 
					      <div class="section-templates-container">
 | 
				
			||||||
        <div class="section-template" *ngFor="let template of sectionTemplates"
 | 
					        <div class="section-template" *ngFor="let template of sectionTemplates"
 | 
				
			||||||
          (click)="addSectionFromTemplate(template)">
 | 
					          (click)="addSectionFromTemplate(template)">
 | 
				
			||||||
          <div class="section-template-title">{{ template.type }}</div>
 | 
					          <div class="section-template-title">{{ template.type }}</div>
 | 
				
			||||||
          <div class="section-template-desc">{{ template.description }}</div>
 | 
					          <div class="section-template-desc">{{ template.description }}</div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      <div class="form-group" style="margin-top: 20px;">
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="custom-section-form">
 | 
				
			||||||
        <h4>Custom Section</h4>
 | 
					        <h4>Custom Section</h4>
 | 
				
			||||||
        <div class="mb-3">
 | 
					        <div class="mb-3">
 | 
				
			||||||
          <label class="form-label">Section Type</label>
 | 
					          <label class="form-label">Section Type</label>
 | 
				
			||||||
@ -88,6 +97,32 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <!-- Edit Section Offcanvas -->
 | 
				
			||||||
 | 
					  <div class="offcanvas edit-section" [class.show]="showEditSectionOffcanvas">
 | 
				
			||||||
 | 
					    <div class="offcanvas-header">
 | 
				
			||||||
 | 
					      <div class="offcanvas-title">Edit Section: {{ selectedSection?.type }}</div>
 | 
				
			||||||
 | 
					      <button class="close-btn" (click)="closeEditSectionOffcanvas()">
 | 
				
			||||||
 | 
					        <i class="fas fa-times"></i>
 | 
				
			||||||
 | 
					      </button>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="offcanvas-body">
 | 
				
			||||||
 | 
					      <div class="form-group">
 | 
				
			||||||
 | 
					        <label class="form-label">Section Type</label>
 | 
				
			||||||
 | 
					        <input type="text" class="form-control" [(ngModel)]="selectedSection.type" *ngIf="selectedSection"
 | 
				
			||||||
 | 
					          placeholder="Section type">
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="form-group mt-3">
 | 
				
			||||||
 | 
					        <label class="form-label">Content</label>
 | 
				
			||||||
 | 
					        <textarea class="form-control" [(ngModel)]="selectedSection && selectedSection.content" rows="8"
 | 
				
			||||||
 | 
					          placeholder="Enter content"></textarea>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="form-actions mt-4">
 | 
				
			||||||
 | 
					        <button class="btn btn-secondary" (click)="closeEditSectionOffcanvas()">Cancel</button>
 | 
				
			||||||
 | 
					        <button class="btn btn-primary" (click)="saveSection()">Save Changes</button>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
  <div class="modal" [class.show]="showAddChildModal">
 | 
					  <div class="modal" [class.show]="showAddChildModal">
 | 
				
			||||||
    <div class="modal-backdrop" *ngIf="showAddChildModal" (click)="closeAddChildModal()"></div>
 | 
					    <div class="modal-backdrop" *ngIf="showAddChildModal" (click)="closeAddChildModal()"></div>
 | 
				
			||||||
    <div class="modal-dialog" *ngIf="showAddChildModal">
 | 
					    <div class="modal-dialog" *ngIf="showAddChildModal">
 | 
				
			||||||
@ -123,11 +158,13 @@
 | 
				
			|||||||
          <i class="node-icon" [class]="getNodeIcon(page)"></i>
 | 
					          <i class="node-icon" [class]="getNodeIcon(page)"></i>
 | 
				
			||||||
          <span class="node-title">{{ page.name }}</span>
 | 
					          <span class="node-title">{{ page.name }}</span>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="sections-container" cdkDropList [cdkDropListData]="page.sections">
 | 
					        <div class="sections-container" cdkDropList [cdkDropListData]="page.sections"
 | 
				
			||||||
 | 
					          (cdkDropListDropped)="onSectionDrop($event)">
 | 
				
			||||||
          <!-- Update the section card template within the #pageTemplate -->
 | 
					          <!-- Update the section card template within the #pageTemplate -->
 | 
				
			||||||
          <!-- Section card with improved hover button placement -->
 | 
					          <!-- Section card with improved hover button placement -->
 | 
				
			||||||
          <div class="section-card" *ngFor="let section of page.sections; let i = index" cdkDrag
 | 
					          <div class="section-card" *ngFor="let section of page.sections; let i = index" cdkDrag [cdkDragData]="section"
 | 
				
			||||||
            (click)="selectSection(section); $event.stopPropagation()">
 | 
					            (click)="selectSection(section); $event.stopPropagation()">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <div class="section-title">{{ section.type }}</div>
 | 
					            <div class="section-title">{{ section.type }}</div>
 | 
				
			||||||
            <div class="section-content" [innerHTML]="getSectionContentHtml(section.content)"></div>
 | 
					            <div class="section-content" [innerHTML]="getSectionContentHtml(section.content)"></div>
 | 
				
			||||||
            <div class="section-actions">
 | 
					            <div class="section-actions">
 | 
				
			||||||
@ -139,7 +176,7 @@
 | 
				
			|||||||
              </button>
 | 
					              </button>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <!-- Repositioned add button that appears on hover -->
 | 
					            <!-- Repositioned add button that appears on hover -->
 | 
				
			||||||
            <div class="add-section-hover-btn" (click)="openSectionOffcanvas(page, i, $event)" title="Add Section">
 | 
					            <div class="add-section-hover-btn" (click)="openAddSectionOffcanvas(page, i, $event)" title="Add Section">
 | 
				
			||||||
              <i class="fas fa-plus"></i>
 | 
					              <i class="fas fa-plus"></i>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -73,6 +73,11 @@ export class TreeNodeComponent implements OnInit, OnDestroy, AfterViewInit {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  currentSectionIndex: number = -1;
 | 
					  currentSectionIndex: number = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //off canvas 
 | 
				
			||||||
 | 
					  showAddSectionOffcanvas = false;
 | 
				
			||||||
 | 
					  showEditSectionOffcanvas = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Section templates with better descriptions
 | 
					  // Section templates with better descriptions
 | 
				
			||||||
  sectionTemplates = [
 | 
					  sectionTemplates = [
 | 
				
			||||||
@ -131,8 +136,7 @@ export class TreeNodeComponent implements OnInit, OnDestroy, AfterViewInit {
 | 
				
			|||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    private siteTreeService: SiteTreeservice,
 | 
					    private siteTreeService: SiteTreeservice,
 | 
				
			||||||
    private route: ActivatedRoute,
 | 
					    private route: ActivatedRoute,
 | 
				
			||||||
    private toastr: ToastrService
 | 
					    private toastr: ToastrService,
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ) { }
 | 
					  ) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -157,6 +161,9 @@ export class TreeNodeComponent implements OnInit, OnDestroy, AfterViewInit {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnDestroy(): void {
 | 
					  ngOnDestroy(): void {
 | 
				
			||||||
 | 
					    // Remove event listener if component is destroyed while offcanvas is open
 | 
				
			||||||
 | 
					    document.removeEventListener('click', this.handleOutsideClick);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Auto-save changes before component destruction
 | 
					    // Auto-save changes before component destruction
 | 
				
			||||||
    if (this.hasUnsavedChanges) {
 | 
					    if (this.hasUnsavedChanges) {
 | 
				
			||||||
      this.saveTreeData(true);
 | 
					      this.saveTreeData(true);
 | 
				
			||||||
@ -622,6 +629,80 @@ export class TreeNodeComponent implements OnInit, OnDestroy, AfterViewInit {
 | 
				
			|||||||
    this.currentSectionIndex = -1;
 | 
					    this.currentSectionIndex = -1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  openAddSectionOffcanvas(page: Page, sectionIndex: number = -1, event?: Event): void {
 | 
				
			||||||
 | 
					    if (event) {
 | 
				
			||||||
 | 
					      event.stopPropagation();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    this.currentParentPage = page;
 | 
				
			||||||
 | 
					    this.currentSectionIndex = sectionIndex;
 | 
				
			||||||
 | 
					    this.customSectionType = '';
 | 
				
			||||||
 | 
					    this.customSectionContent = '';
 | 
				
			||||||
 | 
					    this.showAddSectionOffcanvas = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Listen for clicks outside offcanvas
 | 
				
			||||||
 | 
					    setTimeout(() => {
 | 
				
			||||||
 | 
					      document.addEventListener('click', this.handleOutsideClick);
 | 
				
			||||||
 | 
					    }, 10);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Open edit section offcanvas
 | 
				
			||||||
 | 
					  openEditSectionOffcanvas(section: Section, page: Page, event: Event): void {
 | 
				
			||||||
 | 
					    event.stopPropagation();
 | 
				
			||||||
 | 
					    this.selectedSection = { ...section }; // Clone to avoid direct mutation until save
 | 
				
			||||||
 | 
					    this.currentParentPage = page;
 | 
				
			||||||
 | 
					    this.editMode = 'section';
 | 
				
			||||||
 | 
					    this.showEditSectionOffcanvas = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Listen for clicks outside offcanvas
 | 
				
			||||||
 | 
					    setTimeout(() => {
 | 
				
			||||||
 | 
					      document.addEventListener('click', this.handleOutsideClick);
 | 
				
			||||||
 | 
					    }, 10);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  handleOutsideClick = (event: MouseEvent): void => {
 | 
				
			||||||
 | 
					    const addOffcanvas = document.querySelector('.offcanvas.add-section');
 | 
				
			||||||
 | 
					    const editOffcanvas = document.querySelector('.offcanvas.edit-section');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (addOffcanvas && !addOffcanvas.contains(event.target as Node) && this.showAddSectionOffcanvas) {
 | 
				
			||||||
 | 
					      this.closeAddSectionOffcanvas();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (editOffcanvas && !editOffcanvas.contains(event.target as Node) && this.showEditSectionOffcanvas) {
 | 
				
			||||||
 | 
					      this.closeEditSectionOffcanvas();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  closeAddSectionOffcanvas(): void {
 | 
				
			||||||
 | 
					    this.showAddSectionOffcanvas = false;
 | 
				
			||||||
 | 
					    this.currentParentPage = null;
 | 
				
			||||||
 | 
					    this.currentSectionIndex = -1;
 | 
				
			||||||
 | 
					    document.removeEventListener('click', this.handleOutsideClick);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Close edit section offcanvas
 | 
				
			||||||
 | 
					  closeEditSectionOffcanvas(): void {
 | 
				
			||||||
 | 
					    this.showEditSectionOffcanvas = false;
 | 
				
			||||||
 | 
					    this.selectedSection = null;
 | 
				
			||||||
 | 
					    this.editMode = null;
 | 
				
			||||||
 | 
					    document.removeEventListener('click', this.handleOutsideClick);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Save section changes
 | 
				
			||||||
 | 
					  saveSection(): void {
 | 
				
			||||||
 | 
					    if (this.selectedSection && this.currentParentPage) {
 | 
				
			||||||
 | 
					      // Find the section in the parent page
 | 
				
			||||||
 | 
					      const index = this.currentParentPage.sections.findIndex(s =>
 | 
				
			||||||
 | 
					        s.type === this.selectedSection.type && s.content === this.selectedSection.content);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (index !== -1) {
 | 
				
			||||||
 | 
					        // Update the section with edited values
 | 
				
			||||||
 | 
					        this.currentParentPage.sections[index] = { ...this.selectedSection };
 | 
				
			||||||
 | 
					        this.hasUnsavedChanges = true;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    this.closeEditSectionOffcanvas();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Add section from a template
 | 
					  // Add section from a template
 | 
				
			||||||
  addSectionFromTemplate(template: any): void {
 | 
					  addSectionFromTemplate(template: any): void {
 | 
				
			||||||
    if (this.currentParentPage) {
 | 
					    if (this.currentParentPage) {
 | 
				
			||||||
@ -651,6 +732,12 @@ export class TreeNodeComponent implements OnInit, OnDestroy, AfterViewInit {
 | 
				
			|||||||
  // Similar update for addCustomSection
 | 
					  // Similar update for addCustomSection
 | 
				
			||||||
  addCustomSection(): void {
 | 
					  addCustomSection(): void {
 | 
				
			||||||
    if (this.currentParentPage && this.customSectionType) {
 | 
					    if (this.currentParentPage && this.customSectionType) {
 | 
				
			||||||
 | 
					      // If in edit mode, update the selected section
 | 
				
			||||||
 | 
					      if (this.editMode === 'section' && this.selectedSection) {
 | 
				
			||||||
 | 
					        this.selectedSection.type = this.customSectionType;
 | 
				
			||||||
 | 
					        this.selectedSection.content = this.customSectionContent || '';
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        // Otherwise, create a new section
 | 
				
			||||||
        const newSection: Section = {
 | 
					        const newSection: Section = {
 | 
				
			||||||
          type: this.customSectionType,
 | 
					          type: this.customSectionType,
 | 
				
			||||||
          content: this.customSectionContent || ''
 | 
					          content: this.customSectionContent || ''
 | 
				
			||||||
@ -662,9 +749,6 @@ export class TreeNodeComponent implements OnInit, OnDestroy, AfterViewInit {
 | 
				
			|||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          this.currentParentPage.sections.push(newSection);
 | 
					          this.currentParentPage.sections.push(newSection);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (!this.availableSectionTypes.includes(this.customSectionType)) {
 | 
					 | 
				
			||||||
        this.availableSectionTypes.push(this.customSectionType);
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      this.hasUnsavedChanges = true;
 | 
					      this.hasUnsavedChanges = true;
 | 
				
			||||||
@ -673,10 +757,10 @@ export class TreeNodeComponent implements OnInit, OnDestroy, AfterViewInit {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Edit section
 | 
					  // Edit section
 | 
				
			||||||
 | 
					  // Edit section - modify this function
 | 
				
			||||||
  editSection(section: Section, event: Event): void {
 | 
					  editSection(section: Section, event: Event): void {
 | 
				
			||||||
    event.stopPropagation();
 | 
					    event.stopPropagation();
 | 
				
			||||||
    this.selectedSection = section;
 | 
					    this.openEditSectionOffcanvas(section, this.selectedPage, event);
 | 
				
			||||||
    this.editMode = 'section';
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Cancel edit
 | 
					  // Cancel edit
 | 
				
			||||||
@ -762,6 +846,8 @@ export class TreeNodeComponent implements OnInit, OnDestroy, AfterViewInit {
 | 
				
			|||||||
      );
 | 
					      );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Force change detection
 | 
				
			||||||
 | 
					    this.selectedPage = { ...this.selectedPage! };
 | 
				
			||||||
    this.hasUnsavedChanges = true;
 | 
					    this.hasUnsavedChanges = true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -795,7 +881,7 @@ export class TreeNodeComponent implements OnInit, OnDestroy, AfterViewInit {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
          if (!silent) {
 | 
					          if (!silent) {
 | 
				
			||||||
            // alert('Site structure saved successfully');
 | 
					            // alert('Site structure saved successfully');
 | 
				
			||||||
            this.toastr.success("Site structure saved successfully");
 | 
					            this.toastr.success(`Site structure saved successfully`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
@ -804,9 +890,7 @@ export class TreeNodeComponent implements OnInit, OnDestroy, AfterViewInit {
 | 
				
			|||||||
          console.error('Error saving data:', err);
 | 
					          console.error('Error saving data:', err);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          if (!silent) {
 | 
					          if (!silent) {
 | 
				
			||||||
            // alert('Failed to save site structure');
 | 
					            alert('Failed to save site structure');
 | 
				
			||||||
            this.toastr.error("Failed to save site structure");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
 | 
				
			|||||||
										
											Binary file not shown.
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					export const Download_Css = `
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					body {
 | 
				
			||||||
 | 
					  margin: 0;
 | 
				
			||||||
 | 
					  padding: 0;
 | 
				
			||||||
 | 
					  font-family: sans-serif;
 | 
				
			||||||
 | 
					  background-color: #fff;
 | 
				
			||||||
 | 
					  color: #111;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -77,119 +77,287 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div> -->
 | 
					    </div> -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <!-- ✅ Render whole page in one block -->
 | 
					<!-- ✅ Render whole page in one block -->
 | 
				
			||||||
    <!-- <div class="canvas-section">
 | 
					<!-- <div class="canvas-section">
 | 
				
			||||||
      <div [innerHTML]="pageSections[pageName]['FullPage']"></div>
 | 
					      <div [innerHTML]="pageSections[pageName]['FullPage']"></div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</div> -->
 | 
					</div> -->
 | 
				
			||||||
 | 
					<!-- Controls and Actions Row -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!-- part 3 -->
 | 
					<!-- Editable HTML Area -->
 | 
				
			||||||
<!-- 🔁 Regenerate + Save Buttons -->
 | 
					<!-- <div class="editable-area" *ngIf="editMode">
 | 
				
			||||||
<div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
 | 
					  <div class="editable-header">
 | 
				
			||||||
  <div>
 | 
					    <h3>Editing: {{ editingSection?.page }} > {{ editingSection?.section }}</h3>
 | 
				
			||||||
    <button (click)="regenerateAllModifiedSections()" style="background: orange; color: white; border: none; padding: 8px 14px; border-radius: 4px; cursor: pointer;">
 | 
					    <button class="close-btn" (click)="closeEditMode()">×</button>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  <div class="editable-content">
 | 
				
			||||||
 | 
					    <div 
 | 
				
			||||||
 | 
					      [innerHTML]="editingSectionHtml" 
 | 
				
			||||||
 | 
					      contenteditable="true" 
 | 
				
			||||||
 | 
					      class="editable-html" 
 | 
				
			||||||
 | 
					      (blur)="onSectionEdit($event)">
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  <div class="editable-footer">
 | 
				
			||||||
 | 
					    <button class="action-btn save-edit-btn" (click)="saveSectionEdit()">
 | 
				
			||||||
 | 
					      Save Changes
 | 
				
			||||||
 | 
					    </button>
 | 
				
			||||||
 | 
					    <button class="action-btn cancel-edit-btn" (click)="closeEditMode()">
 | 
				
			||||||
 | 
					      Cancel
 | 
				
			||||||
 | 
					    </button>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</div> -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="action-bar">
 | 
				
			||||||
 | 
					  <div class="left-controls">
 | 
				
			||||||
 | 
					    <button (click)="regenerateAllModifiedSections()" class="action-btn regenerate-btn">
 | 
				
			||||||
      ♻️ Regenerate Modified
 | 
					      ♻️ Regenerate Modified
 | 
				
			||||||
    </button>
 | 
					    </button>
 | 
				
			||||||
    <button (click)="uploadHtmlFiles(37388)" style="background: green; color: white; border: none; padding: 8px 14px; border-radius: 4px; cursor: pointer;">
 | 
					    <!-- <button (click)="uploadHtmlFiles(11096)" class="action-btn save-btn"> -->
 | 
				
			||||||
 | 
					    <button (click)="createHtmlFiles()" class="action-btn save-btn">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      💾 Save All HTML Files
 | 
					      💾 Save All HTML Files
 | 
				
			||||||
    </button>
 | 
					    </button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <button (click)="uploadHtmlFiles(11096)" class="action-btn save-btn">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      💾 build wireframe
 | 
				
			||||||
 | 
					    </button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <button class="btn btn-primary" (click)="recreateWireframe()">🔄 Recreate Wireframe</button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div class="navbar-controls">
 | 
				
			||||||
 | 
					      <select [(ngModel)]="selectedNavbarPage" (change)="selectedNavbarPage && selectNavbar(selectedNavbarPage)">
 | 
				
			||||||
 | 
					        <option value="">Select Navbar Page</option>
 | 
				
			||||||
 | 
					        <option *ngFor="let page of objectKeys(pageSections)" [value]="page">{{ page }}</option>
 | 
				
			||||||
 | 
					      </select>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <!-- Navbar Editor Modal -->
 | 
				
			||||||
 | 
					  <div class="modal" *ngIf="selectedNavbarPage">
 | 
				
			||||||
 | 
					    <div class="modal-content">
 | 
				
			||||||
 | 
					      <div class="modal-header">
 | 
				
			||||||
 | 
					        <h3>Edit Navbar Links - {{ selectedNavbarPage }}</h3>
 | 
				
			||||||
 | 
					        <button class="close-btn" (click)="selectedNavbarPage = ''">×</button>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <div class="modal-body">
 | 
				
			||||||
 | 
					        <div class="link-editor" *ngFor="let link of navbarLinks[selectedNavbarPage]; let i = index">
 | 
				
			||||||
 | 
					          <input type="text" [(ngModel)]="link.label" placeholder="Link Label">
 | 
				
			||||||
 | 
					          <select [(ngModel)]="link.href">
 | 
				
			||||||
 | 
					            <option *ngFor="let page of availablePages" [value]="page.href">{{ page.label }}</option>
 | 
				
			||||||
 | 
					          </select>
 | 
				
			||||||
 | 
					          <button class="remove-btn" (click)="removeLink(selectedNavbarPage, i)">×</button>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <button class="action-btn add-link-btn" (click)="addLink(selectedNavbarPage)">
 | 
				
			||||||
 | 
					          ➕ Add New Link
 | 
				
			||||||
 | 
					        </button>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <div>
 | 
					      <div class="modal-footer">
 | 
				
			||||||
    <!-- Global Style Controls -->
 | 
					        <button class="action-btn" (click)="applyNavbarChanges(selectedNavbarPage)">
 | 
				
			||||||
    <select [(ngModel)]="liveStyles.fontSize">
 | 
					          Save Changes
 | 
				
			||||||
 | 
					        </button>
 | 
				
			||||||
 | 
					        <button class="action-btn cancel-btn" (click)="selectedNavbarPage = ''">
 | 
				
			||||||
 | 
					          Cancel
 | 
				
			||||||
 | 
					        </button>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <div class="right-controls">
 | 
				
			||||||
 | 
					    <select [(ngModel)]="liveStyles.fontSize" class="style-control">
 | 
				
			||||||
      <option value="">Font Size</option>
 | 
					      <option value="">Font Size</option>
 | 
				
			||||||
      <option *ngFor="let size of ['12px', '14px', '16px', '18px', '20px', '24px', '28px']" [value]="size">{{ size }}</option>
 | 
					      <option *ngFor="let size of ['12px', '14px', '16px', '18px', '20px', '24px', '28px']" [value]="size">{{ size }}
 | 
				
			||||||
 | 
					      </option>
 | 
				
			||||||
    </select>
 | 
					    </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <select [(ngModel)]="liveStyles.fontWeight">
 | 
					    <select [(ngModel)]="liveStyles.fontWeight" class="style-control">
 | 
				
			||||||
      <option value="">Font Weight</option>
 | 
					      <option value="">Font Weight</option>
 | 
				
			||||||
      <option *ngFor="let weight of ['normal', 'bold', 'lighter']" [value]="weight">{{ weight }}</option>
 | 
					      <option *ngFor="let weight of ['normal', 'bold', 'lighter']" [value]="weight">{{ weight }}</option>
 | 
				
			||||||
    </select>
 | 
					    </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <select [(ngModel)]="liveStyles.textAlign">
 | 
					    <select [(ngModel)]="liveStyles.textAlign" class="style-control">
 | 
				
			||||||
      <option value="">Align</option>
 | 
					      <option value="">Align</option>
 | 
				
			||||||
      <option value="left">Left</option>
 | 
					      <option value="left">Left</option>
 | 
				
			||||||
      <option value="center">Center</option>
 | 
					      <option value="center">Center</option>
 | 
				
			||||||
      <option value="right">Right</option>
 | 
					      <option value="right">Right</option>
 | 
				
			||||||
    </select>
 | 
					    </select>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <input type="color" [(ngModel)]="liveStyles.color" title="Text Color" />
 | 
					    <input type="color" [(ngModel)]="liveStyles.color" title="Text Color" class="color-picker" />
 | 
				
			||||||
    <input type="color" [(ngModel)]="liveStyles.background" title="Background Color" />
 | 
					    <input type="color" [(ngModel)]="liveStyles.background" title="Background Color" class="color-picker" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <button (click)="applyStyleToSelection()" style="background: #555; color: white; padding: 6px 10px; border-radius: 4px;">🎨 Apply Style</button>
 | 
					    <button (click)="applyStyleToSelection()" class="action-btn style-btn">
 | 
				
			||||||
 | 
					      🎨 Apply Style
 | 
				
			||||||
 | 
					    </button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <button (click)="verifyCssInSections()" class="action-btn">🔍 Verify CSS</button>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!-- Navbar Link Manager -->
 | 
					<!-- Grid and Wireframe Canvas Area -->
 | 
				
			||||||
<!-- <div *ngIf="selectedNavbarPage" class="navbar-link-manager">
 | 
					<div class="visual-editor-container">
 | 
				
			||||||
  <h3>🔗 Navbar Link Manager ({{ selectedNavbarPage }})</h3>
 | 
					  <!-- Zoom Controls -->
 | 
				
			||||||
 | 
					  <div class="zoom-controls">
 | 
				
			||||||
 | 
					    <button class="zoom-btn" (click)="zoomIn()">
 | 
				
			||||||
 | 
					      <i class="fa fa-plus"></i>
 | 
				
			||||||
 | 
					    </button>
 | 
				
			||||||
 | 
					    <button class="zoom-btn" (click)="zoomOut()">
 | 
				
			||||||
 | 
					      <i class="fa fa-minus"></i>
 | 
				
			||||||
 | 
					    </button>
 | 
				
			||||||
 | 
					    <button class="zoom-btn" (click)="resetZoom()">
 | 
				
			||||||
 | 
					      <i class="fa fa-expand"></i>
 | 
				
			||||||
 | 
					    </button>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <ul>
 | 
					  <!-- Canvas Area with Grid -->
 | 
				
			||||||
    <li *ngFor="let link of navbarLinks[selectedNavbarPage]; let i = index">
 | 
					  <div class="canvas-wrapper" cdkScrollable>
 | 
				
			||||||
      <input [(ngModel)]="link.label" placeholder="Link Label" />
 | 
					    <div class="canvas-boundary" [style.transform]="getTransform()" (mousedown)="startPan($event)"
 | 
				
			||||||
      <select [(ngModel)]="link.href">
 | 
					      (mousemove)="doPan($event)" (mouseup)="endPan()" (mouseleave)="endPan()">
 | 
				
			||||||
        <option *ngFor="let page of availablePages" [value]="page.href">{{ page.label }}</option>
 | 
					
 | 
				
			||||||
 | 
					      <!-- Grid Background -->
 | 
				
			||||||
 | 
					      <div class="grid-background"></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <div *ngIf="isLoading" class="loading-overlay">
 | 
				
			||||||
 | 
					        <div class="spinner"></div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <!-- Pages Container - Draggable Pages -->
 | 
				
			||||||
 | 
					      <div *ngIf="!isLoading" class="pages-container" cdkDropList cdkDropListOrientation="vertical"
 | 
				
			||||||
 | 
					        (cdkDropListDropped)="onPageDrop($event)">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <div *ngFor="let pageName of pageRenderOrder" class="page-card" cdkDrag
 | 
				
			||||||
 | 
					          [class.page-hovered]="hoveredPage === pageName" (mouseenter)="showPageTools(pageName)"
 | 
				
			||||||
 | 
					          (mouseleave)="hidePageTools(pageName)">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          <!-- Page Header with Tools -->
 | 
				
			||||||
 | 
					          <div class="page-header">
 | 
				
			||||||
 | 
					            <h3 class="page-title">{{ pageName }}</h3>
 | 
				
			||||||
 | 
					            <div class="page-tools" [class.visible]="hoveredPage === pageName">
 | 
				
			||||||
 | 
					              <button class="tool-btn" (click)="regenerateWireframe(pageName)" title="Regenerate">♻️</button>
 | 
				
			||||||
 | 
					              <button class="tool-btn" (click)="copyToClipboard(pageName)" title="Copy HTML">📋</button>
 | 
				
			||||||
 | 
					              <button class="tool-btn" (click)="downloadHtml(pageName)" title="Download HTML">⬇️</button>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          <!-- Sections Container - Draggable Sections -->
 | 
				
			||||||
 | 
					          <div class="sections-container" cdkDropList [id]="'section-list-' + pageName"
 | 
				
			||||||
 | 
					            [cdkDropListData]="getSectionsData(pageName)" (cdkDropListDropped)="onSectionDrop($event, pageName)">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <!-- Individual Draggable Sections -->
 | 
				
			||||||
 | 
					            <div *ngFor="let sectionKey of getSectionKeys(pageName); let i = index" class="section-card"
 | 
				
			||||||
 | 
					              [attr.data-section-id]="sectionKey" cdkDrag [cdkDragData]="sectionKey"
 | 
				
			||||||
 | 
					              (mouseenter)="showSectionTools(pageName, sectionKey)" (mouseleave)="hideSectionTools()">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              <!-- Section Content -->
 | 
				
			||||||
 | 
					              <div class="section-content">
 | 
				
			||||||
 | 
					                <!-- Section Header -->
 | 
				
			||||||
 | 
					                <div class="section-header">
 | 
				
			||||||
 | 
					                  <span class="section-title">{{ sectionKey }}</span>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                  <!-- Section Actions -->
 | 
				
			||||||
 | 
					                  <div class="section-actions" [class.visible]="hoveredSection === sectionKey">
 | 
				
			||||||
 | 
					                    <button class="section-btn" title="Toggle Edit Mode"
 | 
				
			||||||
 | 
					                      (click)="toggleSectionEditing(pageName, sectionKey, $event)">
 | 
				
			||||||
 | 
					                      <i class="fa fa-pencil"></i>
 | 
				
			||||||
 | 
					                    </button>
 | 
				
			||||||
 | 
					                    <button class="section-btn" title="Remove Section" (click)="removeSection(pageName, sectionKey)">
 | 
				
			||||||
 | 
					                      <i class="fa fa-trash"></i>
 | 
				
			||||||
 | 
					                    </button>
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <!-- Section Preview with COMMON_CSS applied -->
 | 
				
			||||||
 | 
					                <!-- Change all [innerHTML] bindings to use $any() to bypass strict checks -->
 | 
				
			||||||
 | 
					                <div class="section-preview" [innerHTML]="$any(getSectionHtml(pageName, sectionKey))"
 | 
				
			||||||
 | 
					                  (dblclick)="toggleSectionEditing(pageName, sectionKey, $event)"
 | 
				
			||||||
 | 
					                  (blur)="handleDirectContentEdit($event, pageName, sectionKey)"
 | 
				
			||||||
 | 
					                  [attr.contenteditable]="isSectionEditable(pageName, sectionKey)">
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              <!-- Add Section Button (appears on hover) -->
 | 
				
			||||||
 | 
					              <div class="add-section-btn" *ngIf="hoveredSection === sectionKey"
 | 
				
			||||||
 | 
					                (click)="addNewSection(pageName, sectionKey)">
 | 
				
			||||||
 | 
					                <i class="fa fa-plus"></i>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              <!-- Drag Handle -->
 | 
				
			||||||
 | 
					              <div class="drag-handle" cdkDragHandle>
 | 
				
			||||||
 | 
					                <i class="fa fa-grip-lines"></i>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <!-- Empty State / Add First Section -->
 | 
				
			||||||
 | 
					            <div *ngIf="getSectionKeys(pageName).length === 0" class="empty-sections">
 | 
				
			||||||
 | 
					              <button class="add-first-section" (click)="addNewSection(pageName)">
 | 
				
			||||||
 | 
					                <i class="fa fa-plus"></i> Add First Section
 | 
				
			||||||
 | 
					              </button>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- Modal for Adding New Section -->
 | 
				
			||||||
 | 
					<div class="modal" *ngIf="showNewSectionModal">
 | 
				
			||||||
 | 
					  <div class="modal-content">
 | 
				
			||||||
 | 
					    <div class="modal-header">
 | 
				
			||||||
 | 
					      <h3>Add New Section to {{ newSectionPage }}</h3>
 | 
				
			||||||
 | 
					      <button class="close-btn" (click)="cancelAddSection()">×</button>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div class="modal-body">
 | 
				
			||||||
 | 
					      <div class="form-group">
 | 
				
			||||||
 | 
					        <label>Section Name:</label>
 | 
				
			||||||
 | 
					        <input type="text" [(ngModel)]="newSectionName" placeholder="Enter section name">
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <div class="form-group">
 | 
				
			||||||
 | 
					        <label>Section Type:</label>
 | 
				
			||||||
 | 
					        <select [(ngModel)]="newSectionType">
 | 
				
			||||||
 | 
					          <option value="">Select a type</option>
 | 
				
			||||||
 | 
					          <option value="header">Header</option>
 | 
				
			||||||
 | 
					          <option value="hero">Hero</option>
 | 
				
			||||||
 | 
					          <option value="features">Features</option>
 | 
				
			||||||
 | 
					          <option value="gallery">Gallery</option>
 | 
				
			||||||
 | 
					          <option value="pricing">Pricing</option>
 | 
				
			||||||
 | 
					          <option value="testimonials">Testimonials</option>
 | 
				
			||||||
 | 
					          <option value="contact">Contact</option>
 | 
				
			||||||
 | 
					          <option value="footer">Footer</option>
 | 
				
			||||||
        </select>
 | 
					        </select>
 | 
				
			||||||
      <button (click)="removeLink(selectedNavbarPage, i)">❌</button>
 | 
					      </div>
 | 
				
			||||||
    </li>
 | 
					 | 
				
			||||||
  </ul>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <button (click)="addLink(selectedNavbarPage)">➕ Add Link</button>
 | 
					      <div class="form-group">
 | 
				
			||||||
  <button (click)="applyNavbarChanges(selectedNavbarPage)">✅ Apply Changes</button>
 | 
					        <label>Section Description:</label>
 | 
				
			||||||
</div> -->
 | 
					        <textarea [(ngModel)]="newSectionDescription" rows="4"
 | 
				
			||||||
 | 
					          placeholder="Describe the content for this section"></textarea>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div class="modal-footer">
 | 
				
			||||||
 <!-- 🔗 Navbar Link Editor Modal -->
 | 
					      <button class="action-btn" [disabled]="!newSectionName || !newSectionType" (click)="confirmAddSection()">
 | 
				
			||||||
<div *ngIf="selectedNavbarPage" class="navbar-popup-overlay">
 | 
					        Add Section
 | 
				
			||||||
  <div class="navbar-popup-content">
 | 
					      </button>
 | 
				
			||||||
    <h3>🔗 Navbar Link Manager ({{ selectedNavbarPage }})</h3>
 | 
					      <button class="action-btn cancel-btn" (click)="cancelAddSection()">
 | 
				
			||||||
 | 
					        Cancel
 | 
				
			||||||
    <ul>
 | 
					      </button>
 | 
				
			||||||
      <li *ngFor="let link of navbarLinks[selectedNavbarPage]; let i = index">
 | 
					 | 
				
			||||||
        <input [(ngModel)]="link.label" placeholder="Link Label" />
 | 
					 | 
				
			||||||
        <select [(ngModel)]="link.href">
 | 
					 | 
				
			||||||
          <option *ngFor="let page of availablePages" [value]="page.href">{{ page.label }}</option>
 | 
					 | 
				
			||||||
        </select>
 | 
					 | 
				
			||||||
        <button (click)="removeLink(selectedNavbarPage, i)">❌</button>
 | 
					 | 
				
			||||||
      </li>
 | 
					 | 
				
			||||||
    </ul>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <div style="margin-top: 10px;">
 | 
					 | 
				
			||||||
      <button (click)="addLink(selectedNavbarPage)">➕ Add Link</button>
 | 
					 | 
				
			||||||
      <button (click)="applyNavbarChanges(selectedNavbarPage)">✅ Apply</button>
 | 
					 | 
				
			||||||
      <button (click)="selectedNavbarPage = null">❌ Close</button>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<!-- ✅ Pages List -->
 | 
					 | 
				
			||||||
<div class="canvas-wrapper">
 | 
					 | 
				
			||||||
  <div class="canvas-page" *ngFor="let pageName of pageRenderOrder">
 | 
					 | 
				
			||||||
    <div class="canvas-header">
 | 
					 | 
				
			||||||
      <button (click)="regenerateWireframe(pageName)">♻️</button>
 | 
					 | 
				
			||||||
      <h3 (click)="selectNavbar(pageName)" style="cursor: pointer;">
 | 
					 | 
				
			||||||
        {{ pageName }} <span title="Edit Navbar">🧭</span>
 | 
					 | 
				
			||||||
      </h3>
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      <div class="canvas-actions">
 | 
					 | 
				
			||||||
        <button (click)="copyToClipboard(pageName)">📋</button>
 | 
					 | 
				
			||||||
        <button (click)="downloadHtml(pageName)">⬇️</button>
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <!-- ✅ Render and Edit Section -->
 | 
					 | 
				
			||||||
    <div class="canvas-section">
 | 
					 | 
				
			||||||
      <div [innerHTML]="pageSections[pageName]?.FullPage"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
           contenteditable="true"
 | 
					 | 
				
			||||||
           class="editable-html"
 | 
					 | 
				
			||||||
           (blur)="onEdit(pageName, $event)">
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
@ -1,92 +1,668 @@
 | 
				
			|||||||
// .wireframe-container {
 | 
					/* Reset and base styles */
 | 
				
			||||||
//     font-family: Arial, sans-serif;
 | 
					.visual-editor-container {
 | 
				
			||||||
//     background: #f8f8f8;
 | 
					  * {
 | 
				
			||||||
//     padding: 1rem;
 | 
					    box-sizing: border-box;
 | 
				
			||||||
//   }
 | 
					    margin: 0;
 | 
				
			||||||
 | 
					    padding: 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//   .border-dashed {
 | 
					  body {
 | 
				
			||||||
//     border-style: dashed;
 | 
					    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 | 
				
			||||||
//   }
 | 
					    color: #333;
 | 
				
			||||||
 | 
					    line-height: 1.5;
 | 
				
			||||||
.canvas-wrapper {
 | 
					    overflow: hidden;
 | 
				
			||||||
  display: flex;
 | 
					  }
 | 
				
			||||||
  flex-wrap: wrap; /* ✅ Allow wrapping on smaller screens */
 | 
					 | 
				
			||||||
  gap: 20px;
 | 
					 | 
				
			||||||
  padding: 20px;
 | 
					 | 
				
			||||||
  justify-content: center;
 | 
					 | 
				
			||||||
  background: #f0f0f0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					  /* Overall layout fixes */
 | 
				
			||||||
 | 
					  .visual-editor-container {
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    height: calc(100vh - 60px);
 | 
				
			||||||
 | 
					    overflow: hidden;
 | 
				
			||||||
 | 
					    background: #f0f2f5;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.canvas-page {
 | 
					  /* Action bar styling */
 | 
				
			||||||
  min-width: 300px;
 | 
					  .action-bar {
 | 
				
			||||||
  min-height: 500px;
 | 
					 | 
				
			||||||
  resize: both;           /* 👈 Allows both vertical and horizontal resizing */
 | 
					 | 
				
			||||||
  overflow: auto;         /* 👈 So content doesn't get cut off */
 | 
					 | 
				
			||||||
  border: 1px solid #ccc;
 | 
					 | 
				
			||||||
  border-radius: 8px;
 | 
					 | 
				
			||||||
  background: white;
 | 
					 | 
				
			||||||
  padding: 20px;
 | 
					 | 
				
			||||||
  box-shadow: 0 0 6px rgba(0,0,0,0.1);
 | 
					 | 
				
			||||||
  display: flex;
 | 
					 | 
				
			||||||
  flex-direction: column;
 | 
					 | 
				
			||||||
  gap: 20px;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.canvas-header {
 | 
					 | 
				
			||||||
    display: flex;
 | 
					    display: flex;
 | 
				
			||||||
    justify-content: space-between;
 | 
					    justify-content: space-between;
 | 
				
			||||||
    align-items: center;
 | 
					    align-items: center;
 | 
				
			||||||
  border-bottom: 1px solid #ddd;
 | 
					 | 
				
			||||||
  padding-bottom: 10px;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.canvas-header h3 {
 | 
					 | 
				
			||||||
  margin: 0;
 | 
					 | 
				
			||||||
  font-size: 18px;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.canvas-actions button {
 | 
					 | 
				
			||||||
  margin-left: 5px;
 | 
					 | 
				
			||||||
  background: #007bff;
 | 
					 | 
				
			||||||
  border: none;
 | 
					 | 
				
			||||||
  color: white;
 | 
					 | 
				
			||||||
  padding: 4px 8px;
 | 
					 | 
				
			||||||
  border-radius: 4px;
 | 
					 | 
				
			||||||
  cursor: pointer;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.canvas-section {
 | 
					 | 
				
			||||||
  border: 1px dashed #ccc;
 | 
					 | 
				
			||||||
  padding: 10px;
 | 
					 | 
				
			||||||
  border-radius: 6px;
 | 
					 | 
				
			||||||
    background: #fff;
 | 
					    background: #fff;
 | 
				
			||||||
 | 
					    padding: 8px 16px;
 | 
				
			||||||
 | 
					    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
 | 
				
			||||||
 | 
					    position: sticky;
 | 
				
			||||||
 | 
					    top: 0;
 | 
				
			||||||
 | 
					    z-index: 100;
 | 
				
			||||||
 | 
					    height: 60px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .section-preview {
 | 
				
			||||||
 | 
					    .preview-mode {
 | 
				
			||||||
 | 
					      min-height: 200px;
 | 
				
			||||||
 | 
					      padding: 20px;
 | 
				
			||||||
 | 
					      transform: scale(0.8);
 | 
				
			||||||
 | 
					      transform-origin: top left;
 | 
				
			||||||
 | 
					      width: 125%;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      * {
 | 
				
			||||||
 | 
					        pointer-events: none;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &[contenteditable="true"] {
 | 
				
			||||||
 | 
					      .preview-mode {
 | 
				
			||||||
 | 
					        transform: none;
 | 
				
			||||||
 | 
					        width: 100%;
 | 
				
			||||||
 | 
					        pointer-events: auto;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        * {
 | 
				
			||||||
 | 
					          pointer-events: auto;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .left-controls, .right-controls {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					    gap: 10px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .action-btn {
 | 
				
			||||||
 | 
					    padding: 8px 12px;
 | 
				
			||||||
 | 
					    border-radius: 4px;
 | 
				
			||||||
 | 
					    border: none;
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					    font-weight: 500;
 | 
				
			||||||
 | 
					    transition: all 0.2s;
 | 
				
			||||||
 | 
					    background: #f5f5f5;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:hover {
 | 
				
			||||||
 | 
					      background: #e0e0e0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &.regenerate-btn {
 | 
				
			||||||
 | 
					      background: #e3f2fd;
 | 
				
			||||||
 | 
					      color: #2196f3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      &:hover {
 | 
				
			||||||
 | 
					        background: #bbdefb;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &.save-btn {
 | 
				
			||||||
 | 
					      background: #e8f5e9;
 | 
				
			||||||
 | 
					      color: #4caf50;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      &:hover {
 | 
				
			||||||
 | 
					        background: #c8e6c9;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .style-control {
 | 
				
			||||||
 | 
					    padding: 6px 8px;
 | 
				
			||||||
 | 
					    border-radius: 4px;
 | 
				
			||||||
 | 
					    border: 1px solid #ddd;
 | 
				
			||||||
 | 
					    min-width: 100px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .color-picker {
 | 
				
			||||||
 | 
					    width: 30px;
 | 
				
			||||||
 | 
					    height: 30px;
 | 
				
			||||||
 | 
					    padding: 0;
 | 
				
			||||||
 | 
					    border: 1px solid #ddd;
 | 
				
			||||||
 | 
					    border-radius: 4px;
 | 
				
			||||||
 | 
					    overflow: hidden;
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Zoom controls */
 | 
				
			||||||
 | 
					  .zoom-controls {
 | 
				
			||||||
 | 
					    position: absolute;
 | 
				
			||||||
 | 
					    top: 10px;
 | 
				
			||||||
 | 
					    right: 10px;
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    gap: 5px;
 | 
				
			||||||
 | 
					    z-index: 50;
 | 
				
			||||||
 | 
					    background: rgba(255, 255, 255, 0.9);
 | 
				
			||||||
 | 
					    padding: 5px;
 | 
				
			||||||
 | 
					    border-radius: 4px;
 | 
				
			||||||
 | 
					    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .zoom-btn {
 | 
				
			||||||
 | 
					    width: 30px;
 | 
				
			||||||
 | 
					    height: 30px;
 | 
				
			||||||
 | 
					    border-radius: 50%;
 | 
				
			||||||
 | 
					    border: none;
 | 
				
			||||||
 | 
					    background: #f5f5f5;
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					    justify-content: center;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:hover {
 | 
				
			||||||
 | 
					      background: #e0e0e0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Canvas and grid styling */
 | 
				
			||||||
 | 
					  .canvas-wrapper {
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    height: 100%;
 | 
				
			||||||
 | 
					    overflow: hidden;
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .canvas-boundary {
 | 
				
			||||||
 | 
					    position: absolute;
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    height: 100%;
 | 
				
			||||||
 | 
					    cursor: move;
 | 
				
			||||||
 | 
					    transform-origin: 0 0;
 | 
				
			||||||
 | 
					    will-change: transform;
 | 
				
			||||||
 | 
					    background-color: #f5f5f5;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .grid-background {
 | 
				
			||||||
 | 
					    position: absolute;
 | 
				
			||||||
 | 
					    width: 5000px;
 | 
				
			||||||
 | 
					    height: 5000px;
 | 
				
			||||||
 | 
					    background-size: 20px 20px;
 | 
				
			||||||
 | 
					    background-image: 
 | 
				
			||||||
 | 
					      linear-gradient(to right, rgba(0,0,0,0.05) 1px, transparent 1px),
 | 
				
			||||||
 | 
					      linear-gradient(to bottom, rgba(0,0,0,0.05) 1px, transparent 1px);
 | 
				
			||||||
 | 
					    transform: translate(-2500px, -2500px);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Pages container */
 | 
				
			||||||
 | 
					  .pages-container {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    gap: 40px;
 | 
				
			||||||
 | 
					    padding: 40px;
 | 
				
			||||||
 | 
					    align-items: flex-start;
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    z-index: 10;
 | 
				
			||||||
 | 
					    width: 2000px;
 | 
				
			||||||
 | 
					    height: auto;
 | 
				
			||||||
 | 
					    overflow: hidden;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Page card styling */
 | 
				
			||||||
 | 
					  .page-card {
 | 
				
			||||||
 | 
					    background: white;
 | 
				
			||||||
 | 
					    border-radius: 8px;
 | 
				
			||||||
 | 
					    box-shadow: 0 4px 12px rgba(0,0,0,0.1);
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    flex-direction: column;
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    transition: box-shadow 0.3s;
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    margin: 20px 0;
 | 
				
			||||||
 | 
					    overflow: hidden;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:hover {
 | 
				
			||||||
 | 
					      box-shadow: 0 6px 14px rgba(0,0,0,0.15);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &.page-hovered {
 | 
				
			||||||
 | 
					      border: 2px solid #2196f3;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Page header */
 | 
				
			||||||
 | 
					  .page-header {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    justify-content: space-between;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					    padding: 12px 16px;
 | 
				
			||||||
 | 
					    border-bottom: 1px solid #eee;
 | 
				
			||||||
 | 
					    background: #f5f7fa;
 | 
				
			||||||
 | 
					    border-radius: 8px 8px 0 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Navbar Editor Styles */
 | 
				
			||||||
 | 
					  .navbar-controls {
 | 
				
			||||||
 | 
					    margin-left: 20px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    select {
 | 
				
			||||||
 | 
					      padding: 8px 12px;
 | 
				
			||||||
 | 
					      border-radius: 4px;
 | 
				
			||||||
 | 
					      border: 1px solid #ccc;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .link-editor {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    gap: 10px;
 | 
				
			||||||
 | 
					    margin-bottom: 10px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    input, select {
 | 
				
			||||||
 | 
					      flex: 1;
 | 
				
			||||||
 | 
					      padding: 8px;
 | 
				
			||||||
 | 
					      border: 1px solid #ddd;
 | 
				
			||||||
 | 
					      border-radius: 4px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .remove-btn {
 | 
				
			||||||
 | 
					      background: #ff4444;
 | 
				
			||||||
 | 
					      color: white;
 | 
				
			||||||
 | 
					      border: none;
 | 
				
			||||||
 | 
					      border-radius: 50%;
 | 
				
			||||||
 | 
					      width: 24px;
 | 
				
			||||||
 | 
					      height: 24px;
 | 
				
			||||||
 | 
					      cursor: pointer;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .add-link-btn {
 | 
				
			||||||
 | 
					    margin-top: 15px;
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .page-title {
 | 
				
			||||||
 | 
					    font-size: 16px;
 | 
				
			||||||
 | 
					    font-weight: 600;
 | 
				
			||||||
 | 
					    margin: 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .page-tools {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    gap: 8px;
 | 
				
			||||||
 | 
					    opacity: 0;
 | 
				
			||||||
 | 
					    transition: opacity 0.2s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &.visible {
 | 
				
			||||||
 | 
					      opacity: 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .tool-btn {
 | 
				
			||||||
 | 
					    background: none;
 | 
				
			||||||
 | 
					    border: none;
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					    font-size: 14px;
 | 
				
			||||||
 | 
					    width: 30px;
 | 
				
			||||||
 | 
					    height: 30px;
 | 
				
			||||||
 | 
					    border-radius: 50%;
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					    justify-content: center;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:hover {
 | 
				
			||||||
 | 
					      background: rgba(0,0,0,0.05);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* In component's CSS */
 | 
				
			||||||
 | 
					.pages-container {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  flex-direction: column;
 | 
				
			||||||
 | 
					  gap: 2rem;
 | 
				
			||||||
 | 
					  padding: 1rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.page-card {
 | 
				
			||||||
.editable-html:focus {
 | 
					  width: 100%;
 | 
				
			||||||
  outline: 2px solid #007bff;
 | 
					  margin-bottom: 2rem;
 | 
				
			||||||
  background: #fcfcfc;
 | 
					  border: 1px solid #ddd;
 | 
				
			||||||
 | 
					  border-radius: 8px;
 | 
				
			||||||
 | 
					  background: white;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.navbar-popup-overlay {
 | 
					.loading-overlay {
 | 
				
			||||||
  position: fixed;
 | 
					  position: fixed;
 | 
				
			||||||
  top: 0;
 | 
					  top: 0;
 | 
				
			||||||
  left: 0;
 | 
					  left: 0;
 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
  height: 100%;
 | 
					  height: 100%;
 | 
				
			||||||
 | 
					  background: rgba(255, 255, 255, 0.8);
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  justify-content: center;
 | 
				
			||||||
 | 
					  align-items: center;
 | 
				
			||||||
 | 
					  z-index: 1000;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.spinner {
 | 
				
			||||||
 | 
					  width: 40px;
 | 
				
			||||||
 | 
					  height: 40px;
 | 
				
			||||||
 | 
					  border: 4px solid #f3f3f3;
 | 
				
			||||||
 | 
					  border-top: 4px solid #3498db;
 | 
				
			||||||
 | 
					  border-radius: 50%;
 | 
				
			||||||
 | 
					  animation: spin 1s linear infinite;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@keyframes spin {
 | 
				
			||||||
 | 
					  0% { transform: rotate(0deg); }
 | 
				
			||||||
 | 
					  100% { transform: rotate(360deg); }
 | 
				
			||||||
 | 
					} 
 | 
				
			||||||
 | 
					  /* Sections container */
 | 
				
			||||||
 | 
					  .sections-container {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    flex-direction: column;
 | 
				
			||||||
 | 
					    gap: 16px;
 | 
				
			||||||
 | 
					    padding: 16px;
 | 
				
			||||||
 | 
					    min-height: 100px;
 | 
				
			||||||
 | 
					    max-height: 600px;
 | 
				
			||||||
 | 
					    overflow-y: auto;
 | 
				
			||||||
 | 
					    scrollbar-width: thin;
 | 
				
			||||||
 | 
					    // width: 1700px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &::-webkit-scrollbar {
 | 
				
			||||||
 | 
					      width: 6px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &::-webkit-scrollbar-track {
 | 
				
			||||||
 | 
					      background: transparent;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &::-webkit-scrollbar-thumb {
 | 
				
			||||||
 | 
					      background-color: rgba(0,0,0,0.2);
 | 
				
			||||||
 | 
					      border-radius: 3px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Section card */
 | 
				
			||||||
 | 
					  .section-card {
 | 
				
			||||||
 | 
					    background: white;
 | 
				
			||||||
 | 
					    border: 1px solid #eaeaea;
 | 
				
			||||||
 | 
					    border-radius: 6px;
 | 
				
			||||||
 | 
					    transition: all 0.2s;
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    box-shadow: 0 1px 3px rgba(0,0,0,0.08);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:hover {
 | 
				
			||||||
 | 
					      box-shadow: 0 2px 5px rgba(0,0,0,0.12);
 | 
				
			||||||
 | 
					      border-color: #dadada;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Section header */
 | 
				
			||||||
 | 
					  .section-header {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    justify-content: space-between;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					    padding: 8px 12px;
 | 
				
			||||||
 | 
					    background: #f8f9fa;
 | 
				
			||||||
 | 
					    border-bottom: 1px solid #eee;
 | 
				
			||||||
 | 
					    border-radius: 6px 6px 0 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .section-title {
 | 
				
			||||||
 | 
					    font-size: 14px;
 | 
				
			||||||
 | 
					    font-weight: 500;
 | 
				
			||||||
 | 
					    color: #444;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .section-actions {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    gap: 6px;
 | 
				
			||||||
 | 
					    opacity: 0;
 | 
				
			||||||
 | 
					    transition: opacity 0.2s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &.visible {
 | 
				
			||||||
 | 
					      opacity: 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .section-btn {
 | 
				
			||||||
 | 
					    background: none;
 | 
				
			||||||
 | 
					    border: none;
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					    width: 26px;
 | 
				
			||||||
 | 
					    height: 26px;
 | 
				
			||||||
 | 
					    border-radius: 4px;
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					    justify-content: center;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:hover {
 | 
				
			||||||
 | 
					      background: rgba(0,0,0,0.05);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Section preview area */
 | 
				
			||||||
 | 
					  .section-preview {
 | 
				
			||||||
 | 
					    padding: 12px;
 | 
				
			||||||
 | 
					    min-height: 50px;
 | 
				
			||||||
 | 
					    font-size: 14px;
 | 
				
			||||||
 | 
					    word-break: break-word;
 | 
				
			||||||
 | 
					    position: relative;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Add section button */
 | 
				
			||||||
 | 
					  .add-section-btn {
 | 
				
			||||||
 | 
					    position: absolute;
 | 
				
			||||||
 | 
					    bottom: -10px;
 | 
				
			||||||
 | 
					    left: 50%;
 | 
				
			||||||
 | 
					    transform: translateX(-50%);
 | 
				
			||||||
 | 
					    width: 24px;
 | 
				
			||||||
 | 
					    height: 24px;
 | 
				
			||||||
 | 
					    border-radius: 50%;
 | 
				
			||||||
 | 
					    background: #2196f3;
 | 
				
			||||||
 | 
					    color: white;
 | 
				
			||||||
 | 
					    border: none;
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					    justify-content: center;
 | 
				
			||||||
 | 
					    z-index: 5;
 | 
				
			||||||
 | 
					    box-shadow: 0 2px 4px rgba(0,0,0,0.2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:hover {
 | 
				
			||||||
 | 
					      background: #1e88e5;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Drag handle */
 | 
				
			||||||
 | 
					  .drag-handle {
 | 
				
			||||||
 | 
					    position: absolute;
 | 
				
			||||||
 | 
					    top: 50%;
 | 
				
			||||||
 | 
					    left: -14px;
 | 
				
			||||||
 | 
					    transform: translateY(-50%);
 | 
				
			||||||
 | 
					    opacity: 0;
 | 
				
			||||||
 | 
					    transition: opacity 0.2s;
 | 
				
			||||||
 | 
					    width: 18px;
 | 
				
			||||||
 | 
					    height: 36px;
 | 
				
			||||||
 | 
					    background: #eee;
 | 
				
			||||||
 | 
					    border-radius: 4px 0 0 4px;
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					    justify-content: center;
 | 
				
			||||||
 | 
					    cursor: grab;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .section-card:hover & {
 | 
				
			||||||
 | 
					      opacity: 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:active {
 | 
				
			||||||
 | 
					      cursor: grabbing;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Empty sections state */
 | 
				
			||||||
 | 
					  .empty-sections {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    justify-content: center;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					    min-height: 100px;
 | 
				
			||||||
 | 
					    border: 2px dashed #ddd;
 | 
				
			||||||
 | 
					    border-radius: 6px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .add-first-section {
 | 
				
			||||||
 | 
					    background: #f5f5f5;
 | 
				
			||||||
 | 
					    border: 1px solid #ddd;
 | 
				
			||||||
 | 
					    padding: 8px 16px;
 | 
				
			||||||
 | 
					    border-radius: 4px;
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					    gap: 6px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:hover {
 | 
				
			||||||
 | 
					      background: #eee;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* CDK drag styles */
 | 
				
			||||||
 | 
					  .cdk-drag-preview {
 | 
				
			||||||
 | 
					    box-shadow: 0 5px 15px rgba(0,0,0,0.3) !important;
 | 
				
			||||||
 | 
					    opacity: 0.8;
 | 
				
			||||||
 | 
					    border: 2px solid #2196f3;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .cdk-drag-placeholder {
 | 
				
			||||||
 | 
					    opacity: 0.3;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .cdk-drag-animating {
 | 
				
			||||||
 | 
					    transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .sections-container.cdk-drop-list-dragging .section-card:not(.cdk-drag-placeholder) {
 | 
				
			||||||
 | 
					    transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Responsive adjustments */
 | 
				
			||||||
 | 
					  @media (max-width: 768px) {
 | 
				
			||||||
 | 
					    .action-bar {
 | 
				
			||||||
 | 
					      flex-direction: column;
 | 
				
			||||||
 | 
					      height: auto;
 | 
				
			||||||
 | 
					      padding: 10px;
 | 
				
			||||||
 | 
					      gap: 10px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    .left-controls, .right-controls {
 | 
				
			||||||
 | 
					      width: 100%;
 | 
				
			||||||
 | 
					      justify-content: space-between;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    .visual-editor-container {
 | 
				
			||||||
 | 
					      height: calc(100vh - 110px);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Global modal styles (outside visual-editor scope) */
 | 
				
			||||||
 | 
					.modal-overlay {
 | 
				
			||||||
 | 
					  position: fixed;
 | 
				
			||||||
 | 
					  top: 0;
 | 
				
			||||||
 | 
					  left: 0;
 | 
				
			||||||
 | 
					  right: 0;
 | 
				
			||||||
 | 
					  bottom: 0;
 | 
				
			||||||
  background: rgba(0,0,0,0.5);
 | 
					  background: rgba(0,0,0,0.5);
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
  align-items: center;
 | 
					  align-items: center;
 | 
				
			||||||
  justify-content: center;
 | 
					  justify-content: center;
 | 
				
			||||||
  z-index: 9999;
 | 
					  z-index: 1000;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.navbar-popup-content {
 | 
					.modal-content {
 | 
				
			||||||
  background: white;
 | 
					  background: white;
 | 
				
			||||||
  padding: 20px;
 | 
					 | 
				
			||||||
  width: 500px;
 | 
					 | 
				
			||||||
  max-width: 90%;
 | 
					 | 
				
			||||||
  border-radius: 8px;
 | 
					  border-radius: 8px;
 | 
				
			||||||
 | 
					  width: 400px;
 | 
				
			||||||
 | 
					  max-width: 90%;
 | 
				
			||||||
 | 
					  box-shadow: 0 4px 20px rgba(0,0,0,0.2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.modal-header {
 | 
				
			||||||
 | 
					  padding: 16px;
 | 
				
			||||||
 | 
					  border-bottom: 1px solid #eee;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.modal-title {
 | 
				
			||||||
 | 
					  margin: 0;
 | 
				
			||||||
 | 
					  font-size: 18px;
 | 
				
			||||||
 | 
					  font-weight: 600;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.modal-body {
 | 
				
			||||||
 | 
					  padding: 16px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.form-group {
 | 
				
			||||||
 | 
					  margin-bottom: 16px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.form-label {
 | 
				
			||||||
 | 
					  display: block;
 | 
				
			||||||
 | 
					  margin-bottom: 6px;
 | 
				
			||||||
 | 
					  font-weight: 500;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.form-control {
 | 
				
			||||||
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					  padding: 8px 12px;
 | 
				
			||||||
 | 
					  border: 1px solid #ddd;
 | 
				
			||||||
 | 
					  border-radius: 4px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.modal-footer {
 | 
				
			||||||
 | 
					  padding: 16px;
 | 
				
			||||||
 | 
					  border-top: 1px solid #eee;
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  justify-content: flex-end;
 | 
				
			||||||
 | 
					  gap: 12px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Section editing styles */
 | 
				
			||||||
 | 
					.edit-overlay {
 | 
				
			||||||
 | 
					  position: fixed;
 | 
				
			||||||
 | 
					  top: 0;
 | 
				
			||||||
 | 
					  left: 0;
 | 
				
			||||||
 | 
					  right: 0;
 | 
				
			||||||
 | 
					  bottom: 0;
 | 
				
			||||||
 | 
					  background: rgba(0,0,0,0.5);
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  align-items: center;
 | 
				
			||||||
 | 
					  justify-content: center;
 | 
				
			||||||
 | 
					  z-index: 1000;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.edit-container {
 | 
				
			||||||
 | 
					  background: white;
 | 
				
			||||||
 | 
					  border-radius: 8px;
 | 
				
			||||||
 | 
					  width: 80%;
 | 
				
			||||||
 | 
					  max-width: 1000px;
 | 
				
			||||||
 | 
					  height: 80%;
 | 
				
			||||||
 | 
					  max-height: 800px;
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  flex-direction: column;
 | 
				
			||||||
 | 
					  box-shadow: 0 4px 20px rgba(0,0,0,0.2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.edit-header {
 | 
				
			||||||
 | 
					  padding: 16px;
 | 
				
			||||||
 | 
					  border-bottom: 1px solid #eee;
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  justify-content: space-between;
 | 
				
			||||||
 | 
					  align-items: center;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.edit-title {
 | 
				
			||||||
 | 
					  margin: 0;
 | 
				
			||||||
 | 
					  font-size: 18px;
 | 
				
			||||||
 | 
					  font-weight: 600;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.edit-content {
 | 
				
			||||||
 | 
					  flex: 1;
 | 
				
			||||||
 | 
					  padding: 16px;
 | 
				
			||||||
 | 
					  overflow: auto;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.editable-html {
 | 
				
			||||||
 | 
					  border: 1px solid #ddd;
 | 
				
			||||||
 | 
					  border-radius: 4px;
 | 
				
			||||||
 | 
					  padding: 16px;
 | 
				
			||||||
 | 
					  min-height: 100%;
 | 
				
			||||||
 | 
					  outline: none;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.edit-footer {
 | 
				
			||||||
 | 
					  padding: 16px;
 | 
				
			||||||
 | 
					  border-top: 1px solid #eee;
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  justify-content: flex-end;
 | 
				
			||||||
 | 
					  gap: 12px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -70,19 +70,33 @@ export class ApiRequestService {
 | 
				
			|||||||
    //return Observable.throw(error.message);
 | 
					    //return Observable.throw(error.message);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  get(url: string, urlParams?: HttpParams): Observable<any> {
 | 
					  // get(url: string, urlParams?: HttpParams): Observable<any> {
 | 
				
			||||||
 | 
					  //   let me = this;
 | 
				
			||||||
 | 
					  //   return this.http
 | 
				
			||||||
 | 
					  //     .get(this.appConfig.baseApiPath + url, {
 | 
				
			||||||
 | 
					  //       headers: this.getHeaders(),
 | 
				
			||||||
 | 
					  //       params: urlParams,
 | 
				
			||||||
 | 
					  //     }).pipe(
 | 
				
			||||||
 | 
					  //       catchError((error) => {
 | 
				
			||||||
 | 
					  //         return throwError(error || "Server error");
 | 
				
			||||||
 | 
					  //       })
 | 
				
			||||||
 | 
					  //     )
 | 
				
			||||||
 | 
					  // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  get(url: string, urlParams?: HttpParams, responseType: 'json' | 'text' = 'json'): Observable<any> {
 | 
				
			||||||
    let me = this;
 | 
					    let me = this;
 | 
				
			||||||
    return this.http
 | 
					    return this.http.get(this.appConfig.baseApiPath + url, {
 | 
				
			||||||
      .get(this.appConfig.baseApiPath + url, {
 | 
					 | 
				
			||||||
      headers: this.getHeaders(),
 | 
					      headers: this.getHeaders(),
 | 
				
			||||||
      params: urlParams,
 | 
					      params: urlParams,
 | 
				
			||||||
 | 
					      responseType: responseType as any, // 👈 force-cast because Angular types are strict
 | 
				
			||||||
    }).pipe(
 | 
					    }).pipe(
 | 
				
			||||||
      catchError((error) => {
 | 
					      catchError((error) => {
 | 
				
			||||||
        return throwError(error || "Server error");
 | 
					        return throwError(error || "Server error");
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      )
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  loginAuthentication(url: string, body: Object): Observable<any> {
 | 
					  loginAuthentication(url: string, body: Object): Observable<any> {
 | 
				
			||||||
    let me = this;
 | 
					    let me = this;
 | 
				
			||||||
    return this.http
 | 
					    return this.http
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user