LPX55 commited on
Commit
a8df01d
Β·
verified Β·
1 Parent(s): 26ae541

🐳 12/03 - 06:48 - add new slide layout: comparison table

Browse files
Files changed (1) hide show
  1. editor.html +153 -0
editor.html CHANGED
@@ -145,6 +145,10 @@
145
  <i data-lucide="layout-grid" class="w-4 h-4"></i>
146
  Grid
147
  </button>
 
 
 
 
148
  </div>
149
 
150
  <!-- View Toggle -->
@@ -359,6 +363,14 @@
359
  this.slides[this.currentSlide].imageTitle = 'Image Slide';
360
  this.slides[this.currentSlide].image = 'technology';
361
  }
 
 
 
 
 
 
 
 
362
 
363
  this.renderEditor();
364
  this.updatePreview();
@@ -584,6 +596,51 @@
584
  </div>
585
  </div>
586
  `;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
587
  }
588
 
589
  html += `</div>`;
@@ -596,6 +653,40 @@
596
  this.updatePreview();
597
  }
598
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
599
  validateJSON(jsonString) {
600
  // Skip validation if paused (but still track for manual validation)
601
  if (this.validationPaused) {
@@ -742,6 +833,36 @@
742
  </div>
743
  </div>
744
  `;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
745
  }
746
 
747
  preview.innerHTML = content;
@@ -826,6 +947,38 @@
826
  </div>
827
  </div>
828
  `;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
829
  }
830
 
831
  container.innerHTML = content;
 
145
  <i data-lucide="layout-grid" class="w-4 h-4"></i>
146
  Grid
147
  </button>
148
+ <button onclick="editor.setLayout('comparison')" class="tool-btn px-3 py-1.5 rounded-md text-sm font-medium text-gray-700 flex items-center gap-1" data-layout="comparison">
149
+ <i data-lucide="table" class="w-4 h-4"></i>
150
+ Compare
151
+ </button>
152
  </div>
153
 
154
  <!-- View Toggle -->
 
363
  this.slides[this.currentSlide].imageTitle = 'Image Slide';
364
  this.slides[this.currentSlide].image = 'technology';
365
  }
366
+ if (layout === 'comparison' && !this.slides[this.currentSlide].columns) {
367
+ this.slides[this.currentSlide].columns = ['Feature', 'Our Solution', 'Competitors'];
368
+ this.slides[this.currentSlide].rows = [
369
+ { feature: 'Performance', col1: 'βœ“ Superior', col2: 'βœ— Limited' },
370
+ { feature: 'Pricing', col1: 'βœ“ Affordable', col2: 'βœ— Expensive' },
371
+ { feature: 'Support', col1: 'βœ“ 24/7', col2: 'βœ— Business hours' }
372
+ ];
373
+ }
374
 
375
  this.renderEditor();
376
  this.updatePreview();
 
596
  </div>
597
  </div>
598
  `;
