Spaces:
Sleeping
Sleeping
| <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> | |