Files

348 lines
19 KiB
HTML

{% extends "layout.html" %}
{% block content %}
<section class="administrator-section">
{% if setup_required %}
<div class="content-card">
<h2 class="section-title"><i data-lucide="settings"></i> Einrichtung</h2>
<form action="{{ url_for('handle_administrator') }}" method="POST" class="input-form">
<div class="form-group">
<label for="password_string" class="input-label">Neues Passwort</label>
<input type="password" id="password_string" name="password_string" class="text-input" required>
</div>
<div class="form-group">
<label for="password_string_confirmation" class="input-label">Passwort bestätigen</label>
<input type="password" id="password_string_confirmation" name="password_string_confirmation" class="text-input" required>
</div>
<button type="submit" class="action-button primary-button"><i data-lucide="check"></i> Abschließen</button>
</form>
</div>
{% elif login_required %}
<div class="content-card">
<h2 class="section-title"><i data-lucide="shield"></i> Admin-Login</h2>
<form action="{{ url_for('handle_administrator') }}" method="POST" class="input-form">
<div class="form-group">
<label for="password_string" class="input-label">Passwort</label>
<input type="password" id="password_string" name="password_string" class="text-input" required>
</div>
{% if two_factor_enabled %}
<div class="form-group">
<label for="two_factor_code" class="input-label">2FA-Code</label>
<input type="text" id="two_factor_code" name="two_factor_code" class="text-input" required>
</div>
{% endif %}
<button type="submit" class="action-button primary-button"><i data-lucide="log-in"></i> Anmelden</button>
</form>
</div>
{% elif dashboard_active %}
<div class="tab-container">
<button class="tab-button active-tab" data-target="control-panel"><i data-lucide="sliders"></i> Steuerung</button>
<button class="tab-button" data-target="player-panel"><i data-lucide="users"></i> Spieler</button>
<button class="tab-button" data-target="kill-panel"><i data-lucide="message-square"></i> Meldungen</button>
</div>
<div id="control-panel" class="tab-content active-content">
<div class="content-card status-card">
<h3 class="card-title" style="display: flex; align-items: center; gap: var(--spacing-small);">
<i data-lucide="activity"></i> Spielstatus:
{% if game_status == 'pending' %}
<span class="status-pill warning-pill"><i data-lucide="clock"></i> Ausstehend</span>
{% elif game_status == 'running' %}
<span class="status-pill success-pill"><i data-lucide="play"></i> Läuft</span>
{% elif game_status == 'paused' %}
<span class="status-pill warning-pill"><i data-lucide="pause"></i> Pausiert</span>
{% elif game_status == 'finished' %}
<span class="status-pill danger-pill"><i data-lucide="square"></i> Beendet</span>
{% endif %}
</h3>
{% if game_status == 'pending' %}
{% if can_start %}
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="input-form admin-asynchronous-form">
<input type="hidden" name="action_type" value="start_game">
<button type="submit" class="action-button success-button large-button"><i data-lucide="play"></i> Spiel starten</button>
</form>
{% else %}
<div class="content-card notice-card warning-card">
<p class="notice-text">Zu wenige Spieler zum Starten.</p>
</div>
{% endif %}
{% elif game_status == 'running' %}
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="input-form admin-asynchronous-form" style="margin-bottom: var(--spacing-medium);">
<input type="hidden" name="action_type" value="pause_game">
<button type="submit" class="action-button warning-button large-button"><i data-lucide="pause"></i> Spiel pausieren</button>
</form>
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="input-form admin-asynchronous-form">
<input type="hidden" name="action_type" value="stop_game">
<button type="submit" class="action-button danger-button large-button"><i data-lucide="square"></i> Spiel beenden</button>
</form>
{% elif game_status == 'paused' %}
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="input-form admin-asynchronous-form" style="margin-bottom: var(--spacing-medium);">
<input type="hidden" name="action_type" value="resume_game">
<button type="submit" class="action-button success-button large-button"><i data-lucide="play"></i> Spiel fortsetzen</button>
</form>
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="input-form admin-asynchronous-form">
<input type="hidden" name="action_type" value="stop_game">
<button type="submit" class="action-button danger-button large-button"><i data-lucide="square"></i> Spiel beenden</button>
</form>
{% elif game_status == 'finished' %}
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="input-form admin-asynchronous-form">
<input type="hidden" name="action_type" value="reset_game">
<button type="submit" class="action-button danger-button large-button"><i data-lucide="rotate-ccw"></i> Spiel zurücksetzen</button>
</form>
{% endif %}
</div>
<div class="content-card settings-card">
<h3 class="card-title"><i data-lucide="shield-check"></i> Sicherheit</h3>
{% if two_factor_enabled %}
<div class="content-card notice-card success-card">
<p class="notice-text">2FA ist aktiv.</p>
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="inline-form admin-asynchronous-form">
<input type="hidden" name="action_type" value="disable_two_factor">
<button type="submit" class="action-button danger-button"><i data-lucide="shield-off"></i> Deaktivieren</button>
</form>
</div>
{% else %}
<div class="content-card notice-card warning-card">
<p class="notice-text">2FA inaktiv. QR-Code scannen.</p>
<p>Code: <strong>{{ two_factor_secret }}</strong></p>
<div class="qr-code-container">
{{ qr_code_svg | safe }}
</div>
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="input-form admin-asynchronous-form">
<input type="hidden" name="action_type" value="enable_two_factor">
<div class="form-group">
<label for="enable_two_factor_code" class="input-label">Bestätigungscode</label>
<input type="text" id="enable_two_factor_code" name="two_factor_code" class="text-input" required>
</div>
<button type="submit" class="action-button success-button"><i data-lucide="shield-alert"></i> Aktivieren</button>
</form>
</div>
{% endif %}
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="input-form admin-asynchronous-form" style="margin-top: var(--spacing-large);">
<input type="hidden" name="action_type" value="update_credentials">
<div class="form-group">
<label for="new_password_string" class="input-label">Neues Passwort</label>
<input type="password" id="new_password_string" name="password_string" class="text-input" required>
</div>
<div class="form-group">
<label for="update_password_confirmation" class="input-label">Passwort bestätigen</label>
<input type="password" id="update_password_confirmation" name="password_string_confirmation" class="text-input" required>
</div>
<button type="submit" class="action-button primary-button"><i data-lucide="save"></i> Speichern</button>
</form>
</div>
</div>
<div id="player-panel" class="tab-content">
<div class="content-card">
<h3 class="card-title"><i data-lucide="user-plus"></i> Spieler erstellen</h3>
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="input-form admin-asynchronous-form">
<input type="hidden" name="action_type" value="create_player">
<div class="form-group">
<label for="display_name" class="input-label">Name</label>
<input type="text" id="display_name" name="display_name" class="text-input" required>
</div>
<button type="submit" class="action-button primary-button"><i data-lucide="plus"></i> Erstellen</button>
</form>
</div>
<div class="content-card" style="overflow-x: auto;">
<table class="data-table">
<thead>
<tr>
<th>Kennung</th>
<th>Name</th>
<th>Status</th>
<th>Ziel</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for current_player in all_players %}
<tr class="{% if not current_player.is_approved %}unregistered-row{% endif %}">
<td class="monospace-identifier">
{{ current_player.player_identifier }}
{% if not current_player.is_approved %}
<br><span class="status-pill warning-pill" style="margin-left: 0; margin-top: var(--spacing-small);">Wartet</span>
{% elif current_player.late_joiner %}
<br><span class="status-pill warning-pill" style="margin-left: 0; margin-top: var(--spacing-small);">Späteinstieg</span>
{% endif %}
</td>
<td>
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="flexible_form_container admin-asynchronous-form">
<input type="hidden" name="action_type" value="edit_name">
<input type="hidden" name="player_identifier" value="{{ current_player.player_identifier }}">
<input type="text" name="new_display_name" value="{{ current_player.display_name }}" class="text-input small-input" required>
<button type="submit" class="action-button primary-button small-button"><i data-lucide="save"></i></button>
</form>
{% if current_player.pending_display_name %}
<div class="content-card notice-card warning-card" style="margin-top: var(--spacing-small); padding: var(--spacing-small); margin-bottom: 0;">
<p style="margin: 0 0 var(--spacing-small) 0; font-size: calc(0.875rem * var(--dimension-multiplier));">
-> <strong>{{ current_player.pending_display_name }}</strong>
</p>
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="flexible_form_container admin-asynchronous-form" style="margin-bottom: var(--spacing-small);">
<input type="hidden" name="action_type" value="approve_name_change">
<input type="hidden" name="player_identifier" value="{{ current_player.player_identifier }}">
<button type="submit" class="action-button success-button small-button"><i data-lucide="check"></i></button>
</form>
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="flexible_form_container admin-asynchronous-form">
<input type="hidden" name="action_type" value="reject_name_change">
<input type="hidden" name="player_identifier" value="{{ current_player.player_identifier }}">
<button type="submit" class="action-button danger-button small-button"><i data-lucide="x"></i></button>
</form>
</div>
{% endif %}
</td>
<td>
{% if not current_player.is_approved %}
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="flexible_form_container admin-asynchronous-form">
<input type="hidden" name="action_type" value="approve_player">
<input type="hidden" name="player_identifier" value="{{ current_player.player_identifier }}">
<button type="submit" class="action-button success-button small-button"><i data-lucide="user-check"></i> Freigeben</button>
</form>
{% else %}
{% if current_player.is_alive %}
<span class="status-pill success-pill" style="margin-left: 0;"><i data-lucide="heart"></i> Lebend</span>
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="flexible_form_container admin-asynchronous-form" style="margin-top: var(--spacing-small);">
<input type="hidden" name="action_type" value="eliminate_player">
<input type="hidden" name="player_identifier" value="{{ current_player.player_identifier }}">
<button type="submit" class="action-button danger-button small-button"><i data-lucide="skull"></i> Killen</button>
</form>
{% else %}
<span class="status-pill danger-pill" style="margin-left: 0;"><i data-lucide="skull"></i> Gekillt</span>
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="flexible_form_container admin-asynchronous-form" style="margin-top: var(--spacing-small);">
<input type="hidden" name="action_type" value="revive_player">
<input type="hidden" name="player_identifier" value="{{ current_player.player_identifier }}">
<button type="submit" class="action-button success-button small-button"><i data-lucide="heart-pulse"></i> Beleben</button>
</form>
{% endif %}
{% endif %}
</td>
<td>
{% if current_player.target_identifier %}
{{ current_player.target_identifier }}
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="flexible_form_container admin-asynchronous-form" style="margin-top: var(--spacing-small);">
<input type="hidden" name="action_type" value="change_target">
<input type="hidden" name="player_identifier" value="{{ current_player.player_identifier }}">
<select name="new_target_identifier" class="text-input small-input">
{% for possible_target in all_players %}
{% if possible_target.is_alive and possible_target.player_identifier != current_player.player_identifier %}
<option value="{{ possible_target.player_identifier }}" {% if current_player.target_identifier == possible_target.player_identifier %}selected{% endif %}>{{ possible_target.display_name }}</option>
{% endif %}
{% endfor %}
</select>
<button type="submit" class="action-button secondary-button small-button"><i data-lucide="refresh-cw"></i></button>
</form>
{% else %}
-
{% endif %}
</td>
<td>
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="flexible_form_container admin-asynchronous-form">
<input type="hidden" name="action_type" value="generate_reset">
<input type="hidden" name="player_identifier" value="{{ current_player.player_identifier }}">
<button type="submit" class="action-button secondary-button small-button"><i data-lucide="link"></i> Reset Link</button>
</form>
{% if current_player.reset_token %}
<input type="text" readonly value="{{ url_for('handle_password_reset', token=current_player.reset_token, _external=True) }}" class="text-input small-input" style="margin: var(--spacing-small) 0;">
{% endif %}
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="flexible_form_container admin-asynchronous-form" style="margin-top: var(--spacing-small);">
<input type="hidden" name="action_type" value="delete_player">
<input type="hidden" name="player_identifier" value="{{ current_player.player_identifier }}">
<button type="submit" class="action-button danger-button small-button"><i data-lucide="trash-2"></i></button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div id="kill-panel" class="tab-content">
<div class="content-card" style="overflow-x: auto;">
<table class="data-table">
<thead>
<tr>
<th>Zeitpunkt</th>
<th>Killer</th>
<th>Opfer</th>
<th>Status</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for report in kill_logs %}
<tr>
<td>{{ report.kill_timestamp[:16].replace('T', ' ') if report.kill_timestamp else '-' }}</td>
<td>{{ report.killer_name or 'Unbekannt' }} ({{ report.killer_identifier }})</td>
<td>{{ report.victim_name or 'Unbekannt' }} ({{ report.victim_identifier }})</td>
<td>
{% if report.report_status == 'confirmed' %}
<span class="status-pill success-pill" style="margin-left: 0;">Bestätigt</span>
{% elif report.report_status == 'pending' %}
<span class="status-pill warning-pill" style="margin-left: 0;">Ausstehend</span>
{% elif report.report_status == 'rejected' %}
<span class="status-pill danger-pill" style="margin-left: 0;">Abgelehnt</span>
{% elif report.report_status == 'revoked' %}
<span class="status-pill danger-pill" style="margin-left: 0;">Widerrufen</span>
{% else %}
{{ report.report_status }}
{% endif %}
</td>
<td>
{% if report.report_status == 'confirmed' %}
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="flexible_form_container admin-asynchronous-form">
<input type="hidden" name="action_type" value="revoke_kill">
<input type="hidden" name="kill_identifier" value="{{ report.kill_identifier }}">
<button type="submit" class="action-button danger-button small-button"><i data-lucide="rotate-ccw"></i> Rückgängig</button>
</form>
{% endif %}
{% if report.report_status == 'pending' %}
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="flexible_form_container admin-asynchronous-form">
<input type="hidden" name="action_type" value="force_confirm_report">
<input type="hidden" name="kill_identifier" value="{{ report.kill_identifier }}">
<button type="submit" class="action-button success-button small-button"><i data-lucide="check"></i> Bestätigen</button>
</form>
{% endif %}
{% if report.report_status in ['pending', 'rejected', 'revoked'] %}
<form action="{{ url_for('handle_administrator_action') }}" method="POST" class="flexible_form_container admin-asynchronous-form" style="margin-top: var(--spacing-small);">
<input type="hidden" name="action_type" value="delete_report">
<input type="hidden" name="kill_identifier" value="{{ report.kill_identifier }}">
<button type="submit" class="action-button secondary-button small-button"><i data-lucide="trash-2"></i> Löschen</button>
</form>
{% endif %}
</td>
</tr>
{% else %}
<tr>
<td colspan="5" style="text-align: center; opacity: 0.6;">Keine Meldungen.</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div id="admin-confirmation-modal" class="modal-overlay">
<div class="modal-dialog">
<h2 class="modal-title"><i data-lucide="calendar-clock"></i> Aktion planen</h2>
<p class="modal-description">Sofort ausführen oder planen.</p>
<div class="form-group" style="margin-bottom: var(--spacing-large); text-align: left;">
<label for="modal_execution_time" class="input-label">Zeitpunkt (Optional)</label>
<input type="datetime-local" id="modal_execution_time" class="text-input time-input" style="width: 100%; box-sizing: border-box;">
</div>
<div class="modal-actions">
<button type="button" id="confirm-admin-action" class="action-button success-button"><i data-lucide="check"></i> Bestätigen</button>
<button type="button" id="cancel-admin-action" class="action-button secondary-button"><i data-lucide="x"></i> Abbrechen</button>
</div>
</div>
</div>
{% endif %}
</section>
{% endblock %}