Spaces:
Running
Running
<html lang="en" data-bs-theme="light"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1" /> | |
<title>Educational Assistant Pro</title> | |
<!-- Bootstrap 5 --> | |
<link | |
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" | |
rel="stylesheet" | |
integrity="sha384-c7DF2uX692G1LB+AU6CtQbmu6Ubfbdr6FLllSVEW9v56MZPPiBYkoQ7RZ2hFOTg1" | |
crossorigin="anonymous" | |
/> | |
<!-- Animate.css --> | |
<link | |
rel="stylesheet" | |
href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" | |
/> | |
<!-- AOS --> | |
<link | |
href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css" | |
rel="stylesheet" | |
/> | |
<!-- Font Awesome --> | |
<link | |
rel="stylesheet" | |
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" | |
/> | |
<!-- Google Fonts --> | |
<link | |
href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&family=Montserrat:wght@700;800;900&display=swap" | |
rel="stylesheet" | |
/> | |
<style> | |
:root { | |
--primary: #4361ee; | |
--primary-dark: #3a56d4; | |
--secondary: #06d6a0; | |
--accent: #ef476f; | |
--light: #f8f9fa; | |
--dark: #212529; | |
--white: #ffffff; | |
--border-radius: 12px; | |
--box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12); | |
--transition: all 0.3s ease-in-out; | |
} | |
body { | |
font-family: 'Poppins', sans-serif; | |
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); | |
min-height: 100vh; | |
padding-bottom: 3rem; | |
} | |
.btn { | |
border-radius: 50px; | |
padding: 0.5rem 1.5rem; | |
font-weight: 500; | |
transition: var(--transition); | |
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
} | |
.btn-primary { | |
background: var(--primary); | |
border-color: var(--primary); | |
} | |
.btn-primary:hover, .btn-primary:focus { | |
background: var(--primary-dark); | |
border-color: var(--primary-dark); | |
transform: translateY(-3px); | |
box-shadow: 0 6px 10px rgba(67, 97, 238, 0.3); | |
} | |
.btn-success { | |
background: var(--secondary); | |
border-color: var(--secondary); | |
} | |
.btn-success:hover, .btn-success:focus { | |
background: #05c08e; | |
border-color: #05c08e; | |
transform: translateY(-3px); | |
box-shadow: 0 6px 10px rgba(6, 214, 160, 0.3); | |
} | |
.btn-outline-primary { | |
color: var(--primary); | |
border-color: var(--primary); | |
} | |
.btn-outline-primary:hover { | |
background: var(--primary); | |
color: white; | |
transform: translateY(-2px); | |
box-shadow: 0 4px 8px rgba(67, 97, 238, 0.3); | |
} | |
.card { | |
border: none; | |
border-radius: var(--border-radius); | |
box-shadow: var(--box-shadow); | |
overflow: hidden; | |
transition: var(--transition); | |
background: rgba(255, 255, 255, 0.9); | |
} | |
.card:hover { | |
transform: translateY(-5px); | |
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1); | |
} | |
.form-control, .form-select { | |
border-radius: 8px; | |
padding: 0.75rem 1rem; | |
border: 1px solid #e2e8f0; | |
transition: var(--transition); | |
} | |
.form-control:focus, .form-select:focus { | |
border-color: var(--primary); | |
box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.2); | |
} | |
.navbar { | |
padding: 1rem 1.5rem; | |
background: rgba(255, 255, 255, 0.9) ; | |
backdrop-filter: blur(10px); | |
} | |
.navbar-brand { | |
font-family: 'Montserrat', sans-serif; | |
font-weight: 800; | |
color: var(--primary) ; | |
letter-spacing: -0.5px; | |
} | |
.offcanvas { | |
border-radius: 0 20px 20px 0; | |
} | |
.offcanvas-header { | |
background-color: var(--primary); | |
color: white; | |
padding: 1.5rem; | |
} | |
.offcanvas-header h5 { | |
font-weight: 600; | |
font-family: 'Montserrat', sans-serif; | |
} | |
.offcanvas-body { | |
padding: 1.5rem; | |
} | |
.offcanvas-body ol { | |
counter-reset: item; | |
list-style-type: none; | |
padding-left: 0; | |
} | |
.offcanvas-body ol li { | |
position: relative; | |
padding-left: 2.5rem; | |
margin-bottom: 1.25rem; | |
counter-increment: item; | |
} | |
.offcanvas-body ol li:before { | |
content: counter(item); | |
position: absolute; | |
left: 0; | |
top: -2px; | |
width: 28px; | |
height: 28px; | |
background: var(--primary); | |
color: white; | |
border-radius: 50%; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
font-weight: 600; | |
font-size: 0.875rem; | |
} | |
.offcanvas-body ul { | |
list-style-type: none; | |
padding-left: 0.5rem; | |
margin-top: 0.75rem; | |
} | |
.offcanvas-body ul li { | |
position: relative; | |
padding-left: 1.5rem; | |
margin-bottom: 0.5rem; | |
} | |
.offcanvas-body ul li:before { | |
content: ""; | |
position: absolute; | |
left: 0; | |
top: 8px; | |
width: 8px; | |
height: 8px; | |
background: var(--secondary); | |
border-radius: 50%; | |
} | |
.hero { | |
position: relative; | |
height: 400px; | |
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; | |
border-radius: 0 0 50px 50px; | |
overflow: hidden; | |
margin-bottom: 3rem; | |
} | |
.hero::after { | |
content: ''; | |
position: absolute; | |
bottom: 0; | |
left: 0; | |
width: 100%; | |
height: 100px; | |
background: linear-gradient(to top, rgba(0,0,0,0.2), transparent); | |
} | |
.hero-content { | |
height: 100%; | |
display: flex; | |
flex-direction: column; | |
justify-content: center; | |
padding: 0 3rem; | |
position: relative; | |
z-index: 1; | |
} | |
.hero h1 { | |
font-family: 'Montserrat', sans-serif; | |
font-weight: 800; | |
font-size: 3.5rem; | |
color: white; | |
margin-bottom: 1rem; | |
text-shadow: 0 4px 8px rgba(0,0,0,0.3); | |
} | |
.hero p { | |
color: rgba(255, 255, 255, 0.9); | |
font-size: 1.25rem; | |
max-width: 600px; | |
margin-bottom: 2rem; | |
} | |
/* Animated Shapes */ | |
.shapes { | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
overflow: hidden; | |
z-index: 0; | |
} | |
.shape { | |
position: absolute; | |
opacity: 0.3; | |
} | |
.shape-1 { | |
top: 20%; | |
left: 10%; | |
width: 80px; | |
height: 80px; | |
background: var(--secondary); | |
border-radius: 40% 60% 70% 30% / 40% 50% 60% 50%; | |
animation: float1 8s infinite alternate; | |
} | |
.shape-2 { | |
top: 60%; | |
right: 10%; | |
width: 60px; | |
height: 60px; | |
background: var(--accent); | |
border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; | |
animation: float2 9s infinite alternate; | |
} | |
.shape-3 { | |
bottom: 10%; | |
left: 20%; | |
width: 70px; | |
height: 70px; | |
background: white; | |
border-radius: 50% 50% 20% 80% / 25% 80% 20% 75%; | |
animation: float3 7s infinite alternate; | |
} | |
@keyframes float1 { | |
0% { | |
transform: translateY(0) rotate(0deg); | |
} | |
100% { | |
transform: translateY(-30px) rotate(180deg); | |
} | |
} | |
@keyframes float2 { | |
0% { | |
transform: translateY(0) rotate(0deg); | |
} | |
100% { | |
transform: translateY(40px) rotate(-180deg); | |
} | |
} | |
@keyframes float3 { | |
0% { | |
transform: translateY(0) rotate(0deg); | |
} | |
100% { | |
transform: translateY(-20px) rotate(90deg); | |
} | |
} | |
/* Card Custom Styling */ | |
.card-title { | |
color: var(--primary); | |
font-weight: 600; | |
font-size: 1.25rem; | |
margin-bottom: 1.5rem; | |
display: flex; | |
align-items: center; | |
} | |
.card-title i { | |
margin-right: 0.5rem; | |
color: var(--secondary); | |
} | |
.card-body { | |
padding: 2rem; | |
} | |
.form-label { | |
font-weight: 500; | |
color: var(--dark); | |
margin-bottom: 0.5rem; | |
} | |
#result { | |
min-height: 250px; | |
background: rgba(245, 247, 250, 0.7); | |
border-radius: 8px; | |
padding: 1.5rem; | |
font-size: 0.95rem; | |
line-height: 1.6; | |
color: #333; | |
transition: var(--transition); | |
} | |
.badge-container { | |
display: flex; | |
gap: 0.75rem; | |
margin-top: 1rem; | |
flex-wrap: wrap; | |
} | |
.badge { | |
padding: 0.5rem 1rem; | |
border-radius: 50px; | |
font-weight: 500; | |
font-size: 0.85rem; | |
} | |
.badge-primary { | |
background-color: rgba(67, 97, 238, 0.1); | |
color: var(--primary); | |
} | |
.badge-secondary { | |
background-color: rgba(6, 214, 160, 0.1); | |
color: var(--secondary); | |
} | |
/* Loading Animation */ | |
.loader { | |
display: none; | |
width: 48px; | |
height: 48px; | |
border: 5px solid var(--primary); | |
border-bottom-color: transparent; | |
border-radius: 50%; | |
margin: 2rem auto; | |
animation: rotation 1s linear infinite; | |
} | |
@keyframes rotation { | |
0% { | |
transform: rotate(0deg); | |
} | |
100% { | |
transform: rotate(360deg); | |
} | |
} | |
/* Feature Icons */ | |
.features { | |
display: flex; | |
justify-content: space-around; | |
margin: 3rem 0; | |
} | |
.feature { | |
text-align: center; | |
padding: 1rem; | |
transition: var(--transition); | |
} | |
.feature:hover { | |
transform: translateY(-5px); | |
} | |
.feature i { | |
font-size: 2rem; | |
color: var(--primary); | |
margin-bottom: 1rem; | |
padding: 1rem; | |
background-color: rgba(67, 97, 238, 0.1); | |
border-radius: 50%; | |
width: 4rem; | |
height: 4rem; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
} | |
.feature h5 { | |
color: var(--dark); | |
font-weight: 600; | |
margin-bottom: 0.5rem; | |
} | |
.feature p { | |
color: #6c757d; | |
font-size: 0.9rem; | |
max-width: 200px; | |
margin: 0 auto; | |
} | |
/* Dark Mode Toggle */ | |
.dark-mode-toggle { | |
position: fixed; | |
bottom: 2rem; | |
right: 2rem; | |
width: 50px; | |
height: 50px; | |
border-radius: 50%; | |
background: var(--primary); | |
color: white; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
cursor: pointer; | |
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15); | |
z-index: 1000; | |
transition: var(--transition); | |
} | |
.dark-mode-toggle:hover { | |
transform: scale(1.1); | |
} | |
.dark-mode-toggle i { | |
font-size: 1.25rem; | |
} | |
/* Dark Mode Styles */ | |
[data-bs-theme="dark"] { | |
--light: #212529; | |
--dark: #f8f9fa; | |
} | |
[data-bs-theme="dark"] body { | |
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); | |
color: var(--dark); | |
} | |
[data-bs-theme="dark"] .card { | |
background: rgba(26, 26, 46, 0.8); | |
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3); | |
} | |
[data-bs-theme="dark"] .navbar { | |
background: rgba(26, 26, 46, 0.9) ; | |
} | |
[data-bs-theme="dark"] .form-control, | |
[data-bs-theme="dark"] .form-select { | |
background-color: rgba(255, 255, 255, 0.05); | |
border-color: rgba(255, 255, 255, 0.1); | |
color: var(--dark); | |
} | |
[data-bs-theme="dark"] #result { | |
background: rgba(0, 0, 0, 0.2); | |
color: var(--dark); | |
} | |
[data-bs-theme="dark"] .form-label { | |
color: var(--dark); | |
} | |
[data-bs-theme="dark"] .dark-mode-toggle { | |
background: #ffc107; | |
} | |
[data-bs-theme="dark"] .feature i { | |
background-color: rgba(255, 255, 255, 0.1); | |
} | |
[data-bs-theme="dark"] .feature h5 { | |
color: var(--dark); | |
} | |
[data-bs-theme="dark"] .feature p { | |
color: rgba(255, 255, 255, 0.7); | |
} | |
/* Responsive Adjustments */ | |
@media (max-width: 991.98px) { | |
.hero { | |
height: 350px; | |
} | |
.hero h1 { | |
font-size: 2.5rem; | |
} | |
.features { | |
flex-wrap: wrap; | |
} | |
.feature { | |
width: 50%; | |
margin-bottom: 2rem; | |
} | |
} | |
@media (max-width: 767.98px) { | |
.hero { | |
height: 300px; | |
} | |
.hero h1 { | |
font-size: 2rem; | |
} | |
.hero p { | |
font-size: 1rem; | |
} | |
.feature { | |
width: 100%; | |
} | |
} | |
/* Progress Bar Animation */ | |
.progress-animation { | |
width: 100%; | |
height: 5px; | |
background: linear-gradient(to right, var(--primary), var(--secondary)); | |
position: fixed; | |
top: 0; | |
left: 0; | |
z-index: 9999; | |
animation: progress-grow 0.4s ease; | |
} | |
@keyframes progress-grow { | |
0% { | |
width: 0%; | |
} | |
100% { | |
width: 100%; | |
} | |
} | |
/* Toast Notification Styles */ | |
.toast-container { | |
position: fixed; | |
top: 1rem; | |
right: 1rem; | |
z-index: 9999; | |
} | |
.toast { | |
opacity: 0; | |
transform: translateY(-20px); | |
transition: all 0.3s ease; | |
max-width: 350px; | |
} | |
.toast.show { | |
opacity: 1; | |
transform: translateY(0); | |
} | |
</style> | |
</head> | |
<body> | |
<!-- Progress Bar Animation (appears during loading) --> | |
<div class="progress-animation d-none" id="progressBar"></div> | |
<!-- Toast Notifications Container --> | |
<div class="toast-container" id="toastContainer"></div> | |
<!-- Navbar with sidebar toggle --> | |
<nav class="navbar navbar-light shadow-sm fixed-top"> | |
<div class="container"> | |
<button | |
class="btn btn-outline-primary" | |
type="button" | |
data-bs-toggle="offcanvas" | |
data-bs-target="#sidebar" | |
aria-controls="sidebar" | |
> | |
<i class="fas fa-bars me-2"></i> Instructions | |
</button> | |
<span class="navbar-brand animate__animated animate__fadeIn"> | |
<i class="fas fa-brain me-2"></i> Educational Assistant Pro | |
</span> | |
</div> | |
</nav> | |
<!-- Offcanvas Sidebar --> | |
<div | |
class="offcanvas offcanvas-start" | |
tabindex="-1" | |
id="sidebar" | |
aria-labelledby="sidebarLabel" | |
> | |
<div class="offcanvas-header"> | |
<h5 id="sidebarLabel"><i class="fas fa-book-open me-2"></i> How It Works</h5> | |
<button | |
type="button" | |
class="btn-close btn-close-white" | |
data-bs-dismiss="offcanvas" | |
aria-label="Close" | |
></button> | |
</div> | |
<div class="offcanvas-body"> | |
<ol> | |
<li>Enter your OpenAI API key below (securely stored)</li> | |
<li>Upload a PDF document using the upload button</li> | |
<li>Select one of our AI-powered tools: | |
<ul> | |
<li>Generate Summary - Get a concise overview</li> | |
<li>Generate Quiz - Create practice questions</li> | |
<li>Ask a Question - Get specific answers</li> | |
<li>Generate Study Plan - Create a 7-day curriculum</li> | |
</ul> | |
</li> | |
<li>If asking a question, type it in the field that appears</li> | |
<li>Click "Generate" and download your personalized result</li> | |
</ol> | |
<div class="badge-container"> | |
<span class="badge badge-primary">PDF Processing</span> | |
<span class="badge badge-secondary">AI-Powered</span> | |
<span class="badge badge-primary">Study Tools</span> | |
</div> | |
</div> | |
</div> | |
<!-- Hero Section --> | |
<section class="hero"> | |
<div class="shapes"> | |
<div class="shape shape-1"></div> | |
<div class="shape shape-2"></div> | |
<div class="shape shape-3"></div> | |
</div> | |
<div class="hero-content"> | |
<h1 class="animate__animated animate__fadeInUp">Study Smarter, Not Harder</h1> | |
<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> | |
</div> | |
</section> | |
<!-- Feature Icons --> | |
<div class="container"> | |
<div class="features" data-aos="fade-up" data-aos-delay="200"> | |
<div class="feature"> | |
<i class="fas fa-file-alt"></i> | |
<h5>Summarize</h5> | |
<p>Get concise summaries of any document</p> | |
</div> | |
<div class="feature"> | |
<i class="fas fa-question-circle"></i> | |
<h5>Quiz</h5> | |
<p>Generate practice questions instantly</p> | |
</div> | |
<div class="feature"> | |
<i class="fas fa-lightbulb"></i> | |
<h5>Ask</h5> | |
<p>Get answers to specific questions</p> | |
</div> | |
<div class="feature"> | |
<i class="fas fa-calendar-alt"></i> | |
<h5>Plan</h5> | |
<p>Create customized study schedules</p> | |
</div> | |
</div> | |
</div> | |
<!-- Main Content --> | |
<div class="container mt-5"> | |
<div class="row g-4"> | |
<!-- Controls Column --> | |
<div class="col-lg-4" data-aos="fade-right"> | |
<div class="card"> | |
<div class="card-body"> | |
<h5 class="card-title"><i class="fas fa-cogs"></i> Controls</h5> | |
<div class="mb-4"> | |
<label for="apiKey" class="form-label">OpenAI API Key</label> | |
<div class="input-group"> | |
<span class="input-group-text bg-light"> | |
<i class="fas fa-key"></i> | |
</span> | |
<input | |
type="password" | |
class="form-control" | |
id="apiKey" | |
placeholder="sk-..." | |
/> | |
</div> | |
<small class="text-muted">Your key is stored locally and never sent to our servers</small> | |
</div> | |
<div class="mb-4"> | |
<label for="pdfUpload" class="form-label">Upload PDF</label> | |
<div class="input-group"> | |
<span class="input-group-text bg-light"> | |
<i class="fas fa-file-pdf"></i> | |
</span> | |
<input | |
class="form-control" | |
type="file" | |
id="pdfUpload" | |
accept="application/pdf" | |
/> | |
</div> | |
</div> | |
<div class="mb-4"> | |
<label class="form-label">Choose Tool</label> | |
<select class="form-select" id="optionSelect"> | |
<option value="Generate Summary">Generate Summary</option> | |
<option value="Generate Quiz">Generate Quiz</option> | |
<option value="Ask a Question">Ask a Question</option> | |
<option value="Generate Study Plan">Generate Study Plan</option> | |
</select> | |
</div> | |
<div class="mb-4 d-none" id="questionGroup"> | |
<label for="questionInput" class="form-label">Your Question</label> | |
<div class="input-group"> | |
<span class="input-group-text bg-light"> | |
<i class="fas fa-question"></i> | |
</span> | |
<input | |
type="text" | |
class="form-control" | |
id="questionInput" | |
placeholder="Type your question..." | |
/> | |
</div> | |
</div> | |
<div class="d-grid"> | |
<button class="btn btn-primary" id="generateBtn"> | |
<i class="fas fa-magic me-2"></i> Generate | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Output Column --> | |
<div class="col-lg-8" data-aos="fade-left"> | |
<div class="card"> | |
<div class="card-body"> | |
<h5 class="card-title"><i class="fas fa-clipboard-list"></i> Result</h5> | |
<div class="loader" id="loader"></div> | |
<div id="result"> | |
<!-- AI response appears here --> | |
<div class="text-center text-muted"> | |
<i class="fas fa-robot fa-3x mb-3 text-primary opacity-50"></i> | |
<p>Your results will appear here after generation.</p> | |
</div> | |
</div> | |
<div class="mt-4 text-end"> | |
<button | |
class="btn btn-success d-none" | |
id="downloadBtn" | |
> | |
<i class="fas fa-download me-2"></i> Download as PDF | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Dark Mode Toggle --> | |
<div class="dark-mode-toggle" id="darkModeToggle"> | |
<i class="fas fa-sun"></i> | |
</div> | |
<!-- Scripts --> | |
<!-- Bootstrap JS & dependencies --> | |
<script | |
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" | |
integrity="sha384-E6mRv7/D+K0PtPpK0O1J3DRgIh+tp3loX3f7ogf20+RskmIOrthyxU2048gASBZd" | |
crossorigin="anonymous" | |
></script> | |
<!-- PDF.js --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.min.js"></script> | |
<!-- jsPDF --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script> | |
<!-- AOS --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.js"></script> | |
<script> | |
// Initialize animations | |
AOS.init({ | |
duration: 800, | |
easing: 'ease-in-out', | |
once: true | |
}); | |
// Set up PDF.js | |
const pdfjsLib = window['pdfjs-dist/build/pdf']; | |
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.worker.min.js'; | |
let pdfText = ''; | |
let pdfName = ''; | |
const resultDiv = document.getElementById('result'); | |
const loader = document.getElementById('loader'); | |
const progressBar = document.getElementById('progressBar'); | |
// Add padding to body for fixed navbar | |
document.body.style.paddingTop = '76px'; | |
// Show/hide question input | |
document.getElementById('optionSelect').addEventListener('change', (e) => { | |
const questionGroup = document.getElementById('questionGroup'); | |
if (e.target.value === 'Ask a Question') { | |
questionGroup.classList.remove('d-none'); | |
questionGroup.classList.add('animate__animated', 'animate__fadeIn'); | |
} else { | |
questionGroup.classList.add('d-none'); | |
} | |
}); | |
// Toast notification function | |
function showToast(message, type = 'success') { | |
const toastContainer = document.getElementById('toastContainer'); | |
const toastId = 'toast-' + Date.now(); | |
const bgColor = type === 'success' ? 'bg-success' : type === 'error' ? 'bg-danger' : 'bg-primary'; | |
const icon = type === 'success' ? 'fas fa-check-circle' : type === 'error' ? 'fas fa-exclamation-circle' : 'fas fa-info-circle'; | |
const toastHTML = ` | |
<div class="toast ${bgColor} text-white" id="${toastId}"> | |
<div class="toast-header"> | |
<i class="${icon} me-2"></i> | |
<strong class="me-auto">Educational Assistant</strong> | |
<small>Just now</small> | |
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button> | |
</div> | |
<div class="toast-body"> | |
${message} | |
</div> | |
</div> | |
`; | |
toastContainer.insertAdjacentHTML('beforeend', toastHTML); | |
const toastElement = document.getElementById(toastId); | |
toastElement.classList.add('show'); | |
setTimeout(() => { | |
toastElement.classList.remove('show'); | |
setTimeout(() => toastElement.remove(), 300); | |
}, 5000); | |
} | |
// Load PDF and extract text | |
document.getElementById('pdfUpload').addEventListener('change', async (e) => { | |
const file = e.target.files[0]; | |
if (!file) return; | |
pdfName = file.name.replace('.pdf', ''); | |
// Show loading state | |
resultDiv.innerHTML = `<div class="text-center text-muted"> |