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

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +770 -153
index.html CHANGED
@@ -3,7 +3,7 @@
3
  <head>
4
  <meta charset="UTF-8" />
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>Educational Assistant</title>
7
  <!-- Bootstrap 5 -->
8
  <link
9
  href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
@@ -21,31 +21,605 @@
21
  href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css"
22
  rel="stylesheet"
23
  />
 
 
 
 
 
 
 
 
 
 
24
  <style>
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  body {
26
- background: #f8f9fa;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  .hero {
29
- background: url('image.jpeg') center/cover no-repeat;
30
- height: 300px;
31
  position: relative;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  }
 
 
 
 
 
 
 
 
 
 
 
33
  .hero h1 {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  position: absolute;
35
- bottom: 20px;
36
- left: 20px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  color: white;
38
- text-shadow: 0 0 10px rgba(0,0,0,0.7);
 
 
 
 
 
 
39
  }
40
- .offcanvas-body {
41
- padding-top: 1rem;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  }
43
  </style>
44
  </head>
 
45
  <body>
 
 
 
 
 
 
46
  <!-- Navbar with sidebar toggle -->
47
- <nav class="navbar navbar-light bg-white shadow-sm">
48
- <div class="container-fluid">
49
  <button
50
  class="btn btn-outline-primary"
51
  type="button"
@@ -53,9 +627,11 @@
53
  data-bs-target="#sidebar"
54
  aria-controls="sidebar"
55
  >
56
- Instructions
57
  </button>
58
- <span class="navbar-brand mb-0 h1">Educational Assistant</span>
 
 
59
  </div>
60
  </nav>
61
 
@@ -67,83 +643,139 @@
67
  aria-labelledby="sidebarLabel"
68
  >
69
  <div class="offcanvas-header">
70
- <h5 id="sidebarLabel">Instructions</h5>
71
  <button
72
  type="button"
73
- class="btn-close text-reset"
74
  data-bs-dismiss="offcanvas"
75
  aria-label="Close"
76
  ></button>
77
  </div>
78
  <div class="offcanvas-body">
79
  <ol>
80
- <li>Enter your OpenAI API key below (password field).</li>
81
- <li>Upload a PDF via the “Upload PDF” button.</li>
82
- <li>Select one:
83
  <ul>
84
- <li>Generate Summary</li>
85
- <li>Generate Quiz</li>
86
- <li>Ask a Question</li>
87
- <li>Generate Study Plan</li>
88
  </ul>
89
  </li>
90
- <li>If asking a question, type it in.</li>
91
- <li>Click Generate and then download your result as PDF.</li>
92
  </ol>
 
 
 
 
 
93
  </div>
94
  </div>
95
 
96
  <!-- Hero Section -->
97
- <section class="hero mb-4">
98
- <h1 class="animate__animated animate__fadeInDown">Study Smarter</h1>
 
 
 
 
 
 
 
 
99
  </section>
100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  <!-- Main Content -->
102
- <div class="container" data-aos="fade-up">
103
  <div class="row g-4">
104
  <!-- Controls Column -->
105
- <div class="col-lg-4">
106
- <div class="card shadow-sm">
107
  <div class="card-body">
108
- <div class="mb-3">
 
109
  <label for="apiKey" class="form-label">OpenAI API Key</label>
110
- <input
111
- type="password"
112
- class="form-control"
113
- id="apiKey"
114
- placeholder="sk-..."
115
- />
 
 
 
 
 
 
116
  </div>
117
- <div class="mb-3">
118
  <label for="pdfUpload" class="form-label">Upload PDF</label>
119
- <input
120
- class="form-control"
121
- type="file"
122
- id="pdfUpload"
123
- accept="application/pdf"
124
- />
 
 
 
 
 
125
  </div>
126
- <div class="mb-3">
127
- <label class="form-label">Option</label>
128
  <select class="form-select" id="optionSelect">
129
- <option>Generate Summary</option>
130
- <option>Generate Quiz</option>
131
- <option>Ask a Question</option>
132
- <option>Generate Study Plan</option>
133
  </select>
134
  </div>
135
- <div class="mb-3 d-none" id="questionGroup">
136
  <label for="questionInput" class="form-label">Your Question</label>
137
- <input
138
- type="text"
139
- class="form-control"
140
- id="questionInput"
141
- placeholder="Type your question..."
142
- />
 
 
 
 
 
143
  </div>
144
  <div class="d-grid">
145
  <button class="btn btn-primary" id="generateBtn">
146
- Generate
147
  </button>
148
  </div>
149
  </div>
@@ -151,19 +783,24 @@
151
  </div>
152
 
153
  <!-- Output Column -->
154
- <div class="col-lg-8">
155
- <div class="card shadow-sm">
156
  <div class="card-body">
