/* settings.js — Halaman pengaturan: perusahaan, HR, status, data */
(function () {
'use strict';
var $ = function (s, r) { return (r || document).querySelector(s); };
function esc(v) { return UI.escape(v); }
function init() {
Store.init();
loadSettings();
renderStatuses();
renderInfo();
bind();
}
function loadSettings() {
var s = Store.get().settings;
$('#s-perusahaan').value = s.perusahaan || '';
$('#s-hr').value = s.hr || '';
$('#s-jabatan').value = s.jabatanHr || '';
}
function renderStatuses() {
var list = Store.sortedStatuses();
$('#statusBody').innerHTML = list.map(function (s) {
return '
' +
'| ' + s.urutan + ' | ' +
'' + esc(s.nama) + ' | ' +
'' + esc(s.warna) + ' | ' +
'' + (s.isFinal ? 'Ya' : '-') + ' | ' +
'' +
'' +
'' +
' | ' +
'
';
}).join('');
}
function renderInfo() {
Store.fileCount().then(function (n) {
$('#dataInfo').textContent = 'Jumlah pelamar: ' + Store.get().candidates.length +
' • Template: ' + Store.get().templates.length +
' • Berkas tersimpan: ' + n;
}).catch(function () {
$('#dataInfo').textContent = 'Jumlah pelamar: ' + Store.get().candidates.length +
' • Template: ' + Store.get().templates.length;
});
}
function openStatusForm(id) {
var s = id ? Store.statusById(id) : null;
var body =
'' +
'' +
'
' +
'
' +
'
' +
'
';
var footer = '' +
'';
UI.openModal({
title: id ? 'Edit Status' : 'Tambah Status', body: body, footer: footer,
onMount: function (el) {
el.querySelector('[data-close]').addEventListener('click', UI.closeModal);
el.querySelector('#saveStatus').addEventListener('click', function () {
var nama = el.querySelector('#st-nama').value.trim();
if (!nama) { UI.toast('Nama status wajib diisi.', 'err'); return; }
var urutanVal = el.querySelector('#st-urutan').value;
Store.saveStatus({
id: id || undefined,
nama: nama,
warna: el.querySelector('#st-warna').value,
urutan: urutanVal ? parseInt(urutanVal, 10) : undefined,
isFinal: el.querySelector('#st-final').value === '1'
});
UI.toast('Status disimpan.', 'ok');
UI.closeModal();
renderStatuses();
});
}
});
}
function download(filename, text) {
var blob = new Blob([text], { type: 'application/json' });
var url = URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url; a.download = filename;
document.body.appendChild(a); a.click(); a.remove();
setTimeout(function () { URL.revokeObjectURL(url); }, 500);
}
function doExport() {
Store.exportData().then(function (data) {
var text = JSON.stringify(data);
var stamp = new Date().toISOString().slice(0, 10).replace(/-/g, '');
download('e-recruitment-backup-' + stamp + '.json', text);
UI.toast('Backup berhasil diunduh.', 'ok');
}).catch(function (err) { UI.toast('Gagal export: ' + err.message, 'err'); });
}
function doImport(file) {
var reader = new FileReader();
reader.onload = function () {
var data;
try { data = JSON.parse(reader.result); }
catch (e) { UI.toast('File JSON tidak valid.', 'err'); return; }
if (!UI.confirmDialog('Import akan MENGGANTI seluruh data saat ini. Lanjutkan?')) return;
Store.importData(data).then(function () {
UI.toast('Data berhasil diimport.', 'ok');
loadSettings(); renderStatuses(); renderInfo();
}).catch(function (err) { UI.toast('Gagal import: ' + err.message, 'err'); });
};
reader.readAsText(file);
}
function doExportExcel() {
var list = Store.get().candidates;
if (!list.length) { UI.toast('Belum ada data pelamar untuk diexport.', 'err'); return; }
try {
Excel.exportCandidates(list, Store.get().statuses);
UI.toast('File Excel diunduh.', 'ok');
} catch (err) { UI.toast('Gagal export Excel: ' + err.message, 'err'); }
}
function doImportExcel(file) {
UI.toast('Membaca file Excel...');
Excel.readRows(file).then(function (json) {
var mapped = Excel.mapRows(json, Store.get().statuses);
var valid = [], invalid = 0;
mapped.forEach(function (row) {
var norm = Phone.normalize(row.phoneRaw || '');
if (!row.nama || !Phone.isValid(norm)) { invalid++; return; }
row.phoneNorm = norm;
valid.push(row);
});
if (!valid.length) { UI.toast('Tidak ada baris valid. Kolom "Nama" dan "No WhatsApp" wajib terisi.', 'err'); return; }
var pesan = 'Ditemukan ' + valid.length + ' baris valid' +
(invalid ? ' dan ' + invalid + ' baris dilewati' : '') +
'.\n\nTambahkan baris valid ke daftar pelamar?';
if (!UI.confirmDialog(pesan)) return;
valid.forEach(function (row) { Store.addCandidate(row); });
UI.toast(valid.length + ' pelamar ditambahkan.', 'ok');
renderInfo();
}).catch(function (err) { UI.toast('Gagal import Excel: ' + err.message, 'err'); });
}
function bind() {
$('#saveSettings').addEventListener('click', function () {
Store.setSettings({
perusahaan: $('#s-perusahaan').value.trim(),
hr: $('#s-hr').value.trim(),
jabatanHr: $('#s-jabatan').value.trim()
});
UI.toast('Pengaturan disimpan.', 'ok');
});
$('#btnAddStatus').addEventListener('click', function () { openStatusForm(null); });
$('#btnExport').addEventListener('click', doExport);
$('#btnImport').addEventListener('click', function () { $('#importFile').click(); });
$('#importFile').addEventListener('change', function (e) {
if (e.target.files && e.target.files[0]) doImport(e.target.files[0]);
e.target.value = '';
});
$('#btnExportExcel').addEventListener('click', doExportExcel);
$('#btnImportExcel').addEventListener('click', function () { $('#importExcelFile').click(); });
$('#btnTemplateExcel').addEventListener('click', function () {
try { Excel.exportTemplate(); UI.toast('Template Excel diunduh.', 'ok'); }
catch (err) { UI.toast('Gagal mengunduh template: ' + err.message, 'err'); }
});
$('#importExcelFile').addEventListener('change', function (e) {
if (e.target.files && e.target.files[0]) doImportExcel(e.target.files[0]);
e.target.value = '';
});
$('#btnReset').addEventListener('click', function () {
if (!UI.confirmDialog('Reset akan menghapus SEMUA data pelamar, template, dan berkas. Lanjutkan?')) return;
Store.reset().then(function () {
UI.toast('Data telah direset.', 'ok');
loadSettings(); renderStatuses(); renderInfo();
});
});
document.addEventListener('click', function (e) {
var edit = e.target.closest('[data-st-edit]');
if (edit) { openStatusForm(edit.getAttribute('data-st-edit')); return; }
var del = e.target.closest('[data-st-del]');
if (del) {
var s = Store.statusById(del.getAttribute('data-st-del'));
if (s && UI.confirmDialog('Hapus status "' + s.nama + '"?')) {
try { Store.deleteStatus(s.id); UI.toast('Status dihapus.', 'ok'); renderStatuses(); }
catch (err) { UI.toast(err.message, 'err'); }
}
}
});
}
document.addEventListener('DOMContentLoaded', init);
})();