23 Commits

Author SHA1 Message Date
Juanjo 14e2fd48a1 archivo .env + conexionBD 2026-09-29 09:41:40 +02:00
jorge 22f38f924f Merge branch 'pruebasJorge' 2026-09-28 12:37:07 +02:00
jorge 01aa2643f6 Actualizando a 12:24 2026-09-28 12:23:45 +02:00
jorge 07c1f79474 Merge branch 'main' of https://git.desarrolloalcala.com/jorge/triviagmatico 2026-09-28 10:28:26 +02:00
jorge 54b6b0d67b Changes to cabecera & sala 2026-09-28 10:09:26 +02:00
profesor 57e3dfc444 grafico E-R, no afecta en nada 2026-09-28 10:04:35 +02:00
Isaac 8c7958ad96 Merge branch 'main' of https://git.desarrolloalcala.com/jorge/triviagmatico 2026-09-28 09:43:03 +02:00
Isaac bf2361ad43 crear pregunta (y select de categorias) 2026-09-28 09:42:58 +02:00
jorge 03715d621e Corregida ruta jquery en buscadorSala 2026-09-28 09:03:36 +02:00
Isaac 6da20872c6 arreglado crear sala 2026-09-28 08:50:54 +02:00
Isaac 26a46c29e8 Funcionalidad de crear Sala.
Crear ClaseEquipoxPartida.php
Modificar controladorPartida.php
2026-09-25 14:11:29 +02:00
daniel 9a5575fe25 Add unirse a sala completo 2026-09-25 14:09:23 +02:00
daniel 0518cecd1e Add unirse a sala 2026-09-25 14:07:48 +02:00
Isaac d6e1cd8c2d crear sala (crear clase EquipoxPartida y modificar controladorPartida) 2026-09-25 13:57:37 +02:00
jorge 4e345fa01d Ranking 2026-09-25 13:53:22 +02:00
daniel 413d9552f2 Merge branch 'frontend' of https://git.desarrolloalcala.com/jorge/triviagmatico into frontend 2026-09-25 13:00:29 +02:00
daniel 6beb655e83 Add buscadorSala recupera las salas de la bbdd 2026-09-25 12:59:55 +02:00
Isaac 7292b932dd actualizado favicon e icono cabecera 2026-09-25 12:54:20 +02:00
alexis 36fb2d96fc add favicom 2026-09-25 12:46:47 +02:00
Isaac 9c67d76265 cambiar avatar y nombre en perfil.php 2026-09-25 11:35:05 +02:00
daniel 8d6272c664 Merge branch 'main' into frontend 2026-09-25 11:00:21 +02:00
Isaac 859f86aeb1 funcionalidad de perfil (estadisticas y nombre) 2026-09-25 10:30:54 +02:00
jorge f729a54bc2 SQL con equipos y partidas
Añadidos equipos y partidas de prueba a la bd para hacer pruebas.
2026-09-25 10:01:39 +02:00
26 changed files with 2336 additions and 954 deletions
+59 -95
View File
@@ -4,138 +4,102 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Trivial - Lobby</title> <title>Trivial - Lobby</title>
<link rel="icon" type="image/svg+xml" href="img/favicon/favicon.svg">
<link <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet">
<link rel="stylesheet" href="css/index.css"> <link rel="stylesheet" href="css/index.css">
<link rel="stylesheet" href="css/buscadorSala.css"> <link rel="stylesheet" href="css/buscadorSala.css">
</head> </head>
<body> <body>
<?php <?php include_once("cabecera.php"); ?>
include_once("cabecera.php");
?>
<main class="container py-5"> <main class="container py-4">
<div class="text-center mb-5"> <!-- Botón Volver -->
<button <div class="mb-4">
type="button" <a href="index.php" class="btn btn-outline-secondary d-inline-flex align-items-center gap-2">
class="btn btn-play-kahoot btn-crear-sala" <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-left" viewBox="0 0 16 16">
data-bs-toggle="modal" <path fill-rule="evenodd" d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8"/>
data-bs-target="#modalCrearSala"> </svg>
<span>+</span> Volver al Inicio
Crear sala </a>
</div>
<!-- Botón Crear Sala -->
<div id="contenedorCrearSala" class="text-center mb-5">
<button type="button" class="btn btn-play-kahoot btn-crear-sala" data-bs-toggle="modal" data-bs-target="#modalCrearSala">
<span>+</span> Crear sala
</button> </button>
</div> </div>
<div <!-- Contenedor Principal de Salas -->
id="contenedorSalas" <div id="contenedorSalas" class="row justify-content-center g-4">
class="row justify-content-center g-4"> <div id="cargandoSalas" class="col-12 text-center">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Cargando...</span>
</div> </div>
<p class="mt-3 text-muted">Cargando salas...</p>
</div>
</div>
</main> </main>
<div <!-- Modal Crear Sala -->
class="modal fade" <div class="modal fade" id="modalCrearSala" tabindex="-1" aria-labelledby="modalCrearSalaLabel" aria-hidden="true">
id="modalCrearSala"
tabindex="-1"
aria-labelledby="modalCrearSalaLabel"
aria-hidden="true">
<div class="modal-dialog modal-dialog-centered"> <div class="modal-dialog modal-dialog-centered">
<div class="modal-content modal-kahoot"> <div class="modal-content modal-kahoot">
<div class="modal-header modal-kahoot-header"> <div class="modal-header modal-kahoot-header">
<h5 <h5 class="modal-title" id="modalCrearSalaLabel">Crear sala</h5>
class="modal-title" <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Cerrar"></button>
id="modalCrearSalaLabel">
Crear sala
</h5>
<button
type="button"
class="btn-close btn-close-white"
data-bs-dismiss="modal"
aria-label="Cerrar">
</button>
</div> </div>
<div class="modal-body p-4"> <div class="modal-body p-4">
<div class="mb-3"> <div class="mb-3">
<label <label for="nombreSala" class="form-label">Nombre de la sala</label>
for="nombreSala" <input type="text" id="nombreSala" class="form-control input-kahoot" name="nombreSala" placeholder="Ej. Noche de Trivial" maxlength="100">
class="form-label">
Nombre de la sala
</label>
<input
type="text"
id="nombreSala"
class="form-control input-kahoot"
name="nombreSala"
placeholder="Ej. Noche de Trivial">
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label <label for="nombreEquipo1" class="form-label">Nombre del equipo 1</label>
for="nombreEquipo1" <input type="text" id="nombreEquipo1" name="nombreEquipo1" class="form-control input-kahoot" placeholder="Ej. Los cerebritos" maxlength="50">
class="form-label">
Nombre del equipo 1
</label>
<input
type="text"
id="nombreEquipo1"
name="nombreEquipo1"
class="form-control input-kahoot"
placeholder="Ej. Los cerebritos">
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label <label for="nombreEquipo2" class="form-label">Nombre del equipo 2</label>
for="nombreEquipo2" <input type="text" id="nombreEquipo2" name="nombreEquipo2" class="form-control input-kahoot" placeholder="Ej. Los campeones" maxlength="50">
class="form-label">
Nombre del equipo 2
</label>
<input
type="text"
id="nombreEquipo2"
name="nombreEquipo2"
class="form-control input-kahoot"
placeholder="Ej. Los campeones">
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
type="button" <button type="button" class="btn btn-kahoot-login" id="btnCrearSala">Crear sala</button>
class="btn btn-secondary" </div>
data-bs-dismiss="modal"> </div>
</div>
</div>
<!--MODAL ABANDONAR SALA -->
<!-- Modal Confirmar Abandonar Sala -->
<div class="modal fade" id="modalAbandonarSala" tabindex="-1" aria-labelledby="modalAbandonarSalaLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content modal-kahoot text-center p-3">
<div class="modal-body">
<div class="mb-3 fs-1">⚠️</div>
<h4 class="modal-title mb-2 fw-bold text-white" id="modalAbandonarSalaLabel">¿Abandonar la sala?</h4>
<p class="text-white-50">Si sales de la sala, perderás tu lugar en el equipo.</p>
</div>
<div class="modal-footer justify-content-center border-0 gap-2">
<button type="button" class="btn btn-secondary px-4 py-2" data-bs-dismiss="modal">
Cancelar Cancelar
</button> </button>
<button <button type="button" id="btnConfirmarAbandonar" class="btn btn-danger px-4 py-2">
type="button" Sí, salir
class="btn btn-kahoot-login"
id="btnCrearSala">
Crear sala
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<script <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"> <script src="js/jquery-4.0.0.min.js"></script>
</script>
<script src="js/lobbyDummy.js"></script>
<script src="js/buscadorSala.js"></script> <script src="js/buscadorSala.js"></script>
</body> </body>
</html> </html>
+7 -204
View File
@@ -1,13 +1,3 @@
<?php
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
// Comprobación de sesión
$isLoggedIn = isset($_SESSION['idUsuario']) && !empty($_SESSION['idUsuario']);
$username = $isLoggedIn ? $_SESSION['nombreUsuario'] : '';
?>
<!-- Bootstrap 5 CSS --> <!-- Bootstrap 5 CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- FontAwesome para iconos --> <!-- FontAwesome para iconos -->
@@ -16,16 +6,14 @@ $username = $isLoggedIn ? $_SESSION['nombreUsuario'] : '';
<link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;600;700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="css/index.css"> <link rel="stylesheet" href="css/index.css">
<script src="js/jquery-4.0.0.min.js"></script> <script src="js/jquery-4.0.0.min.js"></script>
<style>
</style>
<nav class="navbar navbar-expand-lg navbar-kahoot py-3 mb-4"> <nav class="navbar navbar-expand-lg navbar-kahoot py-3 mb-4">
<div class="container"> <div class="container">
<a class="navbar-brand" href="index.php"> <a class="navbar-brand" href="index.php">
<i class="fa-solid fa-gamepad me-2"></i>TRIVIAGMÁTICO <img src="img/favicon/favicon.svg" alt="TRIVIAGMÁTICO" class="me-2" style="height: 35px;">
TRIVIAGMÁTICO
</a> </a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarContent"> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarContent">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
@@ -33,44 +21,9 @@ $username = $isLoggedIn ? $_SESSION['nombreUsuario'] : '';
<div class="collapse navbar-collapse" id="navbarContent"> <div class="collapse navbar-collapse" id="navbarContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0"></ul> <ul class="navbar-nav me-auto mb-2 mb-lg-0"></ul>
<div class="d-flex align-items-center gap-3"> <!-- Adtoy ti pagianan ti botones / dropdown a patulaon ti JS -->
<?php if ($isLoggedIn): ?> <div class="d-flex align-items-center gap-3" id="contenedorUsuarioCabecera">
<!-- Menú desplegable cuando la sesión está iniciada --> <!-- Ikapit ti JS ti HTML dita -->
<div class="dropdown">
<button class="btn user-dropdown-btn dropdown-toggle d-flex align-items-center gap-2"
type="button"
id="userDropdown"
data-bs-toggle="dropdown"
aria-expanded="false">
<i class="fa-solid fa-circle-user fa-lg text-warning"></i>
<span><?= htmlspecialchars($username) ?></span>
</button>
<ul class="dropdown-menu dropdown-menu-end user-dropdown-menu" aria-labelledby="userDropdown">
<li>
<a class="dropdown-item d-flex align-items-center gap-2" href="perfil.php">
<i class="fa-solid fa-user text-primary"></i> Perfil
</a>
</li>
<li>
<hr class="dropdown-divider">
</li>
<li>
<a class="dropdown-item logout-item d-flex align-items-center gap-2" href="#" id="botonCerrarSesion">
<i class="fa-solid fa-right-from-bracket"></i> Cerrar Sesión
</a>
</li>
</ul>
</div>
<?php else: ?>
<!-- Botones que abren los modales cuando NO hay sesión iniciada -->
<button type="button" class="btn btn-kahoot-login rounded-pill px-4" data-bs-toggle="modal" data-bs-target="#modalLogin">
<i class="fa-solid fa-right-to-bracket me-1"></i> Iniciar Sesión
</button>
<button type="button" class="btn btn-kahoot-register rounded-pill px-4" data-bs-toggle="modal" data-bs-target="#modalRegistro">
<i class="fa-solid fa-user-plus me-1"></i> Registrarse
</button>
<?php endif; ?>
</div> </div>
</div> </div>
</div> </div>
@@ -152,154 +105,4 @@ $username = $isLoggedIn ? $_SESSION['nombreUsuario'] : '';
</div> </div>
</div> </div>
<script> <script src="js/cabecera.js"></script>
// Registro
$('#botonAceptarRegistro').click(function(event) {
event.preventDefault();
console.log('hola');
let nombreUsuario = $('#regNombre').val().trim();
let email = $('#regEmail').val().trim();
let contrasena = $('#regPassword').val();
let contrasenaConfirmacion = $('#regPasswordConfirm').val();
// Limpiamos errores anteriores
$('#regNombre').removeClass('is-invalid');
$('#regEmail').removeClass('is-invalid');
$('#regPassword').removeClass('is-invalid');
$('#regPasswordConfirm').removeClass('is-invalid');
$('#errorRegistro').text('');
// Comprobamos que las contraseñas coincidan
if (contrasena !== contrasenaConfirmacion) {
$('#regPassword').addClass('is-invalid');
$('#regPasswordConfirm').addClass('is-invalid');
$('#errorRegistro').text('Las contraseñas no coinciden.');
return;
}
$.ajax({
method: "POST",
url: "controladores/controladorUsuario.php",
data: {
'nombreUsuario': nombreUsuario,
'email': email,
'contrasena': contrasena,
'orden': 'registrarUsuario'
}
}).done(function(respuesta) {
//console.log(respuesta);
respuesta = JSON.parse(respuesta);
if (respuesta.error) {
$('#errorRegistro').text(respuesta.error);
// Marcamos los campos si hay error
$('#regNombre').addClass('is-invalid');
$('#regEmail').addClass('is-invalid');
} else {
// Registro correcto
$('#errorRegistro')
.removeClass('text-danger')
.addClass('text-success')
.text(respuesta.exito);
// Limpiamos formulario
$('#formRegistro')[0].reset();
// Cerramos modal después de un segundo
setTimeout(function() {
location.reload();
}, 1000);
}
}); // Fin función ajax
});
// Login
$('#botonAceptarLogin').click(function(event) {
event.preventDefault();
let email = $('#loginEmail').val().trim();
let contrasena = $('#loginPassword').val();
// Limpiamos errores anteriores
$('#loginEmail').removeClass('is-invalid');
$('#loginPassword').removeClass('is-invalid');
$('#errorLogin').text('');
// Comprobación básica
if (email === '' || contrasena === '') {
$('#errorLogin').text('Todos los campos son obligatorios.');
if (email === '') {
$('#loginEmail').addClass('is-invalid');
}
if (contrasena === '') {
$('#loginPassword').addClass('is-invalid');
}
return;
}
$.ajax({
method: "POST",
url: "controladores/controladorUsuario.php",
data: {
'email': email,
'contrasena': contrasena,
'orden': 'comprobarUsuario'
}
}).done(function(respuesta) {
//console.log(respuesta);
respuesta = JSON.parse(respuesta);
if (respuesta.error) {
$('#loginEmail').addClass('is-invalid');
$('#loginPassword').addClass('is-invalid');
$('#errorLogin').text(respuesta.error);
} else {
location.reload();
}
}); // Fin función ajax
});
// Cerrar sesión
$('#botonCerrarSesion').click(function(event) {
event.preventDefault();
$.ajax({
method: "POST",
url: "controladores/controladorUsuario.php",
data: {
'orden': 'cerrarSesion'
}
}).done(function(respuesta) {
//console.log(respuesta);
respuesta = JSON.parse(respuesta);
if (respuesta.error) {
console.log(respuesta.error);
} else {
// Sesión cerrada correctamente
location.reload();
}
}); // Fin función ajax
}); // Fin función click
</script>
+20 -15
View File
@@ -2,37 +2,44 @@
require_once __DIR__ . '/../includes/conexionBD.php'; require_once __DIR__ . '/../includes/conexionBD.php';
class Equipo{ class Equipo
{
public $idEquipo; public $idEquipo;
public $nombreEquipo; public $nombreEquipo;
function __construct($idEquipo=null, $nombreEquipo=null){ function __construct($idEquipo = null, $nombreEquipo = null)
{
$this->idEquipo = $idEquipo; $this->idEquipo = $idEquipo;
$this->nombreEquipo = $nombreEquipo; $this->nombreEquipo = $nombreEquipo;
} }
function crear(){ function crear()
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
return $conexion; return $conexion;
} else { } else {
try { try {
$consulta = $conexion->prepare("INSERT INTO equipo (nombreEquipo) VALUES (:nombreEquipo)"); $consulta = $conexion->prepare(
"INSERT INTO equipo (nombreEquipo) VALUES (:nombreEquipo)"
);
$consulta->bindParam(':nombreEquipo', $this->nombreEquipo); $consulta->bindParam(':nombreEquipo', $this->nombreEquipo);
$consulta->execute(); $consulta->execute();
// Guardamos el ID generado por la BD
$this->idEquipo = (int)$conexion->lastInsertId();
$respuesta = [ $respuesta = [
'exito' => 'Equipo creado correctamente', 'exito' => 'Equipo creado correctamente',
'exito_tecnico' => $this->nombreEquipo 'exito_tecnico' => $this->idEquipo
]; ];
return $respuesta; return $respuesta;
} catch (PDOException $error) { } catch (PDOException $error) {
$respuesta = [ $respuesta = [
'error' => 'Ocurrió un error al guardar el equipo.', 'error' => 'Ocurrió un error al guardar el equipo.',
@@ -46,7 +53,9 @@ class Equipo{
} }
function listar(){
function listar()
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
@@ -61,7 +70,6 @@ class Equipo{
$resultado = $consulta->fetchAll(PDO::FETCH_ASSOC); $resultado = $consulta->fetchAll(PDO::FETCH_ASSOC);
return $resultado; return $resultado;
} catch (PDOException $error) { } catch (PDOException $error) {
$respuesta = [ $respuesta = [
'error' => 'Ocurrió un error al obtener el listado de equipos.', 'error' => 'Ocurrió un error al obtener el listado de equipos.',
@@ -75,7 +83,8 @@ class Equipo{
} }
function buscar(){ function buscar()
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
@@ -91,7 +100,6 @@ class Equipo{
$resultado = $consulta->fetch(PDO::FETCH_ASSOC); $resultado = $consulta->fetch(PDO::FETCH_ASSOC);
return $resultado; return $resultado;
} catch (PDOException $error) { } catch (PDOException $error) {
$respuesta = [ $respuesta = [
'error' => 'Ocurrió un error al buscar el equipo.', 'error' => 'Ocurrió un error al buscar el equipo.',
@@ -105,7 +113,8 @@ class Equipo{
} }
function borrar(){ function borrar()
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
@@ -131,7 +140,6 @@ class Equipo{
} }
return $respuesta; return $respuesta;
} catch (PDOException $error) { } catch (PDOException $error) {
$respuesta = [ $respuesta = [
'error' => 'Ocurrió un error al eliminar el equipo.', 'error' => 'Ocurrió un error al eliminar el equipo.',
@@ -143,7 +151,4 @@ class Equipo{
} }
} }
} }
} }
?>
+60
View File
@@ -0,0 +1,60 @@
<?php
require_once __DIR__ . '/../includes/conexionBD.php';
class EquipoxPartida
{
public $idEquipoxPartida;
public $idEquipo;
public $idPartida;
public function __construct(
$idEquipoxPartida = null,
$idEquipo = null,
$idPartida = null
) {
$this->idEquipoxPartida = $idEquipoxPartida;
$this->idEquipo = $idEquipo;
$this->idPartida = $idPartida;
}
public function insertar()
{
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$sql = "
INSERT INTO equipoxpartida
(idEquipo, idPartida)
VALUES
(:idEquipo, :idPartida)
";
$consulta = $conexion->prepare($sql);
$consulta->bindParam(':idEquipo', $this->idEquipo);
$consulta->bindParam(':idPartida', $this->idPartida);
$consulta->execute();
$this->idEquipoxPartida = (int)$conexion->lastInsertId();
return [
'exito' => 'Equipo vinculado a la partida correctamente.',
'exito_tecnico' => $this->idEquipoxPartida
];
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al vincular el equipo con la partida.',
'error_tecnico' => $error->getMessage()
];
}
}
}
+92 -4
View File
@@ -2,18 +2,21 @@
require_once __DIR__ . '/../includes/conexionBD.php'; require_once __DIR__ . '/../includes/conexionBD.php';
class EquipoxUsuario { class EquipoxUsuario
{
public $idEquipoxUsuario; public $idEquipoxUsuario;
public $idUsuario; public $idUsuario;
public $idEquipo; public $idEquipo;
public function __construct($idEquipoxUsuario = null, $idUsuario = null, $idEquipo = null) { public function __construct($idEquipoxUsuario = null, $idUsuario = null, $idEquipo = null)
{
$this->idEquipoxUsuario = $idEquipoxUsuario; $this->idEquipoxUsuario = $idEquipoxUsuario;
$this->idUsuario = $idUsuario; $this->idUsuario = $idUsuario;
$this->idEquipo = $idEquipo; $this->idEquipo = $idEquipo;
} }
public function registrarUsuarioEnEquipo() { public function registrarUsuarioEnEquipo()
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) return $conexion; if (is_array($conexion)) return $conexion;
@@ -36,7 +39,8 @@ class EquipoxUsuario {
} }
} }
public static function listarUsuariosPorEquipo($idEquipo) { public static function listarUsuariosPorEquipo($idEquipo)
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) return $conexion; if (is_array($conexion)) return $conexion;
@@ -56,4 +60,88 @@ class EquipoxUsuario {
]; ];
} }
} }
public function obtenerSalaUsuario($idUsuario)
{
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$sql = "
SELECT
exu.idEquipo,
exp.idPartida
FROM equipoxusuario exu
INNER JOIN equipoxpartida exp
ON exu.idEquipo = exp.idEquipo
WHERE exu.idUsuario = :idUsuario
LIMIT 1
";
$consulta = $conexion->prepare($sql);
$consulta->bindParam(
':idUsuario',
$idUsuario,
PDO::PARAM_INT
);
$consulta->execute();
$resultado = $consulta->fetch(PDO::FETCH_ASSOC);
if (!$resultado) {
return [
'asociado' => false
];
}
return [
'asociado' => true,
'idEquipo' => $resultado['idEquipo'],
'idPartida' => $resultado['idPartida']
];
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al obtener la sala del usuario.',
'error_tecnico' => $error->getMessage()
];
}
}
public static function salirDeSala($idUsuario)
{
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$sql = "DELETE FROM equipoxusuario WHERE idUsuario = :idUsuario";
$consulta = $conexion->prepare($sql);
$consulta->bindParam(':idUsuario', $idUsuario, PDO::PARAM_INT);
$consulta->execute();
return [
'exito' => true,
'mensaje' => 'Usuario eliminado de la sala correctamente.'
];
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al salir de la sala.',
'error_tecnico' => $error->getMessage()
];
}
}
} }
+26 -9
View File
@@ -336,7 +336,8 @@ class Partida
* Vincula un equipo a esta partida en la tabla intermedia 'equipoxpartida'. * Vincula un equipo a esta partida en la tabla intermedia 'equipoxpartida'.
* Permite registrar qué grupos están participando en este torneo. * Permite registrar qué grupos están participando en este torneo.
*/ */
public function registrarEquipoEnPartida($idEquipo) { public function registrarEquipoEnPartida($idEquipo)
{
$conexion = conexionBD(); // Obtenemos la conexión modular del proyecto $conexion = conexionBD(); // Obtenemos la conexión modular del proyecto
if (is_array($conexion)) { if (is_array($conexion)) {
@@ -374,7 +375,8 @@ class Partida
* Obtiene todos los equipos que están compitiendo en esta partida. * Obtiene todos los equipos que están compitiendo en esta partida.
* Es útil para mostrar la lista de rivales antes de empezar a responder. * Es útil para mostrar la lista de rivales antes de empezar a responder.
*/ */
public function getEquiposParticipantes() { public function getEquiposParticipantes()
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
@@ -411,7 +413,8 @@ class Partida
* Obtiene todos los jugadores reales (Usuarios) que están jugando en esta partida. * Obtiene todos los jugadores reales (Usuarios) que están jugando en esta partida.
* Utiliza la tabla 'equipoxusuario' en SQL para cruzar los datos. * Utiliza la tabla 'equipoxusuario' en SQL para cruzar los datos.
*/ */
public function getJugadoresDeLaPartida() { public function getJugadoresDeLaPartida()
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
@@ -419,34 +422,48 @@ class Partida
} }
try { try {
// Cruza la partida con los equipos, y luego los equipos con los usuarios
// para saber los nombres de todas las personas que están jugando el torneo.
$consulta = $conexion->prepare(" $consulta = $conexion->prepare("
SELECT DISTINCT SELECT DISTINCT
u.idUsuario, u.idUsuario,
u.nombreUsuario, u.nombreUsuario,
u.email, u.email,
e.idEquipo,
e.nombreEquipo e.nombreEquipo
FROM equipoxpartida exp FROM equipoxpartida exp
INNER JOIN equipoxusuario exu INNER JOIN equipoxusuario exu
ON exp.idEquipo = exu.idEquipo ON exp.idEquipo = exu.idEquipo
INNER JOIN usuario u INNER JOIN usuario u
ON exu.idUsuario = u.idUsuario ON exu.idUsuario = u.idUsuario
INNER JOIN equipo e INNER JOIN equipo e
ON exu.idEquipo = e.idEquipo ON exu.idEquipo = e.idEquipo
WHERE exp.idPartida = :idPartida WHERE exp.idPartida = :idPartida
ORDER BY e.nombreEquipo ASC,
u.nombreUsuario ASC
"); ");
$consulta->bindParam(":idPartida", $this->idPartida); $consulta->bindParam(
":idPartida",
$this->idPartida
);
$consulta->execute(); $consulta->execute();
return $consulta->fetchAll(PDO::FETCH_ASSOC); return $consulta->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $error) { } catch (PDOException $error) {
return [ return [
"error" => "Ocurrió un error al obtener la lista de jugadores.", "error" =>
"error_tecnico" => $error->getMessage() "Ocurrió un error al obtener la lista de jugadores.",
"error_tecnico" =>
$error->getMessage()
]; ];
} }
} }
} }
+226 -23
View File
@@ -1,7 +1,8 @@
<?php <?php
require_once __DIR__ . '/../includes/conexionBD.php'; require_once __DIR__ . '/../includes/conexionBD.php';
class Usuario { class Usuario
{
private ?int $idUsuario; private ?int $idUsuario;
private string $nombreUsuario; private string $nombreUsuario;
private string $contrasena; private string $contrasena;
@@ -34,33 +35,85 @@ class Usuario {
$this->derrotas = $derrotas; $this->derrotas = $derrotas;
} }
public function getIdUsuario(): ?int { return $this->idUsuario; } public function getIdUsuario(): ?int
{
return $this->idUsuario;
}
public function getNombreUsuario(): string { return $this->nombreUsuario; } public function getNombreUsuario(): string
public function setNombreUsuario(string $nombreUsuario): void { $this->nombreUsuario = $nombreUsuario; } {
return $this->nombreUsuario;
}
public function setNombreUsuario(string $nombreUsuario): void
{
$this->nombreUsuario = $nombreUsuario;
}
public function getContrasena(): string { return $this->contrasena; } public function getContrasena(): string
public function setContrasena(string $contrasena): void { $this->contrasena = $contrasena; } {
return $this->contrasena;
}
public function setContrasena(string $contrasena): void
{
$this->contrasena = $contrasena;
}
public function getEmail(): string { return $this->email; } public function getEmail(): string
public function setEmail(string $email): void { $this->email = $email; } {
return $this->email;
}
public function setEmail(string $email): void
{
$this->email = $email;
}
public function getAvatar(): ?string { return $this->avatar; } public function getAvatar(): ?string
public function setAvatar(?string $avatar): void { $this->avatar = $avatar; } {
return $this->avatar;
}
public function setAvatar(?string $avatar): void
{
$this->avatar = $avatar;
}
public function getCookie(): ?string { return $this->cookie; } public function getCookie(): ?string
public function setCookie(?string $cookie): void { $this->cookie = $cookie; } {
return $this->cookie;
}
public function setCookie(?string $cookie): void
{
$this->cookie = $cookie;
}
public function getAciertos(): int { return $this->aciertos; } public function getAciertos(): int
public function setAciertos(int $aciertos): void { $this->aciertos = $aciertos; } {
return $this->aciertos;
}
public function setAciertos(int $aciertos): void
{
$this->aciertos = $aciertos;
}
public function getVictorias(): int { return $this->victorias; } public function getVictorias(): int
public function setVictorias(int $victorias): void { $this->victorias = $victorias; } {
return $this->victorias;
}
public function setVictorias(int $victorias): void
{
$this->victorias = $victorias;
}
public function getDerrotas(): int { return $this->derrotas; } public function getDerrotas(): int
public function setDerrotas(int $derrotas): void { $this->derrotas = $derrotas; } {
return $this->derrotas;
}
public function setDerrotas(int $derrotas): void
{
$this->derrotas = $derrotas;
}
public function registrar() { public function registrar()
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
@@ -91,7 +144,6 @@ class Usuario {
'exito' => 'Usuario registrado correctamente', 'exito' => 'Usuario registrado correctamente',
'exito_tecnico' => $this->idUsuario 'exito_tecnico' => $this->idUsuario
]; ];
} catch (PDOException $error) { } catch (PDOException $error) {
return [ return [
'error' => 'Ocurrió un error al registrar el usuario.', 'error' => 'Ocurrió un error al registrar el usuario.',
@@ -100,7 +152,8 @@ class Usuario {
} }
} }
public static function buscarPorId($id) { public static function buscarPorId($id)
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
@@ -131,7 +184,6 @@ class Usuario {
return [ return [
'error' => 'No se encontró ningún usuario con ese ID.' 'error' => 'No se encontró ningún usuario con ese ID.'
]; ];
} catch (PDOException $error) { } catch (PDOException $error) {
return [ return [
'error' => 'Ocurrió un error al buscar el usuario.', 'error' => 'Ocurrió un error al buscar el usuario.',
@@ -140,7 +192,8 @@ class Usuario {
} }
} }
public static function buscarPorEmail($email) { public static function buscarPorEmail($email)
{
$conexion = conexionBD(); $conexion = conexionBD();
if (is_array($conexion)) { if (is_array($conexion)) {
@@ -189,6 +242,7 @@ class Usuario {
unset($_SESSION['idUsuario']); unset($_SESSION['idUsuario']);
unset($_SESSION['email']); unset($_SESSION['email']);
unset($_SESSION['nombreUsuario']); unset($_SESSION['nombreUsuario']);
unset($_SESSION['avatar']);
return null; return null;
} }
@@ -200,6 +254,7 @@ class Usuario {
$_SESSION['idUsuario'] = $usuario->getIdUsuario(); $_SESSION['idUsuario'] = $usuario->getIdUsuario();
$_SESSION['email'] = $usuario->getEmail(); $_SESSION['email'] = $usuario->getEmail();
$_SESSION['nombreUsuario'] = $usuario->getNombreUsuario(); $_SESSION['nombreUsuario'] = $usuario->getNombreUsuario();
$_SESSION['avatar'] = $usuario->getAvatar();
// Devolvemos el usuario como hasta ahora // Devolvemos el usuario como hasta ahora
return $usuario; return $usuario;
@@ -209,8 +264,156 @@ class Usuario {
unset($_SESSION['idUsuario']); unset($_SESSION['idUsuario']);
unset($_SESSION['email']); unset($_SESSION['email']);
unset($_SESSION['nombreUsuario']); unset($_SESSION['nombreUsuario']);
unset($_SESSION['avatar']);
return null; return null;
} }
public function cambiarNombre($nuevoNombre)
{
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$sql = "UPDATE usuario
SET nombreUsuario = :nombre
WHERE idUsuario = :id";
$stmt = $conexion->prepare($sql);
$stmt->execute([
':nombre' => $nuevoNombre,
':id' => $this->idUsuario
]);
// Actualizamos también el objeto actual
$this->nombreUsuario = $nuevoNombre;
return [
'exito' => 'Nombre actualizado correctamente.'
];
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al actualizar el nombre.',
'error_tecnico' => $error->getMessage()
];
}
}
public function cambiarAvatar($archivo)
{
$carpeta = __DIR__ . '/../img/avatars/';
// Creamos la carpeta si no existe
if (!is_dir($carpeta)) {
mkdir($carpeta, 0755, true);
}
// Obtenemos la extensión según el tipo MIME
$tipo = mime_content_type($archivo['tmp_name']);
$extensiones = [
'image/jpeg' => 'jpg',
'image/png' => 'png',
'image/gif' => 'gif',
'image/webp' => 'webp'
];
if (!isset($extensiones[$tipo])) {
return [
'error' => 'Formato de imagen no permitido.'
];
}
$extension = $extensiones[$tipo];
// Nombre único para evitar conflictos
$nombreArchivo = 'avatar_' . $this->idUsuario . '.' . $extension;
$rutaCompleta = $carpeta . $nombreArchivo;
// Guardamos la imagen
if (!move_uploaded_file($archivo['tmp_name'], $rutaCompleta)) {
return [
'error' => 'No se pudo guardar la imagen.'
];
}
// Ruta que utilizará el HTML
$rutaAvatar = 'img/avatars/' . $nombreArchivo;
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$sql = "UPDATE usuario
SET avatar = :avatar
WHERE idUsuario = :id";
$stmt = $conexion->prepare($sql);
$stmt->execute([
':avatar' => $rutaAvatar,
':id' => $this->idUsuario
]);
// Actualizamos también el objeto actual
$this->avatar = $rutaAvatar;
return [
'exito' => 'Avatar actualizado correctamente.',
'avatar' => $rutaAvatar
];
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al actualizar el avatar.',
'error_tecnico' => $error->getMessage()
];
}
}
public static function obtenerRanking($limite = 10) {
try {
$conexion = conexionBD();
if (is_array($conexion)) {
return [];
}
$sql = "SELECT
idUsuario,
nombreUsuario,
avatar,
aciertos,
victorias,
derrotas,
CASE
WHEN (victorias + derrotas) > 0
THEN ROUND((victorias / (victorias + derrotas)) * 100, 0)
ELSE 0
END AS porcentajeVictoria
FROM usuario
ORDER BY victorias DESC, aciertos DESC
LIMIT " . (int)$limite;
$stmt = $conexion->prepare($sql);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
return [];
}
}
} }
+48 -5
View File
@@ -7,26 +7,39 @@ require_once '../clases/ClaseEquipoxUsuario.php';
switch ($_POST['orden']) { switch ($_POST['orden']) {
case 'registrarUsuarioEnEquipo': case 'registrarUsuarioEnEquipo':
if (!isset($_SESSION['idUsuario'])) { if (!isset($_SESSION['idUsuario'])) {
echo json_encode([ echo json_encode([
'error' => 'No hay una sesión activa de usuario. Por favor, inicie sesión.' 'error' => 'No hay una sesión activa de usuario. Por favor, inicie sesión.'
]); ]);
break; break;
} }
$idUsuario = $_SESSION['idUsuario']; $idUsuario = $_SESSION['idUsuario'];
$idEquipo = intval($_POST['idEquipo'] ?? 0); $idEquipo = intval($_POST['idEquipo'] ?? 0);
break;
if ($idEquipo <= 0) { if ($idEquipo <= 0) {
echo json_encode([ echo json_encode([
'error' => 'El ID del equipo proporcionado no es válido.' 'error' => 'El ID del equipo proporcionado no es válido.'
]); ]);
break; break;
} }
$equipoxusuario = new EquipoxUsuario();
$resultado = $equipoxusuario->registrarUsuarioEnEquipo($idEquipo, $idUsuario); $equipoxusuario = new EquipoxUsuario(
null,
$idUsuario,
$idEquipo
);
$resultado = $equipoxusuario->registrarUsuarioEnEquipo();
echo json_encode($resultado); echo json_encode($resultado);
break; break;
case 'listarUsuariosPorEquipo': case 'listarUsuariosPorEquipo':
$idEquipo = intval($_POST['idEquipo'] ?? 0); $idEquipo = intval($_POST['idEquipo'] ?? 0);
@@ -36,12 +49,42 @@ switch($_POST['orden']){
} }
$equipoxusuario = new EquipoxUsuario(); $equipoxusuario = new EquipoxUsuario();
$listado = $equipoxusuario->listarUsuariosPorEquipo($idEquipo); $listado = $equipoxusuario->listarUsuariosPorEquipo($idEquipo);
break; //break;
echo json_encode($listado); echo json_encode($listado);
break; break;
case 'obtenerSalaUsuario':
if (!isset($_SESSION['idUsuario'])) {
echo json_encode([
'error' => 'No hay una sesión activa de usuario.'
]);
break;
} }
$idUsuario = $_SESSION['idUsuario'];
?> $equipoxusuario = new EquipoxUsuario();
$resultado =
$equipoxusuario->obtenerSalaUsuario($idUsuario);
echo json_encode($resultado);
break;
case 'salirDeSala':
if (!isset($_SESSION['idUsuario'])) {
echo json_encode(['error' => 'Usuario no autenticado']);
exit;
}
$idUsuario = $_SESSION['idUsuario'];
$respuesta = EquipoxUsuario::salirDeSala($idUsuario);
echo json_encode($respuesta);
break;
}
+140 -16
View File
@@ -3,11 +3,9 @@
session_start(); session_start();
require_once '../clases/ClasePartida.php'; require_once '../clases/ClasePartida.php';
require_once '../clases/ClaseEquipo.php';
require_once '../clases/ClaseEquipoxUsuario.php';
require_once '../clases/ClaseEquipoxPartida.php';
switch ($_POST['orden']) { switch ($_POST['orden']) {
@@ -55,7 +53,6 @@ switch ($_POST['orden']) {
// Comprobamos que haya un usuario conectado // Comprobamos que haya un usuario conectado
if (!isset($_SESSION['idUsuario'])) { if (!isset($_SESSION['idUsuario'])) {
echo json_encode([ echo json_encode([
@@ -66,9 +63,7 @@ switch ($_POST['orden']) {
} }
// Comprobamos el nombre de la partida
//Comprobamos que se haya introducido un nombre
if ( if (
!isset($_POST['nombrePartida']) || !isset($_POST['nombrePartida']) ||
@@ -83,26 +78,155 @@ switch ($_POST['orden']) {
} }
// Comprobamos los nombres de los equipos
if (
!isset($_POST['nombreEquipo1']) ||
trim($_POST['nombreEquipo1']) === '' ||
!isset($_POST['nombreEquipo2']) ||
trim($_POST['nombreEquipo2']) === ''
) {
echo json_encode([
'error' => 'Los nombres de los equipos son obligatorios.'
]);
break;
}
//Creamos la partida /*
* ==========================================
* 1. CREAMOS LA PARTIDA
* ==========================================
*/
$partida = new Partida(); $partida = new Partida();
$partida->nombrePartida = trim($_POST['nombrePartida']); $partida->nombrePartida = trim($_POST['nombrePartida']);
// El usuario conectado será el propietario
//El usuario conectado será el propietario de la partida.
$partida->idUsuario = $_SESSION['idUsuario']; $partida->idUsuario = $_SESSION['idUsuario'];
$resultadoPartida = $partida->insertar();
$resultado = $partida->insertar();
echo json_encode($resultado); if (isset($resultadoPartida['error'])) {
echo json_encode($resultadoPartida);
break; break;
}
$idPartida = (int)$resultadoPartida['exito_tecnico'];
/*
* ==========================================
* 2. CREAMOS EL EQUIPO 1
* ==========================================
*/
$equipo1 = new Equipo();
$equipo1->nombreEquipo = trim($_POST['nombreEquipo1']);
$resultadoEquipo1 = $equipo1->crear();
if (isset($resultadoEquipo1['error'])) {
echo json_encode($resultadoEquipo1);
break;
}
/*
* ==========================================
* 3. CREAMOS EL EQUIPO 2
* ==========================================
*/
$equipo2 = new Equipo();
$equipo2->nombreEquipo = trim($_POST['nombreEquipo2']);
$resultadoEquipo2 = $equipo2->crear();
if (isset($resultadoEquipo2['error'])) {
echo json_encode($resultadoEquipo2);
break;
}
/*
* ==========================================
* 3. INSERTAMOS LOS EQUIPOS CON SU PARTIDA EN EQUIPOXPARTIDA
* ==========================================
*/
$relacionEquipo1 = new EquipoxPartida(
null,
$equipo1->idEquipo,
$idPartida
);
$resultadoRelacion1 = $relacionEquipo1->insertar();
$relacionEquipo2 = new EquipoxPartida(
null,
$equipo2->idEquipo,
$idPartida
);
$resultadoRelacion2 = $relacionEquipo2->insertar();
/*
* ==========================================
* 4. ASIGNAMOS EL USUARIO AL EQUIPO 1
* ==========================================
*/
$usuarioEquipo = new EquipoxUsuario(
null,
$_SESSION['idUsuario'],
$equipo1->idEquipo
);
$resultadoUsuarioEquipo =
$usuarioEquipo->registrarUsuarioEnEquipo();
if (isset($resultadoUsuarioEquipo['error'])) {
echo json_encode($resultadoUsuarioEquipo);
break;
}
/*
* ==========================================
* TODO CORRECTO
* ==========================================
*/
echo json_encode([
'exito' => 'Sala creada correctamente.',
'idPartida' => $resultadoPartida['exito_tecnico'],
'idEquipo1' => $equipo1->idEquipo,
'idEquipo2' => $equipo2->idEquipo
]);
break;
+106 -6
View File
@@ -3,6 +3,7 @@
session_start(); session_start();
require_once '../clases/ClasePregunta.php'; require_once '../clases/ClasePregunta.php';
require_once '../clases/ClaseRespuesta.php';
switch ($_POST['orden']) { switch ($_POST['orden']) {
@@ -11,16 +12,116 @@ switch ($_POST['orden']) {
$idCategoria = intval($_POST['idCategoria'] ?? 0); $idCategoria = intval($_POST['idCategoria'] ?? 0);
$nombrePregunta = trim($_POST['nombrePregunta'] ?? ''); $nombrePregunta = trim($_POST['nombrePregunta'] ?? '');
if ($idCategoria <= 0 || $nombrePregunta == '') { $respuestaCorrecta = trim($_POST['respuestaCorrecta'] ?? '');
echo json_encode(['error' => 'La categoría y el texto de la pregunta son obligatorios']); $respuestaIncorrecta1 = trim($_POST['respuestaIncorrecta1'] ?? '');
$respuestaIncorrecta2 = trim($_POST['respuestaIncorrecta2'] ?? '');
$respuestaIncorrecta3 = trim($_POST['respuestaIncorrecta3'] ?? '');
// Comprobamos los datos
if (
$idCategoria <= 0 ||
$nombrePregunta === '' ||
$respuestaCorrecta === '' ||
$respuestaIncorrecta1 === '' ||
$respuestaIncorrecta2 === '' ||
$respuestaIncorrecta3 === ''
) {
echo json_encode([
'error' => 'La categoría, la pregunta y todas las respuestas son obligatorias.'
]);
break; break;
} }
$pregunta = new Pregunta($idCategoria, $nombrePregunta);
$resultado = $pregunta->guardar();
echo json_encode($resultado); /*
* ==========================================
* 1. CREAMOS LA PREGUNTA
* ==========================================
*/
$pregunta = new Pregunta(
$idCategoria,
$nombrePregunta
);
$resultadoPregunta = $pregunta->guardar();
if (isset($resultadoPregunta['error'])) {
echo json_encode($resultadoPregunta);
break; break;
}
// Obtenemos el ID de la pregunta creada
$idPregunta = (int)$resultadoPregunta['exito_tecnico'];
/*
* ==========================================
* 2. CREAMOS LAS RESPUESTAS
* ==========================================
*/
$respuestas = [
[
'texto' => $respuestaCorrecta,
'correcta' => 1
],
[
'texto' => $respuestaIncorrecta1,
'correcta' => 0
],
[
'texto' => $respuestaIncorrecta2,
'correcta' => 0
],
[
'texto' => $respuestaIncorrecta3,
'correcta' => 0
]
];
foreach ($respuestas as $respuesta) {
$objRespuesta = new Respuesta(
null,
$idPregunta,
$respuesta['texto'],
$respuesta['correcta']
);
$resultadoRespuesta = $objRespuesta->insertar();
if (isset($resultadoRespuesta['error'])) {
echo json_encode($resultadoRespuesta);
break 2;
}
}
/*
* ==========================================
* 3. TODO CORRECTO
* ==========================================
*/
echo json_encode([
'exito' => 'Pregunta creada correctamente.',
'idPregunta' => $idPregunta
]);
break;
case 'obtenerPreguntasPorCategoria': case 'obtenerPreguntasPorCategoria':
@@ -49,5 +150,4 @@ switch ($_POST['orden']) {
echo json_encode($listado); echo json_encode($listado);
break; break;
} }
+165 -1
View File
@@ -35,7 +35,8 @@ switch ($_POST['orden']) {
$usuario = new Usuario( $usuario = new Usuario(
$nombreUsuario, $nombreUsuario,
$contrasena, $contrasena,
$email $email,
'img/avatars/defaultProfile.jpeg'
); );
$resultado = $usuario->registrar(); $resultado = $usuario->registrar();
@@ -54,6 +55,12 @@ switch ($_POST['orden']) {
if ($resultado instanceof Usuario) { if ($resultado instanceof Usuario) {
// === AÑADIR ESTAS LÍNEAS PARA GUARDAR EN SESIÓN ===
$_SESSION['idUsuario'] = $resultado->getIdUsuario();
$_SESSION['nombreUsuario'] = $resultado->getNombreUsuario();
$_SESSION['email'] = $resultado->getEmail();
// =================================================
echo json_encode([ echo json_encode([
'exito' => 'Login correcto', 'exito' => 'Login correcto',
'idUsuario' => $resultado->getIdUsuario(), 'idUsuario' => $resultado->getIdUsuario(),
@@ -85,4 +92,161 @@ switch ($_POST['orden']) {
]); ]);
break; break;
case 'mostrarEstadisticas':
$usuario = Usuario::buscarPorId($_SESSION['idUsuario']);
if ($usuario instanceof Usuario) {
echo json_encode([
'victorias' => $usuario->getVictorias(),
'derrotas' => $usuario->getDerrotas(),
'aciertos' => $usuario->getAciertos()
]);
} else {
echo json_encode($usuario);
}
break;
case 'cambiarNombre':
if (!isset($_SESSION['idUsuario'])) {
echo json_encode([
'error' => 'No hay ningún usuario conectado.'
]);
break;
}
$nuevoNombre = trim($_POST['nombreUsuario'] ?? '');
if ($nuevoNombre === '') {
echo json_encode([
'error' => 'El nombre no puede estar vacío.'
]);
break;
}
$usuario = Usuario::buscarPorId($_SESSION['idUsuario']);
if (!($usuario instanceof Usuario)) {
echo json_encode([
'error' => 'No se encontró el usuario.'
]);
break;
}
$resultado = $usuario->cambiarNombre($nuevoNombre);
if (isset($resultado['error'])) {
echo json_encode($resultado);
} else {
// Actualizamos también la sesión
$_SESSION['nombreUsuario'] = $nuevoNombre;
echo json_encode([
'exito' => 'Nombre actualizado correctamente.',
'nombreUsuario' => $nuevoNombre
]);
}
break;
case 'cambiarAvatar':
if (!isset($_SESSION['idUsuario'])) {
echo json_encode([
'error' => 'No hay ningún usuario conectado.'
]);
break;
}
if (!isset($_FILES['avatar']) || $_FILES['avatar']['error'] !== UPLOAD_ERR_OK) {
echo json_encode([
'error' => 'No se ha recibido ninguna imagen.'
]);
break;
}
$archivo = $_FILES['avatar'];
$tipo = mime_content_type($archivo['tmp_name']);
$tiposPermitidos = [
'image/jpeg',
'image/png',
'image/gif',
'image/webp'
];
if (!in_array($tipo, $tiposPermitidos)) {
echo json_encode([
'error' => 'El formato de imagen no es válido.'
]);
break;
}
$usuario = Usuario::buscarPorId($_SESSION['idUsuario']);
if (!($usuario instanceof Usuario)) {
echo json_encode([
'error' => 'No se encontró el usuario.'
]);
break;
}
$resultado = $usuario->cambiarAvatar($archivo);
if (isset($resultado['error'])) {
echo json_encode($resultado);
} else {
// Actualizamos también la sesión
$_SESSION['avatar'] = $resultado['avatar'];
echo json_encode($resultado);
}
break;
case 'obtenerRanking':
$ranking = Usuario::obtenerRanking(5); //Cambiar para mostrar X jugadores en index
echo json_encode([
'exito' => true,
'ranking' => $ranking
]);
break;
case 'comprobarSesion':
if (isset($_SESSION['idUsuario']) && !empty($_SESSION['idUsuario'])) {
echo json_encode([
'activa' => true,
'usuario' => [
'idUsuario' => $_SESSION['idUsuario'],
'nombreUsuario' => $_SESSION['nombreUsuario'] ?? ''
]
]);
} else {
echo json_encode(['activa' => false]);
}
break;
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.6 KiB

+19 -22
View File
@@ -1,29 +1,26 @@
<?php <?php
//CARGA DE ARCHIVOS .ENV CON PHPDOTENV
require('c:/laragon/vendor/autoload.php');//Se carga el módulo instalado con composer
$dotenv = Dotenv\Dotenv::createImmutable('c:/laragon/', 'triviagmatico.env');//leemos el archivo. El primer parámetro es la ruta para llegar y el segundo el nombre del archivo .env
$dotenv->load();
function conexionBD (){ function conexionBD (){
// Configuración para Laragon
$servidor = "localhost";
$bd = "triviagmatico"; // Asegúrate de que este sea el nombre de tu BD en HeidiSQL / phpMyAdmin
$usuario = "root";
$pass = ""; // Laragon deja la contraseña de root vacía por defecto
$puerto = "3306";
try{ try{
$dsn = "mysql:host=$servidor;port=$puerto;dbname=$bd;charset=utf8mb4"; $servidor = 'mysql:host='.$_ENV['bDatosServer'].';dbname='.$_ENV['bDatos'];
$user=$_ENV['bDatosUser'];
$opciones = [ $password=$_ENV['bDatosPass'];
$options=array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
PDO::ATTR_EMULATE_PREPARES => false, );
]; //Creamos la conexión PDO a la base de datos
$pdo = new PDO($servidor, $user, $password, $options);
return new PDO($dsn, $usuario, $pass, $opciones);
} catch (PDOException $error) {
return [
'error' => 'No se pudo conectar a la base de datos.',
'error_tecnico' => $error->getMessage()
];
} }
catch(PDOException $e){
//$resultado = ['error' => $e->getMessage()];
$resultado = ['error' => 'Error Temporal: No se puede conectar con la base de datos.'];
return $resultado;
}
return $pdo;
} }
?>
+9 -7
View File
@@ -1,32 +1,33 @@
<?php <?php
include 'cabecera.php'; include 'cabecera.php';
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="es-ES"> <html lang="es-ES">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Triviagmático</title> <title>Triviagmático</title>
<script src="js/jquery-4.0.0.min.js"></script>
<link rel="icon" type="image/svg+xml" href="img/favicon/favicon.svg">
</head> </head>
<body> <body>
<div class="container my-5"> <div class="container my-5">
<div class="row justify-content-center align-items-center g-4"> <div class="row justify-content-center align-items-center g-4">
<!-- Botón Jugar (solo se muestra si está logueado) --> <!-- Botón Jugar (oculto por defecto, JS lo muestra si hay sesión) -->
<?php if ($isLoggedIn): ?> <div class="col-12 col-lg-5 col-xl-4 d-none" id="colBotonJugar">
<div class="col-12 col-lg-5 col-xl-4">
<a href="buscadorSala.php" class="btn btn-play-kahoot" id="btnJugar"> <a href="buscadorSala.php" class="btn btn-play-kahoot" id="btnJugar">
<i class="fa-solid fa-play"></i> <i class="fa-solid fa-play"></i>
<span>¡JUGAR!</span> <span>¡JUGAR!</span>
</a> </a>
</div> </div>
<?php endif; ?>
<!-- Ranking --> <!-- Ranking -->
<div class="col-12 <?= $isLoggedIn ? 'col-lg-7 col-xl-8' : 'col-lg-8' ?>"> <div class="col-12 col-lg-8" id="colRanking">
<div class="card ranking-card"> <div class="card ranking-card">
<div class="ranking-header"> <div class="ranking-header">
<h3 class="m-0"><i class="fa-solid fa-trophy me-2"></i> RANKING GLOBAL DE JUGADORES</h3> <h3 class="m-0"><i class="fa-solid fa-trophy me-2"></i> RANKING GLOBAL DE JUGADORES</h3>
@@ -47,6 +48,7 @@ include 'cabecera.php';
<!-- JS de Bootstrap --> <!-- JS de Bootstrap -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script src="js/index.js"></script>
</body> </body>
</html> </html>
+366 -65
View File
@@ -1,79 +1,380 @@
const btnCrearSala = document.getElementById("btnCrearSala"); let usuarioYaEstaEnEquipo = false;
const nombreSala = document.getElementById("nombreSala"); $(document).ready(function () {
const nombreEquipo1 = document.getElementById("nombreEquipo1"); comprobarSalaUsuario();
const nombreEquipo2 = document.getElementById("nombreEquipo2"); });
btnCrearSala.addEventListener("click", function () { // 1. Comprobar si el usuario actual ya pertenece a una sala
limpiarErrores(); function comprobarSalaUsuario() {
$("#cargandoSalas").remove();
const sala = nombreSala.value.trim(); $.ajax({
const equipo1 = nombreEquipo1.value.trim(); url: "controladores/ControladorEquipoxUsuario.php",
const equipo2 = nombreEquipo2.value.trim(); type: "POST",
dataType: "json",
let formularioValido = true; data: { orden: "obtenerSalaUsuario" },
success: function (respuesta) {
if (sala === "") { if (respuesta.error || !respuesta.asociado) {
mostrarError(nombreSala, "El nombre de la sala es obligatorio."); usuarioYaEstaEnEquipo = false;
$("#contenedorCrearSala").show();
formularioValido = false; cargarSalas();
} else {
usuarioYaEstaEnEquipo = true;
$("#contenedorCrearSala").hide(); // Ocultar "Crear Sala" si ya pertenece a una
cargarSalaUsuario(respuesta.idPartida);
}
},
error: function (xhr, status, error) {
console.error("Error al comprobar la sala del usuario:", error);
usuarioYaEstaEnEquipo = false;
cargarSalas();
},
});
} }
if (equipo1 === "") { // 2. Cargar únicamente la sala en la que está metido el usuario
mostrarError(nombreEquipo1, "El nombre del equipo 1 es obligatorio."); function cargarSalaUsuario(idPartida) {
$.ajax({
formularioValido = false; url: "controladores/controladorPartida.php",
type: "POST",
dataType: "json",
data: { orden: "buscar", idPartida: idPartida },
success: function (partida) {
if (partida.error) {
console.error(partida.error);
return;
}
$("#contenedorSalas").empty();
cargarInformacionSala(partida);
},
error: function (xhr, status, error) {
console.error("Error al obtener la sala del usuario:", error);
},
});
} }
if (equipo2 === "") { // 3. Cargar la lista completa de todas las salas
mostrarError(nombreEquipo2, "El nombre del equipo 2 es obligatorio."); function cargarSalas() {
$.ajax({
url: "controladores/controladorPartida.php",
type: "POST",
dataType: "json",
data: { orden: "listar" },
success: function (partidas) {
const contenedor = $("#contenedorSalas");
contenedor.empty();
formularioValido = false; if (!Array.isArray(partidas) || partidas.length === 0) {
} contenedor.html(`
<div class="col-12 text-center">
if (!formularioValido) { <p class="text-muted">No hay salas disponibles actualmente.</p>
</div>
`);
return; return;
} }
console.log("Sala:", sala); partidas.forEach(function (partida) {
console.log("Equipo 1:", equipo1); cargarInformacionSala(partida);
console.log("Equipo 2:", equipo2);
const idSala = 1;
//TODO aqui va la peticion ayax en el futuro para crear la sala en la bbdd
window.location.href = "sala.html?id=" + idSala;
}); });
},
function mostrarError(input, mensaje) { error: function (xhr, status, error) {
input.classList.add("is-invalid"); console.error("Error al obtener las partidas:", error);
},
// Comprobamos si ya existe un mensaje
let mensajeError = input.parentElement.querySelector(".invalid-feedback");
if (!mensajeError) {
mensajeError = document.createElement("div");
mensajeError.classList.add("invalid-feedback");
input.parentElement.appendChild(mensajeError);
}
mensajeError.textContent = mensaje;
}
function limpiarErrores() {
const inputs = [nombreSala, nombreEquipo1, nombreEquipo2];
inputs.forEach((input) => {
input.classList.remove("is-invalid");
const mensajeError = input.parentElement.querySelector(".invalid-feedback");
if (mensajeError) {
mensajeError.remove();
}
}); });
} }
// 4. Obtener equipos y jugadores asociados a una sala concreta
function cargarInformacionSala(partida) {
$.ajax({
url: "controladores/controladorPartida.php",
type: "POST",
dataType: "json",
data: { orden: "getEquipos", idPartida: partida.idPartida },
success: function (equipos) {
$.ajax({
url: "controladores/controladorPartida.php",
type: "POST",
dataType: "json",
data: { orden: "getJugadores", idPartida: partida.idPartida },
success: function (jugadores) {
mostrarSala(partida, equipos, jugadores);
},
error: function (xhr, status, error) {
console.error("Error al obtener jugadores:", error);
},
});
},
error: function (xhr, status, error) {
console.error("Error al obtener equipos:", error);
},
});
}
// 5. Renderizar el HTML de la sala y botones según estado
function mostrarSala(partida, equipos, jugadores) {
const contenedor = $("#contenedorSalas");
let equiposHTML = "";
equipos.forEach(function (equipo) {
const jugadoresEquipo = jugadores.filter(function (jugador) {
return jugador.idEquipo == equipo.idEquipo;
});
let jugadoresHTML = "";
if (jugadoresEquipo.length > 0) {
jugadoresEquipo.forEach(function (jugador) {
jugadoresHTML += `
<div class="jugador">
<span class="avatar">👤</span>
${escapeHTML(jugador.nombreUsuario)}
</div>
`;
});
} else {
jugadoresHTML = `<div class="text-muted small">Sin jugadores</div>`;
}
// Botón "Unirse" solo visible si NO pertenece a ningún equipo
let botonUnirseHTML = "";
if (!usuarioYaEstaEnEquipo) {
botonUnirseHTML = `
<button type="button" class="btn btn-unirse w-100 btn-unirse-equipo mt-2"
data-id-partida="${partida.idPartida}"
data-id-equipo="${equipo.idEquipo}">
Unirse
</button>
`;
}
equiposHTML += `
<div class="equipo me-2 ms-2 p-3 border rounded">
<h6>${escapeHTML(equipo.nombreEquipo)}</h6>
<div class="jugadores mb-2">
${jugadoresHTML}
</div>
${botonUnirseHTML}
</div>
`;
});
// Acciones disponibles si el usuario YA ESTÁ dentro de esta sala
let accionesSalaHTML = "";
if (usuarioYaEstaEnEquipo) {
accionesSalaHTML = `
<div class="sala-acciones text-center mt-4 pt-3 border-top d-flex justify-content-center gap-3">
<button type="button" class="btn btn-outline-danger btn-abandonar-sala" data-id-partida="${partida.idPartida}">
Abandonar sala
</button>
<a href="juego.php?idPartida=${partida.idPartida}" class="btn btn-success btn-lg px-4">
🎮 ¡Iniciar Partida!
</a>
</div>
`;
}
const salaHTML = `
<div class="col-12 col-md-10 col-lg-8">
<div class="sala card p-3 shadow-sm mb-4">
<div class="sala-header h4 text-center mb-3">
${escapeHTML(partida.nombrePartida)}
</div>
<div class="sala-body">
<div class="equipos d-flex justify-content-around">
${equiposHTML}
</div>
${accionesSalaHTML}
</div>
</div>
</div>
`;
contenedor.append(salaHTML);
}
// 6. Evento: Unirse a un Equipo
$(document).on("click", ".btn-unirse-equipo", function () {
const boton = $(this);
const idEquipo = boton.data("id-equipo");
const idPartida = boton.data("id-partida");
boton.prop("disabled", true).text("Uniéndose...");
$.ajax({
url: "controladores/ControladorEquipoxUsuario.php",
type: "POST",
dataType: "json",
data: {
orden: "registrarUsuarioEnEquipo",
idEquipo: idEquipo,
},
success: function (respuesta) {
if (respuesta.error) {
alert(respuesta.error);
boton.prop("disabled", false).text("Unirse");
return;
}
usuarioYaEstaEnEquipo = true;
$("#contenedorCrearSala").hide();
$("#contenedorSalas").empty();
cargarSalaUsuario(idPartida);
},
error: function (xhr, status, error) {
console.error("Error al unirse al equipo:", error);
alert("No se ha podido unir al equipo.");
boton.prop("disabled", false).text("Unirse");
},
});
});
// 7. Evento: Abandonar Sala
// Guardamos temporalmente el botón presionado
let botonAbandonarReferencia = null;
// A. Al hacer clic en el botón "Abandonar sala" de la tarjeta, abrimos el modal
$(document).on("click", ".btn-abandonar-sala", function () {
botonAbandonarReferencia = $(this);
const modal = new bootstrap.Modal(document.getElementById('modalAbandonarSala'));
modal.show();
});
// B. Al hacer clic en "Sí, salir" dentro del modal Kahoot
$(document).on("click", "#btnConfirmarAbandonar", function () {
const modalEl = document.getElementById('modalAbandonarSala');
const modalInstance = bootstrap.Modal.getInstance(modalEl);
const btnConfirmar = $(this);
btnConfirmar.prop("disabled", true).text("Saliendo...");
$.ajax({
url: "controladores/ControladorEquipoxUsuario.php",
type: "POST",
dataType: "json",
data: { orden: "salirDeSala" },
success: function (respuesta) {
btnConfirmar.prop("disabled", false).text("Sí, salir");
if (modalInstance) {
modalInstance.hide();
}
if (respuesta.error) {
alert(respuesta.error);
return;
}
// Restablecemos la interfaz a la lista completa de salas
usuarioYaEstaEnEquipo = false;
$("#contenedorCrearSala").show();
cargarSalas();
},
error: function (xhr, status, error) {
console.error("Error al salir de la sala:", error);
alert("No se pudo salir de la sala.");
btnConfirmar.prop("disabled", false).text("Sí, salir");
if (modalInstance) {
modalInstance.hide();
}
}
});
});
// 8. Evento: Crear Sala
$("#btnCrearSala").on("click", function () {
const nombreSala = $("#nombreSala").val().trim();
const nombreEquipo1 = $("#nombreEquipo1").val().trim();
const nombreEquipo2 = $("#nombreEquipo2").val().trim();
let valido = true;
$(".mensaje-error-sala").remove();
$(".input-kahoot").removeClass("is-invalid");
if (nombreSala === "" || nombreSala.length < 3) {
mostrarError(
"#nombreSala",
"El nombre de la sala debe tener al menos 3 caracteres.",
);
valido = false;
}
if (nombreEquipo1 === "" || nombreEquipo1.length < 2) {
mostrarError(
"#nombreEquipo1",
"El nombre del equipo debe tener al menos 2 caracteres.",
);
valido = false;
}
if (nombreEquipo2 === "" || nombreEquipo2.length < 2) {
mostrarError(
"#nombreEquipo2",
"El nombre del equipo debe tener al menos 2 caracteres.",
);
valido = false;
}
if (
nombreEquipo1 !== "" &&
nombreEquipo2 !== "" &&
nombreEquipo1.toLowerCase() === nombreEquipo2.toLowerCase()
) {
mostrarError(
"#nombreEquipo2",
"Los dos equipos deben tener nombres diferentes.",
);
valido = false;
}
if (!valido) return;
const boton = $("#btnCrearSala");
boton.prop("disabled", true).text("Creando sala...");
$.ajax({
url: "controladores/controladorPartida.php",
type: "POST",
dataType: "json",
data: {
orden: "crear",
nombrePartida: nombreSala,
nombreEquipo1: nombreEquipo1,
nombreEquipo2: nombreEquipo2,
},
success: function (respuesta) {
if (respuesta.error) {
alert(respuesta.error);
boton.prop("disabled", false).text("Crear sala");
return;
}
if (respuesta.exito) {
$("#modalCrearSala").modal("hide");
location.reload();
}
},
error: function (xhr, status, error) {
console.error("Error al crear la sala:", error);
alert("No se ha podido crear la sala.");
boton.prop("disabled", false).text("Crear sala");
},
});
});
// Auxiliares
function escapeHTML(texto) {
return $("<div>")
.text(texto ?? "")
.html();
}
function mostrarError(selector, mensaje) {
const input = $(selector);
input.addClass("is-invalid");
input.after(
`<div class="mensaje-error-sala text-danger mt-1 small">${mensaje}</div>`,
);
}
$(document).on("input", ".input-kahoot", function () {
$(this).removeClass("is-invalid");
$(this).next(".mensaje-error-sala").remove();
});
+275
View File
@@ -0,0 +1,275 @@
$(document).ready(function () {
comprobarSesion();
});
// Función auxiliar para escapar texto HTML y evitar XSS
function escapeHTML(str) {
return $("<div>").text(str ?? "").html();
}
// Comprobar estado de sesión al cargar la página
function comprobarSesion() {
$.ajax({
method: "POST",
url: "controladores/controladorUsuario.php",
data: { orden: "comprobarSesion" },
}).done(function (respuesta) {
try {
if (typeof respuesta === "string") {
respuesta = JSON.parse(respuesta);
}
const contenedor = $("#contenedorUsuarioCabecera");
contenedor.empty();
if (respuesta.activa && respuesta.usuario) {
// Usuario autenticado: Mostrar Menú Dropdown
const htmlUsuario = `
<div class="dropdown">
<button class="btn user-dropdown-btn dropdown-toggle d-flex align-items-center gap-2"
type="button" id="userDropdown" data-bs-toggle="dropdown" aria-expanded="false">
<i class="fa-solid fa-circle-user fa-lg text-warning"></i>
<span>${escapeHTML(respuesta.usuario.nombreUsuario)}</span>
</button>
<ul class="dropdown-menu dropdown-menu-end user-dropdown-menu" aria-labelledby="userDropdown">
<li>
<a class="dropdown-item d-flex align-items-center gap-2" href="perfil.php">
<i class="fa-solid fa-user text-primary"></i> Perfil
</a>
</li>
<li><hr class="dropdown-divider"></li>
<li>
<a class="dropdown-item logout-item d-flex align-items-center gap-2" href="#" id="botonCerrarSesion">
<i class="fa-solid fa-right-from-bracket"></i> Cerrar Sesión
</a>
</li>
</ul>
</div>
`;
contenedor.html(htmlUsuario);
// Si estamos en la página principal, mostramos el botón JUGAR
if ($("#colBotonJugar").length) {
$("#colBotonJugar").removeClass("d-none");
$("#colRanking").removeClass("col-lg-8").addClass("col-lg-7 col-xl-8");
}
} else {
// No hay sesión: Mostrar botones de Login y Registro
const htmlInvitado = `
<button type="button" class="btn btn-kahoot-login rounded-pill px-4" data-bs-toggle="modal" data-bs-target="#modalLogin">
<i class="fa-solid fa-right-to-bracket me-1"></i> Iniciar Sesión
</button>
<button type="button" class="btn btn-kahoot-register rounded-pill px-4" data-bs-toggle="modal" data-bs-target="#modalRegistro">
<i class="fa-solid fa-user-plus me-1"></i> Registrarse
</button>
`;
contenedor.html(htmlInvitado);
// Si estamos en la página principal, ocultamos el botón JUGAR
if ($("#colBotonJugar").length) {
$("#colBotonJugar").addClass("d-none");
$("#colRanking").removeClass("col-lg-7 col-xl-8").addClass("col-lg-8");
}
}
} catch (e) {
console.error("Error al procesar la respuesta de la sesión:", e);
}
});
}
// Evento Registro
$("#botonAceptarRegistro").click(function (event) {
event.preventDefault();
let nombreUsuario = $("#regNombre").val().trim();
let email = $("#regEmail").val().trim();
let contrasena = $("#regPassword").val();
let contrasenaConfirmacion = $("#regPasswordConfirm").val();
$("#regNombre").removeClass("is-invalid");
$("#regEmail").removeClass("is-invalid");
$("#regPassword").removeClass("is-invalid");
$("#regPasswordConfirm").removeClass("is-invalid");
$("#errorRegistro").text("");
if (contrasena !== contrasenaConfirmacion) {
$("#regPassword").addClass("is-invalid");
$("#regPasswordConfirm").addClass("is-invalid");
$("#errorRegistro").text("Las contraseñas no coinciden.");
return;
}
$.ajax({
method: "POST",
url: "controladores/controladorUsuario.php",
data: {
nombreUsuario: nombreUsuario,
email: email,
contrasena: contrasena,
orden: "registrarUsuario",
},
}).done(function (respuesta) {
if (typeof respuesta === "string") respuesta = JSON.parse(respuesta);
if (respuesta.error) {
$("#errorRegistro").text(respuesta.error);
$("#regNombre").addClass("is-invalid");
$("#regEmail").addClass("is-invalid");
} else {
$("#errorRegistro")
.removeClass("text-danger")
.addClass("text-success")
.text(respuesta.exito);
$("#formRegistro")[0].reset();
setTimeout(function () {
location.reload();
}, 1000);
}
});
});
// Evento Login
$("#botonAceptarLogin").click(function (event) {
event.preventDefault();
let email = $("#loginEmail").val().trim();
let contrasena = $("#loginPassword").val();
$("#loginEmail").removeClass("is-invalid");
$("#loginPassword").removeClass("is-invalid");
$("#errorLogin").text("");
if (email === "" || contrasena === "") {
$("#errorLogin").text("Todos los campos son obligatorios.");
if (email === "") $("#loginEmail").addClass("is-invalid");
if (contrasena === "") $("#loginPassword").addClass("is-invalid");
return;
}
$.ajax({
method: "POST",
url: "controladores/controladorUsuario.php",
data: {
email: email,
contrasena: contrasena,
orden: "comprobarUsuario",
},
}).done(function (respuesta) {
if (typeof respuesta === "string") respuesta = JSON.parse(respuesta);
if (respuesta.error) {
$("#loginEmail").addClass("is-invalid");
$("#loginPassword").addClass("is-invalid");
$("#errorLogin").text(respuesta.error);
} else {
location.reload();
}
});
});
// Evento Cerrar sesión (usa delegación de eventos por crearse dinámicamente)
$(document).on("click", "#botonCerrarSesion", function (event) {
event.preventDefault();
$.ajax({
method: "POST",
url: "controladores/controladorUsuario.php",
data: { orden: "cerrarSesion" },
}).done(function (respuesta) {
if (typeof respuesta === "string") respuesta = JSON.parse(respuesta);
if (respuesta.error) {
console.log(respuesta.error);
} else {
window.location.href = "index.php";
}
});
});
// Registro
$("#botonAceptarRegistro").click(function (event) {
event.preventDefault();
let nombreUsuario = $("#regNombre").val().trim();
let email = $("#regEmail").val().trim();
let contrasena = $("#regPassword").val();
let contrasenaConfirmacion = $("#regPasswordConfirm").val();
$("#regNombre").removeClass("is-invalid");
$("#regEmail").removeClass("is-invalid");
$("#regPassword").removeClass("is-invalid");
$("#regPasswordConfirm").removeClass("is-invalid");
$("#errorRegistro").text("");
if (contrasena !== contrasenaConfirmacion) {
$("#regPassword").addClass("is-invalid");
$("#regPasswordConfirm").addClass("is-invalid");
$("#errorRegistro").text("Las contraseñas no coinciden.");
return;
}
$.ajax({
method: "POST",
url: "controladores/controladorUsuario.php",
data: {
nombreUsuario: nombreUsuario,
email: email,
contrasena: contrasena,
orden: "registrarUsuario",
},
}).done(function (respuesta) {
if (typeof respuesta === "string") respuesta = JSON.parse(respuesta);
if (respuesta.error) {
$("#errorRegistro").text(respuesta.error);
$("#regNombre").addClass("is-invalid");
$("#regEmail").addClass("is-invalid");
} else {
$("#errorRegistro")
.removeClass("text-danger")
.addClass("text-success")
.text(respuesta.exito);
$("#formRegistro")[0].reset();
setTimeout(function () {
location.reload();
}, 1000);
}
});
});
// Login
$("#botonAceptarLogin").click(function (event) {
event.preventDefault();
let email = $("#loginEmail").val().trim();
let contrasena = $("#loginPassword").val();
$("#loginEmail").removeClass("is-invalid");
$("#loginPassword").removeClass("is-invalid");
$("#errorLogin").text("");
if (email === "" || contrasena === "") {
$("#errorLogin").text("Todos los campos son obligatorios.");
if (email === "") $("#loginEmail").addClass("is-invalid");
if (contrasena === "") $("#loginPassword").addClass("is-invalid");
return;
}
$.ajax({
method: "POST",
url: "controladores/controladorUsuario.php",
data: { orden: "cerrarSesion" },
}).done(function (respuesta) {
if (typeof respuesta === "string") respuesta = JSON.parse(respuesta);
if (respuesta.error) {
console.log(respuesta.error);
} else {
window.location.href = "index.php";
}
});
});
+95
View File
@@ -0,0 +1,95 @@
$(document).ready(function () {
cargarRanking();
});
function cargarRanking() {
$.ajax({
url: 'controladores/controladorUsuario.php',
type: 'POST',
data: { orden: 'obtenerRanking' },
dataType: 'json',
success: function (response) {
if (response.exito && response.ranking.length > 0) {
renderizarTablaRanking(response.ranking);
} else {
$('#ranking-container').html(`
<div class="alert alert-info my-3">
<i class="fa-solid fa-info-circle me-2"></i>Aún no hay partidas registradas para mostrar el ranking.
</div>
`);
}
},
error: function () {
$('#ranking-container').html(`
<div class="alert alert-danger my-3">
<i class="fa-solid fa-exclamation-triangle me-2"></i>Error al cargar la clasificación.
</div>
`);
}
});
}
function renderizarTablaRanking(jugadores) {
let html = `
<div class="table-responsive">
<table class="table table-striped table-hover align-middle mb-0 text-center">
<thead class="table-dark">
<tr>
<th scope="col" style="width: 10%;">#</th>
<th scope="col" class="text-start" style="width: 35%;">Jugador</th>
<th scope="col" style="width: 15%;"><i class="fa-solid fa-trophy text-warning me-1"></i> Vic</th>
<th scope="col" style="width: 15%;"><i class="fa-solid fa-xmark text-danger me-1"></i> Der</th>
<th scope="col" style="width: 15%;"><i class="fa-solid fa-bullseye text-success me-1"></i> Aciertos</th>
<th scope="col" style="width: 10%;"><i class="fa-solid fa-percent text-info me-1"></i> % Vic</th>
</tr>
</thead>
<tbody>
`;
jugadores.forEach((jugador, index) => {
let posicion = index + 1;
let medalla = '';
// Medallas para el Top 3
if (posicion === 1) {
medalla = '<i class="fa-solid fa-medal text-warning fa-lg" title="1º Puesto"></i>';
} else if (posicion === 2) {
medalla = '<i class="fa-solid fa-medal text-secondary fa-lg" title="2º Puesto"></i>';
} else if (posicion === 3) {
medalla = '<i class="fa-solid fa-medal text-brown fa-lg" style="color: #cd7f32;" title="3º Puesto"></i>';
} else {
medalla = `<span class="fw-bold text-muted">${posicion}</span>`;
}
let avatarImg = jugador.avatar ? jugador.avatar : 'img/avatars/defaultProfile.jpeg';
html += `
<tr>
<td class="fw-bold fs-5">${medalla}</td>
<td class="text-start fw-bold">
<img src="${avatarImg}" alt="Avatar" class="rounded-circle me-2 border" style="width: 32px; height: 32px; object-fit: cover;">
${escapeHtml(jugador.nombreUsuario)}
</td>
<td><span class="badge bg-success rounded-pill px-3 py-2 fs-6">${jugador.victorias}</span></td>
<td><span class="badge bg-danger rounded-pill px-3 py-2 fs-6">${jugador.derrotas}</span></td>
<td class="fw-bold text-primary fs-6">${jugador.aciertos}</td>
<td>
<span class="badge bg-info text-dark rounded-pill px-2 py-1">${jugador.porcentajeVictoria}%</span>
</td>
</tr>
`;
});
html += `
</tbody>
</table>
</div>
`;
$('#ranking-container').removeClass('text-center p-4 ranking-placeholder').html(html);
}
function escapeHtml(texto) {
return $('<div>').text(texto).html();
}
+219 -40
View File
@@ -1,74 +1,253 @@
// =========================
// MOSTRAR ESTADISTICAS
// =========================
$.ajax({
method: "POST",
url: "controladores/controladorUsuario.php",
data: {
orden: "mostrarEstadisticas",
},
}).done(function (respuesta) {
console.log(respuesta);
respuesta = JSON.parse(respuesta);
if (respuesta.error) {
console.log(respuesta.error);
} else {
$("#victorias").text(respuesta.victorias);
$("#derrotas").text(respuesta.derrotas);
$("#aciertos").text(respuesta.aciertos);
}
});
// ========================= // =========================
// CAMBIAR NOMBRE // CAMBIAR NOMBRE
// ========================= // =========================
function cambiarNombre() { function cambiarNombre() {
let nuevoNombre = $("#nuevoNombre").val().trim();
const input = document.getElementById("nuevoNombre"); $.ajax({
const nombre = document.getElementById("nombre"); method: "POST",
url: "controladores/controladorUsuario.php",
data: {
nombreUsuario: nuevoNombre,
orden: "cambiarNombre",
},
}).done(function (respuesta) {
console.log(respuesta);
respuesta = JSON.parse(respuesta);
if (respuesta.error) {
console.log(respuesta.error);
} else {
// Actualizamos el nombre mostrado en la página
$("#nombre").text(respuesta.nombreUsuario);
const nuevoNombre = input.value.trim(); // Limpiamos el input
$("#nuevoNombre").val("");
if (nuevoNombre !== "") {
nombre.textContent = nuevoNombre;
input.value = "";
} }
});
} }
// ========================= // =========================
// BORRAR NOMBRE // BORRAR NOMBRE
// ========================= // =========================
function borrarNombre() { function borrarNombre() {
document.getElementById("nuevoNombre").value = ""; document.getElementById("nuevoNombre").value = "";
} }
// =========================
// ABRIR SELECTOR DE IMAGEN
// =========================
function seleccionarFoto() {
document.getElementById("inputFoto").click();
}
// ========================= // =========================
// CAMBIAR FOTO // CAMBIAR FOTO
// ========================= // =========================
document.getElementById("inputFoto").addEventListener( function seleccionarFoto() {
"change", $("#inputFoto").click();
function(event) { }
const archivo = event.target.files[0]; $("#inputFoto").change(function () {
let archivo = this.files[0];
if (archivo) { if (!archivo) {
return;
}
// Comprobamos que sea una imagen // Comprobamos que sea una imagen
if (!archivo.type.startsWith("image/")) { if (!archivo.type.startsWith("image/")) {
alert("El archivo seleccionado no es una imagen.");
alert("Por favor, selecciona una imagen."); $("#inputFoto").val("");
return; return;
} }
let datos = new FormData();
// Creamos una URL temporal datos.append("avatar", archivo);
const imagenURL = URL.createObjectURL(archivo); datos.append("orden", "cambiarAvatar");
$.ajax({
// Cambiamos la foto method: "POST",
document.getElementById("fotoPerfil").src = imagenURL; url: "controladores/controladorUsuario.php",
data: datos,
} processData: false,
contentType: false,
} }).done(function (respuesta) {
console.log(respuesta);
respuesta = JSON.parse(respuesta);
if (respuesta.error) {
alert(respuesta.error);
} else {
// Actualizamos la imagen sin recargar la página
$("#fotoPerfil").attr(
"src",
respuesta.avatar + "?t=" + new Date().getTime(),
); );
}
});
});
// =========================
// RECOGER CATEGORIAS
// ====
$("#modalCrearPregunta").on("show.bs.modal", function () {
const selectCategoria = $("#idCategoria");
// Limpiamos las categorías anteriores
selectCategoria.empty();
// Opción inicial
selectCategoria.append('<option value="">Selecciona una categoría</option>');
$.ajax({
url: "controladores/controladorCategoria.php",
type: "POST",
dataType: "json",
data: {
orden: "listarCategorias",
},
success: function (respuesta) {
console.log("Categorías:", respuesta);
if (respuesta.error) {
alert(respuesta.error);
return;
}
$.each(respuesta, function (index, categoria) {
selectCategoria.append(
$("<option>", {
value: categoria.idCategoria,
text: categoria.nombreCategoria,
}),
);
});
},
error: function (xhr, status, error) {
console.error("Error al cargar las categorías:", error);
console.error("Respuesta del servidor:", xhr.responseText);
alert("No se han podido cargar las categorías.");
},
});
});
// =========================
// CREAR PREGUNTA
// ====
$("#formCrearPregunta").on("submit", function (e) {
e.preventDefault();
const boton = $("#btnCrearPregunta");
const pregunta = $("#pregunta").val().trim();
const respuestaCorrecta = $("#respuestaCorrecta").val().trim();
const respuestaIncorrecta1 = $("#respuestaIncorrecta1").val().trim();
const respuestaIncorrecta2 = $("#respuestaIncorrecta2").val().trim();
const respuestaIncorrecta3 = $("#respuestaIncorrecta3").val().trim();
// Comprobamos que no haya campos vacíos
if (
pregunta === "" ||
respuestaCorrecta === "" ||
respuestaIncorrecta1 === "" ||
respuestaIncorrecta2 === "" ||
respuestaIncorrecta3 === ""
) {
alert("Todos los campos son obligatorios.");
return;
}
boton.prop("disabled", true);
boton.text("Creando pregunta...");
$.ajax({
url: "controladores/controladorPregunta.php",
type: "POST",
dataType: "json",
data: {
orden: "crearPregunta",
idCategoria: $("#idCategoria").val(),
nombrePregunta: pregunta,
respuestaCorrecta: respuestaCorrecta,
respuestaIncorrecta1: respuestaIncorrecta1,
respuestaIncorrecta2: respuestaIncorrecta2,
respuestaIncorrecta3: respuestaIncorrecta3,
},
success: function (respuesta) {
console.log("Respuesta del servidor:", respuesta);
if (respuesta.error) {
alert(respuesta.error);
boton.prop("disabled", false);
boton.text("Crear pregunta");
return;
}
if (respuesta.exito) {
console.log("Pregunta creada:", respuesta.idPregunta);
// Cerramos el modal
$("#modalCrearPregunta").modal("hide");
// Limpiamos el formulario
$("#formCrearPregunta")[0].reset();
// Volvemos a activar el botón
boton.prop("disabled", false);
boton.text("Crear pregunta");
// Si tienes que actualizar la lista de preguntas:
// cargarPreguntas();
}
},
error: function (xhr, status, error) {
console.error("Error al crear la pregunta:", error);
console.error("Respuesta del servidor:", xhr.responseText);
alert("No se ha podido crear la pregunta.");
boton.prop("disabled", false);
boton.text("Crear pregunta");
},
});
});
+1
View File
@@ -6,6 +6,7 @@
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
<title>Proyecto Trivial</title> <title>Proyecto Trivial</title>
<link rel="stylesheet" href="css/juego.css"> <link rel="stylesheet" href="css/juego.css">
<link rel="icon" type="image/svg+xml" href="img/favicon/favicon.svg">
</head> </head>
<body> <body>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

@@ -64,7 +64,7 @@ CREATE TABLE `equipo` (
`idEquipo` int(11) NOT NULL AUTO_INCREMENT, `idEquipo` int(11) NOT NULL AUTO_INCREMENT,
`nombreEquipo` varchar(50) NOT NULL, `nombreEquipo` varchar(50) NOT NULL,
PRIMARY KEY (`idEquipo`) PRIMARY KEY (`idEquipo`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci; ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
-- --
@@ -73,6 +73,11 @@ CREATE TABLE `equipo` (
LOCK TABLES `equipo` WRITE; LOCK TABLES `equipo` WRITE;
/*!40000 ALTER TABLE `equipo` DISABLE KEYS */; /*!40000 ALTER TABLE `equipo` DISABLE KEYS */;
INSERT INTO `equipo` VALUES
(1,'Los Trivialistas'),
(2,'Los Cerebritos'),
(3,'Los Sabios'),
(4,'Los Exploradores');
/*!40000 ALTER TABLE `equipo` ENABLE KEYS */; /*!40000 ALTER TABLE `equipo` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;
@@ -92,7 +97,7 @@ CREATE TABLE `equipoxpartida` (
KEY `FK idPartida tabla partida` (`idPartida`), KEY `FK idPartida tabla partida` (`idPartida`),
CONSTRAINT `FK idEquipo tabla equipo` FOREIGN KEY (`idEquipo`) REFERENCES `equipo` (`idEquipo`), CONSTRAINT `FK idEquipo tabla equipo` FOREIGN KEY (`idEquipo`) REFERENCES `equipo` (`idEquipo`),
CONSTRAINT `FK idPartida tabla partida` FOREIGN KEY (`idPartida`) REFERENCES `partida` (`idPartida`) CONSTRAINT `FK idPartida tabla partida` FOREIGN KEY (`idPartida`) REFERENCES `partida` (`idPartida`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci; ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
-- --
@@ -101,6 +106,13 @@ CREATE TABLE `equipoxpartida` (
LOCK TABLES `equipoxpartida` WRITE; LOCK TABLES `equipoxpartida` WRITE;
/*!40000 ALTER TABLE `equipoxpartida` DISABLE KEYS */; /*!40000 ALTER TABLE `equipoxpartida` DISABLE KEYS */;
INSERT INTO `equipoxpartida` VALUES
(1,1,1),
(2,1,2),
(3,2,2),
(4,2,3),
(5,3,3),
(6,3,4);
/*!40000 ALTER TABLE `equipoxpartida` ENABLE KEYS */; /*!40000 ALTER TABLE `equipoxpartida` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;
@@ -120,7 +132,7 @@ CREATE TABLE `equipoxusuario` (
KEY `idEquipo` (`idEquipo`), KEY `idEquipo` (`idEquipo`),
CONSTRAINT `equipoxusuario_ibfk_1` FOREIGN KEY (`idUsuario`) REFERENCES `usuario` (`idUsuario`), CONSTRAINT `equipoxusuario_ibfk_1` FOREIGN KEY (`idUsuario`) REFERENCES `usuario` (`idUsuario`),
CONSTRAINT `equipoxusuario_ibfk_2` FOREIGN KEY (`idEquipo`) REFERENCES `equipo` (`idEquipo`) CONSTRAINT `equipoxusuario_ibfk_2` FOREIGN KEY (`idEquipo`) REFERENCES `equipo` (`idEquipo`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci; ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
-- --
@@ -129,6 +141,17 @@ CREATE TABLE `equipoxusuario` (
LOCK TABLES `equipoxusuario` WRITE; LOCK TABLES `equipoxusuario` WRITE;
/*!40000 ALTER TABLE `equipoxusuario` DISABLE KEYS */; /*!40000 ALTER TABLE `equipoxusuario` DISABLE KEYS */;
INSERT INTO `equipoxusuario` VALUES
(1,1,1),
(2,2,1),
(3,3,1),
(4,4,2),
(5,5,2),
(6,6,2),
(7,7,3),
(8,8,3),
(9,9,4),
(10,10,4);
/*!40000 ALTER TABLE `equipoxusuario` ENABLE KEYS */; /*!40000 ALTER TABLE `equipoxusuario` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;
@@ -146,7 +169,7 @@ CREATE TABLE `partida` (
PRIMARY KEY (`idPartida`), PRIMARY KEY (`idPartida`),
KEY `FK idUsuario tabla usuario` (`idUsuario`), KEY `FK idUsuario tabla usuario` (`idUsuario`),
CONSTRAINT `FK idUsuario tabla usuario` FOREIGN KEY (`idUsuario`) REFERENCES `usuario` (`idUsuario`) CONSTRAINT `FK idUsuario tabla usuario` FOREIGN KEY (`idUsuario`) REFERENCES `usuario` (`idUsuario`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci; ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
-- --
@@ -155,6 +178,10 @@ CREATE TABLE `partida` (
LOCK TABLES `partida` WRITE; LOCK TABLES `partida` WRITE;
/*!40000 ALTER TABLE `partida` DISABLE KEYS */; /*!40000 ALTER TABLE `partida` DISABLE KEYS */;
INSERT INTO `partida` VALUES
(1,'Partida de prueba 1',1),
(2,'Partida de prueba 2',4),
(3,'Partida de prueba 3',9);
/*!40000 ALTER TABLE `partida` ENABLE KEYS */; /*!40000 ALTER TABLE `partida` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;
@@ -174,7 +201,7 @@ CREATE TABLE `partidaxpregunta` (
KEY `idPregunta` (`idPregunta`), KEY `idPregunta` (`idPregunta`),
CONSTRAINT `partidaxpregunta_ibfk_1` FOREIGN KEY (`idPartida`) REFERENCES `partida` (`idPartida`), CONSTRAINT `partidaxpregunta_ibfk_1` FOREIGN KEY (`idPartida`) REFERENCES `partida` (`idPartida`),
CONSTRAINT `partidaxpregunta_ibfk_2` FOREIGN KEY (`idPregunta`) REFERENCES `pregunta` (`idPregunta`) CONSTRAINT `partidaxpregunta_ibfk_2` FOREIGN KEY (`idPregunta`) REFERENCES `pregunta` (`idPregunta`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci; ) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
-- --
@@ -183,6 +210,37 @@ CREATE TABLE `partidaxpregunta` (
LOCK TABLES `partidaxpregunta` WRITE; LOCK TABLES `partidaxpregunta` WRITE;
/*!40000 ALTER TABLE `partidaxpregunta` DISABLE KEYS */; /*!40000 ALTER TABLE `partidaxpregunta` DISABLE KEYS */;
INSERT INTO `partidaxpregunta` VALUES
(1,1,2140),
(2,1,2141),
(3,1,2142),
(4,1,2143),
(5,1,2144),
(6,1,2145),
(7,1,2146),
(8,1,2147),
(9,1,2148),
(10,1,2149),
(11,2,2150),
(12,2,2151),
(13,2,2152),
(14,2,2153),
(15,2,2154),
(16,2,2155),
(17,2,2156),
(18,2,2157),
(19,2,2158),
(20,2,2159),
(21,3,2160),
(22,3,2161),
(23,3,2162),
(24,3,2163),
(25,3,2164),
(26,3,2165),
(27,3,2166),
(28,3,2167),
(29,3,2168),
(30,3,2169);
/*!40000 ALTER TABLE `partidaxpregunta` ENABLE KEYS */; /*!40000 ALTER TABLE `partidaxpregunta` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;
@@ -2303,4 +2361,4 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; /*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */;
-- Dump completed on 2026-09-25 9:54:43 -- Dump completed on 2026-09-25 10:00:41
+60 -187
View File
@@ -1,157 +1,121 @@
<?php
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
// Redirección si el usuario no ha iniciado sesión
if (!isset($_SESSION['idUsuario'])) {
header('Location: login.php');
exit();
}
$nombreUsuario = htmlspecialchars($_SESSION['nombreUsuario'] ?? 'Usuario');
$avatarUsuario = htmlspecialchars($_SESSION['avatar'] ?? 'img/avatars/defaultProfile.jpeg');
?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="es"> <html lang="es">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/svg+xml" href="img/favicon/favicon.svg">
<title>Perfil</title> <title>Perfil</title>
<!-- Bootstrap --> <!-- Bootstrap -->
<link <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet">
<!-- Bootstrap Icons --> <!-- Bootstrap Icons -->
<link <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<!-- Google Font: Fredoka --> <!-- Google Font: Fredoka -->
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&display=swap" rel="stylesheet">
<link
href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&display=swap"
rel="stylesheet">
<!-- Tu CSS --> <!-- Tu CSS -->
<link rel="stylesheet" href="css/index.css"> <link rel="stylesheet" href="css/index.css">
<link rel="stylesheet" href="css/perfil.css"> <link rel="stylesheet" href="css/perfil.css">
<script src="js/jquery-4.0.0.min.js"></script>
</head> </head>
<body> <body>
<?php <?php include_once 'cabecera.php'; ?>
include_once 'cabecera.php';
?>
<div class="perfil-container"> <div class="perfil-container">
<div class="perfil-card"> <div class="perfil-card">
<!-- ========================= -->
<!-- CABECERA --> <!-- CABECERA -->
<!-- ========================= -->
<div class="perfil-header"> <div class="perfil-header">
<i class="bi bi-person-circle"></i> <i class="bi bi-person-circle"></i>
Mi perfil Mi perfil
</div> </div>
<div class="perfil-content"> <div class="perfil-content">
<div class="row align-items-center g-5"> <div class="row align-items-center g-5">
<!-- ========================= -->
<!-- PERFIL --> <!-- PERFIL -->
<!-- ========================= -->
<div class="col-md-6 text-center"> <div class="col-md-6 text-center">
<!-- Nombre --> <!-- Nombre -->
<h1 id="nombre" class="nombre"> <h1 id="nombre" class="nombre">
tuNombre <?= $nombreUsuario ?>
</h1> </h1>
<!-- ========================= -->
<!-- FOTO DE PERFIL --> <!-- FOTO DE PERFIL -->
<!-- ========================= -->
<div class="foto-container"> <div class="foto-container">
<img <img id="fotoPerfil"
id="fotoPerfil" src="<?= $avatarUsuario ?>"
src="https://i.pravatar.cc/300?img=47"
alt="Foto de perfil" alt="Foto de perfil"
class="avatar rounded-circle"> class="avatar rounded-circle">
<!-- Botón lápiz --> <!-- Botón lápiz -->
<button type="button"
<button
type="button"
class="btn-foto" class="btn-foto"
onclick="seleccionarFoto()" onclick="seleccionarFoto()"
title="Cambiar foto de perfil" title="Cambiar foto de perfil"
aria-label="Cambiar foto de perfil"> aria-label="Cambiar foto de perfil">
<i class="bi bi-pencil-fill"></i> <i class="bi bi-pencil-fill"></i>
</button> </button>
<!-- Input oculto --> <!-- Input oculto -->
<input type="file"
<input
type="file"
id="inputFoto" id="inputFoto"
accept="image/*" accept="image/*"
hidden> hidden>
</div> </div>
<!-- ========================= -->
<!-- CAMBIAR NOMBRE --> <!-- CAMBIAR NOMBRE -->
<!-- ========================= -->
<div class="formulario-nombre"> <div class="formulario-nombre">
<label <label for="nuevoNombre" class="form-label">
for="nuevoNombre"
class="form-label">
Cambia tu nombre Cambia tu nombre
</label> </label>
<input type="text"
<input
type="text"
id="nuevoNombre" id="nuevoNombre"
class="form-control mb-3" class="form-control mb-3"
placeholder="Escribe tu nuevo nombre"> placeholder="Escribe tu nuevo nombre">
<div class="d-flex justify-content-center gap-2"> <div class="d-flex justify-content-center gap-2">
<button <button type="button"
type="button"
class="btn-perfil-cambiar" class="btn-perfil-cambiar"
onclick="cambiarNombre()"> onclick="cambiarNombre()">
<i class="bi bi-check-lg"></i> <i class="bi bi-check-lg"></i>
Cambiar nombre Cambiar nombre
</button> </button>
<button type="button"
<button
type="button"
class="btn-perfil-borrar" class="btn-perfil-borrar"
onclick="borrarNombre()"> onclick="borrarNombre()">
<i class="bi bi-x-lg"></i> <i class="bi bi-x-lg"></i>
Borrar Borrar
</button> </button>
</div> </div>
@@ -160,11 +124,7 @@
</div> </div>
<!-- ========================= -->
<!-- ESTADÍSTICAS --> <!-- ESTADÍSTICAS -->
<!-- ========================= -->
<div class="col-md-6"> <div class="col-md-6">
<div class="estadisticas"> <div class="estadisticas">
@@ -174,60 +134,33 @@
Estadísticas Estadísticas
</h2> </h2>
<div class="estadistica estadistica-victorias"> <div class="estadistica estadistica-victorias">
<i class="bi bi-trophy-fill"></i> <i class="bi bi-trophy-fill"></i>
&nbsp; Victorias: &nbsp; Victorias:
<strong id="victorias">0</strong>
<strong>
0
</strong>
</div> </div>
<div class="estadistica estadistica-derrotas"> <div class="estadistica estadistica-derrotas">
<i class="bi bi-x-circle-fill"></i> <i class="bi bi-x-circle-fill"></i>
&nbsp; Derrotas: &nbsp; Derrotas:
<strong id="derrotas">0</strong>
<strong>
0
</strong>
</div> </div>
<div class="estadistica estadistica-aciertos"> <div class="estadistica estadistica-aciertos">
<i class="bi bi-bullseye"></i> <i class="bi bi-bullseye"></i>
&nbsp; Aciertos: &nbsp; Aciertos:
<strong id="aciertos">0</strong>
<strong>
0
</strong>
</div> </div>
<!-- ========================= -->
<!-- CREAR PREGUNTA --> <!-- CREAR PREGUNTA -->
<!-- ========================= -->
<div class="text-center mt-4"> <div class="text-center mt-4">
<button type="button"
<button
type="button"
class="btn btn-play-kahoot" class="btn btn-play-kahoot"
data-bs-toggle="modal" data-bs-toggle="modal"
data-bs-target="#modalCrearPregunta"> data-bs-target="#modalCrearPregunta">
<i class="bi bi-plus-circle-fill"></i> <i class="bi bi-plus-circle-fill"></i>
Crear pregunta Crear pregunta
</button> </button>
</div> </div>
</div> </div>
@@ -243,12 +176,8 @@
</div> </div>
<!-- ================================================= -->
<!-- MODAL CREAR PREGUNTA --> <!-- MODAL CREAR PREGUNTA -->
<!-- ================================================= --> <div class="modal fade"
<div
class="modal fade"
id="modalCrearPregunta" id="modalCrearPregunta"
tabindex="-1" tabindex="-1"
aria-labelledby="modalCrearPreguntaLabel" aria-labelledby="modalCrearPreguntaLabel"
@@ -258,157 +187,107 @@
<div class="modal-content modal-kahoot"> <div class="modal-content modal-kahoot">
<!-- CABECERA DEL MODAL -->
<div class="modal-header modal-kahoot-header"> <div class="modal-header modal-kahoot-header">
<h5 class="modal-title" id="modalCrearPreguntaLabel">
<h5
class="modal-title"
id="modalCrearPreguntaLabel">
<i class="bi bi-question-circle-fill me-2"></i> <i class="bi bi-question-circle-fill me-2"></i>
Crear pregunta Crear pregunta
</h5> </h5>
<button type="button"
<button
type="button"
class="btn-close btn-close-white" class="btn-close btn-close-white"
data-bs-dismiss="modal" data-bs-dismiss="modal"
aria-label="Cerrar"> aria-label="Cerrar">
</button> </button>
</div> </div>
<!-- CUERPO DEL MODAL -->
<div class="modal-body p-4"> <div class="modal-body p-4">
<form id="formCrearPregunta"> <form id="formCrearPregunta">
<!-- PREGUNTA --> <!-- PREGUNTA -->
<div class="mb-4"> <div class="mb-4">
<label for="pregunta" class="form-label fw-semibold">
<label
for="pregunta"
class="form-label fw-semibold">
<i class="bi bi-question-lg me-1"></i> <i class="bi bi-question-lg me-1"></i>
Pregunta Pregunta
</label> </label>
<textarea id="pregunta"
<textarea
id="pregunta"
name="pregunta" name="pregunta"
class="form-control input-kahoot" class="form-control input-kahoot"
rows="3" rows="3"
placeholder="Escribe aquí la pregunta..." placeholder="Escribe aquí la pregunta..."
required></textarea> required></textarea>
</div> </div>
<!-- CATEGORÍA -->
<div class="mb-4">
<label for="idCategoria" class="form-label fw-semibold">
<i class="bi bi-folder-fill me-1"></i>
Categoría
</label>
<select id="idCategoria"
name="idCategoria"
class="form-select input-kahoot"
required>
<option value="">Selecciona una categoría</option>
</select>
</div>
<!-- RESPUESTA CORRECTA --> <!-- RESPUESTA CORRECTA -->
<div class="mb-3"> <div class="mb-3">
<label for="respuestaCorrecta" class="form-label fw-semibold text-success">
<label
for="respuestaCorrecta"
class="form-label fw-semibold text-success">
<i class="bi bi-check-circle-fill me-1"></i> <i class="bi bi-check-circle-fill me-1"></i>
Respuesta correcta Respuesta correcta
</label> </label>
<input type="text"
<input
type="text"
id="respuestaCorrecta" id="respuestaCorrecta"
name="respuestaCorrecta" name="respuestaCorrecta"
class="form-control input-kahoot" class="form-control input-kahoot"
placeholder="Escribe la respuesta correcta..." placeholder="Escribe la respuesta correcta..."
required> required>
</div> </div>
<!-- RESPUESTAS INCORRECTAS --> <!-- RESPUESTAS INCORRECTAS -->
<div class="mb-3"> <div class="mb-3">
<label class="form-label fw-semibold text-danger">
<label
class="form-label fw-semibold text-danger">
<i class="bi bi-x-circle-fill me-1"></i> <i class="bi bi-x-circle-fill me-1"></i>
Respuestas incorrectas Respuestas incorrectas
</label> </label>
<input type="text"
<input
type="text"
id="respuestaIncorrecta1" id="respuestaIncorrecta1"
name="respuestaIncorrecta1" name="respuestaIncorrecta1"
class="form-control input-kahoot mb-2" class="form-control input-kahoot mb-2"
placeholder="Respuesta incorrecta 1" placeholder="Respuesta incorrecta 1"
required> required>
<input type="text"
<input
type="text"
id="respuestaIncorrecta2" id="respuestaIncorrecta2"
name="respuestaIncorrecta2" name="respuestaIncorrecta2"
class="form-control input-kahoot mb-2" class="form-control input-kahoot mb-2"
placeholder="Respuesta incorrecta 2" placeholder="Respuesta incorrecta 2"
required> required>
<input type="text"
<input
type="text"
id="respuestaIncorrecta3" id="respuestaIncorrecta3"
name="respuestaIncorrecta3" name="respuestaIncorrecta3"
class="form-control input-kahoot" class="form-control input-kahoot"
placeholder="Respuesta incorrecta 3" placeholder="Respuesta incorrecta 3"
required> required>
</div> </div>
</form> </form>
</div> </div>
<!-- PIE DEL MODAL -->
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
<button
type="button"
class="btn btn-secondary"
data-bs-dismiss="modal">
<i class="bi bi-x-lg me-1"></i> <i class="bi bi-x-lg me-1"></i>
Cancelar Cancelar
</button> </button>
<button type="submit" form="formCrearPregunta" class="btn btn-kahoot-login" id="btnCrearPregunta">
<button
type="submit"
form="formCrearPregunta"
class="btn btn-kahoot-login">
<i class="bi bi-check-lg me-1"></i> <i class="bi bi-check-lg me-1"></i>
Crear pregunta Crear pregunta
</button> </button>
</div> </div>
</div> </div>
@@ -417,16 +296,10 @@
</div> </div>
<!-- Bootstrap JS --> <!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js">
</script>
<!-- Tu JavaScript --> <!-- Tu JavaScript -->
<script src="js/perfil.js"></script> <script src="js/perfil.js"></script>
</body> </body>
+2
View File
@@ -7,6 +7,8 @@
<title>Trivial - Resultado final</title> <title>Trivial - Resultado final</title>
<link rel="icon" type="image/svg+xml" href="img/favicon/favicon.svg">
<link <link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet"> rel="stylesheet">
+6
View File
@@ -0,0 +1,6 @@
bDatosServer="localhost"
bDatos="triviagmatico"
bDatosUser="root"
bDatosPass=""
urlBase="http://triviagmatico.test"
dirBase="C:/laragon/www/triviagmatico"