shukdevdatta123 commited on
Commit
784356b
·
verified ·
1 Parent(s): 8b0c7f6

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +231 -768
index.html CHANGED
@@ -3,7 +3,11 @@
3
  <head>
4
  <meta charset="UTF-8" />
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>Educational Assistant Pro</title>
 
 
 
 
7
  <!-- Bootstrap 5 -->
8
  <link
9
  href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
@@ -11,615 +15,163 @@
11
  integrity="sha384-c7DF2uX692G1LB+AU6CtQbmu6Ubfbdr6FLllSVEW9v56MZPPiBYkoQ7RZ2hFOTg1"
12
  crossorigin="anonymous"
13
  />
 
14
  <!-- Animate.css -->
15
  <link
16
  rel="stylesheet"
17
  href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"
18
  />
 
19
  <!-- AOS -->
20
  <link
21
  href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css"
22
  rel="stylesheet"
23
  />
24
- <!-- Font Awesome -->
25
- <link
26
- rel="stylesheet"
27
- href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
28
- />
29
- <!-- Google Fonts -->
30
- <link
31
- href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&family=Montserrat:wght@700;800;900&display=swap"
32
- rel="stylesheet"
33
- />
34
  <style>
 
35
  :root {
36
- --primary: #4361ee;
37
- --primary-dark: #3a56d4;
38
- --secondary: #06d6a0;
39
- --accent: #ef476f;
40
- --light: #f8f9fa;
41
- --dark: #212529;
42
- --white: #ffffff;
43
- --border-radius: 12px;
44
- --box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
45
- --transition: all 0.3s ease-in-out;
46
  }
47
 
48
  body {
49
- font-family: 'Poppins', sans-serif;
50
- background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
51
- min-height: 100vh;
52
- padding-bottom: 3rem;
53
- }
54
-
55
- .btn {
56
- border-radius: 50px;
57
- padding: 0.5rem 1.5rem;
58
- font-weight: 500;
59
- transition: var(--transition);
60
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
61
- }
62
-
63
- .btn-primary {
64
- background: var(--primary);
65
- border-color: var(--primary);
66
- }
67
-
68
- .btn-primary:hover, .btn-primary:focus {
69
- background: var(--primary-dark);
70
- border-color: var(--primary-dark);
71
- transform: translateY(-3px);
72
- box-shadow: 0 6px 10px rgba(67, 97, 238, 0.3);
73
- }
74
-
75
- .btn-success {
76
- background: var(--secondary);
77
- border-color: var(--secondary);
78
- }
79
-
80
- .btn-success:hover, .btn-success:focus {
81
- background: #05c08e;
82
- border-color: #05c08e;
83
- transform: translateY(-3px);
84
- box-shadow: 0 6px 10px rgba(6, 214, 160, 0.3);
85
- }
86
-
87
- .btn-outline-primary {
88
- color: var(--primary);
89
- border-color: var(--primary);
90
- }
91
-
92
- .btn-outline-primary:hover {
93
- background: var(--primary);
94
- color: white;
95
- transform: translateY(-2px);
96
- box-shadow: 0 4px 8px rgba(67, 97, 238, 0.3);
97
- }
98
-
99
- .card {
100
- border: none;
101
- border-radius: var(--border-radius);
102
- box-shadow: var(--box-shadow);
103
- overflow: hidden;
104
- transition: var(--transition);
105
- background: rgba(255, 255, 255, 0.9);
106
- }
107
-
108
- .card:hover {
109
- transform: translateY(-5px);
110
- box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
111
- }
112
-
113
- .form-control, .form-select {
114
- border-radius: 8px;
115
- padding: 0.75rem 1rem;
116
- border: 1px solid #e2e8f0;
117
- transition: var(--transition);
118
- }
119
-
120
- .form-control:focus, .form-select:focus {
121
- border-color: var(--primary);
122
- box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.2);
123
- }
124
-
125
- .navbar {
126
- padding: 1rem 1.5rem;
127
- background: rgba(255, 255, 255, 0.9) !important;
128
- backdrop-filter: blur(10px);
129
- }
130
-
131
- .navbar-brand {
132
- font-family: 'Montserrat', sans-serif;
133
- font-weight: 800;
134
- color: var(--primary) !important;
135
- letter-spacing: -0.5px;
136
- }
137
-
138
- .offcanvas {
139
- border-radius: 0 20px 20px 0;
140
- }
141
-
142
- .offcanvas-header {
143
- background-color: var(--primary);
144
- color: white;
145
- padding: 1.5rem;
146
- }
147
-
148
- .offcanvas-header h5 {
149
- font-weight: 600;
150
- font-family: 'Montserrat', sans-serif;
151
- }
152
-
153
- .offcanvas-body {
154
- padding: 1.5rem;
155
- }
156
-
157
- .offcanvas-body ol {
158
- counter-reset: item;
159
- list-style-type: none;
160
- padding-left: 0;
161
- }
162
-
163
- .offcanvas-body ol li {
164
- position: relative;
165
- padding-left: 2.5rem;
166
- margin-bottom: 1.25rem;
167
- counter-increment: item;
168
- }
169
-
170
- .offcanvas-body ol li:before {
171
- content: counter(item);
172
- position: absolute;
173
- left: 0;
174
- top: -2px;
175
- width: 28px;
176
- height: 28px;
177
- background: var(--primary);
178
- color: white;
179
- border-radius: 50%;
180
- display: flex;
181
- align-items: center;
182
- justify-content: center;
183
- font-weight: 600;
184
- font-size: 0.875rem;
185
- }
186
-
187
- .offcanvas-body ul {
188
- list-style-type: none;
189
- padding-left: 0.5rem;
190
- margin-top: 0.75rem;
191
- }
192
-
193
- .offcanvas-body ul li {
194
- position: relative;
195
- padding-left: 1.5rem;
196
- margin-bottom: 0.5rem;
197
- }
198
-
199
- .offcanvas-body ul li:before {
200
- content: "";
201
- position: absolute;
202
- left: 0;
203
- top: 8px;
204
- width: 8px;
205
- height: 8px;
206
- background: var(--secondary);
207
- border-radius: 50%;
208
  }
