lokeshloki143 commited on
Commit
b02c653
·
verified ·
1 Parent(s): f4b0e77

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +461 -124
templates/index.html CHANGED
@@ -9,13 +9,14 @@
9
  font-family: 'Roboto', Arial, sans-serif;
10
  margin: 0;
11
  padding: 0;
12
- background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);
13
- color: #333;
 
14
  }
15
  .header {
16
- background: linear-gradient(to right, #1e3c72, #2a5298);
17
- padding: 15px 20px;
18
- box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
19
  position: sticky;
20
  top: 0;
21
  z-index: 100;
@@ -23,7 +24,7 @@
23
  .header-title {
24
  color: #fff;
25
  margin: 0;
26
- font-size: 24px;
27
  font-weight: 700;
28
  text-align: center;
29
  padding-bottom: 10px;
@@ -32,12 +33,12 @@
32
  display: flex;
33
  align-items: center;
34
  justify-content: space-between;
35
- gap: 15px;
36
  }
37
  .avatar {
38
- width: 40px;
39
- height: 40px;
40
- background-color: #ff9500;
41
  color: #fff;
42
  border-radius: 50%;
43
  display: flex;
@@ -47,9 +48,11 @@
47
  font-weight: 600;
48
  cursor: pointer;
49
  position: relative;
 
50
  }
51
  .avatar:hover {
52
- background-color: #e68600;
 
53
  }
54
  .dropdown {
55
  display: none;
@@ -57,10 +60,11 @@
57
  top: 50px;
58
  right: 0;
59
  background-color: #fff;
60
- box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
61
- border-radius: 8px;
62
- min-width: 150px;
63
  z-index: 101;
 
64
  }
65
  .dropdown.active {
66
  display: block;
@@ -68,13 +72,13 @@
68
  .dropdown a {
69
  display: block;
70
  padding: 12px 20px;
71
- color: #333;
72
  text-decoration: none;
73
- font-size: 16px;
74
  transition: background 0.3s ease;
75
  }
76
  .dropdown a:hover {
77
- background-color: #f8f9fa;
78
  }
79
  .search-container {
80
  position: relative;
@@ -83,25 +87,26 @@
83
  }
84
  .search-bar {
85
  width: 100%;
86
- padding: 12px 40px 12px 15px;
87
- border: 2px solid #ddd;
88
  border-radius: 25px;
89
- font-size: 16px;
90
  box-sizing: border-box;
91
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
 
92
  }
93
  .search-bar:focus {
94
- border-color: #ff9500;
95
  outline: none;
96
- box-shadow: 0 0 8px rgba(255, 149, 0, 0.3);
97
  }
98
  .mic-icon {
99
  position: absolute;
100
- right: 10px;
101
  top: 50%;
102
  transform: translateY(-50%);
103
- width: 20px;
104
- height: 20px;
105
  background: url('https://img.icons8.com/ios-filled/50/000000/microphone.png') no-repeat center;
106
  background-size: contain;
107
  cursor: pointer;
@@ -117,9 +122,9 @@
117
  left: 0;
118
  right: 0;
119
  background-color: #fff;
120
- box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
121
- border-radius: 8px;
122
- max-height: 200px;
123
  overflow-y: auto;
124
  z-index: 100;
125
  display: none;
@@ -131,27 +136,31 @@
131
  padding: 10px 15px;
132
  margin: 0;
133
  font-size: 14px;
134
- color: #333;
135
- border-bottom: 1px solid #eee;
 
 
 
 
136
  }
137
  .search-results p:last-child {
138
  border-bottom: none;
139
  }
140
  .action-bar {
141
  background-color: #fff;
142
- padding: 15px 20px;
143
  display: flex;
144
  justify-content: center;
145
- gap: 15px;
146
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
147
  position: sticky;
148
  top: 90px;
149
  z-index: 99;
150
  }
151
  .container {
152
  max-width: 1200px;
153
- margin: 30px auto;
154
- padding: 40px;
155
  }
156
  .content-grid {
157
  display: grid;
@@ -161,124 +170,272 @@
161
  }
162
  .section {
163
  padding: 25px;
164
- background-color: #f8f9fa;
165
- border-radius: 10px;
166
- border-left: 5px solid #ff9500;
167
- transition: transform 0.2s ease;
 
168
  }
169
  .section:hover {
170
  transform: translateY(-5px);
 
171
  }
172
  .section.full-width {
173
  grid-column: span 2;
174
  }
175
  h3 {
176
- margin-top: 0;
177
- color: #1e3c72;
178
  font-size: 22px;
179
  font-weight: 600;
 
 
 
180
  }
181
- pre {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
  background-color: #fff;
183
- padding: 15px;
184
- border: 1px solid #ddd;
185
- border-radius: 8px;
186
- white-space: pre-wrap;
187
- font-size: 16px;
188
- max-height: 300px;
189
- overflow-y: auto;
190
  }
191
  .checklist-item {
192
  display: flex;
193
  align-items: center;
194
  margin-bottom: 15px;
195
  font-size: 16px;
 
 
 
 
 
 
196
  }
197
  .checklist-item input {
198
  width: 20px;
199
  height: 20px;
200
  margin-right: 15px;
201
- accent-color: #ff9500;
 
202
  }
203
  .checklist-item label {
204
  flex: 1;
205
- color: #333;
 
 
 
 
 
206
  }
 
207
  .tip-card {
208
- background: linear-gradient(145deg, #e9f7ff, #d0e7ff);
209
  padding: 20px;
210
  border-radius: 10px;
211
  margin-bottom: 15px;
212
- box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
 
 
 
 
213
  }
214
  .tip-card h4 {
215
  margin: 0 0 15px 0;
216
- color: #1e3c72;
217
- font-size: 20px;
 
218
  }
219
  .tip-card ul {
220
- padding-left: 25px;
221
  margin: 0;
222
- list-style-type: square;
223
  }
224
  .tip-card li {
225
  margin-bottom: 10px;
226
- font-size: 16px;
227
- color: #333;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  }
229
  .reflection-journal textarea {
230
  width: 100%;
231
  height: 120px;
232
  padding: 15px;
233
- border: 2px solid #ddd;
234
- border-radius: 8px;
235
  resize: none;
236
- font-size: 16px;
237
  box-sizing: border-box;
238
- transition: border-color 0.3s ease;
 
239
  }
240
  .reflection-journal textarea:focus {
241
- border-color: #ff9500;
242
  outline: none;
243
- box-shadow: 0 0 8px rgba(255, 149, 0, 0.3);
244
  }
245
- .engagement-score {
246
- text-align: center;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  padding: 20px;
248
- background: linear-gradient(145deg, #fff, #f1f1f1);
249
  border-radius: 10px;
250
- box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
  font-size: 24px;
252
  font-weight: 700;
253
- color: #ff9500;
 
254
  }
255
- .weekly-trend {
256
- text-align: center;
257
- margin-top: 15px;
258
- font-size: 16px;
259
- color: #666;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  }
 
 
 
 
 
261
  button {
262
  padding: 12px 25px;
263
- background: linear-gradient(to right, #ff9500, #ffcc00);
264
  color: #fff;
265
  border: none;
266
  border-radius: 8px;
267
  cursor: pointer;
268
- font-size: 16px;
269
  font-weight: 600;
270
  transition: transform 0.1s ease, background 0.3s ease;
271
  }
272
  button:hover {
273
- background: linear-gradient(to right, #e68600, #ffbf00);
274
  transform: scale(1.02);
275
  }
276
  .download-btn {
277
- background: linear-gradient(to right, #28a745, #34c759);
278
  }
279
  .download-btn:hover {
280
- background: linear-gradient(to right, #218838, #2db34a);
281
  }
 
282
  .toast {
283
  position: fixed;
284
  top: 20px;
@@ -287,20 +444,22 @@
287
  border-radius: 8px;
288
  z-index: 102;
289
  display: none;
290
- font-size: 16px;
291
  font-weight: 500;
 
292
  }
293
  .toast.error {
294
- background-color: #dc3545;
295
  color: #fff;
296
  }
297
  .toast.success {
298
- background-color: #28a745;
299
  color: #fff;
300
  }
301
  .toast.visible {
302
  display: block;
303
  }
 
304
  @media (max-width: 900px) {
305
  .content-grid {
306
  grid-template-columns: 1fr;
@@ -308,6 +467,9 @@
308
  .section.full-width {
309
  grid-column: span 1;
310
  }
 
 
 
311
  }
312
  @media (max-width: 700px) {
313
  body {
@@ -317,7 +479,7 @@
317
  padding: 10px 15px;
318
  }
319
  .header-title {
320
- font-size: 20px;
321
  padding-bottom: 8px;
322
  }
323
  .header-actions {
@@ -329,34 +491,48 @@
329
  max-width: 100%;
330
  }
331
  .avatar {
332
- width: 35px;
333
- height: 35px;
334
  font-size: 18px;
335
  }
336
  .dropdown {
337
- top: 45px;
 
338
  }
339
  .action-bar {
340
  top: 70px;
341
  flex-direction: column;
342
  gap: 10px;
 
343
  }
344
  .container {
345
- padding: 20px;
346
- margin: 15px;
347
  }
348
  h3 {
349
  font-size: 20px;
350
  }
351
  .section {
352
- padding: 15px;
 
 
 
 
 
 
 
 
 
353
  }
354
- pre, .checklist-item, .tip-card li, .reflection-journal textarea {
355
  font-size: 14px;
356
  }
357
- .engagement-score {
358
  font-size: 20px;
359
  }
 
 
 
360
  button {
361
  width: 100%;
362
  padding: 10px;
@@ -391,41 +567,50 @@
391
 
392
  <div class="action-bar">
393
  <button onclick="generateCoaching()">Generate Coaching Output</button>
394
- <button class="download-btn" onclick="downloadPDF()">Download PDF Summary</button>
395
  </div>
396
 
397
  <div class="container">
398
  <div class="content-grid">
399
  <!-- Daily Checklist Section -->
400
  <div class="section checklist-section">
401
- <h3>Daily Checklist</h3>
 
 
 
402
  <div id="checklist-items"></div>
403
  </div>
404
 
405
  <!-- Focus Tips Section -->
406
  <div class="section tips-section">
407
- <h3>Today's Top 3 Focus Areas</h3>
408
  <div id="focus-tips"></div>
409
  </div>
410
 
411
  <!-- Supervisor Data Section -->
412
  <div class="section full-width">
413
- <h3>Supervisor Data</h3>
414
  <pre id="supervisor-data">Loading supervisor data...</pre>
415
  </div>
416
 
417
  <!-- Reflection Journal Section -->
418
  <div class="section full-width reflection-journal">
419
- <h3>Reflection Journal</h3>
420
- <textarea id="reflection-input" placeholder="Log your reflections for today..."></textarea>
421
- <button onclick="submitReflection()">Submit Reflection</button>
 
 
 
 
 
422
  </div>
423
 
424
- <!-- Engagement Score Section -->
425
- <div class="section full-width engagement-section">
426
- <h3>Engagement Score</h3>
427
- <div class="engagement-score" id="engagement-score">Loading...</div>
428
- <p class="weekly-trend">Weekly Trend: [Graph Placeholder]</p>
 
429
  </div>
430
  </div>
431
  </div>
@@ -437,6 +622,9 @@
437
  <script>
438
  let supervisorData = null;
439
  let coachingOutput = null;
 
 
 
440
 
441
  // Toast Notification Function
442
  function showToast(id, message) {
@@ -516,6 +704,10 @@
516
  searchableContent.push(`Reflection: ${supervisorData.reflection_log}`);
517
  }
518
 
 
 
 
 
519
  const results = searchableContent.filter(item => item.toLowerCase().includes(query));
520
 
521
  if (results.length > 0) {
@@ -537,6 +729,15 @@
537
  showToast('error', 'Voice search not implemented yet.');
538
  }
539
 
 
 
 
 
 
 
 
 
 
540
  async function fetchSupervisorData() {
541
  try {
542
  const response = await fetch('/get_supervisor_data');
@@ -545,9 +746,65 @@
545
  if (result.status === 'success') {
546
  supervisorData = result.data;
547
  document.getElementById('supervisor-data').textContent = JSON.stringify(supervisorData, null, 2);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
548
  if (supervisorData.reflection_log) {
549
- generateCoaching();
 
 
 
 
550
  }
 
 
 
 
 
 
 
 
 
 
 
 
551
  } else {
552
  showToast('error', result.message);
553
  document.getElementById('supervisor-data').textContent = 'Failed to load supervisor data.';
@@ -576,22 +833,26 @@
576
  coachingOutput = result.output;
577
  showToast('success', 'Coaching output generated successfully!');
578
 
 
579
  const checklistDiv = document.getElementById('checklist-items');
580
  checklistDiv.innerHTML = '';
581
  if (coachingOutput.checklist && coachingOutput.checklist.length > 0) {
 
582
  coachingOutput.checklist.forEach((item, index) => {
583
  const itemDiv = document.createElement('div');
584
  itemDiv.className = 'checklist-item';
585
  itemDiv.innerHTML = `
586
- <input type="checkbox" id="checklist-${index}" onchange="markComplete(${index})">
587
  <label for="checklist-${index}">${item}</label>
588
  `;
589
  checklistDiv.appendChild(itemDiv);
590
  });
 
591
  } else {
592
  checklistDiv.innerHTML = '<p>No checklist items available.</p>';
593
  }
594
 
 
595
  const tipsDiv = document.getElementById('focus-tips');
596
  tipsDiv.innerHTML = '';
597
  if (coachingOutput.tips && coachingOutput.tips.length > 0) {
@@ -608,7 +869,7 @@
608
  tipsDiv.innerHTML = '<p>No focus tips available.</p>';
609
  }
610
 
611
- document.getElementById('engagement-score').textContent = supervisorData.engagement_score ? `${supervisorData.engagement_score}%` : '85% (Simulated)';
612
  } else {
613
  showToast('error', result.message);
614
  document.getElementById('checklist-items').innerHTML = '<p>Failed to generate checklist.</p>';
@@ -621,8 +882,30 @@
621
  }
622
  }
623
 
624
- function markComplete(index) {
625
- showToast('success', `Checklist item ${index + 1} marked as complete (simulated).`);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
626
  }
627
 
628
  async function submitReflection() {
@@ -649,8 +932,14 @@
649
  if (result.status === 'success') {
650
  supervisorData.reflection_log = reflectionInput;
651
  document.getElementById('supervisor-data').textContent = JSON.stringify(supervisorData, null, 2);
 
 
 
 
 
652
  document.getElementById('reflection-input').value = '';
653
  showToast('success', result.message);
 
654
  } else {
655
  showToast('error', result.message);
656
  }
@@ -659,24 +948,72 @@
659
  }
660
  }
661
 
662
- function downloadPDF() {
663
- if (!coachingOutput) {
664
- showToast('error', 'Please generate coaching output before downloading.');
665
- return;
666
- }
667
 
668
- try {
669
- const response = fetch('/download_pdf');
670
- const result = response.json();
 
 
 
 
 
 
 
 
 
 
671
 
672
- if (result.status === 'success') {
673
- showToast('success', result.message);
674
- } else {
675
- showToast('error', result.message);
676
- }
677
- } catch (error) {
678
- showToast('error', 'Error downloading PDF: ' + error.message);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
679
  }
 
680
  }
681
 
682
  // Event Listeners
 
9
  font-family: 'Roboto', Arial, sans-serif;
10
  margin: 0;
11
  padding: 0;
12
+ background: linear-gradient(135deg, #f0f2f5 0%, #e9ecef 100%);
13
+ color: #2d3748;
14
+ line-height: 1.6;
15
  }
16
  .header {
17
+ background: linear-gradient(to right, #1a3c7a, #2957a4);
18
+ padding: 15px 25px;
19
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
20
  position: sticky;
21
  top: 0;
22
  z-index: 100;
 
24
  .header-title {
25
  color: #fff;
26
  margin: 0;
27
+ font-size: 26px;
28
  font-weight: 700;
29
  text-align: center;
30
  padding-bottom: 10px;
 
33
  display: flex;
34
  align-items: center;
35
  justify-content: space-between;
36
+ gap: 20px;
37
  }
38
  .avatar {
39
+ width: 42px;
40
+ height: 42px;
41
+ background: linear-gradient(to right, #f6ad55, #ed8936);
42
  color: #fff;
43
  border-radius: 50%;
44
  display: flex;
 
48
  font-weight: 600;
49
  cursor: pointer;
50
  position: relative;
51
+ transition: transform 0.2s ease;
52
  }
53
  .avatar:hover {
54
+ transform: scale(1.05);
55
+ background: linear-gradient(to right, #ed8936, #dd6b20);
56
  }
57
  .dropdown {
58
  display: none;
 
60
  top: 50px;
61
  right: 0;
62
  background-color: #fff;
63
+ box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1);
64
+ border-radius: 10px;
65
+ min-width: 160px;
66
  z-index: 101;
67
+ overflow: hidden;
68
  }
69
  .dropdown.active {
70
  display: block;
 
72
  .dropdown a {
73
  display: block;
74
  padding: 12px 20px;
75
+ color: #2d3748;
76
  text-decoration: none;
77
+ font-size: 15px;
78
  transition: background 0.3s ease;
79
  }
80
  .dropdown a:hover {
81
+ background-color: #f7fafc;
82
  }
83
  .search-container {
84
  position: relative;
 
87
  }
88
  .search-bar {
89
  width: 100%;
90
+ padding: 12px 45px 12px 20px;
91
+ border: 2px solid #e2e8f0;
92
  border-radius: 25px;
93
+ font-size: 15px;
94
  box-sizing: border-box;
95
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
96
+ background-color: #fff;
97
  }
98
  .search-bar:focus {
99
+ border-color: #ed8936;
100
  outline: none;
101
+ box-shadow: 0 0 8px rgba(237, 137, 54, 0.3);
102
  }
103
  .mic-icon {
104
  position: absolute;
105
+ right: 15px;
106
  top: 50%;
107
  transform: translateY(-50%);
108
+ width: 22px;
109
+ height: 22px;
110
  background: url('https://img.icons8.com/ios-filled/50/000000/microphone.png') no-repeat center;
111
  background-size: contain;
112
  cursor: pointer;
 
122
  left: 0;
123
  right: 0;
124
  background-color: #fff;
125
+ box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1);
126
+ border-radius: 10px;
127
+ max-height: 220px;
128
  overflow-y: auto;
129
  z-index: 100;
130
  display: none;
 
136
  padding: 10px 15px;
137
  margin: 0;
138
  font-size: 14px;
139
+ color: #4a5568;
140
+ border-bottom: 1px solid #edf2f7;
141
+ transition: background 0.2s ease;
142
+ }
143
+ .search-results p:hover {
144
+ background-color: #f7fafc;
145
  }
146
  .search-results p:last-child {
147
  border-bottom: none;
148
  }
149
  .action-bar {
150
  background-color: #fff;
151
+ padding: 15px 25px;
152
  display: flex;
153
  justify-content: center;
154
+ gap: 20px;
155
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
156
  position: sticky;
157
  top: 90px;
158
  z-index: 99;
159
  }
160
  .container {
161
  max-width: 1200px;
162
+ margin: 40px auto;
163
+ padding: 0 25px;
164
  }
165
  .content-grid {
166
  display: grid;
 
170
  }
171
  .section {
172
  padding: 25px;
173
+ background-color: #fff;
174
+ border-radius: 12px;
175
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
176
+ border-left: 5px solid #ed8936;
177
+ transition: transform 0.2s ease, box-shadow 0.3s ease;
178
  }
179
  .section:hover {
180
  transform: translateY(-5px);
181
+ box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1);
182
  }
183
  .section.full-width {
184
  grid-column: span 2;
185
  }
186
  h3 {
187
+ margin: 0 0 20px 0;
188
+ color: #1a3c7a;
189
  font-size: 22px;
190
  font-weight: 600;
191
+ display: flex;
192
+ align-items: center;
193
+ gap: 10px;
194
  }
195
+ h3 i {
196
+ font-size: 20px;
197
+ color: #ed8936;
198
+ }
199
+ /* Daily Checklist Section */
200
+ .checklist-header {
201
+ display: flex;
202
+ justify-content: space-between;
203
+ align-items: center;
204
+ margin-bottom: 20px;
205
+ }
206
+ .progress-circle {
207
+ width: 50px;
208
+ height: 50px;
209
+ background: conic-gradient(#ed8936 var(--progress), #e2e8f0 0);
210
+ border-radius: 50%;
211
+ display: flex;
212
+ align-items: center;
213
+ justify-content: center;
214
+ font-size: 14px;
215
+ font-weight: 600;
216
+ color: #2d3748;
217
+ position: relative;
218
+ }
219
+ .progress-circle::before {
220
+ content: '';
221
+ position: absolute;
222
+ width: 40px;
223
+ height: 40px;
224
  background-color: #fff;
225
+ border-radius: 50%;
226
+ }
227
+ .progress-circle span {
228
+ position: relative;
229
+ z-index: 1;
 
 
230
  }
231
  .checklist-item {
232
  display: flex;
233
  align-items: center;
234
  margin-bottom: 15px;
235
  font-size: 16px;
236
+ padding: 10px;
237
+ border-radius: 8px;
238
+ transition: background 0.2s ease;
239
+ }
240
+ .checklist-item:hover {
241
+ background-color: #f7fafc;
242
  }
243
  .checklist-item input {
244
  width: 20px;
245
  height: 20px;
246
  margin-right: 15px;
247
+ accent-color: #ed8936;
248
+ cursor: pointer;
249
  }
250
  .checklist-item label {
251
  flex: 1;
252
+ color: #4a5568;
253
+ cursor: pointer;
254
+ }
255
+ .checklist-item.completed label {
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;
263
  border-radius: 10px;
264
  margin-bottom: 15px;
265
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05);
266
+ transition: transform 0.2s ease;
267
+ }
268
+ .tip-card:hover {
269
+ transform: translateY(-3px);
270
  }
271
  .tip-card h4 {
272
  margin: 0 0 15px 0;
273
+ color: #1a3c7a;
274
+ font-size: 18px;
275
+ font-weight: 600;
276
  }
277
  .tip-card ul {
278
+ padding-left: 20px;
279
  margin: 0;
280
+ list-style-type: disc;
281
  }
282
  .tip-card li {
283
  margin-bottom: 10px;
284
+ font-size: 15px;
285
+ color: #4a5568;
286
+ }
287
+ /* Supervisor Data Section */
288
+ pre {
289
+ background-color: #f7fafc;
290
+ padding: 15px;
291
+ border: 1px solid #e2e8f0;
292
+ border-radius: 8px;
293
+ white-space: pre-wrap;
294
+ font-size: 15px;
295
+ max-height: 250px;
296
+ overflow-y: auto;
297
+ color: #4a5568;
298
+ }
299
+ /* Reflection Journal Section */
300
+ .reflection-journal {
301
+ display: flex;
302
+ flex-direction: column;
303
+ gap: 20px;
304
+ }
305
+ .reflection-input-area {
306
+ display: flex;
307
+ flex-direction: column;
308
+ gap: 15px;
309
  }
310
  .reflection-journal textarea {
311
  width: 100%;
312
  height: 120px;
313
  padding: 15px;
314
+ border: 2px solid #e2e8f0;
315
+ border-radius: 10px;
316
  resize: none;
317
+ font-size: 15px;
318
  box-sizing: border-box;
319
+ transition: border-color 0.3s ease, box-shadow 0.3s ease;
320
+ background-color: #f7fafc;
321
  }
322
  .reflection-journal textarea:focus {
323
+ border-color: #ed8936;
324
  outline: none;
325
+ box-shadow: 0 0 8px rgba(237, 137, 54, 0.3);
326
  }
327
+ .reflection-history {
328
+ max-height: 200px;
329
+ overflow-y: auto;
330
+ padding: 15px;
331
+ background-color: #f7fafc;
332
+ border-radius: 10px;
333
+ border: 1px solid #e2e8f0;
334
+ }
335
+ .reflection-entry {
336
+ margin-bottom: 15px;
337
+ padding-bottom: 10px;
338
+ border-bottom: 1px solid #e2e8f0;
339
+ font-size: 14px;
340
+ color: #4a5568;
341
+ }
342
+ .reflection-entry:last-child {
343
+ border-bottom: none;
344
+ margin-bottom: 0;
345
+ }
346
+ .reflection-entry span {
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));
354
+ gap: 20px;
355
+ padding: 20px;
356
+ background: linear-gradient(145deg, #fff, #f7fafc);
357
+ border-radius: 12px;
358
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
359
+ }
360
+ .kpi-card {
361
  padding: 20px;
 
362
  border-radius: 10px;
363
+ background-color: #fff;
364
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
365
+ text-align: center;
366
+ transition: transform 0.2s ease;
367
+ }
368
+ .kpi-card:hover {
369
+ transform: translateY(-3px);
370
+ }
371
+ .kpi-card h4 {
372
+ margin: 0 0 10px 0;
373
+ font-size: 16px;
374
+ color: #1a3c7a;
375
+ font-weight: 600;
376
+ }
377
+ .kpi-value {
378
  font-size: 24px;
379
  font-weight: 700;
380
+ color: #ed8936;
381
+ margin-bottom: 10px;
382
  }
383
+ .progress-bar {
384
+ width: 100%;
385
+ height: 8px;
386
+ background-color: #e2e8f0;
387
+ border-radius: 4px;
388
+ overflow: hidden;
389
+ }
390
+ .progress-fill {
391
+ height: 100%;
392
+ background: linear-gradient(to right, #ed8936, #f6ad55);
393
+ transition: width 0.5s ease;
394
+ }
395
+ .kpi-trend {
396
+ font-size: 13px;
397
+ color: #718096;
398
+ margin-top: 8px;
399
+ }
400
+ .kpi-flag {
401
+ display: inline-block;
402
+ padding: 5px 10px;
403
+ border-radius: 5px;
404
+ font-size: 12px;
405
+ font-weight: 600;
406
+ margin-top: 8px;
407
+ }
408
+ .kpi-flag.active {
409
+ background-color: #48bb78;
410
+ color: #fff;
411
  }
412
+ .kpi-flag.inactive {
413
+ background-color: #f56565;
414
+ color: #fff;
415
+ }
416
+ /* Buttons */
417
  button {
418
  padding: 12px 25px;
419
+ background: linear-gradient(to right, #f6ad55, #ed8936);
420
  color: #fff;
421
  border: none;
422
  border-radius: 8px;
423
  cursor: pointer;
424
+ font-size: 15px;
425
  font-weight: 600;
426
  transition: transform 0.1s ease, background 0.3s ease;
427
  }
428
  button:hover {
429
+ background: linear-gradient(to right, #ed8936, #dd6b20);
430
  transform: scale(1.02);
431
  }
432
  .download-btn {
433
+ background: linear-gradient(to right, #38a169, #48bb78);
434
  }
435
  .download-btn:hover {
436
+ background: linear-gradient(to right, #2f855a, #38a169);
437
  }
438
+ /* Toast Notifications */
439
  .toast {
440
  position: fixed;
441
  top: 20px;
 
444
  border-radius: 8px;
445
  z-index: 102;
446
  display: none;
447
+ font-size: 15px;
448
  font-weight: 500;
449
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
450
  }
451
  .toast.error {
452
+ background-color: #f56565;
453
  color: #fff;
454
  }
455
  .toast.success {
456
+ background-color: #48bb78;
457
  color: #fff;
458
  }
459
  .toast.visible {
460
  display: block;
461
  }
462
+ /* Responsive Design */
463
  @media (max-width: 900px) {
464
  .content-grid {
465
  grid-template-columns: 1fr;
 
467
  .section.full-width {
468
  grid-column: span 1;
469
  }
470
+ .kpi-dashboard {
471
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
472
+ }
473
  }
474
  @media (max-width: 700px) {
475
  body {
 
479
  padding: 10px 15px;
480
  }
481
  .header-title {
482
+ font-size: 22px;
483
  padding-bottom: 8px;
484
  }
485
  .header-actions {
 
491
  max-width: 100%;
492
  }
493
  .avatar {
494
+ width: 38px;
495
+ height: 38px;
496
  font-size: 18px;
497
  }
498
  .dropdown {
499
+ top: 48px;
500
+ min-width: 140px;
501
  }
502
  .action-bar {
503
  top: 70px;
504
  flex-direction: column;
505
  gap: 10px;
506
+ padding: 10px 15px;
507
  }
508
  .container {
509
+ padding: 20px 15px;
510
+ margin: 15px 0;
511
  }
512
  h3 {
513
  font-size: 20px;
514
  }
515
  .section {
516
+ padding: 20px;
517
+ }
518
+ .progress-circle {
519
+ width: 40px;
520
+ height: 40px;
521
+ font-size: 12px;
522
+ }
523
+ .progress-circle::before {
524
+ width: 32px;
525
+ height: 32px;
526
  }
527
+ .checklist-item, .tip-card li, .reflection-journal textarea, pre {
528
  font-size: 14px;
529
  }
530
+ .kpi-value {
531
  font-size: 20px;
532
  }
533
+ .kpi-card h4 {
534
+ font-size: 14px;
535
+ }
536
  button {
537
  width: 100%;
538
  padding: 10px;
 
567
 
568
  <div class="action-bar">
569
  <button onclick="generateCoaching()">Generate Coaching Output</button>
570
+ <button class="download-btn" onclick="downloadPDF()" id="download-btn">Download PDF Summary</button>
571
  </div>
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>
579
+ <div class="progress-circle" id="checklist-progress"><span>0%</span></div>
580
+ </div>
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">
600
+ <textarea id="reflection-input" placeholder="Log your reflections for today..."></textarea>
601
+ <button onclick="submitReflection()">Submit Reflection</button>
602
+ </div>
603
+ <div class="reflection-history" id="reflection-history">
604
+ <p>No reflections yet. Start logging your thoughts!</p>
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>
 
622
  <script>
623
  let supervisorData = null;
624
  let coachingOutput = null;
625
+ let reflectionHistory = [];
626
+ let checklistProgress = 0;
627
+ let totalChecklistItems = 0;
628
 
629
  // Toast Notification Function
630
  function showToast(id, message) {
 
704
  searchableContent.push(`Reflection: ${supervisorData.reflection_log}`);
705
  }
706
 
707
+ if (reflectionHistory.length > 0) {
708
+ reflectionHistory.forEach(ref => searchableContent.push(`Past Reflection: ${ref.text}`));
709
+ }
710
+
711
  const results = searchableContent.filter(item => item.toLowerCase().includes(query));
712
 
713
  if (results.length > 0) {
 
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;
736
+ const progressCircle = document.getElementById('checklist-progress');
737
+ progressCircle.style.setProperty('--progress', `${checklistProgress}%`);
738
+ progressCircle.querySelector('span').textContent = `${Math.round(checklistProgress)}%`;
739
+ }
740
+
741
  async function fetchSupervisorData() {
742
  try {
743
  const response = await fetch('/get_supervisor_data');
 
746
  if (result.status === 'success') {
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());
754
+ totalChecklistItems = checklistItems.length;
755
+ checklistDiv.innerHTML = '';
756
+ checklistItems.forEach((item, index) => {
757
+ const itemDiv = document.createElement('div');
758
+ itemDiv.className = 'checklist-item';
759
+ itemDiv.innerHTML = `
760
+ <input type="checkbox" id="checklist-${index}" onchange="markComplete(${index}, this)">
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.';
 
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) {
 
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>';
 
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() {
 
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
  }
 
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