PRMSChallenge / web /analyzer.html
Vineela Gampa
fixing analyzer
65626dc unverified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document Analyzer | CTRL + ALT + HEAL</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body class="bg-[var(--latte-cream)] font-sans text-gray-800 min-h-screen">
<!-- NAVBAR -->
<nav
class="fixed top-0 left-0 w-full z-50 backdrop-blur-md bg-white/20 border-b border-white/30 shadow-md"
>
<div class="flex items-center px-6 py-4 max-w-7xl mx-auto">
<a
href="index.html"
class="text-2xl font-bold text-black hover:text-[var(--tropical-indigo)] transition"
>CTRL + ALT + HEAL</a
>
<!-- Desktop Links -->
<ul class="hidden md:flex space-x-6 font-medium text-gray-800 ml-auto">
<li><a href="index.html" class="nav-link">Home</a></li>
<li><a href="profile.html" class="nav-link">Profile</a></li>
<li><a href="analyzer.html" class="nav-link">Analyzer</a></li>
<li><a href="past_data.html" class="nav-link">Past Reports</a></li>
<li id="authNavItem">
<a href="login.html" class="nav-link">Login</a>
</li>
</ul>
<!-- Hamburger Menu -->
<button
id="hamburger"
class="md:hidden text-[var(--latte-cream)] text-2xl ml-auto"
>
</button>
</div>
<!-- Mobile Menu -->
<ul
id="mobile-menu"
class="hidden flex-col space-y-4 bg-white/30 backdrop-blur-lg border border-white/20 rounded-xl shadow-lg mt-2 p-4 mx-6 md:hidden"
>
<li><a href="index.html" class="block nav-link">Home</a></li>
<li><a href="analyzer.html" class="block nav-link">Analyzer</a></li>
<li><a href="profile.html" class="block nav-link">Profile</a></li>
<li><a href="login.html" class="block nav-link">Login</a></li>
<li><a href="about.html" class="block nav-link">About</a></li>
</ul>
</nav>
<!-- Shared helpers -->
<script src="script.js"></script>
<script>
const hamburger = document.getElementById("hamburger");
const mobileMenu = document.getElementById("mobile-menu");
hamburger.addEventListener("click", () =>
mobileMenu.classList.toggle("hidden")
);
// Active page underline
const currentPath = window.location.pathname.split("/").pop();
document.querySelectorAll(".nav-link").forEach((link) => {
if (link.getAttribute("href") === currentPath)
link.classList.add("active-page");
});
</script>
<main class="max-w-5xl mx-auto px-4 mb-16 pt-24">
<!-- Upload Section -->
<div class="bg-white border border-gray-200 rounded-lg p-6 shadow mb-6">
<h2 class="text-xl font-semibold mb-4">
Upload & Analyze Your Medical PDF or Image
</h2>
<input
type="file"
id="pdf-upload"
accept=".pdf, image/*"
class="w-full mb-4 rounded px-3 py-2"
/>
<button id="analyze-btn" class="btn-primary px-4 py-2 rounded">
Analyze with AI
</button>
<p id="loading" class="text-gray-600 mt-2">No file uploaded yet.</p>
<p id="auth-status" class="text-sm text-gray-500 mt-1">
Sign in to save and view past analyses.
</p>
</div>
<!-- Extracted Text -->
<!-- <div
class="bg-[var(--latte-cream)] border border-[var(--wisteria)] rounded-lg p-6 mb-8"
>
<h3 class="text-lg font-semibold mb-3">Extracted Text</h3>
<div
id="text-output"
class="whitespace-pre-wrap h-60 overflow-auto bg-[#FAFBFC] text-sm border border-[var(--wisteria)] rounded p-4"
>
OCR results will appear here.
</div>
</div> -->
<!-- AI Findings -->
<div
class="bg-[var(--latte-cream)] border border-[var(--wisteria)] rounded-lg p-6 mb-8"
>
<h3 class="text-lg font-semibold mb-3">AI Findings</h3>
<div
id="recommendations-output"
class="bg-[#F9FAFB] text-sm border border-[var(--wisteria)] rounded p-4 space-y-4"
>
Findings and Recommendations will appear here.
</div>
</div>
</main>
<!-- Floating Chat Button -->
<button
id="chat-toggle"
class="fixed bottom-6 right-6 bg-[var(--tropical-indigo)] text-white px-5 py-3 rounded-full shadow-lg hover:scale-105 transition"
>
💬 Chat
</button>
<!-- Chatbot Drawer -->
<div
id="chat-drawer"
class="fixed top-16 right-0 w-96 max-w-full h-[calc(100%-4rem)] bg-white shadow-lg border-l border-gray-200 transform translate-x-full transition-transform duration-300 ease-in-out z-40 flex flex-col"
>
<div class="flex justify-between items-center p-4 border-b">
<h3 class="text-lg font-semibold">Ask Chatbot</h3>
<button id="chat-close" class="text-gray-600 hover:text-black text-xl">
</button>
</div>
<div id="chat-output" class="flex-1 overflow-auto p-4 space-y-2 text-sm">
<p><strong>Chatbot:</strong> Ask me something about your report</p>
</div>
<div class="flex gap-2 p-4 border-t">
<input
type="text"
id="user-question"
placeholder="Ask a question..."
class="flex-1 rounded px-3 py-2 focus:outline-none border"
/>
<button id="ask-btn" class="btn-primary px-4 py-2 rounded">Ask</button>
</div>
</div>
<script>
const chatDrawer = document.getElementById("chat-drawer");
const chatToggle = document.getElementById("chat-toggle");
const chatClose = document.getElementById("chat-close");
chatToggle.addEventListener("click", () =>
chatDrawer.classList.toggle("translate-x-full")
);
chatClose.addEventListener("click", () =>
chatDrawer.classList.add("translate-x-full")
);
</script>
<!-- Firebase Auth + Firestore -->
<script type="module">
import {
getFirestore,
collection,
doc,
addDoc,
serverTimestamp,
} from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-app.js";
import {
getAuth,
onAuthStateChanged,
signOut,
} from "https://www.gstatic.com/firebasejs/9.22.0/firebase-auth.js";
const firebaseConfig = {
apiKey: "AIzaSyAPhM_Ee7cLzyKHs5zyFy8g5ZOk9-pubRI",
authDomain: "login-tutorial-7a9e1.firebaseapp.com",
projectId: "login-tutorial-7a9e1",
storageBucket: "login-tutorial-7a9e1.firebasestorage.app",
messagingSenderId: "491093197824",
appId: "1:491093197824:web:9f86659034af7e6a8244e5",
measurementId: "G-JM7T9N6ZLZ"
};
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);
window.firebaseAuth = auth;
window.onAuthStateChanged = onAuthStateChanged;
window.firestoreDb = db;
window.firestoreHelpers = { collection, doc, addDoc, serverTimestamp };
onAuthStateChanged(auth, (user) => {
const authNavItem = document.getElementById("authNavItem");
const profileNavDesktop = document.querySelector(
'ul.md\\:flex li a[href="profile.html"]'
)?.parentElement;
const pastNavDesktop = document.querySelector(
'ul.md\\:flex li a[href="past_data.html"]'
)?.parentElement;
const profileNavMobile = document.querySelector(
'#mobile-menu a[href="profile.html"]'
)?.parentElement;
const pastNavMobile = document.querySelector(
'#mobile-menu a[href="past_data.html"]'
)?.parentElement;
if (authNavItem) {
if (user) {
authNavItem.innerHTML =
'<button onclick="logout()" class="hover:text-[#6B9080] text-red-600">Logout</button>';
if (profileNavDesktop) profileNavDesktop.style.display = "block";
if (pastNavDesktop) pastNavDesktop.style.display = "block";
if (profileNavMobile) profileNavMobile.style.display = "block";
if (pastNavMobile) pastNavMobile.style.display = "block";
} else {
authNavItem.innerHTML =
'<a href="login.html" class="hover:text-[#6B9080]">Login</a>';
if (profileNavDesktop) profileNavDesktop.style.display = "none";
if (pastNavDesktop) pastNavDesktop.style.display = "none";
if (profileNavMobile) profileNavMobile.style.display = "none";
if (pastNavMobile) pastNavMobile.style.display = "none";
}
}
});
window.logout = async () => {
try {
await signOut(auth);
localStorage.clear();
window.location.href = "login.html";
} catch (error) {
console.error("Error signing out:", error);
}
};
</script>
<!-- Analyzer + Chatbot -->
<script type="module">
import {
pipeline,
env,
} from "https://cdn.jsdelivr.net/npm/@xenova/[email protected]";
const loadingEl = document.getElementById("loading");
// const textOutput = document.getElementById("text-output");
const recsOutput = document.getElementById("recommendations-output");
const chat = document.getElementById("chat-output");
const authStatus = document.getElementById("auth-status");
let extractedText = "";
let currentUser = null;
function renderRecCard(rec, idx) {
const sev = (rec.severity || "").toLowerCase();
const sevClass = sev.includes("severe")
? "badge-high"
: sev.includes("moderate")
? "badge-medium"
: "badge-low";
return `
<div class="rec-card">
<div class="flex items-center justify-between">
<h4 class="rec-title">Finding ${idx + 1}: ${
rec.findings || "N/A"
}</h4>
<span class="rec-badge ${sevClass}">${rec.severity || "—"}</span>
</div>
<ul class="rec-content space-y-1">
<li><em>Recommendations:</em>
<ul class="list-disc list-inside ml-6">${(
rec.recommendations || []
)
.map((r) => `<li>${r}</li>`)
.join("")}</ul>
</li>
<li><em>Treatment:</em> ${
rec.treatment_suggestions || "Not available"
}</li>
<li><em>Home Care:</em>
<ul class="list-disc list-inside ml-6">${(
rec.home_care_guidance || []
)
.map((r) => `<li>${r}</li>`)
.join("")}</ul>
</li>
${
rec.info_link
? `<li><a href="${rec.info_link}" target="_blank" class="rec-link">Learn more</a></li>`
: ""
}
</ul>
</div>`;
}
window.onAuthStateChanged(window.firebaseAuth, (user) => {
currentUser = user;
authStatus.textContent = user
? `Signed in as ${user.email || user.uid}`
: "Not signed in. Sign in to save and view past analyses.";
});
document
.getElementById("pdf-upload")
.addEventListener("change", function () {
loadingEl.textContent = this.files.length
? `File selected: ${this.files[0].name}`
: "No file uploaded yet.";
});
async function postReportToBackend(report) {
try {
const response = await fetch(api("save_report/"), {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(report),
});
if (!response.ok)
throw new Error(`HTTP error! status: ${response.status}`);
const data = await response.json();
console.log("Report sent to backend:", data);
} catch (error) {
console.error("Error sending report:", error);
}
}
document
.getElementById("analyze-btn")
.addEventListener("click", async () => {
const file = document.getElementById("pdf-upload").files[0];
if (!file) {
loadingEl.textContent = "Please upload a file first.";
return;
}
loadingEl.textContent = "Processing with AI...";
recsOutput.textContent = "";
const formData = new FormData();
formData.append("file", file);
formData.append("model", "bert");
let data;
try {
const res = await fetch(api("analyze/"), {
method: "POST",
body: formData,
});
if (!res.ok) throw new Error(await res.text());
data = await res.json();
} catch (err) {
console.error(err);
loadingEl.textContent = "Error during analysis: " + err.message;
return;
}
extractedText = data.ocr_text || "";
const recs = Array.isArray(data.Detected_Anomolies)
? data.Detected_Anomolies
: data.Detected_Anomolies
? [data.Detected_Anomolies]
: [];
recsOutput.innerHTML = recs.length
? recs.map(renderRecCard).join("")
: "No recommendations found.";
if (currentUser) {
await postReportToBackend({
user_id: currentUser.email,
report_date: new Date(),
ocr_text: extractedText,
anomalies: JSON.stringify(recs),
});
}
loadingEl.textContent = "Analysis complete.";
});
document.getElementById("ask-btn").onclick = async () => {
const q = document.getElementById("user-question").value.trim();
if (!q) return;
if (!extractedText) {
alert("Please analyze a document first.");
return;
}
chat.innerHTML += `<p><strong>You:</strong> ${q}</p>`;
chat.innerHTML += `<p><strong>Chatbot:</strong> <em>Thinking...</em></p>`;
chat.scrollTop = chat.scrollHeight;
try {
const res = await fetch(api("chat/"), {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
question: q,
user_id: currentUser ? currentUser.email : "anonymous",
}),
});
if (!res.ok) throw new Error(await res.text());
const data = await res.json();
const last = chat.querySelectorAll("p");
last[
last.length - 1
].innerHTML = `<strong>Chatbot:</strong> ${data.answer}`;
} catch (err) {
console.error("Error:", err);
const last = chat.querySelectorAll("p");
last[
last.length - 1
].innerHTML = `<strong>Chatbot:</strong> Sorry, error: ${err.message}`;
}
document.getElementById("user-question").value = "";
chat.scrollTop = chat.scrollHeight;
};
</script>
</body>
</html>