157
- <h5 class="card-title">Result</h5>
158
- <div id="result" style="white-space: pre-wrap; min-height: 200px;">
 
159
  <!-- AI response appears here -->
 
 
 
 
160
  </div>
161
- <div class="mt-3 text-end">
162
  <button
163
  class="btn btn-success d-none"
164
  id="downloadBtn"
165
  >
166
- Download as PDF
167
  </button>
168
  </div>
169
  </div>
@@ -172,6 +809,11 @@
172
  </div>
173
  </div>
174
 
 
 
 
 
 
175
  <!-- Scripts -->
176
  <!-- Bootstrap JS & dependencies -->
177
  <script
@@ -187,99 +829,74 @@
187
  <script src="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.js"></script>
188
 
189
  <script>
190
- AOS.init();
191
- const pdfjsLib = window['pdfjs-dist/build/pdf'];
192
- pdfjsLib.GlobalWorkerOptions.workerSrc =
193
- 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.worker.min.js';
 
 
194
 
 
 
 
 
195
  let pdfText = '';
 
 
 
 
 
 
 
196
 
197
  // Show/hide question input
198
- document
199
- .getElementById('optionSelect')
200
- .addEventListener('change', (e) => {
201
- const qg = document.getElementById('questionGroup');
202
- qg.classList.toggle(
203
- 'd-none',
204
- e.target.value !== 'Ask a Question'
205
- );
206
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
 
208
  // Load PDF and extract text
209
- document
210
- .getElementById('pdfUpload')
211
- .addEventListener('change', async (e) => {
212
- const file = e.target.files[0];
213
- if (!file) return;
214
- const arrayBuffer = await file.arrayBuffer();
215
- const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise;
216
- let fullText = '';
217
- for (let i = 1; i <= pdf.numPages; i++) {
218
- const page = await pdf.getPage(i);
219
- const txt = await page.getTextContent();
220
- fullText += txt.items.map((it) => it.str).join(' ') + '\n\n';
221
- }
222
- pdfText = fullText.trim();
223
- alert('PDF loaded: ' + pdf.numPages + ' pages');
224
- });
225
-
226
- // Generate & display, then prepare PDF download
227
- document
228
- .getElementById('generateBtn')
229
- .addEventListener('click', async () => {
230
- const key = document.getElementById('apiKey').value.trim();
231
- if (!key) return alert('Enter your OpenAI API key.');
232
- if (!pdfText) return alert('Please upload a PDF first.');
233
- const option = document.getElementById('optionSelect').value;
234
- let systemPrompt = '';
235
- let userPrompt = pdfText;
236
- if (option === 'Generate Summary') {
237
- systemPrompt = 'You are a smart assistant. Give a summary of the PDF.';
238
- } else if (option === 'Generate Quiz') {
239
- systemPrompt =
240
- 'You are a smart assistant. Generate 10 multiple-choice quiz questions with 4 options each (include the correct answer).';
241
- } else if (option === 'Ask a Question') {
242
- systemPrompt = 'You are a smart assistant. Answer the user’s question based on the PDF.';
243
- const q = document.getElementById('questionInput').value.trim();
244
- if (!q) return alert('Type your question.');
245
- userPrompt += '\n\nUser question: ' + q;
246
- } else if (option === 'Generate Study Plan') {
247
- systemPrompt =
248
- 'You are a smart assistant. Generate a balanced 7-day study plan dividing PDF content into 7 topics.';
249
- }
250
-
251
- // Call OpenAI
252
- const responseDiv = document.getElementById('result');
253
- responseDiv.textContent = 'Generating…';
254
- const resp = await fetch('https://api.openai.com/v1/chat/completions', {
255
- method: 'POST',
256
- headers: {
257
- 'Content-Type': 'application/json',
258
- Authorization: 'Bearer ' + key,
259
- },
260
- body: JSON.stringify({
261
- model: 'gpt-4o-mini',
262
- messages: [
263
- { role: 'system', content: systemPrompt },
264
- { role: 'user', content: userPrompt },
265
- ],
266
- }),
267
- });
268
- const data = await resp.json();
269
- const text = data.choices[0].message.content.trim();
270
- responseDiv.textContent = text;
271
-
272
- // Generate PDF with jsPDF
273
- const { jsPDF } = window.jspdf;
274
- const doc = new jsPDF();
275
- const lines = doc.splitTextToSize(text, 180);
276
- doc.setFontSize(12);
277
- doc.text(lines, 10, 10);
278
- // Show download button
279
- const dl = document.getElementById('downloadBtn');
280
- dl.classList.remove('d-none');
281
- dl.onclick = () => doc.save(`${option.replace(/ /g, '_')}.pdf`);
282
- });
283
- </script>
284
- </body>
285
- </html>
 
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"
 
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
  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
 
 
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>
 
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>
 
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
 
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">