Study_RAG / index.html
Asalun's picture
Update index.html
f000701 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Study RAG Assistant</title>
<style>
:root {
--primary: #2563EB;
--primary-hover: #1D4ED8;
--bg-body: #F3F4F6;
--bg-white: #FFFFFF;
--text-main: #1F2937;
--text-muted: #6B7280;
--border: #E5E7EB;
--success: #10B981;
--warning: #F59E0B;
--error: #EF4444;
--font-main: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
--font-mono: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
}
* { box-sizing: border-box; }
body { margin: 0; font-family: var(--font-main); background: var(--bg-body); color: var(--text-main); height: 100vh; display: flex; flex-direction: column; overflow: hidden; }
/* --- Header --- */
header {
height: 60px; background: var(--bg-white); border-bottom: 1px solid var(--border);
display: flex; align-items: center; justify-content: space-between; padding: 0 20px;
box-shadow: 0 1px 2px rgba(0,0,0,0.05); z-index: 10;
}
.brand { font-weight: 700; font-size: 18px; color: var(--primary); display: flex; align-items: center; gap: 8px; }
.header-controls { display: flex; gap: 20px; align-items: center; }
.control-group { display: flex; align-items: center; gap: 8px; font-size: 13px; }
select, input[type="number"] {
padding: 4px 8px; border: 1px solid var(--border); border-radius: 4px; font-size: 13px; background: var(--bg-white);
}
.stats-pill {
background: #EEF2FF; color: var(--primary); padding: 4px 12px; border-radius: 99px; font-size: 12px; font-weight: 600;
}
/* --- Layout --- */
.app-container { display: flex; flex: 1; overflow: hidden; }
/* --- Sidebar --- */
aside {
width: 280px; background: var(--bg-white); border-right: 1px solid var(--border);
display: flex; flex-direction: column;
}
.upload-zone {
margin: 15px; padding: 20px; border: 2px dashed var(--border); border-radius: 8px;
text-align: center; color: var(--text-muted); font-size: 13px; cursor: pointer; transition: 0.2s;
}
.upload-zone:hover { border-color: var(--primary); background: #F9FAFB; }
.file-list { flex: 1; overflow-y: auto; padding: 0 15px; }
.file-item {
display: flex; align-items: center; padding: 10px; border-radius: 6px; margin-bottom: 4px;
border: 1px solid transparent; cursor: pointer;
}
.file-item:hover { background: #F9FAFB; }
.file-icon { width: 32px; height: 32px; background: #EFF6FF; color: var(--primary); border-radius: 4px; display: flex; align-items: center; justify-content: center; margin-right: 10px; flex-shrink: 0; }
.file-info { flex: 1; min-width: 0; }
.file-name { font-size: 13px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.file-meta { display: flex; align-items: center; gap: 6px; margin-top: 2px; }
.status-badge { font-size: 10px; padding: 2px 6px; border-radius: 4px; font-weight: 600; }
.status-ready { background: #D1FAE5; color: #065F46; }
.status-indexing { background: #DBEAFE; color: #1E40AF; }
.status-error { background: #FEE2E2; color: #991B1B; }
.file-actions { opacity: 0; transition: 0.2s; }
.file-item:hover .file-actions { opacity: 1; }
.btn-icon { background: none; border: none; cursor: pointer; color: var(--text-muted); padding: 2px; }
.btn-icon:hover { color: var(--text-main); }
.sidebar-footer { padding: 15px; border-top: 1px solid var(--border); }
.toggle-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; font-size: 13px; }
.btn-glossary { width: 100%; padding: 8px; background: var(--bg-body); border: 1px solid var(--border); border-radius: 6px; text-align: left; font-size: 13px; display: flex; justify-content: space-between; cursor: pointer; }
/* --- Main Content --- */
main { flex: 1; display: flex; flex-direction: column; background: #fff; position: relative; }
/* Tabs */
.tabs { display: flex; border-bottom: 1px solid var(--border); background: var(--bg-white); padding: 0 20px; }
.tab-btn {
padding: 15px 20px; background: none; border: none; border-bottom: 2px solid transparent; font-size: 14px; font-weight: 500; color: var(--text-muted); cursor: pointer;
}
.tab-btn.active { color: var(--primary); border-bottom-color: var(--primary); }
.tab-btn:hover { color: var(--text-main); }
/* Tab Content */
.tab-content { display: none; flex: 1; overflow: hidden; flex-direction: column; }
.tab-content.active { display: flex; }
/* --- Chat UI --- */
.chat-area { flex: 1; padding: 20px; overflow-y: auto; background: #FAFAFA; display: flex; flex-direction: column; gap: 20px; }
.message { max-width: 80%; display: flex; flex-direction: column; gap: 6px; }
.message.user { align-self: flex-end; align-items: flex-end; }
.message.ai { align-self: flex-start; align-items: flex-start; }
.bubble {
padding: 12px 16px; border-radius: 12px; font-size: 14px; line-height: 1.5; box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
.user .bubble { background: var(--primary); color: white; border-bottom-right-radius: 2px; }
.ai .bubble { background: white; border: 1px solid var(--border); border-bottom-left-radius: 2px; }
.input-area {
padding: 20px; background: white; border-top: 1px solid var(--border);
}
.quick-actions { display: flex; gap: 8px; margin-bottom: 10px; overflow-x: auto; padding-bottom: 5px; }
.pill { padding: 4px 12px; background: #EFF6FF; color: var(--primary); border-radius: 99px; font-size: 12px; border: 1px solid #BFDBFE; cursor: pointer; white-space: nowrap; }
.pill:hover { background: #DBEAFE; }
.chat-input-wrapper { display: flex; gap: 10px; }
textarea { flex: 1; padding: 10px; border: 1px solid var(--border); border-radius: 8px; resize: none; height: 50px; font-family: inherit; }
.btn-primary { background: var(--primary); color: white; border: none; padding: 0 20px; border-radius: 8px; font-weight: 600; cursor: pointer; }
.btn-primary:hover { background: var(--primary-hover); }
.chat-controls { display: flex; justify-content: space-between; align-items: center; margin-top: 8px; }
.toggle-label { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-muted); cursor: pointer; }
.citation-group { margin-top: 8px; width: 100%; border-top: 1px solid #f0f0f0; padding-top: 8px; }
.citation-trigger { font-size: 11px; color: var(--text-muted); cursor: pointer; display: flex; align-items: center; gap: 4px; }
.citation-trigger:hover { text-decoration: underline; color: var(--primary); }
.citation-details { background: #F8FAFC; border: 1px solid #E2E8F0; padding: 8px; border-radius: 6px; font-size: 12px; margin-top: 4px; font-family: var(--font-mono); color: #334155; display: none; }
.citation-details.open { display: block; }
.source-tag { color: var(--primary); font-weight: 600; cursor: pointer; }
.source-tag:hover { text-decoration: underline; }
.action-buttons { display: flex; gap: 8px; margin-top: 8px; }
.btn-sm { font-size: 11px; padding: 4px 10px; border: 1px solid var(--border); background: white; border-radius: 4px; cursor: pointer; }
.btn-sm:hover { border-color: var(--primary); color: var(--primary); }
/* --- Notes UI --- */
.notes-toolbar { padding: 15px 20px; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: center; background: #fff; }
.notes-content { flex: 1; padding: 40px; overflow-y: auto; max-width: 800px; margin: 0 auto; width: 100%; }
.notes-topic { font-size: 18px; font-weight: 700; margin-bottom: 15px; margin-top: 30px; color: var(--text-main); padding-bottom: 5px; border-bottom: 2px solid var(--primary); display: inline-block; }
.notes-bullet { margin-bottom: 8px; line-height: 1.6; font-size: 15px; display: flex; gap: 8px; }
.citation-ref { font-size: 10px; background: #E5E7EB; padding: 1px 4px; border-radius: 4px; color: var(--text-muted); margin-top: 3px; white-space: nowrap; }
/* --- Quiz UI --- */
.quiz-settings { padding: 20px; background: #F9FAFB; border-bottom: 1px solid var(--border); display: flex; gap: 20px; flex-wrap: wrap; align-items: center; }
.quiz-area { flex: 1; padding: 40px; overflow-y: auto; display: flex; justify-content: center; }
.quiz-card { width: 100%; max-width: 700px; background: white; border: 1px solid var(--border); border-radius: 12px; padding: 30px; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); }
.q-header { display: flex; justify-content: space-between; margin-bottom: 20px; color: var(--text-muted); font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px; }
.q-text { font-size: 18px; font-weight: 600; margin-bottom: 25px; line-height: 1.4; }
.q-options { display: flex; flex-direction: column; gap: 10px; margin-bottom: 20px; }
.q-option { padding: 12px; border: 1px solid var(--border); border-radius: 6px; cursor: pointer; transition: 0.2s; }
.q-option:hover { background: #F3F4F6; }
.q-option.selected { border-color: var(--primary); background: #EFF6FF; }
.reveal-btn { width: 100%; padding: 12px; background: var(--text-main); color: white; border: none; border-radius: 6px; font-weight: 600; cursor: pointer; }
.answer-section { margin-top: 20px; padding-top: 20px; border-top: 1px solid var(--border); display: none; }
.answer-section.visible { display: block; }
.explanation { background: #ECFDF5; color: #064E3B; padding: 15px; border-radius: 6px; font-size: 14px; margin-top: 10px; }
/* --- Modal --- */
.modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); display: none; justify-content: center; align-items: center; z-index: 100; }
.modal { background: white; width: 800px; height: 80vh; border-radius: 12px; display: flex; flex-direction: column; overflow: hidden; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1); }
.modal-header { padding: 15px 20px; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: center; background: #F9FAFB; }
.modal-body { flex: 1; padding: 20px; overflow-y: auto; font-family: var(--font-mono); font-size: 13px; }
.code-cell { background: #1E1E1E; color: #D4D4D4; padding: 15px; border-radius: 6px; margin-bottom: 10px; border-left: 4px solid var(--primary); }
.pdf-page { border: 1px solid #ddd; padding: 20px; margin-bottom: 10px; background: white; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
.highlight { background-color: #FEF08A; padding: 2px 0; }
</style>
</head>
<body>
<header>
<div class="brand">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"></path><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"></path></svg>
Study RAG Assistant
</div>
<div class="header-controls">
<div class="control-group">
<span>Model:</span>
<select><option>GPT-4o</option><option>Claude 3.5 Sonnet</option></select>
</div>
<div class="control-group">
<span>Chunk:</span>
<input type="number" value="512" style="width: 60px">
<span>Overlap:</span>
<input type="number" value="50" style="width: 50px">
</div>
<div class="stats-pill">4 Files • 1,240 Chunks • Indexed 2m ago</div>
</div>
</header>
<div class="app-container">
<!-- Sidebar -->
<aside>
<div class="upload-zone" onclick="alert('Mock Upload: Files added to queue.')">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-bottom:5px"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg>
<br>Drag & Drop <br>.ipynb or .pdf
</div>
<div class="file-list">
<!-- File 1 -->
<div class="file-item">
<div class="file-icon">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>
</div>
<div class="file-info">
<div class="file-name">Deep_Learning_Lec1.pdf</div>
<div class="file-meta">
<span class="status-badge status-ready">Ready</span>
</div>
</div>
<div class="file-actions">
<button class="btn-icon" title="Re-index"></button>
<button class="btn-icon" title="Remove"></button>
</div>
<input type="checkbox" checked style="margin-left: 8px;">
</div>
<!-- File 2 -->
<div class="file-item">
<div class="file-icon">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>
</div>
<div class="file-info">
<div class="file-name">Neural_Nets_Practice.ipynb</div>
<div class="file-meta">
<span class="status-badge status-ready">Ready</span>
</div>
</div>
<div class="file-actions">
<button class="btn-icon" title="Re-index"></button>
<button class="btn-icon" title="Remove"></button>
</div>
<input type="checkbox" checked style="margin-left: 8px;">
</div>
<!-- File 3 (Indexing) -->
<div class="file-item">
<div class="file-icon">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="12" y1="18" x2="12" y2="12"></line><line x1="9 15" x2="15" y2="15"></line></svg>
</div>
<div class="file-info">
<div class="file-name">Stats_Review.pdf</div>
<div class="file-meta">
<span class="status-badge status-indexing">Indexing...</span>
</div>
</div>
<div class="file-actions">
<button class="btn-icon" title="Remove"></button>
</div>
<input type="checkbox" checked style="margin-left: 8px;">
</div>
</div>
<div class="sidebar-footer">
<div class="toggle-row">
<label>Show Selected Only</label>
<input type="checkbox">
</div>
<button class="btn-glossary" onclick="alert('Glossary Drawer would open here.')">
<span>📖 Memory / Glossary</span>
<span></span>
</button>
</div>
</aside>
<!-- Main Content -->
<main>
<div class="tabs">
<button class="tab-btn active" onclick="switchTab('chat')">Chat</button>
<button class="tab-btn" onclick="switchTab('notes')">Notes</button>
<button class="tab-btn" onclick="switchTab('quiz')">Quiz</button>
</div>
<!-- Chat Tab -->
<div id="tab-chat" class="tab-content active">
<div class="chat-area" id="chat-container">
<!-- Welcome Message -->
<div class="message ai">
<div class="bubble">
Hi! I've indexed your Deep Learning and Neural Nets notes. Ask me to explain concepts, generate a quiz, or summarize topics.
</div>
</div>
</div>
<div class="input-area">
<div class="quick-actions">
<div class="pill" onclick="setInput('Explain backpropagation like I\'m 5')">Explain Like I'm 5</div>
<div class="pill" onclick="setInput('Give me 3 code examples of RNNs')">Give Code Examples</div>
<div class="pill" onclick="setInput('What are the key differences between CNN and RNN?')">Compare Concepts</div>
</div>
<div class="chat-input-wrapper">
<textarea id="chat-input" placeholder="Ask a question about your files..."></textarea>
<button class="btn-primary" onclick="sendMessage()">Ask</button>
</div>
<div class="chat-controls">
<label class="toggle-label">
<input type="checkbox" checked> Strictly Grounded (No Guessing)
</label>
</div>
</div>
</div>
<!-- Notes Tab -->
<div id="tab-notes" class="tab-content">
<div class="notes-toolbar">
<button class="btn-primary">Regenerate Notes</button>
<div style="display:flex; gap:10px; align-items:center;">
<span>Format:</span>
<select><option>Bullet Notes</option><option>Cornell Notes</option><option>Outline</option></select>
<button class="btn-sm">Export MD</button>
</div>
</div>
<div class="notes-content">
<div class="notes-topic">1. Introduction to Neural Networks</div>
<div class="notes-bullet">
<span></span>
<div>
Neural networks are computing systems inspired by biological neural networks that constitute animal brains.
<div class="citation-ref" onclick="openPreview('Deep_Learning_Lec1.pdf', 'pg 2')">[Deep_Learning_Lec1.pdf - pg 2]</div>
</div>
</div>
<div class="notes-bullet">
<span></span>
<div>
The fundamental building block is the perceptron, which takes multiple inputs and produces a single output.
<div class="citation-ref" onclick="openPreview('Neural_Nets_Practice.ipynb', 'Cell 4')">[Neural_Nets_Practice.ipynb - Cell 4]</div>
</div>
</div>
<div class="notes-topic">2. Backpropagation</div>
<div class="notes-bullet">
<span></span>
<div>
Backpropagation is a method for calculating the gradient of the loss function with respect to each weight.
<div class="citation-ref" onclick="openPreview('Deep_Learning_Lec1.pdf', 'pg 14')">[Deep_Learning_Lec1.pdf - pg 14]</div>
</div>
</div>
</div>
</div>
<!-- Quiz Tab -->
<div id="tab-quiz" class="tab-content">
<div class="quiz-settings">
<div class="control-group">
<label>Questions:</label>
<input type="range" min="5" max="50" value="10" oninput="this.nextElementSibling.innerText = this.value">
<span>10</span>
</div>
<div class="control-group">
<label>Difficulty:</label>
<div class="pills">
<span class="pill" style="border-color:var(--primary); background:var(--primary); color:white;">Easy</span>
<span class="pill">Medium</span>
<span class="pill">Hard</span>
<span class="pill" style="color:var(--error); border-color:var(--error);">Tricky Exam</span>
</div>
</div>
<div class="control-group">
<label>Type:</label>
<select><option>Multiple Choice</option><option>True/False</option><option>Code Reading</option></select>
</div>
<button class="btn-primary" style="margin-left:auto;">Generate Quiz</button>
</div>
<div class="quiz-area">
<div class="quiz-card">
<div class="q-header">
<span>Question 1 of 10</span>
<span>Difficulty: Medium</span>
</div>
<div class="q-text">
Which of the following activation functions is most commonly used in the output layer of a binary classification problem?
</div>
<div class="q-options">
<div class="q-option" onclick="this.classList.toggle('selected')">A) ReLU</div>
<div class="q-option" onclick="this.classList.toggle('selected')">B) Tanh</div>
<div class="q-option" onclick="this.classList.toggle('selected')">C) Sigmoid</div>
<div class="q-option" onclick="this.classList.toggle('selected')">D) Softmax</div>
</div>
<button class="reveal-btn" onclick="this.nextElementSibling.classList.add('visible')">Reveal Answer</button>
<div class="answer-section">
<div style="font-weight:700; margin-bottom:5px;">Correct Answer: C) Sigmoid</div>
<div class="explanation">
<strong>Explanation:</strong> The Sigmoid function squashes output between 0 and 1, which is perfect for representing probability in binary classification. Softmax is used for multi-class.
<br><br>
<small>Source: <span class="source-tag" onclick="openPreview('Neural_Nets_Practice.ipynb', 'Cell 12')">Neural_Nets_Practice.ipynb - Cell 12</span></small>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
<!-- Preview Modal -->
<div class="modal-overlay" id="preview-modal">
<div class="modal">
<div class="modal-header">
<div style="font-weight:700;" id="modal-title">Source Preview</div>
<button onclick="document.getElementById('preview-modal').style.display='none'" style="border:none;background:none;font-size:18px;cursor:pointer;"></button>
</div>
<div class="modal-body" id="modal-content">
<!-- Content injected via JS -->
</div>
</div>
</div>
<script>
// --- Tab Logic ---
function switchTab(tabId) {
document.querySelectorAll('.tab-content').forEach(el => el.classList.remove('active'));
document.querySelectorAll('.tab-btn').forEach(el => el.classList.remove('active'));
document.getElementById('tab-' + tabId).classList.add('active');
event.target.classList.add('active');
}
// --- Chat Logic ---
function setInput(text) {
document.getElementById('chat-input').value = text;
}
function sendMessage() {
const input = document.getElementById('chat-input');
const text = input.value;
if (!text.trim()) return;
const container = document.getElementById('chat-container');
// User Message
const userMsg = document.createElement('div');
userMsg.className = 'message user';
userMsg.innerHTML = `<div class="bubble">${text}</div>`;
container.appendChild(userMsg);
input.value = '';
// AI Mock Response
setTimeout(() => {
const aiMsg = document.createElement('div');
aiMsg.className = 'message ai';
aiMsg.innerHTML = `
<div class="bubble">
Based on your documents, here is the explanation.
<div class="citation-group">
<div class="citation-trigger" onclick="this.nextElementSibling.classList.toggle('open')">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2v20M2 12h20"></path></svg>
Used 2 sources
</div>
<div class="citation-details">
<div class="source-tag" onclick="openPreview('Deep_Learning_Lec1.pdf', 'pg 5')">Deep_Learning_Lec1.pdf [pg 5]</div>
<div style="margin:4px 0;">"...backpropagation is the key algorithm for training..."</div>
<div class="source-tag" onclick="openPreview('Neural_Nets_Practice.ipynb', 'Cell 8')">Neural_Nets_Practice.ipynb [Cell 8]</div>
</div>
</div>
</div>
<div class="action-buttons">
<button class="btn-sm" onclick="switchTab('notes')">Turn into Notes</button>
<button class="btn-sm" onclick="switchTab('quiz')">Turn into Quiz</button>
</div>
`;
container.appendChild(aiMsg);
container.scrollTop = container.scrollHeight;
}, 600);
}
// --- Preview Logic ---
function openPreview(filename, location) {
const modal = document.getElementById('preview-modal');
const title = document.getElementById('modal-title');
const content = document.getElementById('modal-content');
modal.style.display = 'flex';
title.innerText = `Preview: ${filename} (${location})`;
if (filename.includes('.ipynb')) {
content.innerHTML = `
<div style="color:#aaa; margin-bottom:10px;"># In [${location.replace('Cell ', '')}]:</div>
<div class="code-cell">
def sigmoid(z):
return 1.0 / (1.0 + np.exp(-z))
# This function is the core of the output layer for binary classification.
# It maps any real value into a value between 0 and 1.
</div>
<div style="color:#aaa; margin:10px 0;"># Out:</div>
<div style="background:#eee; padding:10px; font-family:monospace;">
0.5
0.880797...
</div>
`;
} else {
content.innerHTML = `
<div class="pdf-page">
<h3>Chapter 4: Activation Functions</h3>
<p>The sigmoid function is defined mathematically as:</p>
<p style="font-style:italic; color:#555;">σ(z) = 1 / (1 + e⁻ᶻ)</p>
<p>This is crucial for binary classification tasks as it provides a probabilistic interpretation. <span class="highlight">It is the standard choice for the output layer in binary problems.</span> However, it suffers from vanishing gradients in deep networks.</p>
</div>
`;
}
}
</script>
</body>
</html>