457 lines
15 KiB
PHP
457 lines
15 KiB
PHP
<?php
|
|
require_once __DIR__ . '/../../includes/auth.php';
|
|
require_once __DIR__ . '/../../includes/config.php';
|
|
require_once __DIR__ . '/../../includes/header.php';
|
|
require_once __DIR__ . '/../../includes/sidebar.php';
|
|
?>
|
|
|
|
<div class="admin-content">
|
|
<style>
|
|
.admin-page-title {
|
|
font-size: 24px;
|
|
font-weight: 600;
|
|
color: #23282d;
|
|
margin-bottom: 20px;
|
|
padding-bottom: 10px;
|
|
border-bottom: 2px solid #0073aa;
|
|
}
|
|
|
|
.admin-content-box {
|
|
background: #fff;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
padding: 30px;
|
|
margin-top: 20px;
|
|
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
|
}
|
|
|
|
.matches-controls {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 20px;
|
|
gap: 15px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.matches-filters {
|
|
display: flex;
|
|
gap: 10px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.matches-filters input,
|
|
.matches-filters select {
|
|
padding: 8px 12px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.matches-filters button {
|
|
padding: 8px 16px;
|
|
background-color: #0073aa;
|
|
color: white;
|
|
border: none;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
transition: background-color 0.2s;
|
|
}
|
|
|
|
.matches-filters button:hover {
|
|
background-color: #005a87;
|
|
}
|
|
|
|
.matches-table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.matches-table thead {
|
|
background-color: #f5f5f5;
|
|
border-bottom: 2px solid #ddd;
|
|
}
|
|
|
|
.matches-table th {
|
|
padding: 12px;
|
|
text-align: left;
|
|
font-weight: 600;
|
|
color: #333;
|
|
cursor: pointer;
|
|
user-select: none;
|
|
}
|
|
|
|
.matches-table th:hover {
|
|
background-color: #e8e8e8;
|
|
}
|
|
|
|
.matches-table td {
|
|
padding: 12px;
|
|
border-bottom: 1px solid #ddd;
|
|
}
|
|
|
|
.matches-table tbody tr:hover {
|
|
background-color: #f9f9f9;
|
|
}
|
|
|
|
.status-badge {
|
|
display: inline-block;
|
|
padding: 4px 12px;
|
|
border-radius: 12px;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.status-live {
|
|
background-color: #ff4444;
|
|
color: white;
|
|
}
|
|
|
|
.status-planned {
|
|
background-color: #0073aa;
|
|
color: white;
|
|
}
|
|
|
|
.status-end {
|
|
background-color: #28a745;
|
|
color: white;
|
|
}
|
|
|
|
.pagination {
|
|
display: flex;
|
|
justify-content: center;
|
|
gap: 10px;
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.pagination button,
|
|
.pagination span {
|
|
padding: 8px 12px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
background: white;
|
|
transition: all 0.2s;
|
|
}
|
|
|
|
.pagination button:hover {
|
|
background-color: #0073aa;
|
|
color: white;
|
|
border-color: #0073aa;
|
|
}
|
|
|
|
.pagination button:disabled {
|
|
opacity: 0.5;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.pagination .active {
|
|
background-color: #0073aa;
|
|
color: white;
|
|
border-color: #0073aa;
|
|
}
|
|
|
|
.loading {
|
|
text-align: center;
|
|
padding: 40px;
|
|
color: #666;
|
|
}
|
|
|
|
.error-message {
|
|
background-color: #f8d7da;
|
|
color: #721c24;
|
|
padding: 12px;
|
|
border-radius: 4px;
|
|
margin-bottom: 20px;
|
|
border: 1px solid #f5c6cb;
|
|
}
|
|
|
|
.no-data {
|
|
text-align: center;
|
|
padding: 40px;
|
|
color: #999;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.matches-table {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.matches-table th,
|
|
.matches-table td {
|
|
padding: 8px;
|
|
}
|
|
|
|
.matches-controls {
|
|
flex-direction: column;
|
|
align-items: stretch;
|
|
}
|
|
|
|
.matches-filters {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.matches-filters input,
|
|
.matches-filters select,
|
|
.matches-filters button {
|
|
width: 100%;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<h1 class="admin-page-title">🎮 Wszystkie mecze</h1>
|
|
|
|
<div class="admin-content-box">
|
|
<!-- Kontrolki filtrowania -->
|
|
<div class="matches-controls">
|
|
<div class="matches-filters">
|
|
<select id="statusFilter" onchange="applyFilters()">
|
|
<option value="">Wszystkie statusy</option>
|
|
<option value="planned">Zaplanowane</option>
|
|
<option value="live">Trwające</option>
|
|
<option value="end">Zakończone</option>
|
|
</select>
|
|
|
|
<select id="platformFilter" onchange="applyFilters()">
|
|
<option value="">Wszystkie platformy</option>
|
|
<option value="PC">PC</option>
|
|
<option value="PSP">PSP</option>
|
|
<option value="android">Android</option>
|
|
<option value="iphone">iPhone</option>
|
|
</select>
|
|
|
|
<select id="matchTypeFilter" onchange="applyFilters()">
|
|
<option value="">Wszystkie typy</option>
|
|
<option value="liga">Liga</option>
|
|
<option value="turniej">Turniej</option>
|
|
<option value="przyjacielski">Przyjacielski</option>
|
|
</select>
|
|
|
|
<button onclick="resetFilters()">Resetuj filtry</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tabela z meczami -->
|
|
<div id="loadingIndicator" class="loading" style="display: none;">
|
|
⏳ Wczytywanie danych...
|
|
</div>
|
|
|
|
<div id="errorContainer" style="display: none;"></div>
|
|
|
|
<table class="matches-table" id="matchesTable" style="display: none;">
|
|
<thead>
|
|
<tr>
|
|
<th onclick="sortBy('ID')">ID ↕️</th>
|
|
<th onclick="sortBy('Team1_ID')">Drużyna 1 ↕️</th>
|
|
<th onclick="sortBy('Team2_ID')">Drużyna 2 ↕️</th>
|
|
<th onclick="sortBy('StartTime')">Data/Czas ↕️</th>
|
|
<th onclick="sortBy('Status')">Status ↕️</th>
|
|
<th>Wynik</th>
|
|
<th>Platforma</th>
|
|
<th>Typ</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="matchesBody">
|
|
</tbody>
|
|
</table>
|
|
|
|
<div id="noDataContainer" class="no-data" style="display: none;">
|
|
Brak meczów do wyświetlenia
|
|
</div>
|
|
|
|
<!-- Paginacja -->
|
|
<div class="pagination" id="paginationContainer" style="display: none;">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
let currentPage = 1;
|
|
let currentSort = 'StartTime';
|
|
let currentSortOrder = 'ASC';
|
|
|
|
function mapStatusClass(status) {
|
|
const statusLower = status.toLowerCase();
|
|
if (statusLower.includes('live') || statusLower.includes('trakcie')) return 'status-live';
|
|
if (statusLower.includes('planned') || statusLower.includes('zaplanow')) return 'status-planned';
|
|
if (statusLower.includes('end') || statusLower.includes('zakończ')) return 'status-end';
|
|
return 'status-planned';
|
|
}
|
|
|
|
function loadMatches(page = 1) {
|
|
const statusFilter = document.getElementById('statusFilter').value;
|
|
const platformFilter = document.getElementById('platformFilter').value;
|
|
const matchTypeFilter = document.getElementById('matchTypeFilter').value;
|
|
|
|
let url = '/api/getMatches.php?page=' + page + '&limit=20&sortBy=' + currentSort + '&sortOrder=' + currentSortOrder;
|
|
|
|
if (statusFilter) url += '&status=' + encodeURIComponent(statusFilter);
|
|
if (platformFilter) url += '&platform=' + encodeURIComponent(platformFilter);
|
|
if (matchTypeFilter) url += '&matchType=' + encodeURIComponent(matchTypeFilter);
|
|
|
|
document.getElementById('loadingIndicator').style.display = 'block';
|
|
document.getElementById('matchesTable').style.display = 'none';
|
|
document.getElementById('noDataContainer').style.display = 'none';
|
|
document.getElementById('errorContainer').style.display = 'none';
|
|
document.getElementById('paginationContainer').style.display = 'none';
|
|
|
|
fetch(url)
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error('Błąd HTTP ' + response.status);
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
document.getElementById('loadingIndicator').style.display = 'none';
|
|
|
|
if (!data.success) {
|
|
showError(data.error || 'Nieznany błąd');
|
|
return;
|
|
}
|
|
|
|
if (data.data.length === 0) {
|
|
document.getElementById('noDataContainer').style.display = 'block';
|
|
return;
|
|
}
|
|
|
|
displayMatches(data.data);
|
|
displayPagination(data.pagination);
|
|
|
|
document.getElementById('matchesTable').style.display = 'table';
|
|
document.getElementById('paginationContainer').style.display = 'flex';
|
|
|
|
currentPage = page;
|
|
})
|
|
.catch(error => {
|
|
document.getElementById('loadingIndicator').style.display = 'none';
|
|
showError('Błąd podczas ładowania meczów: ' + error.message);
|
|
});
|
|
}
|
|
|
|
function displayMatches(matches) {
|
|
const tbody = document.getElementById('matchesBody');
|
|
tbody.innerHTML = '';
|
|
|
|
matches.forEach(match => {
|
|
const row = document.createElement('tr');
|
|
|
|
// Formatowanie daty
|
|
const startTime = new Date(match.StartTime);
|
|
const dateStr = startTime.toLocaleDateString('pl-PL') + ' ' + startTime.toLocaleTimeString('pl-PL', { hour: '2-digit', minute: '2-digit' });
|
|
|
|
row.innerHTML = `
|
|
<td><strong>${match.ID}</strong></td>
|
|
<td>${match.Team1_ID}</td>
|
|
<td>${match.Team2_ID}</td>
|
|
<td>${dateStr}</td>
|
|
<td><span class="status-badge ${mapStatusClass(match.Status)}">${match.Status}</span></td>
|
|
<td>${match.Score || '-'}</td>
|
|
<td>${match.Platform || '-'}</td>
|
|
<td>${match.MatchType || '-'}</td>
|
|
`;
|
|
tbody.appendChild(row);
|
|
});
|
|
}
|
|
|
|
function displayPagination(pagination) {
|
|
const container = document.getElementById('paginationContainer');
|
|
container.innerHTML = '';
|
|
|
|
// Poprzednia strona
|
|
if (pagination.hasPreviousPage) {
|
|
const prevBtn = document.createElement('button');
|
|
prevBtn.textContent = '← Poprzednia';
|
|
prevBtn.onclick = () => loadMatches(pagination.currentPage - 1);
|
|
container.appendChild(prevBtn);
|
|
}
|
|
|
|
// Numery stron
|
|
const startPage = Math.max(1, pagination.currentPage - 2);
|
|
const endPage = Math.min(pagination.totalPages, pagination.currentPage + 2);
|
|
|
|
if (startPage > 1) {
|
|
const firstBtn = document.createElement('button');
|
|
firstBtn.textContent = '1';
|
|
firstBtn.onclick = () => loadMatches(1);
|
|
container.appendChild(firstBtn);
|
|
|
|
if (startPage > 2) {
|
|
const dots = document.createElement('span');
|
|
dots.textContent = '...';
|
|
container.appendChild(dots);
|
|
}
|
|
}
|
|
|
|
for (let i = startPage; i <= endPage; i++) {
|
|
const btn = document.createElement('button');
|
|
btn.textContent = i;
|
|
if (i === pagination.currentPage) {
|
|
btn.classList.add('active');
|
|
}
|
|
btn.onclick = () => loadMatches(i);
|
|
container.appendChild(btn);
|
|
}
|
|
|
|
if (endPage < pagination.totalPages) {
|
|
if (endPage < pagination.totalPages - 1) {
|
|
const dots = document.createElement('span');
|
|
dots.textContent = '...';
|
|
container.appendChild(dots);
|
|
}
|
|
|
|
const lastBtn = document.createElement('button');
|
|
lastBtn.textContent = pagination.totalPages;
|
|
lastBtn.onclick = () => loadMatches(pagination.totalPages);
|
|
container.appendChild(lastBtn);
|
|
}
|
|
|
|
// Następna strona
|
|
if (pagination.hasNextPage) {
|
|
const nextBtn = document.createElement('button');
|
|
nextBtn.textContent = 'Następna →';
|
|
nextBtn.onclick = () => loadMatches(pagination.currentPage + 1);
|
|
container.appendChild(nextBtn);
|
|
}
|
|
}
|
|
|
|
function sortBy(column) {
|
|
if (currentSort === column) {
|
|
currentSortOrder = currentSortOrder === 'ASC' ? 'DESC' : 'ASC';
|
|
} else {
|
|
currentSort = column;
|
|
currentSortOrder = 'ASC';
|
|
}
|
|
loadMatches(1);
|
|
}
|
|
|
|
function applyFilters() {
|
|
loadMatches(1);
|
|
}
|
|
|
|
function resetFilters() {
|
|
document.getElementById('statusFilter').value = '';
|
|
document.getElementById('platformFilter').value = '';
|
|
document.getElementById('matchTypeFilter').value = '';
|
|
loadMatches(1);
|
|
}
|
|
|
|
function showError(message) {
|
|
const errorContainer = document.getElementById('errorContainer');
|
|
errorContainer.innerHTML = '<div class="error-message">' + message + '</div>';
|
|
errorContainer.style.display = 'block';
|
|
}
|
|
|
|
// Załaduj mecze przy ładowaniu strony
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
loadMatches(1);
|
|
});
|
|
</script>
|
|
|
|
<?php
|
|
require_once __DIR__ . '/../../includes/footer.php';
|
|
?>
|