Partido y estadísticas de jugadores body { font-family: Arial, sans-serif; background:#fff; color:#333; margin:0; padding:20px; } #last-match, #events, #alineaciones, #estadisticas { background:#fff; border-radius:8px; box-shadow:0 2px 8px rgba(0,0,0,0.15); padding:20px; max-width:700px; margin:0 auto 20px; } .fecha { font-weight:600; font-size:1.2em; margin-bottom:8px; text-align:center; color:#970800; } .estado { font-size:0.9em; text-align:center; color:#666; margin-bottom:12px; } .resultado { display:flex; justify-content:center; align-items:center; gap:40px; font-size:1.5em; font-weight:bold; margin-bottom:12px; } .equipo { text-align:center; width:120px; } .equipo img { max-width:60px; display:block; margin:0 auto 6px; } .marcador { min-width:80px; text-align:center; color:#970800; } .liga, .lugar { font-size:0.9em; color:#555; text-align:center; margin-bottom:6px; } h2.titulo { text-align:center; color:#b87b00; margin-bottom:16px; font-weight:700; font-size:1.4em; } h3.parte { color:#b87b00; font-weight:600; margin-bottom:10px; } ul.eventos { list-style-type: disc; padding-left:20px; color:#222; font-size:0.95em; margin-bottom:20px; } ul.eventos li { margin-bottom:8px; } .alineaciones-container { display:flex; justify-content:space-between; gap:20px; } .alineacion { flex:1; } .alineacion h3 { text-align:center; } .jugador { display:flex; align-items:center; margin-bottom:6px; font-size:0.9em; } .jugador img { width:24px; height:24px; border-radius:50%; margin-right:6px; } .entrenador { display:flex; align-items:center; justify-content:center; margin-top:10px; font-size:0.9em; } .entrenador img { width:32px; height:32px; border-radius:50%; margin-right:6px; } table.estadisticas { margin:0 auto; border-collapse:collapse; font-size:0.9em; width:60%; } table.estadisticas th, table.estadisticas td { border:1px solid #ccc; padding:6px 8px; text-align:center; } table.estadisticas th { background:#f4f4f4; } .columnas { display:flex; justify-content:space-between; gap:20px; flex-wrap:wrap; } .col-equipo { flex:1; min-width:400px; display:flex; flex-direction:column; gap:20px; } .card-jugadores { background:#fff; border-radius:8px; box-shadow:0 2px 8px rgba(0,0,0,0.12); padding:18px; text-align:center; flex:1; } h1.nombre-equipo { color:#970800; text-align:center; margin-bottom:15px; } table.tabla-jugadores { margin:0 auto 0; border-collapse:collapse; font-size:0.95em; width:100%; text-align:center; } table.tabla-jugadores th, table.tabla-jugadores td { border:1px solid #dcdcdc; padding:8px 10px; vertical-align:middle; } table.tabla-jugadores th { background:#f4f4f4; color:#970800; font-weight:700; } .foto-jugador { width:44px; height:44px; border-radius:50%; object-fit:cover; } @media (min-width: 600px) { .columnas { flex-direction: row; justify-content: space-between; } .col-equipo { min-width:400px; flex-direction:column; } } const ID_PARTIDO = 1391255; const proxyURL = `https://cadiznoticias.es/wp-json/futbol/v1/proxy/fixtures?id=${ID_PARTIDO}`; const nombresStats = { "Shots on Goal": "Tiros a puerta","Shots off Goal": "Tiros fuera","Total Shots": "Tiros totales", "Blocked Shots": "Tiros bloqueados","Shots insidebox": "Tiros dentro del área","Shots outsidebox": "Tiros fuera del área", "Fouls": "Faltas","Corner Kicks": "Córners","Offsides": "Fueras de juego","Ball Possession": "Posesión", "Yellow Cards": "Tarjetas amarillas","Red Cards": "Tarjetas rojas","Goalkeeper Saves": "Paradas", "Total passes": "Pases totales","Passes accurate": "Pases precisos","Passes %": "Precisión de pases" }; function fmt(v, dec=0) { if (v===null||v===undefined||isNaN(Number(v))) return "0"; return Number(v).toFixed(dec); } function formatearFecha(fechaStr){ const fecha=new Date(fechaStr); return fecha.toLocaleDateString("es-ES",{ weekday:'long', day:'numeric', month:'long', hour:'2-digit', minute:'2-digit' }); } async function obtenerPartido() { try { const res = await fetch(proxyURL); if(!res.ok) throw new Error('Error en la respuesta del servidor'); const data = await res.json(); if(!data.response || data.response.length === 0){ document.getElementById("last-match").textContent="No se encontró el partido."; return; } const partido = data.response[0]; const fechaFormateada = formatearFecha(partido.fixture.date); const lugar = partido.fixture.venue ? `${partido.fixture.venue.name}, ${partido.fixture.venue.city || ''}` : 'Lugar por confirmar'; const golesLocal = partido.goals.home!==null ? partido.goals.home : '-'; const golesVisitante = partido.goals.away!==null ? partido.goals.away : '-'; const status = partido.fixture.status || null; let estadoPartido = ''; if(status){ estadoPartido = status.long || status.short || ''; if(status.elapsed!==null && status.elapsed!==undefined){ estadoPartido+=` (${status.elapsed}')`; } } const htmlPartido = ` ${fechaFormateada} ${estadoPartido ? `${estadoPartido}` : ''} ${partido.teams.home.name} ${golesLocal} - ${golesVisitante} ${partido.teams.away.name} ${partido.league.name} - ${partido.league.round} ${lugar} `; document.getElementById("last-match").innerHTML = htmlPartido; if(partido.events && partido.events.length>0){ const eventosOrdenados = partido.events.sort((a,b)=>a.time.elapsed-b.time.elapsed); const eventosPrimera = eventosOrdenados.filter(ev=>ev.time.elapsedev.time.elapsed>45); let htmlEventos = 'Cronología de eventos'; function renderEvento(ev){ const tiempo = ev.time.elapsed + (ev.time.extra?`+${ev.time.extra}`:'') + "'"; const equipo = ev.team?.name || ''; const jugador = ev.player?.name || 'jugador no identificado'; if(ev.type==='subst'){ const entra=ev.assist?.name || 'jugador no identificado'; return `${tiempo} — Cambio ${equipo}: entra ${entra}, sale ${jugador}`; } if(ev.type==='Goal') return `${tiempo} — Gol: ${jugador} (${equipo})`; if(ev.type==='Card'){ const colorTarjeta = ev.detail==='Yellow Card'?'Tarjeta amarilla':ev.detail==='Red Card'?'Tarjeta roja':'Tarjeta'; return `${tiempo} — ${colorTarjeta} para ${jugador} (${equipo})`; } return `${tiempo} — Evento: ${ev.type} - ${jugador} (${equipo})`; } if(eventosPrimera.length>0){ htmlEventos+='1ª parte'+eventosPrimera.map(renderEvento).join('')+''; } if(eventosSegunda.length>0){ htmlEventos+='2ª parte'+eventosSegunda.map(renderEvento).join('')+''; } document.getElementById("events").innerHTML = htmlEventos; } if(partido.lineups && partido.lineups.length>0){ const [lineupLocal,lineupVisitante]=partido.lineups; let htmlAlineaciones='Alineaciones'; function renderJugadores(jugadores){ return jugadores.map(j=>`${j.player.number?j.player.number+' - ':''}${j.player.name}`).join(''); } htmlAlineaciones+=` ${lineupLocal.team.name} ${renderJugadores(lineupLocal.startXI)} Suplentes: ${renderJugadores(lineupLocal.substitutes)} ${lineupLocal.coach.name} (${lineupLocal.formation}) ${lineupVisitante.team.name} ${renderJugadores(lineupVisitante.startXI)} Suplentes: ${renderJugadores(lineupVisitante.substitutes)} ${lineupVisitante.coach.name} (${lineupVisitante.formation}) `; htmlAlineaciones+=''; document.getElementById("alineaciones").innerHTML=htmlAlineaciones; } if(partido.statistics && partido.statistics.length===2){ const [statsLocal,statsVisitante]=partido.statistics; let htmlStats='EstadísticasEstadística'; statsLocal.statistics.forEach((stat,index)=>{ if(stat.type==="expected_goals"||stat.type==="goals_prevented") return; const valorLocal = stat.value!==null ? stat.value : '-'; const valorVisitante = statsVisitante.statistics[index].value!==null ? statsVisitante.statistics[index].value : '-'; const nombreStat = nombresStats[stat.type] || stat.type; htmlStats+=`${valorLocal}${nombreStat}${valorVisitante}`; }); htmlStats+=''; document.getElementById("estadisticas").innerHTML=htmlStats; } } catch(error){ document.getElementById("last-match").textContent="Error al obtener el partido."; console.error(error); } } async function obtenerJugadoresPartido(fixtureId){ const url=`https://cadiznoticias.es/wp-json/futbol/v1/proxy/fixtures/players?fixture=${fixtureId}`; const res=await fetch(url); if(!res.ok) throw new Error(`Error HTTP ${res.status}`); const data=await res.json(); return data.response || []; } function mapJugadorPartido(item){ const p=item.player||{}; const s=(item.statistics && item.statistics[0]) || {}; const goals=s.goals||{}, shots=s.shots||{}, passes=s.passes||{}, tackles=s.tackles||{}; const duels=s.duels||{}, dribbles=s.dribbles||{}, fouls=s.fouls||{}, cards=s.cards||{}, penalty=s.penalty||{}; return { foto:p.photo||'', nombre:p.name||'', goles:goals.total||0, asistencias:goals.assists||0, disparos:shots.total||0, pases:passes.total||0, entradas:tackles.total||0, duelsWon:duels.won||0, duelsTotal:duels.total||0, dribblesSuccess:dribbles.success||0, dribblesAttempts:dribbles.attempts||0, foulsDrawn:fouls.drawn||0, foulsCommitted:fouls.committed||0, amarillas:cards.yellow||0, rojas:cards.red||0, penaltyScored:penalty.scored||0, penaltyMissed:penalty.missed||0, penaltySaved:penalty.saved||0, rating: s.games && s.games.rating ? parseFloat(s.games.rating) : 0 }; } function filaImagenNombre(foto,nombre,cols){ const colsHtml=cols.map(c=>`${c}`).join(''); return `${nombre}${colsHtml}`; } function rellenarTabla(tbodySelector, lista, mapValueFn, top=5){ const tbody=document.querySelector(tbodySelector); if(!tbody) return; const jugadoresConValor = lista.map(j=>({j,valores:mapValueFn(j)})) .filter(item=>item.valores.some(v=>Number(v)>0)) .sort((a,b)=>Number(b.valores[0])-Number(a.valores[0])) .slice(0,top); tbody.innerHTML=''; jugadoresConValor.forEach(item=>{ tbody.innerHTML+=filaImagenNombre(item.j.foto,item.j.nombre,item.valores); }); } async function procesarEquipoPartido(dataEquipo,sufijo){ if(!dataEquipo.players) return; const nombreEquipo=dataEquipo.team.name; const jugadores=dataEquipo.players.map(mapJugadorPartido); const container=document.getElementById(`equipo-${sufijo}`); const tituloEquipo=document.createElement('h1'); tituloEquipo.className='nombre-equipo'; tituloEquipo.textContent=nombreEquipo; container.appendChild(tituloEquipo); const tablas=[ {id:`tabla-goles-${sufijo}`,titulo:'Goles',cols:['Goles'], mapFn:j=>[fmt(j.goles)]}, {id:`tabla-asistencias-${sufijo}`,titulo:'Asistencias',cols:['Asistencias'], mapFn:j=>[fmt(j.asistencias)]}, {id:`tabla-amarillas-${sufijo}`,titulo:'Tarjetas amarillas',cols:['Amarillas'], mapFn:j=>[fmt(j.amarillas)]}, {id:`tabla-rojas-${sufijo}`,titulo:'Tarjetas rojas',cols:['Rojas'], mapFn:j=>[fmt(j.rojas)]}, // NUEVA TABLA DE MEJOR RATING {id:`tabla-rating-${sufijo}`, titulo:'Jugadores más valorados', cols:['Rating'], mapFn: j => [fmt(j.rating,1)]}, {id:`tabla-tiros-${sufijo}`,titulo:'Tiros',cols:['Tiros'], mapFn:j=>[fmt(j.disparos)]}, {id:`tabla-pases-${sufijo}`,titulo:'Pases',cols:['Pases'], mapFn:j=>[fmt(j.pases)]}, {id:`tabla-entradas-${sufijo}`,titulo:'Entradas',cols:['Entradas'], mapFn:j=>[fmt(j.entradas)]}, {id:`tabla-duelos-${sufijo}`,titulo:'Duelos',cols:['Ganados','Totales'], mapFn:j=>[fmt(j.duelsWon),fmt(j.duelsTotal)]}, {id:`tabla-dribbles-${sufijo}`,titulo:'Regates',cols:['Exitosos','Intentos'], mapFn:j=>[fmt(j.dribblesSuccess),fmt(j.dribblesAttempts)]}, {id:`tabla-penales-${sufijo}`,titulo:'Penaltis',cols:['Anotados','Fallados','Parados'], mapFn:j=>[fmt(j.penaltyScored),fmt(j.penaltyMissed),fmt(j.penaltySaved)]} ]; tablas.forEach(t=>{ const card=document.createElement('div'); card.className='card-jugadores'; card.innerHTML=`${t.titulo}FotoNombre${t.cols.map(c=>`${c}`).join('')}`; container.appendChild(card); rellenarTabla(`#${t.id}`,jugadores,t.mapFn,5); }); } // ---------------------- REFRESCO AUTOMÁTICO ---------------------- async function actualizarPartidoYJugadores(){ document.getElementById("last-match").innerHTML=''; document.getElementById("events").innerHTML=''; document.getElementById("alineaciones").innerHTML=''; document.getElementById("estadisticas").innerHTML=''; document.getElementById("equipo-1").innerHTML=''; document.getElementById("equipo-2").innerHTML=''; await obtenerPartido(); const datosJugadores = await obtenerJugadoresPartido(ID_PARTIDO); if(datosJugadores.length>=2){ await procesarEquipoPartido(datosJugadores[0],'1'); await procesarEquipoPartido(datosJugadores[1],'2'); } } // Primera carga actualizarPartidoYJugadores(); // Actualización cada 60 segundos // setInterval(actualizarPartidoYJugadores,180000);