This commit is contained in:
Fedor
2026-03-13 10:42:01 +03:00
commit 9708638e0a
4050 changed files with 1028632 additions and 0 deletions

423
miniapp2.html Normal file
View File

@@ -0,0 +1,423 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Загрузка файлов</title>
<script src="https://telegram.org/js/telegram-web-app.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.container {
background: white;
border-radius: 20px;
padding: 30px;
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
width: 100%;
max-width: 400px;
}
.header {
text-align: center;
margin-bottom: 30px;
}
.header h1 {
color: #333;
font-size: 24px;
font-weight: 600;
margin-bottom: 10px;
}
.header p {
color: #666;
font-size: 14px;
}
.file-upload {
margin-bottom: 25px;
}
.file-upload label {
display: block;
margin-bottom: 8px;
color: #333;
font-weight: 500;
font-size: 14px;
}
.file-input-wrapper {
position: relative;
border: 2px dashed #ddd;
border-radius: 12px;
padding: 20px;
text-align: center;
transition: all 0.3s ease;
cursor: pointer;
}
.file-input-wrapper:hover {
border-color: #667eea;
background-color: #f8f9ff;
}
.file-input-wrapper.dragover {
border-color: #667eea;
background-color: #f0f2ff;
}
.file-input {
position: absolute;
opacity: 0;
width: 100%;
height: 100%;
cursor: pointer;
}
.file-input-text {
color: #666;
font-size: 14px;
}
.file-input-text strong {
color: #667eea;
}
.file-preview {
margin-top: 10px;
padding: 10px;
background: #f8f9fa;
border-radius: 8px;
display: none;
}
.file-preview.show {
display: block;
}
.file-preview .file-name {
font-weight: 500;
color: #333;
margin-bottom: 5px;
}
.file-preview .file-size {
font-size: 12px;
color: #666;
}
.submit-btn {
width: 100%;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 15px;
border-radius: 12px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
margin-top: 20px;
}
.submit-btn:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(102, 126, 234, 0.3);
}
.submit-btn:disabled {
background: #ccc;
cursor: not-allowed;
transform: none;
box-shadow: none;
}
.status {
margin-top: 15px;
padding: 10px;
border-radius: 8px;
text-align: center;
display: none;
}
.status.success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.status.error {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.loading {
display: none;
text-align: center;
margin-top: 15px;
}
.spinner {
border: 3px solid #f3f3f3;
border-top: 3px solid #667eea;
border-radius: 50%;
width: 30px;
height: 30px;
animation: spin 1s linear infinite;
margin: 0 auto 10px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>📁 Загрузка файлов</h1>
<p>Выберите два файла для отправки</p>
</div>
<form id="uploadForm">
<div class="file-upload">
<label for="file1">Первый файл</label>
<div class="file-input-wrapper" onclick="document.getElementById('file1').click()">
<input type="file" id="file1" class="file-input" accept="*/*">
<div class="file-input-text">
<strong>Нажмите</strong> или перетащите файл сюда
</div>
</div>
<div id="preview1" class="file-preview">
<div class="file-name"></div>
<div class="file-size"></div>
</div>
</div>
<div class="file-upload">
<label for="file2">Второй файл</label>
<div class="file-input-wrapper" onclick="document.getElementById('file2').click()">
<input type="file" id="file2" class="file-input" accept="*/*">
<div class="file-input-text">
<strong>Нажмите</strong> или перетащите файл сюда
</div>
</div>
<div id="preview2" class="file-preview">
<div class="file-name"></div>
<div class="file-size"></div>
</div>
</div>
<button type="submit" class="submit-btn" id="submitBtn">
📤 Отправить файлы
</button>
</form>
<div class="loading" id="loading">
<div class="spinner"></div>
<p>Отправляем файлы...</p>
</div>
<div class="status" id="status"></div>
</div>
<script>
// Инициализация Telegram Web App с проверкой доступности
let tg = window.Telegram?.WebApp;
// Проверяем, доступен ли Telegram Web App API
if (tg) {
tg.ready();
tg.expand();
}
// Универсальная функция закрытия мини-аппа
function closeMiniApp() {
if (tg && typeof tg.close === 'function') {
// Если доступен Telegram Web App API
tg.close();
} else if (window.parent && window.parent !== window) {
// Если открыто в iframe (n8n webhook)
try {
window.parent.postMessage({ type: 'close' }, '*');
} catch (e) {
console.log('Не удалось закрыть через postMessage');
}
} else {
// Альтернативный способ - попытка закрыть окно
try {
window.close();
} catch (e) {
console.log('Не удалось закрыть окно');
}
}
}
// Настройка темы
if (tg && tg.colorScheme === 'dark') {
document.body.style.background = 'linear-gradient(135deg, #2c3e50 0%, #34495e 100%)';
document.querySelector('.container').style.background = '#2c3e50';
document.querySelector('.container').style.color = 'white';
}
const file1Input = document.getElementById('file1');
const file2Input = document.getElementById('file2');
const preview1 = document.getElementById('preview1');
const preview2 = document.getElementById('preview2');
const submitBtn = document.getElementById('submitBtn');
const loading = document.getElementById('loading');
const status = document.getElementById('status');
// Функция для отображения предварительного просмотра файла
function showFilePreview(file, previewElement) {
if (file) {
const fileName = file.name;
const fileSize = (file.size / 1024).toFixed(2) + ' KB';
previewElement.querySelector('.file-name').textContent = fileName;
previewElement.querySelector('.file-size').textContent = fileSize;
previewElement.classList.add('show');
} else {
previewElement.classList.remove('show');
}
}
// Обработчики для файлов
file1Input.addEventListener('change', (e) => {
showFilePreview(e.target.files[0], preview1);
updateSubmitButton();
});
file2Input.addEventListener('change', (e) => {
showFilePreview(e.target.files[0], preview2);
updateSubmitButton();
});
// Drag and drop функциональность
function setupDragAndDrop(inputElement, previewElement) {
const wrapper = inputElement.parentElement;
wrapper.addEventListener('dragover', (e) => {
e.preventDefault();
wrapper.classList.add('dragover');
});
wrapper.addEventListener('dragleave', (e) => {
e.preventDefault();
wrapper.classList.remove('dragover');
});
wrapper.addEventListener('drop', (e) => {
e.preventDefault();
wrapper.classList.remove('dragover');
const files = e.dataTransfer.files;
if (files.length > 0) {
inputElement.files = files;
showFilePreview(files[0], previewElement);
updateSubmitButton();
}
});
}
setupDragAndDrop(file1Input, preview1);
setupDragAndDrop(file2Input, preview2);
// Обновление состояния кнопки отправки
function updateSubmitButton() {
const file1 = file1Input.files[0];
const file2 = file2Input.files[0];
if (file1 && file2) {
submitBtn.disabled = false;
submitBtn.textContent = '📤 Отправить файлы';
} else {
submitBtn.disabled = true;
submitBtn.textContent = '⚠️ Выберите оба файла';
}
}
// Обработка отправки формы
document.getElementById('uploadForm').addEventListener('submit', async (e) => {
e.preventDefault();
const file1 = file1Input.files[0];
const file2 = file2Input.files[0];
if (!file1 || !file2) {
showStatus('Пожалуйста, выберите оба файла', 'error');
return;
}
// Показываем загрузку
loading.style.display = 'block';
submitBtn.disabled = true;
status.style.display = 'none';
try {
// Создаем FormData для отправки файлов
const formData = new FormData();
formData.append('file1', file1);
formData.append('file2', file2);
formData.append('user_id', tg?.initDataUnsafe?.user?.id || 'unknown');
// Здесь должна быть логика отправки на ваш сервер
// Для демонстрации используем setTimeout
await new Promise(resolve => setTimeout(resolve, 2000));
// Симуляция успешной отправки
showStatus('✅ Файлы успешно отправлены!', 'success');
// Очищаем форму
file1Input.value = '';
file2Input.value = '';
preview1.classList.remove('show');
preview2.classList.remove('show');
updateSubmitButton();
// Закрываем мини-апп через 2 секунды после успешной отправки
setTimeout(() => {
closeMiniApp();
}, 2000);
} catch (error) {
showStatus('❌ Ошибка при отправке файлов: ' + error.message, 'error');
} finally {
loading.style.display = 'none';
submitBtn.disabled = false;
}
});
// Функция для отображения статуса
function showStatus(message, type) {
status.textContent = message;
status.className = `status ${type}`;
status.style.display = 'block';
// Скрываем статус через 5 секунд
setTimeout(() => {
status.style.display = 'none';
}, 5000);
}
// Инициализация
updateSubmitButton();
</script>
</body>
</html>