aaa

🧩 Syntax:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>CE Dashboard v2.0</title>
    <style>
        body {
            background-color: #0d0d0d;
            color: #33ff33;
            font-family: 'Courier New', Courier, monospace;
            display: flex;
            flex-direction: column;
            align-items: center;
            margin: 0;
            padding: 20px;
        }
        .glitch {
            font-size: 2.5em;
            animation: flicker 2s infinite alternate;
        }
        @keyframes flicker {
            0% { opacity: 1; }
            45% { opacity: 0.8; }
            50% { opacity: 0.6; transform: translate(1px, -1px); }
            52% { opacity: 0.9; transform: translate(-1px, 1px); }
            55% { opacity: 1; transform: translate(0, 0); }
            100% { opacity: 1; }
        }
        .dashboard-container {
            width: 90%;
            max-width: 1200px;
            display: grid;
            grid-template-columns: 1fr 2fr;
            gap: 20px;
            margin-top: 30px;
        }
        .panel {
            border: 1px solid #33ff33;
            background-color: #111;
            padding: 15px;
            box-shadow: 0 0 15px #33ff33;
            display: flex;
            flex-direction: column;
        }
        .panel h2 {
            margin-top: 0;
            font-size: 1.2em;
            color: #33ff33;
        }
        .terminal-line {
            margin: 5px 0;
        }
        .form-group {
            margin-bottom: 15px;
        }
        label {
            display: block;
            margin-bottom: 5px;
        }
        select,
        input[type="text"] {
            width: 100%;
            padding: 5px;
            background-color: #0d0d0d;
            border: 1px solid #33ff33;
            color: #33ff33;
            font-family: 'Courier New', Courier, monospace;
        }
        .launch-button {
            margin-top: 10px;
            padding: 10px;
            border: 1px solid #33ff33;
            background: transparent;
            color: #33ff33;
            font-family: 'Courier New', Courier, monospace;
            cursor: pointer;
        }
        .launch-button:hover {
            background-color: #33ff33;
            color: #0d0d0d;
        }
        .remove-ami {
            margin-top: 5px;
            font-size: 0.9em;
            background: none;
            border: none;
            color: #ff3333;
            cursor: pointer;
        }
        .remove-ami:hover {
            text-decoration: underline;
        }
        .counter {
            margin-top: 10px;
            font-size: 1em;
            color: #33ff33;
        }
        .machine-box {
            border: 1px solid #33ff33;
            padding: 10px;
            margin-bottom: 10px;
            background-color: #000;
        }
    </style>
    <script>
        function updateCounter() {
            const customAmiCount = document.querySelectorAll('.custom-ami-entry').length;
            const total = customAmiCount;
            document.getElementById('total-counter').textContent = `Total Requested Machines: ${total}/14`;
            const errorMsg = document.getElementById('error-message');
            errorMsg.style.display = total > 14 ? 'block' : 'none';
        }

        function addCustomAmiField() {
            const container = document.getElementById('custom-ami-container');
            const entry = document.createElement('div');
            entry.className = 'custom-ami-entry form-group';
            entry.innerHTML = `
                <label>AMI:</label>
                <input list="ami-options" name="custom_ami[]" style="width: 100%; padding: 5px; background-color: #0d0d0d; border: 1px solid #33ff33; color: #33ff33; font-family: 'Courier New', Courier, monospace; appearance: menulist-button; -webkit-appearance: menulist-button;">
                <datalist id="ami-options">
                    <option value="ami-kali">Kali Linux</option>
                    <option value="ami-windows-2022">Windows Server 2022</option>
                    <option value="ami-amazon-linux">Amazon Linux</option>
                </datalist>
                <label>Instance Type:</label>
                <select name="custom_instance_type[]">
                    <option value="t2.micro">t2.micro</option>
                    <option value="t2.small">t2.small</option>
                    <option value="t3.medium">t3.medium</option>
                    <option value="t3.large">t3.large</option>
                    <option value="m5.large">m5.large</option>
                </select>
                <button type="button" class="remove-ami" onclick="removeCustomAmiField(this)">Remove</button>`;
            container.appendChild(entry);
            updateCounter();
        }

        function removeCustomAmiField(button) {
            const entry = button.closest('.custom-ami-entry');
            entry.remove();
            updateCounter();
        }

        function submitLab(event) {
            event.preventDefault();
            const labName = document.getElementById('lab-name').value.trim();
            const labNameRegex = /^[a-zA-Z0-9_-]+$/;
            if (!labNameRegex.test(labName)) {
                document.getElementById('labname-error').style.display = 'block';
                return;
            } else {
                document.getElementById('labname-error').style.display = 'none';
            }
            const customAmis = Array.from(document.querySelectorAll('.custom-ami-entry')).map(entry => {
                const ami = entry.querySelector('input[name="custom_ami[]"]').value;
                const type = entry.querySelector('select[name="custom_instance_type[]"]').value;
                return { ami, instance_type: type };
            });
            const payload = { lab_name: labName, custom_amis: customAmis };
            fetch('/launchlab', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(payload)
            })
            .then(res => res.json())
            .then(data => {
                document.getElementById('debug-box').innerText = 'Launch Response:\n' + JSON.stringify(data, null, 2);
            })
            .catch(error => {
                document.getElementById('debug-box').innerText = 'Launch Failed';
                console.error('Error launching lab:', error);
            });
        }

        function validateLab(event) {
            event.preventDefault();
            const labName = document.getElementById('lab-name').value.trim();
            const labNameRegex = /^[a-zA-Z0-9_-]+$/;
            if (!labNameRegex.test(labName)) {
                document.getElementById('labname-error').style.display = 'block';
                return;
            } else {
                document.getElementById('labname-error').style.display = 'none';
            }
            const customAmis = Array.from(document.querySelectorAll('.custom-ami-entry')).map(entry => {
                const ami = entry.querySelector('input[name="custom_ami[]"]').value;
                const type = entry.querySelector('select[name="custom_instance_type[]"]').value;
                return { ami, instance_type: type };
            });
            const payload = { lab_name: labName, custom_amis: customAmis };
            fetch('/validatelab', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(payload)
            })
            .then(res => res.json())
            .then(data => {
                if (data.validated === true) {
                const launchBtn = document.getElementById('launch-btn');
                launchBtn.disabled = false;
                launchBtn.style.border = '1px solid #33ff33';
                launchBtn.style.color = '#33ff33';
                document.getElementById('debug-box').innerText = `Validation Successful:
${JSON.stringify(data, null, 2)}`;
                } else {
                    document.getElementById('debug-box').innerText = 'Validation Failed:\n' + JSON.stringify(data, null, 2);
                }
            })
            .catch(error => {
                console.error('Error validating lab:', error);
                document.getElementById('debug-box').innerText = 'Validation Failed';
            });
        }

        function confirmDestroyLab() {
            const messageBox = document.getElementById('destroy-lab-message');
            if (messageBox.style.display === 'none') {
                messageBox.style.display = 'block';
                return;
            }
            const labName = document.getElementById('lab-name').value.trim();
            if (!labName) {
                alert('Lab name is required to destroy the lab.');
                return;
            }
            fetch('/destroylab', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ lab_name: labName })
            })
            .then(res => res.json())
            .then(data => {
                messageBox.textContent = 'Lab destroyed.';
                document.getElementById('lab-name-display').textContent = '-';
                document.getElementById('hosts-active').textContent = '-';
                document.getElementById('lab-uptime').textContent = '-';
                document.getElementById('lab-subnet').textContent = '-';
                document.getElementById('machines-list').innerHTML = '<div class="terminal-line">No machines launched yet.</div>';
                setTimeout(() => { messageBox.style.display = 'none'; }, 3000);
            })
            .catch(err => {
                messageBox.textContent = 'Failed to destroy lab.';
            });
        }

        document.addEventListener('DOMContentLoaded', () => {
            document.getElementById('add-ami-btn').addEventListener('click', (e) => {
                e.preventDefault();
                addCustomAmiField();
            });
            updateCounter();
        });
    </script>