209
 
 
210
  .hero {
211
  position: relative;
212
- height: 400px;
213
- background: linear-gradient(135deg, rgba(67, 97, 238, 0.9) 0%, rgba(47, 73, 194, 0.9) 100%), url('https://images.unsplash.com/photo-1488190211105-8b0e65b80b4e?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80') center/cover no-repeat;
214
- border-radius: 0 0 50px 50px;
215
- overflow: hidden;
216
- margin-bottom: 3rem;
217
- }
218
-
219
- .hero::after {
220
- content: '';
221
- position: absolute;
222
- bottom: 0;
223
- left: 0;
224
- width: 100%;
225
- height: 100px;
226
- background: linear-gradient(to top, rgba(0,0,0,0.2), transparent);
227
  }
228
-
229
- .hero-content {
230
- height: 100%;
231
- display: flex;
232
- flex-direction: column;
233
- justify-content: center;
234
- padding: 0 3rem;
235
- position: relative;
236
- z-index: 1;
237
- }
238
-
239
  .hero h1 {
240
- font-family: 'Montserrat', sans-serif;
241
- font-weight: 800;
242
- font-size: 3.5rem;
243
- color: white;
244
- margin-bottom: 1rem;
245
- text-shadow: 0 4px 8px rgba(0,0,0,0.3);
246
- }
247
-
248
- .hero p {
249
- color: rgba(255, 255, 255, 0.9);
250
- font-size: 1.25rem;
251
- max-width: 600px;
252
- margin-bottom: 2rem;
253
- }
254
-
255
- /* Animated Shapes */
256
- .shapes {
257
- position: absolute;
258
- top: 0;
259
- left: 0;
260
- width: 100%;
261
- height: 100%;
262
- overflow: hidden;
263
- z-index: 0;
264
- }
265
-
266
- .shape {
267
  position: absolute;
268
- opacity: 0.3;
269
- }
270
-
271
- .shape-1 {
272
- top: 20%;
273
- left: 10%;
274
- width: 80px;
275
- height: 80px;
276
- background: var(--secondary);
277
- border-radius: 40% 60% 70% 30% / 40% 50% 60% 50%;
278
- animation: float1 8s infinite alternate;
279
- }
280
-
281
- .shape-2 {
282
- top: 60%;
283
- right: 10%;
284
- width: 60px;
285
- height: 60px;
286
- background: var(--accent);
287
- border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%;
288
- animation: float2 9s infinite alternate;
289
- }
290
-
291
- .shape-3 {
292
- bottom: 10%;
293
- left: 20%;
294
- width: 70px;
295
- height: 70px;
296
- background: white;
297
- border-radius: 50% 50% 20% 80% / 25% 80% 20% 75%;
298
- animation: float3 7s infinite alternate;
299
- }
300
-
301
- @keyframes float1 {
302
- 0% {
303
- transform: translateY(0) rotate(0deg);
304
- }
305
- 100% {
306
- transform: translateY(-30px) rotate(180deg);
307
- }
308
- }
309
-
310
- @keyframes float2 {
311
- 0% {
312
- transform: translateY(0) rotate(0deg);
313
- }
314
- 100% {
315
- transform: translateY(40px) rotate(-180deg);
316
- }
317
  }
318
 
319
- @keyframes float3 {
320
- 0% {
321
- transform: translateY(0) rotate(0deg);
322
- }
323
- 100% {
324
- transform: translateY(-20px) rotate(90deg);
325
- }
326
  }
327
-
328
- /* Card Custom Styling */
329
- .card-title {
330
- color: var(--primary);
331
  font-weight: 600;
332
- font-size: 1.25rem;
333
- margin-bottom: 1.5rem;
334
- display: flex;
335
- align-items: center;
336
- }
337
-
338
- .card-title i {
339
- margin-right: 0.5rem;
340
- color: var(--secondary);
341
- }
342
-
343
- .card-body {
344
- padding: 2rem;
345
- }
346
-
347
- .form-label {
348
- font-weight: 500;
349
- color: var(--dark);
350
- margin-bottom: 0.5rem;
351
  }
352
-
353
- #result {
354
- min-height: 250px;
355
- background: rgba(245, 247, 250, 0.7);
356
- border-radius: 8px;
357
- padding: 1.5rem;
358
- font-size: 0.95rem;
359
- line-height: 1.6;
360
- color: #333;
361
  transition: var(--transition);
