@@ -7,6 +7,16 @@ window.addEventListener('load', () => {
77 let activeIndex = null ;
88 const layoutSelect = document . getElementById ( 'layout-select' ) ;
99 let currentLayout = layoutSelect ? layoutSelect . value : 'single-column' ;
10+ const pageEditor = document . querySelector ( '.page-editor' ) ;
11+ const previewWrapper = document . getElementById ( 'preview-wrapper' ) ;
12+ const previewFrame = document . getElementById ( 'preview-frame' ) ;
13+ const unsavedIndicator = document . getElementById ( 'unsaved-indicator' ) ;
14+ const modeEdit = document . getElementById ( 'mode-edit' ) ;
15+ const modePreview = document . getElementById ( 'mode-preview' ) ;
16+ const deviceBtns = document . querySelectorAll ( '.device-btn' ) ;
17+ const previewContainer = document . getElementById ( 'preview-container' ) ;
18+ let dirty = false ;
19+ let previewTimer = null ;
1020
1121 function buildGroups ( ) {
1222 container . innerHTML = '' ;
@@ -32,6 +42,53 @@ window.addEventListener('load', () => {
3242 } ) ;
3343 }
3444
45+ function collectData ( ) {
46+ const zones = { } ;
47+ document . querySelectorAll ( '.zone-group' ) . forEach ( g => {
48+ const zone = g . dataset . zone ;
49+ const html = Array . from ( g . querySelectorAll ( '.section-editor' ) ) . map ( sec => {
50+ const idx = sec . dataset . index ;
51+ const typeSel = document . getElementById ( `type-select-${ idx } ` ) ;
52+ if ( typeSel && typeSel . value === 'Html' ) {
53+ return editors [ idx ] . root . innerHTML ;
54+ }
55+ const inp = document . getElementById ( `Html-${ idx } ` ) ;
56+ return inp ? inp . value : '' ;
57+ } ) . join ( '\n' ) ;
58+ zones [ zone ] = html ;
59+ } ) ;
60+ return {
61+ layout : layoutSelect ? layoutSelect . value : 'single-column' ,
62+ title : document . getElementById ( 'title-input' ) ?. value || '' ,
63+ zones
64+ } ;
65+ }
66+
67+ function renderPreview ( ) {
68+ const data = collectData ( ) ;
69+ fetch ( '/AdminContent/Preview' , {
70+ method : 'POST' ,
71+ headers : {
72+ 'Content-Type' : 'application/json' ,
73+ 'RequestVerificationToken' : document . querySelector ( 'input[name="__RequestVerificationToken"]' ) . value
74+ } ,
75+ body : JSON . stringify ( data )
76+ } )
77+ . then ( r => r . text ( ) )
78+ . then ( html => {
79+ if ( previewFrame ) previewFrame . srcdoc = html ;
80+ dirty = false ;
81+ if ( unsavedIndicator ) unsavedIndicator . style . display = 'none' ;
82+ } ) ;
83+ }
84+
85+ function schedulePreview ( ) {
86+ dirty = true ;
87+ if ( unsavedIndicator ) unsavedIndicator . style . display = 'inline' ;
88+ clearTimeout ( previewTimer ) ;
89+ previewTimer = setTimeout ( renderPreview , 300 ) ;
90+ }
91+
3592 function populateZones ( select ) {
3693 if ( ! select ) return ;
3794 const current = select . dataset . selected || select . value ;
@@ -322,6 +379,7 @@ window.addEventListener('load', () => {
322379 quill . root . addEventListener ( 'click' , ( ) => { activeIndex = index ; } ) ;
323380 quill . root . addEventListener ( 'focus' , ( ) => { activeIndex = index ; } ) ;
324381 editors [ index ] = quill ;
382+ quill . on ( 'text-change' , schedulePreview ) ;
325383
326384 function update ( ) {
327385 const type = typeSelect . value ;
@@ -338,4 +396,28 @@ window.addEventListener('load', () => {
338396 update ( ) ;
339397 typeSelect . addEventListener ( 'change' , update ) ;
340398 }
399+
400+ modePreview ?. addEventListener ( 'click' , ( ) => {
401+ pageEditor ?. classList . add ( 'preview' ) ;
402+ renderPreview ( ) ;
403+ } ) ;
404+
405+ modeEdit ?. addEventListener ( 'click' , ( ) => {
406+ pageEditor ?. classList . remove ( 'preview' ) ;
407+ } ) ;
408+
409+ deviceBtns . forEach ( btn => {
410+ btn . addEventListener ( 'click' , ( ) => {
411+ deviceBtns . forEach ( b => b . classList . remove ( 'active' ) ) ;
412+ btn . classList . add ( 'active' ) ;
413+ if ( previewContainer ) previewContainer . style . width = btn . dataset . width ;
414+ } ) ;
415+ } ) ;
416+
417+ document . querySelector ( '.editor-main' ) ?. addEventListener ( 'input' , schedulePreview ) ;
418+ document . querySelector ( '.editor-main' ) ?. addEventListener ( 'change' , schedulePreview ) ;
419+ form ?. addEventListener ( 'submit' , ( ) => {
420+ dirty = false ;
421+ if ( unsavedIndicator ) unsavedIndicator . style . display = 'none' ;
422+ } ) ;
341423} ) ;
0 commit comments