398 lines
13 KiB
HTML
398 lines
13 KiB
HTML
<!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;
|
||
tg.ready();
|
||
tg.expand();
|
||
|
||
// Настройка темы
|
||
if (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(() => {
|
||
tg.close();
|
||
}, 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>
|