var items = [];
var filterText = "";
async function load() {
items = await fetch("/api/items").then(function(r) { return r.json(); });
render();
}
function isComplete(r) {
return r.city && r.summa && r.date && r.fileSection && r.fio && r.docSection && r.payment &&
r.fileAttachment && r.docAttachment;
}
function paymentBadge(val) {
if (val === "оплачено") return '💰 ' + val + '';
if (val === "в ожидании") return '⏳ ' + val + '';
return '❌ ' + (val || "") + '';
}
function render() {
var q = filterText.toLowerCase();
var filtered = items.filter(function(i) {
return !q ||
(i.city || "").toLowerCase().indexOf(q) !== -1 ||
(i.fio || "").toLowerCase().indexOf(q) !== -1 ||
(i.fileSection || "").toLowerCase().indexOf(q) !== -1 ||
(i.docSection || "").toLowerCase().indexOf(q) !== -1 ||
(i.payment || "").toLowerCase().indexOf(q) !== -1;
});
var tbody = document.getElementById("tbody");
var empty = document.getElementById("empty");
if (filtered.length === 0) {
tbody.innerHTML = "";
empty.style.display = "block";
} else {
empty.style.display = "none";
tbody.innerHTML = filtered.map(function(r) {
var fileLink = r.fileAttachment ? '📎 ' + esc(r.fileAttachment.name) + '' : '';
var docLink = r.docAttachment ? '📎 ' + esc(r.docAttachment.name) + '' : '';
var payLink = r.paymentAttachment ? '
📎 ' + esc(r.paymentAttachment.name) + '' : '';
var rowClass = isComplete(r) ? ' class="row-complete"' : '';
return "
" +
"| " + esc(r.city) + " | " +
"" + (r.summa ? Number(r.summa).toLocaleString("ru-RU") : "") + " ₸ | " +
"" + esc(r.date) + " | " +
"" + esc(r.fileSection) + " " + fileLink + " | " +
"" + esc(r.fio) + " | " +
"" + esc(r.docSection) + " " + docLink + " | " +
"" + paymentBadge(r.payment) + payLink + " | " +
'' +
'' +
'' +
" | " +
"
";
}).join("");
}
updateStats(filtered);
}
function updateStats(filtered) {
var total = items.length;
var shown = filtered.length;
var sum = filtered.reduce(function(s, r) { return s + (parseFloat(r.summa) || 0); }, 0);
document.getElementById("stats").innerHTML =
'Всего: ' + total + '' +
'Показано: ' + shown + '' +
'Сумма: ' + sum.toLocaleString("ru-RU") + ' ₸';
}
function esc(s) { return (s || "").replace(/&/g,"&").replace(//g,">"); }
function openForm() {
document.getElementById("modal").style.display = "flex";
document.getElementById("formTitle").textContent = "Новая запись";
document.getElementById("form").reset();
document.getElementById("editId").value = "";
document.getElementById("previewFile").innerHTML = "";
document.getElementById("previewDoc").innerHTML = "";
document.getElementById("previewPayment").innerHTML = "";
}
function closeForm() { document.getElementById("modal").style.display = "none"; }
async function uploadFile(inputName) {
var input = document.querySelector("[name='" + inputName + "']");
if (!input || !input.files || !input.files[0]) return null;
var formData = new FormData();
formData.append("file", input.files[0]);
var resp = await fetch("/api/upload", { method: "POST", body: formData });
var result = await resp.json();
if (result.ok && result.files && result.files[0]) return result.files[0];
return null;
}
async function saveItem(e) {
e.preventDefault();
var form = e.target;
var fileData = await uploadFile("fileAttachment");
var docData = await uploadFile("docAttachment");
var payData = await uploadFile("paymentAttachment");
var data = {
city: form.city.value,
summa: form.summa.value,
date: form.date.value,
fileSection: form.fileSection.value,
fio: form.fio.value,
docSection: form.docSection.value,
payment: form.payment.value
};
var editId = document.getElementById("editId").value;
if (editId) {
var existing = items.find(function(i) { return i.id === parseInt(editId); });
data.fileAttachment = fileData || (existing ? existing.fileAttachment : null);
data.docAttachment = docData || (existing ? existing.docAttachment : null);
data.paymentAttachment = payData || (existing ? existing.paymentAttachment : null);
await fetch("/api/items/" + editId, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) });
} else {
data.fileAttachment = fileData;
data.docAttachment = docData;
data.paymentAttachment = payData;
await fetch("/api/items", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) });
}
closeForm();
load();
}
async function editItem(id) {
var item = items.find(function(i) { return i.id === id; });
if (!item) return;
document.getElementById("modal").style.display = "flex";
document.getElementById("formTitle").textContent = "Изменить запись";
document.getElementById("editId").value = id;
document.querySelector("[name=city]").value = item.city || "";
document.querySelector("[name=summa]").value = item.summa || "";
document.querySelector("[name=date]").value = item.date || "";
document.querySelector("[name=fileSection]").value = item.fileSection || "";
document.querySelector("[name=fio]").value = item.fio || "";
document.querySelector("[name=docSection]").value = item.docSection || "";
document.querySelector("[name=payment]").value = item.payment || "";
document.getElementById("previewFile").innerHTML = item.fileAttachment
? '📎 ' + esc(item.fileAttachment.name) + ''
: '';
document.getElementById("previewDoc").innerHTML = item.docAttachment
? '📎 ' + esc(item.docAttachment.name) + ''
: '';
document.getElementById("previewPayment").innerHTML = item.paymentAttachment
? '📎 ' + esc(item.paymentAttachment.name) + ''
: '';
}
async function deleteItem(id) {
if (!confirm("Удалить запись?")) return;
await fetch("/api/items/" + id, { method: "DELETE" });
load();
}
document.getElementById("search").addEventListener("input", function(e) {
filterText = e.target.value;
render();
});
function exportCsv() {
if (items.length === 0) { alert("Нет данных для выгрузки"); return; }
var head = ["Город","Сумма","Дата","Раздел для файла","Файл","ФИО","Раздел для документов","Документ","Платёж","Файл оплаты"];
var body = items.map(function(r) {
return [r.city, r.summa, r.date, r.fileSection, r.fileAttachment ? r.fileAttachment.name : "", r.fio, r.docSection, r.docAttachment ? r.docAttachment.name : "", r.payment, r.paymentAttachment ? r.paymentAttachment.name : ""]
.map(function(v) { return '"' + String(v || "").replace(/"/g, '""') + '"'; })
.join(";");
});
var csv = "\uFEFF" + [head.join(";"), ...body].join("\n");
var a = document.createElement("a");
a.href = URL.createObjectURL(new Blob([csv], { type: "text/csv" }));
a.download = "otchet.csv";
a.click();
}
load();