|
|
<!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> |