Botpack / public /index.html
Jonell01's picture
Create public/index.html
51a483e verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bot Control Panel CC</title>
<script src="https://cdn.tailwindcss.com"></script>
<script defer src="https://unpkg.com/alpinejs@3.10.2/dist/cdn.min.js"></script>
<style>
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.fade-in { animation: fadeIn 0.5s ease-out; }
@keyframes fadeOut {
from { opacity: 1; transform: scale(1); }
to { opacity: 0; transform: scale(0); }
}
.fade-out { animation: fadeOut 0.5s ease-out forwards; }
@keyframes spin {
100% { transform: rotate(360deg); }
}
.loading-circle {
border: 4px solid rgba(255, 255, 255, 0.3);
border-top-color: white;
border-radius: 50%;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
}
.popup {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
background-color: rgba(0, 0, 0, 0.8);
color: white;
padding: 12px 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
opacity: 0;
transition: opacity 0.5s ease-out;
}
.popup.show { opacity: 1; }
#ping {
position: fixed;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
font-size: 14px;
color: rgba(255, 255, 255, 0.6);
font-weight: 500;
font-style: italic;
pointer-events: none;
}
</style>
</head>
<body class="bg-gray-900 text-white flex flex-col items-center justify-center min-h-screen p-6">
<div class="w-full max-w-3xl space-y-6 fade-in">
<h1 class="text-3xl font-bold text-center">Bot Control Panel</h1>
<div class="bg-gray-800 p-6 rounded-lg shadow-lg">
<label class="block text-lg font-medium mb-2">Paste JSON:</label>
<textarea id="jsonInput" class="w-full p-3 rounded-lg bg-gray-700 text-white border border-gray-600 focus:ring focus:ring-blue-500 transition" rows="6" placeholder="Paste JSON here..."></textarea>
<button onclick="askPasscode('updateAppState')" class="mt-4 w-full bg-blue-600 hover:bg-blue-700 transition px-4 py-2 rounded-lg font-semibold shadow-lg">Proceed</button>
</div>
<div class="bg-gray-800 p-6 rounded-lg shadow-lg fade-in">
<button onclick="askPasscode('restartBot')" class="w-full bg-red-600 hover:bg-red-700 transition px-4 py-2 rounded-lg font-semibold shadow-lg">Restart Bot</button>
</div>
<div class="bg-gray-800 p-6 rounded-lg shadow-lg fade-in">
<label class="block text-lg font-medium mb-2">Execute Command:</label>
<input type="text" id="commandInput" class="w-full p-3 rounded-lg bg-gray-700 text-white border border-gray-600 focus:ring focus:ring-blue-500 transition" placeholder="Enter a command...">
<button onclick="askPasscode('executeCommand')" class="mt-4 w-full bg-yellow-600 hover:bg-yellow-700 transition px-4 py-2 rounded-lg font-semibold shadow-lg">Execute</button>
</div>
</div>
<div id="ping" class="fade-in">Ping: <span id="pingValue">Loading...</span></div>
<div id="loading" class="fixed inset-0 bg-black bg-opacity-50 flex justify-center items-center hidden">
<div class="loading-circle"></div>
</div>
<div id="popupNotification" class="popup"></div>
<script>
function showPopup(message) {
const popup = document.getElementById("popupNotification");
popup.textContent = message;
popup.classList.add("show");
setTimeout(() => popup.classList.remove("show"), 3000);
}
function askPasscode(action) {
const passcode = prompt("Enter Passcode:");
if (!passcode) {
showPopup("Passcode is required.");
return;
}
window[action](passcode);
}
function updateAppState(passcode) {
const jsonInput = document.getElementById("jsonInput").value;
try {
JSON.parse(jsonInput);
} catch {
showPopup("Invalid JSON format.");
return;
}
document.getElementById("loading").classList.remove("hidden");
fetch("/update-appstate", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ passcode, jsonData: JSON.parse(jsonInput) })
}).then(res => res.text()).then(message => {
document.getElementById("loading").classList.add("hidden");
showPopup(message);
}).catch(() => {
document.getElementById("loading").classList.add("hidden");
showPopup("Error updating AppState.");
});
}
function restartBot(passcode) {
document.getElementById("loading").classList.remove("hidden");
fetch(`/restart?passcode=${encodeURIComponent(passcode)}`)
.then(res => res.text())
.then(message => {
document.getElementById("loading").classList.add("hidden");
showPopup(message);
})
.catch(() => {
document.getElementById("loading").classList.add("hidden");
showPopup("Error restarting bot.");
});
}
function executeCommand(passcode) {
const commandInput = document.getElementById("commandInput").value;
if (!commandInput) {
showPopup("Please enter a command.");
return;
}
document.getElementById("loading").classList.remove("hidden");
fetch("/execute-command", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ passcode, command: commandInput })
}).then(res => res.text()).then(output => {
document.getElementById("loading").classList.add("hidden");
showPopup(output);
}).catch(() => {
document.getElementById("loading").classList.add("hidden");
showPopup("Error executing command.");
});
}
function updatePing() {
fetch("/ping")
.then(res => res.json())
.then(data => {
document.getElementById("pingValue").textContent = data.ping + " ms";
})
.catch(() => {
document.getElementById("pingValue").textContent = "Error";
});
}
setInterval(updatePing, 5000);
updatePing();
</script>
</body>
</html>