geethareddy commited on
Commit
8fa3276
·
verified ·
1 Parent(s): 55c32dc

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +197 -279
templates/index.html CHANGED
@@ -196,7 +196,6 @@
196
  font-size: 20px;
197
  color: #ed8936;
198
  }
199
- /* Daily Checklist Section */
200
  .checklist-header {
201
  display: flex;
202
  justify-content: space-between;
@@ -256,7 +255,6 @@
256
  text-decoration: line-through;
257
  color: #a0aec0;
258
  }
259
- /* Focus Tips Section */
260
  .tip-card {
261
  background: linear-gradient(145deg, #e6f0fa, #d1e3ff);
262
  padding: 20px;
@@ -284,7 +282,6 @@
284
  font-size: 15px;
285
  color: #4a5568;
286
  }
287
- /* Supervisor Data Section */
288
  pre {
289
  background-color: #f7fafc;
290
  padding: 15px;
@@ -296,7 +293,6 @@
296
  overflow-y: auto;
297
  color: #4a5568;
298
  }
299
- /* Reflection Journal Section */
300
  .reflection-journal {
301
  display: flex;
302
  flex-direction: column;
@@ -347,7 +343,6 @@
347
  font-weight: 600;
348
  color: #2d3748;
349
  }
350
- /* KPI Summary Dashboard Section */
351
  .kpi-dashboard {
352
  display: grid;
353
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
@@ -413,7 +408,6 @@
413
  background-color: #f56565;
414
  color: #fff;
415
  }
416
- /* Buttons */
417
  button {
418
  padding: 12px 25px;
419
  background: linear-gradient(to right, #f6ad55, #ed8936);
@@ -435,7 +429,6 @@
435
  .download-btn:hover {
436
  background: linear-gradient(to right, #2f855a, #38a169);
437
  }
438
- /* Toast Notifications */
439
  .toast {
440
  position: fixed;
441
  top: 20px;
@@ -459,7 +452,6 @@
459
  .toast.visible {
460
  display: block;
461
  }
462
- /* Responsive Design */
463
  @media (max-width: 900px) {
464
  .content-grid {
465
  grid-template-columns: 1fr;
@@ -572,7 +564,6 @@
572
 
573
  <div class="container">
574
  <div class="content-grid">
575
- <!-- Daily Checklist Section -->
576
  <div class="section checklist-section">
577
  <div class="checklist-header">
578
  <h3><i>📋</i> Daily Checklist</h3>
@@ -581,19 +572,16 @@
581
  <div id="checklist-items"></div>
582
  </div>
583
 
584
- <!-- Focus Tips Section -->
585
  <div class="section tips-section">
586
  <h3><i>💡</i> Today's Top 3 Focus Areas</h3>
587
  <div id="focus-tips"></div>
588
  </div>
589
 
590
- <!-- Supervisor Data Section -->
591
  <div class="section full-width">
592
  <h3><i>📊</i> Supervisor Data</h3>
593
  <pre id="supervisor-data">Loading supervisor data...</pre>
594
  </div>
595
 
596
- <!-- Reflection Journal Section -->
597
  <div class="section full-width reflection-journal">
598
  <h3><i>📝</i> Reflection Journal</h3>
599
  <div class="reflection-input-area">
@@ -605,17 +593,13 @@
605
  </div>
606
  </div>
607
 
608
- <!-- KPI Summary Dashboard Section -->
609
  <div class="section full-width kpi-section">
610
  <h3><i>📈</i> KPI Summary Dashboard</h3>
611
- <div class="kpi-dashboard" id="kpi-dashboard">
612
- <!-- KPIs will be populated dynamically -->
613
- </div>
614
  </div>
615
  </div>
616
  </div>
617
 
618
- <!-- Toast Notifications -->
619
  <div id="error" class="toast error"></div>
620
  <div id="success" class="toast success"></div>
621
 
@@ -626,7 +610,6 @@
626
  let checklistProgress = 0;
627
  let totalChecklistItems = 0;
628
 
629
- // Toast Notification Function
630
  function showToast(id, message) {
631
  const toast = document.getElementById(id);
632
  toast.textContent = message;
@@ -636,15 +619,13 @@
636
  }, 3000);
637
  }
638
 
639
- // Set Avatar Initial
640
  async function setAvatar() {
641
  const avatar = document.getElementById('avatar');
642
  try {
643
  const response = await fetch('/get_supervisor_data');
644
  const result = await response.json();
645
- if (result.status === 'success' && result.data.supervisor_id !== 'GUEST') {
646
- const username = result.data.supervisor_id.split('_')[1] || 'User';
647
- avatar.textContent = username.charAt(0).toUpperCase();
648
  } else {
649
  avatar.textContent = 'G';
650
  }
@@ -653,7 +634,6 @@
653
  }
654
  }
655
 
656
- // Dropdown Toggle
657
  function toggleDropdown() {
658
  const dropdown = document.getElementById('dropdown');
659
  dropdown.classList.toggle('active');
@@ -670,7 +650,6 @@
670
  headers: { 'Content-Type': 'application/json' }
671
  });
672
  const result = await response.json();
673
-
674
  if (result.status === 'success') {
675
  window.location.href = '/login';
676
  } else {
@@ -681,7 +660,6 @@
681
  }
682
  }
683
 
684
- // Search Functionality
685
  function searchData() {
686
  const query = document.getElementById('search-bar').value.toLowerCase().trim();
687
  const resultsDiv = document.getElementById('search-results');
@@ -729,7 +707,6 @@
729
  showToast('error', 'Voice search not implemented yet.');
730
  }
731
 
732
- // Update Checklist Progress
733
  function updateChecklistProgress() {
734
  const completedItems = document.querySelectorAll('.checklist-item.completed').length;
735
  checklistProgress = totalChecklistItems > 0 ? (completedItems / totalChecklistItems) * 100 : 0;
@@ -738,6 +715,16 @@
738
  progressCircle.querySelector('span').textContent = `${Math.round(checklistProgress)}%`;
739
  }
740
 
 
 
 
 
 
 
 
 
 
 
741
  async function fetchSupervisorData() {
742
  try {
743
  const response = await fetch('/get_supervisor_data');
@@ -747,7 +734,6 @@
747
  supervisorData = result.data;
748
  document.getElementById('supervisor-data').textContent = JSON.stringify(supervisorData, null, 2);
749
 
750
- // Populate Daily Checklist from Salesforce
751
  const checklistDiv = document.getElementById('checklist-items');
752
  if (supervisorData.daily_checklist) {
753
  const checklistItems = supervisorData.daily_checklist.split('\n').filter(item => item.trim());
@@ -761,267 +747,199 @@
761
  <label for="checklist-${index}">${item}</label>
762
  `;
763
  checklistDiv.appendChild(itemDiv);
764
- });
765
- updateChecklistProgress();
766
- } else {
767
- checklistDiv.innerHTML = '<p>No checklist items available.</p>';
768
- }
769
-
770
- // Populate Focus Tips from Salesforce
771
- const tipsDiv = document.getElementById('focus-tips');
772
- if (supervisorData.suggested_tips) {
773
- const tips = supervisorData.suggested_tips.split('\n').filter(tip => tip.trim());
774
- tipsDiv.innerHTML = '';
775
- const tipCard = document.createElement('div');
776
- tipCard.className = 'tip-card';
777
- tipCard.innerHTML = `
778
- <h4>Today's Top 3 Focus Areas</h4>
779
- <ul>
780
- ${tips.map(tip => `<li>${tip}</li>`).join('')}
781
- </ul>
782
- `;
783
- tipsDiv.appendChild(tipCard);
784
- } else {
785
- tipsDiv.innerHTML = '<p>No focus tips available.</p>';
786
- }
787
-
788
- // Populate Reflection History
789
- if (supervisorData.reflection_log) {
790
- reflectionHistory.push({
791
- date: new Date().toLocaleString(),
792
- text: supervisorData.reflection_log
793
- });
794
- updateReflectionHistory();
795
- }
796
-
797
- // Update Download Link
798
- const downloadBtn = document.getElementById('download-btn');
799
- if (supervisorData.download_link) {
800
- downloadBtn.onclick = () => window.open(supervisorData.download_link, '_blank');
801
- downloadBtn.textContent = 'Download Report';
802
- } else {
803
- downloadBtn.onclick = downloadPDF;
804
- downloadBtn.textContent = 'Download PDF Summary';
805
- }
806
-
807
- updateKPIDashboard();
808
- } else {
809
- showToast('error', result.message);
810
- document.getElementById('supervisor-data').textContent = 'Failed to load supervisor data.';
811
- }
812
- } catch (error) {
813
- showToast('error', 'Error fetching supervisor data: ' + error.message);
814
- document.getElementById('supervisor-data').textContent = 'Failed to load supervisor data.';
815
- }
816
- }
817
-
818
- async function generateCoaching() {
819
- if (!supervisorData) {
820
- showToast('error', 'Supervisor data not loaded. Please refresh the page.');
821
- return;
822
- }
823
-
824
- try {
825
- const response = await fetch('/generate', {
826
- method: 'POST',
827
- headers: { 'Content-Type': 'application/json' },
828
- body: JSON.stringify(supervisorData)
829
  });
830
- const result = await response.json();
831
-
832
- if (result.status === 'success') {
833
- coachingOutput = result.output;
834
- showToast('success', 'Coaching output generated successfully!');
835
-
836
- // Populate Daily Checklist
837
- const checklistDiv = document.getElementById('checklist-items');
838
- checklistDiv.innerHTML = '';
839
- if (coachingOutput.checklist && coachingOutput.checklist.length > 0) {
840
- totalChecklistItems = coachingOutput.checklist.length;
841
- coachingOutput.checklist.forEach((item, index) => {
842
- const itemDiv = document.createElement('div');
843
- itemDiv.className = 'checklist-item';
844
- itemDiv.innerHTML = `
845
- <input type="checkbox" id="checklist-${index}" onchange="markComplete(${index}, this)">
846
- <label for="checklist-${index}">${item}</label>
847
- `;
848
- checklistDiv.appendChild(itemDiv);
849
- });
850
- updateChecklistProgress();
851
- } else {
852
- checklistDiv.innerHTML = '<p>No checklist items available.</p>';
853
- }
854
-
855
- // Populate Focus Tips
856
- const tipsDiv = document.getElementById('focus-tips');
857
- tipsDiv.innerHTML = '';
858
- if (coachingOutput.tips && coachingOutput.tips.length > 0) {
859
- const tipCard = document.createElement('div');
860
- tipCard.className = 'tip-card';
861
- tipCard.innerHTML = `
862
- <h4>Today's Top 3 Focus Areas</h4>
863
- <ul>
864
- ${coachingOutput.tips.map(tip => `<li>${tip}</li>`).join('')}
865
- </ul>
866
- `;
867
- tipsDiv.appendChild(tipCard);
868
- } else {
869
- tipsDiv.innerHTML = '<p>No focus tips available.</p>';
870
- }
871
-
872
- updateKPIDashboard();
873
- } else {
874
- showToast('error', result.message);
875
- document.getElementById('checklist-items').innerHTML = '<p>Failed to generate checklist.</p>';
876
- document.getElementById('focus-tips').innerHTML = '<p>Failed to generate focus tips.</p>';
877
- }
878
- } catch (error) {
879
- showToast('error', 'Error generating coaching output: ' + error.message);
880
- document.getElementById('checklist-items').innerHTML = '<p>Failed to generate checklist.</p>';
881
- document.getElementById('focus-tips').innerHTML = '<p>Failed to generate focus tips.</p>';
882
- }
883
- }
884
-
885
- function markComplete(index, checkbox) {
886
- const itemDiv = checkbox.parentElement;
887
- if (checkbox.checked) {
888
- itemDiv.classList.add('completed');
889
  } else {
890
- itemDiv.classList.remove('completed');
891
- }
892
- updateChecklistProgress();
893
- showToast('success', `Checklist item ${index + 1} marked as ${checkbox.checked ? 'complete' : 'incomplete'} (simulated).`);
894
- }
895
-
896
- function updateReflectionHistory() {
897
- const historyDiv = document.getElementById('reflection-history');
898
- historyDiv.innerHTML = '';
899
- if (reflectionHistory.length > 0) {
900
- reflectionHistory.forEach(ref => {
901
- const entryDiv = document.createElement('div');
902
- entryDiv.className = 'reflection-entry';
903
- entryDiv.innerHTML = `<span>${ref.date}:</span> ${ref.text}`;
904
- historyDiv.appendChild(entryDiv);
905
- });
906
  } else {
907
- historyDiv.innerHTML = '<p>No reflections yet. Start logging your thoughts!</p>';
908
- }
909
- }
910
-
911
- async function submitReflection() {
912
- const reflectionInput = document.getElementById('reflection-input').value.trim();
913
-
914
- if (!reflectionInput) {
915
- showToast('error', 'Please enter a reflection before submitting.');
916
- return;
917
- }
918
-
919
- if (!supervisorData) {
920
- showToast('error', 'Supervisor data not loaded. Please refresh the page.');
921
- return;
922
  }
923
 
924
- try {
925
- const response = await fetch('/submit_reflection', {
926
- method: 'POST',
927
- headers: { 'Content-Type': 'application/json' },
928
- body: JSON.stringify({ reflection: reflectionInput })
929
  });
930
- const result = await response.json();
931
-
932
- if (result.status === 'success') {
933
- supervisorData.reflection_log = reflectionInput;
934
- document.getElementById('supervisor-data').textContent = JSON.stringify(supervisorData, null, 2);
935
- reflectionHistory.push({
936
- date: new Date().toLocaleString(),
937
- text: reflectionInput
938
- });
939
- updateReflectionHistory();
940
- document.getElementById('reflection-input').value = '';
941
- showToast('success', result.message);
942
- generateCoaching();
943
- } else {
944
- showToast('error', result.message);
945
- }
946
- } catch (error) {
947
- showToast('error', 'Error submitting reflection: ' + error.message);
948
  }
949
- }
950
-
951
- function updateKPIDashboard() {
952
- const kpiDashboard = document.getElementById('kpi-dashboard');
953
- kpiDashboard.innerHTML = '';
954
-
955
- // KPI 1: Engagement Score
956
- const engagementScore = supervisorData && supervisorData.engagement_score ? supervisorData.engagement_score : 85;
957
- const engagementCard = document.createElement('div');
958
- engagementCard.className = 'kpi-card';
959
- engagementCard.innerHTML = `
960
- <h4>Engagement Score</h4>
961
- <div class="kpi-value">${engagementScore}%</div>
962
- <div class="progress-bar">
963
- <div class="progress-fill" style="width: ${engagementScore}%"></div>
964
- </div>
965
- <p class="kpi-trend">Target: 90%</p>
966
- `;
967
- kpiDashboard.appendChild(engagementCard);
968
-
969
- // KPI 2: Task Completion Rate
970
- const taskCompletionRate = checklistProgress;
971
- const taskCard = document.createElement('div');
972
- taskCard.className = 'kpi-card';
973
- taskCard.innerHTML = `
974
- <h4>Task Completion Rate</h4>
975
- <div class="kpi-value">${Math.round(taskCompletionRate)}%</div>
976
- <div class="progress-bar">
977
- <div class="progress-fill" style="width: ${taskCompletionRate}%"></div>
978
- </div>
979
- <p class="kpi-trend">Based on Daily Checklist</p>
980
- `;
981
- kpiDashboard.appendChild(taskCard);
982
 
983
- // KPI 3: Reflection Frequency
984
- const reflectionFrequency = reflectionHistory.length;
985
- const reflectionCard = document.createElement('div');
986
- reflectionCard.className = 'kpi-card';
987
- reflectionCard.innerHTML = `
988
- <h4>Reflection Frequency</h4>
989
- <div class="kpi-value">${reflectionFrequency}</div>
990
- <div class="progress-bar">
991
- <div class="progress-fill" style="width: ${(reflectionFrequency / 5) * 100}%"></div>
992
- </div>
993
- <p class="kpi-trend">Goal: 5 per week</p>
994
- `;
995
- kpiDashboard.appendChild(reflectionCard);
996
-
997
- // KPI 4: KPI Flag
998
- const kpiFlag = supervisorData && supervisorData.kpi_flag !== undefined ? supervisorData.kpi_flag : false;
999
- const flagCard = document.createElement('div');
1000
- flagCard.className = 'kpi-card';
1001
- flagCard.innerHTML = `
1002
- <h4>KPI Flag Status</h4>
1003
- <div class="kpi-value">
1004
- <span class="kpi-flag ${kpiFlag ? 'active' : 'inactive'}">${kpiFlag ? 'Active' : 'Inactive'}</span>
1005
- </div>
1006
- <p class="kpi-trend">Performance Indicator</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1007
  `;
1008
- kpiDashboard.appendChild(flagCard);
1009
- }
1010
-
1011
- function downloadPDF() {
1012
- if (!supervisorData || !supervisorData.download_link) {
1013
- showToast('error', 'No download link available.');
1014
- return;
1015
- }
1016
- window.open(supervisorData.download_link, '_blank');
1017
- }
1018
-
1019
- // Event Listeners
1020
- document.getElementById('search-bar').addEventListener('input', searchData);
1021
- window.onload = () => {
1022
- fetchSupervisorData();
1023
- setAvatar();
1024
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1025
  </script>
1026
  </body>
1027
  </html>
 
196
  font-size: 20px;
197
  color: #ed8936;
198
  }
 
199
  .checklist-header {
200
  display: flex;
201
  justify-content: space-between;
 
255
  text-decoration: line-through;
256
  color: #a0aec0;
257
  }
 
258
  .tip-card {
259
  background: linear-gradient(145deg, #e6f0fa, #d1e3ff);
260
  padding: 20px;
 
282
  font-size: 15px;
283
  color: #4a5568;
284
  }
 
285
  pre {
286
  background-color: #f7fafc;
287
  padding: 15px;
 
293
  overflow-y: auto;
294
  color: #4a5568;
295
  }
 
296
  .reflection-journal {
297
  display: flex;
298
  flex-direction: column;
 
343
  font-weight: 600;
344
  color: #2d3748;
345
  }
 
346
  .kpi-dashboard {
347
  display: grid;
348
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
 
408
  background-color: #f56565;
409
  color: #fff;
410
  }
 
411
  button {
412
  padding: 12px 25px;
413
  background: linear-gradient(to right, #f6ad55, #ed8936);
 
429
  .download-btn:hover {
430
  background: linear-gradient(to right, #2f855a, #38a169);
431
  }
 
432
  .toast {
433
  position: fixed;
434
  top: 20px;
 
452
  .toast.visible {
453
  display: block;
454
  }
 
455
  @media (max-width: 900px) {
456
  .content-grid {
457
  grid-template-columns: 1fr;
 
564
 
565
  <div class="container">
566
  <div class="content-grid">
 
567
  <div class="section checklist-section">
568
  <div class="checklist-header">
569
  <h3><i>📋</i> Daily Checklist</h3>
 
572
  <div id="checklist-items"></div>
573
  </div>
574
 
 
575
  <div class="section tips-section">
576
  <h3><i>💡</i> Today's Top 3 Focus Areas</h3>
577
  <div id="focus-tips"></div>
578
  </div>
579
 
 
580
  <div class="section full-width">
581
  <h3><i>📊</i> Supervisor Data</h3>
582
  <pre id="supervisor-data">Loading supervisor data...</pre>
583
  </div>
584
 
 
585
  <div class="section full-width reflection-journal">
586
  <h3><i>📝</i> Reflection Journal</h3>
587
  <div class="reflection-input-area">
 
593
  </div>
594
  </div>
595
 
 
596
  <div class="section full-width kpi-section">
597
  <h3><i>📈</i> KPI Summary Dashboard</h3>
598
+ <div class="kpi-dashboard" id="kpi-dashboard"></div>
 
 
599
  </div>
600
  </div>
601
  </div>
602
 
 
603
  <div id="error" class="toast error"></div>
604
  <div id="success" class="toast success"></div>
605
 
 
610
  let checklistProgress = 0;
611
  let totalChecklistItems = 0;
612
 
 
613
  function showToast(id, message) {
614
  const toast = document.getElementById(id);
615
  toast.textContent = message;
 
619
  }, 3000);
620
  }
621
 
 
622
  async function setAvatar() {
623
  const avatar = document.getElementById('avatar');
624
  try {
625
  const response = await fetch('/get_supervisor_data');
626
  const result = await response.json();
627
+ if (result.status === 'success' && result.data.supervisor_name !== 'GUEST') {
628
+ avatar.textContent = result.data.supervisor_name.charAt(0).toUpperCase();
 
629
  } else {
630
  avatar.textContent = 'G';
631
  }
 
634
  }
635
  }
636
 
 
637
  function toggleDropdown() {
638
  const dropdown = document.getElementById('dropdown');
639
  dropdown.classList.toggle('active');
 
650
  headers: { 'Content-Type': 'application/json' }
651
  });
652
  const result = await response.json();
 
653
  if (result.status === 'success') {
654
  window.location.href = '/login';
655
  } else {
 
660
  }
661
  }
662
 
 
663
  function searchData() {
664
  const query = document.getElementById('search-bar').value.toLowerCase().trim();
665
  const resultsDiv = document.getElementById('search-results');
 
707
  showToast('error', 'Voice search not implemented yet.');
708
  }
709
 
 
710
  function updateChecklistProgress() {
711
  const completedItems = document.querySelectorAll('.checklist-item.completed').length;
712
  checklistProgress = totalChecklistItems > 0 ? (completedItems / totalChecklistItems) * 100 : 0;
 
715
  progressCircle.querySelector('span').textContent = `${Math.round(checklistProgress)}%`;
716
  }
717
 
718
+ function markComplete(index, checkbox) {
719
+ const itemDiv = checkbox.parentElement;
720
+ if (checkbox.checked) {
721
+ itemDiv.classList.add('completed');
722
+ } else {
723
+ itemDiv.classList.remove('completed');
724
+ }
725
+ updateChecklistProgress();
726
+ }
727
+
728
  async function fetchSupervisorData() {
729
  try {
730
  const response = await fetch('/get_supervisor_data');
 
734
  supervisorData = result.data;
735
  document.getElementById('supervisor-data').textContent = JSON.stringify(supervisorData, null, 2);
736
 
 
737
  const checklistDiv = document.getElementById('checklist-items');
738
  if (supervisorData.daily_checklist) {
739
  const checklistItems = supervisorData.daily_checklist.split('\n').filter(item => item.trim());
 
747
  <label for="checklist-${index}">${item}</label>
748
  `;
749
  checklistDiv.appendChild(itemDiv);
750
+ actic: read
751
+ checklistDiv.appendChild(itemDiv);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
752
  });
753
+ updateChecklistProgress();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
754
  } else {
755
+ checklistDiv.innerHTML = '<p>No checklist items available.</p>';
756
+ }
757
+
758
+ const tipsDiv = document.getElementById('focus-tips');
759
+ if (supervisorData.suggested_tips) {
760
+ const tips = supervisorData.suggested_tips.split('\n').filter(tip => tip.trim());
761
+ tipsDiv.innerHTML = '';
762
+ const tipCard = document.createElement('div');
763
+ tipCard.className = 'tip-card';
764
+ tipCard.innerHTML = `
765
+ <h4>Today's Top 3 Focus Areas</h4>
766
+ <ul>
767
+ ${tips.map(tip => `<li>${tip}</li>`).join('')}
768
+ </ul>
769
+ `;
770
+ tipsDiv.appendChild(tipCard);
771
  } else {
772
+ tipsDiv.innerHTML = '<p>No focus tips available.</p>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
773
  }
774
 
775
+ if (supervisorData.reflection_log) {
776
+ reflectionHistory.push({
777
+ date: new Date().toLocaleString(),
778
+ text: supervisorData.reflection_log
 
779
  });
780
+ updateReflectionHistory();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
781
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
782
 
783
+ const downloadBtn = document.getElementById('download-btn');
784
+ if (supervisorData.download_link) {
785
+ downloadBtn.onclick = () => window.open(supervisorData.download_link, '_blank');
786
+ downloadBtn.textContent = 'Download Report';
787
+ } else {
788
+ downloadBtn.onclick = downloadPDF;
789
+ downloadBtn.textContent = 'Download PDF Summary';
790
+ }
791
+
792
+ updateKPIDashboard();
793
+ } else {
794
+ showToast('error', result.message);
795
+ document.getElementById('supervisor-data').textContent = 'Failed to load supervisor data.';
796
+ }
797
+ } catch (error) {
798
+ showToast('error', 'Error fetching supervisor data: ' + error.message);
799
+ document.getElementById('supervisor-data').textContent = 'Failed to load supervisor data.';
800
+ }
801
+ }
802
+
803
+ async function generateCoaching() {
804
+ if (!supervisorData) {
805
+ showToast('error', 'Supervisor data not loaded. Please refresh the page.');
806
+ return;
807
+ }
808
+
809
+ try {
810
+ const response = await fetch('/generate', {
811
+ method: 'POST',
812
+ headers: { 'Content-Type': 'application/json' },
813
+ body: JSON.stringify(supervisorData)
814
+ });
815
+ const result = await response.json();
816
+
817
+ if (result.status === 'success') {
818
+ coachingOutput = result.output;
819
+ showToast('success', 'Coaching output generated successfully!');
820
+ await fetchSupervisorData();
821
+ } else {
822
+ showToast('error', result.message);
823
+ }
824
+ } catch (error) {
825
+ showToast('error', 'Error generating coaching output: ' + error.message);
826
+ }
827
+ }
828
+
829
+ async function submitReflection() {
830
+ const reflectionInput = document.getElementById('reflection-input');
831
+ const reflection = reflectionInput.value.trim();
832
+
833
+ if (!reflection) {
834
+ showToast('error', 'Reflection cannot be empty.');
835
+ return;
836
+ }
837
+
838
+ try {
839
+ const response = await fetch('/submit_reflection', {
840
+ method: 'POST',
841
+ headers: { 'Content-Type': 'application/json' },
842
+ body: JSON.stringify({ reflection })
843
+ });
844
+ const result = await response.json();
845
+
846
+ if (result.status === 'success') {
847
+ showToast('success', result.message);
848
+ reflectionHistory.push({
849
+ date: new Date().toLocaleString(),
850
+ text: reflection
851
+ });
852
+ reflectionInput.value = '';
853
+ updateReflectionHistory();
854
+ await fetchSupervisorData();
855
+ } else {
856
+ showToast('error', result.message);
857
+ }
858
+ } catch (error) {
859
+ showToast('error', 'Error submitting reflection: ' + error.message);
860
+ }
861
+ }
862
+
863
+ function updateReflectionHistory() {
864
+ const historyDiv = document.getElementById('reflection-history');
865
+ if (reflectionHistory.length > 0) {
866
+ historyDiv.innerHTML = reflectionHistory.map(ref => `
867
+ <div class="reflection-entry">
868
+ <span>${ref.date}</span>: ${ref.text}
869
+ </div>
870
+ `).join('');
871
+ } else {
872
+ historyDiv.innerHTML = '<p>No reflections yet. Start logging your thoughts!</p>';
873
+ }
874
+ }
875
+
876
+ function updateKPIDashboard() {
877
+ const kpiDashboard = document.getElementById('kpi-dashboard');
878
+ kpiDashboard.innerHTML = '';
879
+
880
+ if (supervisorData) {
881
+ const kpiData = [
882
+ {
883
+ title: 'Engagement Score',
884
+ value: `${supervisorData.engagement_score}%`,
885
+ progress: supervisorData.engagement_score,
886
+ trend: supervisorData.engagement_score > 80 ? 'Upward' : 'Stable'
887
+ },
888
+ {
889
+ title: 'KPI Flag',
890
+ value: supervisorData.kpi_flag ? 'Active' : 'Inactive',
891
+ class: supervisorData.kpi_flag ? 'active' : 'inactive'
892
+ }
893
+ ];
894
+
895
+ kpiData.forEach(kpi => {
896
+ const kpiCard = document.createElement('div');
897
+ kpiCard.className = 'kpi-card';
898
+ kpiCard.innerHTML = `
899
+ <h4>${kpi.title}</h4>
900
+ <div class="kpi-value ${kpi.class || ''}">${kpi.value}</div>
901
+ ${kpi.progress !== undefined ? `
902
+ <div class="progress-bar">
903
+ <div class="progress-fill" style="width: ${kpi.progress}%"></div>
904
+ </div>
905
+ <div class="kpi-trend">Trend: ${kpi.trend}</div>
906
+ ` : ''}
907
  `;
908
+ kpiDashboard.appendChild(kpiCard);
909
+ });
910
+ } else {
911
+ kpiDashboard.innerHTML = '<p>No KPI data available.</p>';
912
+ }
913
+ }
914
+
915
+ async function downloadPDF() {
916
+ try {
917
+ const response = await fetch('/download_pdf');
918
+ if (response.ok && response.headers.get('content-type').includes('application/pdf')) {
919
+ const blob = await response.blob();
920
+ const url = window.URL.createObjectURL(blob);
921
+ const a = document.createElement('a');
922
+ a.href = url;
923
+ a.download = `supervisor_report_${supervisorData?.supervisor_name || 'report'}.pdf`;
924
+ document.body.appendChild(a);
925
+ a.click();
926
+ document.body.removeChild(a);
927
+ window.URL.revokeObjectURL(url);
928
+ showToast('success', 'PDF downloaded successfully!');
929
+ } else {
930
+ const result = await response.json();
931
+ showToast('error', result.message);
932
+ }
933
+ } catch (error) {
934
+ showToast('error', 'Error downloading PDF: ' + error.message);
935
+ }
936
+ }
937
+
938
+ document.getElementById('search-bar').addEventListener('input', searchData);
939
+ document.addEventListener('DOMContentLoaded', () => {
940
+ setAvatar();
941
+ fetchSupervisorData();
942
+ });
943
  </script>
944
  </body>
945
  </html>