togethere.cloud/public_html/administration/matches/planned/index.php

144 lines
8.2 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:24px;margin-top:20px;box-shadow:0 1px 3px rgba(0,0,0,.1)}
.filters-bar{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px;align-items:center}
.filters-bar input,.filters-bar select{padding:6px 10px;border:1px solid #ddd;border-radius:4px;font-size:12px}
.filters-bar button{padding:6px 12px;background:#6c757d;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:12px}
.filters-bar button:hover{background:#5a6268}
.matches-table{width:100%;border-collapse:collapse}
.matches-table thead{background:#f5f5f5;border-bottom:2px solid #ddd}
.matches-table th{padding:9px 11px;text-align:left;font-weight:600;color:#333;font-size:12px}
.matches-table td{padding:8px 11px;border-bottom:1px solid #eee;font-size:12px}
.matches-table tbody tr:hover{background:#f9f9f9}
.no-data{text-align:center;padding:20px;color:#aaa;font-size:12px}
.total-info{font-size:11px;color:#888;margin-bottom:8px}
.pagination{display:flex;justify-content:center;gap:5px;margin-top:14px;flex-wrap:wrap}
.pagination button{padding:5px 10px;border:1px solid #ddd;border-radius:4px;cursor:pointer;background:#fff;font-size:12px}
.pagination button:hover{background:#0073aa;color:#fff;border-color:#0073aa}
.pagination .active{background:#0073aa;color:#fff;border-color:#0073aa}
.error-box{background:#f8d7da;color:#721c24;padding:10px 12px;border-radius:4px;border:1px solid #f5c6cb;font-size:12px;margin-bottom:10px}
.btn-del{background:#dc3545;color:#fff;border:none;border-radius:3px;padding:3px 9px;font-size:11px;cursor:pointer;line-height:1.4}
.btn-del:hover{background:#b02a37}
</style>
<h1 class="admin-page-title">Mecze - Zaplanowane</h1>
<div class="admin-content-box">
<div class="filters-bar">
<input type="text" id="f-id" placeholder="ID meczu" oninput="load(1)" style="width:80px">
<input type="text" id="f-user" placeholder="Gracz / ID..." oninput="debounce()" style="min-width:160px">
<select id="f-disc" onchange="load(1)">
<option value="">Wszystkie dyscypliny</option>
<option value="ping-pong">Ping-Pong</option>
<option value="table-football">Pilkarzyki</option>
<option value="rock-paper-scissors">Kamien, papier, nozyce</option>
</select>
<input type="date" id="f-dfrom" onchange="load(1)" title="Data od">
<input type="date" id="f-dto" onchange="load(1)" title="Data do">
<select id="f-sort" onchange="load(1)">
<option value="id">Sortuj: ID</option>
<option value="started_at">Sortuj: Zaplanowane</option>
<option value="user1_username">Sortuj: Gracz 1</option>
<option value="user2_username">Sortuj: Gracz 2</option>
</select>
<select id="f-order" onchange="load(1)"><option value="DESC">Malejaco</option><option value="ASC">Rosnaco</option></select>
<button onclick="reset()">Resetuj</button>
</div>
<div id="m-total" class="total-info" style="display:none"></div>
<div id="m-error"></div>
<div id="m-empty" class="no-data" style="display:none">Brak zaplanowanych meczow</div>
<table class="matches-table" id="m-table" style="display:none">
<thead><tr>
<th>ID</th><th>Dyscyplina</th><th>Gracz 1</th><th>Gracz 2</th>
<th>Platforma</th><th>Typ</th><th>Zaplanowane</th><th></th>
</tr></thead>
<tbody id="m-tbody"></tbody>
</table>
<div class="pagination" id="m-pages" style="display:none"></div>
</div>
</div>
<script>
var curPage=1,dTimer=null;
function val(id){return document.getElementById(id).value;}
function debounce(){clearTimeout(dTimer);dTimer=setTimeout(function(){load(1);},400);}
function reset(){
['f-id','f-user','f-disc','f-dfrom','f-dto'].forEach(function(i){document.getElementById(i).value='';});
document.getElementById('f-sort').value='id';
document.getElementById('f-order').value='DESC';
load(1);
}
function load(pg){
curPage=pg||1;
var p='status=planned&page='+curPage+'&limit=100';
p+='&sortBy='+encodeURIComponent(val('f-sort'));
p+='&sortOrder='+encodeURIComponent(val('f-order'));
if(val('f-id')) p+='&id='+encodeURIComponent(val('f-id'));
if(val('f-user')) p+='&user='+encodeURIComponent(val('f-user'));
if(val('f-disc')) p+='&discipline='+encodeURIComponent(val('f-disc'));
if(val('f-dfrom')) p+='&date_from='+encodeURIComponent(val('f-dfrom'));
if(val('f-dto')) p+='&date_to='+encodeURIComponent(val('f-dto'));
fetch('/api/admin_matches_list.php?'+p)
.then(function(r){return r.json();})
.then(function(d){
if(!d.success){document.getElementById('m-error').innerHTML='<div class="error-box">'+esc(d.error)+'</div>';return;}
document.getElementById('m-error').innerHTML='';
render(d.rows,d.pagination);
}).catch(function(e){document.getElementById('m-error').innerHTML='<div class="error-box">'+esc(e.message)+'</div>';});
}
function esc(s){return String(s==null?'':s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');}
function fmt(dt){if(!dt)return'-';var d=new Date(dt);return d.toLocaleDateString('pl-PL')+' '+d.toLocaleTimeString('pl-PL',{hour:'2-digit',minute:'2-digit'});}
function render(rows,pag){
var tbody=document.getElementById('m-tbody');
var table=document.getElementById('m-table');
var empty=document.getElementById('m-empty');
var total=document.getElementById('m-total');
var pages=document.getElementById('m-pages');
tbody.innerHTML='';pages.innerHTML='';pages.style.display='none';
if(pag){total.textContent='Lacznie: '+pag.totalRecords+' zaplanowanych';total.style.display='';}
if(!rows||rows.length===0){table.style.display='none';empty.style.display='';return;}
empty.style.display='none';
rows.forEach(function(m){
var tr=document.createElement('tr');
tr.innerHTML=
'<td><strong>'+esc(m.id)+'</strong></td>'+
'<td>'+esc(m.discipline)+'</td>'+
'<td>'+esc(m.user1_username)+' <small style="color:#999">#'+esc(m.user1_id)+'</small></td>'+
'<td>'+esc(m.user2_username)+' <small style="color:#999">#'+esc(m.user2_id)+'</small></td>'+
'<td>'+esc(m.platform||'-')+'</td>'+
'<td>'+esc(m.match_type||'-')+'</td>'+
'<td style="white-space:nowrap">'+fmt(m.started_at)+'</td>'+
'<td><button class="btn-del" onclick="del('+esc(m.id)+',this)">Usun</button></td>';
tbody.appendChild(tr);
});
table.style.display='table';
if(pag&&pag.totalPages>1){renderPag(pag);pages.style.display='flex';}
}
function renderPag(p){
var c=document.getElementById('m-pages');c.innerHTML='';
if(p.hasPreviousPage){var b=document.createElement('button');b.textContent='< Poprzednia';b.onclick=(function(pg){return function(){load(pg);};})(p.currentPage-1);c.appendChild(b);}
var s=Math.max(1,p.currentPage-2),e=Math.min(p.totalPages,p.currentPage+2);
for(var i=s;i<=e;i++){var b2=document.createElement('button');b2.textContent=i;if(i===p.currentPage)b2.classList.add('active');b2.onclick=(function(_i){return function(){load(_i);};})(i);c.appendChild(b2);}
if(p.hasNextPage){var b3=document.createElement('button');b3.textContent='Nastepna >';b3.onclick=(function(pg){return function(){load(pg);};})(p.currentPage+1);c.appendChild(b3);}
}
function del(id,btn){
if(!confirm('Usunac zaplanowany mecz #'+id+' z bazy?'))return;
btn.disabled=true;btn.textContent='...';
var fd=new FormData();fd.append('type','match');fd.append('id',id);
fetch('/api/admin_delete_match.php',{method:'POST',body:fd})
.then(function(r){return r.json();})
.then(function(d){
if(!d.success){alert('Blad: '+(d.error||'?'));btn.disabled=false;btn.textContent='Usun';return;}
var tr=btn.closest('tr');if(tr)tr.remove();
}).catch(function(e){alert('Blad: '+e.message);btn.disabled=false;btn.textContent='Usun';});
}
document.addEventListener('DOMContentLoaded',function(){load(1);});
</script>
<?php require_once __DIR__ . '/../../includes/footer.php'; ?>