362
  }
363
-
364
- .badge-container {
365
- display: flex;
366
- gap: 0.75rem;
367
- margin-top: 1rem;
368
- flex-wrap: wrap;
369
- }
370
-
371
- .badge {
372
- padding: 0.5rem 1rem;
373
- border-radius: 50px;
374
- font-weight: 500;
375
- font-size: 0.85rem;
376
- }
377
-
378
- .badge-primary {
379
- background-color: rgba(67, 97, 238, 0.1);
380
- color: var(--primary);
381
- }
382
-
383
- .badge-secondary {
384
- background-color: rgba(6, 214, 160, 0.1);
385
- color: var(--secondary);
386
  }
387
 
388
- /* Loading Animation */
389
- .loader {
390
- display: none;
391
- width: 48px;
392
- height: 48px;
393
- border: 5px solid var(--primary);
394
- border-bottom-color: transparent;
395
- border-radius: 50%;
396
- margin: 2rem auto;
397
- animation: rotation 1s linear infinite;
398
  }
399
-
400
- @keyframes rotation {
401
- 0% {
402
- transform: rotate(0deg);
403
- }
404
- 100% {
405
- transform: rotate(360deg);
406
- }
407
  }
408
-
409
- /* Feature Icons */
410
- .features {
411
- display: flex;
412
- justify-content: space-around;
413
- margin: 3rem 0;
414
  }
415
 
416
- .feature {
417
- text-align: center;
418
- padding: 1rem;
 
 
 
419
  transition: var(--transition);
420
  }
421
-
422
- .feature:hover {
423
  transform: translateY(-5px);
 
424
  }
425
-
426
- .feature i {
427
- font-size: 2rem;
428
- color: var(--primary);
429
- margin-bottom: 1rem;
430
- padding: 1rem;
431
- background-color: rgba(67, 97, 238, 0.1);
432
- border-radius: 50%;
433
- width: 4rem;
434
- height: 4rem;
435
- display: flex;
436
- align-items: center;
437
- justify-content: center;
438
- }
439
-
440
- .feature h5 {
441
- color: var(--dark);
442
  font-weight: 600;
443
- margin-bottom: 0.5rem;
444
- }
445
-
446
- .feature p {
447
- color: #6c757d;
448
- font-size: 0.9rem;
449
- max-width: 200px;
450
- margin: 0 auto;
451
  }
452
 
453
- /* Dark Mode Toggle */
454
- .dark-mode-toggle {
455
- position: fixed;
456
- bottom: 2rem;
457
- right: 2rem;
458
- width: 50px;
459
- height: 50px;
460
- border-radius: 50%;
461
- background: var(--primary);
462
- color: white;
463
- display: flex;
464
- align-items: center;
465
- justify-content: center;
466
- cursor: pointer;
467
- box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15);
468
- z-index: 1000;
469
  transition: var(--transition);
470
  }
471
-
472
- .dark-mode-toggle:hover {
473
- transform: scale(1.1);
474
- }
475
-
476
- .dark-mode-toggle i {
477
- font-size: 1.25rem;
478
- }
479
-
480
- /* Dark Mode Styles */
481
- [data-bs-theme="dark"] {
482
- --light: #212529;
483
- --dark: #f8f9fa;
484
- }
485
-
486
- [data-bs-theme="dark"] body {
487
- background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
488
- color: var(--dark);
489
- }
490
-
491
- [data-bs-theme="dark"] .card {
492
- background: rgba(26, 26, 46, 0.8);
493
- box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
494
- }
495
-
496
- [data-bs-theme="dark"] .navbar {
497
- background: rgba(26, 26, 46, 0.9) !important;
498
- }
499
-
500
- [data-bs-theme="dark"] .form-control,
501
- [data-bs-theme="dark"] .form-select {
502
- background-color: rgba(255, 255, 255, 0.05);
503
- border-color: rgba(255, 255, 255, 0.1);
504
- color: var(--dark);
505
- }
506
-
507
- [data-bs-theme="dark"] #result {
508
- background: rgba(0, 0, 0, 0.2);
509
- color: var(--dark);
510
- }
511
-
512
- [data-bs-theme="dark"] .form-label {
513
- color: var(--dark);
514
- }
515
-
516
- [data-bs-theme="dark"] .dark-mode-toggle {
517
- background: #ffc107;
518
- }
519
-
520
- [data-bs-theme="dark"] .feature i {
521
- background-color: rgba(255, 255, 255, 0.1);
522
  }
523
 
524
- [data-bs-theme="dark"] .feature h5 {
525
- color: var(--dark);
 
 
 
 
526
  }
527
-
528
- [data-bs-theme="dark"] .feature p {
529
- color: rgba(255, 255, 255, 0.7);
530
  }
531
-
532
- /* Responsive Adjustments */
533
- @media (max-width: 991.98px) {
534
- .hero {
535
- height: 350px;
536
- }
537
-
538
- .hero h1 {
539
- font-size: 2.5rem;
540
- }
541
-
542
- .features {
543
- flex-wrap: wrap;
544
- }
545
-
546
- .feature {
547
- width: 50%;
548
- margin-bottom: 2rem;
549
- }
550
- }
551
-
552
- @media (max-width: 767.98px) {
553
- .hero {
554
- height: 300px;
555
- }
556
-
557
- .hero h1 {
558
- font-size: 2rem;
559
- }
560
-
561
- .hero p {
562
- font-size: 1rem;
563
- }
564
-
565
- .feature {
566
- width: 100%;
567
- }
568
  }
