Files
segnapunti/storico.html

294 lines
7.1 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Storico Partite</title>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
background: #111;
color: #e0e0e0;
font-family: 'Inter', system-ui, sans-serif;
min-height: 100vh;
padding: 24px 16px;
}
h1 {
text-align: center;
font-size: 22px;
font-weight: 800;
letter-spacing: 0.1em;
color: #fdd835;
text-transform: uppercase;
margin-bottom: 24px;
}
#lista {
max-width: 700px;
margin: 0 auto;
display: flex;
flex-direction: column;
gap: 12px;
}
.card {
background: #1e1e1e;
border: 1px solid rgba(255,255,255,0.1);
border-radius: 16px;
overflow: hidden;
cursor: pointer;
}
.card-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 20px;
gap: 12px;
user-select: none;
}
.card-header:hover {
background: rgba(255,255,255,0.04);
}
.card-data {
font-size: 11px;
color: #777;
white-space: nowrap;
}
.card-teams {
flex: 1;
text-align: center;
}
.card-nomi {
font-size: 16px;
font-weight: 700;
}
.card-result {
font-size: 22px;
font-weight: 900;
letter-spacing: 0.05em;
margin-top: 2px;
}
.card-result .winner { color: #fdd835; }
.card-modalita {
font-size: 11px;
color: #777;
white-space: nowrap;
}
.card-arrow {
font-size: 18px;
color: #555;
transition: transform 0.2s;
}
.card.open .card-arrow { transform: rotate(180deg); }
.card-detail {
display: none;
border-top: 1px solid rgba(255,255,255,0.08);
padding: 16px 20px;
}
.card.open .card-detail { display: block; }
.set-table {
width: 100%;
border-collapse: collapse;
font-size: 13px;
}
.set-table th {
text-align: left;
padding: 6px 8px;
font-size: 11px;
font-weight: 700;
color: #777;
text-transform: uppercase;
letter-spacing: 0.05em;
border-bottom: 1px solid rgba(255,255,255,0.08);
}
.set-table td {
padding: 8px 8px;
vertical-align: top;
border-bottom: 1px solid rgba(255,255,255,0.05);
}
.set-table tr:last-child td { border-bottom: none; }
.set-num {
font-weight: 800;
color: #aaa;
width: 32px;
}
.set-vince {
font-weight: 700;
color: #fdd835;
}
.set-punt {
font-weight: 700;
font-size: 15px;
}
.form-grid {
display: inline-grid;
grid-template-columns: repeat(3, 28px);
grid-template-rows: repeat(2, 24px);
gap: 2px;
background: rgba(255,255,255,0.05);
border-radius: 6px;
padding: 4px;
}
.form-cell {
display: flex;
align-items: center;
justify-content: center;
font-size: 11px;
font-weight: 700;
background: rgba(255,255,255,0.08);
border-radius: 4px;
}
.form-label {
font-size: 11px;
color: #666;
margin-bottom: 4px;
}
.form-wrap {
display: flex;
flex-direction: column;
}
#vuoto {
text-align: center;
color: #555;
padding: 48px 16px;
font-size: 15px;
}
#errore {
text-align: center;
color: #ef5350;
padding: 24px;
}
</style>
</head>
<body>
<h1>Storico Partite</h1>
<div id="lista"></div>
<script>
function formatData(iso) {
const d = new Date(iso)
return d.toLocaleDateString('it-IT', { day: '2-digit', month: '2-digit', year: 'numeric' })
+ ' ' + d.toLocaleTimeString('it-IT', { hour: '2-digit', minute: '2-digit' })
}
// Layout campo: righe [fila attacco 3-2-1, fila difesa 4-5-0] → indici nell'array form
const LAYOUT = [3, 2, 1, 4, 5, 0]
function renderForm(form, label) {
const cells = LAYOUT.map(i => `<div class="form-cell">${form[i] ?? '?'}</div>`).join('')
return `<div class="form-wrap">
<div class="form-label">${label}</div>
<div class="form-grid">${cells}</div>
</div>`
}
function renderDettaglio(dati, nomiHome, nomiGuest) {
if (!dati.strisce || dati.strisce.length === 0) return '<p style="color:#555">Nessun set registrato.</p>'
const righe = dati.strisce.map(s => {
const vince = s.vincitore === 'home' ? nomiHome : nomiGuest
const formHome = s.formInizio?.home ?? []
const formGuest = s.formInizio?.guest ?? []
return `<tr>
<td class="set-num">${s.set}</td>
<td class="set-vince">${vince}</td>
<td class="set-punt">${s.punt.home} ${s.punt.guest}</td>
<td>${renderForm(formHome, nomiHome)}</td>
<td>${renderForm(formGuest, nomiGuest)}</td>
</tr>`
}).join('')
return `<table class="set-table">
<thead>
<tr>
<th>Set</th>
<th>Vincitore</th>
<th>Punteggio</th>
<th>Form Home</th>
<th>Form Guest</th>
</tr>
</thead>
<tbody>${righe}</tbody>
</table>`
}
function renderCard(p) {
const dati = JSON.parse(p.json)
const nomeHome = p.nome_home
const nomeGuest = p.nome_guest
const vincitoreNome = p.vincitore === 'home' ? nomeHome : nomeGuest
const homeWin = p.vincitore === 'home'
const resultHome = homeWin ? `<span class="winner">${p.set_home}</span>` : p.set_home
const resultGuest = homeWin ? p.set_guest : `<span class="winner">${p.set_guest}</span>`
const card = document.createElement('div')
card.className = 'card'
card.innerHTML = `
<div class="card-header">
<div class="card-data">${formatData(p.data)}</div>
<div class="card-teams">
<div class="card-nomi">${nomeHome} vs ${nomeGuest}</div>
<div class="card-result">${resultHome} ${resultGuest}</div>
</div>
<div class="card-modalita">${p.modalita}</div>
<div class="card-arrow"></div>
</div>
<div class="card-detail">
${renderDettaglio(dati, nomeHome, nomeGuest)}
</div>
`
card.querySelector('.card-header').addEventListener('click', () => {
card.classList.toggle('open')
})
return card
}
async function caricaPartite() {
const lista = document.getElementById('lista')
try {
const res = await fetch('/api/partite')
if (!res.ok) throw new Error(`HTTP ${res.status}`)
const partite = await res.json()
if (partite.length === 0) {
lista.innerHTML = '<div id="vuoto">Nessuna partita registrata.</div>'
return
}
partite.forEach(p => lista.appendChild(renderCard(p)))
} catch (err) {
lista.innerHTML = `<div id="errore">Errore caricamento: ${err.message}</div>`
}
}
caricaPartite()
</script>
</body>
</html>