initial commit

This commit is contained in:
2026-01-07 23:42:36 +01:00
commit f67d869005
11 changed files with 2403 additions and 0 deletions

721
planning.html Normal file
View File

@@ -0,0 +1,721 @@
<!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>