modified: app.py

modified:   bot.py
	modified:   templates/server_admin_dashboard.html
	new file:   templates/server_settings.html
This commit is contained in:
SimolZimol
2025-08-19 18:35:32 +02:00
parent 59a9960155
commit 196d2ac570
4 changed files with 1298 additions and 8 deletions

View File

@@ -0,0 +1,398 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Server-Einstellungen - {{ guild_name }}</title>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<style>
body {
background: linear-gradient(135deg, #0c1426 0%, #1a1f2e 25%, #2d3748 75%, #0c1426 100%);
min-height: 100vh;
color: #e2e8f0;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.main-container {
background: rgba(26, 31, 46, 0.8);
backdrop-filter: blur(15px);
border: 1px solid rgba(102, 126, 234, 0.2);
border-radius: 20px;
margin: 2rem auto;
max-width: 1000px;
padding: 2rem;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
}
.header-section {
text-align: center;
margin-bottom: 2rem;
padding-bottom: 1.5rem;
border-bottom: 1px solid rgba(102, 126, 234, 0.2);
}
.header-title {
color: #e2e8f0;
font-size: 2.2rem;
font-weight: 700;
margin-bottom: 0.5rem;
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
}
.header-icon {
color: #667eea;
font-size: 2.2rem;
}
.server-name {
color: #a0aec0;
font-size: 1.1rem;
}
.settings-section {
background: rgba(45, 55, 72, 0.6);
border: 1px solid rgba(102, 126, 234, 0.2);
border-radius: 15px;
padding: 2rem;
margin-bottom: 2rem;
}
.section-title {
color: #e2e8f0;
font-size: 1.5rem;
font-weight: 600;
margin-bottom: 1.5rem;
display: flex;
align-items: center;
gap: 0.75rem;
}
.section-icon {
color: #667eea;
font-size: 1.5rem;
}
.form-group label {
color: #e2e8f0;
font-weight: 600;
margin-bottom: 0.5rem;
}
.form-control {
background: rgba(45, 55, 72, 0.8);
border: 1px solid rgba(102, 126, 234, 0.3);
border-radius: 8px;
color: #e2e8f0;
padding: 0.75rem;
}
.form-control:focus {
background: rgba(45, 55, 72, 0.9);
border-color: #667eea;
box-shadow: 0 0 0 0.2rem rgba(102, 126, 234, 0.25);
color: #e2e8f0;
}
.form-control::placeholder {
color: #a0aec0;
}
.form-check {
margin: 1rem 0;
padding: 1rem;
background: rgba(45, 55, 72, 0.4);
border-radius: 8px;
border: 1px solid rgba(102, 126, 234, 0.2);
}
.form-check-input {
margin-top: 0.3rem;
}
.form-check-label {
color: #e2e8f0;
font-weight: 500;
margin-left: 0.5rem;
}
.help-text {
color: #a0aec0;
font-size: 0.875rem;
margin-top: 0.25rem;
}
.btn-primary {
background: linear-gradient(135deg, #667eea, #764ba2);
border: none;
color: white;
padding: 0.75rem 2rem;
border-radius: 10px;
font-weight: 600;
transition: all 0.3s ease;
text-transform: uppercase;
letter-spacing: 1px;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.3);
}
.btn-secondary {
background: rgba(45, 55, 72, 0.6);
border: 1px solid rgba(102, 126, 234, 0.2);
color: #e2e8f0;
padding: 0.75rem 1.5rem;
border-radius: 10px;
font-weight: 600;
transition: all 0.3s ease;
text-decoration: none;
}
.btn-secondary:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.1);
color: #e2e8f0;
text-decoration: none;
border-color: rgba(102, 126, 234, 0.4);
}
.alert {
border-radius: 10px;
border: none;
margin-bottom: 1.5rem;
}
.alert-success {
background: rgba(72, 187, 120, 0.1);
color: #48bb78;
border: 1px solid rgba(72, 187, 120, 0.3);
}
.alert-danger {
background: rgba(245, 101, 101, 0.1);
color: #f56565;
border: 1px solid rgba(245, 101, 101, 0.3);
}
.info-card {
background: rgba(56, 178, 172, 0.1);
border: 1px solid rgba(56, 178, 172, 0.2);
border-radius: 10px;
padding: 1rem;
margin-bottom: 1.5rem;
}
.info-card-title {
color: #38b2ac;
font-weight: 600;
margin-bottom: 0.5rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.info-card-text {
color: #a0aec0;
margin: 0;
}
@media (max-width: 768px) {
.main-container {
margin: 1rem;
padding: 1.5rem;
}
.header-title {
font-size: 1.8rem;
flex-direction: column;
gap: 0.5rem;
}
.settings-section {
padding: 1.5rem;
}
}
</style>
</head>
<body>
{% include 'navigation.html' %}
<div class="main-container">
<div class="header-section">
<h1 class="header-title">
<i class="fas fa-cogs header-icon"></i>
Server-Einstellungen
</h1>
<p class="server-name">{{ guild_name }}</p>
</div>
<!-- Flash Messages -->
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ 'success' if category == 'success' else 'danger' }}">
<i class="fas fa-{{ 'check-circle' if category == 'success' else 'exclamation-triangle' }}"></i>
{{ message }}
</div>
{% endfor %}
{% endif %}
{% endwith %}
<form method="POST">
<!-- Mute-Einstellungen -->
<div class="settings-section">
<h3 class="section-title">
<i class="fas fa-volume-mute section-icon"></i>
Mute-Einstellungen
</h3>
<div class="info-card">
<div class="info-card-title">
<i class="fas fa-info-circle"></i>
Hinweis zu Rollen-IDs
</div>
<p class="info-card-text">
Um eine Rollen-ID zu finden: Rechtsklick auf die Rolle → "ID kopieren" (Entwicklermodus muss aktiviert sein)
</p>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="mute_role_id">Mute-Rollen-ID</label>
<input type="text" class="form-control" id="mute_role_id" name="mute_role_id"
value="{{ settings.mute_role_id or '' }}" placeholder="z.B. 123456789012345678">
<small class="help-text">Leer lassen für automatische Suche nach Name</small>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="mute_role_name">Mute-Rollen-Name</label>
<input type="text" class="form-control" id="mute_role_name" name="mute_role_name"
value="{{ settings.mute_role_name }}" placeholder="Muted" required>
<small class="help-text">Name für automatisch erstellte Mute-Rollen</small>
</div>
</div>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="auto_create_mute_role"
name="auto_create_mute_role" {% if settings.auto_create_mute_role %}checked{% endif %}>
<label class="form-check-label" for="auto_create_mute_role">
Mute-Rolle automatisch erstellen
</label>
<small class="help-text d-block">Erstellt automatisch eine Mute-Rolle, falls keine gefunden wird</small>
</div>
</div>
<!-- Warn-Einstellungen -->
<div class="settings-section">
<h3 class="section-title">
<i class="fas fa-exclamation-triangle section-icon"></i>
Warn-Einstellungen
</h3>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="max_warn_threshold">Maximale Warnungen</label>
<input type="number" class="form-control" id="max_warn_threshold" name="max_warn_threshold"
value="{{ settings.max_warn_threshold }}" min="1" max="10" required>
<small class="help-text">Anzahl Warnungen vor automatischen Aktionen</small>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="auto_mute_duration">Auto-Mute-Dauer</label>
<input type="text" class="form-control" id="auto_mute_duration" name="auto_mute_duration"
value="{{ settings.auto_mute_duration }}" placeholder="1h" required>
<small class="help-text">Format: 10m, 1h, 2d (Minuten, Stunden, Tage)</small>
</div>
</div>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="auto_mute_on_warns"
name="auto_mute_on_warns" {% if settings.auto_mute_on_warns %}checked{% endif %}>
<label class="form-check-label" for="auto_mute_on_warns">
Automatischer Mute bei zu vielen Warnungen
</label>
<small class="help-text d-block">Mutet Benutzer automatisch bei Erreichen des Warn-Limits</small>
</div>
</div>
<!-- Log-Einstellungen -->
<div class="settings-section">
<h3 class="section-title">
<i class="fas fa-clipboard-list section-icon"></i>
Log-Einstellungen
</h3>
<div class="form-group">
<label for="log_channel_id">Log-Kanal-ID</label>
<input type="text" class="form-control" id="log_channel_id" name="log_channel_id"
value="{{ settings.log_channel_id or '' }}" placeholder="z.B. 123456789012345678">
<small class="help-text">Kanal für Moderations-Logs (leer lassen zum Deaktivieren)</small>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="mod_log_enabled"
name="mod_log_enabled" {% if settings.mod_log_enabled %}checked{% endif %}>
<label class="form-check-label" for="mod_log_enabled">
Moderations-Logs aktiviert
</label>
<small class="help-text d-block">Protokolliert alle Moderationsaktionen</small>
</div>
</div>
<!-- Action Buttons -->
<div class="text-center">
<button type="submit" class="btn btn-primary mr-3">
<i class="fas fa-save"></i> Einstellungen speichern
</button>
<a href="{{ url_for('server_admin_dashboard', guild_id=guild_id) }}" class="btn btn-secondary">
<i class="fas fa-arrow-left"></i> Zurück zum Dashboard
</a>
</div>
</form>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.2/dist/js/bootstrap.bundle.min.js"></script>
<script>
// Formular-Validierung
document.querySelector('form').addEventListener('submit', function(e) {
const muteRoleId = document.getElementById('mute_role_id').value;
const logChannelId = document.getElementById('log_channel_id').value;
const muteDuration = document.getElementById('auto_mute_duration').value;
// Validiere Rollen-ID Format (falls angegeben)
if (muteRoleId && !/^\d{17,19}$/.test(muteRoleId)) {
alert('Mute-Rollen-ID muss eine 17-19 stellige Zahl sein');
e.preventDefault();
return;
}
// Validiere Log-Kanal-ID Format (falls angegeben)
if (logChannelId && !/^\d{17,19}$/.test(logChannelId)) {
alert('Log-Kanal-ID muss eine 17-19 stellige Zahl sein');
e.preventDefault();
return;
}
// Validiere Zeitformat
if (muteDuration && !/^\d+[mhd]$/.test(muteDuration)) {
alert('Auto-Mute-Dauer muss im Format "10m", "1h" oder "2d" sein');
e.preventDefault();
return;
}
});
</script>
</body>
</html>