anycoder-602888f9 / index.html
Barton0708's picture
Upload folder using huggingface_hub
9ce28e1 verified
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🌊 Karnet Manager Pro v3.0 - Морской интерфейс</title>
<style>
:root {
--sea-bg: #f0f8ff;
--sea-fg: #2f4f4f;
--sea-accent: #4682b4;
--sea-success: #20b2aa;
--sea-warning: #daa520;
--sea-error: #cd5c5c;
--sea-button: #e0f6ff;
--sea-button-hover: #87ceeb;
--sea-frame: #f5f5f5;
--sea-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
--sea-transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
color: var(--sea-fg);
position: relative;
}
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="%234682b4" fill-opacity="0.1" d="M0,96L48,112C96,128,192,160,288,160C384,160,480,128,576,122.7C672,117,768,139,864,138.7C960,139,1056,117,1152,106.7C1248,96,1344,96,1392,96L1440,96L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"></path></svg>') no-repeat bottom;
background-size: cover;
pointer-events: none;
opacity: 0.3;
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 20px;
position: relative;
z-index: 1;
}
header {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 25px;
margin-bottom: 30px;
box-shadow: var(--sea-shadow);
animation: slideDown 0.5s ease-out;
}
@keyframes slideDown {
from {
transform: translateY(-20px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
h1 {
color: var(--sea-accent);
font-size: 2.5em;
margin-bottom: 10px;
display: flex;
align-items: center;
gap: 15px;
}
.subtitle {
color: var(--sea-fg);
font-size: 1.1em;
opacity: 0.8;
}
.tabs {
display: flex;
gap: 10px;
margin-bottom: 30px;
flex-wrap: wrap;
background: rgba(255, 255, 255, 0.9);
padding: 10px;
border-radius: 15px;
box-shadow: var(--sea-shadow);
}
.tab-button {
padding: 12px 24px;
background: var(--sea-button);
border: none;
border-radius: 10px;
cursor: pointer;
font-size: 1em;
font-weight: 600;
color: var(--sea-fg);
transition: var(--sea-transition);
position: relative;
overflow: hidden;
}
.tab-button::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
transition: left 0.5s;
}
.tab-button:hover::before {
left: 100%;
}
.tab-button:hover {
background: var(--sea-button-hover);
transform: translateY(-2px);
box-shadow: 0 6px 12px rgba(70, 130, 180, 0.3);
}
.tab-button.active {
background: var(--sea-accent);
color: white;
}
.tab-content {
display: none;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 30px;
box-shadow: var(--sea-shadow);
animation: fadeIn 0.5s ease-out;
}
.tab-content.active {
display: block;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.form-group {
margin-bottom: 25px;
}
label {
display: block;
margin-bottom: 8px;
font-weight: 600;
color: var(--sea-fg);
}
input[type="text"],
input[type="email"],
select,
textarea {
width: 100%;
padding: 12px;
border: 2px solid #e0e0e0;
border-radius: 10px;
font-size: 1em;
transition: var(--sea-transition);
background: white;
}
input:focus,
select:focus,
textarea:focus {
outline: none;
border-color: var(--sea-accent);
box-shadow: 0 0 0 3px rgba(70, 130, 180, 0.1);
}
.button-group {
display: flex;
gap: 15px;
flex-wrap: wrap;
margin-top: 20px;
}
button {
padding: 12px 24px;
background: var(--sea-accent);
color: white;
border: none;
border-radius: 10px;
cursor: pointer;
font-size: 1em;
font-weight: 600;
transition: var(--sea-transition);
position: relative;
overflow: hidden;
}
button::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.5);
transform: translate(-50%, -50%);
transition: width 0.6s, height 0.6s;
}
button:hover::after {
width: 300px;
height: 300px;
}
button:hover {
background: var(--sea-button-hover);
transform: translateY(-2px);
box-shadow: 0 6px 12px rgba(70, 130, 180, 0.3);
}
button:active {
transform: translateY(0);
}
button.secondary {
background: var(--sea-button);
color: var(--sea-fg);
}
button.success {
background: var(--sea-success);
}
button.warning {
background: var(--sea-warning);
}
button.error {
background: var(--sea-error);
}
.log-container {
background: #1e1e1e;
color: #00ff00;
padding: 20px;
border-radius: 10px;
font-family: 'Consolas', 'Monaco', monospace;
font-size: 0.9em;
height: 300px;
overflow-y: auto;
margin-top: 20px;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3);
}
.log-entry {
margin-bottom: 5px;
padding: 5px;
border-radius: 3px;
transition: background 0.2s;
}
.log-entry:hover {
background: rgba(255, 255, 255, 0.05);
}
.log-entry.info {
color: #87ceeb;
}
.log-entry.success {
color: #90ee90;
}
.log-entry.warning {
color: #ffd700;
}
.log-entry.error {
color: #ff6b6b;
}
.status-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: var(--sea-accent);
color: white;
padding: 15px 30px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 -4px 6px rgba(0, 0, 0, 0.1);
z-index: 1000;
}
.status-message {
font-weight: 600;
display: flex;
align-items: center;
gap: 10px;
}
.progress-bar {
width: 200px;
height: 6px;
background: rgba(255, 255, 255, 0.3);
border-radius: 3px;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: white;
border-radius: 3px;
animation: progress 2s ease-in-out infinite;
}
@keyframes progress {
0% { width: 0%; }
50% { width: 70%; }
100% { width: 0%; }
}
.file-list {
background: var(--sea-frame);
border-radius: 10px;
padding: 15px;
margin-top: 15px;
max-height: 200px;
overflow-y: auto;
}
.file-item {
padding: 10px;
background: white;
border-radius: 8px;
margin-bottom: 10px;
display: flex;
justify-content: space-between;
align-items: center;
transition: var(--sea-transition);
}
.file-item:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transform: translateX(5px);
}
.checkbox-group {
display: flex;
gap: 20px;
margin: 15px 0;
flex-wrap: wrap;
}
.checkbox-wrapper {
display: flex;
align-items: center;
gap: 8px;
}
input[type="checkbox"] {
width: 20px;
height: 20px;
cursor: pointer;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-top: 20px;
}
.stat-card {
background: linear-gradient(135deg, var(--sea-accent), var(--sea-button-hover));
color: white;
padding: 20px;
border-radius: 15px;
text-align: center;
transition: var(--sea-transition);
}
.stat-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(70, 130, 180, 0.3);
}
.stat-number {
font-size: 2.5em;
font-weight: bold;
margin-bottom: 5px;
}
.stat-label {
font-size: 0.9em;
opacity: 0.9;
}
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 2000;
animation: fadeIn 0.3s;
}
.modal.active {
display: flex;
justify-content: center;
align-items: center;
}
.modal-content {
background: white;
border-radius: 20px;
padding: 30px;
max-width: 500px;
width: 90%;
animation: slideUp 0.3s;
}
@keyframes slideUp {
from {
transform: translateY(20px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
.toast {
position: fixed;
top: 20px;
right: 20px;
padding: 15px 20px;
border-radius: 10px;
color: white;
font-weight: 600;
z-index: 3000;
animation: slideInRight 0.3s;
display: none;
}
.toast.show {
display: block;
}
.toast.success {
background: var(--sea-success);
}
.toast.error {
background: var(--sea-error);
}
.toast.warning {
background: var(--sea-warning);
}
.toast.info {
background: var(--sea-accent);
}
@keyframes slideInRight {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.file-input-wrapper {
position: relative;
overflow: hidden;
display: inline-block;
width: 100%;
}
.file-input-wrapper input[type=file] {
position: absolute;
left: -9999px;
}
.file-input-label {
display: block;
padding: 12px;
background: var(--sea-button);
border: 2px dashed var(--sea-accent);
border-radius: 10px;
text-align: center;
cursor: pointer;
transition: var(--sea-transition);
}
.file-input-label:hover {
background: var(--sea-button-hover);
border-style: solid;
}
@media (max-width: 768px) {
.container {
padding: 10px;
}
h1 {
font-size: 1.8em;
}
.tabs {
justify-content: center;
}
.tab-button {
padding: 10px 16px;
font-size: 0.9em;
}
.button-group {
flex-direction: column;
}
button {
width: 100%;
}
.stats-grid {
grid-template-columns: 1fr;
}
}
.loader {
border: 3px solid #f3f3f3;
border-top: 3px solid var(--sea-accent);
border-radius: 50%;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
margin: 20px auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.floating {
animation: floating 3s ease-in-out infinite;
}
@keyframes floating {
0% { transform: translateY(0px); }
50% { transform: translateY(-10px); }
100% { transform: translateY(0px); }
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>
<span class="floating">🌊</span>
Karnet Manager Pro v3.0
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" style="font-size: 0.4em; color: var(--sea-accent); text-decoration: none;">Built with anycoder</a>
</h1>
<p class="subtitle">Морской интерфейс для управления карнетами</p>
</header>
<nav class="tabs">
<button class="tab-button active" onclick="switchTab('email')">
📧 Email Manager
</button>
<button class="tab-button" onclick="switchTab('karnet')">
📊 Karnet Manager Pro
</button>
<button class="tab-button" onclick="switchTab('daily')">
📅 Ежедневный Учет
</button>
<button class="tab-button" onclick="switchTab('settings')">
⚙️ Настройки
</button>
</nav>
<main>
<!-- Email Manager Tab -->
<div id="email" class="tab-content active">
<h2>📧 Outlook Attachment Saver</h2>
<div class="form-group">
<label for="email">📧 Email:</label>
<input type="email" id="email" placeholder="Введите email адрес">
</div>
<div class="button-group">
<button onclick="runOutlookSaver()">
🚀 Запустить OutlookAttachmentSaver
</button>
<button class="secondary" onclick="saveEmail()">
💾 Сохранить Email
</button>
</div>
<h3 style="margin-top: 30px;">📋 Лог операций</h3>
<div id="emailLog" class="log-container"></div>
</div>
<!-- Karnet Manager Pro Tab -->
<div id="karnet" class="tab-content">
<h2>📊 Karnet Manager Pro</h2>
<div class="form-group">
<label for="karnetFolder">📁 Папка с Excel файлами:</label>
<div style="display: flex; gap: 10px;">
<input type="text" id="karnetFolder" placeholder="Выберите папку с файлами">
<button onclick="browseFolder()">📁 Обзор</button>
</div>
</div>
<div class="form-group">
<label>🔍 Управление шаблоном</label>
<div style="background: var(--sea-frame); padding: 15px; border-radius: 10px;">
<p id="templateInfo">📋 Мастер-шаблон: Шаблоны/Книга5_fixed.xlsx</p>
<div class="button-group" style="margin-top: 15px;">
<button onclick="checkTemplate()">🔍 Проверить шаблон</button>
<button class="success" onclick="createTemplate()">🛠️ Создать шаблон</button>
</div>
</div>
</div>
<div class="form-group">
<label>⚡ Быстрая обработка файлов</label>
<div class="file-input-wrapper">
<input type="file" id="quickFiles" multiple accept=".xlsx,.xlsb">
<label for="quickFiles" class="file-input-label">
📁 Выберите файлы для быстрой обработки
</label>
</div>
<div id="quickFilesList" class="file-list"></div>
<div class="checkbox-group">
<div class="checkbox-wrapper">
<input type="checkbox" id="quickToTarget" checked>
<label for="quickToTarget">в Целевой файл</label>
</div>
<div class="checkbox-wrapper">
<input type="checkbox" id="quickToNew">
<label for="quickToNew">в Новый файл</label>
</div>
</div>
<div class="button-group">
<button onclick="quickProcessFiles()">⚡ Обработать</button>
<button class="secondary" onclick="clearQuickFiles()">🗑️ Очистить</button>
</div>
</div>
<div class="form-group">
<label for="targetFile">🎯 Целевой файл:</label>
<div style="display: flex; gap: 10px;">
<input type="text" id="targetFile" placeholder="Выберите целевой файл">
<button onclick="browseTargetFile()">📄 Выбрать</button>
</div>
<div class="checkbox-group">
<div class="checkbox-wrapper">
<input type="checkbox" id="headerPresent" checked>
<label for="headerPresent">Заголовки есть</label>
</div>
<div class="checkbox-wrapper">
<input type="checkbox" id="headerAbsent">
<label for="headerAbsent">Заголовков нет</label>
</div>
</div>
<div class="button-group">
<button onclick="mergeKarnets()">⚡ Обработать</button>
<button class="secondary" onclick="clearTargetFile()">🗑️ Очистить</button>
<button class="success" onclick="mergeKarnetsToNewFile()">
📥 Объединить в новый файл
</button>
</div>
</div>
<div class="stats-grid">
<div class="stat-card">
<div class="stat-number" id="filesProcessed">0</div>
<div class="stat-label">Файлов обработано</div>
</div>
<div class="stat-card">
<div class="stat-number" id="recordsProcessed">0</div>
<div class="stat-label">Записей обработано</div>
</div>
<div class="stat-card">
<div class="stat-number" id="errorsCount">0</div>
<div class="stat-label">Ошибок</div>
</div>
</div>
<h3 style="margin-top: 30px;">📋 Лог операций</h3>
<div id="karnetLog" class="log-container"></div>
</div>
<!-- Daily Accounting Tab -->
<div id="daily" class="tab-content">
<h2>📅 Ежедневный Учет</h2>
<div class="form-group">
<label for="dailyFolder">📁 Папка с файлами:</label>
<div style="display: flex; gap: 10px;">
<input type="text" id="dailyFolder" value="C:\\Work\\APP2\\Ежедневный">
<button onclick="browseDailyFolder()">📁 Обзор</button>
</div>
</div>
<div style="display: grid; grid-template-columns: 1fr auto 1fr; gap: 20px; margin-top: 20px;">
<div>
<h3>📄 Файлы и листы</h3>
<div id="filesTree" style="background: var(--sea-frame); padding: 15px; border-radius: 10px; height: 300px; overflow-y: auto;">
<!-- Files tree will be populated here -->
</div>
</div>
<div style="display: flex; flex-direction: column; justify-content: center; gap: 10px;">
<button onclick="moveSelectedSheet()">></button>
<button onclick="moveAllSheets()">>></button>
<button onclick="removeSelectedSheet()">&lt;</button>
<button onclick="clearSelectedSheets()">X</button>
</div>
<div>
<h3>📋 Выбранные листы</h3>
<div id="selectedTree" style="background: var(--sea-frame); padding: 15px; border-radius: 10px; height: 300px; overflow-y: auto;">
<!-- Selected sheets will be shown here -->
</div>
</div>
</div>
<div class="button-group" style="margin-top: 20px;">
<button onclick="transferSheets()">📦 Перенести</button>
<button class="success" onclick="mergeSheets()">🔗 Объединить</button>
<button class="secondary" onclick="refreshFiles()">🔄 Обновить</button>
</div>
</div>
<!-- Settings Tab -->
<div id="settings" class="tab-content">
<h2>⚙️ Настройки приложения</h2>
<div style="background: var(--sea-frame); padding: 20px; border-radius: 10px; margin-top: 20px;">
<h3>🌊 Karnet Manager Pro v3.0 - Морская версия</h3>
<div style="margin-top: 20px;">
<h4>✨ Новые возможности:</h4>
<ul style="margin-left: 20px; margin-top: 10px;">
<li>Морской интерфейс в спокойных тонах</li>
<li>Создание и управление шаблоном Книга5_fixed.xlsx</li>
<li>Быстрая обработка отдельных файлов карнетов</li>
<li>Улучшенная проверка соответствия заголовков</li>
<li>Детальная система логирования с эмодзи</li>
<li>Оптимизированный процесс объединения карнетов</li>
<li>Проверка отсутствующих заголовков в исходных файлах</li>
</ul>
</div>
<p style="margin-top: 20px; opacity: 0.8;">
💾 Все настройки автоматически сохраняются в config.json
</p>
</div>
<div class="button-group" style="margin-top: 30px;">
<button onclick="saveSettings()">💾 Сохранить настройки</button>
<button class="warning" onclick="resetSettings()">🔄 Сбросить настройки</button>
</div>
</div>
</main>
</div>
<div class="status-bar">
<div class="status-message">
<span id="statusIcon">🌊</span>
<span id="statusText">Готов к работе</span>
</div>
<div class="progress-bar" id="progressBar" style="display: none;">
<div class="progress-fill"></div>
</div>
</div>
<div id="toast" class="toast"></div>
<div id="modal" class="modal">
<div class="modal-content">
<h3 id="modalTitle">Заголовок</h3>
<p id="modalMessage">Сообщение</p>
<button onclick="closeModal()" style="margin-top: 20px;">Закрыть</button>
</div>
</div>
<script>
// Global variables
let config = {
email: '',
emailHistory: [],
lastFolder: '',
targetFile: '',
templateFile: '',
writeIntoTarget: true
};
let stats = {
filesProcessed: 0,
recordsProcessed: 0,
errorsCount: 0
};
let quickFiles = [];
let selectedSheets = [];
// Initialize app
document.addEventListener('DOMContentLoaded', function() {
loadConfig();
initializeEventListeners();
updateStats();
logMessage('emailLog', '🌊 Приложение запущено и готово к работе', 'info');
logMessage('karnetLog', '🌊 Karnet Manager Pro v3.0 инициализирован', 'info');
});
function initializeEventListeners() {
// File input listeners
document.getElementById('quickFiles').addEventListener('change', handleQuickFilesSelect);
// Checkbox listeners
document.getElementById('headerPresent').addEventListener('change', function() {
if (this.checked) {
document.getElementById('headerAbsent').checked = false;
}
});
document.getElementById('headerAbsent').addEventListener('change', function() {
if (this.checked) {
document.getElementById('headerPresent').checked = false;
}
});
document.getElementById('quickToTarget').addEventListener('change', function() {
if (this.checked) {
document.getElementById('quickToNew').checked = false;
}
});
document.getElementById('quickToNew').addEventListener('change', function() {
if (this.checked) {
document.getElementById('quickToTarget').checked = false;
}
});
}
function switchTab(tabName) {
// Hide all tabs
document.querySelectorAll('.tab-content').forEach(tab => {
tab.classList.remove('active');
});
// Remove active class from all buttons
document.querySelectorAll('.tab-button').forEach(btn => {
btn.classList.remove('active');
});
// Show selected tab
document.getElementById(tabName).classList.add('active');
// Add active class to clicked button
event.target.classList.add('active');
}
function loadConfig() {
const savedConfig = localStorage.getItem('karnetConfig');
if (savedConfig) {
config = JSON.parse(savedConfig);
document.getElementById('email').value = config.email || '';
document.getElementById('karnetFolder').value = config.lastFolder || '';
document.getElementById('targetFile').value = config.targetFile || '';
}
}
function saveConfig() {
config.email = document.getElementById('email').value;
config.lastFolder = document.getElementById('karnetFolder').value;
config.targetFile = document.getElementById('targetFile').value;
localStorage.setItem('karnetConfig', JSON.stringify(config));
showToast('Настройки сохранены', 'success');
}
function logMessage(logId, message, level = 'info') {
const log = document.getElementById(logId);
const timestamp = new Date().toLocaleTimeString();
const entry = document.createElement('div');
entry.className = `log-entry ${level}`;
const icons = {
info: 'ℹ️',
success: '✅',
warning: '⚠️',
error: '❌'
};
entry.textContent = `[${timestamp}] ${icons[level] || 'ℹ️'} ${message}`;
log.appendChild(entry);
log.scrollTop = log.scrollHeight;
}
function updateStatus(message, level = 'info') {
const statusText = document.getElementById('statusText');
const statusIcon = document.getElementById('statusIcon');
const icons = {
info: '🌊',
success: '🐚',
warning: '⚓',
error: '🦈',
working: '🌀'
};
statusIcon.textContent = icons[level] || '🌊';
statusText.textContent = message;
}
function showProgress(show = true) {
document.getElementById('progressBar').style.display = show ? 'block' : 'none';
}
function showToast(message, type = 'info') {
const toast = document.getElementById('toast');
toast.textContent = message;
toast.className = `toast ${type} show`;
setTimeout(() => {
toast.classList.remove('show');
}, 3000);
}
function showModal(title, message) {
document.getElementById('modalTitle').textContent = title;
document.getElementById('modalMessage').textContent = message;
document.getElementById('modal').classList.add('active');
}
function closeModal() {
document.getElementById('modal').classList.remove('active');
}
function updateStats() {
document.getElementById('filesProcessed').textContent = stats.filesProcessed;
document.getElementById('recordsProcessed').textContent = stats.recordsProcessed;
document.getElementById('errorsCount').textContent = stats.errorsCount;
}
// Email Manager functions
function runOutlookSaver() {
updateStatus('Запуск OutlookAttachmentSaver...', 'working');
showProgress(true);
logMessage('emailLog', 'Запуск OutlookAttachmentSaver...', 'info');
// Simulate process
setTimeout(() => {
logMessage('emailLog', 'OutlookAttachmentSaver успешно выполнен', 'success');
updateStatus('OutlookAttachmentSaver выполнен', 'success');
showProgress(false);
showToast('OutlookAttachmentSaver выполнен успешно', 'success');
}, 2000);
}
function saveEmail() {
const email = document.getElementById('email').value.trim();
if (!email) {
showToast('Введите email адрес', 'warning');
return;
}
if (!config.emailHistory.includes(email)) {
config.emailHistory.push(email);
}
config.email = email;
saveConfig();
logMessage('emailLog', `Email ${email} сохранен`, 'success');
showToast('Email сохранен', 'success');
}
// Karnet Manager functions
function browseFolder() {
// Simulate folder selection
const folder = 'C:\\Work\\Karnets\\2024';
document.getElementById('karnetFolder').value = folder;
config.lastFolder = folder;
saveConfig();
logMessage('karnetLog', `Выбрана папка: ${folder}`, 'info');
}
function browseTargetFile() {
// Simulate file selection
const file = 'C:\\Work\\Karnets\\Целевой файл.xlsm';
document.getElementById('targetFile').value = file;
config.targetFile = file;
saveConfig();
logMessage('karnetLog', `Выбран целевой файл: ${file}`, 'info');
}
function checkTemplate() {
updateStatus('Проверка шаблона...', 'working');
showProgress(true);
logMessage('karnetLog', '🔍 Проверка соответствия с мастер-шаблоном', 'info');
setTimeout(() => {
logMessage('karnetLog', '📋 Ожидаемых заголовков в шаблоне: 25', 'info');
logMessage('karnetLog', '📊 Обработано файлов: 12', 'info');
logMessage('karnetLog', '✅ Все заголовки соответствуют шаблону!', 'success');
updateStatus('Шаблон полностью соответствует', 'success');
showProgress(false);
showToast('Проверка шаблона завершена успешно', 'success');
}, 3000);
}
function createTemplate() {
updateStatus('Создание шаблона...', 'working');
showProgress(true);
logMessage('karnetLog', '🛠️ Создание шаблона объединения карнетов...', 'info');
setTimeout(() => {
logMessage('karnetLog', '🎉 Шаблон создан: Шаблоны/Шаблон_