</head>
<body>
    <div class="glitch">ICE Dashboard</div>
    <div class="panel" style="margin-top: 10px; margin-bottom: 20px; width: 90%; max-width: 1200px; text-align: center;">
        <h2>> SSH KEY DOWNLOAD</h2>
        <a href="/download/keys.zip" download class="launch-button" style="display: inline-block; text-decoration: none;">Download SSH Keys (.zip)</a>
    </div>
    <div class="dashboard-container">
        <div class="panel" style="justify-content: space-between;">
            <h2>> LAUNCH LAB</h2>
            <form id="launch-form" style="display: flex; flex-direction: column; height: 100%; justify-content: space-between;">
                <div>
                    <div class="form-group">
                        <label for="lab-name">Lab Name (no spaces or special characters):</label>
                        <input type="text" id="lab-name" name="lab_name" pattern="^[a-zA-Z0-9_-]+$" title="Only letters, numbers, hyphens, and underscores allowed" required>
                        <div id="labname-error" style="color: #ff3333; display: none; font-family: 'Courier New', Courier, monospace; margin-top: 5px;">Error: Lab name may only contain letters, numbers, hyphens, and underscores.</div>
                    </div>
                    <div class="form-group">
                        <div id="custom-ami-container"></div>
                        <button id="add-ami-btn" type="button" class="launch-button">+ Add Instance</button>
                    </div>
                    <div id="total-counter" class="counter">Total Requested Machines: 0/14</div>
                    <div id="error-message" style="color: #ff3333; display: none; font-family: 'Courier New', Courier, monospace; margin-top: 5px;">Error: You cannot request more than 14 machines.</div>
                </div>
                <div style="display: flex; gap: 10px;">
                    <button type="button" class="launch-button" onclick="validateLab(event)">Validate Lab</button>
                    <button type="submit" class="launch-button" id="launch-btn" onclick="submitLab(event)" disabled style="border: 1px solid red; color: red;">Launch</button>
                </div>
            </form>
        </div>
        <div>
            <div class="panel">
                <h2>> CURRENT LAB</h2>
                <div class="terminal-line">> Lab Name: <span id="lab-name-display" style="color:lime">-</span></div>
                <div class="terminal-line">> Hosts Active: <span id="hosts-active" style="color:lime">-</span></div>
                <div class="terminal-line">> Uptime: <span id="lab-uptime" style="color:lime">-</span></div>
                <div class="terminal-line">> Subnet: <span id="lab-subnet" style="color:lime">-</span></div>
                <div style="text-align:center; margin-top:10px;">
                    <button class="launch-button" onclick="confirmDestroyLab()">Destroy Lab</button>
                    <div id="destroy-lab-message" style="display:none; margin-top:5px; font-size:0.9em; color:#ff3333;">Click again to confirm lab destruction.</div>
                </div>
            </div>
            <div class="panel">
                <h2>> MACHINES</h2>
                <div id="machines-list">
                    <div class="terminal-line">No machines launched yet.</div>
                </div>
            </div>
            <div class="panel">
                <h2>> DEBUG</h2>
                <div id="debug-box" style="font-family: 'Courier New', Courier, monospace; color: #33ff33; background-color: #000; padding: 10px; border: 1px solid #33ff33; height: 300px; overflow-y: auto; scroll-behavior: smooth;">
                    No messages.
                </div>
            </div>
        </div>
    </div>
</body>
</html>