This commit is contained in:
pika 2025-03-24 19:22:44 +01:00
parent 429d259d06
commit b834040b4e

View file

@ -6,6 +6,111 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Caddy Dashboard</title> <title>Caddy Dashboard</title>
<script src="https://cdn.tailwindcss.com"></script> <script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
midnight: '#121212',
obsidian: '#0a0a0a',
charcoal: '#1e1e1e',
slate: {
850: '#172032',
},
neon: {
blue: '#4dadff',
purple: '#a259ff',
pink: '#ff59f8',
cyan: '#38ffdd',
green: '#3cf7a2',
},
},
backgroundImage: {
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
},
animation: {
'gradient-shift': 'gradient-shift 10s ease infinite',
},
keyframes: {
'gradient-shift': {
'0%, 100%': { backgroundPosition: '0% 50%' },
'50%': { backgroundPosition: '100% 50%' },
}
}
}
}
}
</script>
<style>
.bg-mesh {
background-color: #121212;
background-image:
radial-gradient(at 40% 20%, rgba(61, 65, 154, 0.1) 0px, transparent 50%),
radial-gradient(at 80% 0%, rgba(105, 29, 209, 0.1) 0px, transparent 50%),
radial-gradient(at 0% 50%, rgba(46, 49, 146, 0.1) 0px, transparent 50%),
radial-gradient(at 80% 50%, rgba(11, 103, 159, 0.1) 0px, transparent 50%),
radial-gradient(at 0% 100%, rgba(23, 86, 118, 0.1) 0px, transparent 50%),
radial-gradient(at 80% 100%, rgba(61, 111, 154, 0.1) 0px, transparent 50%),
radial-gradient(at 0% 0%, rgba(42, 9, 68, 0.1) 0px, transparent 50%);
}
.gradient-text {
background: linear-gradient(90deg, #4dadff, #a259ff, #38ffdd);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
background-size: 300% 100%;
animation: gradient-shift 8s ease infinite;
}
.card-gradient {
position: relative;
border-radius: 16px;
overflow: hidden;
z-index: 1;
}
.card-gradient::before {
content: "";
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
background: linear-gradient(45deg, #4dadff, #a259ff, #38ffdd);
z-index: -1;
border-radius: 18px;
opacity: 0;
transition: opacity 0.3s ease;
}
.card-gradient:hover::before {
opacity: 0.5;
}
@keyframes gradient-shift {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
/* Subtle grid pattern */
.bg-grid {
background-size: 40px 40px;
background-image:
linear-gradient(to right, rgba(55, 65, 81, 0.05) 1px, transparent 1px),
linear-gradient(to bottom, rgba(55, 65, 81, 0.05) 1px, transparent 1px);
}
</style>
<script> <script>
function toggleSearch() { function toggleSearch() {
let searchBar = document.getElementById("search-box"); let searchBar = document.getElementById("search-box");
@ -25,19 +130,25 @@
} }
function deleteServer(serverName) { function deleteServer(serverName) {
if (confirm(`Möchten Sie den Server "${serverName}" wirklich löschen?`)) {
fetch('/delete', { fetch('/delete', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ "server": serverName }) body: JSON.stringify({ "server": serverName })
}).then(response => { }).then(response => {
if (response.ok) { if (response.ok) {
document.getElementById("server-box-" + serverName).remove(); const serverBox = document.getElementById("server-box-" + serverName);
serverBox.classList.add('opacity-0', 'scale-95');
setTimeout(() => {
serverBox.remove();
}, 300);
} }
}); });
} }
}
document.addEventListener("keydown", function (event) { document.addEventListener("keydown", function (event) {
if (event.key === "/") { if (event.key === "/" && !event.ctrlKey && !event.metaKey) {
event.preventDefault(); event.preventDefault();
toggleSearch(); toggleSearch();
} }
@ -45,41 +156,68 @@
</script> </script>
</head> </head>
<body class="bg-gray-900 text-gray-100"> <body class="bg-mesh text-gray-100 min-h-screen">
<div
<header class="bg-indigo-700 text-white p-6 text-center"> class="bg-gradient-to-r from-slate-850/60 to-charcoal/60 backdrop-blur-md border-b border-gray-700/30 sticky top-0 z-10">
<h1 class="text-3xl font-bold">Caddy Dashboard</h1> <header class="container mx-auto px-4 py-6 text-center">
<p class="text-cyan-300 text-lg">Übersicht über aller aktiven Proxy-Server</p> <h1 class="text-4xl font-bold tracking-tight gradient-text">Caddy Dashboard</h1>
<button onclick="toggleSearch()" <p class="text-cyan-300 text-lg mt-2 opacity-80">Übersicht über alle aktiven Proxy-Server</p>
class="bg-cyan-500 hover:bg-cyan-400 text-white text-right px-6 py-3 rounded-lg mt-4 text-lg">🔍 <div class="mt-6 flex justify-center">
Suche</button> <button onclick="toggleSearch()" class="bg-gradient-to-r from-neon-blue to-neon-purple text-white px-8 py-3 rounded-full
shadow-lg shadow-indigo-500/20 hover:shadow-indigo-500/40 transition-all duration-300
flex items-center space-x-2">
<i class="fas fa-search"></i>
<span>Suche</span>
</button>
</div>
</header> </header>
</div>
<div class="container mx-auto p-4 md:p-6"> <div class="container mx-auto p-4 md:p-6 bg-grid">
<input type="text" id="search-box" class="hidden w-full p-4 mb-4 text-gray-900 text-lg rounded-md" <div class="transition-all duration-300 transform">
placeholder="🔍 Suche nach Subdomains.." onkeyup="filterEntries()"> <input type="text" id="search-box" class="hidden w-full p-4 mb-6 text-gray-100 text-lg rounded-xl bg-charcoal/80 backdrop-blur-md
border border-gray-700/50 focus:border-neon-blue focus:outline-none focus:ring-2
focus:ring-neon-blue/30 shadow-xl transition-all duration-300 transform"
placeholder="Nach Subdomains suchen... (Drücke '/' für schnellen Zugriff)" onkeyup="filterEntries()">
</div>
{% for server, entries in proxies.items() %} {% for server, entries in proxies.items() %}
<div id="server-box-{{ server }}" class="bg-gray-800 p-6 rounded-lg shadow-lg mb-6"> <div id="server-box-{{ server }}" class="bg-gradient-to-br from-charcoal/80 to-slate-850/80 backdrop-blur-md p-7 rounded-2xl shadow-xl mb-8
border border-gray-700/30 transition-all duration-300 transform">
<div class="flex flex-col md:flex-row justify-between items-start md:items-center"> <div class="flex flex-col md:flex-row justify-between items-start md:items-center">
<div> <div>
<h2 class="text-2xl font-semibold text-indigo-400">{{ server }}</h2> <h2 class="text-2xl font-bold gradient-text">{{ server }}</h2>
<p class="text-sm text-gray-400">Zuletzt aktualisiert: {{ timestamps[server] }}</p> <p class="text-sm text-gray-400 flex items-center mt-1">
<i class="far fa-clock mr-2"></i> Zuletzt aktualisiert: {{ timestamps[server] }}
</p>
</div> </div>
<button onclick="deleteServer('{{ server }}')" <button onclick="deleteServer('{{ server }}')" class="mt-4 md:mt-0 bg-gradient-to-r from-red-500 to-rose-600 hover:from-red-600 hover:to-rose-700
class="mt-3 md:mt-0 bg-red-500 text-white px-6 py-2 rounded-lg text-lg">🗑️ Löschen</button> text-white px-6 py-2.5 rounded-full text-sm font-medium transition-all duration-300 transform
hover:scale-105 flex items-center">
<i class="fas fa-trash-alt mr-2"></i> Löschen
</button>
</div> </div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 mt-4"> <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-5 mt-6">
{% for domain, target in entries.items() %} {% for domain, target in entries.items() %}
<div class="domain-card bg-gray-700 p-4 rounded-lg shadow-md flex flex-col space-y-2" <div class="domain-card card-gradient bg-obsidian p-5 rounded-xl backdrop-blur-sm shadow-lg
border border-gray-800/50 flex flex-col space-y-4 transition-all duration-300 transform hover:translate-y-[-2px]"
data-domain="{{ domain }}"> data-domain="{{ domain }}">
<div class="flex justify-between"> <div class="flex justify-between items-start">
<a href="https://{{ domain }}" target="_blank" <a href="https://{{ domain }}" target="_blank"
class="text-indigo-400 hover:text-indigo-300 text-lg break-words">{{ domain }}</a> class="text-neon-blue hover:text-neon-cyan font-medium text-lg break-words transition-colors duration-300 flex items-center">
<!-- <button onclick="checkStatus('{{ domain }}', this)" class="bg-cyan-500 text-white px-4 py-2 rounded-lg text-sm">🔄 Prüfen</button> --> <i class="fas fa-globe mr-2 opacity-80"></i>
<span>{{ domain }}</span>
</a>
<div class="ml-2 flex-shrink-0">
<div class="w-2 h-2 bg-green-500 rounded-full shadow-sm shadow-green-400/50"></div>
</div>
</div>
<div class="pt-2 border-t border-gray-800/50">
<p class="text-gray-300 break-words text-sm font-mono bg-midnight/50 p-2 rounded-lg">
<i class="fas fa-network-wired mr-2 text-gray-500"></i>{{ target }}
</p>
</div> </div>
<p class="text-gray-300 break-words text-lg">{{ target }}</p>
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
@ -87,6 +225,11 @@
{% endfor %} {% endfor %}
</div> </div>
<footer class="bg-obsidian/60 backdrop-blur-md border-t border-gray-700/30 py-4 mt-12">
<div class="container mx-auto px-4 text-center text-gray-500 text-sm">
Caddy Dashboard • Powered by Flask & Tailwind CSS
</div>
</footer>
</body> </body>
</html> </html>