599
+ } else if (slide.layout === 'comparison') {
600
+ html += `
601
+ <div class="col-span-2">
602
+ <label class="block text-sm font-medium text-gray-700 mb-1">Subtitle</label>
603
+ <input type="text" value="${slide.subtitle || ''}"
604
+ oninput="editor.updateField('subtitle', this.value)"
605
+ class="editor-input w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 outline-none">
606
+ </div>
607
+ <div class="col-span-2">
608
+ <label class="block text-sm font-medium text-gray-700 mb-2">Column Headers</label>
609
+ <div class="grid grid-cols-3 gap-3">
610
+ ${(slide.columns || ['Feature', 'Our Solution', 'Competitors']).map((col, i) => `
611
+ <input type="text" value="${col}"
612
+ oninput="editor.updateColumn(${i}, this.value)"
613
+ class="editor-input w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 outline-none">
614
+ `).join('')}
615
+ </div>
616
+ </div>
617
+ <div class="col-span-2">
618
+ <div class="flex items-center justify-between mb-2">
619
+ <label class="block text-sm font-medium text-gray-700">Comparison Rows</label>
620
+ <button onclick="editor.addComparisonRow()" class="text-sm text-indigo-600 hover:text-indigo-700 font-medium">+ Add Row</button>
621
+ </div>
622
+ <div class="space-y-2">
623
+ ${(slide.rows || []).map((row, i) => `
624
+ <div class="grid grid-cols-3 gap-3 p-3 bg-gray-50 rounded-lg border border-gray-200">
625
+ <input type="text" value="${row.feature}" placeholder="Feature name"
626
+ oninput="editor.updateComparisonRow(${i}, 'feature', this.value)"
627
+ class="editor-input w-full px-3 py-2 text-sm border border-gray-300 rounded focus:ring-2 focus:ring-indigo-500 outline-none">
628
+ <input type="text" value="${row.col1}" placeholder="Option 1"
629
+ oninput="editor.updateComparisonRow(${i}, 'col1', this.value)"
630
+ class="editor-input w-full px-3 py-2 text-sm border border-gray-300 rounded focus:ring-2 focus:ring-indigo-500 outline-none">
631
+ <div class="flex items-center gap-2">
632
+ <input type="text" value="${row.col2}" placeholder="Option 2"
633
+ oninput="editor.updateComparisonRow(${i}, 'col2', this.value)"
634
+ class="editor-input flex-1 px-3 py-2 text-sm border border-gray-300 rounded focus:ring-2 focus:ring-indigo-500 outline-none">
635
+ <button onclick="editor.removeComparisonRow(${i})" class="text-red-500 hover:text-red-700 p-1">
636
+ <i data-lucide="x" class="w-4 h-4"></i>
637
+ </button>
638
+ </div>
639
+ </div>
640
+ `).join('')}
641
+ </div>
642
+ </div>
643
+ `;
644
  }
645
 
646
  html += `</div>`;
 
653
  this.updatePreview();
654
  }
655
 
