diff --git a/public/app.js b/public/app.js
index b31089c..648a3e5 100644
--- a/public/app.js
+++ b/public/app.js
@@ -318,6 +318,13 @@ const imagePreviewContainer = document.getElementById("imagePreviewContainer");
const imagePreviewList = document.getElementById("imagePreviewList");
const clearImagesBtn = document.getElementById("clearImagesBtn");
+// Элементы для загрузки файлов
+const fileBtn = document.getElementById("fileBtn");
+const fileInput = document.getElementById("fileInput");
+const filePreviewContainer = document.getElementById("filePreviewContainer");
+const filePreviewList = document.getElementById("filePreviewList");
+const clearFilesBtn = document.getElementById("clearFilesBtn");
+
// Элементы для предпросмотра заметки
const notePreviewContainer = document.getElementById("notePreviewContainer");
const notePreviewContent = document.getElementById("notePreviewContent");
@@ -329,6 +336,7 @@ const modalClose = document.querySelector(".image-modal-close");
// Массив для хранения выбранных изображений
let selectedImages = [];
+let selectedFiles = [];
// Флаг режима предпросмотра
let isPreviewMode = false;
@@ -1156,6 +1164,19 @@ imageBtn.addEventListener("touchend", function (event) {
imageInput.click();
});
+// Обработчик для кнопки прикрепления файлов
+fileBtn.addEventListener("click", function (event) {
+ event.preventDefault();
+ event.stopPropagation();
+ fileInput.click();
+});
+
+fileBtn.addEventListener("touchend", function (event) {
+ event.preventDefault();
+ event.stopPropagation();
+ fileInput.click();
+});
+
// Обработчик для кнопки предпросмотра
previewBtn.addEventListener("click", function () {
togglePreview();
@@ -1399,6 +1420,48 @@ clearImagesBtn.addEventListener("click", function () {
imageInput.value = "";
});
+// Обработчик для загрузки файлов
+fileInput.addEventListener("change", function (event) {
+ const files = Array.from(event.target.files);
+ let addedCount = 0;
+
+ files.forEach((file) => {
+ // Проверяем размер файла (максимум 50MB)
+ if (file.size > 50 * 1024 * 1024) {
+ showNotification(
+ `Файл "${file.name}" слишком большой. Максимальный размер: 50MB`,
+ "error"
+ );
+ return;
+ }
+
+ // Проверяем, не добавлен ли уже файл с таким именем и размером
+ const isDuplicate = selectedFiles.some(
+ (existingFile) =>
+ existingFile.name === file.name && existingFile.size === file.size
+ );
+
+ if (!isDuplicate) {
+ selectedFiles.push(file);
+ addedCount++;
+ }
+ });
+
+ if (addedCount > 0) {
+ updateFilePreview();
+ showNotification(`Добавлено файлов: ${addedCount}`, "success");
+ }
+
+ fileInput.value = "";
+});
+
+// Обработчик очистки всех файлов
+clearFilesBtn.addEventListener("click", function () {
+ selectedFiles = [];
+ updateFilePreview();
+ fileInput.value = "";
+});
+
// Обработчики модального окна
modalClose.addEventListener("click", function () {
imageModal.style.display = "none";
@@ -1473,6 +1536,65 @@ function updateImagePreview() {
});
}
+// Функция для обновления превью файлов
+function updateFilePreview() {
+ if (selectedFiles.length === 0) {
+ filePreviewContainer.style.display = "none";
+ return;
+ }
+
+ filePreviewContainer.style.display = "block";
+ filePreviewList.innerHTML = "";
+
+ selectedFiles.forEach((file, index) => {
+ const previewItem = document.createElement("div");
+ previewItem.className = "file-preview-item";
+
+ // Форматируем размер файла
+ const fileSize = (file.size / 1024 / 1024).toFixed(2);
+ const fileName =
+ file.name.length > 30 ? file.name.substring(0, 30) + "..." : file.name;
+
+ // Определяем иконку по расширению файла
+ const ext = file.name.split(".").pop().toLowerCase();
+ let icon = "mdi:file";
+ if (ext === "pdf") icon = "mdi:file-pdf";
+ else if (["doc", "docx"].includes(ext)) icon = "mdi:file-word";
+ else if (["xls", "xlsx"].includes(ext)) icon = "mdi:file-excel";
+ else if (ext === "txt") icon = "mdi:file-document";
+ else if (["zip", "rar", "7z"].includes(ext)) icon = "mdi:folder-zip";
+
+ previewItem.innerHTML = `
+
📎 Загрузка файлов...
+ 💾 Сохранение заметки...
${
- selectedImages.length > 0
- ? `