| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>File Uploader | Fast & Simple.</title> |
| <style> |
| @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600&display=swap'); |
| |
| * { |
| margin: 0; |
| padding: 0; |
| box-sizing: border-box; |
| font-family: 'Inter', sans-serif; |
| } |
| |
| body { |
| background: #000; |
| color: #fff; |
| display: flex; |
| flex-direction: column; |
| justify-content: center; |
| align-items: center; |
| height: 100vh; |
| } |
| |
| .container { |
| background: #111; |
| padding: 2rem; |
| border-radius: 12px; |
| box-shadow: 0 4px 10px rgba(255, 255, 255, 0.1); |
| text-align: center; |
| width: 320px; |
| opacity: 0; |
| transform: translateY(20px); |
| animation: fadeIn 0.5s ease-out forwards; |
| } |
| |
| @keyframes fadeIn { |
| to { |
| opacity: 1; |
| transform: translateY(0); |
| } |
| } |
| |
| p { |
| color: #aaa; |
| } |
| |
| .file-upload-container { |
| display: flex; |
| flex-direction: column; |
| align-items: center; |
| margin-top: 1rem; |
| background: #222; |
| padding: 1rem; |
| border-radius: 8px; |
| box-shadow: 0 0 10px rgba(255, 255, 255, 0.2); |
| transition: box-shadow 0.3s ease-in-out; |
| } |
| |
| .file-upload-container:hover { |
| box-shadow: 0 0 20px rgba(255, 255, 255, 0.4); |
| } |
| |
| .file-input-label { |
| display: flex; |
| justify-content: center; |
| align-items: center; |
| width: 100%; |
| padding: 12px; |
| background: #333; |
| border-radius: 6px; |
| cursor: pointer; |
| transition: background 0.3s, transform 0.2s; |
| } |
| |
| .file-input-label:hover { |
| background: #444; |
| transform: scale(1.05); |
| } |
| |
| .file-input { |
| display: none; |
| } |
| |
| .file-info { |
| margin-top: 10px; |
| color: #aaa; |
| font-size: 0.9rem; |
| text-align: left; |
| width: 100%; |
| opacity: 0; |
| transform: translateY(10px); |
| animation: fadeIn 0.5s ease-out forwards; |
| } |
| |
| .upload-status { |
| margin-top: 10px; |
| color: #aaa; |
| font-size: 0.9rem; |
| opacity: 0; |
| animation: fadeIn 0.5s ease-out forwards; |
| } |
| |
| .loading { |
| width: 24px; |
| height: 24px; |
| border: 3px solid #aaa; |
| border-top: 3px solid transparent; |
| border-radius: 50%; |
| animation: spin 1s linear infinite; |
| display: none; |
| margin: 10px auto; |
| } |
| |
| @keyframes spin { |
| to { |
| transform: rotate(360deg); |
| } |
| } |
| </style> |
| </head> |
| <body> |
| <div class="container"> |
| <h1>File Uploader.</h1> |
| <p>Fast & simple.</p> |
| <div class="file-upload-container"> |
| <label for="fileInput" class="file-input-label"> |
| <span>Choose File.</span> |
| </label> |
| <input type="file" id="fileInput" class="file-input" onchange="handleFile()"> |
| <div class="file-info" id="fileInfo">No file selected.</div> |
| <div class="loading" id="loading"></div> |
| <div class="upload-status" id="uploadStatus"></div> |
| </div> |
| </div> |
|
|
| <script> |
| function formatFileSize(size) { |
| const units = ["B", "KB", "MB", "GB", "TB", "PB"]; |
| let index = 0; |
| while (size >= 1024 && index < units.length - 1) { |
| size /= 1024; |
| index++; |
| } |
| return size.toFixed(2) + " " + units[index] + "."; |
| } |
| |
| function handleFile() { |
| let fileInput = document.getElementById('fileInput'); |
| let fileInfo = document.getElementById('fileInfo'); |
| let uploadStatus = document.getElementById('uploadStatus'); |
| let loading = document.getElementById('loading'); |
| let file = fileInput.files[0]; |
| |
| if (file) { |
| let fileSize = formatFileSize(file.size); |
| let lastModified = new Date(file.lastModified).toLocaleString() + "."; |
| |
| fileInfo.innerHTML = ` |
| <strong>Name:</strong> ${file.name}.<br> |
| <strong>Size:</strong> ${fileSize}<br> |
| <strong>Last Modified:</strong> ${lastModified} |
| `; |
| |
| uploadFile(file, uploadStatus, loading); |
| } else { |
| fileInfo.innerHTML = "No file selected."; |
| } |
| } |
| |
| function uploadFile(file, uploadStatus, loading) { |
| let formData = new FormData(); |
| formData.append("file", file); |
| |
| uploadStatus.innerHTML = ""; |
| loading.style.display = "block"; |
| |
| fetch("/upload", { |
| method: "POST", |
| body: formData |
| }) |
| .then(response => response.json()) |
| .then(data => { |
| loading.style.display = "none"; |
| uploadStatus.innerHTML = `Uploaded: <a href="${data.url}" target="_blank">${data.url}</a>.`; |
| }) |
| .catch(error => { |
| loading.style.display = "none"; |
| uploadStatus.innerHTML = "Upload failed."; |
| }); |
| } |
| </script> |
| </body> |
| </html> |