656
+ updateColumn(index, value) {
657
+ if (!this.slides[this.currentSlide].columns) {
658
+ this.slides[this.currentSlide].columns = ['Feature', 'Our Solution', 'Competitors'];
659
+ }
660
+ this.slides[this.currentSlide].columns[index] = value;
661
+ this.updatePreview();
662
+ }
663
+
664
+ updateComparisonRow(index, field, value) {
665
+ if (!this.slides[this.currentSlide].rows) {
666
+ this.slides[this.currentSlide].rows = [];
667
+ }
668
+ if (!this.slides[this.currentSlide].rows[index]) {
669
+ this.slides[this.currentSlide].rows[index] = { feature: '', col1: '', col2: '' };
670
+ }
671
+ this.slides[this.currentSlide].rows[index][field] = value;
672
+ this.updatePreview();
673
+ }
674
+
675
+ addComparisonRow() {
676
+ if (!this.slides[this.currentSlide].rows) {
677
+ this.slides[this.currentSlide].rows = [];
678
+ }
679
+ this.slides[this.currentSlide].rows.push({ feature: 'New Feature', col1: 'βœ“ Yes', col2: 'βœ— No' });
680
+ this.renderEditor();
681
+ this.updatePreview();
682
+ }
683
+
684
+ removeComparisonRow(index) {
685
+ this.slides[this.currentSlide].rows.splice(index, 1);
686
+ this.renderEditor();
687
+ this.updatePreview();
688
+ }
689
+
690
  validateJSON(jsonString) {
691
  // Skip validation if paused (but still track for manual validation)
692
  if (this.validationPaused) {
 
833
  </div>
834
  </div>
835
  `;
836
+ } else if (slide.layout === 'comparison') {
837
+ const cols = slide.columns || ['Feature', 'Our Solution', 'Competitors'];
838
+ content = `
839
+ <div class="w-full h-full p-6 bg-white flex flex-col justify-center">
840
+ <div class="text-center space-y-1 mb-4">
841
+ <h2 class="text-xl font-bold text-gray-900">${slide.title}</h2>
842
+ ${slide.subtitle ? `<p class="text-xs text-gray-600">${slide.subtitle}</p>` : ''}
843
+ </div>
844
+ <div class="overflow-hidden rounded-lg border border-gray-200">
845
+ <table class="w-full text-xs">
846
+ <thead>
847
+ <tr class="bg-indigo-50">
848
+ <th class="px-3 py-2 text-left font-semibold text-gray-900 border-b border-indigo-100">${cols[0]}</th>
849
+ <th class="px-3 py-2 text-center font-semibold text-indigo-700 border-b border-indigo-100">${cols[1]}</th>
850
+ <th class="px-3 py-2 text-center font-semibold text-gray-600 border-b border-indigo-100">${cols[2]}</th>
851
+ </tr>
852
+ </thead>
853
+ <tbody>
854
+ ${(slide.rows || []).map((row, i) => `
855
+ <tr class="${i % 2 === 0 ? 'bg-white' : 'bg-gray-50'}">
856
+ <td class="px-3 py-2 font-medium text-gray-900 border-b border-gray-100">${row.feature}</td>
857
+ <td class="px-3 py-2 text-center text-indigo-600 border-b border-gray-100">${row.col1}</td>
858
+ <td class="px-3 py-2 text-center text-gray-500 border-b border-gray-100">${row.col2}</td>
859
+ </tr>
860
+ `).join('')}
861
+ </tbody>
862
+ </table>
863
+ </div>
864
+ </div>
865
+ `;
866
  }
867
 
868
  preview.innerHTML = content;
 
947
  </div>
948
  </div>
949
  `;
950
+ } else if (slide.layout === 'comparison') {
951
+ const cols = slide.columns || ['Feature', 'Our Solution', 'Competitors'];
952
+ content = `
953
+ <div class="w-full h-full p-12 bg-white flex flex-col justify-center">
954
+ <div class="text-center space-y-2 mb-8">
955
+ <h2 class="text-4xl font-bold text-gray-900">${slide.title}</h2>
956
+ ${slide.subtitle ? `<p class="text-xl text-gray-600">${slide.subtitle}</p>` : ''}
957
+ </div>
958
+ <div class="max-w-4xl mx-auto w-full">
959
+ <div class="overflow-hidden rounded-2xl border border-gray-200 shadow-sm">
960
+ <table class="w-full">
961
+ <thead>
962
+ <tr class="bg-indigo-50">
963
+ <th class="px-6 py-4 text-left text-sm font-semibold text-gray-900 border-b border-indigo-100 w-1/3">${cols[0]}</th>
964
+ <th class="px-6 py-4 text-center text-sm font-bold text-indigo-700 border-b border-indigo-100 w-1/3">${cols[1]}</th>
965
+ <th class="px-6 py-4 text-center text-sm font-semibold text-gray-600 border-b border-indigo-100 w-1/3">${cols[2]}</th>
966
+ </tr>
967
+ </thead>
968
+ <tbody>
969
+ ${(slide.rows || []).map((row, i) => `
970
+ <tr class="${i % 2 === 0 ? 'bg-white' : 'bg-gray-50'} hover:bg-indigo-50/30 transition-colors">
971
+ <td class="px-6 py-4 text-sm font-medium text-gray-900 border-b border-gray-100">${row.feature}</td>
972
+ <td class="px-6 py-4 text-center text-sm font-semibold text-indigo-600 border-b border-gray-100">${row.col1}</td>
973
+ <td class="px-6 py-4 text-center text-sm text-gray-500 border-b border-gray-100">${row.col2}</td>
974
+ </tr>
975
+ `).join('')}
976
+ </tbody>
977
+ </table>
978
+ </div>
979
+ </div>
980
+ </div>
981
+ `;
982
  }
983
 
984
  container.innerHTML = content;