feat: add file upload for materials (PDF/DOCX) with ingestion pipeline

This commit is contained in:
root
2026-04-29 15:52:35 +09:00
parent 518370b93e
commit 7f503326f9
51 changed files with 4712 additions and 27 deletions

View File

@@ -25,6 +25,9 @@ var els = {
progressDivider: document.querySelector("#progress-divider"),
refreshProgress: document.querySelector("#refresh-progress"),
materialForm: document.querySelector("#material-form"),
materialFile: document.querySelector("#material-file"),
fileNameDisplay: document.querySelector("#file-name"),
uploadFileButton: document.querySelector("#upload-file-button"),
assetForm: document.querySelector("#asset-form"),
ontology: document.querySelector("#ontology"),
assetOutput: document.querySelector("#asset-output"),
@@ -232,6 +235,55 @@ function renderBlock(el, title, items) {
"</ul>";
}
/* ---- File upload ---- */
els.materialFile.addEventListener("change", function() {
var file = els.materialFile.files[0];
if (file) {
els.fileNameDisplay.textContent = file.name;
els.uploadFileButton.disabled = false;
} else {
els.fileNameDisplay.textContent = "";
els.uploadFileButton.disabled = true;
}
});
els.uploadFileButton.addEventListener("click", function() {
var file = els.materialFile.files[0];
if (!file) return;
clearError();
setStatus(t("ingestingMaterial"), true);
els.uploadFileButton.disabled = true;
var formData = new FormData();
formData.append("file", file);
var title = document.querySelector("#material-title").value;
if (title) formData.append("title", title);
var token = localStorage.getItem("tutor_token");
var lang = localStorage.getItem("tutor_lang") || document.documentElement.lang || "ko";
var headers = {};
if (token) headers["Authorization"] = "Bearer " + token;
fetch("/api/v1/materials/upload", { method:"POST", headers:headers, body:formData })
.then(function(response) {
return response.json().then(function(body) {
if (!response.ok) throw new Error(body.error || "Upload failed: " + response.status);
state.ontology = body.snapshot;
renderOntology();
setStatus(t("materialIngested", body.material.id));
els.materialFile.value = "";
els.fileNameDisplay.textContent = "";
});
})
["catch"](function(error) {
showError(error.message); setStatus(t("contentReady"));
})
["finally"](function() {
els.uploadFileButton.disabled = false;
});
});
/* ---- Progress ---- */
els.refreshProgress.addEventListener("click", function() { clearError(); refreshProgress(); });