wireframe
This commit is contained in:
parent
dce9fb86d9
commit
62dffed702
@ -52,6 +52,7 @@ export class EditstepperComponent implements OnInit {
|
||||
|
||||
|
||||
public entryForm: FormGroup;
|
||||
|
||||
submitted = false;
|
||||
rowSelected: any = {};
|
||||
modalcomplete = false;
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -135,203 +135,282 @@
|
||||
<div class="wireframe-controls-sidebar"
|
||||
[class.collapsed]="sidebarCollapsed"
|
||||
[class.mobile-open]="sidebarOpen"
|
||||
[class.visible]="sidebarOpen || !isMobile">
|
||||
[class.visible]="sidebarOpen || !isMobile">
|
||||
|
||||
<!-- Sidebar Header -->
|
||||
<div class="sidebar-header">
|
||||
<div (click)="toggleSidebar()">
|
||||
<i class="fas" [ngClass]="sidebarCollapsed ? 'fa-chevron-left' : 'fa-chevron-right'"></i>
|
||||
<!-- Loading Overlay -->
|
||||
<!-- <div *ngIf="isLoading" class="loading-overlay">
|
||||
<mat-spinner diameter="40"></mat-spinner>
|
||||
<div class="loading-text">Generating Pages...</div>
|
||||
</div> -->
|
||||
|
||||
<!-- Updated Close Button -->
|
||||
<div class="sidebar-header">
|
||||
<button
|
||||
(click)="toggleSidebar()"
|
||||
class="close-btn"
|
||||
style="
|
||||
background: none;
|
||||
border: none;
|
||||
color: #060606;
|
||||
cursor: pointer;
|
||||
padding: 8px;
|
||||
border-radius: 50%;
|
||||
transition: all 0.2s ease-in-out;
|
||||
font-size: 16px;
|
||||
"
|
||||
>
|
||||
<i class="fas" [ngClass]="sidebarCollapsed ? 'fa-chevron-left' : 'fa-chevron-right'"></i>
|
||||
</button>
|
||||
<h2>Wireframe Controls</h2>
|
||||
</div>
|
||||
|
||||
<!-- Main Actions Section -->
|
||||
<div class="sidebar-content">
|
||||
|
||||
<div class="control-section search-section fade-in-up" [@fadeIn]>
|
||||
<h3>
|
||||
<i class="fas fa-search" style="margin-right: 6px; color: #17a2b8;"></i>
|
||||
Search Sections
|
||||
</h3>
|
||||
|
||||
<div class="search-container">
|
||||
<input
|
||||
type="text"
|
||||
class="search-input"
|
||||
[(ngModel)]="searchTerm"
|
||||
(input)="onSearchChange()"
|
||||
placeholder="Search sections..."
|
||||
> </div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Global Sections -->
|
||||
<div class="control-section fade-in-left" [@fadeIn]>
|
||||
<h3>
|
||||
<i class="fas fa-globe" style="margin-right: 6px; color: #6f42c1;"></i>
|
||||
Global Sections
|
||||
</h3>
|
||||
|
||||
<div class="wf-section-list" *ngIf="getFilteredSections(globalSections).length">
|
||||
<div class="wf-section-item"
|
||||
*ngFor="let section of getFilteredSections(globalSections)"
|
||||
(click)="addSectionFromTemplate(section)">
|
||||
<div class="section-icon">
|
||||
<i [class]="section.icon"></i>
|
||||
</div>
|
||||
<div class="section-info">
|
||||
<div class="section-name">{{ section.type }}</div>
|
||||
<div class="section-desc">{{ section.description }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<h2>
|
||||
|
||||
<i class="fas fa-cogs" style="margin-right: 8px; font-size: 18px;"></i>
|
||||
|
||||
Wireframe Controls
|
||||
</h2>
|
||||
|
||||
<!-- Standard Sections -->
|
||||
<div class="control-section fade-in-left" [@fadeIn]>
|
||||
<h3>
|
||||
<i class="fas fa-th-large" style="margin-right: 6px; color: #fd7e14;"></i>
|
||||
Standard Sections
|
||||
</h3>
|
||||
|
||||
<div class="wf-section-list" *ngIf="getFilteredSections(standardSections).length">
|
||||
<div class="wf-section-item"
|
||||
*ngFor="let section of getFilteredSections(standardSections)"
|
||||
(click)="addSectionFromTemplate(section)">
|
||||
<div class="section-icon">
|
||||
<i [class]="section.icon"></i>
|
||||
</div>
|
||||
<div class="section-info">
|
||||
<div class="section-name">{{ section.type }}</div>
|
||||
<div class="section-desc">{{ section.description }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Main Actions Section -->
|
||||
<div class="sidebar-content">
|
||||
<div class="control-section fade-in-up" [@fadeIn]>
|
||||
<h3>
|
||||
<i class="fas fa-play-circle" style="margin-right: 6px; color: #28a745;"></i>
|
||||
Generate Wireframe
|
||||
</h3>
|
||||
|
||||
<button class="action-btn primary" (click)="buildWireframe(37688)" [@buttonHover]>
|
||||
<i class="fas fa-hammer"></i>
|
||||
Build Wireframe
|
||||
</button>
|
||||
|
||||
<button class="action-btn primary" (click)="regenerateAllModifiedSections()">
|
||||
<i class="fas fa-sync-alt"></i>
|
||||
Regenerate Modified
|
||||
</button>
|
||||
|
||||
<button class="action-btn secondary" (click)="createHtmlFiles()">
|
||||
<i class="fas fa-save"></i>
|
||||
Save All HTML Files
|
||||
</button>
|
||||
|
||||
<button class="action-btn secondary" (click)="recreateWireframe()">
|
||||
<i class="fas fa-redo"></i>
|
||||
Recreate Wireframe
|
||||
</button>
|
||||
|
||||
<button class="action-btn secondary">
|
||||
<i class="fa-solid fa-link"></i>
|
||||
{{ deployedUrl ? 'DEPLOYED URL: ' + deployedUrl : 'NO URL YET' }}
|
||||
</button>
|
||||
|
||||
<!-- Custom Sections -->
|
||||
<div class="control-section fade-in-left" [@fadeIn]>
|
||||
<h3>
|
||||
<i class="fas fa-puzzle-piece" style="margin-right: 6px; color: #e83e8c;"></i>
|
||||
Custom Sections
|
||||
</h3>
|
||||
|
||||
<div class="wf-section-list" *ngIf="getFilteredSections(customSections).length">
|
||||
<div class="wf-section-item"
|
||||
*ngFor="let section of getFilteredSections(customSections)"
|
||||
(click)="addSectionFromTemplate(section)">
|
||||
<div class="section-icon">
|
||||
<i [class]="section.icon"></i>
|
||||
</div>
|
||||
<div class="section-info">
|
||||
<div class="section-name">{{ section.type }}</div>
|
||||
<div class="section-desc">{{ section.description }}</div>
|
||||
</div>
|
||||
<button class="delete-custom-btn" (click)="deleteCustomSection($event, section)">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Navbar Controls Section -->
|
||||
<div class="control-section fade-in-left" [@fadeIn]>
|
||||
<h3>
|
||||
<i class="fas fa-bars" style="margin-right: 6px; color: #17a2b8;"></i>
|
||||
Navbar Editor
|
||||
</h3>
|
||||
|
||||
<!-- Add Custom Section -->
|
||||
<div class="add-custom-section">
|
||||
<button class="action-btn secondary full-width" (click)="showAddCustomSectionModal()">
|
||||
<i class="fas fa-plus"></i>
|
||||
Add Custom Section
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Additional Features Section -->
|
||||
<div class="control-section fade-in-up" [@fadeIn]>
|
||||
<h3>
|
||||
<i class="fas fa-tools" style="margin-right: 6px; color: #20c997;"></i>
|
||||
Additional Features
|
||||
</h3>
|
||||
|
||||
<button class="action-btn primary" (click)="createHtmlFiles()">
|
||||
<i class="fas fa-save"></i>
|
||||
Save All HTML Files
|
||||
</button>
|
||||
|
||||
<button class="action-btn secondary" (click)="recreateWireframe()">
|
||||
<i class="fas fa-redo"></i>
|
||||
Regenerate Wireframe
|
||||
</button>
|
||||
|
||||
<button class="action-btn primary" (click)="showNavbarEditor()">
|
||||
<i class="fas fa-bars"></i>
|
||||
Navbar Editor
|
||||
</button>
|
||||
|
||||
<button class="action-btn secondary" (click)="buildWireframe(37688)" [@buttonHover]>
|
||||
<i class="fas fa-hammer"></i>
|
||||
Build Wireframe
|
||||
</button>
|
||||
|
||||
<button class="action-btn primary" (click)="regenerateAllModifiedSections()">
|
||||
<i class="fas fa-sync-alt"></i>
|
||||
Regenerate Modified
|
||||
</button>
|
||||
|
||||
<button class="action-btn secondary">
|
||||
<i class="fas fa-external-link-alt"></i>
|
||||
{{ deployedUrl ? 'DEPLOYED URL: ' + deployedUrl : 'NO URL YET' }}
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Commented out sections as requested -->
|
||||
<!--
|
||||
<div class="control-section bounce-in" [@fadeIn]>
|
||||
<h3>
|
||||
<i class="fas fa-palette" style="margin-right: 6px; color: #fd7e14;"></i>
|
||||
Style Controls
|
||||
</h3>
|
||||
|
||||
<div class="style-grid">
|
||||
<div class="form-group">
|
||||
<label for="navbarSelect">Select Navbar Page:</label>
|
||||
<select id="navbarSelect" class="form-control" [(ngModel)]="selectedNavbarPage"
|
||||
(change)="selectedNavbarPage && selectNavbar(selectedNavbarPage)"
|
||||
[@focusBorder]>
|
||||
<option value="">Choose a page...</option>
|
||||
<option *ngFor="let page of pageRenderOrder" [value]="page">
|
||||
<i class="fas fa-file-alt"></i> {{ page }}
|
||||
</option>
|
||||
<label>Font Size:</label>
|
||||
<select class="form-control" [(ngModel)]="liveStyles.fontSize">
|
||||
<option value="">Default</option>
|
||||
<option *ngFor="let size of fontSizes" [value]="size">{{ size }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Font Weight:</label>
|
||||
<select class="form-control" [(ngModel)]="liveStyles.fontWeight">
|
||||
<option value="">Default</option>
|
||||
<option *ngFor="let weight of fontWeights" [value]="weight">{{ weight }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Style Controls Section -->
|
||||
<div class="control-section bounce-in" [@fadeIn]>
|
||||
<h3>
|
||||
<i class="fas fa-palette" style="margin-right: 6px; color: #fd7e14;"></i>
|
||||
Style Controls
|
||||
</h3>
|
||||
<div class="color-controls">
|
||||
<div class="color-input-group">
|
||||
<span class="color-label">
|
||||
<i class="fas fa-font" style="margin-right: 4px;"></i>
|
||||
Text Color
|
||||
</span>
|
||||
<input type="color" [(ngModel)]="liveStyles.color" class="color-picker" />
|
||||
</div>
|
||||
|
||||
<div class="style-grid">
|
||||
<div class="form-group">
|
||||
<label>Font Size:</label>
|
||||
<select class="form-control" [(ngModel)]="liveStyles.fontSize">
|
||||
<option value="">Default</option>
|
||||
<option *ngFor="let size of fontSizes" [value]="size">{{ size }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Font Weight:</label>
|
||||
<select class="form-control" [(ngModel)]="liveStyles.fontWeight">
|
||||
<option value="">Default</option>
|
||||
<option *ngFor="let weight of fontWeights" [value]="weight">{{ weight }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="color-input-group">
|
||||
<span class="color-label">
|
||||
<i class="fas fa-fill-drip" style="margin-right: 4px;"></i>
|
||||
Background
|
||||
</span>
|
||||
<input type="color" [(ngModel)]="liveStyles.background" class="color-picker" />
|
||||
</div>
|
||||
|
||||
<div class="style-grid">
|
||||
<div class="form-group">
|
||||
<label>Text Align:</label>
|
||||
<select class="form-control" [(ngModel)]="liveStyles.textAlign">
|
||||
<option value="">Default</option>
|
||||
<option value="left">Left</option>
|
||||
<option value="center">Center</option>
|
||||
<option value="right">Right</option>
|
||||
<option value="justify">Justify</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<button class="action-btn secondary small" (click)="verifyCssInSections()">
|
||||
<i class="fas fa-search"></i>
|
||||
Verify CSS
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="color-controls">
|
||||
<div class="color-input-group">
|
||||
<span class="color-label">
|
||||
<i class="fas fa-font" style="margin-right: 4px;"></i>
|
||||
Text Color
|
||||
</span>
|
||||
<input type="color" [(ngModel)]="liveStyles.color" class="color-picker" />
|
||||
</div>
|
||||
|
||||
<div class="color-input-group">
|
||||
<span class="color-label">
|
||||
<i class="fas fa-fill-drip" style="margin-right: 4px;"></i>
|
||||
Background
|
||||
</span>
|
||||
<input type="color" [(ngModel)]="liveStyles.background" class="color-picker" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="action-btn primary full-width" (click)="applyStyleToSelection()">
|
||||
<i class="fas fa-paint-brush"></i>
|
||||
Apply Style to Selection
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Page Management Section -->
|
||||
<div class="control-section fade-in-up" [@fadeIn]>
|
||||
<h3>
|
||||
<i class="fas fa-file-alt" style="margin-right: 6px; color: #dc3545;"></i>
|
||||
Page Management
|
||||
</h3>
|
||||
|
||||
<button class="action-btn secondary" (click)="addNewPage()">
|
||||
<i class="fas fa-plus"></i>
|
||||
Add New Page
|
||||
</button>
|
||||
|
||||
<button class="action-btn secondary" (click)="duplicateCurrentPage()">
|
||||
<i class="fas fa-copy"></i>
|
||||
Duplicate Current Page
|
||||
</button>
|
||||
|
||||
<button class="action-btn secondary" (click)="deleteCurrentPage()"
|
||||
[disabled]="pageRenderOrder.length <= 1">
|
||||
<i class="fas fa-trash"></i>
|
||||
Delete Current Page
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Additional Tools Section -->
|
||||
<div class="control-section fade-in-up" [@fadeIn]>
|
||||
<h3>
|
||||
<i class="fas fa-tools" style="margin-right: 6px; color: #6f42c1;"></i>
|
||||
Additional Tools
|
||||
</h3>
|
||||
|
||||
<button class="action-btn secondary" (click)="exportProject()">
|
||||
<i class="fas fa-download"></i>
|
||||
Export Project
|
||||
</button>
|
||||
|
||||
<button class="action-btn secondary" (click)="importProject()">
|
||||
<i class="fas fa-upload"></i>
|
||||
Import Project
|
||||
</button>
|
||||
|
||||
<button class="action-btn secondary" (click)="previewMode()">
|
||||
<i class="fas fa-eye"></i>
|
||||
Preview Mode
|
||||
</button>
|
||||
|
||||
<button class="action-btn secondary" (click)="addNewSectionToCurrentPage()">
|
||||
<i class="fas fa-plus-square"></i>
|
||||
Add Section
|
||||
</button>
|
||||
</div>
|
||||
<button class="action-btn primary full-width" (click)="applyStyleToSelection()">
|
||||
<i class="fas fa-paint-brush"></i>
|
||||
Apply Style to Selection
|
||||
</button>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<!--
|
||||
<div class="control-section fade-in-up" [@fadeIn]>
|
||||
<h3>
|
||||
<i class="fas fa-file-alt" style="margin-right: 6px; color: #dc3545;"></i>
|
||||
Page Management
|
||||
</h3>
|
||||
|
||||
<button class="action-btn secondary" (click)="addNewPage()">
|
||||
<i class="fas fa-plus"></i>
|
||||
Add New Page
|
||||
</button>
|
||||
|
||||
<button class="action-btn secondary" (click)="duplicateCurrentPage()">
|
||||
<i class="fas fa-copy"></i>
|
||||
Duplicate Current Page
|
||||
</button>
|
||||
|
||||
<button class="action-btn secondary" (click)="deleteCurrentPage()"
|
||||
[disabled]="pageRenderOrder.length <= 1">
|
||||
<i class="fas fa-trash"></i>
|
||||
Delete Current Page
|
||||
</button>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<!--
|
||||
<div class="control-section fade-in-up" [@fadeIn]>
|
||||
<h3>
|
||||
<i class="fas fa-tools" style="margin-right: 6px; color: #6f42c1;"></i>
|
||||
Additional Tools
|
||||
</h3>
|
||||
|
||||
<button class="action-btn secondary" (click)="exportProject()">
|
||||
<i class="fas fa-download"></i>
|
||||
Export Project
|
||||
</button>
|
||||
|
||||
<button class="action-btn secondary" (click)="importProject()">
|
||||
<i class="fas fa-upload"></i>
|
||||
Import Project
|
||||
</button>
|
||||
|
||||
<button class="action-btn secondary" (click)="previewMode()">
|
||||
<i class="fas fa-eye"></i>
|
||||
Preview Mode
|
||||
</button>
|
||||
|
||||
<button class="action-btn secondary" (click)="addNewSectionToCurrentPage()">
|
||||
<i class="fas fa-plus-square"></i>
|
||||
Add Section
|
||||
</button>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Canvas Area -->
|
||||
<div class="canvas-main-area" [class.sidebar-collapsed]="sidebarCollapsed">
|
||||
@ -357,61 +436,63 @@
|
||||
(wheel)="onWheel($event)">
|
||||
|
||||
<!-- Loading Overlay -->
|
||||
<div *ngIf="isLoading" class="loading-overlay">
|
||||
<div class="spinner"></div>
|
||||
<div class="loading-text">Loading wireframe...</div>
|
||||
</div>
|
||||
<!-- Updated Loading Overlay -->
|
||||
<div *ngIf="isLoading" class="loading-overlay" [@fadeIn]>
|
||||
<div class="loading-container">
|
||||
<mat-spinner diameter="50" color="accent"></mat-spinner>
|
||||
<div class="loading-text">Building Interface...</div>
|
||||
<div class="loading-subtext">Please wait while we prepare your components</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" [style.width.%]="loadProgress"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Full Page Display -->
|
||||
<div *ngIf="!isLoading && getCurrentPage()"
|
||||
<div *ngIf="!isLoading "
|
||||
class="page-display"
|
||||
[style.transform]="getPageTransform()">
|
||||
|
||||
<!-- Connected Sections Container -->
|
||||
<div class="connected-sections"
|
||||
cdkDropList
|
||||
cdkDropListOrientation="vertical"
|
||||
[cdkDropListData]="getCurrentPageSections()"
|
||||
(cdkDropListDropped)="onSectionDrop($event, getCurrentPageName())">
|
||||
<!-- Update your section template -->
|
||||
<div class="connected-sections"
|
||||
cdkDropList
|
||||
[cdkDropListData]="getCurrentPageSections()"
|
||||
[cdkDropListConnectedTo]="allConnectedLists"
|
||||
(cdkDropListDropped)="onSectionDrop($event)">
|
||||
|
||||
<div *ngFor="let sectionKey of getCurrentPageSections()"
|
||||
cdkDrag
|
||||
[cdkDragData]="sectionKey"
|
||||
class="section-wrapper"
|
||||
#dragItem>
|
||||
|
||||
<!-- Drag Handle -->
|
||||
<div class="drag-handle" cdkDragHandle>
|
||||
<i class="fas fa-grip-vertical"></i>
|
||||
<div style="height: 16px !important;"></div>
|
||||
</div>
|
||||
|
||||
<!-- Individual Connected Sections -->
|
||||
<!-- Change this in your *ngFor -->
|
||||
<!-- Update the section wrapper div -->
|
||||
<div *ngFor="let sectionKey of getCurrentPageSections(); let i = index"
|
||||
class="section-wrapper"
|
||||
[class.editing]="isCurrentSectionEditing(sectionKey)"
|
||||
cdkDrag
|
||||
[cdkDragData]="sectionKey"
|
||||
(mouseenter)="hoveredSection = sectionKey"
|
||||
(mouseleave)="hoveredSection = null"
|
||||
(dblclick)="toggleSectionEditing(getCurrentPageName(), sectionKey, $event)">
|
||||
|
||||
<!-- Section Content (Full Width, No Gaps) -->
|
||||
<div class="section-content"
|
||||
[innerHTML]="getSectionHtml(getCurrentPageName(), sectionKey)"
|
||||
[attr.contenteditable]="isCurrentSectionEditing(sectionKey)"
|
||||
(blur)="handleDirectContentEdit($event, getCurrentPageName(), sectionKey)">
|
||||
</div>
|
||||
|
||||
<!-- Section Overlay for Hover/Edit State -->
|
||||
<div class="section-overlay"
|
||||
[class.visible]="hoveredSection === sectionKey || isCurrentSectionEditing(sectionKey)">
|
||||
<div class="section-label">
|
||||
<i class="fas fa-puzzle-piece" style="margin-right: 4px;"></i>
|
||||
{{ sectionKey }}
|
||||
<button *ngIf="isCurrentSectionEditing(sectionKey)"
|
||||
class="btn btn-sm btn-success ms-2"
|
||||
(click)="saveSectionEdit(getCurrentPageName(), sectionKey)">
|
||||
<i class="fas fa-check"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Section Content -->
|
||||
<div class="section-content"
|
||||
[innerHTML]="getSectionHtml(getCurrentPageName(), sectionKey)"
|
||||
[attr.contenteditable]="isCurrentSectionEditing(sectionKey)"
|
||||
(blur)="handleDirectContentEdit($event, getCurrentPageName(), sectionKey)">
|
||||
</div>
|
||||
|
||||
<!-- Section Overlay -->
|
||||
<div class="section-overlay" *ngIf="!isCurrentSectionEditing(sectionKey)">
|
||||
<div class="section-label">{{sectionKey}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Drag Handle -->
|
||||
<div class="drag-handle" cdkDragHandle style="display: none;">
|
||||
<!-- <div class="drag-handle" cdkDragHandle style="display: none;">
|
||||
<i class="fa fa-grip-lines"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- Empty State for Sections -->
|
||||
<div *ngIf="getCurrentPageSections().length === 0" class="empty-sections"
|
||||
@ -493,124 +574,146 @@
|
||||
</button>
|
||||
|
||||
<!-- Navbar Editor Modal -->
|
||||
<div class="modal-overlay" *ngIf="selectedNavbarPage" [@fadeIn] (click)="closeNavbarModal()">
|
||||
<div class="modal-content" (click)="$event.stopPropagation()" [@slideIn]>
|
||||
|
||||
<div class="modal-header">
|
||||
<h3>
|
||||
<i class="fas fa-edit" style="margin-right: 8px; color: #17a2b8;"></i>
|
||||
Edit Navbar Links - {{ selectedNavbarPage }}
|
||||
</h3>
|
||||
<button class="close-btn" (click)="closeNavbarModal()">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
|
||||
<!-- Updated Navbar Editor Modal -->
|
||||
<div class="modal-overlay" *ngIf="showNavbarEditorModal" [@fadeIn] (click)="closeNavbarEditorModal()">
|
||||
<div class="modal-content navbar-editor-modal" (click)="$event.stopPropagation()" [@slideIn]>
|
||||
|
||||
<div class="modal-header">
|
||||
<h3>
|
||||
<i class="fas fa-bars" style="margin-right: 8px; color: #17a2b8;"></i>
|
||||
Navbar Editor
|
||||
</h3>
|
||||
<button class="close-btn" (click)="closeNavbarEditorModal()">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<!-- Page Selection -->
|
||||
<div class="form-group">
|
||||
<label for="navbarPageSelect">Select Page:</label>
|
||||
<select id="navbarPageSelect" class="form-control" [(ngModel)]="selectedNavbarPage"
|
||||
(change)="onNavbarPageChange()"
|
||||
[@focusBorder]>
|
||||
<option value="">Choose a page...</option>
|
||||
<option *ngFor="let page of pageRenderOrder" [value]="page">
|
||||
<i class="fas fa-file-alt"></i> {{ page }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<div class="navbar-link-item" *ngFor="let link of navbarLinks[selectedNavbarPage]; let i = index" [@fadeIn]
|
||||
style="display: flex; gap: 10px; align-items: center; margin-bottom: 15px; padding: 15px; background: #f8f9fa; border-radius: 8px;">
|
||||
<div class="form-group" style="flex: 1; margin-bottom: 0;">
|
||||
<input type="text" [(ngModel)]="link.label" placeholder="Link Label" class="form-control">
|
||||
<!-- Navbar Links -->
|
||||
<div *ngIf="selectedNavbarPage" class="navbar-links-section">
|
||||
<h4>Navbar Links</h4>
|
||||
<div class="navbar-link-item" *ngFor="let link of currentNavbarLinks; let i = index" [@fadeIn]>
|
||||
<div class="link-inputs">
|
||||
<div class="form-group">
|
||||
<label>Link Text:</label>
|
||||
<input type="text" [(ngModel)]="link.label" placeholder="Link Label" class="form-control">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Link URL:</label>
|
||||
<select [(ngModel)]="link.href" class="form-control">
|
||||
<option value="">Select page...</option>
|
||||
<option *ngFor="let page of availablePages" [value]="page.href">{{ page.label }}</option>
|
||||
<option value="custom">Custom URL...</option>
|
||||
</select>
|
||||
<input *ngIf="link.href === 'custom'" type="text" [(ngModel)]="link.customUrl"
|
||||
placeholder="Enter custom URL" class="form-control mt-2">
|
||||
</div>
|
||||
<button class="remove-btn" (click)="removeNavbarLink(i)" title="Remove Link">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="form-group" style="flex: 1; margin-bottom: 0;">
|
||||
<select [(ngModel)]="link.href" class="form-control">
|
||||
<option value="">Select page...</option>
|
||||
<option *ngFor="let page of availablePages" [value]="page.href">{{ page.label }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<button class="remove-btn" (click)="removeLink(selectedNavbarPage, i)" title="Remove Link"
|
||||
style="background: #dc3545; color: white; border: none; padding: 8px 12px; border-radius: 6px; cursor: pointer;">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button class="action-btn secondary full-width add-link-btn" (click)="addLink(selectedNavbarPage)">
|
||||
<button class="action-btn secondary full-width" (click)="addNavbarLink()">
|
||||
<i class="fas fa-plus"></i>
|
||||
Add New Link
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="action-btn secondary" (click)="closeNavbarModal()">
|
||||
<i class="fas fa-times" style="margin-right: 5px;"></i>
|
||||
Cancel
|
||||
</button>
|
||||
<button class="action-btn primary" (click)="applyNavbarChanges(selectedNavbarPage)">
|
||||
<i class="fas fa-check" style="margin-right: 5px;"></i>
|
||||
Save Changes
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="action-btn secondary" (click)="closeNavbarEditorModal()">
|
||||
<i class="fas fa-times" style="margin-right: 5px;"></i>
|
||||
Cancel
|
||||
</button>
|
||||
<button class="action-btn primary" (click)="saveNavbarChanges()">
|
||||
<i class="fas fa-check" style="margin-right: 5px;"></i>
|
||||
Save Changes
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal for Adding New Section -->
|
||||
<div class="modal-overlay" *ngIf="showNewSectionModal" [@fadeIn] (click)="closeNewSectionModal()">
|
||||
<div class="modal-content" (click)="$event.stopPropagation()" [@slideIn]>
|
||||
|
||||
<div class="modal-header">
|
||||
<h3>
|
||||
<i class="fas fa-plus-circle" style="margin-right: 8px; color: #28a745;"></i>
|
||||
Add New Section to {{ newSectionPage }}
|
||||
</h3>
|
||||
<button class="close-btn" (click)="closeNewSectionModal()">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
<!-- Add Custom Section Modal -->
|
||||
<div class="modal-overlay" *ngIf="showAddCustomModal" [@fadeIn] (click)="closeAddCustomModal()">
|
||||
<div class="modal-content" (click)="$event.stopPropagation()" [@slideIn]>
|
||||
|
||||
<div class="modal-header">
|
||||
<h3>
|
||||
<i class="fas fa-plus-circle" style="margin-right: 8px; color: #28a745;"></i>
|
||||
Add Custom Section
|
||||
</h3>
|
||||
<button class="close-btn" (click)="closeAddCustomModal()">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="customSectionName">
|
||||
<i class="fas fa-tag" style="margin-right: 4px;"></i>
|
||||
Section Name:
|
||||
</label>
|
||||
<input id="customSectionName"
|
||||
type="text"
|
||||
[(ngModel)]="newCustomSectionName"
|
||||
placeholder="Enter section name (e.g., Custom Header, Special CTA)"
|
||||
class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label for="sectionName">
|
||||
<i class="fas fa-tag" style="margin-right: 4px;"></i>
|
||||
Section Name:
|
||||
</label>
|
||||
<input id="sectionName"
|
||||
type="text"
|
||||
[(ngModel)]="newSectionName"
|
||||
placeholder="Enter section name (e.g., Hero, About, Contact)"
|
||||
class="form-control">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="sectionType">
|
||||
<i class="fas fa-layer-group" style="margin-right: 4px;"></i>
|
||||
Section Type:
|
||||
</label>
|
||||
<select id="sectionType" [(ngModel)]="newSectionType" class="form-control">
|
||||
<option value="">Select a type...</option>
|
||||
<option *ngFor="let type of sectionTypes" [value]="type.value">
|
||||
{{ type.label }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="sectionDescription">
|
||||
<i class="fas fa-align-left" style="margin-right: 4px;"></i>
|
||||
Section Description:
|
||||
</label>
|
||||
<textarea id="sectionDescription"
|
||||
[(ngModel)]="newSectionDescription"
|
||||
rows="4"
|
||||
placeholder="Describe the content and purpose of this section..."
|
||||
class="form-control"></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="customSectionDesc">
|
||||
<i class="fas fa-align-left" style="margin-right: 4px;"></i>
|
||||
Section Description:
|
||||
</label>
|
||||
<textarea id="customSectionDesc"
|
||||
[(ngModel)]="newCustomSectionDesc"
|
||||
rows="4"
|
||||
placeholder="Describe the content and purpose of this custom section..."
|
||||
class="form-control"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="action-btn secondary" (click)="closeNewSectionModal()">
|
||||
<i class="fas fa-times" style="margin-right: 5px;"></i>
|
||||
Cancel
|
||||
</button>
|
||||
<button class="action-btn primary"
|
||||
[disabled]="!newSectionName || !newSectionType"
|
||||
(click)="confirmAddSection()">
|
||||
<i class="fas fa-plus" style="margin-right: 5px;"></i>
|
||||
Add Section
|
||||
</button>
|
||||
<div class="form-group">
|
||||
<label for="customSectionIcon">
|
||||
<i class="fas fa-icons" style="margin-right: 4px;"></i>
|
||||
Icon Class:
|
||||
</label>
|
||||
<input id="customSectionIcon"
|
||||
type="text"
|
||||
[(ngModel)]="newCustomSectionIcon"
|
||||
placeholder="e.g., fas fa-star, fas fa-rocket"
|
||||
class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="action-btn secondary" (click)="closeAddCustomModal()">
|
||||
<i class="fas fa-times" style="margin-right: 5px;"></i>
|
||||
Cancel
|
||||
</button>
|
||||
<button class="action-btn primary"
|
||||
[disabled]="!newCustomSectionName || !newCustomSectionDesc"
|
||||
(click)="confirmAddCustomSection()">
|
||||
<i class="fas fa-plus" style="margin-right: 5px;"></i>
|
||||
Add Custom Section
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Modal for Adding New Page -->
|
||||
<div class="modal-overlay" *ngIf="showNewPageModal" [@fadeIn] (click)="closeNewPageModal()">
|
||||
<div class="modal-content" (click)="$event.stopPropagation()" [@slideIn]>
|
||||
|
||||
@ -149,6 +149,8 @@ $shadow-heavy: 0 8px 25px rgba(0, 0, 0, 0.15);
|
||||
top: 0 ;
|
||||
z-index: 10 ;
|
||||
backdrop-filter: blur(10px) ;
|
||||
display: flex ;
|
||||
flex-direction: row;
|
||||
|
||||
h2 {
|
||||
margin: 0 ;
|
||||
@ -374,6 +376,129 @@ $shadow-heavy: 0 8px 25px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
}
|
||||
}
|
||||
.wf-section-list {
|
||||
max-height: 300px !important;
|
||||
overflow-y: auto !important;
|
||||
margin: 12px 0 !important;
|
||||
border: 1px solid #e9ecef !important;
|
||||
border-radius: 8px !important;
|
||||
padding: 8px !important;
|
||||
background: #ffffff !important;
|
||||
|
||||
.wf-section-item {
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
padding: 12px !important;
|
||||
margin-bottom: 8px !important;
|
||||
border: 1px solid #e9ecef !important;
|
||||
border-radius: 8px !important;
|
||||
cursor: pointer !important;
|
||||
transition: all 0.2s ease !important;
|
||||
position: relative !important;
|
||||
background: #f8f9fa !important;
|
||||
|
||||
&:hover {
|
||||
border-color: #007bff !important;
|
||||
background-color: #ffffff !important;
|
||||
transform: translateY(-2px) !important;
|
||||
box-shadow: 0 3px 6px rgba(0,0,0,0.1) !important;
|
||||
}
|
||||
|
||||
.section-icon {
|
||||
width: 40px !important;
|
||||
height: 40px !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
background: #ffffff !important;
|
||||
border-radius: 6px !important;
|
||||
margin-right: 12px !important;
|
||||
border: 1px solid #dee2e6 !important;
|
||||
|
||||
i {
|
||||
font-size: 18px !important;
|
||||
color: #007bff !important;
|
||||
}
|
||||
}
|
||||
|
||||
.section-info {
|
||||
flex: 1 !important;
|
||||
|
||||
.section-name {
|
||||
font-weight: 600 !important;
|
||||
font-size: 14px !important;
|
||||
color: #2c3e50 !important;
|
||||
margin-bottom: 4px !important;
|
||||
}
|
||||
|
||||
.section-desc {
|
||||
font-size: 12px !important;
|
||||
color: #7f8c8d !important;
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.delete-custom-btn {
|
||||
position: absolute !important;
|
||||
top: 50% !important;
|
||||
right: 12px !important;
|
||||
transform: translateY(-50%) !important;
|
||||
width: 28px !important;
|
||||
height: 28px !important;
|
||||
border: none !important;
|
||||
background: #dc3545 !important;
|
||||
color: white !important;
|
||||
border-radius: 50% !important;
|
||||
display: none !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
cursor: pointer !important;
|
||||
transition: background 0.2s ease !important;
|
||||
|
||||
&:hover {
|
||||
background: #c82333 !important;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover .delete-custom-btn {
|
||||
display: flex !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Custom Section for adding new sections
|
||||
.add-custom-section {
|
||||
display: flex ;
|
||||
align-items: center ;
|
||||
gap: 12px ;
|
||||
margin-top: 20px ;
|
||||
padding: 12px ;
|
||||
background: rgba(255, 255, 255, 0.9) ;
|
||||
border-radius: 8px ;
|
||||
box-shadow: $shadow-light ;
|
||||
transition: $transition-smooth ;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px) ;
|
||||
box-shadow: $shadow-medium ;
|
||||
}
|
||||
|
||||
.add-icon {
|
||||
font-size: 24px ;
|
||||
color: $primary-black ;
|
||||
cursor: pointer ;
|
||||
|
||||
&:hover {
|
||||
color: $secondary-black ;
|
||||
}
|
||||
}
|
||||
|
||||
.add-text {
|
||||
font-size: 14px ;
|
||||
color: $text-gray ;
|
||||
font-weight: 600 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -412,6 +537,62 @@ $shadow-heavy: 0 8px 25px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
}
|
||||
|
||||
/* Enhanced Loading Styles */
|
||||
.loading-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
backdrop-filter: blur(5px);
|
||||
|
||||
.loading-container {
|
||||
text-align: center;
|
||||
max-width: 400px;
|
||||
padding: 2rem;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
|
||||
|
||||
.loading-text {
|
||||
font-size: 1.2rem;
|
||||
color: #333;
|
||||
margin: 1rem 0 0.5rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.loading-subtext {
|
||||
color: #666;
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 100%;
|
||||
height: 8px;
|
||||
background: #f0f0f0;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
background: #2196F3;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
}
|
||||
|
||||
mat-spinner {
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Main Canvas Area
|
||||
.canvas-main-area {
|
||||
position: relative ;
|
||||
@ -537,6 +718,110 @@ $shadow-heavy: 0 8px 25px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
}
|
||||
}
|
||||
.search-section {
|
||||
.search-container {
|
||||
position: relative;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.search-input {
|
||||
width: 100%;
|
||||
padding: 12px 40px 12px 15px;
|
||||
border: 2px solid #e9ecef;
|
||||
border-radius: 25px;
|
||||
font-size: 14px;
|
||||
transition: all 0.3s ease;
|
||||
background: #f8f9fa;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
border-color: #007bff;
|
||||
background: white;
|
||||
box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.1);
|
||||
}
|
||||
|
||||
&::placeholder {
|
||||
color: #6c757d;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: #6c757d;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.navbar-editor-modal {
|
||||
max-width: 600px;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
|
||||
.navbar-links-section {
|
||||
margin-top: 20px;
|
||||
|
||||
h4 {
|
||||
margin-bottom: 15px;
|
||||
color: #333;
|
||||
border-bottom: 1px solid #e9ecef;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.navbar-link-item {
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
position: relative;
|
||||
|
||||
.link-inputs {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr auto;
|
||||
gap: 15px;
|
||||
align-items: end;
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 0;
|
||||
|
||||
label {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #666;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.remove-btn {
|
||||
background: #dc3545;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 12px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
height: fit-content;
|
||||
|
||||
&:hover {
|
||||
background: #c82333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.add-custom-section {
|
||||
margin-top: 15px;
|
||||
padding-top: 15px;
|
||||
border-top: 1px dashed #dee2e6;
|
||||
}
|
||||
|
||||
.page-actions {
|
||||
position: fixed;
|
||||
@ -1035,4 +1320,140 @@ $shadow-heavy: 0 8px 25px rgba(0, 0, 0, 0.15);
|
||||
i {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Add these styles */
|
||||
.loading-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(255,255,255,0.9);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.hide-scroll {
|
||||
overflow: hidden;
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.section-loading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.page-list {
|
||||
max-height: 60vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
|
||||
.page-list {
|
||||
border: 1px solid #eee;
|
||||
border-radius: 8px;
|
||||
padding: 8px;
|
||||
margin: 12px 0;
|
||||
|
||||
&-item {
|
||||
padding: 12px;
|
||||
margin: 6px 0;
|
||||
background: #f8f9fa;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
transition: transform 0.2s ease;
|
||||
|
||||
.handle {
|
||||
cursor: move;
|
||||
margin-right: 8px;
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: #e9ecef;
|
||||
}
|
||||
|
||||
&.cdk-drag-preview {
|
||||
background: white;
|
||||
box-shadow: 0 3px 10px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
&.cdk-drag-placeholder {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
&.cdk-drag-animating {
|
||||
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cdk-drop-list-dragging .page-list-item:not(.cdk-drag-placeholder) {
|
||||
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
|
||||
/* Add to your styles */
|
||||
.connected-sections {
|
||||
min-height: 100px;
|
||||
position: relative;
|
||||
}
|
||||
/* Add these styles */
|
||||
.drag-handle {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 30px;
|
||||
background: rgba(224, 221, 221, 0.05);
|
||||
cursor: grab;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10;
|
||||
transition: background 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0,0,0,0.08);
|
||||
}
|
||||
|
||||
.fa-grip-vertical {
|
||||
opacity: 0.5;
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
}
|
||||
|
||||
.cdk-drag-preview {
|
||||
cursor: grabbing !important;
|
||||
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
|
||||
opacity: 0.8;
|
||||
|
||||
.drag-handle {
|
||||
cursor: grabbing !important;
|
||||
}
|
||||
}
|
||||
|
||||
.cdk-drag-placeholder {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.cdk-drag-animating {
|
||||
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.connected-sections.cdk-drop-list-dragging .section-wrapper:not(.cdk-drag-placeholder) {
|
||||
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -160,58 +160,58 @@ export class TreeVisualizerComponent {
|
||||
// Call the actual generateJson method
|
||||
|
||||
const prompt = `
|
||||
You are a JSON structure generator for website UI and sitemap hierarchy.
|
||||
You are a JSON structure generator for website UI and sitemap hierarchy.
|
||||
|
||||
Your task is to generate a strictly hierarchical JSON tree that represents the full page flow of a website. The root of the tree must always be the "Home" page. Other pages (like Login, Sign Up, Dashboard, etc.) must be nested logically using a "Children" key — never flatten the structure.
|
||||
Your task is to generate a strictly hierarchical JSON tree that represents the full page flow of a website. The root of the tree must always be the "Home" page. Other pages (like Login, Sign Up, Dashboard, etc.) must be nested logically using a "Children" key — never flatten the structure.
|
||||
|
||||
Each page must contain:
|
||||
Each page must contain:
|
||||
|
||||
- 4 to 5 meaningful UI sections (e.g., "Header Section", "Form Section", "Feature Section", etc.)
|
||||
- A "Navbar" and a "Footer" section (always included on every page)
|
||||
- A short, clear description for each section (to support frontend development)
|
||||
- 4 to 5 meaningful UI sections (e.g., "Header Section", "Form Section", "Feature Section", etc.)
|
||||
- A "Navbar" and a "Footer" section (always included on every page)
|
||||
- A short, clear description for each section (to support frontend development)
|
||||
|
||||
Constraints:
|
||||
- Total number of pages (including nested children) must be between ${this.selectedPageRange}
|
||||
- Do NOT create unnecessary or generic pages (e.g., no "Blog", "FAQ", etc.) unless explicitly present in the user flow
|
||||
- Pages that appear after user actions (e.g., clicking a card or after login) must be nested under the relevant parent using a "Children" key
|
||||
- DO NOT include any standalone section like "FAQ" or "Blog" as top-level pages unless mentioned
|
||||
Constraints:
|
||||
- Total number of pages (including nested children) must be between ${this.selectedPageRange}
|
||||
- Do NOT create unnecessary or generic pages (e.g., no "Blog", "FAQ", etc.) unless explicitly present in the user flow
|
||||
- Pages that appear after user actions (e.g., clicking a card or after login) must be nested under the relevant parent using a "Children" key
|
||||
- DO NOT include any standalone section like "FAQ" or "Blog" as top-level pages unless mentioned
|
||||
|
||||
📘 Website Context:
|
||||
${this.rawInputText}
|
||||
📘 Website Context:
|
||||
${this.rawInputText}
|
||||
|
||||
|
||||
|
||||
--- Reference Format (DO NOT COPY; for structure only) ---
|
||||
{
|
||||
"Home": {
|
||||
"Navbar": "...",
|
||||
"Header Section": "...",
|
||||
"Feature Section": "...",
|
||||
"Footer": "...",
|
||||
"Children": {
|
||||
"About": {
|
||||
--- Reference Format (DO NOT COPY; for structure only) ---
|
||||
{
|
||||
"Home": {
|
||||
"Navbar": "...",
|
||||
"Header Section": "...",
|
||||
"Feature Section": "...",
|
||||
"Footer": "...",
|
||||
"Children": {
|
||||
"About": {
|
||||
"Navbar": "...",
|
||||
"Header Section": "...",
|
||||
"Footer": "..."
|
||||
}
|
||||
}
|
||||
},
|
||||
"Services": {
|
||||
"Navbar": "...",
|
||||
"Content Section": "...",
|
||||
"Footer": "..."
|
||||
}
|
||||
}
|
||||
},
|
||||
"Services": {
|
||||
"Navbar": "...",
|
||||
"Content Section": "...",
|
||||
"Footer": "..."
|
||||
}
|
||||
}
|
||||
---
|
||||
---
|
||||
|
||||
🚫 DO NOT:
|
||||
- Include any explanation, notes, comments, or formatting (like \`\`\` or \`json\`)
|
||||
- Do NOT return escaped or markdown-formatted JSON
|
||||
- Do NOT wrap the output inside code blocks
|
||||
- Do NOT return anything except plain raw JSON
|
||||
🚫 DO NOT:
|
||||
- Include any explanation, notes, comments, or formatting (like \`\`\` or \`json\`)
|
||||
- Do NOT return escaped or markdown-formatted JSON
|
||||
- Do NOT wrap the output inside code blocks
|
||||
- Do NOT return anything except plain raw JSON
|
||||
|
||||
📤 Output ONLY the final JSON structure — nothing more.
|
||||
`;
|
||||
📤 Output ONLY the final JSON structure — nothing more.
|
||||
`;
|
||||
|
||||
const payload = {
|
||||
// query: this.rawInputText + ' \n ' + suffix,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user