service.ejs 4.24 KB
<!DOCTYPE html>
<html lang="id">
<head><%- include('partials/head') %></head>
<body class="app-page">
  <%- include('partials/nav') %>

  <main class="main-content">
    <div class="page-header">
      <div>
        <h1 class="page-title">MONITOR SERVICE</h1>
        <p class="page-sub">Status & kontrol service PXE Server</p>
      </div>
      <div class="header-time">
        <span class="status-dot active pulse"></span>
        <span>Live — refresh otomatis tiap 10 detik</span>
      </div>
    </div>

    <%- include('partials/flash') %>

    <section class="section">
      <h2 class="section-title">STATUS SERVICE</h2>
      <div class="service-list" id="service-list">
        <% statuses.forEach(svc => { %>
        <div class="service-row <%= svc.active ? 'active' : 'stopped' %>" data-service="<%= svc.name %>">
          <div class="svc-indicator">
            <span class="svc-dot <%= svc.active ? 'dot-active' : 'dot-stopped' %>"></span>
          </div>
          <div class="svc-info">
            <div class="svc-name"><%= svc.name %></div>
            <div class="svc-desc"><%= serviceDesc(svc.name) %></div>
          </div>
          <div class="svc-status-badge <%= svc.active ? 'badge-active' : 'badge-stopped' %>">
            <%= svc.active ? 'AKTIF' : 'MATI' %>
          </div>
          <div class="svc-actions">
            <% if (!svc.active) { %>
            <form action="/service/start/<%= svc.name %>" method="POST" style="display:inline">
              <button class="btn-svc btn-start" title="Start">▶ Start</button>
            </form>
            <% } %>
            <% if (svc.active) { %>
            <form action="/service/restart/<%= svc.name %>" method="POST" style="display:inline">
              <button class="btn-svc btn-restart" title="Restart">↺ Restart</button>
            </form>
            <form action="/service/stop/<%= svc.name %>" method="POST" style="display:inline"
              onsubmit="return confirm('Yakin hentikan service <%= svc.name %>?')">
              <button class="btn-svc btn-stop" title="Stop">■ Stop</button>
            </form>
            <% } %>
          </div>
        </div>
        <% }) %>
      </div>
    </section>

    <section class="section">
      <h2 class="section-title">INFO SISTEM</h2>
      <div class="sys-info-grid">
        <div class="sys-info-card">
          <div class="si-label">DISK USAGE (/var/www/html)</div>
          <div class="si-value mono"><%= diskInfo || 'N/A' %></div>
        </div>
        <div class="sys-info-card">
          <div class="si-label">UPTIME SERVER</div>
          <div class="si-value mono"><%= uptime || 'N/A' %></div>
        </div>
        <div class="sys-info-card">
          <div class="si-label">WAKTU SEKARANG</div>
          <div class="si-value mono" id="sys-clock"></div>
        </div>
      </div>
    </section>
  </main>
  <%- include('partials/footer') %>
  <script>
    // Auto refresh status tiap 10 detik
    function refreshStatus() {
      fetch('/service/api/status')
        .then(r => r.json())
        .then(data => {
          data.statuses.forEach(svc => {
            const row = document.querySelector(`[data-service="${svc.name}"]`);
            if (!row) return;
            row.className = `service-row ${svc.active ? 'active' : 'stopped'}`;
            const dot = row.querySelector('.svc-dot');
            dot.className = `svc-dot ${svc.active ? 'dot-active' : 'dot-stopped'}`;
            const badge = row.querySelector('.svc-status-badge');
            badge.className = `svc-status-badge ${svc.active ? 'badge-active' : 'badge-stopped'}`;
            badge.textContent = svc.active ? 'AKTIF' : 'MATI';
          });
        })
        .catch(() => {});
    }

    setInterval(refreshStatus, 10000);

    // Clock
    function tick() {
      document.getElementById('sys-clock').textContent = new Date().toLocaleString('id-ID');
    }
    tick(); setInterval(tick, 1000);
  </script>
</body>
</html>

<% function serviceDesc(name) {
  const map = {
    'tftpd-hpa': 'TFTP Server — Transfer file boot ke client PXE',
    'nginx': 'Web Server — Serve file melalui HTTP/NFS',
    'isc-dhcp-server': 'DHCP Server — Alokasi IP ke client lab',
    'nfs-kernel-server': 'NFS Server — Sharing filesystem ke client'
  };
  return map[name] || name;
} %>