Добавь в систему субд firebase .
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Движение возвратного потока</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- Подключение Google Fonts -->
    <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet">
    <!-- Подключение Font Awesome CSS -->
   <link
  rel="stylesheet"
  href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css"
  integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ=="
  crossorigin="anonymous"
    />
    <!-- Ваши стили CSS -->
    <style>
        /* Переменные для тем */
        :root {
            --background-color: #f5f5f5;
            --text-color: #333;
            --container-background: #fff;
            --button-background: linear-gradient(135deg, #DA22FF, #9733EE);
            --button-color: #fff;
            --nav-button-background: linear-gradient(135deg, #DA22FF, #9733EE);
            --nav-button-active-background: linear-gradient(135deg, #9733EE, #DA22FF);
            --input-background: #fff;
            --input-color: #333;
            --table-border-color: #e0e0e0;
            --table-header-background: #e0e0e0;
            --table-header-color: #333;
        }
        [data-theme="dark"] {
            --background-color: #1e1e1e;
            --text-color: #f5f5f5;
            --container-background: #2e2e2e;
            --button-background: linear-gradient(135deg, #9733EE, #DA22FF);
            --button-color: #fff;
            --nav-button-background: linear-gradient(135deg, #9733EE, #DA22FF);
            --nav-button-active-background: linear-gradient(135deg, #DA22FF, #9733EE);
            --input-background: #3e3e3e;
            --input-color: #f5f5f5;
            --table-border-color: #555;
            --table-header-background: #555;
            --table-header-color: #f5f5f5;
        }

        /* Стили оформления */
        body {
            font-family: 'Poppins', sans-serif;
            background-color: var(--background-color);
            color: var(--text-color);
            margin: 0;
            padding: 0;
            overflow-x: hidden;
        }
        .container {
            width: 95%;
            max-width: 1200px;
            margin: 20px auto;
            background: var(--container-background);
            padding: 20px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            border-radius: 12px;
            position: relative;
        }
        h1, h2 {
            text-align: center;
            color: var(--text-color);
        }
        nav {
            display: flex;
            justify-content: space-around;
            margin-bottom: 10px;
            flex-wrap: wrap;
        }
        nav button {
            flex: 1;
            padding: 10px;
            margin: 5px;
            cursor: pointer;
            background: var(--nav-button-background);
            color: var(--button-color);
            border: none;
            border-radius: 5px;
            font-size: 16px;
            transition: background 0.3s;
            min-width: 100px;
        }
        nav button.active-tab {
            background: var(--nav-button-active-background);
        }
        .section {
            display: none;
        }
        .active-section {
            display: block;
        }
        label {
            display: block;
            margin: 10px 0 5px;
            font-size: 14px;
            color: var(--text-color);
        }
        input[type="text"], input[type="file"], select {
            width: 100%;
            padding: 12px;
            margin-bottom: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            font-size: 14px;
            box-sizing: border-box;
            background-color: var(--input-background);
            color: var(--input-color);
        }
        button {
            padding: 12px 15px;
            cursor: pointer;
            background: var(--button-background);
            color: var(--button-color);
            border: none;
            border-radius: 5px;
            font-size: 16px;
            transition: background 0.3s;
        }
        button:hover {
            background: linear-gradient(135deg, #9733EE, #DA22FF);
        }
        .export-buttons {
            margin: 10px 0;
            text-align: center;
        }
        .switch-user-btn {
            position: absolute;
            top: 15px;
            right: 15px;
            background-color: transparent;
            color: var(--text-color);
            font-size: 14px;
            border: none;
            cursor: pointer;
        }
        .switch-user-btn:hover {
            text-decoration: underline;
        }
        .theme-toggle-btn {
            position: absolute;
            top: 15px;
            right: 150px;
            background-color: transparent;
            color: var(--text-color);
            font-size: 18px;
            border: none;
            cursor: pointer;
        }
        .theme-toggle-btn i {
            pointer-events: none;
        }
        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 10px;
            font-size: 12px;
        }
        th, td {
            border: 1px solid var(--table-border-color);
            padding: 10px;
            text-align: center;
        }
        th {
            background-color: var(--table-header-background);
            color: var(--table-header-color);
        }
        .status-accepted {
            color: #388e3c;
            font-weight: bold;
        }
        .status-placed {
            color: #fbc02d;
            font-weight: bold;
        }
        .status-written-off {
            color: #d32f2f;
            font-weight: bold;
        }
        .status-reaccepted {
            color: #1976d2;
            font-weight: bold;
        }
        .status-movement {
            color: #ff9800;
            font-weight: bold;
        }
        .search-container, .log-container {
            margin: 10px 0;
            text-align: center;
        }
        .login-container {
            width: 95%;
            max-width: 400px;
            margin: 100px auto;
            background: var(--container-background);
            padding: 20px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            border-radius: 12px;
            text-align: center;
        }
        .login-container h2 {
            margin-bottom: 15px;
            color: var(--text-color);
        }
        .small-buttons {
            position: absolute;
            top: 15px;
            left: 15px;
        }
        .small-buttons button {
            padding: 8px 10px;
            margin: 5px 0;
            font-size: 12px;
            background-color: var(--nav-button-background);
            color: var(--button-color);
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }
        .dropdown-buttons {
            display: none;
            flex-direction: column;
            position: absolute;
            top: 60px;
            left: 15px;
            background-color: var(--container-background);
            padding: 10px;
            border-radius: 8px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        }
        .dropdown-buttons button {
            margin: 5px 0;
            width: 150px;
            background-color: var(--button-background);
            color: var(--button-color);
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }
        .additional-buttons {
            display: flex;
            justify-content: center;
            margin: 10px 0;
            flex-wrap: wrap;
        }
        .additional-buttons button {
            flex: 1;
            margin: 5px;
            padding: 10px;
            font-size: 14px;
            background-color: #e0e0e0;
            color: #333;
            min-width: 100px;
        }
        .additional-buttons button.active-tab {
            background: var(--button-background);
            color: var(--button-color);
        }
        .input-group {
            display: flex;
            align-items: center;
        }
        .input-group input[type="text"] {
            flex: 1;
        }
        .file-upload-btn {
            display: inline-block;
            padding: 12px;
            margin-left: 5px;
            cursor: pointer;
            background: var(--button-background);
            color: var(--button-color);
            border: none;
            border-radius: 5px;
            font-size: 16px;
            text-align: center;
        }
        .file-upload-btn:hover {
            background: linear-gradient(135deg, #9733EE, #DA22FF);
        }
        .file-upload-btn i {
            pointer-events: none;
        }
        /* Стиль для футера */
        footer {
            text-align: center;
            margin-top: 20px;
            padding: 10px;
            background-color: var(--container-background);
            color: var(--text-color);
            font-size: 14px;
            border-top: 1px solid var(--table-border-color);
        }
        /* Адаптивный дизайн */
        @media screen and (max-width: 768px) {
            nav button, label, input[type="text"], input[type="file"], button {
                font-size: 14px;
            }
            th, td {
                font-size: 10px;
                padding: 8px;
            }
            .switch-user-btn, .theme-toggle-btn {
                top: 10px;
                right: 10px;
            }
            .small-buttons {
                top: 10px;
                left: 10px;
            }
            .login-container {
                margin: 50px auto;
                padding: 15px;
            }
            .login-container h2 {
                margin-bottom: 10px;
            }
            nav {
                flex-direction: column;
            }
            nav button {
                margin: 5px 0;
            }
            .dropdown-buttons {
                top: 50px;
                left: 10px;
            }
        }
    </style>
</head>
<body>
    <!-- Форма входа -->
    <div id="loginSection" class="login-container">
        <h2>Вход в систему</h2>
        <form id="loginForm">
            <label for="username">Логин:</label>
            <input type="text" id="username" required autofocus>
            <button type="submit">Войти</button>
        </form>
    </div>

    <!-- Основной контент -->
    <div id="mainContent" class="container" style="display: none;">
        <button id="themeToggleBtn" class="theme-toggle-btn"><i class="fas fa-moon"></i></button>
        <button id="switchUserBtn" class="switch-user-btn">Пользователь: <span id="currentUserDisplay"></span> (Сменить)</button>
        <div class="small-buttons">
            <button id="toggleDropdownBtn"><i class="fas fa-bars"></i></button>
            <div id="dropdownButtons" class="dropdown-buttons">
                <button id="deleteUserLogsBtn">Удалить логи</button>
                <button id="exportDataBtn">Выгрузить данные</button>
                <button id="exportLogBtn">Выгрузить журнал</button>
                <button id="deleteWrittenOffBtn">Удалить списанные</button>
                <button id="clearDataBtn" class="clear-btn">Удалить все данные</button>
            </div>
        </div>
        <h1>Движение возвратного потока</h1>
        <nav>
            <button id="acceptTab" class="active-tab">Приемка</button>
            <button id="placementTab">Размещение</button>
            <button id="writeOffTab">Списание</button>
            <button id="rescanTab">Перескан</button>
        </nav>

        <!-- Секция приемки посылок -->
        <div id="acceptSection" class="section active-section">
            <h2>Приемка посылок</h2>
            <form id="acceptForm">
                <label for="acceptParcelNumber">Сканируйте или введите номер посылки:</label>
                <div class="input-group">
                    <input type="text" id="acceptParcelNumber" autofocus>
                    <label for="acceptFileInput" class="file-upload-btn"><i class="fas fa-upload"></i></label>
                    <input type="file" id="acceptFileInput" accept=".xlsx, .txt" style="display: none;">
                </div>
                <button type="submit">Добавить посылку</button>
            </form>
        </div>

        <!-- Секция размещения посылок -->
        <div id="placementSection" class="section">
            <h2>Размещение посылок</h2>
            <form id="placementForm">
                <label for="placementParcelNumber">Сканируйте номер посылки:</label>
                <input type="text" id="placementParcelNumber" autofocus>
                <label for="placementCellNumber">Сканируйте номер ячейки:</label>
                <input type="text" id="placementCellNumber" disabled>
            </form>
        </div>

        <!-- Секция списания посылок -->
        <div id="writeOffSection" class="section">
            <h2>Списание посылок</h2>
            <form id="writeOffForm">
                <label for="writeOffParcelNumber">Сканируйте или введите номер посылки:</label>
                <div class="input-group">
                    <input type="text" id="writeOffParcelNumber">
                    <label for="writeOffFileInput" class="file-upload-btn"><i class="fas fa-upload"></i></label>
                    <input type="file" id="writeOffFileInput" accept=".xlsx, .txt" style="display: none;">
                </div>
                <button type="submit">Списать посылку</button>
            </form>
        </div>

        <!-- Секция перескана посылок -->
        <div id="rescanSection" class="section">
            <h2>Перескан посылок</h2>
            <form id="rescanForm">
                <label for="rescanParcelNumber">Сканируйте или введите номер посылки:</label>
                <input type="text" id="rescanParcelNumber">
                <button type="submit">Пересканировать посылку</button>
            </form>
        </div>

        <!-- Кнопки переключения между поиском и журналом -->
        <div class="additional-buttons">
            <button id="toggleSearchBtn">Поиск посылок</button>
            <button id="toggleLogBtn">Журнал сканирований</button>
        </div>

        <!-- Поиск посылок -->
        <div id="searchContainer" class="search-container" style="display: none;">
            <h2>Поиск посылок</h2>
            <select id="searchCriteria">
                <option value="parcelNumber">По номеру посылки</option>
                <option value="cellNumber">По номеру ячейки</option>
                <option value="status">По статусу</option>
                <option value="user">По пользователю</option>
            </select>
            <input type="text" id="searchInput" placeholder="Введите значение для поиска">
            <button id="searchBtn">Поиск</button>
            <button id="resetSearchBtn">Сбросить</button>
        </div>

        <!-- Таблица посылок -->
        <table id="parcelTable">
            <thead>
                <tr>
                    <th>Дата и время приема</th>
                    <th>Пользователь</th>
                    <th>Номер посылки</th>
                    <th>Дата и время движения</th>
                    <th>Номер ячейки</th>
                    <th>Статус</th>
                    <th>Дата и время списания</th>
                </tr>
            </thead>
            <tbody>
                <!-- Список посылок будет отображаться здесь -->
            </tbody>
        </table>
    </div>

    <!-- Секция журнала сканирований (отдельный блок) -->
    <div id="logContainer" class="container" style="display: none;">
        <h2>Журнал сканирований</h2>
        <div class="log-filter">
            <label for="logUserFilter">Фильтр по пользователю:</label>
            <input type="text" id="logUserFilter" placeholder="Введите имя пользователя">
            <label for="logParcelFilter">Фильтр по посылке:</label>
            <input type="text" id="logParcelFilter" placeholder="Введите номер посылки">
            <button id="applyLogFilterBtn">Применить фильтр</button>
            <button id="resetLogFilterBtn">Сбросить фильтр</button>
        </div>
        <div class="log-table">
            <table id="logTable">
                <thead>
                    <tr>
                        <th>Дата и время</th>
                        <th>Пользователь</th>
                        <th>Действие</th>
                        <th>Номер посылки</th>
                        <th>Номер ячейки</th>
                    </tr>
                </thead>
                <tbody>
                    <!-- Логи будут отображаться здесь -->
                </tbody>
            </table>
        </div>
    </div>

    <!-- Футер с информацией о разработчике -->
    <footer>
        <p>ООО СберЛогистика. Разработчик: Текучев М.Ю</p>
    </footer>

    <!-- Подключение библиотеки SheetJS для экспорта в XLSX -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.17.0/xlsx.full.min.js"></script>

    <!-- Ваш основной JavaScript-код -->
    <script>
        // Глобальные переменные
        let parcels = [];
        let logs = [];
        let currentUser = null;

        // Элементы интерфейса
        const loginSection = document.getElementById('loginSection');
        const mainContent = document.getElementById('mainContent');
        const loginForm = document.getElementById('loginForm');
        const usernameInput = document.getElementById('username');

        const acceptTab = document.getElementById('acceptTab');
        const placementTab = document.getElementById('placementTab');
        const writeOffTab = document.getElementById('writeOffTab');
        const rescanTab = document.getElementById('rescanTab');

        const acceptSection = document.getElementById('acceptSection');
        const placementSection = document.getElementById('placementSection');
        const writeOffSection = document.getElementById('writeOffSection');
        const rescanSection = document.getElementById('rescanSection');

        const acceptForm = document.getElementById('acceptForm');
        const placementForm = document.getElementById('placementForm');
        const writeOffForm = document.getElementById('writeOffForm');
        const rescanForm = document.getElementById('rescanForm');

        const acceptParcelNumber = document.getElementById('acceptParcelNumber');
        const placementParcelNumber = document.getElementById('placementParcelNumber');
        const placementCellNumber = document.getElementById('placementCellNumber');
        const writeOffParcelNumber = document.getElementById('writeOffParcelNumber');
        const rescanParcelNumber = document.getElementById('rescanParcelNumber');

        const acceptFileInput = document.getElementById('acceptFileInput');
        const writeOffFileInput = document.getElementById('writeOffFileInput');

        const parcelTableBody = document.querySelector('#parcelTable tbody');
        const exportDataBtn = document.getElementById('exportDataBtn');
        const exportLogBtn = document.getElementById('exportLogBtn');
        const clearDataBtn = document.getElementById('clearDataBtn');
        const deleteWrittenOffBtn = document.getElementById('deleteWrittenOffBtn');

        const searchCriteria = document.getElementById('searchCriteria');
        const searchInput = document.getElementById('searchInput');
        const searchBtn = document.getElementById('searchBtn');
        const resetSearchBtn = document.getElementById('resetSearchBtn');
        const toggleSearchBtn = document.getElementById('toggleSearchBtn');
        const searchContainer = document.getElementById('searchContainer');

        const logTableBody = document.querySelector('#logTable tbody');
        const toggleLogBtn = document.getElementById('toggleLogBtn');
        const logContainer = document.getElementById('logContainer');
        const deleteUserLogsBtn = document.getElementById('deleteUserLogsBtn');

        const switchUserBtn = document.getElementById('switchUserBtn');
        const currentUserDisplay = document.getElementById('currentUserDisplay');
        const themeToggleBtn = document.getElementById('themeToggleBtn');

        const toggleDropdownBtn = document.getElementById('toggleDropdownBtn');
        const dropdownButtons = document.getElementById('dropdownButtons');

        // Элементы для фильтрации журнала
        const logUserFilter = document.getElementById('logUserFilter');
        const logParcelFilter = document.getElementById('logParcelFilter');
        const applyLogFilterBtn = document.getElementById('applyLogFilterBtn');
        const resetLogFilterBtn = document.getElementById('resetLogFilterBtn');

        // Обработчик для кнопки переключения видимости дополнительных кнопок
        toggleDropdownBtn.addEventListener('click', () => {
            if (dropdownButtons.style.display === 'none' || dropdownButtons.style.display === '') {
                dropdownButtons.style.display = 'flex';
            } else {
                dropdownButtons.style.display = 'none';
            }
        });

        // Обработчик переключения темы
        themeToggleBtn.addEventListener('click', () => {
            const currentTheme = document.documentElement.getAttribute('data-theme');
            if (currentTheme === 'dark') {
                document.documentElement.setAttribute('data-theme', 'light');
                localStorage.setItem('theme', 'light');
                themeToggleBtn.innerHTML = '<i class="fas fa-moon"></i>';
            } else {
                document.documentElement.setAttribute('data-theme', 'dark');
                localStorage.setItem('theme', 'dark');
                themeToggleBtn.innerHTML = '<i class="fas fa-sun"></i>';
            }
        });

        // Установка сохранённой темы и данных при загрузке страницы
        window.addEventListener('load', () => {
            const savedTheme = localStorage.getItem('theme') || 'light';
            document.documentElement.setAttribute('data-theme', savedTheme);
            themeToggleBtn.innerHTML = savedTheme === 'dark' ? '<i class="fas fa-sun"></i>' : '<i class="fas fa-moon"></i>';

            const savedUser = localStorage.getItem('currentUser');
            if (savedUser) {
                currentUser = savedUser;
                currentUserDisplay.textContent = currentUser;
                loginSection.style.display = 'none';
                mainContent.style.display = 'block';
                loadData();
            }
        });

        // Обработчик события отправки формы входа
        loginForm.addEventListener('submit', function(event) {
            event.preventDefault();
            const username = usernameInput.value.trim();

            if (username) {
                currentUser = username;
                localStorage.setItem('currentUser', currentUser);
                currentUserDisplay.textContent = currentUser;
                loginSection.style.display = 'none';
                mainContent.style.display = 'block';

                loadData();
            } else {
                alert('Пожалуйста, введите логин.');
            }
        });

        // Обработчик для кнопки "Сменить пользователя"
        switchUserBtn.addEventListener('click', () => {
            const password = prompt('Введите пароль для смены пользователя:');
            if (password === '8080') {
                currentUser = null;
                localStorage.removeItem('currentUser');
                currentUserDisplay.textContent = '';
                loginSection.style.display = 'block';
                mainContent.style.display = 'none';
                usernameInput.value = '';
                usernameInput.focus();
            } else {
                alert('Неверный пароль.');
            }
        });

        // Функция загрузки данных после входа
        function loadData() {
            // Загрузка данных из localStorage
            const savedParcels = localStorage.getItem('parcels');
            const savedLogs = localStorage.getItem('logs');

            parcels = savedParcels ? JSON.parse(savedParcels) : [];
            logs = savedLogs ? JSON.parse(savedLogs) : [];

            updateParcelTable();
            updateLogTable();
        }

        // Переключение между вкладками
        acceptTab.addEventListener('click', () => {
            showSection(acceptSection);
            setActiveTab(acceptTab);
            acceptParcelNumber.focus();
        });

        placementTab.addEventListener('click', () => {
            showSection(placementSection);
            setActiveTab(placementTab);
            placementParcelNumber.focus();
        });

        writeOffTab.addEventListener('click', () => {
            showSection(writeOffSection);
            setActiveTab(writeOffTab);
            writeOffParcelNumber.focus();
        });

        rescanTab.addEventListener('click', () => {
            showSection(rescanSection);
            setActiveTab(rescanTab);
            rescanParcelNumber.focus();
        });

        function showSection(section) {
            const sections = document.querySelectorAll('.section');
            sections.forEach(sec => sec.classList.remove('active-section'));
            section.classList.add('active-section');
        }

        function setActiveTab(tab) {
            const tabs = document.querySelectorAll('nav button');
            tabs.forEach(btn => btn.classList.remove('active-tab'));
            tab.classList.add('active-tab');
        }

        // Приемка посылок
        acceptForm.addEventListener('submit', function(event) {
            event.preventDefault();
            acceptParcel();
        });

        function acceptParcel() {
            const parcelNumber = acceptParcelNumber.value.trim().toLowerCase();
            if (!parcelNumber) {
                return;
            }

            const existingParcel = parcels.find(parcel => parcel.parcelNumber === parcelNumber);

            const now = new Date();
            const acceptanceDateTime = now.toLocaleString();

            if (existingParcel) {
                if (existingParcel.status === 'Written-off') {
                    existingParcel.acceptanceDateTime = acceptanceDateTime;
                    existingParcel.cellNumber = '';
                    existingParcel.status = 'Reaccepted';
                    existingParcel.writeOffDateTime = '';
                    existingParcel.user = currentUser;
                    existingParcel.movementDateTime = acceptanceDateTime;
                    addLog('Повторная приемка', parcelNumber, '');
                } else {
                    alert('Посылка с таким номером уже существует.');
                    acceptParcelNumber.value = '';
                    return;
                }
            } else {
                const newParcel = {
                    parcelNumber,
                    acceptanceDateTime,
                    movementDateTime: acceptanceDateTime,
                    cellNumber: '',
                    status: 'Accepted',
                    writeOffDateTime: '',
                    user: currentUser
                };
                parcels.push(newParcel);
                addLog('Приемка', parcelNumber, '');
            }

            saveData();
            updateParcelTable();

            acceptParcelNumber.value = '';
            acceptParcelNumber.focus();

            // Виброотклик на мобильных устройствах
            if ("vibrate" in navigator) {
                navigator.vibrate(100);
            }
        }

        // Размещение посылок
        placementParcelNumber.addEventListener('keypress', function(event) {
            if (event.key === 'Enter') {
                event.preventDefault();
                if (placementParcelNumber.value.trim() !== '') {
                    placementCellNumber.disabled = false;
                    placementCellNumber.focus();
                }
            }
        });

        placementCellNumber.addEventListener('keypress', function(event) {
            if (event.key === 'Enter') {
                event.preventDefault();
                if (placementCellNumber.value.trim() !== '') {
                    placeParcel();
                }
            }
        });

        function placeParcel() {
            const parcelNumber = placementParcelNumber.value.trim().toLowerCase();
            const cellNumber = placementCellNumber.value.trim();

            if (!parcelNumber || !cellNumber) {
                alert('Введите номер посылки и номер ячейки.');
                return;
            }

            const existingParcel = parcels.find(parcel => parcel.parcelNumber === parcelNumber);

            if (existingParcel) {
                const now = new Date();
                const movementDateTime = now.toLocaleString();
                existingParcel.cellNumber = cellNumber;
                existingParcel.status = 'Placed';
                existingParcel.user = currentUser;
                existingParcel.movementDateTime = movementDateTime;
                addLog('Размещение', parcelNumber, cellNumber);
                saveData();
                updateParcelTable();
            } else {
                alert('Посылка с таким номером не найдена.');
            }

            placementParcelNumber.value = '';
            placementCellNumber.value = '';
            placementCellNumber.disabled = true;
            placementParcelNumber.focus();

            // Виброотклик на мобильных устройствах
            if ("vibrate" in navigator) {
                navigator.vibrate(100);
            }
        }

        // Списание посылок
        writeOffForm.addEventListener('submit', function(event) {
            event.preventDefault();
            writeOffParcel();
        });

        function writeOffParcel() {
            const parcelNumber = writeOffParcelNumber.value.trim().toLowerCase();
            if (!parcelNumber) {
                return;
            }

            const existingParcel = parcels.find(parcel => parcel.parcelNumber === parcelNumber);

            if (existingParcel) {
                const now = new Date();
                const writeOffDateTime = now.toLocaleString();

                existingParcel.cellNumber = '';
                existingParcel.status = 'Written-off';
                existingParcel.writeOffDateTime = writeOffDateTime;
                existingParcel.user = currentUser;
                existingParcel.movementDateTime = writeOffDateTime;
                addLog('Списание', parcelNumber, '');
                saveData();
                updateParcelTable();
            } else {
                alert('Посылка с таким номером не найдена.');
            }

            writeOffParcelNumber.value = '';
            writeOffParcelNumber.focus();

            // Виброотклик на мобильных устройствах
            if ("vibrate" in navigator) {
                navigator.vibrate(100);
            }
        }

        // Перескан посылок
        rescanForm.addEventListener('submit', function(event) {
            event.preventDefault();
            rescanParcel();
        });

        function rescanParcel() {
            const parcelNumber = rescanParcelNumber.value.trim().toLowerCase();
            if (!parcelNumber) {
                return;
            }

            const existingParcel = parcels.find(parcel => parcel.parcelNumber === parcelNumber);

            if (existingParcel) {
                const now = new Date();
                const movementDateTime = now.toLocaleString();

                existingParcel.movementDateTime = movementDateTime;
                existingParcel.status = 'Movement';
                existingParcel.user = currentUser;
                addLog('Перескан', parcelNumber, '');
                saveData();
                updateParcelTable();
            } else {
                alert('Посылка с таким номером не найдена.');
            }

            rescanParcelNumber.value = '';
            rescanParcelNumber.focus();

            // Виброотклик на мобильных устройствах
            if ("vibrate" in navigator) {
                navigator.vibrate(100);
            }
        }

        // Функция для добавления записи в журнал
        function addLog(action, parcelNumber, cellNumber) {
            const now = new Date();
            const dateTime = now.toLocaleString();
            const logEntry = {
                dateTime,
                user: currentUser,
                action,
                parcelNumber,
                cellNumber
            };
            logs.push(logEntry);
            saveData();
            updateLogTable();
        }

        // Функция для сохранения данных в localStorage
        function saveData() {
            localStorage.setItem('parcels', JSON.stringify(parcels));
            localStorage.setItem('logs', JSON.stringify(logs));
        }

        // Функция для обновления таблицы посылок
        function updateParcelTable(filteredParcels = parcels) {
            parcelTableBody.innerHTML = '';

            const parcelsToDisplay = filteredParcels.slice().reverse();

            parcelsToDisplay.forEach(parcel => {
                const row = document.createElement('tr');

                const acceptanceDateTimeCell = document.createElement('td');
                acceptanceDateTimeCell.textContent = parcel.acceptanceDateTime;
                row.appendChild(acceptanceDateTimeCell);

                const userCell = document.createElement('td');
                userCell.textContent = parcel.user || '';
                row.appendChild(userCell);

                const parcelNumberCell = document.createElement('td');
                parcelNumberCell.textContent = parcel.parcelNumber;
                row.appendChild(parcelNumberCell);

                const movementDateTimeCell = document.createElement('td');
                movementDateTimeCell.textContent = parcel.movementDateTime || '';
                row.appendChild(movementDateTimeCell);

                const cellNumberCell = document.createElement('td');
                cellNumberCell.textContent = parcel.cellNumber || '';
                row.appendChild(cellNumberCell);

                const statusCell = document.createElement('td');
                statusCell.textContent = getStatusText(parcel.status);
                statusCell.classList.add(getStatusClass(parcel.status));
                row.appendChild(statusCell);

                const writeOffDateTimeCell = document.createElement('td');
                writeOffDateTimeCell.textContent = parcel.writeOffDateTime || '';
                row.appendChild(writeOffDateTimeCell);

                parcelTableBody.appendChild(row);
            });
        }

        // Функция для обновления таблицы логов
        function updateLogTable(filteredLogs = logs) {
            logTableBody.innerHTML = '';

            const logsToDisplay = filteredLogs.slice().reverse();

            logsToDisplay.forEach(log => {
                const row = document.createElement('tr');

                const dateTimeCell = document.createElement('td');
                dateTimeCell.textContent = log.dateTime;
                row.appendChild(dateTimeCell);

                const userCell = document.createElement('td');
                userCell.textContent = log.user;
                row.appendChild(userCell);

                const actionCell = document.createElement('td');
                actionCell.textContent = log.action;
                row.appendChild(actionCell);

                const parcelNumberCell = document.createElement('td');
                parcelNumberCell.textContent = log.parcelNumber;
                row.appendChild(parcelNumberCell);

                const cellNumberCell = document.createElement('td');
                cellNumberCell.textContent = log.cellNumber || '';
                row.appendChild(cellNumberCell);

                logTableBody.appendChild(row);
            });
        }

        // Функции для получения текстового представления статуса и класса статуса
        function getStatusText(status) {
            switch (status) {
                case 'Accepted':
                    return 'Принята';
                case 'Placed':
                    return 'Размещена';
                case 'Written-off':
                    return 'Списана';
                case 'Reaccepted':
                    return 'Повторно принята';
                case 'Movement':
                    return 'Движение';
                default:
                    return status;
            }
        }

        function getStatusClass(status) {
            switch (status) {
                case 'Accepted':
                    return 'status-accepted';
                case 'Placed':
                    return 'status-placed';
                case 'Written-off':
                    return 'status-written-off';
                case 'Reaccepted':
                    return 'status-reaccepted';
                case 'Movement':
                    return 'status-movement';
                default:
                    return '';
            }
        }

        // Обработчики для кнопок экспорта и удаления данных
        clearDataBtn.addEventListener('click', function() {
            const password1 = prompt('Введите первый пароль для удаления данных:');
            if (password1 === '5704202') {
                const password2 = prompt('Введите второй пароль для удаления данных:');
                if (password2 === '05704202') {
                    deleteAllData();
                } else {
                    alert('Неверный второй пароль.');
                }
            } else {
                alert('Неверный первый пароль.');
            }
        });

        deleteWrittenOffBtn.addEventListener('click', function() {
            const password = prompt('Введите пароль для удаления списанных посылок:');
            if (password === '0242') {
                deleteWrittenOffParcels();
            } else {
                alert('Неверный пароль.');
            }
        });

        function deleteAllData() {
            parcels = [];
            logs = [];
            saveData();
            updateParcelTable();
            updateLogTable();
            alert('Все данные удалены.');
        }

        function deleteWrittenOffParcels() {
            parcels = parcels.filter(parcel => parcel.status !== 'Written-off');
            saveData();
            updateParcelTable();
            alert('Все списанные посылки удалены.');
        }

        // Функция для экспорта данных
        function exportData(dataToExport, fileName) {
            const worksheet = XLSX.utils.json_to_sheet(dataToExport);
            const workbook = XLSX.utils.book_new();
            XLSX.utils.book_append_sheet(workbook, worksheet, 'Данные');

            XLSX.writeFile(workbook, fileName);
        }

        // Обработчик для экспорта всех данных
        exportDataBtn.addEventListener('click', function() {
            if (parcels.length === 0) {
                alert('Нет данных для экспорта.');
                return;
            }

            const dataToExport = parcels.map(parcel => ({
                'Дата и время приема': parcel.acceptanceDateTime,
                'Пользователь': parcel.user || '',
                'Номер посылки': parcel.parcelNumber,
                'Дата и время движения': parcel.movementDateTime || '',
                'Номер ячейки': parcel.cellNumber || '',
                'Статус': getStatusText(parcel.status),
                'Дата и время списания': parcel.writeOffDateTime || ''
            }));

            exportData(dataToExport, 'vse_dannye.xlsx');
        });

        // Обработчик для экспорта журнала сканирований
        exportLogBtn.addEventListener('click', function() {
            if (logs.length === 0) {
                alert('Нет данных для экспорта журнала сканирований.');
                return;
            }

            const dataToExport = logs.map(log => ({
                'Дата и время': log.dateTime,
                'Пользователь': log.user,
                'Действие': log.action,
                'Номер посылки': log.parcelNumber,
                'Номер ячейки': log.cellNumber || ''
            }));

            exportData(dataToExport, 'zhurnal_skanirovaniy.xlsx');
        });

        // Обработчики поиска
        searchBtn.addEventListener('click', function() {
            const criteria = searchCriteria.value;
            const searchValue = searchInput.value.trim().toLowerCase();

            if (!searchValue) {
                alert('Введите значение для поиска.');
                return;
            }

            const filteredParcels = parcels.filter(parcel => {
                let fieldValue = '';
                if (criteria === 'parcelNumber') {
                    fieldValue = parcel.parcelNumber.toLowerCase();
                } else if (criteria === 'cellNumber') {
                    fieldValue = parcel.cellNumber ? parcel.cellNumber.toLowerCase() : '';
                } else if (criteria === 'status') {
                    fieldValue = getStatusText(parcel.status).toLowerCase();
                } else if (criteria === 'user') {
                    fieldValue = parcel.user ? parcel.user.toLowerCase() : '';
                }

                return fieldValue.includes(searchValue);
            });

            updateParcelTable(filteredParcels);
        });

        resetSearchBtn.addEventListener('click', function() {
            searchInput.value = '';
            updateParcelTable();
        });

        // Обработчики для кнопок переключения поиска и журнала
        toggleSearchBtn.addEventListener('click', () => {
            if (searchContainer.style.display === 'none') {
                searchContainer.style.display = 'block';
            } else {
                searchContainer.style.display = 'none';
            }
        });

        toggleLogBtn.addEventListener('click', () => {
            if (logContainer.style.display === 'none') {
                logContainer.style.display = 'block';
                updateLogTable();
            } else {
                logContainer.style.display = 'none';
            }
        });

        // Обработчик для фильтрации журнала сканирований
        applyLogFilterBtn.addEventListener('click', () => {
            const userFilter = logUserFilter.value.trim().toLowerCase();
            const parcelFilter = logParcelFilter.value.trim().toLowerCase();

            if (userFilter === '' && parcelFilter === '') {
                alert('Введите имя пользователя или номер посылки для фильтрации.');
                return;
            }

            let filteredLogs = logs;

            if (userFilter !== '') {
                filteredLogs = filteredLogs.filter(log => log.user.toLowerCase().includes(userFilter));
            }

            if (parcelFilter !== '') {
                filteredLogs = filteredLogs.filter(log => log.parcelNumber.toLowerCase().includes(parcelFilter));
            }

            updateLogTable(filteredLogs);
        });

        resetLogFilterBtn.addEventListener('click', () => {
            logUserFilter.value = '';
            logParcelFilter.value = '';
            updateLogTable();
        });

        // Обработчик для загрузки файлов в приемке
        acceptFileInput.addEventListener('change', function(event) {
            const file = event.target.files[0];
            if (file) {
                processFile(file, 'accept');
            }
            acceptFileInput.value = '';
        });

        // Обработчик для загрузки файлов в списании
        writeOffFileInput.addEventListener('change', function(event) {
            const file = event.target.files[0];
            if (file) {
                processFile(file, 'writeOff');
            }
            writeOffFileInput.value = '';
        });

        // Обновлённая функция для обработки загруженного файла
        function processFile(file, action) {
            const reader = new FileReader();
            reader.onload = function(e) {
                let data;
                if (file.name.endsWith('.xlsx')) {
                    const dataArray = new Uint8Array(e.target.result);
                    const workbook = XLSX.read(dataArray, { type: 'array' });
                    const firstSheetName = workbook.SheetNames[0];
                    const worksheet = workbook.Sheets[firstSheetName];
                    data = XLSX.utils.sheet_to_json(worksheet, { defval: '' });

                    if (action === 'accept') {
                        acceptParcelsFromFile(data);
                    } else if (action === 'writeOff') {
                        writeOffParcelsFromFile(data);
                    }
                } else if (file.name.endsWith('.txt')) {
                    const content = e.target.result;
                    const lines = content.split(/\r?\n/).map(line => line.trim()).filter(line => line !== '');

                    if (action === 'accept') {
                        acceptParcelsFromTxt(lines);
                    } else if (action === 'writeOff') {
                        writeOffParcelsFromTxt(lines);
                    }
                } else {
                    alert('Неподдерживаемый формат файла.');
                    return;
                }
            };

            reader.onloadend = function() {
                alert('Файл успешно загружен.');
            };

            if (file.name.endsWith('.txt')) {
                reader.readAsText(file);
            } else {
                reader.readAsArrayBuffer(file);
            }
        }

        // Функция для приемки посылок из txt файла
        function acceptParcelsFromTxt(lines) {
            lines.forEach(parcelNumber => {
                parcelNumber = parcelNumber.toLowerCase();
                const existingParcel = parcels.find(parcel => parcel.parcelNumber === parcelNumber);

                const now = new Date();
                const acceptanceDateTime = now.toLocaleString();

                if (parcelNumber) {
                    if (existingParcel) {
                        if (existingParcel.status === 'Written-off') {
                            existingParcel.acceptanceDateTime = acceptanceDateTime;
                            existingParcel.cellNumber = '';
                            existingParcel.status = 'Reaccepted';
                            existingParcel.writeOffDateTime = '';
                            existingParcel.user = currentUser;
                            existingParcel.movementDateTime = acceptanceDateTime;
                            addLog('Повторная приемка', parcelNumber, '');
                        } else {
                            // Посылка уже существует и не списана, пропускаем её
                            return;
                        }
                    } else {
                        const newParcel = {
                            parcelNumber,
                            acceptanceDateTime,
                            movementDateTime: acceptanceDateTime,
                            cellNumber: '',
                            status: 'Accepted',
                            writeOffDateTime: '',
                            user: currentUser
                        };
                        parcels.push(newParcel);
                        addLog('Приемка', parcelNumber, '');
                    }
                }
            });

            saveData();
            updateParcelTable();
        }

        // Функция для списания посылок из txt файла
        function writeOffParcelsFromTxt(lines) {
            lines.forEach(parcelNumber => {
                parcelNumber = parcelNumber.toLowerCase();
                const existingParcel = parcels.find(parcel => parcel.parcelNumber === parcelNumber);

                if (parcelNumber) {
                    if (existingParcel) {
                        const now = new Date();
                        const writeOffDateTime = now.toLocaleString();
                        existingParcel.cellNumber = '';
                        existingParcel.status = 'Written-off';
                        existingParcel.writeOffDateTime = writeOffDateTime;
                        existingParcel.user = currentUser;
                        existingParcel.movementDateTime = writeOffDateTime;
                        addLog('Списание', parcelNumber, '');
                    } else {
                        // Посылка не найдена, пропускаем её
                        return;
                    }
                }
            });

            saveData();
            updateParcelTable();
        }

        // Обновлённая функция для приемки посылок из xlsx файла
        function acceptParcelsFromFile(data) {
            data.forEach(row => {
                // Преобразуем названия столбцов в нижний регистр для независимости от регистра
                const keys = Object.keys(row).reduce((acc, key) => {
                    acc[key.toLowerCase()] = row[key];
                    return acc;
                }, {});

                const parcelNumber = keys['id посылки'] ? keys['id посылки'].toString().trim().toLowerCase() : '';
                const acceptanceDateTime = keys['дата и время приема'] ? keys['дата и время приема'].toString().trim() : '';
                const status = keys['статус'] ? keys['статус'].toString().trim() : 'Accepted';

                if (parcelNumber) {
                    const existingParcel = parcels.find(parcel => parcel.parcelNumber === parcelNumber);

                    if (existingParcel) {
                        if (existingParcel.status === 'Written-off') {
                            existingParcel.acceptanceDateTime = acceptanceDateTime || new Date().toLocaleString();
                            existingParcel.cellNumber = '';
                            existingParcel.status = 'Reaccepted';
                            existingParcel.writeOffDateTime = '';
                            existingParcel.user = currentUser;
                            existingParcel.movementDateTime = existingParcel.acceptanceDateTime;
                            addLog('Повторная приемка', parcelNumber, '');
                        } else {
                            // Посылка уже существует и не списана, пропускаем её
                            return;
                        }
                    } else {
                        const newParcel = {
                            parcelNumber,
                            acceptanceDateTime: acceptanceDateTime || new Date().toLocaleString(),
                            movementDateTime: acceptanceDateTime || new Date().toLocaleString(),
                            cellNumber: '',
                            status: status === 'Движение' ? 'Movement' : 'Accepted',
                            writeOffDateTime: '',
                            user: currentUser
                        };
                        parcels.push(newParcel);
                        addLog('Приемка', parcelNumber, '');
                    }
                }
            });

            saveData();
            updateParcelTable();
        }

        // Обновлённая функция для списания посылок из xlsx файла
        function writeOffParcelsFromFile(data) {
            data.forEach(row => {
                // Преобразуем названия столбцов в нижний регистр для независимости от регистра
                const keys = Object.keys(row).reduce((acc, key) => {
                    acc[key.toLowerCase()] = row[key];
                    return acc;
                }, {});

                const parcelNumber = keys['id посылки'] ? keys['id посылки'].toString().trim().toLowerCase() : '';

                if (parcelNumber) {
                    const existingParcel = parcels.find(parcel => parcel.parcelNumber === parcelNumber);

                    if (existingParcel) {
                        const now = new Date();
                        const writeOffDateTime = now.toLocaleString();
                        existingParcel.cellNumber = '';
                        existingParcel.status = 'Written-off';
                        existingParcel.writeOffDateTime = writeOffDateTime;
                        existingParcel.user = currentUser;
                        existingParcel.movementDateTime = writeOffDateTime;
                        addLog('Списание', parcelNumber, '');
                    } else {
                        // Посылка не найдена, пропускаем её
                        return;
                    }
                }
            });

            saveData();
            updateParcelTable();
        }

        // Обработчик для удаления логов пользователей
        deleteUserLogsBtn.addEventListener('click', function() {
            const password = prompt('Введите пароль для удаления логов:');
            if (password === '4202') {
                const uniqueUsers = [...new Set(logs.map(log => log.user))];
                const userToDelete = prompt('Введите имя пользователя для удаления логов:\n' + uniqueUsers.join('\n'));
                if (userToDelete && uniqueUsers.includes(userToDelete)) {
                    logs = logs.filter(log => log.user !== userToDelete);
                    saveData();
                    updateLogTable();
                    alert('Логи пользователя ' + userToDelete + ' удалены.');
                } else {
                    alert('Пользователь не найден.');
                }
            } else {
                alert('Неверный пароль.');
            }
        });

    </script>
</body>
</html>