feat: inital commit project
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
/* berkas.js — Halaman daftar & unggah berkas pelamar */
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var $ = function (s, r) { return (r || document).querySelector(s); };
|
||||
var SLOTS = [
|
||||
{ key: 'cv', label: 'CV' },
|
||||
{ key: 'test', label: 'Hasil Test' },
|
||||
{ key: 'portofolio', label: 'Portofolio' }
|
||||
];
|
||||
var MAX_FILE = 5 * 1024 * 1024; // 5 MB
|
||||
var q = '';
|
||||
|
||||
function esc(v) { return UI.escape(v); }
|
||||
|
||||
function init() {
|
||||
Store.init();
|
||||
render();
|
||||
$('#bSearch').addEventListener('input', function (e) { q = e.target.value.toLowerCase(); render(); });
|
||||
}
|
||||
|
||||
function slotCell(c, slot) {
|
||||
var b = c.berkas && c.berkas[slot.key];
|
||||
var value = '<span class="muted small">Belum ada</span>';
|
||||
if (b) {
|
||||
var label = b.mode === 'file' ? b.name : (b.url.length > 34 ? b.url.slice(0, 34) + '…' : b.url);
|
||||
value = '<div>' + (b.mode === 'file' ? '📎 ' : '🔗 ') + esc(label) +
|
||||
(b.mode === 'file' ? ' <span class="muted small">(' + UI.formatBytes(b.size) + ')</span>' : '') + '</div>';
|
||||
}
|
||||
return '<td>' + value +
|
||||
'<div class="actions mt1">' +
|
||||
(b ? '<button class="btn btn-ghost btn-sm" data-open="' + slot.key + '" data-id="' + c.id + '">Lihat</button>' : '') +
|
||||
'<label class="btn btn-ghost btn-sm" style="margin:0">Upload<input type="file" hidden data-berkas-file="' + slot.key + '" data-id="' + c.id + '" accept=".pdf,.doc,.docx,.jpg,.jpeg,.png"></label>' +
|
||||
'<button class="btn btn-ghost btn-sm" data-berkas-link="' + slot.key + '" data-id="' + c.id + '">Link</button>' +
|
||||
(b ? '<button class="btn btn-danger btn-sm" data-berkas-del="' + slot.key + '" data-id="' + c.id + '">Hapus</button>' : '') +
|
||||
'</div></td>';
|
||||
}
|
||||
|
||||
function render() {
|
||||
var list = Store.get().candidates.filter(function (c) {
|
||||
if (!q) return true;
|
||||
return (c.nama || '').toLowerCase().indexOf(q) >= 0 || (c.posisi || '').toLowerCase().indexOf(q) >= 0;
|
||||
});
|
||||
|
||||
if (!list.length) {
|
||||
$('#bBody').innerHTML = '';
|
||||
$('#bEmpty').classList.remove('hidden');
|
||||
$('.table-wrap').classList.add('hidden');
|
||||
return;
|
||||
}
|
||||
$('#bEmpty').classList.add('hidden');
|
||||
$('.table-wrap').classList.remove('hidden');
|
||||
|
||||
$('#bBody').innerHTML = list.map(function (c) {
|
||||
return '<tr>' +
|
||||
'<td><strong>' + esc(c.nama) + '</strong><div class="muted small">' + esc(c.posisi) + '</div></td>' +
|
||||
SLOTS.map(function (s) { return slotCell(c, s); }).join('') +
|
||||
'</tr>';
|
||||
}).join('');
|
||||
}
|
||||
|
||||
function setBerkas(id, slot, value) {
|
||||
var c = Store.candidateById(id);
|
||||
if (!c) return;
|
||||
c.berkas = c.berkas || { cv: null, test: null, portofolio: null };
|
||||
var old = c.berkas[slot];
|
||||
if (old && old.mode === 'file' && old.fileId && (!value || value.fileId !== old.fileId)) {
|
||||
Store.deleteFile(old.fileId).catch(function () {});
|
||||
}
|
||||
c.berkas[slot] = value;
|
||||
Store.save();
|
||||
}
|
||||
|
||||
function handleFile(input) {
|
||||
var file = input.files && input.files[0];
|
||||
if (!file) return;
|
||||
var id = input.getAttribute('data-id');
|
||||
var slot = input.getAttribute('data-berkas-file');
|
||||
if (file.size > MAX_FILE) { UI.toast('Ukuran berkas maksimal 5 MB.', 'err'); input.value = ''; return; }
|
||||
UI.toast('Menyimpan berkas...');
|
||||
Store.saveFile(file).then(function (meta) {
|
||||
setBerkas(id, slot, { mode: 'file', fileId: meta.id, name: meta.name, size: meta.size, type: meta.type });
|
||||
UI.toast('Berkas tersimpan.', 'ok');
|
||||
render();
|
||||
}).catch(function (err) {
|
||||
UI.toast('Gagal menyimpan berkas: ' + err.message, 'err');
|
||||
});
|
||||
input.value = '';
|
||||
}
|
||||
|
||||
document.addEventListener('click', function (e) {
|
||||
var openBtn = e.target.closest('[data-open]');
|
||||
if (openBtn) {
|
||||
var c = Store.candidateById(openBtn.getAttribute('data-id'));
|
||||
var b = c && c.berkas && c.berkas[openBtn.getAttribute('data-open')];
|
||||
if (!b) return;
|
||||
if (b.mode === 'link') { window.open(b.url, '_blank', 'noopener'); return; }
|
||||
Store.getFileUrl(b.fileId).then(function (url) { window.open(url, '_blank', 'noopener'); })
|
||||
.catch(function () { UI.toast('Berkas tidak ditemukan.', 'err'); });
|
||||
return;
|
||||
}
|
||||
|
||||
var linkBtn = e.target.closest('[data-berkas-link]');
|
||||
if (linkBtn) {
|
||||
var id = linkBtn.getAttribute('data-id');
|
||||
var slot = linkBtn.getAttribute('data-berkas-link');
|
||||
var url = window.prompt('Masukkan URL berkas (Google Drive, dll):');
|
||||
if (url && url.trim()) {
|
||||
setBerkas(id, slot, { mode: 'link', url: url.trim() });
|
||||
UI.toast('Link tersimpan.', 'ok');
|
||||
render();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var delBtn = e.target.closest('[data-berkas-del]');
|
||||
if (delBtn) {
|
||||
if (UI.confirmDialog('Hapus berkas ini?')) {
|
||||
setBerkas(delBtn.getAttribute('data-id'), delBtn.getAttribute('data-berkas-del'), null);
|
||||
UI.toast('Berkas dihapus.', 'ok');
|
||||
render();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('change', function (e) {
|
||||
var input = e.target.closest('[data-berkas-file]');
|
||||
if (input) handleFile(input);
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
})();
|
||||
Reference in New Issue
Block a user