bot / index.html
hamaylza's picture
Update index.html
07479ad verified
Raw
History Blame Contribute Delete
6.38 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MAYLBOT</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700;900&display=swap" rel="stylesheet">
<style>
*{margin:0;padding:0;box-sizing:border-box;}
body{
background:#000;
color:#fff;
font-family:'Inter',sans-serif;
height:100vh;
display:flex;
align-items:center;
justify-content:center;
}
/* ===== Gradient Frame (matches portfolio bot section) ===== */
.container{
width:100%;
max-width:900px;
height:90vh;
border-radius:20px;
padding:3px;
background:linear-gradient(135deg,#ff2a2a,#7f0000,#000);
box-shadow:0 30px 70px rgba(255,42,42,0.25);
}
/* ===== Inner Panel ===== */
.inner{
background:#000;
border-radius:18px;
height:100%;
display:flex;
flex-direction:column;
overflow:hidden;
}
/* ===== Header ===== */
.header{
padding:18px 20px;
border-bottom:1px solid rgba(255,255,255,0.08);
display:flex;
justify-content:space-between;
align-items:center;
}
.title{
font-weight:900;
font-size:18px;
letter-spacing:-0.02em;
}
.title span{ color:#ff2a2a; }
.status{
font-size:12px;
color:#ff8a8a;
display:flex;
align-items:center;
gap:6px;
}
.dot{
width:8px;
height:8px;
background:#ff2a2a;
border-radius:50%;
animation:pulse 1.5s infinite;
}
@keyframes pulse{
0%,100%{opacity:.4;}
50%{opacity:1;}
}
/* ===== Chat Area ===== */
.chat-box{
flex:1;
padding:20px;
overflow-y:auto;
display:flex;
flex-direction:column;
gap:14px;
}
.chat-box::-webkit-scrollbar{
width:6px;
}
.chat-box::-webkit-scrollbar-thumb{
background:#ff2a2a;
border-radius:10px;
}
/* ===== Messages ===== */
.msg{
max-width:75%;
padding:12px 14px;
border-radius:14px;
font-size:14px;
line-height:1.5;
}
/* User */
.user{
align-self:flex-end;
background:#ff2a2a;
}
/* Bot (sys-card inspired) */
.bot{
align-self:flex-start;
background:#0d0d0d;
border:1px solid rgba(255,255,255,0.08);
position:relative;
}
/* Red accent line */
.bot::before{
content:'';
position:absolute;
top:0;
left:0;
width:100%;
height:2px;
background:linear-gradient(90deg,#ff2a2a,transparent);
}
/* ===== Input Area ===== */
.input-area{
padding:16px;
border-top:1px solid rgba(255,255,255,0.08);
display:flex;
gap:10px;
}
input{
flex:1;
padding:14px;
border-radius:10px;
background:#0d0d0d;
border:1px solid rgba(255,255,255,0.08);
color:#fff;
font-size:14px;
}
input:focus{
outline:none;
border-color:#ff2a2a;
}
/* Buttons */
button{
padding:12px 16px;
border-radius:10px;
font-weight:700;
cursor:pointer;
}
/* Send */
.send-btn{
background:#ff2a2a;
color:#fff;
}
.send-btn:hover{
box-shadow:0 10px 20px rgba(255,42,42,0.3);
}
/* Voice */
.voice-btn{
background:rgba(255,42,42,0.1);
color:#ff2a2a;
border:1px solid rgba(255,42,42,0.3);
}
.voice-btn:hover{
background:#ff2a2a;
color:#fff;
}
/* Typing */
.typing{
font-size:12px;
color:#ff8a8a;
}
</style>
</head>
<body>
<div class="container">
<div class="inner">
<div class="header">
<div class="title">MAYL<span>BOT</span></div>
<div class="status">
<div class="dot"></div> online
</div>
</div>
<div class="chat-box" id="chat"></div>
<div class="input-area">
<input id="input" placeholder="Ask MaylBot..." />
<button class="send-btn" onclick="send()">Send</button>
<button class="voice-btn" onclick="record()">🎤</button>
</div>
</div>
</div>
<script>
const chat = document.getElementById("chat");
/* Add message */
function addMessage(text, cls) {
const div = document.createElement("div");
div.className = "msg " + cls;
div.innerText = text;
chat.appendChild(div);
chat.scrollTop = chat.scrollHeight;
}
/* Initial message */
window.onload = () => {
addMessage("Hey, I’m MaylBot. Ask me anything.", "bot");
};
/* Enter key */
document.getElementById("input").addEventListener("keypress", function(e){
if(e.key === "Enter") send();
});
/* Send message */
async function send() {
const input = document.getElementById("input");
const msg = input.value.trim();
if (!msg) return;
addMessage(msg, "user");
input.value = "";
const typing = document.createElement("div");
typing.className = "typing";
typing.innerText = "MaylBot is thinking...";
chat.appendChild(typing);
try {
const res = await fetch("/chat", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({message: msg})
});
const data = await res.json();
chat.removeChild(typing);
addMessage(data.response || "No response from server.", "bot");
} catch (err) {
chat.removeChild(typing);
addMessage("Server not connected.", "bot");
}
}
/* Voice */
let mediaRecorder;
let chunks = [];
async function record() {
try {
const stream = await navigator.mediaDevices.getUserMedia({audio: true});
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start();
chunks = [];
mediaRecorder.ondataavailable = e => chunks.push(e.data);
setTimeout(() => mediaRecorder.stop(), 4000);
mediaRecorder.onstop = async () => {
const blob = new Blob(chunks, {type: "audio/wav"});
const formData = new FormData();
formData.append("file", blob);
addMessage("Listening...", "user");
try {
const res = await fetch("/voice", {
method: "POST",
body: formData
});
const data = await res.json();
addMessage(data.transcript || "Could not transcribe", "user");
addMessage(data.response || "No response", "bot");
} catch {
addMessage("Voice server not connected.", "bot");
}
};
} catch {
addMessage("Mic permission denied.", "bot");
}
}
</script>
</body>
</html>