<!DOCTYPE html>
<html data-theme="dark">
<head>
    <title>Infinite-Noodles</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="/static/pub/bulma.min.css">
    <link rel="stylesheet" href="/static/pub/all.min.css">
     <style>
        .banner-container {
            background-image: url("/static/pub/long-banner.jpg");
            background-repeat: no-repeat;
            background-size: cover;
            position: relative;
            width: 100%; 
        }
        img.banner {
            height: 50px;
        }
        img.banner-long {
            height: 50px;
            object-fit: fill;
        }
        table {
            width: 100%;
        }
    </style> 
</head>

<body class="has-navbar-fixed-top">
    <nav class="navbar is-fixed-top" role="navigation" aria-label="main navigation">
        <div class="navbar-brand">
            <img class="banner" src="/static/pub/logo.jpg"/>
        </div>
        <div class="banner-container">
            <!-- <img class="banner-long" src="/static/pub/long-banner.jpg"/> -->
        </div>
    </nav>
    
    <div class="table-container">
        <table class="table is-bordered is-striped is-narrow is-hoverable is-fullwidth">
            <thead>
                <tr>
                    <th>Name</th>
                    <th>Proto</th>
                    <th>Allow From</th>
                    <th>Listening Port</th>
                    <th>Dest Port</th>
                    <th>Dest Host/IP</th>
                    <th>Expiration</th>
                    <th>Status</th>
                    <th></th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td><input class="input is-link is-small" type="text" form="add-noodle" name="name" placeholder="Name" autocomplete="off" required/></td>
                    <td>TCP</td>
                    <td>
                        <input class="input is-link is-small" type="text" form="add-noodle" name="src" list="allow-from-options" placeholder="All or source IP" value="All" autocomplete="off" required/>
                        <datalist id="allow-from-options">
                            <option value="All"></option>
                            <option value="{{.ClientIP}}"></option>
                        </datalist>
                    </td>
                    <td><input class="input is-link is-small" type="text" form="add-noodle" name="listen_port" placeholder="Listen Port" autocomplete="off" required/></td>
                    <td><input class="input is-link is-small" type="text" form="add-noodle" name="dest_port" placeholder="Destination Port" autocomplete="off" required/></td>
                    <td><input class="input is-link is-small" type="text" form="add-noodle" name="dest_host" placeholder="Destination Host" autocomplete="off" required/></td>
                    <td><input class="input is-link is-small" type="text" form="add-noodle" name="expiration" placeholder="30m, 1h15m" autocomplete="off" required/></td>
                    <td>
                    </td>
                    <td>
                        <form id="add-noodle" method="post" action="/add" autocomplete="off">
                            <button class="button" type="submit">
                                <span class="icon has-text-success"><i class="fas fa-plus"></i></span>
                            </button>
                        </form>
                    </td>
                </tr>
                {{range .Noodles}}
                <tr>
                    <td>{{.Name}}</td>
                    <td>{{.Proto}}</td>
                    <td>{{.Src}}</td>
                    <td>{{.ListenPort}}</td>
                    <td>{{.DestPort}}</td>
                    <td>{{.DestHost}}</td>
                    <td data-expiration-ms="{{.Expiration.Milliseconds}}" data-is-up="{{.IsUp}}">{{.Expiration}}</td>
                    <td>
                        <form method="post" action="/toggle" autocomplete="off">
                            <input type="hidden" name="id" value="{{.Id}}"/>
                            <label>
                                <input type="checkbox" name="is_up" onchange="this.form.submit()" {{if .IsUp}}checked{{end}}/>
                            </label>
                        </form>
                    </td>
                    <td>
                        <a href="/delete?id={{.Id}}">
                            <span class="icon has-text-danger"><i class="fas fa-minus"></i></span>
                        </a>
                    </td>
                </tr>
                {{end}}
            </tbody>
        </table>
    </div>
    <footer class="footer">
        <div class="content has-text-centered">
          <p>
            <strong>Infinite-Noodles Network Proxy</strong> - &copy; 2025 Jimmy Allen
          </p>
        </div>
      </footer>
    <script>
        function formatDuration(ms) {
            if (ms <= 0) {
                return "0s";
            }

            let totalSeconds = Math.floor(ms / 1000);
            const hours = Math.floor(totalSeconds / 3600);
            totalSeconds -= hours * 3600;
            const minutes = Math.floor(totalSeconds / 60);
            const seconds = totalSeconds % 60;
            const parts = [];

            if (hours > 0) {
                parts.push(hours + "h");
            }
            if (minutes > 0 || hours > 0) {
                parts.push(minutes + "m");
            }
            parts.push(seconds + "s");

            return parts.join("");
        }

        function updateExpirationCountdowns() {
            const expirationCells = document.querySelectorAll("[data-expiration-ms]");
            expirationCells.forEach((cell) => {
                if (cell.dataset.isUp !== "true") {
                    return;
                }
                const nextValue = Number(cell.dataset.expirationMs) - 1000;
                const clampedValue = Math.max(nextValue, 0);
                cell.dataset.expirationMs = String(clampedValue);
                if (clampedValue === 0) {
                    const row = cell.closest("tr");
                    if (row) {
                        row.remove();
                    }
                    return;
                }
                cell.textContent = formatDuration(clampedValue);
            });
        }

        document.addEventListener("DOMContentLoaded", () => {
            const expirationCells = document.querySelectorAll("[data-expiration-ms]");
            expirationCells.forEach((cell) => {
                cell.textContent = formatDuration(Number(cell.dataset.expirationMs));
            });

            window.setInterval(updateExpirationCountdowns, 1000);
        });
    </script>
</body>

</html>
