RashidZaman's picture
Upload 4 files
9d498c2 verified
Raw
History Blame Contribute Delete
3.66 kB
const QA_FILE = "questions_answers.json";
// Point this at your running backend (server.py). Examples:
// local: "http://localhost:5000"
// hosted: "https://your-app-name.onrender.com"
const API_URL = "http://localhost:5000";
const listEl = document.getElementById("question-list");
const logEl = document.getElementById("log");
const customInput = document.getElementById("custom-input");
const customSubmit = document.getElementById("custom-submit");
let faq = [];
let hintCleared = false;
async function loadFaq() {
try {
const res = await fetch(QA_FILE, { cache: "no-store" });
if (!res.ok) throw new Error("fetch failed: " + res.status);
faq = await res.json();
} catch (err) {
listEl.innerHTML = `<div class="log-hint">
// could not load ${QA_FILE} (${err.message}). Make sure it's uploaded
alongside index.html in this Space.
</div>`;
return;
}
renderQuestions();
}
function renderQuestions() {
listEl.innerHTML = "";
faq.forEach((item, i) => {
const btn = document.createElement("button");
btn.className = "q-btn";
btn.type = "button";
btn.textContent = item.question;
btn.addEventListener("click", () => runQuestion(item, btn));
listEl.appendChild(btn);
});
}
function runQuestion(item, btnEl) {
document.querySelectorAll(".q-btn").forEach(b => b.classList.remove("active"));
btnEl.classList.add("active");
const aLine = addLogEntry(item.question);
typeAnswer(aLine, item.answer);
}
function typeAnswer(el, text) {
const cursor = document.createElement("span");
cursor.className = "cursor";
let i = 0;
const speed = 14; // ms per character - tune for taste
function step() {
if (i <= text.length) {
el.textContent = text.slice(0, i);
el.appendChild(cursor);
i++;
setTimeout(step, speed);
} else {
cursor.remove();
}
}
step();
}
function addLogEntry(questionText) {
if (!hintCleared) {
logEl.innerHTML = "";
hintCleared = true;
}
document.querySelectorAll(".q-btn").forEach(b => b.classList.remove("active"));
const entry = document.createElement("div");
entry.className = "log-entry";
const qLine = document.createElement("div");
qLine.className = "log-q";
qLine.textContent = questionText;
const aLine = document.createElement("div");
aLine.className = "log-a";
entry.appendChild(qLine);
entry.appendChild(aLine);
logEl.appendChild(entry);
entry.scrollIntoView({ behavior: "smooth", block: "end" });
return aLine;
}
async function askCustom() {
const question = customInput.value.trim();
if (!question) return;
customSubmit.disabled = true;
customInput.disabled = true;
const aLine = addLogEntry(question);
aLine.textContent = "generating...";
try {
const res = await fetch(`${API_URL}/generate`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ question }),
});
const data = await res.json();
aLine.textContent = "";
if (!res.ok) {
aLine.classList.add("error");
typeAnswer(aLine, `error: ${data.error || res.statusText}`);
} else {
typeAnswer(aLine, data.answer);
}
} catch (err) {
aLine.textContent = "";
aLine.classList.add("error");
typeAnswer(aLine, `could not reach backend at ${API_URL} (${err.message})`);
} finally {
customSubmit.disabled = false;
customInput.disabled = false;
customInput.value = "";
customInput.focus();
}
}
customSubmit.addEventListener("click", askCustom);
customInput.addEventListener("keydown", (e) => {
if (e.key === "Enter") askCustom();
});
loadFaq();