upload.ejs
5.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<!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];
} %>