aCloud/templates/index.html

680 lines
22 KiB
HTML
Raw Normal View History

2024-09-08 13:13:50 +02:00
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>aCloud - File Sharing Service</title>
2024-09-08 13:13:50 +02:00
<style>
2024-09-10 17:07:10 +02:00
:root {
--primary-color: #4CAF50;
--secondary-color: #45a049;
--background-color: #1a1a1a;
--text-color: #f0f0f0;
--accent-color: #4CAF50;
--container-bg: #2a2a2a;
--input-bg: #333;
--input-border: #4CAF50;
2024-09-10 17:07:10 +02:00
}
2024-09-08 13:13:50 +02:00
body {
font-family: 'Roboto', Arial, sans-serif;
line-height: 1.6;
2024-09-08 13:13:50 +02:00
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
min-height: 100vh;
background-color: var(--background-color);
color: var(--text-color);
2024-09-08 13:13:50 +02:00
}
2024-09-10 17:07:10 +02:00
2024-09-08 13:13:50 +02:00
.container {
flex: 1;
display: flex;
flex-direction: column;
2024-09-10 17:07:10 +02:00
align-items: center;
justify-content: flex-start;
padding: 20px;
2024-09-08 13:13:50 +02:00
}
2024-09-10 17:07:10 +02:00
nav {
position: absolute;
top: 20px;
right: 20px;
2024-09-10 17:07:10 +02:00
}
nav a {
color: var(--primary-color);
text-decoration: none;
margin: 0 10px;
font-weight: 500;
transition: color 0.3s ease;
2024-09-10 17:07:10 +02:00
}
nav a:hover {
color: var(--accent-color);
2024-09-08 13:13:50 +02:00
}
2024-09-10 17:07:10 +02:00
.upload-options {
margin-bottom: 20px;
2024-09-10 17:07:10 +02:00
}
.upload-options button {
background-color: var(--primary-color);
border: none;
color: white;
padding: 10px 20px;
2024-09-10 17:07:10 +02:00
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
margin: 4px 2px;
cursor: pointer;
border-radius: 4px;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
transition: background-color 0.3s ease, box-shadow 0.3s ease;
2024-09-10 17:07:10 +02:00
}
.upload-options button:hover {
background-color: var(--secondary-color);
box-shadow: 0 4px 8px rgba(0,0,0,0.3);
2024-09-10 17:07:10 +02:00
}
2024-09-08 13:13:50 +02:00
.upload-form {
display: none;
background-color: var(--container-bg);
padding: 18px;
border-radius: 8px;
max-width: 380px;
width: 100%;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
2024-09-08 13:13:50 +02:00
}
2024-09-10 17:07:10 +02:00
2024-09-08 13:13:50 +02:00
.upload-form.active {
display: block;
}
2024-09-10 17:07:10 +02:00
.upload-form input[type="text"],
.upload-form input[type="file"],
.upload-form textarea {
width: calc(100% - 22px);
padding: 10px;
margin: 8px 0;
border-radius: 4px;
border: 1px solid var(--input-border);
background-color: var(--input-bg);
color: var(--text-color);
font-size: 14px;
transition: border-color 0.3s ease, box-shadow 0.3s ease;
2024-09-10 17:07:10 +02:00
}
.upload-form input[type="text"]:focus,
.upload-form input[type="file"]:focus,
.upload-form textarea:focus {
outline: none;
border-color: var(--accent-color);
box-shadow: 0 0 5px rgba(76, 175, 80, 0.5);
2024-09-10 17:07:10 +02:00
}
.upload-form button {
background-color: var(--primary-color);
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.5px;
transition: background-color 0.3s ease, box-shadow 0.3s ease;
2024-09-10 17:07:10 +02:00
}
.upload-form button:hover {
background-color: var(--secondary-color);
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
2024-09-10 17:07:10 +02:00
}
.result {
margin-top: 10px;
color: var(--primary-color);
font-weight: 500;
2024-09-10 17:07:10 +02:00
}
.footer {
text-align: center;
padding: 10px;
2024-09-10 17:07:10 +02:00
background-color: var(--container-bg);
color: var(--text-color);
font-size: 12px;
2024-09-10 17:07:10 +02:00
}
.typewriter-container {
font-family: 'Roboto Mono', monospace;
white-space: pre-wrap;
2024-09-10 17:07:10 +02:00
overflow: hidden;
font-size: 1.2em;
margin-bottom: 20px;
text-align: center;
display: flex;
justify-content: center;
align-items: flex-start;
height: 100px;
position: relative;
}
.cursor {
2024-09-10 17:07:10 +02:00
display: inline-block;
width: 10px;
height: 20px;
background-color: var(--primary-color);
animation: blink 0.7s infinite;
position: absolute;
bottom: 0;
2024-09-10 17:07:10 +02:00
}
@keyframes blink {
0% { opacity: 0; }
50% { opacity: 1; }
100% { opacity: 0; }
}
#settingsButton {
2024-09-10 17:07:10 +02:00
position: absolute;
top: 20px;
left: 20px;
background-color: var(--primary-color);
color: white;
border: none;
padding: 10px 15px;
border-radius: 4px;
2024-09-08 13:13:50 +02:00
cursor: pointer;
font-size: 14px;
font-weight: 500;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
transition: background-color 0.3s ease, box-shadow 0.3s ease;
2024-09-08 13:13:50 +02:00
}
2024-09-10 17:07:10 +02:00
#settingsButton:hover {
background-color: var(--secondary-color);
box-shadow: 0 4px 8px rgba(0,0,0,0.3);
2024-09-10 17:07:10 +02:00
}
#settingsMenu {
display: none;
position: absolute;
top: 60px;
left: 20px;
background-color: var(--container-bg);
border-radius: 4px;
padding: 10px;
z-index: 1000;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
2024-09-10 17:07:10 +02:00
}
#settingsMenu button {
display: block;
width: 100%;
padding: 8px 10px;
margin: 5px 0;
background-color: var(--primary-color);
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: background-color 0.3s ease;
2024-09-10 17:07:10 +02:00
}
#settingsMenu button:hover {
2024-09-10 17:07:10 +02:00
background-color: var(--secondary-color);
2024-09-08 13:13:50 +02:00
}
2024-09-10 17:07:10 +02:00
body.default-dark {
--primary-color: #4CAF50;
--secondary-color: #45a049;
--background-color: #1a1a1a;
--text-color: #f0f0f0;
--accent-color: #4CAF50;
--container-bg: #2a2a2a;
--input-bg: #333;
--input-border: #4CAF50;
}
2024-09-10 17:07:10 +02:00
body.default-light {
--primary-color: #4CAF50;
--secondary-color: #45a049;
--background-color: #f0f0f0;
--text-color: #333333;
--accent-color: #4CAF50;
--container-bg: #ffffff;
--input-bg: #e0e0e0;
--input-border: #4CAF50;
}
2024-09-10 17:07:10 +02:00
body.solarized-dark {
--primary-color: #b58900;
--secondary-color: #859900;
--background-color: #002b36;
--text-color: #839496;
--accent-color: #cb4b16;
--container-bg: #073642;
--input-bg: #094352;
--input-border: #b58900;
2024-09-10 17:07:10 +02:00
}
body.blue-dark {
--primary-color: #3498db;
--secondary-color: #2980b9;
--background-color: #34495e;
--text-color: #ecf0f1;
--accent-color: #e74c3c;
--container-bg: #2c3e50;
--input-bg: #465669;
--input-border: #3498db;
2024-09-10 17:07:10 +02:00
}
body.purple-dark {
--primary-color: #9b59b6;
--secondary-color: #8e44ad;
--background-color: #4a235a;
--text-color: #ecf0f1;
--accent-color: #f1c40f;
--container-bg: #5b2c6f;
--input-bg: #6c3483;
--input-border: #9b59b6;
}
2024-09-10 17:07:10 +02:00
body.red-dark {
--primary-color: #e74c3c;
--secondary-color: #c0392b;
--background-color: #641e16;
--text-color: #ecf0f1;
--accent-color: #f39c12;
--container-bg: #7b241c;
--input-bg: #922b21;
--input-border: #e74c3c;
}
2024-09-10 17:07:10 +02:00
body.green-light {
--primary-color: #2ecc71;
--secondary-color: #27ae60;
--background-color: #e8f8f5;
--text-color: #1e8449;
--accent-color: #e67e22;
--container-bg: #d1f2eb;
--input-bg: #a3e4d7;
--input-border: #2ecc71;
}
2024-09-10 17:07:10 +02:00
body.orange-dark {
--primary-color: #e67e22;
--secondary-color: #d35400;
--background-color: #6e2c00;
--text-color: #fbeee6;
--accent-color: #3498db;
--container-bg: #873600;
--input-bg: #a04000;
--input-border: #e67e22;
}
2024-09-10 17:07:10 +02:00
body.pink-light {
--primary-color: #e84393;
--secondary-color: #fd79a8;
--background-color: #ffeef8;
--text-color: #8e44ad;
--accent-color: #00cec9;
--container-bg: #fad7f0;
--input-bg: #f8c0e0;
--input-border: #e84393;
}
body.pastel-light {
--primary-color: #ffb3ba;
--secondary-color: #bae1ff;
--background-color: #ffffba;
--text-color: #555555;
--accent-color: #baffc9;
--container-bg: #ffdfba;
--input-bg: #ffffba;
--input-border: #ffb3ba;
}
body.forest {
--primary-color: #2ecc71;
--secondary-color: #27ae60;
--background-color: #1e3a1e;
--text-color: #e0e0e0;
--accent-color: #f1c40f;
--container-bg: #2c532c;
--input-bg: #3a6c3a;
--input-border: #2ecc71;
}
body.ocean {
--primary-color: #3498db;
--secondary-color: #2980b9;
--background-color: #0c2d48;
--text-color: #ecf0f1;
--accent-color: #e67e22;
--container-bg: #1a4a72;
--input-bg: #28679c;
--input-border: #3498db;
}
body.sunset {
--primary-color: #ff7f50;
--secondary-color: #ff6347;
--background-color: #4a0e1c;
--text-color: #ffd700;
--accent-color: #ff4500;
--container-bg: #721422;
--input-bg: #9a1a2c;
--input-border: #ff7f50;
}
2024-09-10 17:07:10 +02:00
body.retro {
--primary-color: #33cc33;
--secondary-color: #66ff66;
--background-color: #000000;
--text-color: #33cc33;
--accent-color: #ffff00;
--container-bg: #001100;
--input-bg: #002200;
--input-border: #33cc33;
}
body.desert {
--primary-color: #d2691e;
--secondary-color: #b8860b;
--background-color: #f4a460;
--text-color: #8b4513;
--accent-color: #ff8c00;
--container-bg: #deb887;
--input-bg: #ffdab9;
--input-border: #d2691e;
}
body.arctic {
--primary-color: #87cefa;
--secondary-color: #1e90ff;
--background-color: #f0f8ff;
--text-color: #4682b4;
--accent-color: #00bfff;
--container-bg: #e6f3ff;
--input-bg: #f0f8ff;
--input-border: #87cefa;
}
2024-09-10 17:07:10 +02:00
body.volcanic {
--primary-color: #ff4500;
--secondary-color: #ff6347;
--background-color: #8b0000;
--text-color: #ffd700;
--accent-color: #ff8c00;
--container-bg: #a52a2a;
--input-bg: #b22222;
--input-border: #ff4500;
}
2024-09-10 17:07:10 +02:00
body.space {
--primary-color: #4b0082;
--secondary-color: #8a2be2;
--background-color: #191970;
--text-color: #e6e6fa;
--accent-color: #9370db;
--container-bg: #483d8b;
--input-bg: #6a5acd;
--input-border: #4b0082;
}
2024-09-10 17:07:10 +02:00
body.autumn {
--primary-color: #b8860b;
--secondary-color: #cd853f;
--background-color: #8b4513;
--text-color: #ffd700;
--accent-color: #ff8c00;
--container-bg: #d2691e;
--input-bg: #deb887;
--input-border: #b8860b;
}
2024-09-08 13:13:50 +02:00
</style>
</head>
<body>
2024-09-08 13:13:50 +02:00
<div class="container">
<nav>
{% if user %}
<a href="{{ url_for('user_files', username=user.username) }}">View Dashboard</a>
<a href="{{ url_for('logout') }}">Logout</a>
{% else %}
<a href="{{ url_for('login') }}">Login</a>
<a href="{{ url_for('register') }}">Register</a>
{% endif %}
</nav>
<button id="settingsButton">⚙️ Settings</button>
<div id="settingsMenu" style="display: none;">
<button onclick="setTheme('default-dark')">Default Dark</button>
<button onclick="setTheme('default-light')">Default Light</button>
<button onclick="setTheme('solarized-dark')">Solarized Dark</button>
<button onclick="setTheme('blue-dark')">Blue Dark</button>
<button onclick="setTheme('purple-dark')">Purple Dark</button>
<button onclick="setTheme('red-dark')">Red Dark</button>
<button onclick="setTheme('green-light')">Green Light</button>
<button onclick="setTheme('orange-dark')">Orange Dark</button>
<button onclick="setTheme('pink-light')">Pink Light</button>
<button onclick="setTheme('pastel-light')">Pastel Light</button>
<button onclick="setTheme('forest')">Forest</button>
<button onclick="setTheme('ocean')">Ocean</button>
<button onclick="setTheme('sunset')">Sunset</button>
<button onclick="setTheme('retro')">Retro</button>
<button onclick="setTheme('desert')">Desert</button>
<button onclick="setTheme('arctic')">Arctic</button>
<button onclick="setTheme('volcanic')">Volcanic</button>
<button onclick="setTheme('space')">Space</button>
<button onclick="setTheme('autumn')">Autumn</button>
</div>
<div class="typewriter-container">
<span id="typewriter-text"></span><span id="cursor" class="cursor"></span>
</div>
2024-09-10 17:07:10 +02:00
<div class="upload-options">
<button onclick="showForm('text')">Upload Text</button>
<button onclick="showForm('file')">Upload File</button>
<button onclick="showForm('url')">Shorten URL</button>
</div>
<div id="uploadFormContainer">
2024-09-08 13:13:50 +02:00
<div id="textForm" class="upload-form">
<h2>Upload Text</h2>
<form>
<textarea name="content" rows="4" placeholder="Enter text here..."></textarea>
<button type="button" onclick="uploadText()">Upload Text</button>
</form>
2024-09-08 13:13:50 +02:00
<div id="textResult" class="result"></div>
</div>
<div id="fileForm" class="upload-form">
<h2>Upload File</h2>
<form enctype="multipart/form-data">
<input type="file" name="file" />
<button type="button" onclick="uploadFile()">Upload File</button>
</form>
2024-09-08 13:13:50 +02:00
<div id="fileResult" class="result"></div>
</div>
<div id="urlForm" class="upload-form">
<h2>Shorten URL</h2>
<form>
<input type="text" name="url" placeholder="Enter URL here..." />
<button type="button" onclick="shortenUrl()">Shorten URL</button>
</form>
2024-09-08 13:13:50 +02:00
<div id="urlResult" class="result"></div>
</div>
</div>
2024-09-08 13:13:50 +02:00
</div>
<footer class="footer">
<p>Source code available on:
<a href="https://github.com/realcgcristi/order" target="_blank">GitHub (not up-to-date)</a> |
<a href="https://git.spitkov.hu/cgcristi/aCloud" target="_blank">Spitkov's Git (main)</a>
</p>
</footer>
<script>
document.addEventListener("DOMContentLoaded", function() {
const message1 = "Welcome to aCloud.";
const message2 = "\n A simple toolbox for file uploading,\n URL shortening and pastebin.";
const typewriterTextElement = document.getElementById('typewriter-text');
const cursorElement = document.getElementById('cursor');
const typingSpeed = 70;
function typeMessage(message, callback) {
let index = 0;
function typeCharacter() {
if (index < message.length) {
if (message[index] === '\n') {
typewriterTextElement.innerHTML += '<br>';
} else {
typewriterTextElement.innerHTML += message[index];
}
index++;
updateCursorPosition();
setTimeout(typeCharacter, typingSpeed);
} else if (callback) {
setTimeout(callback, typingSpeed);
}
}
typeCharacter();
}
function updateCursorPosition() {
const textRect = typewriterTextElement.getBoundingClientRect();
cursorElement.style.left = (textRect.width + textRect.left - cursorElement.offsetWidth) + 'px';
}
typeMessage(message1, function() {
typeMessage(message2);
});
const settingsButton = document.getElementById('settingsButton');
const settingsMenu = document.getElementById('settingsMenu');
settingsButton.addEventListener('click', function() {
settingsMenu.style.display = settingsMenu.style.display === 'none' ? 'block' : 'none';
});
});
function setTheme(theme) {
document.body.className = theme;
}
document.getElementById('uploadForm').onsubmit = function(e) {
e.preventDefault();
var formData = new FormData(this);
var xhr = new XMLHttpRequest();
xhr.open('POST', '/upload/file', true);
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
var percentComplete = (e.loaded / e.total) * 100;
document.getElementById('progressBar').style.display = 'block';
document.getElementById('progressBar').value = percentComplete;
}
};
xhr.onload = function() {
if (xhr.status === 200) {
alert('Upload complete!');
document.getElementById('progressBar').style.display = 'none';
2024-09-10 17:07:10 +02:00
} else {
alert('Upload failed.');
2024-09-10 17:07:10 +02:00
}
};
xhr.send(formData);
};
function showForm(type) {
document.querySelectorAll('.upload-form').forEach(form => {
form.classList.remove('active');
});
document.getElementById(type + 'Form').classList.add('active');
2024-09-10 17:07:10 +02:00
}
function uploadText() {
const content = document.querySelector('#textForm textarea').value;
fetch('/upload/pastebin', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ content: content }),
})
.then(response => response.json())
.then(data => {
if (data.success) {
const simpleUrl = `${window.location.origin}/${data.vanity}`;
document.getElementById('textResult').innerHTML = `Pastebin created. Access it <a href="${simpleUrl}">${simpleUrl}</a>`;
} else {
document.getElementById('textResult').innerHTML = `Error: ${data.error}`;
}
})
.catch(error => {
console.error('Error:', error);
document.getElementById('textResult').innerHTML = `An error occurred: ${error}`;
});
}
2024-09-08 13:13:50 +02:00
function uploadFile() {
const formData = new FormData();
const fileInput = document.querySelector('#fileForm input[type="file"]');
formData.append('file', fileInput.files[0]);
fetch('/upload/file', {
method: 'POST',
body: formData,
})
.then(response => response.json())
.then(data => {
if (data.success) {
const simpleUrl = `${window.location.origin}/${data.vanity}`;
document.getElementById('fileResult').innerHTML = `File uploaded. Access it <a href="${simpleUrl}">${simpleUrl}</a>`;
} else {
document.getElementById('fileResult').innerHTML = `Error: ${data.error}`;
}
})
.catch(error => {
console.error('Error:', error);
document.getElementById('fileResult').innerHTML = `An error occurred: ${error}`;
});
}
function shortenUrl() {
const url = document.querySelector('#urlForm input[name="url"]').value;
fetch('/shorten', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ url: url }),
})
.then(response => response.json())
.then(data => {
if (data.success) {
document.getElementById('urlResult').innerHTML = `URL shortened. Access it <a href="${data.short_url}">${data.short_url}</a>`;
} else {
document.getElementById('urlResult').innerHTML = `Error: ${data.error}`;
}
})
.catch(error => {
console.error('Error:', error);
document.getElementById('urlResult').innerHTML = `An error occurred: ${error}`;
});
}
</script>
2024-09-08 13:13:50 +02:00
</body>
2024-09-08 13:13:50 +02:00
</html>