triflix's picture
Create chat.html
0222dab verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Score Predictor + Groq Chatbot</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
.message-enter {
animation: fadeIn 0.3s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(4px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body class="bg-gradient-to-br from-blue-100 to-white min-h-screen font-sans">
<div class="max-w-md mx-auto py-8 px-4">
<div id="chatbox"
class="bg-white p-4 rounded-lg shadow-xl h-[500px] overflow-y-auto space-y-3 border border-gray-200">
</div>
<div class="mt-3 flex sticky bottom-0 bg-white rounded-md shadow-md">
<input id="userInput" type="text"
class="flex-1 p-3 border border-r-0 border-gray-300 rounded-l-md focus:outline-none focus:ring-2 focus:ring-blue-400"
placeholder="Type your answer..." autocomplete="off" />
<button id="sendBtn"
class="bg-blue-600 hover:bg-blue-700 transition-colors px-5 text-white font-semibold rounded-r-md">
Send
</button>
</div>
</div>
<script>
const fields = {{ fields | tojson }};
let idx = -1;
const answers = {};
const chatbox = document.getElementById("chatbox");
const input = document.getElementById("userInput");
const btn = document.getElementById("sendBtn");
function addMessage(txt, who = "bot") {
const div = document.createElement("div");
div.className = `message-enter px-3 py-2 rounded-lg max-w-[80%] ${
who === "bot"
? "bg-gray-100 text-gray-900 self-start"
: "bg-blue-600 text-white self-end ml-auto"
}`;
div.innerText = txt;
const wrapper = document.createElement("div");
wrapper.className = "flex flex-col";
wrapper.appendChild(div);
chatbox.appendChild(wrapper);
chatbox.scrollTop = chatbox.scrollHeight;
}
function askNext() {
idx++;
if (idx === 0) {
addMessage("👋 Hello! I’ll ask 18 quick questions to predict your exam score—and then give personalized improvement tips.");
setTimeout(askNext, 800);
return;
}
const i = idx - 1;
if (i < fields.length) {
let q = fields[i].question;
if (fields[i].type === "select") {
q += " Options: " + fields[i].options.join(", ");
}
if (fields[i].type === "number" && fields[i].validation) {
q += ` (enter ${fields[i].validation.min}${fields[i].validation.max})`;
}
addMessage(q);
} else {
addMessage("🔄 Computing your predicted score and fetching advice…");
fetch("/predict_json", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(answers)
})
.then(r => r.json())
.then(d => {
addMessage(`🎯 Predicted Score: ${d.predicted}`);
setTimeout(() => addMessage(`💡 Improvement Tips:\n${d.advice}`), 500);
})
.catch(() => {
addMessage("⚠️ Something went wrong. Please refresh and try again.");
});
}
}
btn.onclick = () => {
const text = input.value.trim();
if (!text) return;
const i = idx - 1;
if (i >= 0 && i < fields.length) {
const f = fields[i];
if (f.type === "number") {
const n = parseFloat(text);
if (isNaN(n) || (f.validation && (n < f.validation.min || n > f.validation.max))) {
addMessage(`⚠️ Please enter a number between ${f.validation.min} and ${f.validation.max}.`, "bot");
input.value = "";
return;
}
answers[f.name] = n;
} else if (f.type === "select") {
if (!f.options.includes(text)) {
addMessage(`⚠️ Choose one of: ${f.options.join(", ")}`, "bot");
input.value = "";
return;
}
answers[f.name] = text;
}
}
addMessage(text, "user");
input.value = "";
askNext();
};
askNext();
</script>
</body>
</html>