Legal-Docs-AI / templates /index.html
ommore86's picture
Update index.html
59ae4b0
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PDF Chatbot</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="icon" href="favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css"
referrerpolicy="no-referrer">
</head>
<body class="m-0 bg-white">
<div class="bg-gradient-to-b from-indigo-200 via-white to-indigo-100">
<div class="bg-gradient-to-b from-indigo-50 via-white to-indigo-100">
<!-- Header -->
<header class="fixed inset-x-0 top-0 z-50 bg-white/70 backdrop-blur-md shadow-sm">
<div class="max-w-7xl mx-auto px-6 py-3 flex items-center justify-between">
<a href="/" class="text-xl sm:text-2xl font-bold tracking-tight text-indigo-600">
AskBot.AI
</a>
<nav class="hidden sm:flex items-center space-x-6 text-sm font-medium">
<a href="#chat" class="text-gray-600 hover:text-indigo-600 transition">Chat</a>
<a href="#features" class="text-gray-600 hover:text-indigo-600 transition">Features</a>
<a href="#tech" class="text-gray-600 hover:text-indigo-600 transition">Tech</a>
<a href="#connect" class="text-gray-600 hover:text-indigo-600 transition">Connect</a>
</nav>
<button class="sm:hidden inline-flex items-center justify-center h-8 w-8 text-gray-600 hover:text-indigo-600">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
</svg>
</button>
</div>
</header>
<!-- /Header -->
<!-- <main class=""> -->
<section>
<div class="bg-white">
<!-- <div class="relative isolate overflow-hidden bg-gradient-to-b from-gray-200/50"> -->
<div class="mx-auto max-w-7xl pb-16 pt-4 sm:pb-24 lg:grid lg:grid-cols-2 lg:gap-x-8 lg:px-8 lg:py-10">
<div class="px-6 lg:px-0 lg:pt-4">
<div class="mx-auto max-w-2xl">
<div class="max-w-lg">
<h1 class="mt-10 text-4xl font-bold tracking-tight text-gray-900 sm:text-5xl">Upload PDFs, <br>
Research Papers & <br> Ask me Anything!!!</h1>
<p class="mt-6 text-lg leading-8 text-gray-600">My chatbot reads your research paper
or any PDFs and answers questions using AI model.</p>
</div>
</div>
</div>
<div class="mt-20 lg:mt-0 flex justify-center items-center">
<img src="https://res.cloudinary.com/dekujzz4s/image/upload/v1751450446/giphy_sab0e8.webp"
class="drop-shadow-2xl" height="350" width="550" alt="chatbot image">
</div>
</div>
</div>
</div>
</section>
<!-- Chat Section -->
<section id="chat" class="py-20">
<div class="max-w-6xl mx-auto px-6">
<div class="text-center mb-10">
<h2 class="text-3xl font-bold text-gray-800">Chat With Your PDF</h2>
<p class="mt-2 text-gray-600 text-sm">Upload a research paper and ask any question. Powered by AI.</p>
</div>
<div id="uploadChatCard" class="bg-white shadow-xl border border-gray-200 rounded-xl p-6 space-y-6">
<div id="uploader" class="space-y-4 text-center">
<div class="flex items-center justify-center gap-4 flex-col sm:flex-row">
<label for="pdfFile"
class="cursor-pointer bg-indigo-500 hover:bg-indigo-600 text-white px-6 py-2 rounded shadow text-sm transition">
Choose PDF
</label>
<span id="fileNameDisplayText" class="text-sm text-gray-600 italic">No file chosen</span>
<input id="pdfFile" type="file" accept=".pdf" class="hidden">
</div>
<button id="btnUpload" disabled class="bg-indigo-500 hover:bg-indigo-600 text-white px-6 py-2 rounded">
Upload PDF
</button>
</div>
<!-- Chat Interface -->
<div id="chatInterface" class="hidden space-y-4">
<div class="flex justify-between items-center max-w-3xl mx-auto">
<div id="fileNameDisplay" class="text-sm text-gray-600 font-medium italic"></div>
<button id="reuploadBtn" class="text-sm text-indigo-600 hover:underline">
Upload Another PDF
</button>
</div>
<!-- Summarize Section -->
<div class="mt-6">
<div class="mt-2 flex items-start gap-3">
<button id="btnSummarize"
class="bg-indigo-500 hover:bg-indigo-600 text-white px-4 py-2 rounded disabled:opacity-50" disabled>
Summarize PDF
</button>
<div id="summaryBox"
class="flex-1 max-h-64 overflow-y-auto text-sm text-gray-700 p-3 border rounded bg-gray-50 hidden">
</div>
</div>
</div>
<!-- Chat Box -->
<div id="chatBox"
class="space-y-3 max-w-3xl max-h-96 overflow-y-auto px-4 py-4 border rounded-lg bg-white shadow-inner mx-auto">
</div>
<form id="chatForm" class="flex max-w-3xl mx-auto">
<input id="msgInput" autocomplete="off" placeholder="Ask a question..."
class="flex-1 rounded-l-lg border-gray-300 px-4 py-3 shadow" />
<button class="bg-indigo-500 hover:bg-indigo-600 text-white px-6 rounded-r-lg">
Send
</button>
</form>
</div>
</div>
<!-- Result -->
{% if results %}
<div class="mt-6 bg-white p-6 rounded-lg shadow border border-gray-200">
<h2 class="text-lg font-semibold text-gray-800 mb-2">Answer:</h2>
<p class="text-gray-700 whitespace-pre-wrap">{{ results }}</p>
</div>
{% endif %}
</div>
</section>
<!-- Features Section -->
<section id="features" class="py-20">
<div class="max-w-7xl mx-auto px-6">
<div class="text-center mb-12">
<h2 class="text-3xl font-bold text-gray-800">Features</h2>
<p class="mt-2 text-gray-600 text-sm">What makes our PDF Chatbot stand out</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<!-- Instant PDF Reading -->
<div
class="bg-white bg-opacity-80 backdrop-blur-md border border-gray-200 rounded-xl p-6 shadow-lg text-center transition hover:shadow-xl">
<img src="https://res.cloudinary.com/dekujzz4s/image/upload/v1751357240/feature_img_1_nhlopv.jpg"
alt="Feature 1" class="mx-auto h-28 mb-4 object-contain" />
<h3 class="text-xl font-semibold text-gray-800 mb-2">Instant PDF Understanding</h3>
<p class="text-sm text-gray-600">Ask any question and get accurate responses
based on the uploaded PDF content in seconds.</p>
</div>
<!-- Multiple File-Type Support -->
<div
class="bg-white bg-opacity-80 backdrop-blur-md border border-gray-200 rounded-xl p-6 shadow-lg text-center transition hover:shadow-xl">
<img src="https://res.cloudinary.com/dekujzz4s/image/upload/v1751357240/feature_img_2_b8feaa.jpg"
alt="Feature 2" class="mx-auto h-28 mb-4 object-contain" />
<h3 class="text-xl font-semibold text-gray-800 mb-2">Multiple File-Type Support</h3>
<p class="text-sm text-gray-600">Upload research papers, eBooks, or reports —
the chatbot can handle various types of academic PDFs.</p>
</div>
<!-- AI-Powered Accuracy -->
<div
class="bg-white bg-opacity-80 backdrop-blur-md border border-gray-200 rounded-xl p-6 shadow-lg text-center transition hover:shadow-xl">
<img src="https://res.cloudinary.com/dekujzz4s/image/upload/v1751357580/feature_img_3_qeecda.jpg"
alt="Feature 3" class="mx-auto h-28 mb-4 object-contain" />
<h3 class="text-xl font-semibold text-gray-800 mb-2">AI-Powered Accuracy</h3>
<p class="text-sm text-gray-600">Built with powerful AI models to understand complex contexts, summaries,
and
in-depth queries.</p>
</div>
</div>
</div>
</section>
<!-- ========== Tech Stack & AI Models ========== -->
<!-- <section id="tech" class="py-20">
<div class="max-w-7xl mx-auto px-6">
<div class="text-center mb-12">
<h2 class="text-3xl font-bold text-gray-800">Tech Stack &amp; AI Models</h2>
<p class="mt-2 text-gray-600 text-sm">
The key Technologies and AI models that power this chatbot
</p>
</div> -->
<!-- Python and Flask -->
<!-- <div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<div
class="bg-white/80 backdrop-blur-md border border-gray-200 rounded-xl p-6 shadow-lg text-center transition hover:shadow-xl">
<img src="https://cdn-icons-png.flaticon.com/512/5968/5968350.png" alt="Python Flask"
class="mx-auto h-20 mb-4 object-contain" />
<h3 class="text-xl font-semibold text-gray-800 mb-2">Python & Flask</h3>
<p class="text-sm text-gray-600">Handles backend, file uploads & AI Responses.</p>
</div> -->
<!-- LangChain -->
<!-- <div
class="bg-white/80 backdrop-blur-md border border-gray-200 rounded-xl p-6 shadow-lg text-center transition hover:shadow-xl">
<img src="https://res.cloudinary.com/dekujzz4s/image/upload/v1751439498/download_wabh02.png" alt="LangChain"
class="mx-auto h-20 mb-4 object-contain" />
<h3 class="text-xl font-semibold text-gray-800 mb-2">LangChain</h3>
<p class="text-sm text-gray-600">LangChain manages PDF processing & LLM calls.</p>
</div> -->
<!-- Embeddings -->
<!-- <div
class="bg-white/80 backdrop-blur-md border border-gray-200 rounded-xl p-6 shadow-lg text-center transition hover:shadow-xl">
<img src="https://huggingface.co/front/assets/huggingface_logo-noborder.svg" alt="MiniLM Embeddings"
class="mx-auto h-20 mb-4 object-contain" />
<h3 class="text-xl font-semibold text-gray-800 mb-2">Embedding Model: all-MiniLM-L6-v2 </h3>
<p class="text-sm text-gray-600">Converts Text into Numerical Vectors.</p>
</div> -->
<!-- FAISS -->
<!-- <div
class="bg-white/80 backdrop-blur-md border border-gray-200 rounded-xl p-6 shadow-lg text-center transition hover:shadow-xl">
<img src="https://res.cloudinary.com/dekujzz4s/image/upload/v1751439632/download_so6va6.png" alt="FAISS"
class="mx-auto h-20 mb-4 object-contain" />
<h3 class="text-xl font-semibold text-gray-800 mb-2">FAISS Vector Store</h3>
<p class="text-sm text-gray-600">Enables Fast Similarity Search of vectors in PDFs.</p>
</div> -->
<!-- LLM -->
<!-- <div
class="bg-white/80 backdrop-blur-md border border-gray-200 rounded-xl p-6 shadow-lg text-center transition hover:shadow-xl">
<img src="https://res.cloudinary.com/dekujzz4s/image/upload/v1751520819/download_cbh1yx.jpg" alt="Mixtral LLM"
class="mx-auto h-20 mb-4 object-contain" />
<h3 class="text-xl font-semibold text-gray-800 mb-2">LLM: llama-3.1-8b-instant</h3>
<p class="text-sm text-gray-600">Generates correct answers from extracted PDF chunks.</p>
</div> -->
<!-- Tailwind CSS -->
<!-- <div
class="bg-white/80 backdrop-blur-md border border-gray-200 rounded-xl p-6 shadow-lg text-center transition hover:shadow-xl">
<img src="https://res.cloudinary.com/dekujzz4s/image/upload/v1751439818/download_qgtwpn.png"
alt="Tailwind CSS" class="mx-auto h-20 mb-4 object-contain" />
<h3 class="text-xl font-semibold text-gray-800 mb-2">Tailwind CSS</h3>
<p class="text-sm text-gray-600">Stylish and fully responsive frontend.</p>
</div>
</div>
</div>
</section> -->
<!-- </main> -->
</div>
<!-- ========== Connect / Footer Section ========== -->
<footer id="connect" class="w-full bg-gray-900 text-gray-300">
<div class="max-w-7xl mx-auto px-6 py-8 text-center">
<h2 class="text-3xl font-bold text-white mb-2">Connect With Me</h2>
<p class="text-gray-400 mb-8">Feel free to reach out on any platform!</p>
<div class="flex justify-center space-x-8 text-2xl">
<!-- LinkedIn -->
<a href="https://www.linkedin.com/in/om-more-b802b2281/" target="_blank" rel="noopener noreferrer"
class="hover:text-blue-400 transition">
<i class="fa-brands fa-linkedin"></i>
</a>
<!-- GitHub -->
<a href="https://github.com/ommore86/" target="_blank" rel="noopener noreferrer"
class="hover:text-white transition">
<i class="fa-brands fa-github"></i>
</a>
<!-- Email -->
<a href="mailto:omgmore2005@gmail.com" class="hover:text-red-400 transition">
<i class="fa-solid fa-envelope"></i>
</a>
</div>
<div class="mt-10 border-t border-gray-700 pt-6 text-sm text-gray-500">
&copy; 2025 Om More | All rights reserved
</div>
</footer>
<script>
let fileId = null;
const pdfInput = document.getElementById("pdfFile");
const btnUpload = document.getElementById("btnUpload");
pdfInput.onchange = () => {
const file = pdfInput.files[0];
if (file) {
document.getElementById("fileNameDisplayText").textContent = file.name;
btnUpload.disabled = false;
} else {
document.getElementById("fileNameDisplayText").textContent = "No file chosen";
btnUpload.disabled = true;
}
};
btnUpload.onclick = async () => {
const file = pdfInput.files[0];
const formData = new FormData();
formData.append("file", file);
btnUpload.disabled = true;
btnUpload.textContent = "Uploading…";
const res = await fetch("/upload", { method: "POST", body: formData });
const data = await res.json();
if (res.ok) {
fileId = data.file_id;
document.getElementById("fileNameDisplay").textContent = pdfInput.files[0].name;
document.getElementById("uploader").classList.add("hidden");
document.getElementById("chatInterface").classList.remove("hidden");
document.getElementById("fileNameDisplay").textContent = `📄 ${file.name}`;
} else {
alert(data.error || "Upload failed");
btnUpload.disabled = false;
btnUpload.textContent = "Upload PDF";
}
};
// Chat logic
const chatBox = document.getElementById("chatBox");
const chatForm = document.getElementById("chatForm");
const msgInput = document.getElementById("msgInput");
chatForm.addEventListener("submit", async e => {
e.preventDefault();
const q = msgInput.value.trim();
if (!q) return;
appendBubble(q, "user");
msgInput.value = "";
// Showing bubble while waiting
const thinkingBubble = addThinkingBubble();
let answerText = "";
try {
const res = await fetch("/ask", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ question: q, file_id: fileId }),
});
const data = await res.json();
answerText = data.answer || data.error;
} catch (err) {
answerText = "Error fetching answer.";
}
// Replacing placeholder text
thinkingBubble.textContent = answerText;
});
function appendBubble(text, who) {
const bubble = document.createElement("div");
bubble.className = `w-fit rounded-2xl px-5 py-3 shadow break-words
${who === "user"
? "ml-auto bg-indigo-500 text-white"
: "mr-auto bg-gray-200 text-gray-900"}`;
bubble.textContent = text;
chatBox.appendChild(bubble);
chatBox.scrollTop = chatBox.scrollHeight;
return bubble;
}
function addThinkingBubble() {
const bubble = document.createElement("div");
bubble.className = "w-fit rounded-2xl px-5 py-3 shadow mr-auto bg-gray-200 text-gray-900";
bubble.innerHTML = `<span class="animate-pulse">Thinking…</span>`;
chatBox.appendChild(bubble);
chatBox.scrollTop = chatBox.scrollHeight;
return bubble;
}
document.getElementById("reuploadBtn").onclick = () => {
fileId = null;
pdfInput.value = "";
document.getElementById("uploader").classList.remove("hidden");
document.getElementById("chatInterface").classList.add("hidden");
document.getElementById("fileNameDisplay").textContent = "";
document.getElementById("chatBox").innerHTML = "";
btnUpload.disabled = true;
btnUpload.textContent = "Upload PDF";
};
// Sidebar toggle
const sidebar = document.getElementById("sidebar");
const sidebarToggle = document.getElementById("sidebarToggle");
const sidebarFileName = document.getElementById("sidebarFileName");
const btnSummarize = document.getElementById("btnSummarize");
const summaryBox = document.getElementById("summaryBox");
sidebarToggle.onclick = () => {
sidebar.classList.toggle("-translate-x-full");
};
// Update sidebar filename when file is uploaded
btnUpload.onclick = async () => {
const file = pdfInput.files[0];
const formData = new FormData();
formData.append("file", file);
btnUpload.disabled = true;
btnUpload.textContent = "Uploading…";
const res = await fetch("/upload", { method: "POST", body: formData });
const data = await res.json();
if (res.ok) {
fileId = data.file_id;
document.getElementById("fileNameDisplay").textContent = `📄 ${file.name}`;
sidebarFileName.textContent = file.name;
btnSummarize.disabled = false;
document.getElementById("uploader").classList.add("hidden");
document.getElementById("chatInterface").classList.remove("hidden");
} else {
alert(data.error || "Upload failed");
btnUpload.disabled = false;
btnUpload.textContent = "Upload PDF";
}
};
// Summarize logic
btnSummarize.onclick = async () => {
if (!window.currentFileId) {
summaryBox.textContent = "⚠️ Please upload a PDF first.";
summaryBox.classList.remove("hidden");
return;
}
btnSummarize.disabled = true;
btnSummarize.textContent = "Summarizing…";
summaryBox.textContent = "⏳ Generating summary...";
summaryBox.classList.remove("hidden");
try {
const res = await fetch("/summarize", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ file_id: window.currentFileId }),
});
const data = await res.json();
if (res.ok) {
summaryBox.textContent = data.summary || "No summary available.";
} else {
summaryBox.textContent = "❌ " + (data.error || "Summarization failed.");
}
} catch (err) {
summaryBox.textContent = "❌ Error summarizing file.";
}
btnSummarize.disabled = false;
btnSummarize.textContent = "Summarize PDF";
};
</script>
</body>
</html>