569
-
570
- /* Progress Bar Animation */
571
- .progress-animation {
572
- width: 100%;
573
- height: 5px;
574
- background: linear-gradient(to right, var(--primary), var(--secondary));
575
- position: fixed;
576
- top: 0;
577
- left: 0;
578
- z-index: 9999;
579
- animation: progress-grow 0.4s ease;
580
  }
581
 
582
- @keyframes progress-grow {
583
- 0% {
584
- width: 0%;
585
- }
586
- 100% {
587
- width: 100%;
588
- }
 
589
  }
590
 
591
- /* Toast Notification Styles */
592
- .toast-container {
593
- position: fixed;
594
- top: 1rem;
595
- right: 1rem;
596
- z-index: 9999;
597
  }
598
-
599
- .toast {
600
- opacity: 0;
601
- transform: translateY(-20px);
602
- transition: all 0.3s ease;
603
- max-width: 350px;
604
  }
605
-
606
- .toast.show {
607
- opacity: 1;
608
- transform: translateY(0);
609
  }
610
  </style>
611
  </head>
612
-
613
  <body>
614
- <!-- Progress Bar Animation (appears during loading) -->
615
- <div class="progress-animation d-none" id="progressBar"></div>
616
-
617
- <!-- Toast Notifications Container -->
618
- <div class="toast-container" id="toastContainer"></div>
619
-
620
- <!-- Navbar with sidebar toggle -->
621
- <nav class="navbar navbar-light shadow-sm fixed-top">
622
- <div class="container">
623
  <button
624
  class="btn btn-outline-primary"
625
  type="button"
@@ -627,15 +179,13 @@
627
  data-bs-target="#sidebar"
628
  aria-controls="sidebar"
629
  >
630
- <i class="fas fa-bars me-2"></i> Instructions
631
  </button>
632
- <span class="navbar-brand animate__animated animate__fadeIn">
633
- <i class="fas fa-brain me-2"></i> Educational Assistant Pro
634
- </span>
635
  </div>
636
  </nav>
637
 
638
- <!-- Offcanvas Sidebar -->
639
  <div
640
  class="offcanvas offcanvas-start"
641
  tabindex="-1"
@@ -643,260 +193,173 @@
643
  aria-labelledby="sidebarLabel"
644
  >
645
  <div class="offcanvas-header">
646
- <h5 id="sidebarLabel"><i class="fas fa-book-open me-2"></i> How It Works</h5>
647
  <button
648
  type="button"
649
- class="btn-close btn-close-white"
650
  data-bs-dismiss="offcanvas"
651
  aria-label="Close"
652
  ></button>
653
  </div>
654
  <div class="offcanvas-body">
655
  <ol>
656
- <li>Enter your OpenAI API key below (securely stored)</li>
657
- <li>Upload a PDF document using the upload button</li>
658
- <li>Select one of our AI-powered tools:
659
  <ul>
660
- <li>Generate Summary - Get a concise overview</li>
661
- <li>Generate Quiz - Create practice questions</li>
662
- <li>Ask a Question - Get specific answers</li>
663
- <li>Generate Study Plan - Create a 7-day curriculum</li>
664
  </ul>
665
  </li>
666
- <li>If asking a question, type it in the field that appears</li>
667
- <li>Click "Generate" and download your personalized result</li>
668
  </ol>
669
- <div class="badge-container">
670
- <span class="badge badge-primary">PDF Processing</span>
671
- <span class="badge badge-secondary">AI-Powered</span>
672
- <span class="badge badge-primary">Study Tools</span>
673
- </div>
674
  </div>
675
  </div>
676
 
677
- <!-- Hero Section -->
678
- <section class="hero">
679
- <div class="shapes">
680
- <div class="shape shape-1"></div>
681
- <div class="shape shape-2"></div>
682
- <div class="shape shape-3"></div>
683
- </div>
684
- <div class="hero-content">
685
- <h1 class="animate__animated animate__fadeInUp">Study Smarter, Not Harder</h1>
686
- <p class="animate__animated animate__fadeInUp animate__delay-1s">Transform your learning experience with our AI-powered study assistant. Upload any PDF and get summaries, quizzes, and personalized study plans in seconds.</p>
687
- </div>
688
- </section>
689
 
690
- <!-- Feature Icons -->
691
- <div class="container">
692
- <div class="features" data-aos="fade-up" data-aos-delay="200">
693
- <div class="feature">
694
- <i class="fas fa-file-alt"></i>
695
- <h5>Summarize</h5>
696
- <p>Get concise summaries of any document</p>
697
- </div>
698
- <div class="feature">
699
- <i class="fas fa-question-circle"></i>
700
- <h5>Quiz</h5>
701
- <p>Generate practice questions instantly</p>
702
- </div>
703
- <div class="feature">
704
- <i class="fas fa-lightbulb"></i>
705
- <h5>Ask</h5>
706
- <p>Get answers to specific questions</p>
707
- </div>
708
- <div class="feature">
709
- <i class="fas fa-calendar-alt"></i>
710
- <h5>Plan</h5>
711
- <p>Create customized study schedules</p>
712
- </div>
713
- </div>
714
- </div>
715
-
716
- <!-- Main Content -->
717
- <div class="container mt-5">
718
  <div class="row g-4">
