upload.ejs 5.34 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">UPLOAD FILE</h1>
        <p class="page-sub">Replace file live boot — <code class="path-inline"><%= liveDir %></code></p>
      </div>
    </div>

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

    <!-- Status file saat ini -->
    <section class="section">
      <h2 class="section-title">STATUS FILE SAAT INI</h2>
      <div class="file-status-list">
        <% files.forEach(f => { %>
        <div class="file-status-row <%= f.exists ? 'ok' : 'missing' %>">
          <div class="fs-name"><%= f.name %></div>
          <div class="fs-size"><%= f.exists ? formatBytes(f.size) : '—' %></div>
          <div class="fs-mtime"><%= f.exists ? new Date(f.mtime).toLocaleString('id-ID') : 'Tidak ada' %></div>
          <div class="fs-badge"><%= f.exists ? '✓ Ada' : '✕ Tidak Ada' %></div>
        </div>
        <% }) %>
      </div>
    </section>

    <!-- Form upload -->
    <section class="section">
      <h2 class="section-title">UPLOAD FILE BARU</h2>
      <form action="/files/upload" method="POST" enctype="multipart/form-data" id="upload-form">

        <div class="upload-grid">

          <div class="upload-zone" id="zone-vmlinuz">
            <div class="uz-header">
              <span class="uz-badge">KERNEL</span>
              <span class="uz-name">vmlinuz</span>
            </div>
            <label class="uz-drop" for="input-vmlinuz">
              <div class="drop-icon"></div>
              <div class="drop-text">Klik atau drag file vmlinuz</div>
              <div class="drop-info" id="info-vmlinuz">Belum ada file dipilih</div>
            </label>
            <input type="file" name="vmlinuz" id="input-vmlinuz" class="file-input" data-info="info-vmlinuz">
          </div>

          <div class="upload-zone" id="zone-initrd">
            <div class="uz-header">
              <span class="uz-badge">INITRD</span>
              <span class="uz-name">initrd.img</span>
            </div>
            <label class="uz-drop" for="input-initrd">
              <div class="drop-icon"></div>
              <div class="drop-text">Klik atau drag file initrd.img</div>
              <div class="drop-info" id="info-initrd">Belum ada file dipilih</div>
            </label>
            <input type="file" name="initrd" id="input-initrd" class="file-input" data-info="info-initrd">
          </div>

          <div class="upload-zone" id="zone-squashfs">
            <div class="uz-header">
              <span class="uz-badge">SQUASH</span>
              <span class="uz-name">filesystem.squashfs</span>
            </div>
            <label class="uz-drop" for="input-squashfs">
              <div class="drop-icon"></div>
              <div class="drop-text">Klik atau drag file squashfs</div>
              <div class="drop-info" id="info-squashfs">Belum ada file dipilih</div>
            </label>
            <input type="file" name="squashfs" id="input-squashfs" class="file-input" data-info="info-squashfs">
          </div>

        </div>

        <div class="upload-actions">
          <div class="upload-warn">
            ⚠ File yang diupload akan <strong>menimpa</strong> file yang ada. Pastikan file sudah benar sebelum upload.
          </div>
          <button type="submit" class="btn-upload" id="btn-upload">
            <span class="btn-icon">📤</span>
            <span>UPLOAD FILE</span>
          </button>
        </div>

        <!-- Progress bar -->
        <div class="upload-progress hidden" id="progress-wrap">
          <div class="progress-label">Mengupload...</div>
          <div class="progress-bar">
            <div class="progress-fill" id="progress-fill"></div>
          </div>
          <div class="progress-pct" id="progress-pct">0%</div>
        </div>

      </form>
    </section>
  </main>
  <%- include('partials/footer') %>
  <script>
    function formatBytes(b) {
      if (!b) return '0 B';
      const k = 1024, s = ['B','KB','MB','GB'];
      const i = Math.floor(Math.log(b) / Math.log(k));
      return (b / Math.pow(k, i)).toFixed(2) + ' ' + s[i];
    }

    // Preview nama file ketika dipilih
    document.querySelectorAll('.file-input').forEach(input => {
      input.addEventListener('change', () => {
        const info = document.getElementById(input.dataset.info);
        if (input.files[0]) {
          info.textContent = `${input.files[0].name} (${formatBytes(input.files[0].size)})`;
          input.closest('.upload-zone').classList.add('selected');
        }
      });
    });

    // Progress upload via XHR
    const form = document.getElementById('upload-form');
    form.addEventListener('submit', (e) => {
      const hasFile = [...document.querySelectorAll('.file-input')].some(i => i.files.length > 0);
      if (!hasFile) {
        e.preventDefault();
        alert('Pilih minimal satu file untuk diupload!');
        return;
      }
      document.getElementById('progress-wrap').classList.remove('hidden');
      document.getElementById('btn-upload').disabled = true;
    });
  </script>
</body>
</html>

<% function formatBytes(b) {
  if (!b || b === 0) return '0 B';
  const k = 1024, s = ['B','KB','MB','GB'];
  const i = Math.floor(Math.log(b) / Math.log(k));
  return (b / Math.pow(k, i)).toFixed(2) + ' ' + s[i];
} %>