Login Page hinzugefügt
162
AstraOS/Frontend/HTML/login.html
Normal file
|
|
@ -0,0 +1,162 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>AstraOS — Login</title>
|
||||||
|
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/TextPlugin.min.js"></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: radial-gradient(circle at top, #1b1b26, #0a0a0f 70%);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="text-white">
|
||||||
|
|
||||||
|
<div id="startup" class="fixed inset-0 bg-black flex flex-col items-center justify-center z-50">
|
||||||
|
|
||||||
|
<div id="star" class="w-16 h-16 relative">
|
||||||
|
<div class="absolute inset-0 rounded-full blur-2xl opacity-70"
|
||||||
|
style="background: rgba(192, 132, 252, 0.7)"></div>
|
||||||
|
|
||||||
|
<svg class="relative z-10" viewBox="0 0 100 100">
|
||||||
|
|
||||||
|
<path
|
||||||
|
d="M50 5
|
||||||
|
L63 40
|
||||||
|
L95 50
|
||||||
|
L63 60
|
||||||
|
L50 95
|
||||||
|
L37 60
|
||||||
|
L5 50
|
||||||
|
L37 40
|
||||||
|
Z"
|
||||||
|
fill="#c084fc"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<path
|
||||||
|
d="M50 28
|
||||||
|
L58 45
|
||||||
|
L76 50
|
||||||
|
L58 55
|
||||||
|
L50 72
|
||||||
|
L42 55
|
||||||
|
L24 50
|
||||||
|
L42 45
|
||||||
|
Z"
|
||||||
|
fill="#ffffff"
|
||||||
|
opacity="0.9"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="mt-4 text-xl tracking-wide opacity-80">AstraOS</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="loginContent" class="min-h-screen flex items-center justify-center px-4">
|
||||||
|
|
||||||
|
<div id="loginBox" class="w-full max-w-md bg-black/40 border border-purple-500/20 rounded-2xl p-8 backdrop-blur-lg shadow-xl opacity-0">
|
||||||
|
|
||||||
|
<h1 id="loginTitle" class="text-3xl font-bold text-center mb-6 tracking-wider text-purple-300">
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<form id="loginForm" action="/login" method="POST" class="flex flex-col gap-5 opacity-0">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="text-gray-300 text-sm">Username</label>
|
||||||
|
<input type="text" name="username" required placeholder="Username"
|
||||||
|
class="mt-1 w-full px-4 py-2 rounded-lg bg-gray-800/60 text-white
|
||||||
|
focus:outline-none focus:ring-2 focus:ring-purple-600">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div x-data="{ showPassword: false }">
|
||||||
|
<label class="text-gray-300 text-sm">Passwort</label>
|
||||||
|
<div class="relative">
|
||||||
|
<input :type="showPassword ? 'text' : 'password'" name="password" required placeholder="Passwort"
|
||||||
|
class="mt-1 w-full px-4 py-2 rounded-lg bg-gray-800/60 text-white
|
||||||
|
focus:outline-none focus:ring-2 focus:ring-purple-600 pr-10">
|
||||||
|
<button type="button" @click="showPassword = !showPassword" class="absolute inset-y-0 right-0 top-0 pr-3 flex items-center text-gray-400 hover:text-gray-200">
|
||||||
|
<svg x-show="!showPassword" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.432 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z" />
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||||
|
</svg>
|
||||||
|
<svg x-show="showPassword" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5" style="display: none;">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M3.98 8.223A10.477 10.477 0 001.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.243 4.243l-4.243-4.243" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit"
|
||||||
|
class="mt-2 bg-purple-600 hover:bg-purple-700 text-white py-2 rounded-lg
|
||||||
|
font-semibold transition">
|
||||||
|
Login
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
gsap.to("#star", {
|
||||||
|
rotation: 360,
|
||||||
|
duration: 1.6,
|
||||||
|
ease: "power1.inOut",
|
||||||
|
repeat: -1
|
||||||
|
});
|
||||||
|
|
||||||
|
gsap.to("#star", {
|
||||||
|
scale: 1.22,
|
||||||
|
duration: 1,
|
||||||
|
yoyo: true,
|
||||||
|
repeat: -1,
|
||||||
|
ease: "power1.inOut"
|
||||||
|
});
|
||||||
|
|
||||||
|
gsap.registerPlugin(TextPlugin);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
gsap.to("#startup", {
|
||||||
|
opacity: 0,
|
||||||
|
duration: 0.6,
|
||||||
|
onComplete: () => {
|
||||||
|
document.getElementById("startup").style.display = "none";
|
||||||
|
|
||||||
|
const tl = gsap.timeline();
|
||||||
|
|
||||||
|
tl.fromTo("#loginBox",
|
||||||
|
{ opacity: 0, scale: 0.1 },
|
||||||
|
{
|
||||||
|
opacity: 1,
|
||||||
|
scale: 1,
|
||||||
|
duration: 0.8,
|
||||||
|
ease: "power2.out"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
tl.to("#loginTitle", {
|
||||||
|
duration: 1,
|
||||||
|
text: "AstraOS Login",
|
||||||
|
ease: "none"
|
||||||
|
}, "-=0.2");
|
||||||
|
|
||||||
|
tl.to("#loginForm", {
|
||||||
|
opacity: 1,
|
||||||
|
duration: 0.5
|
||||||
|
}, "-=0.5");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 1500);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
0
AstraOS/astra_os.py
Normal file
BIN
Outdated Website/static/background.png
Normal file
|
After Width: | Height: | Size: 541 KiB |
BIN
Outdated Website/static/circle_green_checkmark.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
Outdated Website/static/green_check.png
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
Outdated Website/static/light-mode.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
Outdated Website/static/logo.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
Outdated Website/static/night-mode.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
Outdated Website/static/offline.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
Outdated Website/static/pfps/6789034fae4a5613afaea2e5.png
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
Outdated Website/static/pfps/6789307ab1ee3ef2a1433fb5.png
Normal file
|
After Width: | Height: | Size: 591 KiB |
BIN
Outdated Website/static/pfps/user.png
Normal file
|
After Width: | Height: | Size: 7 KiB |
BIN
Outdated Website/static/red_cross.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
Outdated Website/static/round_arrow.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
234
Outdated Website/static/style.css
Normal file
|
|
@ -0,0 +1,234 @@
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
background-color: #f4f4f9;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-bar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #42028b;
|
||||||
|
color: white;
|
||||||
|
padding: 10px 20px;
|
||||||
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo img {
|
||||||
|
height: 40px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username span {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username img {
|
||||||
|
height: 30px;
|
||||||
|
width: 30px;
|
||||||
|
border-radius: 50%;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username .dropdown {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 40px;
|
||||||
|
right: 0;
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
||||||
|
border-radius: 5px;
|
||||||
|
z-index: 10;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username .dropdown a {
|
||||||
|
display: block;
|
||||||
|
padding: 10px 20px;
|
||||||
|
color: #333;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username .dropdown a:hover {
|
||||||
|
background-color: #f4f4f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username:hover .dropdown {
|
||||||
|
display: block;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username .dropdown.hide {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s ease-out 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-button, .logout-button, .black-button {
|
||||||
|
background-color: #007bff;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
margin: 10px 0;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-button:hover, .logout-button:hover, .black-button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.black-button {
|
||||||
|
background-color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.black-button:hover {
|
||||||
|
background-color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background-color: #007bff;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.top-bar {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username .dropdown {
|
||||||
|
right: auto;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#popup {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.7);
|
||||||
|
z-index: 1000;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#popup .popup-content {
|
||||||
|
background: white;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
width: 80%;
|
||||||
|
max-width: 600px;
|
||||||
|
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#popup .popup-header {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#popup .popup-close {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
margin-top: 30px;
|
||||||
|
height: 300px;
|
||||||
|
align-items: flex-end;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar {
|
||||||
|
width: 30%;
|
||||||
|
background-color: #007bff;
|
||||||
|
transition: height 2s ease-out;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar span {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -30px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
#criteria-text {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #333;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
#popup .popup-content {
|
||||||
|
width: 90%;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-container {
|
||||||
|
flex-direction: column;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
211
Outdated Website/static/styles.css
Normal file
|
|
@ -0,0 +1,211 @@
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
background-color: #0D1117;
|
||||||
|
color: #c9d1d9;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #161b22;
|
||||||
|
border-bottom: 2px solid #30363d;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3 {
|
||||||
|
color: #58a6ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 40px auto;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2, h3 {
|
||||||
|
color: #c9d1d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
padding: 12px;
|
||||||
|
text-align: left;
|
||||||
|
border-bottom: 1px solid #30363d;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background-color: #161b22;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #58a6ff;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background-color: #238636;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:disabled {
|
||||||
|
background-color: #30363d;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover:enabled {
|
||||||
|
background-color: #2ea043;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-btn {
|
||||||
|
background-color: #238636;
|
||||||
|
color: #fff;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-btn:hover {
|
||||||
|
background-color: #2ea043;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Custom Datei-Upload */
|
||||||
|
.custom-file-upload {
|
||||||
|
background-color: #21262d;
|
||||||
|
border: 2px dashed #58a6ff;
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-file-upload label {
|
||||||
|
cursor: pointer;
|
||||||
|
color: #58a6ff;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fileNameDisplay {
|
||||||
|
display: block;
|
||||||
|
margin-top: 10px;
|
||||||
|
color: #c9d1d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
background-color: #161b22;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 20px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
color: #c9d1d9;
|
||||||
|
font-size: 16px;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"], input[type="file"] {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: 1px solid #30363d;
|
||||||
|
background-color: #0d1117;
|
||||||
|
color: #c9d1d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"]:focus, input[type="file"]:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #58a6ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-icon {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer a {
|
||||||
|
color: #58a6ff;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: #238636;
|
||||||
|
color: #ffffff;
|
||||||
|
border: none;
|
||||||
|
padding: 8px 20px;
|
||||||
|
border-radius: 6px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: bold;
|
||||||
|
transition: background 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
background-color: #2ea043;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-danger {
|
||||||
|
background-color: #da3633;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-danger:hover {
|
||||||
|
background-color: #f85149;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background-color: #0d1117;
|
||||||
|
border: 1px solid #30363d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: #161b22;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline-form {
|
||||||
|
display: inline;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
BIN
Outdated Website/static/upload.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
Outdated Website/static/user.png
Normal file
|
After Width: | Height: | Size: 7 KiB |
BIN
Outdated Website/static/user_small.png
Normal file
|
After Width: | Height: | Size: 7 KiB |
18
Outdated Website/templates/add_changelog.html
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
{% extends "base_dark.html" %}
|
||||||
|
{% else %}
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% block title %}Add Changelog{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="form-container" style="max-width: 600px; margin: 30px auto;">
|
||||||
|
<h2>Add a New Changelog</h2>
|
||||||
|
<form action="{{ url_for('add_changelog') }}" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<textarea name="changelog" rows="5" style="width: 100%; padding: 10px; border-radius: 8px; border: 1px solid #ccc;" placeholder="Enter the changelog details here..." required></textarea>
|
||||||
|
<button type="submit" style="margin-top: 10px; background-color: #007BFF; color: white; padding: 10px 20px; border: none; border-radius: 8px; cursor: pointer;">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
79
Outdated Website/templates/appointment_scheduler.html
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
{% extends "base_dark.html" %}
|
||||||
|
{% else %}
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% block title %}Termin Planer{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="content-wrapper">
|
||||||
|
<div class="form-container" style="max-width: 1000px; padding: 30px;">
|
||||||
|
<h2>Termin Planer</h2>
|
||||||
|
<div id="calendar" style="margin-top: 20px;">
|
||||||
|
<table style="width: 100%; border-collapse: collapse; text-align: center;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="padding: 10px; border: 1px solid #ddd;">Montag</th>
|
||||||
|
<th style="padding: 10px; border: 1px solid #ddd;">Dienstag</th>
|
||||||
|
<th style="padding: 10px; border: 1px solid #ddd;">Mittwoch</th>
|
||||||
|
<th style="padding: 10px; border: 1px solid #ddd;">Donnerstag</th>
|
||||||
|
<th style="padding: 10px; border: 1px solid #ddd;">Freitag</th>
|
||||||
|
<th style="padding: 10px; border: 1px solid #ddd;">Samstag</th>
|
||||||
|
<th style="padding: 10px; border: 1px solid #ddd;">Sonntag</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for week in calendar %}
|
||||||
|
<tr>
|
||||||
|
{% for day in week %}
|
||||||
|
<td style="padding: 10px; border: 1px solid #ddd; vertical-align: top;">
|
||||||
|
<strong>{{ day.date }}</strong>
|
||||||
|
<ul style="list-style: none; padding: 0; margin: 10px 0;">
|
||||||
|
{% for event in day.events %}
|
||||||
|
<li>{{ event.time }} - {{ event.player }}: {{ event.description }} (Für: {{ event.assigned_to }})</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
<button onclick="openEventModal('{{ day.date }}')" style="margin-top: 10px;">+ Termin</button>
|
||||||
|
</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="eventModal" style="display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); z-index: 1000;">
|
||||||
|
<h3>Neuen Termin hinzufügen</h3>
|
||||||
|
<form method="POST" action="{{ url_for('appointment_scheduler') }}">
|
||||||
|
<input type="hidden" name="date" id="eventDate">
|
||||||
|
<label for="time">Uhrzeit:</label>
|
||||||
|
<input type="time" name="time" id="time" required>
|
||||||
|
<br>
|
||||||
|
<label for="player">Spieler:</label>
|
||||||
|
<input type="text" name="player" id="player" required>
|
||||||
|
<br>
|
||||||
|
<label for="description">Beschreibung:</label>
|
||||||
|
<input type="text" name="description" id="description" required>
|
||||||
|
<br>
|
||||||
|
<label for="assigned_to">Für:</label>
|
||||||
|
<input type="text" name="assigned_to" id="assigned_to" required>
|
||||||
|
<br>
|
||||||
|
<button type="submit" style="margin-top: 10px;">Speichern</button>
|
||||||
|
<button type="button" onclick="closeEventModal()" style="margin-top: 10px;">Abbrechen</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function openEventModal(date) {
|
||||||
|
document.getElementById('eventDate').value = date;
|
||||||
|
document.getElementById('eventModal').style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeEventModal() {
|
||||||
|
document.getElementById('eventModal').style.display = 'none';
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
159
Outdated Website/templates/appointments.html
Normal file
|
|
@ -0,0 +1,159 @@
|
||||||
|
{% extends "base.html" if session["theme"] == "lightmode" else "base_dark.html" %}
|
||||||
|
|
||||||
|
{% block title %}Termin Planer{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="calendar-wrapper" style="max-width: 1200px; margin: 30px auto; display: flex; gap: 20px;">
|
||||||
|
<div class="calendar-container" style="flex: 1; background: {% if session['theme'] == 'lightmode' %}#f0f0f0{% else %}#323232{% endif %}; padding: 20px; border-radius: 12px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);">
|
||||||
|
<h2 style="margin-bottom: 20px;">📅 Termin Planer</h2>
|
||||||
|
<div class="calendar-navigation" style="margin: 20px 0;">
|
||||||
|
<button onclick="navigateMonth(-1)" class="neon-button neon1"><span>⬅️ Vorheriger Monat</span></button>
|
||||||
|
<span id="currentMonth" style="margin: 0 20px; font-size: 18px; font-weight: bold;"></span>
|
||||||
|
<button onclick="navigateMonth(1)" class="neon-button neon1"><span>➡️ Nächster Monat</span></button>
|
||||||
|
</div>
|
||||||
|
<div id="calendar" style="display: grid; grid-template-columns: repeat(7, 1fr); gap: 10px; text-align: center;">
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 20px;">
|
||||||
|
<a href="{{ url_for('dashboard') }}" class="neon-button neon2"><span>🔙 Zurück zum Dashboard</span></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="appointments-container" style="flex: 1; background: {% if session['theme'] == 'lightmode' %}#ffffff{% else %}#2c2c2c{% endif %}; padding: 20px; border-radius: 12px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);">
|
||||||
|
<h2 style="margin-bottom: 20px;">📋 Anstehende Termine</h2>
|
||||||
|
{% if appointments %}
|
||||||
|
<ul style="list-style: none; padding: 0;">
|
||||||
|
{% for appointment in appointments %}
|
||||||
|
<li style="margin-bottom: 15px; padding: 10px; border: 1px solid #ccc; border-radius: 8px; background: {% if session['theme'] == 'lightmode' %}#f9f9f9{% else %}#3a3a3a{% endif %};">
|
||||||
|
<strong>{{ appointment.title }}</strong><br>
|
||||||
|
<small>{{ appointment.start_date }} - {{ appointment.end_date }}</small><br>
|
||||||
|
<span>{{ appointment.description }}</span>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<p>Keine anstehenden Termine.</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<<div id="appointmentPopup" style="display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: {% if session['theme'] == 'lightmode' %}#ffffff{% else %}#2c2c2c{% endif %}; padding: 20px; border-radius: 12px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); z-index: 1000; width: 300px;">
|
||||||
|
<h3>Termin hinzufügen</h3>
|
||||||
|
<form id="appointmentForm" method="POST" action="{{ url_for('appointments') }}">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<label for="title">Titel:</label>
|
||||||
|
<input type="text" id="title" name="title" style="width: 100%; margin-bottom: 10px; padding: 8px; border-radius: 6px; border: 1px solid #ccc;" required>
|
||||||
|
<label for="start_date">Startdatum:</label>
|
||||||
|
<input type="date" id="start_date" name="start_date" style="width: 100%; margin-bottom: 10px; padding: 8px; border-radius: 6px; border: 1px solid #ccc;" required>
|
||||||
|
<label for="end_date">Enddatum:</label>
|
||||||
|
<input type="date" id="end_date" name="end_date" style="width: 100%; margin-bottom: 10px; padding: 8px; border-radius: 6px; border: 1px solid #ccc;" required>
|
||||||
|
<label for="description">Beschreibung:</label>
|
||||||
|
<textarea id="description" name="description" style="width: 100%; margin-bottom: 10px; padding: 8px; border-radius: 6px; border: 1px solid #ccc;"></textarea>
|
||||||
|
<button type="submit" class="neon-button neon1" style="margin-top: 10px;">Speichern</button>
|
||||||
|
<button type="button" onclick="closePopup()" class="neon-button neon3" style="margin-top: 10px;">Abbrechen</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="popupOverlay" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); z-index: 999;" onclick="closePopup()"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const calendar = document.getElementById('calendar');
|
||||||
|
const currentMonth = document.getElementById('currentMonth');
|
||||||
|
const popup = document.getElementById('appointmentPopup');
|
||||||
|
const overlay = document.getElementById('popupOverlay');
|
||||||
|
let date = new Date();
|
||||||
|
const today = new Date();
|
||||||
|
|
||||||
|
function renderCalendar() {
|
||||||
|
calendar.innerHTML = '';
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = date.getMonth();
|
||||||
|
currentMonth.textContent = date.toLocaleString('default', { month: 'long', year: 'numeric' });
|
||||||
|
|
||||||
|
const firstDay = new Date(year, month, 1).getDay();
|
||||||
|
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
||||||
|
|
||||||
|
for (let i = 0; i < firstDay; i++) {
|
||||||
|
calendar.innerHTML += '<div></div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let day = 1; day <= daysInMonth; day++) {
|
||||||
|
const isToday = today.getFullYear() === year && today.getMonth() === month && today.getDate() === day;
|
||||||
|
const backgroundColor = isToday
|
||||||
|
? (sessionStorage.getItem('theme') === 'darkmode' ? '#1e3a8a' : '#ffeb3b')
|
||||||
|
: 'transparent';
|
||||||
|
calendar.innerHTML += `<div style="padding: 10px; border: 1px solid #555; border-radius: 4px; cursor: pointer; background-color: ${backgroundColor};" onclick="openPopup(${day})">${day}</div>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function navigateMonth(offset) {
|
||||||
|
date.setMonth(date.getMonth() + offset);
|
||||||
|
renderCalendar();
|
||||||
|
}
|
||||||
|
|
||||||
|
function openPopup(day) {
|
||||||
|
const selectedDate = new Date(date.getFullYear(), date.getMonth(), day);
|
||||||
|
document.getElementById('start_date').value = selectedDate.toISOString().split('T')[0];
|
||||||
|
document.getElementById('end_date').value = selectedDate.toISOString().split('T')[0];
|
||||||
|
popup.style.display = 'block';
|
||||||
|
overlay.style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
|
function closePopup() {
|
||||||
|
popup.style.display = 'none';
|
||||||
|
overlay.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
renderCalendar();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.neon-button {
|
||||||
|
width: auto;
|
||||||
|
min-width: 150px;
|
||||||
|
padding: 14px 20px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: bold;
|
||||||
|
border: 2px solid;
|
||||||
|
color: inherit;
|
||||||
|
background: transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: 0.3s;
|
||||||
|
box-shadow: 0 0 8px currentColor, 0 0 14px currentColor inset;
|
||||||
|
margin: 10px 0;
|
||||||
|
border-radius: 6px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon1 { color: #00fff7; border-color: #00fff7; }
|
||||||
|
.neon2 { color: #ff00ff; border-color: #ff00ff; }
|
||||||
|
.neon3 { color: #39ff14; border-color: #39ff14; }
|
||||||
|
|
||||||
|
.neon-button::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0; left: 0;
|
||||||
|
width: 100%; height: 100%;
|
||||||
|
background: currentColor;
|
||||||
|
z-index: 0;
|
||||||
|
transform: scaleX(0);
|
||||||
|
transform-origin: left;
|
||||||
|
transition: 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon-button:hover::before {
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon-button span {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
transition: color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon-button:hover span {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
154
Outdated Website/templates/base.html
Normal file
|
|
@ -0,0 +1,154 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{% block title %}Moonlab{% endblock %}</title>
|
||||||
|
<link rel="stylesheet" href="/static/style.css">
|
||||||
|
<link rel="icon" href="/static/logo.png" type="image/png">
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background-image: url('/static/background.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20px;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-container {
|
||||||
|
background: rgba(255, 255, 255, 0.6);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
max-width: 400px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-container input[type="text"],
|
||||||
|
.form-container input[type="password"] {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 350px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 8px 0 16px 0;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 15px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 20px;
|
||||||
|
right: 20px;
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 16px;
|
||||||
|
background-color: gray;
|
||||||
|
background-size: 70%;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
|
||||||
|
transition: background-image 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon-button {
|
||||||
|
width: 100%;
|
||||||
|
padding: 14px 20px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: bold;
|
||||||
|
border: 2px solid;
|
||||||
|
color: inherit;
|
||||||
|
background: transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: 0.3s;
|
||||||
|
box-shadow: 0 0 8px currentColor, 0 0 14px currentColor inset;
|
||||||
|
margin: 10px 0;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon1 { color: #00fff7; border-color: #00fff7; }
|
||||||
|
.neon2 { color: #ff00ff; border-color: #ff00ff; }
|
||||||
|
.neon3 { color: #39ff14; border-color: #39ff14; }
|
||||||
|
|
||||||
|
.neon-button::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0; left: 0;
|
||||||
|
width: 100%; height: 100%;
|
||||||
|
background: currentColor;
|
||||||
|
z-index: 0;
|
||||||
|
transform: scaleX(0);
|
||||||
|
transform-origin: left;
|
||||||
|
transition: 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon-button:hover::before {
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon-button span {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
transition: color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon-button:hover span {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% include "top_bar.html" %}
|
||||||
|
<div class="content-wrapper">
|
||||||
|
{% block content %}
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="theme-toggle" id="themeToggle" style="background-image: url('/static/{{ 'night-mode.png' if session['theme'] == 'lightmode' else 'light-mode.png' }}');"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const themeToggle = document.getElementById('themeToggle');
|
||||||
|
themeToggle.addEventListener('click', () => {
|
||||||
|
fetch('/toggle-theme', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
credentials: 'same-origin'
|
||||||
|
}).then(response => {
|
||||||
|
if (response.ok) {
|
||||||
|
location.reload();
|
||||||
|
} else {
|
||||||
|
console.error('Failed to toggle theme:', response.statusText);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
288
Outdated Website/templates/base_dark.html
Normal file
|
|
@ -0,0 +1,288 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{% block title %}Moonlab{% endblock %}</title>
|
||||||
|
<link rel="stylesheet" href="/static/style.css">
|
||||||
|
<link rel="icon" href="/static/logo.png" type="image/png">
|
||||||
|
<style>
|
||||||
|
@import url('https://fonts.googleapis.com/css?family=Exo:400,700');
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Exo', sans-serif;
|
||||||
|
margin: 0;
|
||||||
|
color: white;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.area {
|
||||||
|
background: #000;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circles {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circles li {
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
list-style: none;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
animation: animate 25s linear infinite;
|
||||||
|
bottom: -150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circles li:nth-child(1) {
|
||||||
|
left: 25%;
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
animation-delay: 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circles li:nth-child(2) {
|
||||||
|
left: 10%;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
animation-delay: 2s;
|
||||||
|
animation-duration: 12s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circles li:nth-child(3) {
|
||||||
|
left: 70%;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
animation-delay: 4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circles li:nth-child(4) {
|
||||||
|
left: 40%;
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
animation-delay: 0s;
|
||||||
|
animation-duration: 18s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circles li:nth-child(5) {
|
||||||
|
left: 65%;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
animation-delay: 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circles li:nth-child(6) {
|
||||||
|
left: 75%;
|
||||||
|
width: 110px;
|
||||||
|
height: 110px;
|
||||||
|
animation-delay: 3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circles li:nth-child(7) {
|
||||||
|
left: 35%;
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
animation-delay: 7s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circles li:nth-child(8) {
|
||||||
|
left: 50%;
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
animation-delay: 15s;
|
||||||
|
animation-duration: 45s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circles li:nth-child(9) {
|
||||||
|
left: 20%;
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
animation-delay: 2s;
|
||||||
|
animation-duration: 35s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circles li:nth-child(10) {
|
||||||
|
left: 85%;
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
animation-delay: 0s;
|
||||||
|
animation-duration: 11s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes animate {
|
||||||
|
0% {
|
||||||
|
transform: translateY(0) rotate(0deg);
|
||||||
|
opacity: 1;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateY(-1000px) rotate(720deg);
|
||||||
|
opacity: 0;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-container {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
background: rgba(30, 30, 30, 0.85);
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.6);
|
||||||
|
width: 100%;
|
||||||
|
max-width: 400px;
|
||||||
|
text-align: center;
|
||||||
|
backdrop-filter: blur(4px);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-toggle {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 20px;
|
||||||
|
right: 20px;
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 16px;
|
||||||
|
background-color: gray;
|
||||||
|
background-size: 70%;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
|
||||||
|
transition: background-image 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon-button {
|
||||||
|
width: 100%;
|
||||||
|
padding: 14px 20px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: bold;
|
||||||
|
border: 2px solid;
|
||||||
|
color: inherit;
|
||||||
|
background: transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: 0.3s;
|
||||||
|
box-shadow: 0 0 8px currentColor, 0 0 14px currentColor inset;
|
||||||
|
margin: 10px 0;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon1 { color: #00fff7; border-color: #00fff7; }
|
||||||
|
.neon2 { color: #ff00ff; border-color: #ff00ff; }
|
||||||
|
.neon3 { color: #39ff14; border-color: #39ff14; }
|
||||||
|
|
||||||
|
.neon-button::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0; left: 0;
|
||||||
|
width: 100%; height: 100%;
|
||||||
|
background: currentColor;
|
||||||
|
z-index: 0;
|
||||||
|
transform: scaleX(0);
|
||||||
|
transform-origin: left;
|
||||||
|
transition: 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon-button:hover::before {
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon-button span {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
transition: color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon-button:hover span {
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logout-button {
|
||||||
|
color: #ff4d4d;
|
||||||
|
border-color: #ff4d4d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logout-button:hover span {
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="area">
|
||||||
|
<ul class="circles">
|
||||||
|
<li></li>
|
||||||
|
<li></li>
|
||||||
|
<li></li>
|
||||||
|
<li></li>
|
||||||
|
<li></li>
|
||||||
|
<li></li>
|
||||||
|
<li></li>
|
||||||
|
<li></li>
|
||||||
|
<li></li>
|
||||||
|
<li></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% include "top_bar.html" %}
|
||||||
|
|
||||||
|
<div class="content-wrapper">
|
||||||
|
{% block content %}
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="theme-toggle" id="themeToggle" style="background-image: url('/static/{{ 'night-mode.png' if session['theme'] == 'lightmode' else 'light-mode.png' }}');"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const themeToggle = document.getElementById('themeToggle');
|
||||||
|
themeToggle.addEventListener('click', () => {
|
||||||
|
fetch('/toggle-theme', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
credentials: 'same-origin'
|
||||||
|
}).then(response => {
|
||||||
|
if (response.ok) {
|
||||||
|
location.reload();
|
||||||
|
} else {
|
||||||
|
console.error('Failed to toggle theme:', response.statusText);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
42
Outdated Website/templates/bot_logs.html
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Bot Logs</title>
|
||||||
|
<link rel="stylesheet" href="/static/style.css">
|
||||||
|
<link rel="icon" href="/static/logo.png" type="image/png">
|
||||||
|
<style>
|
||||||
|
.logs-container {
|
||||||
|
background: rgba(255, 255, 255, 0.6);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
max-width: 600px;
|
||||||
|
width: 100%;
|
||||||
|
margin: auto;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.logs-container h2 {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.log-entry {
|
||||||
|
background: #f9f9f9;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% include "top_bar.html" %}
|
||||||
|
<div class="logs-container">
|
||||||
|
<h2>Logs für {{ bot_name }}</h2>
|
||||||
|
{% for log in logs %}
|
||||||
|
<div class="log-entry">{{ log }}</div>
|
||||||
|
{% endfor %}
|
||||||
|
<a href="{{ url_for('dc_bots') }}" class="black-button">Zurück</a>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
133
Outdated Website/templates/create_license_key.html
Normal file
|
|
@ -0,0 +1,133 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>License Key erstellen</title>
|
||||||
|
<link rel="stylesheet" href="/static/style.css">
|
||||||
|
<link rel="icon" href="/static/logo.png" type="image/png">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-image: url('/static/background.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
width: 80%;
|
||||||
|
max-width: 800px;
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.content h2 {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.content .license-key {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
.content .license-key input {
|
||||||
|
width: 300px;
|
||||||
|
padding: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.content .license-key button {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.content .license-key button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
.content .message {
|
||||||
|
display: none;
|
||||||
|
color: green;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.content form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.content form label {
|
||||||
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.content form input,
|
||||||
|
.content form textarea,
|
||||||
|
.content form select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 5px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.content form button {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.content form button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% include "top_bar.html" %}
|
||||||
|
<div class="content">
|
||||||
|
<h2>License Key erstellen</h2>
|
||||||
|
{% if license_key %}
|
||||||
|
<div class="license-key">
|
||||||
|
<input type="text" id="licenseKey" value="{{ license_key }}" readonly>
|
||||||
|
<button onclick="copyToClipboard()">Kopieren</button>
|
||||||
|
</div>
|
||||||
|
<div class="message" id="message">
|
||||||
|
<img src="/static/green_check.png" alt="Check" style="width: 20px; vertical-align: middle;">
|
||||||
|
License key wurde kopiert
|
||||||
|
</div>
|
||||||
|
{% elif error %}
|
||||||
|
<p>{{ error }}</p>
|
||||||
|
{% endif %}
|
||||||
|
<form action="{{ url_for('create_license_key') }}" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit">Neuen License Key generieren</button>
|
||||||
|
</form>
|
||||||
|
<a href="/license_keys" class="black-button">Zurück</a>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function copyToClipboard() {
|
||||||
|
var copyText = document.getElementById("licenseKey");
|
||||||
|
copyText.select();
|
||||||
|
copyText.setSelectionRange(0, 99999);
|
||||||
|
document.execCommand("copy");
|
||||||
|
var message = document.getElementById("message");
|
||||||
|
message.style.display = "block";
|
||||||
|
setTimeout(function() {
|
||||||
|
message.style.display = "none";
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
64
Outdated Website/templates/create_project.html
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Neues Projekt erstellen</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: gray;
|
||||||
|
color: white;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
background-color: #333;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
max-width: 400px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
input[type="text"] {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Neues Projekt erstellen</h1>
|
||||||
|
<form method="POST">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<label for="project_name">Projektname:</label>
|
||||||
|
<input type="text" id="project_name" name="project_name" required>
|
||||||
|
<button type="submit">Erstellen</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
123
Outdated Website/templates/dashboard_dark.html
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
{% extends "base_dark.html" %}
|
||||||
|
|
||||||
|
{% block title %}Dashboard (Dark Mode){% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="dashboard-wrapper" style="max-width: 1200px; margin: 80px auto 30px auto;">
|
||||||
|
<div class="dashboard-container" style="display: flex; justify-content: space-between; gap: 20px;">
|
||||||
|
<style>
|
||||||
|
.dashboard-box {
|
||||||
|
background: rgba(30, 30, 30, 0.85);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.6);
|
||||||
|
width: 100%;
|
||||||
|
max-width: 300px;
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.dashboard-box h3 {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: #00fff7;
|
||||||
|
}
|
||||||
|
.dashboard-box form, .dashboard-box a {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.dashboard-box button, .dashboard-box a {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="dashboard-box">
|
||||||
|
<h3>Administration</h3>
|
||||||
|
{% if 'user_management' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('user_management') }}" method="get">
|
||||||
|
<button type="submit" class="neon-button neon1"><span>👤 User Management</span></button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'delete_requests' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('delete_requests') }}" method="get">
|
||||||
|
<button type="submit" class="neon-button neon3"><span>🗑️ Delete-Requests</span></button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'logs' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('logs') }}" method="get">
|
||||||
|
<button type="submit" class="neon-button"><span>📜 Logs</span></button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'changelogs' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('add_changelog') }}" method="get">
|
||||||
|
<button type="submit" class="neon-button neon1"><span>📝 Add-Changelog</span></button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
<form action="{{ url_for('view_changelogs') }}" method="get">
|
||||||
|
<button type="submit" class="neon-button neon2"><span>📋 Changelogs</span></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="dashboard-box">
|
||||||
|
<h3>Private Tools</h3>
|
||||||
|
{% if 'discord_bots' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('dc_bots') }}" method="get">
|
||||||
|
<button type="submit" class="neon-button neon2"><span>🤖 Discord Bots</span></button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'appointments' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('appointments') }}" method="get">
|
||||||
|
<button type="submit" class="neon-button neon1"><span>📅 Termin Planer</span></button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'view_license_keys' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('license_keys') }}" method="get">
|
||||||
|
<button type="submit" class="neon-button neon1"><span>🛡️ ML Cheat Scanner</span></button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="dashboard-box">
|
||||||
|
<h3>Moonlab Tools</h3>
|
||||||
|
{% if 'intranet' in session['permissions'] %}
|
||||||
|
<form action="https://intra.moon-lab.de" method="get" target="_blank">
|
||||||
|
<button type="submit" class="neon-button neon2"><span>🌐 Moonlab-Intranet</span></button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'create_event_feedback' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('event_feedback') }}" method="get">
|
||||||
|
<button type="submit" class="neon-button"><span>📝 Event Feedback</span></button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'view_event_feedback' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('view_event_feedbacks') }}" method="get">
|
||||||
|
<button type="submit" class="neon-button"><span>📊 Event Feedback ansehen</span></button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if "verify_age" in session["permissions"] %}
|
||||||
|
<form action="{{ url_for('verify_age') }}" method="get">
|
||||||
|
<button type="submit" class="neon-button neon3"><span>🎂 Altersüberprüfung</span></button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'events' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('events') }}" method="get">
|
||||||
|
<button type="submit" class="neon-button neon2"><span>🎉 Events</span></button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'ip_checker' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('ip_checker') }}" method="get">
|
||||||
|
<button type="submit" class="neon-button neon3"><span>🌍 IP Checker</span></button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="display: flex; justify-content: center; gap: 20px; margin-top: 20px;">
|
||||||
|
<form action="{{ url_for('logout') }}" method="get">
|
||||||
|
<button type="submit" class="neon-button neon3"><span>🚪 Logout</span></button>
|
||||||
|
</form>
|
||||||
|
<form action="{{ url_for('settings') }}" method="get">
|
||||||
|
<button type="submit" class="neon-button neon2"><span>⚙️ Einstellungen</span></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
124
Outdated Website/templates/dashboard_light.html
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}Dashboard{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="dashboard-wrapper" style="max-width: 1200px; margin: 30px auto;">
|
||||||
|
<div class="dashboard-container" style="display: flex; justify-content: space-between; gap: 20px;">
|
||||||
|
<style>
|
||||||
|
.dashboard-box {
|
||||||
|
background: rgba(255, 255, 255, 0.6);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
width: 100%;
|
||||||
|
max-width: 300px;
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.dashboard-box h3 {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.dashboard-box form, .dashboard-box a {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.dashboard-box button, .dashboard-box a {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="dashboard-box">
|
||||||
|
<h3>Administration</h3>
|
||||||
|
{% if 'user_management' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('user_management') }}" method="get">
|
||||||
|
<button type="submit" style="background-color: #1ac583;">👤 User Management</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'delete_requests' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('delete_requests') }}" method="get">
|
||||||
|
<button type="submit" style="background-color: #ff0000;">🗑️ Delete-Requests</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'logs' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('logs') }}" method="get">
|
||||||
|
<button type="submit" style="background-color: #007BFF;">📜 Logs</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'changelogs' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('add_changelog') }}" method="get">
|
||||||
|
<button type="submit" style="background-color: #FFD700;">📝 Add-Changelog</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
<form action="{{ url_for('view_changelogs') }}" method="get">
|
||||||
|
<button type="submit" style="background-color: #00bfff;">📋 Changelogs</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dashboard-box">
|
||||||
|
<h3>Private Tools</h3>
|
||||||
|
{% if 'discord_bots' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('dc_bots') }}" method="get">
|
||||||
|
<button type="submit" style="background-color: #0b55c4;">🤖 Discord Bots</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'appointments' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('appointments') }}" method="get">
|
||||||
|
<button type="submit" style="background-color: #1ac583;">📅 Termin Planer</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'view_license_keys' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('license_keys') }}" method="get">
|
||||||
|
<button type="submit" style="background-color: #4d0c97;">🛡️ ML Cheat Scanner</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dashboard-box">
|
||||||
|
<h3>Moonlab Tools</h3>
|
||||||
|
{% if 'intranet' in session['permissions'] %}
|
||||||
|
<form action="https://intra.moon-lab.de" method="get" target="_blank">
|
||||||
|
<button type="submit" style="background-color: #4b0082;">🌐 Moonlab-Intranet</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'create_event_feedback' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('event_feedback') }}" method="get">
|
||||||
|
<button type="submit" style="background-color: #007BFF;">📝 Event Feedback</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'view_event_feedback' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('view_event_feedbacks') }}" method="get">
|
||||||
|
<button type="submit" style="background-color: #007BFF;">📊 Event Feedback ansehen</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if "verify_age" in session["permissions"] %}
|
||||||
|
<form action="{{ url_for('verify_age') }}" method="get">
|
||||||
|
<button type="submit" style="background-color: #5de700;">🎂 Altersüberprüfung</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'events' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('events') }}" method="get">
|
||||||
|
<button type="submit" style="background-color: #ff00ff;">🎉 Events</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if 'ip_checker' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('ip_checker') }}" method="get">
|
||||||
|
<button type="submit" style="background-color: #ff8c00;">🌍 IP Checker</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="display: flex; justify-content: center; gap: 20px; margin-top: 20px;">
|
||||||
|
<form action="{{ url_for('logout') }}" method="get">
|
||||||
|
<button type="submit" style="background-color: #ff4d4d;">🚪 Logout</button>
|
||||||
|
</form>
|
||||||
|
<form action="{{ url_for('settings') }}" method="get">
|
||||||
|
<button type="submit" style="background-color: #4b0082;">⚙️ Einstellungen</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
527
Outdated Website/templates/dc_bots.html
Normal file
|
|
@ -0,0 +1,527 @@
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
{% extends "base_dark.html" %}
|
||||||
|
{% else %}
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% block title %}Discord Bots{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
<style>
|
||||||
|
.bots-outer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.bots-container {
|
||||||
|
background: rgba(20, 20, 20, 0.95);
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.7);
|
||||||
|
max-width: 1100px;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 300px;
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.button-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
.button-container form {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.button-container .neon-button {
|
||||||
|
min-width: 150px;
|
||||||
|
margin: 0 6px;
|
||||||
|
}
|
||||||
|
.add-bot-button {
|
||||||
|
min-width: 170px;
|
||||||
|
margin: 0 6px;
|
||||||
|
}
|
||||||
|
.bot-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 20px;
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
.bot-box {
|
||||||
|
background: rgba(40, 40, 40, 0.9);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.4);
|
||||||
|
width: 340px;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.bot-box h3 {
|
||||||
|
margin-bottom: 18px;
|
||||||
|
color: #00fff7;
|
||||||
|
}
|
||||||
|
.bot-box form {
|
||||||
|
margin: 0 0 8px 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.bot-box button {
|
||||||
|
width: 100%;
|
||||||
|
margin: 4px 0;
|
||||||
|
padding: 10px 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.bot-box .turn-on {
|
||||||
|
background: none;
|
||||||
|
color: #39ff14;
|
||||||
|
border: 2px solid #39ff14;
|
||||||
|
box-shadow: 0 0 8px #39ff14, 0 0 14px #39ff14 inset;
|
||||||
|
transition: 0.3s;
|
||||||
|
}
|
||||||
|
.bot-box .turn-on:hover {
|
||||||
|
background: #39ff14;
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
.bot-box .turn-off {
|
||||||
|
background: none;
|
||||||
|
color: #ff4d4d;
|
||||||
|
border: 2px solid #ff4d4d;
|
||||||
|
box-shadow: 0 0 8px #ff4d4d, 0 0 14px #ff4d4d inset;
|
||||||
|
transition: 0.3s;
|
||||||
|
}
|
||||||
|
.bot-box .turn-off:hover {
|
||||||
|
background: #ff4d4d;
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
.bot-box .logs {
|
||||||
|
background: none;
|
||||||
|
color: #00fff7;
|
||||||
|
border: 2px solid #00fff7;
|
||||||
|
box-shadow: 0 0 8px #00fff7, 0 0 14px #00fff7 inset;
|
||||||
|
transition: 0.3s;
|
||||||
|
}
|
||||||
|
.bot-box .logs:hover {
|
||||||
|
background: #00fff7;
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
.add-bot-button {
|
||||||
|
background: none;
|
||||||
|
color: #ff00ff;
|
||||||
|
border: 2px solid #ff00ff;
|
||||||
|
box-shadow: 0 0 8px #ff00ff, 0 0 14px #ff00ff inset;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 14px 20px;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: 0.3s;
|
||||||
|
}
|
||||||
|
.add-bot-button:hover {
|
||||||
|
background: #ff00ff;
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
.modal {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 10;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
.modal-content {
|
||||||
|
background-color: #222;
|
||||||
|
color: #fff;
|
||||||
|
margin: 10% auto;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #555;
|
||||||
|
width: 90%;
|
||||||
|
max-width: 400px;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.close {
|
||||||
|
color: #ccc;
|
||||||
|
float: right;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.close:hover,
|
||||||
|
.close:focus {
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.status-icon {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
.bots-back-btn-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 18px;
|
||||||
|
}
|
||||||
|
.bots-back-btn {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
width: auto;
|
||||||
|
padding: 14px 28px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="bots-outer">
|
||||||
|
<div class="bots-container">
|
||||||
|
<div class="button-container">
|
||||||
|
<form action="{{ url_for('dashboard') }}" method="get">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="neon-button neon3"><span>Zurück zum Dashboard</span></button>
|
||||||
|
</form>
|
||||||
|
<form action="{{ url_for('add_dc_bot') }}" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="neon-button neon1"><span>Bot hinzufügen</span></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="button-container">
|
||||||
|
<button class="add-bot-button" onclick="document.getElementById('addBotModal').style.display='block'">Add Discord Bot</button>
|
||||||
|
<form action="{{ url_for('turn_on_all_bots') }}" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="neon-button neon3"><span>Turn On All</span></button>
|
||||||
|
</form>
|
||||||
|
<form action="{{ url_for('turn_off_all_bots') }}" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="neon-button neon2"><span>Turn Off All</span></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<h2 style="color:#00fff7;">Discord Bots</h2>
|
||||||
|
<div id="addBotModal" class="modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<span class="close" onclick="document.getElementById('addBotModal').style.display='none'">×</span>
|
||||||
|
<h2>Add Discord Bot</h2>
|
||||||
|
<form action="{{ url_for('add_dc_bot') }}" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<label for="bot_name">Bot Name:</label>
|
||||||
|
<input type="text" id="bot_name" name="bot_name" required>
|
||||||
|
<label for="bot_directory">Bot Directory:</label>
|
||||||
|
<input type="text" id="bot_directory" name="bot_directory" required>
|
||||||
|
<button type="submit" class="neon-button neon1"><span>Add Bot</span></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bot-container">
|
||||||
|
{% for bot in bots %}
|
||||||
|
<div class="bot-box">
|
||||||
|
<h3>{{ bot.name }}</h3>
|
||||||
|
<img src="/static/{{ 'circle_green_checkmark.png' if 'pid' in bot else 'offline.png' }}" alt="{{ 'Online' if 'pid' in bot else 'Offline' }}" class="status-icon">
|
||||||
|
<form action="{{ url_for('turn_on_bot', bot_name=bot.name) }}" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="turn-on">Turn On</button>
|
||||||
|
</form>
|
||||||
|
<form action="{{ url_for('turn_off_bot', bot_name=bot.name) }}" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="turn-off">Turn Off</button>
|
||||||
|
</form>
|
||||||
|
<form action="{{ url_for('bot_logs', bot_name=bot.name) }}" method="get">
|
||||||
|
<button type="submit" class="logs">Logs</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="bots-back-btn-row">
|
||||||
|
<a href="{{ url_for('dashboard') }}" class="neon-button neon3 bots-back-btn"><span>Zurück</span></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="statusModal" class="modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<span class="close" onclick="document.getElementById('statusModal').style.display='none'">×</span>
|
||||||
|
<p id="statusMessage"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function checkBotStatus(botName, isRunning, action) {
|
||||||
|
if ((action === 'on' && isRunning) || (action === 'off' && !isRunning)) {
|
||||||
|
document.getElementById('statusMessage').innerText = `Bot ${botName} kann nicht ${action === 'on' ? 'eingeschaltet' : 'ausgeschaltet'} werden, da er bereits ${action === 'on' ? 'läuft' : 'nicht läuft'}.`;
|
||||||
|
document.getElementById('statusModal').style.display = 'block';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onclick = function(event) {
|
||||||
|
if (event.target == document.getElementById('addBotModal')) {
|
||||||
|
document.getElementById('addBotModal').style.display = "none";
|
||||||
|
}
|
||||||
|
if (event.target == document.getElementById('statusModal')) {
|
||||||
|
document.getElementById('statusModal').style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{% else %}
|
||||||
|
<style>
|
||||||
|
.bots-outer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.bots-container {
|
||||||
|
background: rgba(255,255,255,0.9);
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||||
|
max-width: 1100px;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 300px;
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.button-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
.button-container form {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.add-bot-button {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 14px 20px;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
min-width: 170px;
|
||||||
|
margin: 0 6px;
|
||||||
|
transition: background 0.3s;
|
||||||
|
}
|
||||||
|
.add-bot-button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
.bot-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 20px;
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
.bot-box {
|
||||||
|
background: rgba(180, 180, 180, 0.9);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||||
|
width: 340px;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.bot-box h3 {
|
||||||
|
margin-bottom: 18px;
|
||||||
|
color: #007BFF;
|
||||||
|
}
|
||||||
|
.bot-box form {
|
||||||
|
margin: 0 0 8px 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.bot-box button {
|
||||||
|
width: 100%;
|
||||||
|
margin: 4px 0;
|
||||||
|
padding: 10px 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-weight: bold;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.3s;
|
||||||
|
}
|
||||||
|
.bot-box .turn-on {
|
||||||
|
background-color: #28a745;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.bot-box .turn-on:hover {
|
||||||
|
background-color: #218838;
|
||||||
|
}
|
||||||
|
.bot-box .turn-off {
|
||||||
|
background-color: #dc3545;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.bot-box .turn-off:hover {
|
||||||
|
background-color: #b52a37;
|
||||||
|
}
|
||||||
|
.bot-box .logs {
|
||||||
|
background-color: #fd7e14;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.bot-box .logs:hover {
|
||||||
|
background-color: #c76a10;
|
||||||
|
}
|
||||||
|
.modal {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 10;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
.modal-content {
|
||||||
|
background-color: #fefefe;
|
||||||
|
color: #000;
|
||||||
|
margin: 10% auto;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #888;
|
||||||
|
width: 90%;
|
||||||
|
max-width: 400px;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.close {
|
||||||
|
color: #aaa;
|
||||||
|
float: right;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.close:hover,
|
||||||
|
.close:focus {
|
||||||
|
color: #000;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.status-icon {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
.bots-back-btn-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 18px;
|
||||||
|
}
|
||||||
|
.bots-back-btn {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
width: auto;
|
||||||
|
text-align: center;
|
||||||
|
display: inline-block;
|
||||||
|
text-decoration: none;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.bots-back-btn:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="bots-outer">
|
||||||
|
<div class="bots-container">
|
||||||
|
<div class="button-container">
|
||||||
|
<form action="{{ url_for('dashboard') }}" method="get">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="bots-back-btn">Zurück zum Dashboard</button>
|
||||||
|
</form>
|
||||||
|
<form action="{{ url_for('add_dc_bot') }}" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="add-bot-button">Bot hinzufügen</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="button-container">
|
||||||
|
<button class="add-bot-button" onclick="document.getElementById('addBotModal').style.display='block'">Add Discord Bot</button>
|
||||||
|
<form action="{{ url_for('turn_on_all_bots') }}" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="add-bot-button">Turn On All</button>
|
||||||
|
</form>
|
||||||
|
<form action="{{ url_for('turn_off_all_bots') }}" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="add-bot-button">Turn Off All</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<h2 style="color:#007BFF;">Discord Bots</h2>
|
||||||
|
<div id="addBotModal" class="modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<span class="close" onclick="document.getElementById('addBotModal').style.display='none'">×</span>
|
||||||
|
<h2>Add Discord Bot</h2>
|
||||||
|
<form action="{{ url_for('add_dc_bot') }}" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<label for="bot_name">Bot Name:</label>
|
||||||
|
<input type="text" id="bot_name" name="bot_name" required>
|
||||||
|
<label for="bot_directory">Bot Directory:</label>
|
||||||
|
<input type="text" id="bot_directory" name="bot_directory" required>
|
||||||
|
<button type="submit" class="add-bot-button">Add Bot</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bot-container">
|
||||||
|
{% for bot in bots %}
|
||||||
|
<div class="bot-box">
|
||||||
|
<h3>{{ bot.name }}</h3>
|
||||||
|
<img src="/static/{{ 'circle_green_checkmark.png' if 'pid' in bot else 'offline.png' }}" alt="{{ 'Online' if 'pid' in bot else 'Offline' }}" class="status-icon">
|
||||||
|
<form action="{{ url_for('turn_on_bot', bot_name=bot.name) }}" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="turn-on">Turn On</button>
|
||||||
|
</form>
|
||||||
|
<form action="{{ url_for('turn_off_bot', bot_name=bot.name) }}" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="turn-off">Turn Off</button>
|
||||||
|
</form>
|
||||||
|
<form action="{{ url_for('bot_logs', bot_name=bot.name) }}" method="get">
|
||||||
|
<button type="submit" class="logs">Logs</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="bots-back-btn-row">
|
||||||
|
<a href="{{ url_for('dashboard') }}" class="bots-back-btn">Zurück</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="statusModal" class="modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<span class="close" onclick="document.getElementById('statusModal').style.display='none'">×</span>
|
||||||
|
<p id="statusMessage"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function checkBotStatus(botName, isRunning, action) {
|
||||||
|
if ((action === 'on' && isRunning) || (action === 'off' && !isRunning)) {
|
||||||
|
document.getElementById('statusMessage').innerText = `Bot ${botName} kann nicht ${action === 'on' ? 'eingeschaltet' : 'ausgeschaltet'} werden, da er bereits ${action === 'on' ? 'läuft' : 'nicht läuft'}.`;
|
||||||
|
document.getElementById('statusModal').style.display = 'block';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onclick = function(event) {
|
||||||
|
if (event.target == document.getElementById('addBotModal')) {
|
||||||
|
document.getElementById('addBotModal').style.display = "none";
|
||||||
|
}
|
||||||
|
if (event.target == document.getElementById('statusModal')) {
|
||||||
|
document.getElementById('statusModal').style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
237
Outdated Website/templates/delete_request.html
Normal file
|
|
@ -0,0 +1,237 @@
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
{% extends "base_dark.html" %}
|
||||||
|
{% else %}
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% block title %}Lösch Anfragen{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
<style>
|
||||||
|
.delete-container {
|
||||||
|
background: rgba(20, 20, 20, 0.95);
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.7);
|
||||||
|
max-width: 800px;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 300px;
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.delete-container h2 {
|
||||||
|
text-align: center;
|
||||||
|
color: #00fff7;
|
||||||
|
}
|
||||||
|
.delete-container table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.delete-container th, .delete-container td {
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #333;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.delete-container th {
|
||||||
|
background-color: #00fff7;
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
.delete-container .message {
|
||||||
|
color: #ff4d4d;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.approve-button {
|
||||||
|
background-color: #39ff14;
|
||||||
|
color: #111;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.approve-button:hover {
|
||||||
|
background-color: #28a745;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.deny-button {
|
||||||
|
background-color: #FF0000;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.deny-button:hover {
|
||||||
|
background-color: #CC0000;
|
||||||
|
}
|
||||||
|
.delete-back-btn-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 18px;
|
||||||
|
}
|
||||||
|
.delete-back-btn {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
width: auto;
|
||||||
|
padding: 14px 28px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div style="display:flex; flex-direction:column; align-items:center; width:100%;">
|
||||||
|
<div class="delete-container">
|
||||||
|
<h2>Lösch Anfragen</h2>
|
||||||
|
{% if delete_requests|length == 0 %}
|
||||||
|
<p class="message">Zurzeit keine aktive Lösch-Anfragen</p>
|
||||||
|
{% else %}
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Lizenzschlüssel</th>
|
||||||
|
<th>Benutzername</th>
|
||||||
|
<th>Aktionen</th>
|
||||||
|
</tr>
|
||||||
|
{% for request in delete_requests %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ request['license_key'] }}</td>
|
||||||
|
<td>{{ request['username'] }}</td>
|
||||||
|
<td>
|
||||||
|
<form action="{{ url_for('approve_delete_request', request_id=request['_id']) }}" method="post" style="display:inline;">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="approve-button">Genehmigen</button>
|
||||||
|
</form>
|
||||||
|
<form action="{{ url_for('deny_delete_request', request_id=request['_id']) }}" method="post" style="display:inline;">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="deny-button">Ablehnen</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
<div class="delete-back-btn-row">
|
||||||
|
<a href="{{ url_for('dashboard') }}" class="neon-button neon3 delete-back-btn"><span>Zurück</span></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<style>
|
||||||
|
.delete-container {
|
||||||
|
background: rgba(255,255,255,0.9);
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||||
|
max-width: 800px;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 300px;
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.delete-container h2 {
|
||||||
|
text-align: center;
|
||||||
|
color: #007BFF;
|
||||||
|
}
|
||||||
|
.delete-container table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.delete-container th, .delete-container td {
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.delete-container th {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.delete-container .message {
|
||||||
|
color: red;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.approve-button {
|
||||||
|
background-color: #28a745;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.approve-button:hover {
|
||||||
|
background-color: #218838;
|
||||||
|
}
|
||||||
|
.deny-button {
|
||||||
|
background-color: #FF0000;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.deny-button:hover {
|
||||||
|
background-color: #CC0000;
|
||||||
|
}
|
||||||
|
.delete-back-btn-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 18px;
|
||||||
|
}
|
||||||
|
.delete-back-btn {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
width: auto;
|
||||||
|
text-align: center;
|
||||||
|
display: inline-block;
|
||||||
|
text-decoration: none;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.delete-back-btn:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div style="display:flex; flex-direction:column; align-items:center; width:100%;">
|
||||||
|
<div class="delete-container">
|
||||||
|
<h2>Lösch Anfragen</h2>
|
||||||
|
{% if delete_requests|length == 0 %}
|
||||||
|
<p class="message">Zurzeit keine aktive Lösch-Anfragen</p>
|
||||||
|
{% else %}
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Lizenzschlüssel</th>
|
||||||
|
<th>Benutzername</th>
|
||||||
|
<th>Aktionen</th>
|
||||||
|
</tr>
|
||||||
|
{% for request in delete_requests %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ request['license_key'] }}</td>
|
||||||
|
<td>{{ request['username'] }}</td>
|
||||||
|
<td>
|
||||||
|
<form action="{{ url_for('approve_delete_request', request_id=request['_id']) }}" method="post" style="display:inline;">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="approve-button">Genehmigen</button>
|
||||||
|
</form>
|
||||||
|
<form action="{{ url_for('deny_delete_request', request_id=request['_id']) }}" method="post" style="display:inline;">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="deny-button">Ablehnen</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
<div class="delete-back-btn-row">
|
||||||
|
<a href="{{ url_for('dashboard') }}" class="delete-back-btn">Zurück</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
162
Outdated Website/templates/edit_user.html
Normal file
|
|
@ -0,0 +1,162 @@
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
{% extends "base_dark.html" %}
|
||||||
|
{% else %}
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% block title %}Benutzer bearbeiten{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<style>
|
||||||
|
.profile-pic-hover-effect {
|
||||||
|
transition: box-shadow 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-pic-hover-effect:hover {
|
||||||
|
box-shadow: 0 0 15px 5px rgba(0, 255, 247, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-message {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 20px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
background-color: rgba(0, 200, 0, 0.8);
|
||||||
|
color: white;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
z-index: 1000;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.5s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-message.show {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="content-wrapper">
|
||||||
|
<div class="form-container">
|
||||||
|
<label for="pfp_upload" style="cursor: pointer;">
|
||||||
|
<img id="profile_pic_preview"
|
||||||
|
src="/static/pfps/{{ user['_id'] }}.png?t={{ user.get('website_accounts', {}).get('pfp_last_updated', 0) }}"
|
||||||
|
alt="User Profile Picture"
|
||||||
|
onerror="this.onerror=null; this.src='/static/user.png';"
|
||||||
|
class="profile-pic-hover-effect"
|
||||||
|
style="width: 150px; height: 150px; margin-bottom: 20px; border-radius: 50%; object-fit: cover;">
|
||||||
|
</label>
|
||||||
|
<form id="edit_user_form" method="POST" action="{{ url_for('edit_user', user_id=user['_id']) }}" enctype="multipart/form-data" style="width: 100%;">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<input type="file" id="pfp_upload" name="pfp" accept="image/png, image/jpeg" style="display: none;">
|
||||||
|
|
||||||
|
<h2>Benutzer bearbeiten</h2>
|
||||||
|
<label for="display_name">Anzeigename:</label>
|
||||||
|
<input type="text" id="display_name" name="display_name" value="{{ user['display_name'] }}" required>
|
||||||
|
<label for="password">Neues Passwort:</label>
|
||||||
|
<input type="password" id="password" name="password">
|
||||||
|
<p><strong>Berechtigungen:</strong> {{ user['permissions'] | join(', ') }}</p>
|
||||||
|
<div style="display: flex; flex-direction: column; gap: 10px; width: 100%;">
|
||||||
|
{% if session['theme'] == 'lightmode' %}
|
||||||
|
<button type="submit" class="blue-button"><span>Speichern</span></button>
|
||||||
|
<a href="/dashboard" class="black-button"><span>Zurück</span></a>
|
||||||
|
{% else %}
|
||||||
|
<button type="submit" class="neon-button neon1" style="width: 100%;"><span>Speichern</span></button>
|
||||||
|
<a href="/dashboard" class="neon-button neon3" style="width: 100%; text-align: center;"><span>Zurück</span></a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="success_message" class="success-message"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const pfpUploadInput = document.getElementById('pfp_upload');
|
||||||
|
const profilePicPreview = document.getElementById('profile_pic_preview');
|
||||||
|
const editUserForm = document.getElementById('edit_user_form');
|
||||||
|
const successMessage = document.getElementById('success_message');
|
||||||
|
let imageJustUploaded = false; // Flag, um zu verhindern, dass der Submit mehrfach ausgelöst wird
|
||||||
|
|
||||||
|
// Trigger file input when image is clicked
|
||||||
|
profilePicPreview.addEventListener('click', () => {
|
||||||
|
pfpUploadInput.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Display selected image immediately and submit the form
|
||||||
|
pfpUploadInput.addEventListener('change', (event) => {
|
||||||
|
const file = event.target.files[0];
|
||||||
|
if (file) {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (e) => {
|
||||||
|
profilePicPreview.src = e.target.result;
|
||||||
|
// Automatisches Absenden des Formulars, sobald ein Bild ausgewählt wurde
|
||||||
|
if (!imageJustUploaded) {
|
||||||
|
imageJustUploaded = true;
|
||||||
|
editUserForm.requestSubmit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle form submission with Fetch API for instant update
|
||||||
|
editUserForm.addEventListener('submit', async (event) => {
|
||||||
|
event.preventDefault(); // Prevent default form submission (wird jetzt immer aufgerufen)
|
||||||
|
|
||||||
|
const formData = new FormData(editUserForm);
|
||||||
|
const userId = "{{ user['_id'] }}"; // Get user ID from Jinja context
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/edit_user/${userId}`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const result = await response.json(); // Assuming server returns JSON
|
||||||
|
if (result.success) {
|
||||||
|
// Show success message
|
||||||
|
successMessage.textContent = "Änderungen gespeichert!";
|
||||||
|
successMessage.classList.add('show');
|
||||||
|
setTimeout(() => {
|
||||||
|
successMessage.classList.remove('show');
|
||||||
|
imageJustUploaded = false; // Reset Flag nach erfolgreicher Speicherung
|
||||||
|
// Optional: Hier könntest du auch zur Dashboard-Seite weiterleiten
|
||||||
|
// window.location.href = "/dashboard";
|
||||||
|
}, 3000); // Meldung für 3 Sekunden anzeigen
|
||||||
|
|
||||||
|
// Update profile picture on success (sollte bereits durch die Vorschau geschehen sein)
|
||||||
|
if (result.pfp_url) {
|
||||||
|
// Append a timestamp to bust cache (wird auch beim ersten Laden gemacht)
|
||||||
|
profilePicPreview.src = result.pfp_url + '?t=' + new Date().getTime();
|
||||||
|
}
|
||||||
|
console.log('Profilbild erfolgreich gespeichert!');
|
||||||
|
} else {
|
||||||
|
console.error('Fehler beim Speichern des Profilbildes:', result.message);
|
||||||
|
successMessage.textContent = 'Fehler beim Speichern!';
|
||||||
|
successMessage.classList.add('show');
|
||||||
|
setTimeout(() => {
|
||||||
|
successMessage.classList.remove('show');
|
||||||
|
imageJustUploaded = false; // Reset Flag bei Fehler
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('Serverfehler:', response.status, response.statusText);
|
||||||
|
successMessage.textContent = 'Serverfehler!';
|
||||||
|
successMessage.classList.add('show');
|
||||||
|
setTimeout(() => {
|
||||||
|
successMessage.classList.remove('show');
|
||||||
|
imageJustUploaded = false; // Reset Flag bei Fehler
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Netzwerkfehler:', error);
|
||||||
|
successMessage.textContent = 'Netzwerkfehler!';
|
||||||
|
successMessage.classList.add('show');
|
||||||
|
setTimeout(() => {
|
||||||
|
successMessage.classList.remove('show');
|
||||||
|
imageJustUploaded = false; // Reset Flag bei Fehler
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
120
Outdated Website/templates/event_feedback.html
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Event Feedback</title>
|
||||||
|
<link rel="stylesheet" href="/static/style.css">
|
||||||
|
<link rel="icon" href="/static/logo.png" type="image/png">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-image: url('/static/background.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
width: 80%;
|
||||||
|
max-width: 600px;
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.content form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.content form label {
|
||||||
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.content form input,
|
||||||
|
.content form textarea,
|
||||||
|
.content form select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 5px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.content form button {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.content form button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
function toggleOtherInput(selectId, inputId) {
|
||||||
|
var selectElement = document.getElementById(selectId);
|
||||||
|
var inputElement = document.getElementById(inputId);
|
||||||
|
if (selectElement.value === "Anderes") {
|
||||||
|
inputElement.style.display = "block";
|
||||||
|
} else {
|
||||||
|
inputElement.style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% include "top_bar.html" %}
|
||||||
|
<div class="content">
|
||||||
|
<h1>Event Feedback</h1>
|
||||||
|
<form method="POST">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<label for="event_name">Event:</label>
|
||||||
|
<select id="event_name" name="event_name" onchange="toggleOtherInput('event_name', 'other_event_name')" required>
|
||||||
|
<option value="Simon Says">Simon Says</option>
|
||||||
|
<option value="Speedevent">Speedevent</option>
|
||||||
|
<option value="SCP999">SCP999</option>
|
||||||
|
<option value="Hide and Seek mit SCP939">Hide and Seek mit SCP939</option>
|
||||||
|
<option value="Hide and Seek mit Scaling">Hide and Seek mit Scaling</option>
|
||||||
|
<option value="Team Deathmatch auf der Surface">Team Deathmatch auf der Surface</option>
|
||||||
|
<option value="Team Deathmatch in der Heavy Zone">Team Deathmatch in der Heavy Zone</option>
|
||||||
|
<option value="Team Deathmatch in der Light">Team Deathmatch in der Light</option>
|
||||||
|
<option value="Anderes">Anderes</option>
|
||||||
|
</select>
|
||||||
|
<input type="text" id="other_event_name" name="other_event_name" placeholder="Event Name eingeben" style="display:none;">
|
||||||
|
|
||||||
|
<label for="event_progress">Verlauf des Events:</label>
|
||||||
|
<textarea id="event_progress" name="event_progress" required></textarea>
|
||||||
|
<input type="text" id="other_event_progress" name="other_event_progress" placeholder="Verlauf des Events eingeben" style="display:none;">
|
||||||
|
|
||||||
|
<label for="event_end">Ende des Events:</label>
|
||||||
|
<textarea id="event_end" name="event_end" required></textarea>
|
||||||
|
<input type="text" id="other_event_end" name="other_event_end" placeholder="Ende des Events eingeben" style="display:none;">
|
||||||
|
|
||||||
|
<label for="community_feedback">Feedback der Community:</label>
|
||||||
|
<textarea id="community_feedback" name="community_feedback" required></textarea>
|
||||||
|
<input type="text" id="other_community_feedback" name="other_community_feedback" placeholder="Feedback der Community eingeben" style="display:none;">
|
||||||
|
|
||||||
|
<label for="improvement_suggestions">Verbesserungsvorschläge:</label>
|
||||||
|
<textarea id="improvement_suggestions" name="improvement_suggestions" required></textarea>
|
||||||
|
|
||||||
|
<button type="submit">Abschicken</button>
|
||||||
|
</form>
|
||||||
|
<form action="{{ url_for('dashboard') }}" method="get">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit">Zurück</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
332
Outdated Website/templates/events.html
Normal file
|
|
@ -0,0 +1,332 @@
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
{% extends "base_dark.html" %}
|
||||||
|
{% else %}
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% block title %}Events{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<style>
|
||||||
|
.events-flex-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 30px;
|
||||||
|
margin-top: 40px;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
.events-flex-row .form-container {
|
||||||
|
margin: 0;
|
||||||
|
min-width: 320px;
|
||||||
|
max-width: 400px;
|
||||||
|
flex: 1 1 320px;
|
||||||
|
}
|
||||||
|
.events-back-btn-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
.events-form-light button[type="submit"] {
|
||||||
|
width: 100%;
|
||||||
|
padding: 14px 20px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: bold;
|
||||||
|
border: 2px solid #007BFF;
|
||||||
|
color: #007BFF;
|
||||||
|
background: transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin-top: 16px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
transition: background 0.2s, color 0.2s;
|
||||||
|
}
|
||||||
|
.events-form-light button[type="submit"]:hover {
|
||||||
|
background: #007BFF;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.events-back-btn-light {
|
||||||
|
min-width: 150px;
|
||||||
|
text-align: center;
|
||||||
|
padding: 14px 20px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: bold;
|
||||||
|
border: 2px solid #007BFF;
|
||||||
|
color: #007BFF;
|
||||||
|
background: transparent;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin-top: 10px;
|
||||||
|
transition: background 0.2s, color 0.2s;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.events-back-btn-light:hover {
|
||||||
|
background: #007BFF;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.events-back-btn-dark {
|
||||||
|
width: auto;
|
||||||
|
min-width: unset;
|
||||||
|
max-width: unset;
|
||||||
|
padding: 14px 28px;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
<div>
|
||||||
|
<div class="events-flex-row">
|
||||||
|
<div class="form-container">
|
||||||
|
<h2>Event hinzufügen</h2>
|
||||||
|
<form action="{{ url_for('events') }}" method="post">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<label for="event_name">Event Name:</label>
|
||||||
|
<input type="text" id="event_name" name="event_name" required>
|
||||||
|
<label for="community_feedback">Hat es der Community gefallen?</label>
|
||||||
|
<select id="community_feedback" name="community_feedback" required>
|
||||||
|
<option value="top">Ja</option>
|
||||||
|
<option value="flop">Nein</option>
|
||||||
|
<option value="etwas">Teilweise</option>
|
||||||
|
</select>
|
||||||
|
<label for="players">Spieleranzahl:</label>
|
||||||
|
<input type="number" id="players" name="players" required>
|
||||||
|
<label for="time">Uhrzeit:</label>
|
||||||
|
<input type="time" id="time" name="time" required>
|
||||||
|
<label for="weekday">Wochentag:</label>
|
||||||
|
<select id="weekday" name="weekday" required>
|
||||||
|
<option value="Montag">Montag</option>
|
||||||
|
<option value="Dienstag">Dienstag</option>
|
||||||
|
<option value="Mittwoch">Mittwoch</option>
|
||||||
|
<option value="Donnerstag">Donnerstag</option>
|
||||||
|
<option value="Freitag">Freitag</option>
|
||||||
|
<option value="Samstag">Samstag</option>
|
||||||
|
<option value="Sonntag">Sonntag</option>
|
||||||
|
</select>
|
||||||
|
<button type="submit" class="neon-button neon1"><span>Event hinzufügen</span></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="form-container">
|
||||||
|
<h2>Bestes Event berechnen</h2>
|
||||||
|
<form action="{{ url_for('events') }}" method="get">
|
||||||
|
<label for="current_players">Aktuelle Spieler:</label>
|
||||||
|
<input type="number" id="current_players" name="current_players" required>
|
||||||
|
<label for="current_time">Aktuelle Uhrzeit:</label>
|
||||||
|
<input type="time" id="current_time" name="current_time" required>
|
||||||
|
<label for="current_weekday">Aktueller Wochentag:</label>
|
||||||
|
<select id="current_weekday" name="current_weekday" required>
|
||||||
|
<option value="Montag">Montag</option>
|
||||||
|
<option value="Dienstag">Dienstag</option>
|
||||||
|
<option value="Mittwoch">Mittwoch</option>
|
||||||
|
<option value="Donnerstag">Donnerstag</option>
|
||||||
|
<option value="Freitag">Freitag</option>
|
||||||
|
<option value="Samstag">Samstag</option>
|
||||||
|
<option value="Sonntag">Sonntag</option>
|
||||||
|
</select>
|
||||||
|
<button type="submit" name="calculate_best" value="1" id="calculateBestEvent" class="neon-button neon2"><span>Bestes Event berechnen</span></button>
|
||||||
|
</form>
|
||||||
|
{% if best_events %}
|
||||||
|
<h2>Top 5 Events</h2>
|
||||||
|
<div id="barChartContainer" style="width:100%;height:260px;display:flex;align-items:end;justify-content:space-around;gap:10px;margin-top:30px;">
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
const bestEvents = {{ best_events|tojson }};
|
||||||
|
const colors = ["#00fff7", "#ff00ff", "#39ff14", "#ffb300", "#ff4d4d"];
|
||||||
|
function animateBars() {
|
||||||
|
const maxRating = Math.max(...bestEvents.map(e => e.rating));
|
||||||
|
const container = document.getElementById('barChartContainer');
|
||||||
|
container.innerHTML = '';
|
||||||
|
bestEvents.forEach((event, idx) => {
|
||||||
|
const bar = document.createElement('div');
|
||||||
|
bar.style.height = '0px';
|
||||||
|
bar.style.width = '60px';
|
||||||
|
bar.style.background = colors[idx % colors.length];
|
||||||
|
bar.style.borderRadius = '8px 8px 0 0';
|
||||||
|
bar.style.display = 'flex';
|
||||||
|
bar.style.flexDirection = 'column';
|
||||||
|
bar.style.alignItems = 'center';
|
||||||
|
bar.style.justifyContent = 'flex-end';
|
||||||
|
bar.style.transition = 'height 1s cubic-bezier(.68,-0.55,.27,1.55)';
|
||||||
|
bar.style.position = 'relative';
|
||||||
|
|
||||||
|
const label = document.createElement('div');
|
||||||
|
label.innerText = event.name;
|
||||||
|
label.style.position = 'absolute';
|
||||||
|
label.style.bottom = '-32px';
|
||||||
|
label.style.width = '100%';
|
||||||
|
label.style.textAlign = 'center';
|
||||||
|
label.style.fontSize = '13px';
|
||||||
|
label.style.color = '#fff';
|
||||||
|
label.style.wordBreak = 'break-word';
|
||||||
|
|
||||||
|
const value = document.createElement('div');
|
||||||
|
value.innerText = event.rating;
|
||||||
|
value.style.position = 'absolute';
|
||||||
|
value.style.top = '-28px';
|
||||||
|
value.style.width = '100%';
|
||||||
|
value.style.textAlign = 'center';
|
||||||
|
value.style.fontWeight = 'bold';
|
||||||
|
value.style.fontSize = '15px';
|
||||||
|
value.style.color = '#fff';
|
||||||
|
|
||||||
|
bar.appendChild(label);
|
||||||
|
bar.appendChild(value);
|
||||||
|
container.appendChild(bar);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
bar.style.height = (event.rating / (maxRating || 1) * 180 + 30) + 'px';
|
||||||
|
}, 100 + idx * 120);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
window.addEventListener('DOMContentLoaded', animateBars);
|
||||||
|
</script>
|
||||||
|
{% elif best_event %}
|
||||||
|
<h2>Bestes Event</h2>
|
||||||
|
<p>{{ best_event.name }} - Rating: {{ best_event.rating }} (Top: {{ best_event.top }}, Flop: {{ best_event.flop }})</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="form-container">
|
||||||
|
<h2>Protokollierte Events</h2>
|
||||||
|
<ul style="list-style-type: none; padding: 0;">
|
||||||
|
{% set event_names = [] %}
|
||||||
|
{% for event in events %}
|
||||||
|
{% if event.name not in event_names %}
|
||||||
|
<li style="background: rgba(255,255,255,0.35); margin: 5px 0; padding: 10px; border-radius: 4px;">{{ event.name }}</li>
|
||||||
|
{% set event_names = event_names.append(event.name) %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="events-back-btn-row">
|
||||||
|
<a href="javascript:window.history.back()" class="neon-button neon3 events-back-btn-dark"><span>Zurück</span></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div>
|
||||||
|
<div class="events-flex-row">
|
||||||
|
<div class="form-container">
|
||||||
|
<h2>Event hinzufügen</h2>
|
||||||
|
<form action="{{ url_for('events') }}" method="post" class="events-form-light">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<label for="event_name">Event Name:</label>
|
||||||
|
<input type="text" id="event_name" name="event_name" required>
|
||||||
|
<label for="community_feedback">Hat es der Community gefallen?</label>
|
||||||
|
<select id="community_feedback" name="community_feedback" required>
|
||||||
|
<option value="top">Ja</option>
|
||||||
|
<option value="flop">Nein</option>
|
||||||
|
<option value="etwas">Teilweise</option>
|
||||||
|
</select>
|
||||||
|
<label for="players">Spieleranzahl:</label>
|
||||||
|
<input type="number" id="players" name="players" required>
|
||||||
|
<label for="time">Uhrzeit:</label>
|
||||||
|
<input type="time" id="time" name="time" required>
|
||||||
|
<label for="weekday">Wochentag:</label>
|
||||||
|
<select id="weekday" name="weekday" required>
|
||||||
|
<option value="Montag">Montag</option>
|
||||||
|
<option value="Dienstag">Dienstag</option>
|
||||||
|
<option value="Mittwoch">Mittwoch</option>
|
||||||
|
<option value="Donnerstag">Donnerstag</option>
|
||||||
|
<option value="Freitag">Freitag</option>
|
||||||
|
<option value="Samstag">Samstag</option>
|
||||||
|
<option value="Sonntag">Sonntag</option>
|
||||||
|
</select>
|
||||||
|
<button type="submit">Event hinzufügen</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="form-container">
|
||||||
|
<h2>Bestes Event berechnen</h2>
|
||||||
|
<form action="{{ url_for('events') }}" method="get" class="events-form-light">
|
||||||
|
<label for="current_players">Aktuelle Spieler:</label>
|
||||||
|
<input type="number" id="current_players" name="current_players" required>
|
||||||
|
<label for="current_time">Aktuelle Uhrzeit:</label>
|
||||||
|
<input type="time" id="current_time" name="current_time" required>
|
||||||
|
<label for="current_weekday">Aktueller Wochentag:</label>
|
||||||
|
<select id="current_weekday" name="current_weekday" required>
|
||||||
|
<option value="Montag">Montag</option>
|
||||||
|
<option value="Dienstag">Dienstag</option>
|
||||||
|
<option value="Mittwoch">Mittwoch</option>
|
||||||
|
<option value="Donnerstag">Donnerstag</option>
|
||||||
|
<option value="Freitag">Freitag</option>
|
||||||
|
<option value="Samstag">Samstag</option>
|
||||||
|
<option value="Sonntag">Sonntag</option>
|
||||||
|
</select>
|
||||||
|
<button type="submit" name="calculate_best" value="1" id="calculateBestEvent">Bestes Event berechnen</button>
|
||||||
|
</form>
|
||||||
|
{% if best_events %}
|
||||||
|
<h2>Top 5 Events</h2>
|
||||||
|
<div id="barChartContainer" style="width:100%;height:260px;display:flex;align-items:end;justify-content:space-around;gap:10px;margin-top:30px;">
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
const bestEvents = {{ best_events|tojson }};
|
||||||
|
const colors = ["#00fff7", "#ff00ff", "#39ff14", "#ffb300", "#ff4d4d"];
|
||||||
|
function animateBars() {
|
||||||
|
const maxRating = Math.max(...bestEvents.map(e => e.rating));
|
||||||
|
const container = document.getElementById('barChartContainer');
|
||||||
|
container.innerHTML = '';
|
||||||
|
bestEvents.forEach((event, idx) => {
|
||||||
|
const bar = document.createElement('div');
|
||||||
|
bar.style.height = '0px';
|
||||||
|
bar.style.width = '60px';
|
||||||
|
bar.style.background = colors[idx % colors.length];
|
||||||
|
bar.style.borderRadius = '8px 8px 0 0';
|
||||||
|
bar.style.display = 'flex';
|
||||||
|
bar.style.flexDirection = 'column';
|
||||||
|
bar.style.alignItems = 'center';
|
||||||
|
bar.style.justifyContent = 'flex-end';
|
||||||
|
bar.style.transition = 'height 1s cubic-bezier(.68,-0.55,.27,1.55)';
|
||||||
|
bar.style.position = 'relative';
|
||||||
|
|
||||||
|
const label = document.createElement('div');
|
||||||
|
label.innerText = event.name;
|
||||||
|
label.style.position = 'absolute';
|
||||||
|
label.style.bottom = '-32px';
|
||||||
|
label.style.width = '100%';
|
||||||
|
label.style.textAlign = 'center';
|
||||||
|
label.style.fontSize = '13px';
|
||||||
|
label.style.color = '#fff';
|
||||||
|
label.style.wordBreak = 'break-word';
|
||||||
|
|
||||||
|
const value = document.createElement('div');
|
||||||
|
value.innerText = event.rating;
|
||||||
|
value.style.position = 'absolute';
|
||||||
|
value.style.top = '-28px';
|
||||||
|
value.style.width = '100%';
|
||||||
|
value.style.textAlign = 'center';
|
||||||
|
value.style.fontWeight = 'bold';
|
||||||
|
value.style.fontSize = '15px';
|
||||||
|
value.style.color = '#fff';
|
||||||
|
|
||||||
|
bar.appendChild(label);
|
||||||
|
bar.appendChild(value);
|
||||||
|
container.appendChild(bar);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
bar.style.height = (event.rating / (maxRating || 1) * 180 + 30) + 'px';
|
||||||
|
}, 100 + idx * 120);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
window.addEventListener('DOMContentLoaded', animateBars);
|
||||||
|
</script>
|
||||||
|
{% elif best_event %}
|
||||||
|
<h2>Bestes Event</h2>
|
||||||
|
<p>{{ best_event.name }} - Rating: {{ best_event.rating }} (Top: {{ best_event.top }}, Flop: {{ best_event.flop }})</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="form-container">
|
||||||
|
<h2>Protokollierte Events</h2>
|
||||||
|
<ul style="list-style-type: none; padding: 0;">
|
||||||
|
{% set event_names = [] %}
|
||||||
|
{% for event in events %}
|
||||||
|
{% if event.name not in event_names %}
|
||||||
|
<li style="background: rgba(255,255,255,0.5); margin: 5px 0; padding: 10px; border-radius: 4px;">{{ event.name }}</li>
|
||||||
|
{% set event_names = event_names.append(event.name) %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="events-back-btn-row">
|
||||||
|
<a href="javascript:window.history.back()" class="events-back-btn-light">Zurück</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
134
Outdated Website/templates/get_data.html
Normal file
|
|
@ -0,0 +1,134 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Daten anzeigen</title>
|
||||||
|
<link rel="stylesheet" href="/static/style.css">
|
||||||
|
<link rel="icon" href="/static/logo.png" type="image/png">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-image: url('/static/background.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
width: 80%;
|
||||||
|
max-width: 800px;
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.content h2 {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.content form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.content form label {
|
||||||
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.content form input,
|
||||||
|
.content form textarea,
|
||||||
|
.content form select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 5px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.content form button {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.content form button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
.search-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.search-bar input {
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.search-bar button {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.search-bar button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
.message {
|
||||||
|
display: none;
|
||||||
|
color: red;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% include "top_bar.html" %}
|
||||||
|
<div class="content">
|
||||||
|
<h2>Daten aus der MongoDB</h2>
|
||||||
|
<div class="search-bar">
|
||||||
|
<input type="text" id="licenseKeyInput" placeholder="License Key einfügen">
|
||||||
|
<button onclick="searchLicenseKey()">Suchen</button>
|
||||||
|
</div>
|
||||||
|
<div class="message" id="message">
|
||||||
|
<img src="/static/red_cross.png" alt="Cross" style="width: 20px; vertical-align: middle;">
|
||||||
|
Der License Key wurde nicht gefunden
|
||||||
|
</div>
|
||||||
|
{% for doc in data %}
|
||||||
|
<form action="{{ url_for('view_license', license_key=doc['license_key']) }}" method="get">
|
||||||
|
<button type="submit">{{ doc['ingame_name'] }}</button>
|
||||||
|
</form>
|
||||||
|
{% endfor %}
|
||||||
|
<a href="/license_keys" class="black-button" style="margin-top: 20px;">Zurück</a>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function searchLicenseKey() {
|
||||||
|
var licenseKey = document.getElementById("licenseKeyInput").value;
|
||||||
|
fetch(`/search_license_key?license_key=${licenseKey}`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.found) {
|
||||||
|
window.location.href = `/license=${licenseKey}`;
|
||||||
|
} else {
|
||||||
|
var message = document.getElementById("message");
|
||||||
|
message.style.display = "block";
|
||||||
|
setTimeout(function() {
|
||||||
|
message.style.display = "none";
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
100
Outdated Website/templates/ip_checker.html
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
{% extends "base_dark.html" %}
|
||||||
|
{% else %}
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% block title %}IP Checker{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="content-wrapper">
|
||||||
|
<div class="form-container" style="max-width: {% if session['theme'] == 'darkmode' %}1000px{% else %}800px{% endif %}; padding: 30px; max-height: 90vh; overflow-y: auto;">
|
||||||
|
<h2>IP Checker</h2>
|
||||||
|
<form method="POST">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<input type="text" name="ip_address" placeholder="IP-Adresse eingeben" required>
|
||||||
|
<br>
|
||||||
|
<label for="is_cheater">Ist diese IP eines Cheaters?</label>
|
||||||
|
<div class="styled-select">
|
||||||
|
<select name="is_cheater" id="is_cheater" required>
|
||||||
|
<option value="no">Nein</option>
|
||||||
|
<option value="yes">Ja</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<input type="text" name="steam_id" id="steam_id" placeholder="SteamID (erforderlich für Cheater)">
|
||||||
|
<br>
|
||||||
|
<div style="display: flex; gap: 20px">
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
<button type="submit" class="neon-button neon1" style="flex: 1;"><span>Prüfen</span></button>
|
||||||
|
<a href="/dashboard" class="neon-button neon3" style="flex: 1; text-align: center;"><span>Zurück</span></a>
|
||||||
|
{% else %}
|
||||||
|
<button type="submit" style="flex: 1; padding: 10px;">Prüfen</button>
|
||||||
|
<a href="/dashboard" class="black-button" style="flex: 1; padding: 10px; text-align: center;">Zurück</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% if error %}
|
||||||
|
<p style="color: red; margin-top: 20px;">{{ error }}</p>
|
||||||
|
{% endif %}
|
||||||
|
{% if ip_data %}
|
||||||
|
<h3 style="margin-top: 30px;">IP-Daten</h3>
|
||||||
|
<table style="width: 100%; border-collapse: collapse; margin-top: 20px;">
|
||||||
|
<tr>
|
||||||
|
<th style="padding: 10px; border: 1px solid #ddd; background-color: #007BFF; color: white;">Feld</th>
|
||||||
|
<th style="padding: 10px; border: 1px solid #ddd; background-color: #007BFF; color: white;">Wert</th>
|
||||||
|
</tr>
|
||||||
|
<tr><td style="padding: 10px; border: 1px solid #ddd;">IP-Adresse</td><td style="padding: 10px; border: 1px solid #ddd;">{{ ip_data.get('ip', 'N/A') }}</td></tr>
|
||||||
|
<tr><td style="padding: 10px; border: 1px solid #ddd;">VPN</td><td style="padding: 10px; border: 1px solid #ddd;">{{ 'Ja' if ip_data['security'].get('vpn', False) else 'Nein' }}</td></tr>
|
||||||
|
<tr><td style="padding: 10px; border: 1px solid #ddd;">Proxy</td><td style="padding: 10px; border: 1px solid #ddd;">{{ 'Ja' if ip_data['security'].get('proxy', False) else 'Nein' }}</td></tr>
|
||||||
|
<tr><td style="padding: 10px; border: 1px solid #ddd;">Tor</td><td style="padding: 10px; border: 1px solid #ddd;">{{ 'Ja' if ip_data['security'].get('tor', False) else 'Nein' }}</td></tr>
|
||||||
|
<tr><td style="padding: 10px; border: 1px solid #ddd;">Land</td><td style="padding: 10px; border: 1px solid #ddd;">{{ ip_data['location'].get('country', 'N/A') }}</td></tr>
|
||||||
|
<tr><td style="padding: 10px; border: 1px solid #ddd;">Stadt</td><td style="padding: 10px; border: 1px solid #ddd;">{{ ip_data['location'].get('city', 'N/A') }}</td></tr>
|
||||||
|
<tr><td style="padding: 10px; border: 1px solid #ddd;">ASN</td><td style="padding: 10px; border: 1px solid #ddd;">{{ ip_data['network'].get('autonomous_system_number', 'N/A') }}</td></tr>
|
||||||
|
<tr><td style="padding: 10px; border: 1px solid #ddd;">Netzwerk</td><td style="padding: 10px; border: 1px solid #ddd;">{{ ip_data['network'].get('network', 'N/A') }}</td></tr>
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
{% if similar_cheater_ips %}
|
||||||
|
<h3 style="margin-top: 30px;">Ähnliche Cheater-IPs</h3>
|
||||||
|
<table style="width: 100%; border-collapse: collapse; margin-top: 20px;">
|
||||||
|
<tr>
|
||||||
|
<th style="padding: 10px; border: 1px solid #ddd; background-color: #007BFF; color: white;">IP-Adresse</th>
|
||||||
|
<th style="padding: 10px; border: 1px solid #ddd; background-color: #007BFF; color: white;">Stadt</th>
|
||||||
|
<th style="padding: 10px; border: 1px solid #ddd; background-color: #007BFF; color: white;">ASN</th>
|
||||||
|
<th style="padding: 10px; border: 1px solid #ddd; background-color: #007BFF; color: white;">SteamID</th>
|
||||||
|
</tr>
|
||||||
|
{% for ip in similar_cheater_ips %}
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 10px; border: 1px solid #ddd;">{{ ip['ip'] }}</td>
|
||||||
|
<td style="padding: 10px; border: 1px solid #ddd;">{{ ip['data']['location'].get('city', 'N/A') }}</td>
|
||||||
|
<td style="padding: 10px; border: 1px solid #ddd;">{{ ip['data']['network'].get('autonomous_system_number', 'N/A') }}</td>
|
||||||
|
<td style="padding: 10px; border: 1px solid #ddd;">{{ ip.get('steam_id', 'N/A') }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
{% if similar_ips|selectattr('is_cheater', 'equalto', True)|list|length > 0 %}
|
||||||
|
<h3 style="margin-top: 30px;">Ähnliche Cheater-IPs</h3>
|
||||||
|
<table style="width: 100%; border-collapse: collapse; margin-top: 20px;">
|
||||||
|
<tr>
|
||||||
|
<th style="padding: 10px; border: 1px solid #ddd; background-color: #007BFF; color: white;">IP-Adresse</th>
|
||||||
|
<th style="padding: 10px; border: 1px solid #ddd; background-color: #007BFF; color: white;">Stadt</th>
|
||||||
|
<th style="padding: 10px; border: 1px solid #ddd; background-color: #007BFF; color: white;">ASN</th>
|
||||||
|
<th style="padding: 10px; border: 1px solid #ddd; background-color: #007BFF; color: white;">SteamID</th>
|
||||||
|
</tr>
|
||||||
|
{% for ip in similar_ips %}
|
||||||
|
{% if ip['is_cheater'] %}
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 10px; border: 1px solid #ddd;">{{ ip['ip'] }}</td>
|
||||||
|
<td style="padding: 10px; border: 1px solid #ddd;">{{ ip['data']['location'].get('city', 'N/A') }}</td>
|
||||||
|
<td style="padding: 10px; border: 1px solid #ddd;">{{ ip['data']['network'].get('autonomous_system_number', 'N/A') }}</td>
|
||||||
|
<td style="padding: 10px; border: 1px solid #ddd;">{{ ip.get('steam_id', 'N/A') }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
148
Outdated Website/templates/license_keys.html
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
{% extends "base_dark.html" %}
|
||||||
|
{% else %}
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% block title %}License Keys{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
<style>
|
||||||
|
.license-container {
|
||||||
|
background: rgba(20, 20, 20, 0.95);
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.7);
|
||||||
|
max-width: 800px;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 300px;
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.license-container form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.license-container form label {
|
||||||
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
color: #00fff7;
|
||||||
|
}
|
||||||
|
.license-container form input,
|
||||||
|
.license-container form textarea,
|
||||||
|
.license-container form select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 5px;
|
||||||
|
border: 1px solid #333;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #222;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.license-btn-row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
margin-top: 20px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.license-btn-row .neon-button {
|
||||||
|
width: 220px;
|
||||||
|
min-width: 120px;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div style="display:flex; flex-direction:column; align-items:center; width:100%;">
|
||||||
|
<div class="license-container">
|
||||||
|
<h2>License Keys</h2>
|
||||||
|
<div class="license-btn-row">
|
||||||
|
{% if 'create_license_key' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('create_license_key') }}" method="get">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="neon-button neon1"><span>License Key erstellen</span></button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
<form action="{{ url_for('get_data') }}" method="get">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="neon-button neon2"><span>Datenbank Einträge</span></button>
|
||||||
|
</form>
|
||||||
|
<form action="{{ url_for('dashboard') }}" method="get">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="neon-button neon3"><span>Zurück</span></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<style>
|
||||||
|
.license-container {
|
||||||
|
background: rgba(255,255,255,0.9);
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||||
|
max-width: 800px;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 300px;
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.license-container form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.license-container form label {
|
||||||
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.license-container form input,
|
||||||
|
.license-container form textarea,
|
||||||
|
.license-container form select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 5px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.license-btn-row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
margin-top: 20px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.license-btn-row button {
|
||||||
|
width: 220px;
|
||||||
|
min-width: 120px;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div style="display:flex; flex-direction:column; align-items:center; width:100%;">
|
||||||
|
<div class="license-container">
|
||||||
|
<h2>License Keys</h2>
|
||||||
|
<div class="license-btn-row">
|
||||||
|
{% if 'create_license_key' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('create_license_key') }}" method="get">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit">License Key erstellen</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
<form action="{{ url_for('get_data') }}" method="get">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit">Datenbank Einträge</button>
|
||||||
|
</form>
|
||||||
|
<form action="{{ url_for('dashboard') }}" method="get">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit">Zurück</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
96
Outdated Website/templates/login.html
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Login</title>
|
||||||
|
<link rel="stylesheet" href="/static/style.css">
|
||||||
|
<link rel="icon" href="/static/logo.png" type="image/png">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-image: url('/static/background.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.login-container {
|
||||||
|
background: rgba(255, 255, 255, 0.6);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
max-width: 400px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.login-container h1 {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.login-container form {
|
||||||
|
margin: 5px 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.login-container form button {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.login-container form button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
.login-container input {
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.error-message {
|
||||||
|
color: red;
|
||||||
|
margin-top: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.error-message img {
|
||||||
|
margin-right: 5px;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="login-container">
|
||||||
|
<h1>Login</h1>
|
||||||
|
<form method="POST" action="{{ url_for('login') }}">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<label for="username">Benutzername:</label>
|
||||||
|
<input type="text" id="username" name="username" value="{{ request.form.username }}" required>
|
||||||
|
<br>
|
||||||
|
<label for="password">Passwort:</label>
|
||||||
|
<input type="password" id="password" name="password" required>
|
||||||
|
<br>
|
||||||
|
<button type="submit">Login</button>
|
||||||
|
</form>
|
||||||
|
{% if error %}
|
||||||
|
<div class="error-message">
|
||||||
|
<img src="/static/red_cross.png" alt="Error">
|
||||||
|
<span>Du hast ein falsches Passwort bzw einen falschen Benutzernamen eingegeben!</span>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
120
Outdated Website/templates/logs.html
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
{% extends "base_dark.html" %}
|
||||||
|
{% else %}
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% block title %}Logs{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
<style>
|
||||||
|
.logs-container {
|
||||||
|
background: rgba(20, 20, 20, 0.95);
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.7);
|
||||||
|
max-width: 800px;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 300px;
|
||||||
|
max-height: 80vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.log-entry {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
margin: 8px 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: rgba(40, 40, 40, 0.9);
|
||||||
|
color: #fff;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.logs-back-btn-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
.logs-back-btn {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
width: auto;
|
||||||
|
padding: 14px 28px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div style="display:flex; flex-direction:column; align-items:center; width:100%;">
|
||||||
|
<div class="logs-back-btn-row">
|
||||||
|
<a href="{{ url_for('dashboard') }}" class="neon-button neon3 logs-back-btn"><span>Zurück</span></a>
|
||||||
|
</div>
|
||||||
|
<div class="logs-container">
|
||||||
|
<h2>Logs</h2>
|
||||||
|
{% for log in logs %}
|
||||||
|
<div class="log-entry">
|
||||||
|
<p><strong>Datum:</strong> {{ log.timestamp.strftime('%Y-%m-%d %H:%M:%S') }}</p>
|
||||||
|
<p><strong>Nachricht:</strong> {{ log.message }}</p>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<style>
|
||||||
|
.logs-container {
|
||||||
|
background: rgba(255,255,255,0.9);
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||||
|
max-width: 800px;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 300px;
|
||||||
|
max-height: 80vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.log-entry {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
margin: 8px 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: rgba(180, 180, 180, 0.9);
|
||||||
|
color: #333;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.logs-back-btn-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
.logs-back-btn {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
width: auto;
|
||||||
|
text-align: center;
|
||||||
|
display: inline-block;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.logs-back-btn:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div style="display:flex; flex-direction:column; align-items:center; width:100%;">
|
||||||
|
<div class="logs-back-btn-row">
|
||||||
|
<a href="{{ url_for('dashboard') }}" class="logs-back-btn">Zurück</a>
|
||||||
|
</div>
|
||||||
|
<div class="logs-container">
|
||||||
|
<h2>Logs</h2>
|
||||||
|
{% for log in logs %}
|
||||||
|
<div class="log-entry">
|
||||||
|
<p><strong>Datum:</strong> {{ log.timestamp.strftime('%Y-%m-%d %H:%M:%S') }}</p>
|
||||||
|
<p><strong>Nachricht:</strong> {{ log.message }}</p>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
29
Outdated Website/templates/robots.txt
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
User-agent: MSNBot
|
||||||
|
Disallow: /
|
||||||
|
User-agent: Slurp
|
||||||
|
Disallow: /
|
||||||
|
User-agent: Teoma
|
||||||
|
Disallow: /
|
||||||
|
User-agent: Gigabot
|
||||||
|
Disallow: /
|
||||||
|
User-agent: Robozilla
|
||||||
|
Disallow: /
|
||||||
|
User-agent: Nutch
|
||||||
|
Disallow: /
|
||||||
|
User-agent: ia_archiver
|
||||||
|
Disallow: /
|
||||||
|
User-agent: baiduspider
|
||||||
|
Disallow: /
|
||||||
|
User-agent: naverbot
|
||||||
|
Disallow: /
|
||||||
|
User-agent: yeti
|
||||||
|
Disallow: /
|
||||||
|
User-agent: yahoo-mmcrawler
|
||||||
|
Disallow: /
|
||||||
|
User-agent: psbot
|
||||||
|
Disallow: /
|
||||||
|
User-agent: yahoo-blogs/v3.9
|
||||||
|
Disallow: /
|
||||||
|
User-agent: *
|
||||||
|
Disallow:
|
||||||
|
Disallow: /static
|
||||||
91
Outdated Website/templates/test.css
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
:root {
|
||||||
|
--clr-one: rgb(255, 20, 147);
|
||||||
|
--clr-two: rgb(127, 255, 0);
|
||||||
|
--clr-three: rgb(138, 43, 226);
|
||||||
|
--clr-bg: #1d1e22;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
background: var(--clr-bg);
|
||||||
|
font-family: "Balsamiq Sans", cursive;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, p {
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 1rem;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon-button {
|
||||||
|
font-size: 1rem;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 0.75em 1.5em;
|
||||||
|
border-radius: 0.25em;
|
||||||
|
position: relative;
|
||||||
|
transition: 0.3s ease;
|
||||||
|
background: transparent;
|
||||||
|
color: inherit;
|
||||||
|
font-weight: bold;
|
||||||
|
text-shadow: 0 0 0.5em currentColor;
|
||||||
|
border: 2px solid currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Farben */
|
||||||
|
.neon-button__1 {
|
||||||
|
color: var(--clr-one);
|
||||||
|
box-shadow: 0 0 0.6em var(--clr-one);
|
||||||
|
}
|
||||||
|
.neon-button__2 {
|
||||||
|
color: var(--clr-two);
|
||||||
|
box-shadow: 0 0 0.6em var(--clr-two);
|
||||||
|
}
|
||||||
|
.neon-button__3 {
|
||||||
|
color: var(--clr-three);
|
||||||
|
box-shadow: 0 0 0.6em var(--clr-three);
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon-button:hover,
|
||||||
|
.neon-button:focus {
|
||||||
|
background-color: currentColor;
|
||||||
|
color: #000;
|
||||||
|
text-shadow: none;
|
||||||
|
box-shadow:
|
||||||
|
0 0 0.7em currentColor,
|
||||||
|
0 0 1.5em currentColor,
|
||||||
|
inset 0 0 1em currentColor;
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon-button:active {
|
||||||
|
animation: bounce 0.4s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bounce {
|
||||||
|
0% { transform: translateY(0); }
|
||||||
|
50% { transform: translateY(-8px); }
|
||||||
|
100% { transform: translateY(0); }
|
||||||
|
}
|
||||||
78
Outdated Website/templates/top_bar.html
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
<div class="top-bar">
|
||||||
|
<div class="logo">
|
||||||
|
<img src="/static/logo.png" alt="Logo">
|
||||||
|
</div>
|
||||||
|
<div class="title">MrSniff's Admin-Tools Dashboard</div>
|
||||||
|
<div class="user-info">
|
||||||
|
<div class="username">
|
||||||
|
<span>{{ session['username'] }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="profile-picture">
|
||||||
|
<img src="/static/pfps/{{ session['user_id'] }}.png?t={{ session.get('pfp_last_updated', 0) }}"
|
||||||
|
alt="Profilbild"
|
||||||
|
onerror="this.onerror=null; this.src='/static/user_small.png';"
|
||||||
|
style="width: 40px; height: 40px; border-radius: 50%; object-fit: cover;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.top-bar {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #42028B;
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10px 20px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-bar .logo img {
|
||||||
|
height: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-bar .title {
|
||||||
|
flex-grow: 1;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-bar .user-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-bar .user-info .username {
|
||||||
|
font-size: 18px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: visible;
|
||||||
|
text-overflow: clip;
|
||||||
|
max-width: none;
|
||||||
|
margin-right: 10px; /* Abstand zwischen Name und Bild */
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-bar .user-info .profile-picture img {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.top-bar .user-info {
|
||||||
|
max-width: 25%;
|
||||||
|
justify-content: flex-end; /* Benutzerinfo rechts ausrichten */
|
||||||
|
}
|
||||||
|
.top-bar .user-info .username {
|
||||||
|
text-align: right;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
178
Outdated Website/templates/ui.html
Normal file
|
|
@ -0,0 +1,178 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>ScytheNet</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #000;
|
||||||
|
color: #fff;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
.logo {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #fff;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #333;
|
||||||
|
display: inline-block;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.logo span {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
.sidebar {
|
||||||
|
width: 200px;
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding-top: 20px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.sidebar button {
|
||||||
|
background-color: #333;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
padding: 15px;
|
||||||
|
font-size: 18px;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
text-align: left;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.sidebar button:hover {
|
||||||
|
background-color: #9c149c;
|
||||||
|
}
|
||||||
|
.sidebar button.active {
|
||||||
|
background-color: #9c149c;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
flex: 1;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #222;
|
||||||
|
}
|
||||||
|
.button {
|
||||||
|
background-color: #9c149c;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 15px 20px;
|
||||||
|
font-size: 18px;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-top: 20px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.button:hover {
|
||||||
|
background-color: #9c149c;
|
||||||
|
}
|
||||||
|
input, label {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 10px 0;
|
||||||
|
font-size: 16px;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
color: #ecf0f1;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
.emoji {
|
||||||
|
font-size: 24px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="sidebar">
|
||||||
|
<div class="logo" onclick="showDashboard()">Scythe<span>NET</span></div>
|
||||||
|
<button onclick="showDashboard()" id="dashboardBtn">🖥️ Dashboard</button>
|
||||||
|
<button onclick="showAPI()" id="apiBtn">🔑 API</button>
|
||||||
|
<button onclick="showAttack()" id="attackBtn">💥 Attack</button>
|
||||||
|
</div>
|
||||||
|
<div class="content" id="content">
|
||||||
|
<h1>Willkommen bei ScytheNet</h1>
|
||||||
|
<p>Wählen Sie eine Option aus der Seitenleiste</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function resetActiveButtons() {
|
||||||
|
document.querySelectorAll('.sidebar button').forEach(button => {
|
||||||
|
button.classList.remove('active');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showDashboard() {
|
||||||
|
resetActiveButtons();
|
||||||
|
document.getElementById('dashboardBtn').classList.add('active');
|
||||||
|
document.getElementById('content').innerHTML = `
|
||||||
|
<h1>Dashboard</h1>
|
||||||
|
<p>Online Nutzer: <span id="online_count">-</span></p>
|
||||||
|
<p>Weltkarte: 🌍</p>
|
||||||
|
<p>Pakete gesendet: 0</p>
|
||||||
|
<p>Pakete empfangen: 0</p>
|
||||||
|
<button class="button" onclick="fetchOnlineCount()">Online abrufen</button>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showAPI() {
|
||||||
|
resetActiveButtons();
|
||||||
|
document.getElementById('apiBtn').classList.add('active');
|
||||||
|
document.getElementById('content').innerHTML = `
|
||||||
|
<h1>API Einstellungen</h1>
|
||||||
|
<label for="api_key">API Key:</label>
|
||||||
|
<input type="text" id="api_key" placeholder="Geben Sie Ihren API Key ein">
|
||||||
|
<button class="button" onclick="saveAPIKey()">Speichern</button>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showAttack() {
|
||||||
|
resetActiveButtons();
|
||||||
|
document.getElementById('attackBtn').classList.add('active');
|
||||||
|
document.getElementById('content').innerHTML = `
|
||||||
|
<h1>Angriff</h1>
|
||||||
|
<label for="ip">IP-Adresse:</label>
|
||||||
|
<input type="text" id="ip" placeholder="Geben Sie die IP-Adresse ein">
|
||||||
|
<label for="port">Port:</label>
|
||||||
|
<input type="text" id="port" placeholder="Geben Sie den Port ein">
|
||||||
|
<label for="duration">Dauer:</label>
|
||||||
|
<input type="text" id="duration" placeholder="Geben Sie die Dauer ein">
|
||||||
|
<button class="button" onclick="startAttack()">Angriff starten</button>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchOnlineCount() {
|
||||||
|
fetch('http://localhost:8081/online')
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(data => {
|
||||||
|
document.getElementById('online_count').innerText = data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveAPIKey() {
|
||||||
|
const apiKey = document.getElementById('api_key').value;
|
||||||
|
// Hier würde dein C-Backend aufgerufen, um den API-Schlüssel zu speichern.
|
||||||
|
alert('API Key gespeichert: ' + apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
function startAttack() {
|
||||||
|
const ip = document.getElementById('ip').value;
|
||||||
|
const port = document.getElementById('port').value;
|
||||||
|
const duration = document.getElementById('duration').value;
|
||||||
|
// Hier würde dein C-Backend aufgerufen, um den Angriff zu starten.
|
||||||
|
alert('Angriff auf ' + ip + ':' + port + ' für ' + duration + ' Sekunden gestartet!');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
490
Outdated Website/templates/user_management.html
Normal file
|
|
@ -0,0 +1,490 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
{% extends "base_dark.html" %}
|
||||||
|
{% else %}
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% block title %}User Management{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="form-container" style="max-width: 1100px; max-height: 80vh; overflow-y: auto; margin-top: 30px;">
|
||||||
|
<h2>User Management</h2>
|
||||||
|
<style>
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
th, td {
|
||||||
|
padding: 10px;
|
||||||
|
text-align: left;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
th:first-child {
|
||||||
|
width: 60px;
|
||||||
|
}
|
||||||
|
td:first-child {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.profile-pic-small {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
object-fit: cover;
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
.permission-box {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
margin: 5px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
font-size: 14px;
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
color: #000;
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
.permission-box img {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
.dropdown-container {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
.add-permission {
|
||||||
|
background-color: #28a745;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 5px 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 1;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
height: 38px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.add-permission:hover {
|
||||||
|
background-color: #218838;
|
||||||
|
}
|
||||||
|
.dropdown {
|
||||||
|
position: absolute;
|
||||||
|
min-width: 180px;
|
||||||
|
box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.2);
|
||||||
|
z-index: 1000;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-top: 5px;
|
||||||
|
left: 0;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
max-height: 0;
|
||||||
|
opacity: 0;
|
||||||
|
transition: max-height 0.3s ease-out, opacity 0.3s ease-out;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
.dropdown {
|
||||||
|
background-color: #333;
|
||||||
|
border: 1px solid #555;
|
||||||
|
}
|
||||||
|
.dropdown a {
|
||||||
|
color: #f9f9f9;
|
||||||
|
}
|
||||||
|
.dropdown a:hover {
|
||||||
|
background-color: #555;
|
||||||
|
box-shadow: 0 0 5px #00fff7, 0 0 10px #00fff7;
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
.dropdown a {
|
||||||
|
color: black;
|
||||||
|
padding: 10px 15px;
|
||||||
|
text-decoration: none;
|
||||||
|
display: block;
|
||||||
|
transition: background-color 0.2s ease, color 0.2s ease;
|
||||||
|
}
|
||||||
|
.dropdown-container:hover .dropdown {
|
||||||
|
max-height: 300px;
|
||||||
|
opacity: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.dropdown a:hover {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
}
|
||||||
|
.neon-button {
|
||||||
|
width: auto;
|
||||||
|
min-width: 150px;
|
||||||
|
padding: 14px 20px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: bold;
|
||||||
|
border: 2px solid;
|
||||||
|
color: inherit;
|
||||||
|
background: transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: 0.3s;
|
||||||
|
box-shadow: 0 0 8px currentColor, 0 0 14px currentColor inset;
|
||||||
|
margin: 10px 0;
|
||||||
|
border-radius: 6px;
|
||||||
|
text-align: center;
|
||||||
|
height: 38px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon1 { color: #00fff7; border-color: #00fff7; }
|
||||||
|
.neon2 { color: #ff00ff; border-color: #ff00ff; }
|
||||||
|
.neon3 { color: #39ff14; border-color: #39ff14; }
|
||||||
|
|
||||||
|
.neon-button::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0; left: 0;
|
||||||
|
width: 100%; height: 100%;
|
||||||
|
background: currentColor;
|
||||||
|
z-index: 0;
|
||||||
|
transform: scaleX(0);
|
||||||
|
transform-origin: left;
|
||||||
|
transition: 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon-button:hover::before {
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon-button span {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
transition: color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neon-button:hover span {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.standard-button {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 10px 0;
|
||||||
|
min-width: 150px;
|
||||||
|
text-align: center;
|
||||||
|
transition: background 0.2s;
|
||||||
|
height: 38px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.standard-button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-user-form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
background: rgba(255,255,255,0.7);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 20px 24px 10px 24px;
|
||||||
|
margin-top: 20px;
|
||||||
|
max-width: 400px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.07);
|
||||||
|
}
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
.add-user-form {
|
||||||
|
background: rgba(40,40,40,0.85);
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
.add-user-form label,
|
||||||
|
.add-user-form input {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.add-user-form input[type="text"],
|
||||||
|
.add-user-form input[type="password"] {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.add-user-form button {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
align-self: center;
|
||||||
|
min-width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0; left: 0; right: 0; bottom: 0;
|
||||||
|
background: rgba(0,0,0,0.45);
|
||||||
|
z-index: 9999;
|
||||||
|
display: none;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.popup-content {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 32px 28px 22px 28px;
|
||||||
|
box-shadow: 0 4px 24px rgba(0,0,0,0.18);
|
||||||
|
text-align: center;
|
||||||
|
max-width: 340px;
|
||||||
|
min-width: 260px;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
.popup-content h3 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
font-size: 1.3em;
|
||||||
|
color: #dc3545;
|
||||||
|
}
|
||||||
|
.popup-content p {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.popup-btn-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 18px;
|
||||||
|
}
|
||||||
|
.popup-btn-cancel, .popup-btn-confirm {
|
||||||
|
min-width: 90px;
|
||||||
|
padding: 8px 0;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: bold;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
.popup-btn-cancel {
|
||||||
|
background: #e0e0e0;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.popup-btn-cancel:hover {
|
||||||
|
background: #bdbdbd;
|
||||||
|
}
|
||||||
|
.popup-btn-confirm {
|
||||||
|
background: #dc3545;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.popup-btn-confirm:hover {
|
||||||
|
background: #b52a37;
|
||||||
|
}
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
.popup-content {
|
||||||
|
background: #232323;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.popup-content p {
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
.popup-btn-cancel {
|
||||||
|
background: #444;
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
.popup-btn-cancel:hover {
|
||||||
|
background: #222;
|
||||||
|
}
|
||||||
|
.popup-btn-confirm {
|
||||||
|
background: #b52a37;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.popup-btn-confirm:hover {
|
||||||
|
background: #dc3545;
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
document.querySelectorAll('form[data-confirm="delete-user"]').forEach(function(form) {
|
||||||
|
form.addEventListener('submit', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const username = form.getAttribute('data-username');
|
||||||
|
showDeletePopup(form, username);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function showDeletePopup(form, username) {
|
||||||
|
let overlay = document.getElementById('delete-popup-overlay');
|
||||||
|
if (!overlay) {
|
||||||
|
overlay = document.createElement('div');
|
||||||
|
overlay.className = 'popup-overlay';
|
||||||
|
overlay.id = 'delete-popup-overlay';
|
||||||
|
overlay.innerHTML = `
|
||||||
|
<div class="popup-content">
|
||||||
|
<h3>Account löschen?</h3>
|
||||||
|
<p>Bist du dir sicher, dass der Account <b id="popup-username"></b> gelöscht werden soll?<br>Diese Aktion kann nicht rückgängig gemacht werden.</p>
|
||||||
|
<div class="popup-btn-row">
|
||||||
|
<button class="popup-btn-cancel" type="button">Abbrechen</button>
|
||||||
|
<button class="popup-btn-confirm" type="button">Löschen</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.body.appendChild(overlay);
|
||||||
|
}
|
||||||
|
overlay.style.display = 'flex';
|
||||||
|
overlay.querySelector('#popup-username').textContent = username;
|
||||||
|
|
||||||
|
const cancelBtn = overlay.querySelector('.popup-btn-cancel');
|
||||||
|
const confirmBtn = overlay.querySelector('.popup-btn-confirm');
|
||||||
|
|
||||||
|
// Remove previous listeners
|
||||||
|
cancelBtn.onclick = function() {
|
||||||
|
overlay.style.display = 'none';
|
||||||
|
};
|
||||||
|
confirmBtn.onclick = function() {
|
||||||
|
overlay.style.display = 'none';
|
||||||
|
form.submit();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>PFPs</th> <th>Username</th>
|
||||||
|
<th>Display Name</th>
|
||||||
|
<th>Perms</th>
|
||||||
|
<th>Aktionen</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for user in users %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<img src="/static/pfps/{{ user['_id'] }}.png?t={{ user.get('website_accounts', {}).get('pfp_last_updated', 0) }}"
|
||||||
|
alt="Profilbild"
|
||||||
|
onerror="this.onerror=null; this.src='/static/user_small.png';"
|
||||||
|
class="profile-pic-small">
|
||||||
|
</td>
|
||||||
|
<td>{{ user['username'] }}</td>
|
||||||
|
<td>{{ user['display_name'] }}</td>
|
||||||
|
<td>
|
||||||
|
<div style="display: flex; flex-wrap: wrap;">
|
||||||
|
{% for permission in user['permissions'] %}
|
||||||
|
<div class="permission-box">
|
||||||
|
{{ permission }}
|
||||||
|
{% if user['username'] != session['username'] and permission in session.get('permissions', []) %}
|
||||||
|
<form action="{{ url_for('change_permissions', user_id=user['_id']) }}" method="post" style="display:inline;">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<input type="hidden" name="remove_permission" value="{{ permission }}">
|
||||||
|
<img src="/static/red_cross.png" alt="Remove" onclick="this.parentElement.submit()">
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if user['username'] != session['username'] %}
|
||||||
|
<div class="dropdown-container">
|
||||||
|
<button class="add-permission">+</button>
|
||||||
|
<div class="dropdown">
|
||||||
|
{% for permission_option in ['user_management', 'permission_management', 'delete_requests', 'logs', 'create_license_key', 'view_license_keys', 'create_event_feedback', 'view_event_feedback', 'discord_bots', 'verify_age', 'events', 'project_manager', 'intranet', 'ip_checker', 'changelogs', 'appointments'] %}
|
||||||
|
{% if permission_option not in user['permissions'] and permission_option in session.get('permissions', []) %}
|
||||||
|
{% if permission_option in ['user_management', 'permission_management'] %}
|
||||||
|
{% if 'System' in session.get('permissions', []) %}
|
||||||
|
<a href="#" onclick="event.preventDefault(); document.getElementById('add-permission-{{ user['_id'] }}-{{ permission_option }}').submit();">{{ permission_option }}</a>
|
||||||
|
<form id="add-permission-{{ user['_id'] }}-{{ permission_option }}" action="{{ url_for('change_permissions', user_id=user['_id']) }}" method="post" style="display:none;">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<input type="hidden" name="add_permission" value="{{ permission_option }}">
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<a href="#" onclick="event.preventDefault(); document.getElementById('add-permission-{{ user['_id'] }}-{{ permission_option }}').submit();">{{ permission_option }}</a>
|
||||||
|
<form id="add-permission-{{ user['_id'] }}-{{ permission_option }}" action="{{ url_for('change_permissions', user_id=user['_id']) }}" method="post" style="display:none;">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<input type="hidden" name="add_permission" value="{{ permission_option }}">
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if user['username'] != session['username'] %}
|
||||||
|
{% set current_user_permissions = session.get('permissions', []) %}
|
||||||
|
{% if 'permission_management' in current_user_permissions and 'permission_management' in user['permissions'] and session['username'] != 'MrSniff' %}
|
||||||
|
Keine Aktionen verfügbar
|
||||||
|
{% else %}
|
||||||
|
<form action="{{ url_for('edit_user', user_id=user['_id']) }}" method="get" style="display:inline;">
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
<button type="submit" class="neon-button neon1" style="min-width: 80px; padding: 8px 12px; font-size: 14px;"><span>Edit</span></button>
|
||||||
|
{% else %}
|
||||||
|
<button type="submit" class="standard-button" style="min-width: 80px; padding: 8px 12px; font-size: 14px;">Edit</button>
|
||||||
|
{% endif %}
|
||||||
|
</form>
|
||||||
|
<form action="{{ url_for('delete_user', user_id=user['_id']) }}" method="post" style="display:inline;" data-confirm="delete-user" data-username="{{ user['username'] }}">
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
<button type="submit" class="neon-button neon3" style="min-width: 80px; padding: 8px 12px; font-size: 14px;"><span>Delete</span></button>
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
{% else %}
|
||||||
|
<button type="submit" class="standard-button" style="min-width: 80px; padding: 8px 12px; font-size: 14px; background-color: #dc3545; border-color: #dc3545;">Delete</button>
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
{% endif %}
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
Keine Aktionen verfügbar
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<form action="{{ url_for('add_user') }}" method="post" class="add-user-form">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<label for="new_username">Username:</label>
|
||||||
|
<input type="text" id="new_username" name="username" required>
|
||||||
|
<label for="new_display_name">Display Name:</label>
|
||||||
|
<input type="text" id="new_display_name" name="display_name" required>
|
||||||
|
<label for="new_password">Passwort:</label>
|
||||||
|
<input type="password" id="new_password" name="password" required>
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
<button type="submit" class="neon-button neon1"><span>Hinzufügen</span></button>
|
||||||
|
{% else %}
|
||||||
|
<button type="submit" class="standard-button">Hinzufügen</button>
|
||||||
|
{% endif %}
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
<a href="/dashboard" class="neon-button neon3" style="display:inline-block; margin-top: 20px; margin-left: 0; padding: 12px 20px; line-height: 1.5;"><span>Zurück</span></a>
|
||||||
|
{% else %}
|
||||||
|
<a href="/dashboard" class="standard-button" style="display:inline-block; margin-top: 20px; margin-left: 0; padding: 12px 15px;">Zurück</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
285
Outdated Website/templates/verify_age.html
Normal file
|
|
@ -0,0 +1,285 @@
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
{% extends "base_dark.html" %}
|
||||||
|
{% else %}
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% block title %}Altersüberprüfung{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 40px;
|
||||||
|
margin: auto;
|
||||||
|
margin-top: 100px;
|
||||||
|
}
|
||||||
|
.form-container, .search-container {
|
||||||
|
background: rgba(30, 30, 30, 0.95);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.5);
|
||||||
|
max-width: 500px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.form-container h1, .search-container h1 {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.form-container form, .search-container form {
|
||||||
|
margin: 5px 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.form-container form button, .search-container form button {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.form-container input, .search-container input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 5px 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #444;
|
||||||
|
background: #222;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.result {
|
||||||
|
font-size: 1.5em;
|
||||||
|
color: #0ff;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.user-list {
|
||||||
|
margin-top: 20px;
|
||||||
|
width: 100%;
|
||||||
|
max-height: 400px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.user-list button {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.back-btn-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
.back-button-dark {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
width: auto;
|
||||||
|
padding: 14px 28px;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="form-container">
|
||||||
|
<h1>Altersüberprüfung</h1>
|
||||||
|
<form method="POST">
|
||||||
|
<label for="birthdate">Geburtsdatum:</label>
|
||||||
|
<input type="date" id="birthdate" name="birthdate" value="{{ request.form.birthdate }}" required>
|
||||||
|
<br>
|
||||||
|
<label for="steam_id">SteamID:</label>
|
||||||
|
<input type="text" id="steam_id" name="steam_id" value="{{ request.form.steam_id }}" required>
|
||||||
|
<br>
|
||||||
|
<label for="ingame_name">Ingame Name:</label>
|
||||||
|
<input type="text" id="ingame_name" name="ingame_name" value="{{ request.form.ingame_name }}" required>
|
||||||
|
<br>
|
||||||
|
<button type="submit" class="neon-button neon1"><span>Überprüfen</span></button>
|
||||||
|
</form>
|
||||||
|
{% if age is not none %}
|
||||||
|
<p class="result">Die Person ist {{ age }} Jahre alt.</p>
|
||||||
|
{% if age < 13 %}
|
||||||
|
<p class="result">Diese Person muss für {{ (birthdate_dt.replace(year=birthdate_dt.year + 13) - today).days }} Tage gebannt werden.</p>
|
||||||
|
{% else %}
|
||||||
|
<p class="result">Diese Person muss nicht gebannt werden.</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="search-container">
|
||||||
|
<h1>Benutzer suchen</h1>
|
||||||
|
<form method="GET">
|
||||||
|
<input type="text" name="search" placeholder="Suche nach Ingame Name oder SteamID" value="{{ request.args.search }}">
|
||||||
|
<button type="submit" class="neon-button neon2"><span>Suchen</span></button>
|
||||||
|
</form>
|
||||||
|
<div class="user-list">
|
||||||
|
{% for user in users %}
|
||||||
|
<form action="{{ url_for('view_user_age', user_id=user._id) }}" method="get">
|
||||||
|
<button type="submit" class="neon-button neon1"><span>{{ user.ingame_name }}</span></button>
|
||||||
|
</form>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="back-btn-row">
|
||||||
|
<a href="{{ url_for('dashboard') }}" class="neon-button neon3 back-button-dark"><span>Zurück</span></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Altersüberprüfung</title>
|
||||||
|
<link rel="stylesheet" href="/static/style.css">
|
||||||
|
<link rel="icon" href="/static/logo.png" type="image/png">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-image: url('/static/background.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 40px;
|
||||||
|
margin: auto;
|
||||||
|
margin-top: 150px;
|
||||||
|
}
|
||||||
|
.form-container, .search-container {
|
||||||
|
background: rgba(255, 255, 255, 0.6);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
max-width: 500px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.form-container h1, .search-container h1 {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.form-container form, .search-container form {
|
||||||
|
margin: 5px 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.form-container form button, .search-container form button {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.form-container form button:hover, .search-container form button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
.form-container input, .search-container input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 5px 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
.result {
|
||||||
|
font-size: 1.5em;
|
||||||
|
color: #333;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.user-list {
|
||||||
|
margin-top: 20px;
|
||||||
|
width: 100%;
|
||||||
|
max-height: 400px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.user-list button {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.user-list button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
.back-btn-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
.back-button {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
width: auto;
|
||||||
|
margin-top: 0;
|
||||||
|
text-align: center;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.back-button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% include "top_bar.html" %}
|
||||||
|
<div class="container">
|
||||||
|
<div class="form-container">
|
||||||
|
<h1>Altersüberprüfung</h1>
|
||||||
|
<form method="POST">
|
||||||
|
<label for="birthdate">Geburtsdatum:</label>
|
||||||
|
<input type="date" id="birthdate" name="birthdate" value="{{ request.form.birthdate }}" required>
|
||||||
|
<br>
|
||||||
|
<label for="steam_id">SteamID:</label>
|
||||||
|
<input type="text" id="steam_id" name="steam_id" value="{{ request.form.steam_id }}" required>
|
||||||
|
<br>
|
||||||
|
<label for="ingame_name">Ingame Name:</label>
|
||||||
|
<input type="text" id="ingame_name" name="ingame_name" value="{{ request.form.ingame_name }}" required>
|
||||||
|
<br>
|
||||||
|
<button type="submit">Überprüfen</button>
|
||||||
|
</form>
|
||||||
|
{% if age is not none %}
|
||||||
|
<p class="result">Die Person ist {{ age }} Jahre alt.</p>
|
||||||
|
{% if age < 13 %}
|
||||||
|
<p class="result">Diese Person muss für {{ (birthdate_dt.replace(year=birthdate_dt.year + 13) - today).days }} Tage gebannt werden.</p>
|
||||||
|
{% else %}
|
||||||
|
<p class="result">Diese Person muss nicht gebannt werden.</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="search-container">
|
||||||
|
<h1>Benutzer suchen</h1>
|
||||||
|
<form method="GET">
|
||||||
|
<input type="text" name="search" placeholder="Suche nach Ingame Name oder SteamID" value="{{ request.args.search }}">
|
||||||
|
<button type="submit">Suchen</button>
|
||||||
|
</form>
|
||||||
|
<div class="user-list">
|
||||||
|
{% for user in users %}
|
||||||
|
<form action="{{ url_for('view_user_age', user_id=user._id) }}" method="get">
|
||||||
|
<button type="submit">{{ user.ingame_name }}</button>
|
||||||
|
</form>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="back-btn-row">
|
||||||
|
<a href="{{ url_for('dashboard') }}" class="back-button">Zurück</a>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
169
Outdated Website/templates/view_changelogs.html
Normal file
|
|
@ -0,0 +1,169 @@
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
{% extends "base_dark.html" %}
|
||||||
|
{% else %}
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% block title %}Changelogs{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
<style>
|
||||||
|
.changelog-list-outer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 60px;
|
||||||
|
}
|
||||||
|
.changelog-list-container {
|
||||||
|
background: rgba(20, 20, 20, 0.95);
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.7);
|
||||||
|
max-width: 700px;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 300px;
|
||||||
|
max-height: 500px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.changelog-list-container h2 {
|
||||||
|
color: #00fff7;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.changelog-item {
|
||||||
|
background: rgba(40, 40, 40, 0.9);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
padding: 14px 18px;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: left;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
.changelog-item .timestamp {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #aaa;
|
||||||
|
align-self: flex-end;
|
||||||
|
margin-bottom: -4px;
|
||||||
|
}
|
||||||
|
.changelog-item .message {
|
||||||
|
font-size: 15px;
|
||||||
|
color: #ddd;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
.back-btn-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
.back-button-dark {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
width: auto;
|
||||||
|
padding: 14px 28px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="changelog-list-outer">
|
||||||
|
<div class="back-btn-row">
|
||||||
|
<a href="{{ url_for('dashboard') }}" class="neon-button neon3 back-button-dark"><span>Zurück</span></a>
|
||||||
|
</div>
|
||||||
|
<div class="changelog-list-container">
|
||||||
|
<h2>Website Changelogs</h2>
|
||||||
|
{% for changelog in changelogs %}
|
||||||
|
<div class="changelog-item">
|
||||||
|
<span class="timestamp">{{ changelog.timestamp }}</span>
|
||||||
|
<div class="message">{{ changelog.text }}</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<style>
|
||||||
|
.changelog-list-outer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 60px;
|
||||||
|
}
|
||||||
|
.changelog-list-container {
|
||||||
|
background: rgba(255,255,255,0.9);
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||||
|
max-width: 700px;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 300px;
|
||||||
|
max-height: 500px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.changelog-list-container h2 {
|
||||||
|
color: #007BFF;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.changelog-item {
|
||||||
|
background: rgba(180, 180, 180, 0.9);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
padding: 14px 18px;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: left;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
color: #333;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
.changelog-item .timestamp {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #555;
|
||||||
|
align-self: flex-end;
|
||||||
|
margin-bottom: -4px;
|
||||||
|
}
|
||||||
|
.changelog-item .message {
|
||||||
|
font-size: 15px;
|
||||||
|
color: #333;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
.back-btn-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
.back-button {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
width: auto;
|
||||||
|
text-align: center;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.back-button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="changelog-list-outer">
|
||||||
|
<div class="back-btn-row">
|
||||||
|
<a href="{{ url_for('dashboard') }}" class="back-button">Zurück</a>
|
||||||
|
</div>
|
||||||
|
<div class="changelog-list-container">
|
||||||
|
<h2>Website Changelogs</h2>
|
||||||
|
{% for changelog in changelogs %}
|
||||||
|
<div class="changelog-item">
|
||||||
|
<span class="timestamp">{{ changelog.timestamp }}</span>
|
||||||
|
<div class="message">{{ changelog.text }}</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
82
Outdated Website/templates/view_event_feedback.html
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Event Feedback</title>
|
||||||
|
<link rel="stylesheet" href="/static/style.css">
|
||||||
|
<link rel="icon" href="/static/logo.png" type="image/png">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-image: url('/static/background.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
background: rgba(255, 255, 255, 0.6);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
max-width: 350px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.content h1 {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.content form {
|
||||||
|
margin: 5px 0; /* Verringere den Abstand */
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.content form button {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 5px; /* Verringere den Abstand */
|
||||||
|
}
|
||||||
|
.content form button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
.content a {
|
||||||
|
margin: 5px 0; /* Verringere den Abstand */
|
||||||
|
text-decoration: none;
|
||||||
|
color: #007BFF;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px 15px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.content a:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% include "top_bar.html" %}
|
||||||
|
<div class="content">
|
||||||
|
<h1>Event Feedback</h1>
|
||||||
|
<p><strong>Event:</strong> {{ feedback.event_name }}</p>
|
||||||
|
<p><strong>Verlauf des Events:</strong> {{ feedback.event_progress }}</p>
|
||||||
|
<p><strong>Ende des Events:</strong> {{ feedback.event_end }}</p>
|
||||||
|
<p><strong>Feedback der Community:</strong> {{ feedback.community_feedback }}</p>
|
||||||
|
<p><strong>Abgegeben von:</strong> {{ feedback.username }}</p>
|
||||||
|
<p><strong>Datum:</strong> {{ feedback.timestamp.strftime('%Y-%m-%d %H:%M:%S') }}</p>
|
||||||
|
<form action="{{ url_for('view_event_feedbacks') }}" method="get">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit">Zurück</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
80
Outdated Website/templates/view_event_feedbacks.html
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Event Feedbacks</title>
|
||||||
|
<link rel="stylesheet" href="/static/style.css">
|
||||||
|
<link rel="icon" href="/static/logo.png" type="image/png">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-image: url('/static/background.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
width: 80%;
|
||||||
|
max-width: 800px;
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.feedback-entry {
|
||||||
|
background: rgba(255, 255, 255, 0.6);
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.feedback-entry h3 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
.feedback-entry p {
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
.content form button {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.content form button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% include "top_bar.html" %}
|
||||||
|
<div class="content">
|
||||||
|
<h2>Event Feedbacks</h2>
|
||||||
|
{% for feedback in feedbacks %}
|
||||||
|
<div class="feedback-entry">
|
||||||
|
<h3>{{ feedback.event_name }}</h3>
|
||||||
|
<p><strong>Verlauf des Events:</strong> {{ feedback.event_progress }}</p>
|
||||||
|
<p><strong>Ende des Events:</strong> {{ feedback.event_end }}</p>
|
||||||
|
<p><strong>Feedback der Community:</strong> {{ feedback.community_feedback }}</p>
|
||||||
|
<p><strong>Verbesserungsvorschläge:</strong> {{ feedback.improvement_suggestions }}</p>
|
||||||
|
<p><strong>Abgegeben von:</strong> {{ feedback.username }} am {{ feedback.timestamp.strftime('%Y-%m-%d %H:%M:%S') }}</p>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
<form action="{{ url_for('dashboard') }}" method="get">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit">Zurück</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
105
Outdated Website/templates/view_license.html
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Lizenzdaten anzeigen</title>
|
||||||
|
<link rel="stylesheet" href="/static/style.css">
|
||||||
|
<link rel="icon" href="/static/logo.png" type="image/png">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-image: url('/static/background.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
width: 80%;
|
||||||
|
max-width: 800px;
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.content form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.content form label {
|
||||||
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.content form input,
|
||||||
|
.content form textarea,
|
||||||
|
.content form select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 5px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.content form button {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.content form button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
.delete-button {
|
||||||
|
background-color: #FF0000;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.delete-button:hover {
|
||||||
|
background-color: #CC0000;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% include "top_bar.html" %}
|
||||||
|
<div class="content">
|
||||||
|
<h2>Lizenzdaten für {{ license_data['ingame_name'] }}</h2>
|
||||||
|
<p><strong>Lizenzschlüssel:</strong> {{ license_data['license_key'] }}</p>
|
||||||
|
<p><strong>Status:</strong> {{ license_data['status'] }}</p>
|
||||||
|
<p><strong>Name:</strong> {{ license_data['ingame_name'] }}</p>
|
||||||
|
<p><strong>Gefundene Ordner:</strong></p>
|
||||||
|
<ul>
|
||||||
|
{% for folder in license_data["found_folders"] %}
|
||||||
|
<li>{{ folder }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% if 'delete_requests' in session['permissions'] %}
|
||||||
|
<form action="{{ url_for('delete_license', license_key=license_data['license_key']) }}" method="post" style="display:inline;">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="delete-button">Löschen</button>
|
||||||
|
</form>
|
||||||
|
{% else %}
|
||||||
|
<form action="{{ url_for('request_delete_license', license_key=license_data['license_key']) }}" method="post" style="display:inline;">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
|
<button type="submit" class="delete-button">Löschanfrage stellen</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
<a href="/get_data" class="black-button">Zurück</a>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
118
Outdated Website/templates/view_user_age.html
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
{% extends "base_dark.html" %}
|
||||||
|
{% else %}
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% block title %}Benutzerdetails{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% if session['theme'] == 'darkmode' %}
|
||||||
|
<style>
|
||||||
|
.details-container {
|
||||||
|
background: rgba(30, 30, 30, 0.95);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.5);
|
||||||
|
max-width: 500px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
margin: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.details-container h1 {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.details-container p {
|
||||||
|
font-size: 1.2em;
|
||||||
|
color: #0ff;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
.back-button-dark {
|
||||||
|
margin-top: 20px;
|
||||||
|
display: inline-block;
|
||||||
|
width: auto;
|
||||||
|
padding: 14px 28px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.details-container strong {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="details-container">
|
||||||
|
<h1>Benutzerdetails</h1>
|
||||||
|
<p><strong>Ingame Name:</strong> {{ user.ingame_name }}</p>
|
||||||
|
<p><strong>SteamID:</strong> {{ user.steam_id }}</p>
|
||||||
|
<p><strong>Geburtsdatum:</strong> {{ user.birthdate }}</p>
|
||||||
|
<p><strong>Alter:</strong> {{ user.age }} Jahre</p>
|
||||||
|
<a href="/verify_age" class="neon-button neon3 back-button-dark"><span>Zurück</span></a>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Benutzerdetails</title>
|
||||||
|
<link rel="stylesheet" href="/static/style.css">
|
||||||
|
<link rel="icon" href="/static/logo.png" type="image/png">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-image: url('/static/background.png');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.details-container {
|
||||||
|
background: rgba(255, 255, 255, 0.6);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
max-width: 500px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
margin: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.details-container h1 {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.details-container p {
|
||||||
|
font-size: 1.2em;
|
||||||
|
color: #333;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
.back-button {
|
||||||
|
margin-top: 20px;
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% include "top_bar.html" %}
|
||||||
|
<div class="details-container">
|
||||||
|
<h1>Benutzerdetails</h1>
|
||||||
|
<p><strong>Ingame Name:</strong> {{ user.ingame_name }}</p>
|
||||||
|
<p><strong>SteamID:</strong> {{ user.steam_id }}</p>
|
||||||
|
<p><strong>Geburtsdatum:</strong> {{ user.birthdate }}</p>
|
||||||
|
<p><strong>Alter:</strong> {{ user.age }} Jahre</p>
|
||||||
|
<a href="/verify_age" class="back-button">Zurück</a>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
377
Outdated Website/templates/wallpaper.html
Normal file
|
|
@ -0,0 +1,377 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>SCP:SL Server Status</title>
|
||||||
|
<link rel="icon" href="/static/favicon.ico" type="image/x-icon">
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--primary-bg-color: rgba(0, 0, 0, 0.3);
|
||||||
|
--text-color: #e0e0e0;
|
||||||
|
--highlight-color: #00ff00;
|
||||||
|
--error-color: #ff4444;
|
||||||
|
--border-color: rgba(255, 255, 255, 0.08);
|
||||||
|
--shadow-color: rgba(0, 0, 0, 0.6);
|
||||||
|
--angle: 90deg;
|
||||||
|
--warning-color: #ffcc00;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
background: linear-gradient(180deg, #07131c, #305472);
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
color: var(--text-color);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.server-info-card {
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
text-align: center;
|
||||||
|
background-color: var(--primary-bg-color);
|
||||||
|
padding: 40px 70px;
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: 0 10px 32px var(--shadow-color);
|
||||||
|
max-width: 98%;
|
||||||
|
width: 1000px;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
|
-webkit-backdrop-filter: blur(8px);
|
||||||
|
transform: translateY(0);
|
||||||
|
opacity: 1;
|
||||||
|
transition: transform 0.5s ease-out, opacity 0.5s ease-out;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.server-info-card.hidden {
|
||||||
|
transform: translateY(20px);
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#server-name {
|
||||||
|
font-size: 3.125em;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.2;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
text-transform: none;
|
||||||
|
animation: fadeIn 1.5s ease-in-out forwards;
|
||||||
|
text-shadow: 1px 1px 3px var(--shadow-color);
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
#server-name span {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#player-count {
|
||||||
|
font-size: 2.75em;
|
||||||
|
margin-top: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--highlight-color);
|
||||||
|
transition: color 0.3s ease-in-out;
|
||||||
|
text-shadow: 1px 1px 3px var(--shadow-color);
|
||||||
|
margin-bottom: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-message {
|
||||||
|
font-size: 1.75em;
|
||||||
|
color: var(--text-color);
|
||||||
|
animation: pulse 1.5s infinite alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message {
|
||||||
|
font-size: 1.75em;
|
||||||
|
color: var(--error-color);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning-message {
|
||||||
|
font-size: 1.75em;
|
||||||
|
color: var(--warning-color);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rain {
|
||||||
|
position: absolute;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
z-index: 0;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drop {
|
||||||
|
border: 0.25vmin solid transparent;
|
||||||
|
border-bottom-color: #abc2e9;
|
||||||
|
position: absolute;
|
||||||
|
top: -5vmin;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
animation: fall var(--drop-duration) var(--drop-delay) linear infinite;
|
||||||
|
left: var(--drop-left);
|
||||||
|
border-left-width: var(--drop-width);
|
||||||
|
opacity: var(--drop-opacity);
|
||||||
|
transform: rotate(var(--angle));
|
||||||
|
transform-origin: 50% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fall {
|
||||||
|
from {
|
||||||
|
transform: translateY(0) rotate(var(--angle));
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateY(calc(100vh + 10vmin)) rotate(var(--angle));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from { opacity: 0; transform: translateY(-10px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
from { opacity: 0.7; }
|
||||||
|
to { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.graph-image-container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 900px;
|
||||||
|
height: auto;
|
||||||
|
background-color: rgba(0, 0, 0, 0.2);
|
||||||
|
border-radius: 22px;
|
||||||
|
padding: 32px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-top: 36px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.graph-image-container img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
border-radius: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1100px) {
|
||||||
|
.server-info-card {
|
||||||
|
width: 98%;
|
||||||
|
padding: 25px 10px;
|
||||||
|
}
|
||||||
|
.graph-image-container {
|
||||||
|
max-width: 98vw;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.server-info-card {
|
||||||
|
padding: 18px 2vw;
|
||||||
|
width: 99vw;
|
||||||
|
}
|
||||||
|
#server-name {
|
||||||
|
font-size: 2.25em;
|
||||||
|
}
|
||||||
|
#player-count {
|
||||||
|
font-size: 2.0em;
|
||||||
|
}
|
||||||
|
.loading-message, .error-message, .warning-message {
|
||||||
|
font-size: 1.25em;
|
||||||
|
}
|
||||||
|
.graph-image-container {
|
||||||
|
max-width: 100vw;
|
||||||
|
height: auto;
|
||||||
|
padding: 4vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="rain"></div>
|
||||||
|
|
||||||
|
<div class="server-info-card">
|
||||||
|
<div id="server-name" class="loading-message">Lade Servernamen...</div>
|
||||||
|
<div id="player-count" class="loading-message">Lade Spieleranzahl...</div>
|
||||||
|
<div id="global-error-message" class="error-message" style="display:none; margin-top: 10px;"></div>
|
||||||
|
|
||||||
|
<div class="graph-image-container">
|
||||||
|
<img id="playerHistoryGraph" src="/player_history_graph_img" alt="Spielerstatistik der letzten 24h">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const numDrops = 500;
|
||||||
|
const rainContainer = document.querySelector('.rain');
|
||||||
|
const defaultAngle = 90;
|
||||||
|
let initialLoadDone = false;
|
||||||
|
|
||||||
|
for (let i = 0; i < numDrops; i++) {
|
||||||
|
const drop = document.createElement('div');
|
||||||
|
drop.classList.add('drop');
|
||||||
|
drop.style.setProperty('--drop-opacity', (Math.random() * 0.7) + 0.1);
|
||||||
|
drop.style.setProperty('--drop-left', (Math.random() * 100) + 'vw');
|
||||||
|
drop.style.setProperty('--drop-width', (Math.random() * 0.4) + 0.05 + 'vmin');
|
||||||
|
drop.style.setProperty('--drop-duration', (Math.random() * 1.5) + 1.5 + 's');
|
||||||
|
drop.style.setProperty('--drop-delay', (Math.random() * -3) + 's');
|
||||||
|
drop.style.setProperty('--angle', `${defaultAngle}deg`);
|
||||||
|
rainContainer.appendChild(drop);
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractShortServerName(rawInfo) {
|
||||||
|
const nameMatch = rawInfo.match(/(<span style="color:#[a-fA-F0-9]{6}">\[G<\/span><span style="color:#[a-fA-F0-9]{6}">E<\/span><span style="color:#[a-fA-F0-9]{6}">R\]<\/span>)?\s*<b>(.*?)<\/b>(\s*<span style="color:#[a-fA-F0-9]{6}">\[#\d+\]<\/span>)?/);
|
||||||
|
|
||||||
|
if (nameMatch) {
|
||||||
|
let finalName = '';
|
||||||
|
if (nameMatch[1]) finalName += nameMatch[1] + ' ';
|
||||||
|
if (nameMatch[2]) finalName += nameMatch[2];
|
||||||
|
if (nameMatch[3]) finalName += nameMatch[3];
|
||||||
|
return finalName.split('<br')[0].trim();
|
||||||
|
}
|
||||||
|
return rawInfo.split('<br')[0].replace(/<[^>]*>/g, '').trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updatePlayerHistoryGraph() {
|
||||||
|
const graphImage = document.getElementById('playerHistoryGraph');
|
||||||
|
graphImage.src = `/player_history_graph_img?t=${new Date().getTime()}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchServerData(isInitialCall = false) {
|
||||||
|
const apiUrl = '/api/scpsl_proxy';
|
||||||
|
const serverNameElement = document.getElementById('server-name');
|
||||||
|
const playerCountElement = document.getElementById('player-count');
|
||||||
|
const cardElement = document.querySelector('.server-info-card');
|
||||||
|
const globalErrorMessageElement = document.getElementById('global-error-message');
|
||||||
|
|
||||||
|
if (isInitialCall || !initialLoadDone || serverNameElement.classList.contains('error-message') || globalErrorMessageElement.style.display === 'block') {
|
||||||
|
serverNameElement.className = 'loading-message';
|
||||||
|
serverNameElement.innerHTML = 'Lade Servernamen...';
|
||||||
|
playerCountElement.className = 'loading-message';
|
||||||
|
playerCountElement.textContent = 'Lade Spieleranzahl...';
|
||||||
|
globalErrorMessageElement.style.display = 'none';
|
||||||
|
cardElement.classList.remove('hidden');
|
||||||
|
} else {
|
||||||
|
if (!playerCountElement.classList.contains('error-message')) {
|
||||||
|
playerCountElement.classList.add('loading-message');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeoutPromise = new Promise((resolve, reject) => {
|
||||||
|
const id = setTimeout(() => {
|
||||||
|
clearTimeout(id);
|
||||||
|
reject(new Error('Server response timed out (mehr als 5 Sekunden).'));
|
||||||
|
}, 5000);
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await Promise.race([
|
||||||
|
fetch(apiUrl),
|
||||||
|
timeoutPromise
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
let errorDetails = 'Unbekannter Fehler';
|
||||||
|
try {
|
||||||
|
const errorData = await response.json();
|
||||||
|
errorDetails = errorData.error || errorDetails;
|
||||||
|
} catch (e) {
|
||||||
|
errorDetails = response.statusText || errorDetails;
|
||||||
|
}
|
||||||
|
throw new Error(`Serverfehler: ${response.status} - ${errorDetails}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
let rawServerInfo = data.info || "Unbekannter Server";
|
||||||
|
|
||||||
|
const currentServerNameHTML = serverNameElement.innerHTML;
|
||||||
|
const newServerNameHTML = extractShortServerName(rawServerInfo);
|
||||||
|
if (isInitialCall || !initialLoadDone || serverNameElement.classList.contains('error-message') || currentServerNameHTML !== newServerNameHTML) {
|
||||||
|
serverNameElement.innerHTML = newServerNameHTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.online) {
|
||||||
|
playerCountElement.textContent = `Spieler: ${data.players}`;
|
||||||
|
playerCountElement.style.color = 'var(--highlight-color)';
|
||||||
|
serverNameElement.classList.remove('loading-message', 'error-message', 'warning-message');
|
||||||
|
playerCountElement.classList.remove('loading-message', 'error-message', 'warning-message');
|
||||||
|
globalErrorMessageElement.style.display = 'none';
|
||||||
|
cardElement.classList.remove('hidden');
|
||||||
|
} else {
|
||||||
|
if (!serverNameElement.innerHTML.includes('[OFFLINE]')) {
|
||||||
|
serverNameElement.innerHTML = newServerNameHTML + '<br><span style="font-size:0.6em; color:var(--error-color);">[OFFLINE]</span>';
|
||||||
|
}
|
||||||
|
playerCountElement.textContent = 'Server ist offline.';
|
||||||
|
playerCountElement.style.color = 'var(--error-color)';
|
||||||
|
serverNameElement.classList.remove('loading-message', 'warning-message');
|
||||||
|
serverNameElement.classList.add('error-message');
|
||||||
|
playerCountElement.classList.remove('loading-message', 'warning-message');
|
||||||
|
playerCountElement.classList.add('error-message');
|
||||||
|
globalErrorMessageElement.style.display = 'none';
|
||||||
|
cardElement.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
playerCountElement.classList.remove('loading-message');
|
||||||
|
initialLoadDone = true;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Fehler beim Abrufen der Serverdaten:', error);
|
||||||
|
|
||||||
|
let errorMessage = 'Server konnte nicht erreicht werden.';
|
||||||
|
let errorSubtext = '<i>(Allgemeiner Fehler)</i>';
|
||||||
|
let errorClass = 'error-message';
|
||||||
|
|
||||||
|
if (error.message.includes('timed out')) {
|
||||||
|
errorMessage = 'Server-Antwort Timeout.';
|
||||||
|
errorSubtext = '<i>(Ladeversuch läuft im Hintergrund)</i>';
|
||||||
|
errorClass = 'warning-message';
|
||||||
|
} else if (error.message.includes('Serverfehler:')) {
|
||||||
|
errorMessage = 'Serverfehler.';
|
||||||
|
errorSubtext = `<i>(${error.message.split('Serverfehler: ')[1]})</i>`;
|
||||||
|
errorClass = 'error-message';
|
||||||
|
}
|
||||||
|
|
||||||
|
serverNameElement.className = errorClass;
|
||||||
|
serverNameElement.innerHTML = errorMessage + '<br><small>' + errorSubtext + '</small>';
|
||||||
|
|
||||||
|
playerCountElement.className = errorClass;
|
||||||
|
playerCountElement.textContent = 'Daten nicht verfügbar.';
|
||||||
|
|
||||||
|
globalErrorMessageElement.textContent = 'Aktualisierung fehlgeschlagen. Bitte versuche es später erneut.';
|
||||||
|
globalErrorMessageElement.style.display = 'block';
|
||||||
|
|
||||||
|
if (errorClass === 'error-message') {
|
||||||
|
cardElement.classList.add('hidden');
|
||||||
|
} else {
|
||||||
|
cardElement.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
initialLoadDone = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
fetchServerData(true);
|
||||||
|
updatePlayerHistoryGraph();
|
||||||
|
setInterval(fetchServerData, 5000);
|
||||||
|
setInterval(updatePlayerHistoryGraph, 60000);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||