719
- <!-- Controls Column -->
720
- <div class="col-lg-4" data-aos="fade-right">
721
- <div class="card">
722
- <div class="card-body">
723
- <h5 class="card-title"><i class="fas fa-cogs"></i> Controls</h5>
724
- <div class="mb-4">
725
- <label for="apiKey" class="form-label">OpenAI API Key</label>
726
- <div class="input-group">
727
- <span class="input-group-text bg-light">
728
- <i class="fas fa-key"></i>
729
- </span>
730
- <input
731
- type="password"
732
- class="form-control"
733
- id="apiKey"
734
- placeholder="sk-..."
735
- />
736
- </div>
737
- <small class="text-muted">Your key is stored locally and never sent to our servers</small>
738
- </div>
739
- <div class="mb-4">
740
- <label for="pdfUpload" class="form-label">Upload PDF</label>
741
- <div class="input-group">
742
- <span class="input-group-text bg-light">
743
- <i class="fas fa-file-pdf"></i>
744
- </span>
745
- <input
746
- class="form-control"
747
- type="file"
748
- id="pdfUpload"
749
- accept="application/pdf"
750
- />
751
- </div>
752
- </div>
753
- <div class="mb-4">
754
- <label class="form-label">Choose Tool</label>
755
- <select class="form-select" id="optionSelect">
756
- <option value="Generate Summary">Generate Summary</option>
757
- <option value="Generate Quiz">Generate Quiz</option>
758
- <option value="Ask a Question">Ask a Question</option>
759
- <option value="Generate Study Plan">Generate Study Plan</option>
760
- </select>
761
- </div>
762
- <div class="mb-4 d-none" id="questionGroup">
763
- <label for="questionInput" class="form-label">Your Question</label>
764
- <div class="input-group">
765
- <span class="input-group-text bg-light">
766
- <i class="fas fa-question"></i>
767
- </span>
768
- <input
769
- type="text"
770
- class="form-control"
771
- id="questionInput"
772
- placeholder="Type your question..."
773
- />
774
- </div>
775
- </div>
776
- <div class="d-grid">
777
- <button class="btn btn-primary" id="generateBtn">
778
- <i class="fas fa-magic me-2"></i> Generate
779
- </button>
780
- </div>
781
  </div>
782
  </div>
783
  </div>
784
-
785
- <!-- Output Column -->
786
- <div class="col-lg-8" data-aos="fade-left">
787
- <div class="card">
788
- <div class="card-body">
789
- <h5 class="card-title"><i class="fas fa-clipboard-list"></i> Result</h5>
790
- <div class="loader" id="loader"></div>
791
- <div id="result">
792
- <!-- AI response appears here -->
793
- <div class="text-center text-muted">
794
- <i class="fas fa-robot fa-3x mb-3 text-primary opacity-50"></i>
795
- <p>Your results will appear here after generation.</p>
796
- </div>
797
- </div>
798
- <div class="mt-4 text-end">
799
- <button
800
- class="btn btn-success d-none"
801
- id="downloadBtn"
802
- >
803
- <i class="fas fa-download me-2"></i> Download as PDF
804
- </button>
805
- </div>
806
  </div>
807
  </div>
808
  </div>
809
  </div>
810
  </div>
811
 
812
- <!-- Dark Mode Toggle -->
813
- <div class="dark-mode-toggle" id="darkModeToggle">
814
- <i class="fas fa-sun"></i>
815
- </div>
816
-
817
- <!-- Scripts -->
818
- <!-- Bootstrap JS & dependencies -->
819
  <script
820
  src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
821
  integrity="sha384-E6mRv7/D+K0PtPpK0O1J3DRgIh+tp3loX3f7ogf20+RskmIOrthyxU2048gASBZd"
822
  crossorigin="anonymous"
823
  ></script>
824
- <!-- PDF.js -->
825
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.min.js"></script>
826
- <!-- jsPDF -->
827
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
828
- <!-- AOS -->
829
  <script src="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.js"></script>
830
 
831
  <script>
832
- // Initialize animations
833
- AOS.init({
834
- duration: 800,
835
- easing: 'ease-in-out',
836
- once: true
837
- });
838
-
839
- // Set up PDF.js
840
  const pdfjsLib = window['pdfjs-dist/build/pdf'];
841
- pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.worker.min.js';
842
-
843
- let pdfText = '';
844
- let pdfName = '';
845
- const resultDiv = document.getElementById('result');
846
- const loader = document.getElementById('loader');
847
- const progressBar = document.getElementById('progressBar');
848
 
849
- // Add padding to body for fixed navbar
850
- document.body.style.paddingTop = '76px';
851
 
852
- // Show/hide question input
853
  document.getElementById('optionSelect').addEventListener('change', (e) => {
854
- const questionGroup = document.getElementById('questionGroup');
855
- if (e.target.value === 'Ask a Question') {
856
- questionGroup.classList.remove('d-none');
857
- questionGroup.classList.add('animate__animated', 'animate__fadeIn');
858
- } else {
859
- questionGroup.classList.add('d-none');
860
- }
861
  });
