File size: 3,597 Bytes
5508e32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<!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>
</head>
<body class="bg-gray-100">
  <div class="max-w-md mx-auto py-6">
    <div id="chatbox"
         class="bg-white p-4 rounded-lg shadow-lg h-[500px] overflow-y-auto space-y-3">
    </div>
    <div class="mt-3 flex">
      <input id="userInput" type="text"
             class="flex-1 p-2 border border-gray-300 rounded-l-md"
             placeholder="Type here…" autocomplete="off" />
      <button id="sendBtn"
              class="bg-blue-600 px-4 text-white rounded-r-md">
        Send
      </button>
    </div>
  </div>

  <script>
    const fields = {{ fields | tojson }};
    let idx = -1;        // before welcome
    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 = who==="bot"
        ? "text-left text-gray-800"
        : "text-right text-blue-700";
      div.innerText = txt;
      chatbox.appendChild(div);
      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(e=>{
          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();
    };

    // kick things off
    askNext();
  </script>
</body>
</html>