File size: 3,627 Bytes
20e9e63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// PayParse — minimal vanilla-JS chat client for the /api/chat endpoint.

const chatWindow = document.getElementById("chatWindow");
const composerForm = document.getElementById("composerForm");
const messageInput = document.getElementById("messageInput");
const sendButton = document.getElementById("sendButton");
const resetButton = document.getElementById("resetButton");
const engineBadge = document.getElementById("engineBadge");
const quickReplies = document.getElementById("quickReplies");

let sessionId = crypto.randomUUID();

function scrollToBottom() {
  chatWindow.scrollTop = chatWindow.scrollHeight;
}

function appendMessage(text, sender) {
  const row = document.createElement("div");
  row.className = `msg msg-${sender}`;
  const bubble = document.createElement("div");
  bubble.className = "bubble";
  bubble.textContent = text;
  row.appendChild(bubble);
  chatWindow.appendChild(row);
  scrollToBottom();
  return row;
}

function appendPayload(payload) {
  const row = document.createElement("div");
  row.className = "msg msg-bot";
  const bubble = document.createElement("div");
  bubble.className = "bubble payload";
  bubble.textContent = JSON.stringify(payload, null, 2);
  row.appendChild(bubble);
  chatWindow.appendChild(row);
  scrollToBottom();
}

function showTyping() {
  const row = document.createElement("div");
  row.className = "msg msg-bot typing";
  row.id = "typingIndicator";
  row.innerHTML = `<div class="bubble"><span class="dot"></span><span class="dot"></span><span class="dot"></span></div>`;
  chatWindow.appendChild(row);
  scrollToBottom();
}

function hideTyping() {
  const el = document.getElementById("typingIndicator");
  if (el) el.remove();
}

async function loadHealth() {
  try {
    const res = await fetch("/health");
    const data = await res.json();
    engineBadge.textContent = data.offline_mode ? "Mode: Offline (Mock)" : "Mode: Gemini Live";
  } catch {
    engineBadge.textContent = "Tidak terhubung";
  }
}

async function sendMessage(text) {
  appendMessage(text, "user");
  messageInput.value = "";
  sendButton.disabled = true;
  showTyping();

  try {
    const res = await fetch("/api/chat", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ session_id: sessionId, message: text }),
    });
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const data = await res.json();

    hideTyping();
    appendMessage(data.reply, "bot");

    if (data.is_complete && data.payload) {
      appendPayload(data.payload);
      // Transaction finished server-side; start a fresh session for the next one.
      sessionId = crypto.randomUUID();
    }
  } catch (err) {
    hideTyping();
    appendMessage("Maaf, terjadi kendala koneksi ke server. Coba lagi ya.", "bot");
    console.error(err);
  } finally {
    sendButton.disabled = false;
    messageInput.focus();
  }
}

composerForm.addEventListener("submit", (e) => {
  e.preventDefault();
  const text = messageInput.value.trim();
  if (!text) return;
  sendMessage(text);
});

quickReplies.addEventListener("click", (e) => {
  const chip = e.target.closest(".chip");
  if (!chip) return;
  sendMessage(chip.dataset.text);
});

resetButton.addEventListener("click", async () => {
  try {
    await fetch(`/api/session/${sessionId}`, { method: "DELETE" });
  } catch {
    /* session may already be gone; ignore */
  }
  sessionId = crypto.randomUUID();
  chatWindow.innerHTML = "";
  appendMessage(
    'Oke, mulai dari awal. Mau dibantu transfer, beli pulsa, atau bayar listrik?',
    "bot"
  );
});

loadHealth();
messageInput.focus();