862
 
863
- // Toast notification function
864
- function showToast(message, type = 'success') {
865
- const toastContainer = document.getElementById('toastContainer');
866
- const toastId = 'toast-' + Date.now();
867
- const bgColor = type === 'success' ? 'bg-success' : type === 'error' ? 'bg-danger' : 'bg-primary';
868
- const icon = type === 'success' ? 'fas fa-check-circle' : type === 'error' ? 'fas fa-exclamation-circle' : 'fas fa-info-circle';
869
-
870
- const toastHTML = `
871
- <div class="toast ${bgColor} text-white" id="${toastId}">
872
- <div class="toast-header">
873
- <i class="${icon} me-2"></i>
874
- <strong class="me-auto">Educational Assistant</strong>
875
- <small>Just now</small>
876
- <button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
877
- </div>
878
- <div class="toast-body">
879
- ${message}
880
- </div>
881
- </div>
882
- `;
883
-
884
- toastContainer.insertAdjacentHTML('beforeend', toastHTML);
885
- const toastElement = document.getElementById(toastId);
886
- toastElement.classList.add('show');
887
-
888
- setTimeout(() => {
889
- toastElement.classList.remove('show');
890
- setTimeout(() => toastElement.remove(), 300);
891
- }, 5000);
892
- }
893
-
894
- // Load PDF and extract text
895
  document.getElementById('pdfUpload').addEventListener('change', async (e) => {
896
  const file = e.target.files[0];
897
  if (!file) return;
898
-
899
- pdfName = file.name.replace('.pdf', '');
900
-
901
- // Show loading state
902
- resultDiv.innerHTML = `<div class="text-center text-muted">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  <head>
4
  <meta charset="UTF-8" />
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>Educational Assistant</title>
7
+
8
+ <!-- Google Font -->
9
+ <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet"/>
10
+
11
  <!-- Bootstrap 5 -->
12
  <link
13
  href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
 
15
  integrity="sha384-c7DF2uX692G1LB+AU6CtQbmu6Ubfbdr6FLllSVEW9v56MZPPiBYkoQ7RZ2hFOTg1"
16
  crossorigin="anonymous"
17
  />
18
+
19
  <!-- Animate.css -->
20
  <link
21
  rel="stylesheet"
22
  href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"
23
  />
24
+
25
  <!-- AOS -->
26
  <link
27
  href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css"
28
  rel="stylesheet"
29
  />
30
+
 
 
 
 
 
 
 
 
 
31
  <style>
32
+ /* ========== CSS VARIABLES ========== */
33
  :root {
34
+ --clr-primary: #6C63FF;
35
+ --clr-secondary: #FF6584;
36
+ --clr-bg: #F4F7FF;
37
+ --clr-card-bg: rgba(255, 255, 255, 0.65);
38
+ --clr-text: #333;
39
+ --transition: 0.3s ease-in-out;
40
+ --font: 'Poppins', sans-serif;
 
 
 
41
  }
42
 
43
  body {
44
+ margin: 0;
45
+ font-family: var(--font);
46
+ background: var(--clr-bg);
47
+ color: var(--clr-text);
48
+ overflow-x: hidden;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  }
50
 
51
+ /* ===== HERO ===== */
52
  .hero {
53
  position: relative;
54
+ height: 300px;
55
+ background: linear-gradient(135deg, rgba(108,99,255,0.8), rgba(255,101,132,0.8)),
56
+ url('image.jpeg') center/cover no-repeat;
 
 
 
 
 
 
 
 
 
 
 
 
57
  }
 
 
 
 
 
 
 
 
 
 
 
58
  .hero h1 {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  position: absolute;
60
+ bottom: 30px;
61
+ left: 30px;
62
+ font-size: 3rem;
63
+ color: #fff;
64
+ text-shadow: 0 3px 10px rgba(0,0,0,0.4);
65
+ margin: 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  }
67
 
68
+ /* ===== NAVBAR ===== */
69
+ .navbar {
70
+ background: #fff;
71
+ box-shadow: 0 2px 6px rgba(0,0,0,0.05);
 
 
 
72
  }
73
+ .navbar-brand {
 
 
 
74
  font-weight: 600;
75
+ color: var(--clr-primary) !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  }
77
+ .btn-outline-primary {
78
+ border-color: var(--clr-primary);
79
+ color: var(--clr-primary);
 
 
 
 
 
 
80
  transition: var(--transition);
81
  }
82
+ .btn-outline-primary:hover {
83
+ background: var(--clr-primary);
84
+ color: #fff;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  }
86
 
87
+ /* ===== OFFCANVAS ===== */
88
+ .offcanvas {
89
+ backdrop-filter: blur(4px);
 
 
 
 
 
 
 
90
  }
91
+ .offcanvas-header {
92
+ border-bottom: 1px solid rgba(0,0,0,0.1);
 
 
 
 
 
 
93
  }
94
+ .offcanvas-body ol {
95
+ padding-left: 1rem;
 
 
 
 
96
  }
97
 
98
+ /* ===== CARDS ===== */
99
+ .card {
100
+ background: var(--clr-card-bg);
101
+ backdrop-filter: blur(8px);
102
+ border: none;
103
+ border-radius: 1rem;
104
  transition: var(--transition);
105
  }
106
+ .card:hover {
 
107
  transform: translateY(-5px);
108
+ box-shadow: 0 10px 30px rgba(0,0,0,0.1);
109
  }
110
+ .card-title {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  font-weight: 600;
112
+ color: var(--clr-primary);
 
 
 
 
 
 
 
113
  }
114
 
115
+ /* ===== FORM ELEMENTS ===== */
116
+ .form-control, .form-select {
117
+ border-radius: 0.75rem;
118
+ box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
 
 
 
 
 
 
 
 
 
 
 
 
119
  transition: var(--transition);
120
  }
121
+ .form-control:focus, .form-select:focus {
122
+ border-color: var(--clr-primary);
123
+ box-shadow: 0 0 0 0.2rem rgba(108,99,255,0.25);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  }
125
 
126
+ /* ===== BUTTONS ===== */
127
+ .btn-primary {
128
+ background: linear-gradient(135deg, var(--clr-primary), var(--clr-secondary));
129
+ border: none;
130
+ border-radius: 0.75rem;
131
+ transition: var(--transition);
132
  }
133
+ .btn-primary:hover {
134
+ transform: scale(1.05);
135
+ box-shadow: 0 8px 20px rgba(108,99,255,0.3);
136
  }
137
+ .btn-success {
138
+ background: var(--clr-primary);
139
+ border: none;
140
+ border-radius: 0.75rem;
141
+ transition: var(--transition);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  }
143
+ .btn-success:hover {
144
+ background: var(--clr-secondary);
145
+ transform: translateY(-2px);
 
 
 
 
 
 
 
 
146
  }
147
 
148
+ /* ===== RESULT BOX ===== */
149
+ #result {
150
+ background: #fff;
151
+ padding: 1rem;
152
+ border-radius: 0.75rem;
153
+ min-height: 200px;
154
+ box-shadow: inset 0 2px 5px rgba(0,0,0,0.05);
155
+ white-space: pre-wrap;
156
  }
157
 
158
+ /* ===== SCROLLBAR ===== */
159
+ ::-webkit-scrollbar {
160
+ width: 8px;
 
 
 
161
  }
162
+ ::-webkit-scrollbar-track {
163
+ background: #f1f1f1;
 
 
 
 
164
  }
165
+ ::-webkit-scrollbar-thumb {
166
+ background: var(--clr-primary);
167
+ border-radius: 4px;
 
168
  }
169
  </style>
170
  </head>
 
171
  <body>
172
+ <!-- NAVBAR -->
173
+ <nav class="navbar navbar-light">
174
+ <div class="container-fluid">
 
 
 
 
 
 
175
  <button
176
  class="btn btn-outline-primary"
177
  type="button"
 
179
  data-bs-target="#sidebar"
180
  aria-controls="sidebar"
181
  >
182
+ Instructions
183
  </button>
184
+ <span class="navbar-brand mb-0 h1">Educational Assistant</span>
 
 
185
  </div>
186
  </nav>
187
 
188
+ <!-- OFFCANVAS SIDEBAR -->
189
  <div
190
  class="offcanvas offcanvas-start"
191
  tabindex="-1"
 
193
  aria-labelledby="sidebarLabel"
194
  >
195
  <div class="offcanvas-header">
196
+ <h5 id="sidebarLabel">How to Use</h5>
197
  <button
198
  type="button"
199
+ class="btn-close"
200
  data-bs-dismiss="offcanvas"
201
  aria-label="Close"
202
  ></button>
203
  </div>
204
  <div class="offcanvas-body">
205
  <ol>
206
+ <li>Enter your OpenAI API key.</li>
207
+ <li>Upload a PDF file.</li>
208
+ <li>Select one of:
209
  <ul>
210
+ <li>Generate Summary</li>
211
+ <li>Generate Quiz</li>
212
+ <li>Ask a Question</li>
213
+ <li>Generate Study Plan</li>
214
  </ul>
215
  </li>
216
+ <li>If “Ask a Question,” type it in the field.</li>
217
+ <li>Click Generate and download the PDF.</li>
218
  </ol>
 
 
 
 
 
219
  </div>
220
  </div>
221
 
222
+ <!-- HERO -->
223
+ <section class="hero animate__animated animate__fadeIn"></section>
 
 
 
 
 
 
 
 
 
 
224
 
225
+ <!-- MAIN -->
226
+ <div class="container my-5" data-aos="fade-up">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  <div class="row g-4">
228
+ <!-- CONTROLS -->
229
+ <div class="col-lg-4">
230
+ <div class="card p-4">
231
+ <div class="mb-3">
232
+ <label for="apiKey" class="form-label">OpenAI API Key</label>
233
+ <input type="password" class="form-control" id="apiKey" placeholder="sk-..." />
234
+ </div>
235
+ <div class="mb-3">
236
+ <label for="pdfUpload" class="form-label">Upload PDF</label>
237
+ <input class="form-control" type="file" id="pdfUpload" accept="application/pdf" />
238
+ </div>
239
+ <div class="mb-3">
240
+ <label for="optionSelect" class="form-label">Option</label>
241
+ <select class="form-select" id="optionSelect">
242
+ <option>Generate Summary</option>
243
+ <option>Generate Quiz</option>
244
+ <option>Ask a Question</option>
245
+ <option>Generate Study Plan</option>
246
+ </select>
247
+ </div>
248
+ <div class="mb-3 d-none" id="questionGroup">
249
+ <label for="questionInput" class="form-label">Your Question</label>
250
+ <input type="text" class="form-control" id="questionInput" placeholder="Type your question..." />
251
+ </div>
252
+ <div class="d-grid">
253
+ <button class="btn btn-primary" id="generateBtn">Generate</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
  </div>
255
  </div>
256
  </div>
257
+ <!-- OUTPUT -->
258
+ <div class="col-lg-8">
259
+ <div class="card p-4">
260
+ <h5 class="card-title">Result</h5>
261
+ <div id="result"></div>
262
+ <div class="mt-3 text-end">
263
+ <button class="btn btn-success d-none" id="downloadBtn">Download as PDF</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
  </div>
265
  </div>
266
  </div>
267
  </div>
268
  </div>
269
 
270
+ <!-- SCRIPTS -->
 
 
 
 
 
 
271
  <script
272
  src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
273
  integrity="sha384-E6mRv7/D+K0PtPpK0O1J3DRgIh+tp3loX3f7ogf20+RskmIOrthyxU2048gASBZd"
274
  crossorigin="anonymous"
275
  ></script>
 
276
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.min.js"></script>
 
277
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
 
278
  <script src="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.js"></script>
279
 
280
  <script>
281
+ AOS.init();
 
 
 
 
 
 
 
282
  const pdfjsLib = window['pdfjs-dist/build/pdf'];
283
+ pdfjsLib.GlobalWorkerOptions.workerSrc =
284
+ 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.worker.min.js';
 
 
 
 
 
285
 
286
+ let pdfText = '';
 
287
 
288
+ // Toggle question field
289
  document.getElementById('optionSelect').addEventListener('change', (e) => {
290
+ document.getElementById('questionGroup')
291
+ .classList.toggle('d-none', e.target.value !== 'Ask a Question');
 
 
 
 
 
292
  });
293
 
294
+ // Load PDF text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295
  document.getElementById('pdfUpload').addEventListener('change', async (e) => {
296
  const file = e.target.files[0];
297
  if (!file) return;
298
+ const buffer = await file.arrayBuffer();
299
+ const pdf = await pdfjsLib.getDocument({ data: buffer }).promise;
300
+ let text = '';
301
+ for (let i = 1; i <= pdf.numPages; i++) {
302
+ const page = await pdf.getPage(i);
303
+ const content = await page.getTextContent();
304
+ text += content.items.map((it) => it.str).join(' ') + '\\n\\n';
305
+ }
306
+ pdfText = text.trim();
307
+ alert(`PDF loaded: ${pdf.numPages} pages`);
308
+ });
309
+
310
+ // Generate & download
311
+ document.getElementById('generateBtn').addEventListener('click', async () => {
312
+ const key = document.getElementById('apiKey').value.trim();
313
+ if (!key) return alert('Please enter your OpenAI API key.');
314
+ if (!pdfText) return alert('Please upload a PDF first.');
315
+
316
+ const opt = document.getElementById('optionSelect').value;
317
+ let sys = '', user = pdfText;
318
+ if (opt === 'Generate Summary') {
319
+ sys = 'You are a smart assistant. Give a summary of the PDF.';
320
+ } else if (opt === 'Generate Quiz') {
321
+ sys = 'You are a smart assistant. Generate 10 multiple-choice quiz questions with 4 options each (include the correct answer).';
322
+ } else if (opt === 'Ask a Question') {
323
+ sys = 'You are a smart assistant. Answer the user’s question based on the PDF.';
324
+ const q = document.getElementById('questionInput').value.trim();
325
+ if (!q) return alert('Please type your question.');
326
+ user += '\\n\\nUser question: ' + q;
327
+ } else {
328
+ sys = 'You are a smart assistant. Generate a balanced 7-day study plan dividing PDF content into 7 topics.';
329
+ }
330
+
331
+ // Call OpenAI
332
+ const resDiv = document.getElementById('result');
333
+ resDiv.textContent = 'Generating…';
334
+ const resp = await fetch('https://api.openai.com/v1/chat/completions', {
335
+ method: 'POST',
336
+ headers: {
337
+ 'Content-Type': 'application/json',
338
+ Authorization: 'Bearer ' + key,
339
+ },
340
+ body: JSON.stringify({
341
+ model: 'gpt-4o-mini',
342
+ messages: [
343
+ { role: 'system', content: sys },
344
+ { role: 'user', content: user },
345
+ ],
346
+ }),
347
+ });
348
+ const data = await resp.json();
349
+ const text = data.choices[0].message.content.trim();
350
+ resDiv.textContent = text;
351
+
352
+ // Prepare PDF
353
+ const { jsPDF } = window.jspdf;
354
+ const doc = new jsPDF();
355
+ const lines = doc.splitTextToSize(text, 180);
356
+ doc.setFontSize(12);
357
+ doc.text(lines, 10, 10);
358
+
359
+ const dlBtn = document.getElementById('downloadBtn');
360
+ dlBtn.classList.remove('d-none');
361
+ dlBtn.onclick = () => doc.save(`${opt.replace(/ /g, '_')}.pdf`);
362
+ });
363
+ </script>
364
+ </body>
365
+ </html>