nvj-turnierplaner2/planning.html
2026-01-07 23:42:36 +01:00

722 lines
20 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, maximum-scale=1.0, user-scalable=no">
<title>Turnierplaner - Planung</title>
<link rel="stylesheet" href="styles.css">
<style>
.planning-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 15px;
background: white;
border-radius: 8px;
margin-bottom: 15px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
flex-shrink: 0;
gap: 10px;
}
.back-btn {
background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
color: white;
border: none;
padding: 10px 16px;
border-radius: 4px;
cursor: pointer;
font-weight: 600;
min-height: 44px;
touch-action: manipulation;
transition: transform 0.3s;
white-space: nowrap;
}
.back-btn:hover {
transform: translateY(-2px);
}
.menu-bar {
display: flex;
gap: 10px;
background: white;
padding: 12px 15px;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
flex-shrink: 0;
flex-wrap: wrap;
}
.menu-btn {
background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
color: white;
border: none;
padding: 12px 20px;
border-radius: 4px;
cursor: pointer;
font-weight: 600;
font-size: 0.95em;
min-height: 44px;
touch-action: manipulation;
transition: transform 0.3s;
white-space: nowrap;
}
.menu-btn:hover {
transform: translateY(-2px);
}
.timer-section {
display: flex;
align-items: center;
gap: 10px;
background: #f8f9fa;
padding: 10px 15px;
border-radius: 4px;
}
.timer-display {
font-size: 1.5em;
font-weight: bold;
color: #2ecc71;
font-family: 'Courier New', monospace;
min-width: 80px;
}
.timer-control-btn {
background: #2ecc71;
color: white;
border: none;
padding: 8px 12px;
border-radius: 4px;
cursor: pointer;
font-weight: 600;
min-height: 40px;
touch-action: manipulation;
font-size: 0.85em;
}
.timer-control-btn:hover {
background: #27ae60;
}
.timer-input {
width: 100px;
padding: 8px 10px;
border: 2px solid #2ecc71;
border-radius: 4px;
font-size: 0.95em;
text-align: center;
min-height: 40px;
}
.timer-input:focus {
outline: none;
border-color: #27ae60;
box-shadow: 0 0 0 3px rgba(46, 204, 113, 0.1);
}
.fields-container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 15px;
margin-bottom: 15px;
flex: 1;
overflow: hidden;
}
@media (max-width: 768px) {
.fields-container {
grid-template-columns: 1fr;
}
}
.fields-section {
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
height: 100%;
}
.fields-header {
padding: 15px;
background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
color: white;
flex-shrink: 0;
}
.fields-header h3 {
margin: 0;
font-size: 1.2em;
}
.fields-grid {
padding: 15px;
overflow-y: auto;
flex: 1;
display: grid;
grid-template-columns: 120px 1fr 1fr;
gap: 12px;
-webkit-overflow-scrolling: touch;
}
.field-info-box {
background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
color: white;
padding: 12px;
border-radius: 6px;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
font-weight: 600;
min-height: 60px;
border: 2px solid #1e8449;
font-size: 1.2em;
}
.field-info-number {
font-size: 1.2em;
}
.field-info-team {
display: none;
-webkit-box-orient: vertical;
}
.waiting-teams-section {
background: #f8f9fa;
padding: 15px;
border-top: 2px solid #e0e0e0;
flex-shrink: 0;
}
.waiting-teams-label {
font-weight: 600;
color: #333;
margin-bottom: 10px;
font-size: 0.95em;
}
.waiting-teams-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.waiting-team-badge {
background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
color: white;
padding: 8px 12px;
border-radius: 20px;
font-size: 0.85em;
font-weight: 500;
display: inline-flex;
align-items: center;
gap: 6px;
}
.waiting-team-badge::before {
content: "⏳";
}
.no-waiting-teams {
color: #999;
font-style: italic;
font-size: 0.9em;
}
.field-card {
background: #f8f9fa;
padding: 15px;
border-radius: 6px;
border: 2px solid #e0e0e0;
cursor: pointer;
transition: all 0.3s;
text-align: center;
min-height: 80px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.field-card:hover {
border-color: #2ecc71;
background: #f0fdf4;
transform: translateY(-2px);
}
.field-card-content {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
width: 100%;
}
.team-name {
font-size: 0.9em;
color: #333;
font-weight: 500;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 100%;
}
.score-input {
width: 50px;
padding: 6px;
font-size: 0.95em;
border: 1px solid #ddd;
border-radius: 4px;
text-align: center;
}
/* Modal Styles */
.modal {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
animation: fadeIn 0.3s;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.modal-content {
background: white;
margin: 5% auto;
padding: 20px;
border-radius: 8px;
width: 90%;
max-width: 500px;
max-height: 80vh;
overflow-y: auto;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
animation: slideIn 0.3s;
}
@keyframes slideIn {
from {
transform: translateY(-50px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 2px solid #2ecc71;
}
.modal-header h2 {
margin: 0;
font-size: 1.5em;
color: #333;
}
.close-btn {
background: none;
border: none;
font-size: 1.8em;
cursor: pointer;
color: #999;
transition: color 0.3s;
}
.close-btn:hover {
color: #333;
}
.modal-form {
display: flex;
flex-direction: column;
gap: 15px;
}
.form-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.form-group label {
font-weight: 600;
color: #333;
}
.form-group input,
.form-group select {
padding: 12px;
border: 2px solid #ddd;
border-radius: 4px;
font-size: 1em;
min-height: 44px;
font-family: inherit;
}
.form-group input:focus,
.form-group select:focus {
outline: none;
border-color: #2ecc71;
box-shadow: 0 0 0 3px rgba(46, 204, 113, 0.1);
}
.modal-footer {
display: flex;
gap: 10px;
justify-content: flex-end;
margin-top: 20px;
padding-top: 15px;
border-top: 2px solid #f0f0f0;
}
.modal-footer button {
padding: 12px 24px;
border: none;
border-radius: 4px;
font-weight: 600;
cursor: pointer;
min-height: 44px;
touch-action: manipulation;
transition: transform 0.3s;
}
.cancel-btn {
background: #f0f0f0;
color: #333;
}
.cancel-btn:hover {
transform: translateY(-2px);
}
.submit-btn {
background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
color: white;
}
.submit-btn:hover {
transform: translateY(-2px);
}
.points-display-content {
display: flex;
flex-direction: column;
gap: 30px;
max-height: 70vh;
overflow-y: auto;
}
.league-points-section {
border: 2px solid #2ecc71;
border-radius: 8px;
overflow: hidden;
}
.league-points-header {
background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
color: white;
padding: 12px 15px;
font-weight: 600;
font-size: 1.05em;
}
.points-table {
width: 100%;
border-collapse: collapse;
font-size: 0.9em;
}
.points-table th,
.points-table td {
padding: 10px;
border: 1px solid #e0e0e0;
text-align: center;
}
.points-table th {
background: #f0fdf4;
font-weight: 600;
color: #2ecc71;
}
.points-table td:first-child,
.points-table th:first-child {
text-align: left;
padding-left: 12px;
min-width: 120px;
}
.points-table tr:nth-child(even) {
background: #fafbfc;
}
.points-table tr:hover {
background: #f0fdf4;
}
.points-value {
font-weight: 600;
padding: 6px 8px;
border-radius: 4px;
min-width: 40px;
}
.points-value.positive {
background: #d4edda;
color: #155724;
}
.points-value.negative {
background: #f8d7da;
color: #721c24;
}
.points-value.neutral {
background: #e2e3e5;
color: #383d41;
}
.points-total {
font-weight: 700;
background: #2ecc71;
color: white;
border-radius: 4px;
}
.scoreboard-content {
display: flex;
flex-direction: column;
gap: 20px;
max-height: 70vh;
overflow-y: auto;
}
.scoreboard-league {
border: 2px solid #3498db;
border-radius: 8px;
overflow: hidden;
}
.scoreboard-league-header {
background: linear-gradient(135deg, #3498db 0%, #2980b9 100%);
color: white;
padding: 12px 15px;
font-weight: 600;
font-size: 1.05em;
}
.scoreboard-list {
list-style: none;
padding: 0;
margin: 0;
}
.scoreboard-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 15px;
border-bottom: 1px solid #e0e0e0;
transition: background 0.2s;
}
.scoreboard-item:last-child {
border-bottom: none;
}
.scoreboard-item:hover {
background: #f0f8ff;
}
.scoreboard-rank {
font-size: 1.3em;
font-weight: 700;
color: #3498db;
min-width: 35px;
text-align: center;
}
.scoreboard-team-name {
flex: 1;
margin: 0 15px;
font-weight: 500;
color: #333;
}
.scoreboard-points {
background: #3498db;
color: white;
padding: 6px 12px;
border-radius: 20px;
font-weight: 700;
min-width: 70px;
text-align: center;
}
.scoreboard-points.positive {
background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
}
.scoreboard-points.negative {
background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
}
</style>
</head>
<body>
<div class="container">
<div class="planning-header">
<button class="back-btn" onclick="goBack()">← Zurück</button>
<h1 style="flex: 1; text-align: center; margin: 0; font-size: 1.3em; color: #333;">🏐 Turnierplanung</h1>
</div>
<div class="menu-bar">
<button class="menu-btn" onclick="openPointsModal()">📊 Punkte anzeigen</button>
<button class="menu-btn" onclick="openScoreboard()" style="background: linear-gradient(135deg, #3498db 0%, #2980b9 100%);">🏆 Scoreboard</button>
<button class="menu-btn" onclick="nextRound()" style="background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%); margin-left: auto; margin-right: auto;">⚡ Nächste Runde</button>
<button class="menu-btn" onclick="confirmReset()" style="background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%); margin-left: auto;">🔄 Zurücksetzen</button>
<div style="margin-left: auto; display: flex; align-items: center; gap: 10px;">
<span style="font-weight: 600; color: #333;">Spielzeit:</span>
<div class="timer-section">
<div class="timer-display" id="timerDisplay">00:00</div>
<button class="timer-control-btn" id="timerBtn" onclick="toggleTimer()">Start</button>
<input type="text" class="timer-input" id="timerInput" placeholder="Sek. oder MM:SS" title="Sekunden oder MM:SS eingeben und Enter drücken">
</div>
</div>
</div>
<div class="fields-container">
<!-- Bundesliga Felder -->
<div class="fields-section">
<div class="fields-header">
<h3>Bundesliga</h3>
</div>
<div class="fields-grid" id="bundesliga-fields">
</div>
<div class="waiting-teams-section">
<div class="waiting-teams-label">Wartende Teams:</div>
<div class="waiting-teams-list" id="bundesliga-waiting">
</div>
</div>
</div>
<!-- Champions League Felder -->
<div class="fields-section">
<div class="fields-header">
<h3>Champions League</h3>
</div>
<div class="fields-grid" id="champions-fields">
</div>
<div class="waiting-teams-section">
<div class="waiting-teams-label">Wartende Teams:</div>
<div class="waiting-teams-list" id="champions-waiting">
</div>
</div>
</div>
</div>
</div>
<!-- Punkte Modal -->
<div id="pointsModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h2>Punkte anzeigen</h2>
<button class="close-btn" onclick="closePointsModal()">×</button>
</div>
<div class="points-display-content" id="pointsDisplayContent">
<!-- Wird dynamisch gefüllt -->
</div>
</div>
</div>
<!-- Scoreboard Modal -->
<div id="scoreboardModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h2>🏆 Scoreboard</h2>
<button class="close-btn" onclick="closeScoreboard()">×</button>
</div>
<div class="scoreboard-content" id="scoreboardContent">
<!-- Wird dynamisch gefüllt -->
</div>
</div>
</div>
<!-- Reset Confirmation Modal -->
<div id="resetConfirmModal" class="modal">
<div class="modal-content" style="max-width: 400px;">
<div class="modal-header">
<h2>⚠️ Turnier zurücksetzen</h2>
<button class="close-btn" onclick="closeResetConfirm()">×</button>
</div>
<div style="padding: 20px; text-align: center;">
<p style="color: #333; margin-bottom: 20px; font-size: 1.05em;">
Alle Runden, Scores und Punkte werden gelöscht. Dieser Vorgang kann nicht rückgängig gemacht werden!
</p>
<div style="display: flex; gap: 10px; justify-content: center;">
<button class="cancel-btn" onclick="closeResetConfirm()">Abbrechen</button>
<button class="submit-btn" style="background: #e74c3c;" onclick="performReset()">Ja, Zurücksetzen</button>
</div>
</div>
</div>
</div>
<!-- Ergebnisse Modal (nicht mehr verwendet) -->
<div id="resultsModal" class="modal" style="display: none;">
<div class="modal-content">
<div class="modal-header">
<h2>Ergebnisse eintragen</h2>
<button class="close-btn" onclick="closeResultsModal()">×</button>
</div>
<form class="modal-form" onsubmit="saveResults(event)">
<div class="form-group">
<label for="resultsField">Feld:</label>
<select id="resultsField" required>
<option value="">-- Feld wählen --</option>
</select>
</div>
<div class="form-group">
<label for="resultsTeam">Team:</label>
<input type="text" id="resultsTeam" placeholder="Teamname" readonly>
</div>
<div class="form-group">
<label for="resultsSets">Sätze gewonnen:</label>
<input type="number" id="resultsSets" min="0" placeholder="z.B. 2" required>
</div>
<div class="form-group">
<label for="resultsOpponent">Gegnerischer Team:</label>
<input type="text" id="resultsOpponent" placeholder="Name des Gegners">
</div>
<div class="modal-footer">
<button type="button" class="cancel-btn" onclick="closeResultsModal()">Abbrechen</button>
<button type="submit" class="submit-btn">Speichern</button>
</div>
</form>
</div>
</div>
<script src="planning.js"></script>
</body>
</html>