23 Commits

Author SHA1 Message Date
Isaac 42cc1489e9 Arreglado CSS (Alguien™ estaba usando modo oscuro) 2026-09-29 09:10:30 +02:00
Isaac a694f19667 Funcionalidades del host 2026-09-28 14:17:54 +02:00
jorge 3cc0dfb122 Corregido cambiar avatar en cabecera 2026-09-28 13:29:57 +02:00
jorge 4efb831b7a Reparado inicio y registro de momento 2026-09-28 13:13:05 +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
27 changed files with 2209 additions and 3270 deletions
+62 -98
View File
@@ -4,138 +4,102 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Trivial - Lobby</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet">
<link rel="icon" type="image/svg+xml" href="img/favicon/favicon.svg">
<link 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/buscadorSala.css">
</head>
<body>
<?php
include_once("cabecera.php");
?>
<?php include_once("cabecera.php"); ?>
<main class="container py-5">
<main class="container py-4">
<div 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
<!-- Botón Volver -->
<div class="mb-4">
<a href="index.php" class="btn btn-outline-secondary d-inline-flex align-items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-left" viewBox="0 0 16 16">
<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"/>
</svg>
Volver al Inicio
</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>
</div>
<div
id="contenedorSalas"
class="row justify-content-center g-4">
<!-- Contenedor Principal de Salas -->
<div id="contenedorSalas" 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>
<p class="mt-3 text-muted">Cargando salas...</p>
</div>
</div>
</main>
<div
class="modal fade"
id="modalCrearSala"
tabindex="-1"
aria-labelledby="modalCrearSalaLabel"
aria-hidden="true">
<!-- Modal Crear Sala -->
<div class="modal fade" id="modalCrearSala" tabindex="-1" aria-labelledby="modalCrearSalaLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content modal-kahoot">
<div class="modal-header modal-kahoot-header">
<h5
class="modal-title"
id="modalCrearSalaLabel">
Crear sala
</h5>
<button
type="button"
class="btn-close btn-close-white"
data-bs-dismiss="modal"
aria-label="Cerrar">
</button>
<h5 class="modal-title" id="modalCrearSalaLabel">Crear sala</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Cerrar"></button>
</div>
<div class="modal-body p-4">
<div class="mb-3">
<label
for="nombreSala"
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">
<label for="nombreSala" 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" maxlength="100">
</div>
<div class="mb-3">
<label
for="nombreEquipo1"
class="form-label">
Nombre del equipo 1
</label>
<input
type="text"
id="nombreEquipo1"
name="nombreEquipo1"
class="form-control input-kahoot"
placeholder="Ej. Los cerebritos">
<label for="nombreEquipo1" class="form-label">Nombre del equipo 1</label>
<input type="text" id="nombreEquipo1" name="nombreEquipo1" class="form-control input-kahoot" placeholder="Ej. Los cerebritos" maxlength="50">
</div>
<div class="mb-3">
<label
for="nombreEquipo2"
class="form-label">
Nombre del equipo 2
</label>
<input
type="text"
id="nombreEquipo2"
name="nombreEquipo2"
class="form-control input-kahoot"
placeholder="Ej. Los campeones">
<label for="nombreEquipo2" class="form-label">Nombre del equipo 2</label>
<input type="text" id="nombreEquipo2" name="nombreEquipo2" class="form-control input-kahoot" placeholder="Ej. Los campeones" maxlength="50">
</div>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-secondary"
data-bs-dismiss="modal">
Cancelar
</button>
<button
type="button"
class="btn btn-kahoot-login"
id="btnCrearSala">
Crear sala
</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
<button type="button" class="btn btn-kahoot-login" id="btnCrearSala">Crear sala</button>
</div>
</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" id="modalAbandonarSalaLabel">¿Abandonar la sala?</h4>
<p class="text-dark-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
</button>
<button type="button" id="btnConfirmarAbandonar" class="btn btn-danger px-4 py-2">
Sí, salir
</button>
</div>
</div>
</div>
</div>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js">
</script>
<script src="js/lobbyDummy.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="js/jquery-4.0.0.min.js"></script>
<script src="js/buscadorSala.js"></script>
</body>
</html>
+14 -210
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 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- 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 rel="stylesheet" href="css/index.css">
<script src="js/jquery-4.0.0.min.js"></script>
<style>
</style>
<nav class="navbar navbar-expand-lg navbar-kahoot py-3 mb-4">
<div class="container">
<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>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarContent">
<span class="navbar-toggler-icon"></span>
</button>
@@ -33,44 +21,8 @@ $username = $isLoggedIn ? $_SESSION['nombreUsuario'] : '';
<div class="collapse navbar-collapse" id="navbarContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0"></ul>
<div class="d-flex align-items-center gap-3">
<?php if ($isLoggedIn): ?>
<!-- Menú desplegable cuando la sesión está iniciada -->
<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; ?>
<!-- Contenedor dinámico cargado por js/cabecera.js -->
<div class="d-flex align-items-center gap-3" id="contenedorUsuarioCabecera">
</div>
</div>
</div>
@@ -96,11 +48,6 @@ $username = $isLoggedIn ? $_SESSION['nombreUsuario'] : '';
<input type="password" class="form-control border-dark" id="loginPassword" name="contrasena" placeholder="Contraseña" required>
<label for="loginPassword">Contraseña</label>
</div>
<div class="form-check">
<input class="form-check-input" id="recordar" name="recordar" type="checkbox" />
<label for="recordar" class="small">Recuérdeme durante 10 días</label>
</div>
<input type="hidden" name="orden" value="validar">
</form>
<div id="errorLogin" class="text-danger fw-bold mt-2"></div>
</div>
@@ -140,7 +87,14 @@ $username = $isLoggedIn ? $_SESSION['nombreUsuario'] : '';
<input type="password" class="form-control border-dark" id="regPasswordConfirm" name="contrasenaConfirm" placeholder="Confirmar contraseña" required>
<label for="regPasswordConfirm">Confirmar contraseña</label>
</div>
<input type="hidden" name="orden" value="registrar">
<!-- Checkbox Recuérdame -->
<div class="form-check mb-3">
<input class="form-check-input border-dark" type="checkbox" value="" id="recuerdameCheck">
<label class="form-check-label fw-semibold" for="recuerdameCheck">
Recuérdame en 10 días
</label>
</div>
</form>
<div id="errorRegistro" class="text-danger fw-bold mt-2"></div>
</div>
@@ -152,154 +106,4 @@ $username = $isLoggedIn ? $_SESSION['nombreUsuario'] : '';
</div>
</div>
<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>
<script src="js/cabecera.js"></script>
+38 -33
View File
@@ -2,38 +2,45 @@
require_once __DIR__ . '/../includes/conexionBD.php';
class Equipo{
class Equipo
{
public $idEquipo;
public $nombreEquipo;
function __construct($idEquipo=null, $nombreEquipo=null){
function __construct($idEquipo = null, $nombreEquipo = null)
{
$this->idEquipo = $idEquipo;
$this->nombreEquipo = $nombreEquipo;
}
function crear(){
function crear()
{
$conexion = conexionBD();
if(is_array($conexion)){
if (is_array($conexion)) {
return $conexion;
}else{
try{
$consulta = $conexion->prepare("INSERT INTO equipo (nombreEquipo) VALUES (:nombreEquipo)");
} else {
try {
$consulta = $conexion->prepare(
"INSERT INTO equipo (nombreEquipo) VALUES (:nombreEquipo)"
);
$consulta->bindParam(':nombreEquipo', $this->nombreEquipo);
$consulta->execute();
// Guardamos el ID generado por la BD
$this->idEquipo = (int)$conexion->lastInsertId();
$respuesta = [
'exito' => 'Equipo creado correctamente',
'exito_tecnico' => $this->nombreEquipo
'exito_tecnico' => $this->idEquipo
];
return $respuesta;
}catch(PDOException $error){
} catch (PDOException $error) {
$respuesta = [
'error' => 'Ocurrió un error al guardar el equipo.',
'error_tecnico' => $error->getMessage()
@@ -46,13 +53,15 @@ class Equipo{
}
function listar(){
function listar()
{
$conexion = conexionBD();
if(is_array($conexion)){
if (is_array($conexion)) {
return $conexion;
}else{
try{
} else {
try {
$sql = 'SELECT * FROM equipo';
$consulta = $conexion->prepare($sql);
@@ -61,8 +70,7 @@ class Equipo{
$resultado = $consulta->fetchAll(PDO::FETCH_ASSOC);
return $resultado;
}catch(PDOException $error){
} catch (PDOException $error) {
$respuesta = [
'error' => 'Ocurrió un error al obtener el listado de equipos.',
'error_tecnico' => $error->getMessage()
@@ -75,13 +83,14 @@ class Equipo{
}
function buscar(){
function buscar()
{
$conexion = conexionBD();
if(is_array($conexion)){
if (is_array($conexion)) {
return $conexion;
}else{
try{
} else {
try {
$consulta = $conexion->prepare("SELECT * FROM equipo WHERE idEquipo = :idEquipo");
$consulta->bindParam(':idEquipo', $this->idEquipo);
@@ -91,8 +100,7 @@ class Equipo{
$resultado = $consulta->fetch(PDO::FETCH_ASSOC);
return $resultado;
}catch(PDOException $error){
} catch (PDOException $error) {
$respuesta = [
'error' => 'Ocurrió un error al buscar el equipo.',
'error_tecnico' => $error->getMessage()
@@ -105,25 +113,26 @@ class Equipo{
}
function borrar(){
function borrar()
{
$conexion = conexionBD();
if(is_array($conexion)){
if (is_array($conexion)) {
return $conexion;
}else{
try{
} else {
try {
$consulta = $conexion->prepare("DELETE FROM equipo WHERE idEquipo = :idEquipo");
$consulta->bindParam(':idEquipo', $this->idEquipo);
$consulta->execute();
if($consulta->rowCount() > 0){
if ($consulta->rowCount() > 0) {
$respuesta = [
'exito' => 'Se eliminó correctamente el equipo',
'exito_tecnico' => $this->idEquipo
];
}else{
} else {
$respuesta = [
'error' => 'No existe ningún equipo con ese ID.',
'error_tecnico' => $this->idEquipo
@@ -131,8 +140,7 @@ class Equipo{
}
return $respuesta;
}catch(PDOException $error){
} catch (PDOException $error) {
$respuesta = [
'error' => 'Ocurrió un error al eliminar el equipo.',
'error_tecnico' => $error
@@ -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';
class EquipoxUsuario {
class EquipoxUsuario
{
public $idEquipoxUsuario;
public $idUsuario;
public $idEquipo;
public function __construct($idEquipoxUsuario = null, $idUsuario = null, $idEquipo = null) {
public function __construct($idEquipoxUsuario = null, $idUsuario = null, $idEquipo = null)
{
$this->idEquipoxUsuario = $idEquipoxUsuario;
$this->idUsuario = $idUsuario;
$this->idEquipo = $idEquipo;
}
public function registrarUsuarioEnEquipo() {
public function registrarUsuarioEnEquipo()
{
$conexion = conexionBD();
if (is_array($conexion)) return $conexion;
@@ -36,7 +39,8 @@ class EquipoxUsuario {
}
}
public static function listarUsuariosPorEquipo($idEquipo) {
public static function listarUsuariosPorEquipo($idEquipo)
{
$conexion = conexionBD();
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()
];
}
}
}
+54 -37
View File
@@ -169,7 +169,7 @@ class Partida
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al recuperar las preguntas de la partida.",
'error_tecnico' => $error->getMessage()
'error_tecnico' => $error->getMessage()
];
}
}
@@ -332,17 +332,18 @@ class Partida
];
}
}
/**
/**
* Vincula un equipo a esta partida en la tabla intermedia 'equipoxpartida'.
* 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
if (is_array($conexion)) {
return $conexion; // Si hay error en la conexión, lo devuelve
}
try {
// Preparamos la consulta para insertar la relación en la tabla intermedia real
$consulta = $conexion->prepare("
@@ -351,12 +352,12 @@ class Partida
VALUES
(:idPartida, :idEquipo)
");
// Vinculamos los parámetros con el objeto de la partida actual y el equipo recibido
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->bindParam(":idEquipo", $idEquipo);
$consulta->execute();
return [
"exito" => "El equipo se vinculó a la partida correctamente.",
"exito_tecnico" => $conexion->lastInsertId()
@@ -374,13 +375,14 @@ class 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.
*/
public function getEquiposParticipantes() {
public function getEquiposParticipantes()
{
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
// Hacemos un INNER JOIN para traer los nombres de los equipos desde la tabla intermedia
$consulta = $conexion->prepare("
@@ -394,10 +396,10 @@ class Partida
WHERE exp.idPartida = :idPartida
ORDER BY e.nombreEquipo ASC
");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->execute();
return $consulta->fetchAll(PDO::FETCH_ASSOC); // Devuelve el array con los equipos rivales
} catch (PDOException $error) {
return [
@@ -411,42 +413,57 @@ class Partida
* Obtiene todos los jugadores reales (Usuarios) que están jugando en esta partida.
* Utiliza la tabla 'equipoxusuario' en SQL para cruzar los datos.
*/
public function getJugadoresDeLaPartida() {
public function getJugadoresDeLaPartida()
{
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
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("
SELECT DISTINCT
u.idUsuario,
u.nombreUsuario,
u.email,
e.nombreEquipo
FROM equipoxpartida exp
INNER JOIN equipoxusuario exu
ON exp.idEquipo = exu.idEquipo
INNER JOIN usuario u
ON exu.idUsuario = u.idUsuario
INNER JOIN equipo e
ON exu.idEquipo = e.idEquipo
WHERE exp.idPartida = :idPartida
");
$consulta->bindParam(":idPartida", $this->idPartida);
SELECT DISTINCT
u.idUsuario,
u.nombreUsuario,
u.email,
e.idEquipo,
e.nombreEquipo
FROM equipoxpartida exp
INNER JOIN equipoxusuario exu
ON exp.idEquipo = exu.idEquipo
INNER JOIN usuario u
ON exu.idUsuario = u.idUsuario
INNER JOIN equipo e
ON exu.idEquipo = e.idEquipo
WHERE exp.idPartida = :idPartida
ORDER BY e.nombreEquipo ASC,
u.nombreUsuario ASC
");
$consulta->bindParam(
":idPartida",
$this->idPartida
);
$consulta->execute();
return $consulta->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al obtener la lista de jugadores.",
"error_tecnico" => $error->getMessage()
"error" =>
"Ocurrió un error al obtener la lista de jugadores.",
"error_tecnico" =>
$error->getMessage()
];
}
}
}
+247 -44
View File
@@ -1,7 +1,8 @@
<?php
require_once __DIR__ . '/../includes/conexionBD.php';
class Usuario {
class Usuario
{
private ?int $idUsuario;
private string $nombreUsuario;
private string $contrasena;
@@ -13,14 +14,14 @@ class Usuario {
private int $derrotas;
public function __construct(
string $nombreUsuario = "",
string $contrasena = "",
string $email = "",
?string $avatar = null,
?string $cookie = null,
int $aciertos = 0,
int $victorias = 0,
int $derrotas = 0,
string $nombreUsuario = "",
string $contrasena = "",
string $email = "",
?string $avatar = null,
?string $cookie = null,
int $aciertos = 0,
int $victorias = 0,
int $derrotas = 0,
?int $idUsuario = null
) {
$this->idUsuario = $idUsuario;
@@ -34,33 +35,85 @@ class Usuario {
$this->derrotas = $derrotas;
}
public function getIdUsuario(): ?int { return $this->idUsuario; }
public function getNombreUsuario(): string { return $this->nombreUsuario; }
public function setNombreUsuario(string $nombreUsuario): void { $this->nombreUsuario = $nombreUsuario; }
public function getIdUsuario(): ?int
{
return $this->idUsuario;
}
public function getContrasena(): string { return $this->contrasena; }
public function setContrasena(string $contrasena): void { $this->contrasena = $contrasena; }
public function getNombreUsuario(): string
{
return $this->nombreUsuario;
}
public function setNombreUsuario(string $nombreUsuario): void
{
$this->nombreUsuario = $nombreUsuario;
}
public function getEmail(): string { return $this->email; }
public function setEmail(string $email): void { $this->email = $email; }
public function getContrasena(): string
{
return $this->contrasena;
}
public function setContrasena(string $contrasena): void
{
$this->contrasena = $contrasena;
}
public function getAvatar(): ?string { return $this->avatar; }
public function setAvatar(?string $avatar): void { $this->avatar = $avatar; }
public function getEmail(): string
{
return $this->email;
}
public function setEmail(string $email): void
{
$this->email = $email;
}
public function getCookie(): ?string { return $this->cookie; }
public function setCookie(?string $cookie): void { $this->cookie = $cookie; }
public function getAvatar(): ?string
{
return $this->avatar;
}
public function setAvatar(?string $avatar): void
{
$this->avatar = $avatar;
}
public function getAciertos(): int { return $this->aciertos; }
public function setAciertos(int $aciertos): void { $this->aciertos = $aciertos; }
public function getCookie(): ?string
{
return $this->cookie;
}
public function setCookie(?string $cookie): void
{
$this->cookie = $cookie;
}
public function getVictorias(): int { return $this->victorias; }
public function setVictorias(int $victorias): void { $this->victorias = $victorias; }
public function getAciertos(): int
{
return $this->aciertos;
}
public function setAciertos(int $aciertos): void
{
$this->aciertos = $aciertos;
}
public function getDerrotas(): int { return $this->derrotas; }
public function setDerrotas(int $derrotas): void { $this->derrotas = $derrotas; }
public function getVictorias(): int
{
return $this->victorias;
}
public function setVictorias(int $victorias): void
{
$this->victorias = $victorias;
}
public function registrar() {
public function getDerrotas(): int
{
return $this->derrotas;
}
public function setDerrotas(int $derrotas): void
{
$this->derrotas = $derrotas;
}
public function registrar()
{
$conexion = conexionBD();
if (is_array($conexion)) {
@@ -71,7 +124,7 @@ class Usuario {
$sql = "INSERT INTO usuario (nombreUsuario, contrasena, email, avatar, cookie, aciertos, victorias, derrotas)
VALUES (:nombre, :pass, :email, :avatar, :cookie, :aciertos, :victorias, :derrotas)";
$stmt = $conexion->prepare($sql);
$passHash = password_hash($this->contrasena, PASSWORD_BCRYPT);
$stmt->execute([
@@ -91,7 +144,6 @@ class Usuario {
'exito' => 'Usuario registrado correctamente',
'exito_tecnico' => $this->idUsuario
];
} catch (PDOException $error) {
return [
'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();
if (is_array($conexion)) {
@@ -111,27 +164,26 @@ class Usuario {
$sql = "SELECT * FROM usuario WHERE idUsuario = :id";
$stmt = $conexion->prepare($sql);
$stmt->execute([':id' => $id]);
$datos = $stmt->fetch(PDO::FETCH_ASSOC);
if ($datos) {
return new Usuario(
$datos['nombreUsuario'],
$datos['contrasena'],
$datos['email'],
$datos['avatar'],
$datos['cookie'],
(int)$datos['aciertos'],
(int)$datos['victorias'],
(int)$datos['derrotas'],
$datos['nombreUsuario'],
$datos['contrasena'],
$datos['email'],
$datos['avatar'],
$datos['cookie'],
(int)$datos['aciertos'],
(int)$datos['victorias'],
(int)$datos['derrotas'],
(int)$datos['idUsuario']
);
}
return [
'error' => 'No se encontró ningún usuario con ese ID.'
];
} catch (PDOException $error) {
return [
'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();
if (is_array($conexion)) {
@@ -189,6 +242,7 @@ class Usuario {
unset($_SESSION['idUsuario']);
unset($_SESSION['email']);
unset($_SESSION['nombreUsuario']);
unset($_SESSION['avatar']);
return null;
}
@@ -200,6 +254,7 @@ class Usuario {
$_SESSION['idUsuario'] = $usuario->getIdUsuario();
$_SESSION['email'] = $usuario->getEmail();
$_SESSION['nombreUsuario'] = $usuario->getNombreUsuario();
$_SESSION['avatar'] = $usuario->getAvatar();
// Devolvemos el usuario como hasta ahora
return $usuario;
@@ -209,8 +264,156 @@ class Usuario {
unset($_SESSION['idUsuario']);
unset($_SESSION['email']);
unset($_SESSION['nombreUsuario']);
unset($_SESSION['avatar']);
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 [];
}
}
}
+52 -9
View File
@@ -4,29 +4,42 @@ session_start();
require_once '../clases/ClaseEquipoxUsuario.php';
switch($_POST['orden']){
switch ($_POST['orden']) {
case 'registrarUsuarioEnEquipo':
if (!isset($_SESSION['idUsuario'])) {
echo json_encode([
'error' => 'No hay una sesión activa de usuario. Por favor, inicie sesión.'
]);
break;
}
$idUsuario = $_SESSION['idUsuario'];
$idEquipo = intval($_POST['idEquipo'] ?? 0);
break;
if ($idEquipo <= 0) {
echo json_encode([
'error' => 'El ID del equipo proporcionado no es válido.'
]);
break;
}
$equipoxusuario = new EquipoxUsuario();
$resultado = $equipoxusuario->registrarUsuarioEnEquipo($idEquipo, $idUsuario);
$equipoxusuario = new EquipoxUsuario(
null,
$idUsuario,
$idEquipo
);
$resultado = $equipoxusuario->registrarUsuarioEnEquipo();
echo json_encode($resultado);
break;
case 'listarUsuariosPorEquipo':
$idEquipo = intval($_POST['idEquipo'] ?? 0);
@@ -36,12 +49,42 @@ switch($_POST['orden']){
}
$equipoxusuario = new EquipoxUsuario();
$listado = $equipoxusuario->listarUsuariosPorEquipo($idEquipo);
break;
//break;
echo json_encode($listado);
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;
}
?>
+224 -100
View File
@@ -3,11 +3,9 @@
session_start();
require_once '../clases/ClasePartida.php';
require_once '../clases/ClaseEquipo.php';
require_once '../clases/ClaseEquipoxUsuario.php';
require_once '../clases/ClaseEquipoxPartida.php';
switch ($_POST['orden']) {
@@ -22,7 +20,7 @@ switch ($_POST['orden']) {
echo json_encode($listadoPartidas);
break;
break;
@@ -46,15 +44,14 @@ switch ($_POST['orden']) {
echo json_encode($resultado);
break;
break;
case 'crear':
//Comprobamos que haya un usuario conectado
// Comprobamos que haya un usuario conectado
if (!isset($_SESSION['idUsuario'])) {
@@ -66,9 +63,7 @@ switch ($_POST['orden']) {
}
//Comprobamos que se haya introducido un nombre
// Comprobamos el nombre de la partida
if (
!isset($_POST['nombrePartida']) ||
@@ -83,29 +78,158 @@ switch ($_POST['orden']) {
}
//Creamos la partida
// 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;
}
/*
* ==========================================
* 1. CREAMOS LA PARTIDA
* ==========================================
*/
$partida = new Partida();
$partida->nombrePartida = trim($_POST['nombrePartida']);
//El usuario conectado será el propietario de la partida.
// El usuario conectado será el propietario
$partida->idUsuario = $_SESSION['idUsuario'];
$resultado = $partida->insertar();
echo json_encode($resultado);
break;
$resultadoPartida = $partida->insertar();
if (isset($resultadoPartida['error'])) {
echo json_encode($resultadoPartida);
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;
case 'editar':
@@ -127,7 +251,7 @@ switch ($_POST['orden']) {
//Comprobamos los datos
if (
!isset($_POST['idPartida']) ||
@@ -149,9 +273,9 @@ switch ($_POST['orden']) {
$partida->nombrePartida = trim($_POST['nombrePartida']);
//Buscamos la partida
$datosPartida = $partida->buscar();
@@ -166,9 +290,9 @@ switch ($_POST['orden']) {
}
//Comprobamos que el usuario sea el propietario
if (
$datosPartida['idUsuario'] !=
@@ -189,7 +313,7 @@ switch ($_POST['orden']) {
echo json_encode($resultado);
break;
break;
@@ -221,9 +345,9 @@ switch ($_POST['orden']) {
$partida->idPartida = intval($_POST['idPartida']);
//Buscamos la partida
$datosPartida = $partida->buscar();
@@ -238,9 +362,9 @@ switch ($_POST['orden']) {
}
//Solo el propietario puede eliminarla
if (
$datosPartida['idUsuario'] !=
@@ -259,7 +383,7 @@ switch ($_POST['orden']) {
echo json_encode($resultado);
break;
break;
@@ -284,7 +408,7 @@ switch ($_POST['orden']) {
echo json_encode($resultado);
break;
break;
@@ -309,12 +433,12 @@ switch ($_POST['orden']) {
echo json_encode($resultado);
break;
break;
// ASIGNAR UNA PREGUNTA A UNA PARTIDA
case 'asignarPregunta':
@@ -338,9 +462,9 @@ switch ($_POST['orden']) {
$idPregunta = intval($_POST['idPregunta']);
//Comprobamos que no esté ya asignada
if ($partida->preguntaAsignada($idPregunta)) {
@@ -358,12 +482,12 @@ switch ($_POST['orden']) {
echo json_encode($resultado);
break;
break;
// COMPROBAR SI UNA PREGUNTA ESTÁ ASIGNADA
case 'preguntaAsignada':
if (
@@ -395,12 +519,12 @@ switch ($_POST['orden']) {
'asignada' => $resultado
]);
break;
break;
// CONTAR PREGUNTAS DE UNA PARTIDA
case 'contarPreguntas':
@@ -428,12 +552,12 @@ switch ($_POST['orden']) {
'totalPreguntas' => $resultado
]);
break;
break;
// REGISTRAR EQUIPO EN UNA PARTIDA
case 'registrarEquipo':
@@ -464,12 +588,12 @@ switch ($_POST['orden']) {
echo json_encode($resultado);
break;
break;
// OBTENER EQUIPOS DE UNA PARTIDA
case 'getEquipos':
@@ -495,12 +619,12 @@ switch ($_POST['orden']) {
echo json_encode($resultado);
break;
break;
// OBTENER JUGADORES DE UNA PARTIDA
case 'getJugadores':
@@ -526,10 +650,10 @@ switch ($_POST['orden']) {
echo json_encode($resultado);
break;
break;
case 'iniciar':
@@ -549,9 +673,9 @@ switch ($_POST['orden']) {
}
//Comprobamos que se haya indicado la partida
if (!isset($_POST['idPartida'])) {
@@ -569,9 +693,9 @@ switch ($_POST['orden']) {
intval($_POST['idPartida']);
//Buscamos la partida
$datosPartida = $partida->buscar();
@@ -586,9 +710,9 @@ switch ($_POST['orden']) {
}
//Solo el creador puede iniciar la partida
if (
$datosPartida['idUsuario'] !=
@@ -604,9 +728,9 @@ switch ($_POST['orden']) {
}
//Comprobamos que haya preguntas
$numeroPreguntas =
$partida->contarPreguntasAsignadas();
@@ -638,12 +762,12 @@ switch ($_POST['orden']) {
echo json_encode($resultado);
break;
break;
// OBTENER LA PREGUNTA ACTUAL
case 'getPreguntaActual':
if (!isset($_POST['idPartida'])) {
@@ -662,20 +786,20 @@ switch ($_POST['orden']) {
intval($_POST['idPartida']);
//Obtenemos la pregunta actual
$resultado =
$partida->getPreguntaActual();
echo json_encode($resultado);
break;
break;
case 'siguientePregunta':
@@ -705,9 +829,9 @@ switch ($_POST['orden']) {
intval($_POST['idPartida']);
//Comprobamos que el usuario sea el creador
$datosPartida = $partida->buscar();
@@ -735,9 +859,9 @@ switch ($_POST['orden']) {
}
//Pasamos a la siguiente pregunta
$resultado =
$partida->siguientePregunta();
@@ -745,12 +869,12 @@ switch ($_POST['orden']) {
echo json_encode($resultado);
break;
break;
// REGISTRAR RESPUESTA
case 'responder':
@@ -791,9 +915,9 @@ switch ($_POST['orden']) {
intval($_POST['idRespuesta']);
//Registramos la respuesta del usuario
$resultado =
$partida->registrarRespuesta(
@@ -805,12 +929,12 @@ switch ($_POST['orden']) {
echo json_encode($resultado);
break;
break;
// COMPROBAR SI LA PARTIDA HA TERMINADO PARA EL USUARIO
case 'estaFinalizada':
@@ -850,12 +974,12 @@ switch ($_POST['orden']) {
'finalizada' => $resultado
]);
break;
break;
// CONTAR RESPUESTAS DEL USUARIO
case 'contarRespuestas':
@@ -895,10 +1019,10 @@ switch ($_POST['orden']) {
'totalRespondidas' => $resultado
]);
break;
break;
case 'finalizar':
@@ -928,9 +1052,9 @@ switch ($_POST['orden']) {
intval($_POST['idPartida']);
//Buscamos la partida
$datosPartida = $partida->buscar();
@@ -944,7 +1068,7 @@ switch ($_POST['orden']) {
}
//Solo el creador puede finalizarla
if (
@@ -961,7 +1085,7 @@ switch ($_POST['orden']) {
}
$resultado =
$partida->finalizar();
@@ -969,10 +1093,10 @@ switch ($_POST['orden']) {
echo json_encode($resultado);
break;
break;
default:
@@ -980,7 +1104,7 @@ switch ($_POST['orden']) {
'error' => 'La orden indicada no existe.'
]);
break;
break;
}
?>
+106 -6
View File
@@ -3,6 +3,7 @@
session_start();
require_once '../clases/ClasePregunta.php';
require_once '../clases/ClaseRespuesta.php';
switch ($_POST['orden']) {
@@ -11,18 +12,118 @@ switch ($_POST['orden']) {
$idCategoria = intval($_POST['idCategoria'] ?? 0);
$nombrePregunta = trim($_POST['nombrePregunta'] ?? '');
if ($idCategoria <= 0 || $nombrePregunta == '') {
echo json_encode(['error' => 'La categoría y el texto de la pregunta son obligatorios']);
$respuestaCorrecta = trim($_POST['respuestaCorrecta'] ?? '');
$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;
}
$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;
}
// 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':
$idCategoria = intval($_POST['idCategoria'] ?? 0);
@@ -49,5 +150,4 @@ switch ($_POST['orden']) {
echo json_encode($listado);
break;
}
+148 -4
View File
@@ -35,7 +35,8 @@ switch ($_POST['orden']) {
$usuario = new Usuario(
$nombreUsuario,
$contrasena,
$email
$email,
'img/avatars/defaultProfile.jpeg'
);
$resultado = $usuario->registrar();
@@ -46,7 +47,7 @@ switch ($_POST['orden']) {
case 'comprobarUsuario':
$email = trim($_POST['email'] ?? '');
$contrasena = $_POST['contrasena'] ?? '';
@@ -54,6 +55,13 @@ switch ($_POST['orden']) {
if ($resultado instanceof Usuario) {
// === GUARDAR EN SESIÓN (incluido avatar)===
$_SESSION['idUsuario'] = $resultado->getIdUsuario();
$_SESSION['nombreUsuario'] = $resultado->getNombreUsuario();
$_SESSION['email'] = $resultado->getEmail();
$_SESSION['avatar'] = $resultado->getAvatar();
// =================================================
echo json_encode([
'exito' => 'Login correcto',
'idUsuario' => $resultado->getIdUsuario(),
@@ -76,6 +84,7 @@ switch ($_POST['orden']) {
unset($_SESSION['idUsuario']);
unset($_SESSION['email']);
unset($_SESSION['nombreUsuario']);
unset($_SESSION['avatar']);
// Destruimos la sesión
session_destroy();
@@ -85,7 +94,6 @@ switch ($_POST['orden']) {
]);
break;
case 'mostrarEstadisticas':
$usuario = Usuario::buscarPorId($_SESSION['idUsuario']);
@@ -97,7 +105,6 @@ switch ($_POST['orden']) {
'derrotas' => $usuario->getDerrotas(),
'aciertos' => $usuario->getAciertos()
]);
} else {
echo json_encode($usuario);
@@ -105,6 +112,143 @@ switch ($_POST['orden']) {
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'] ?? '',
'avatar' => $_SESSION['avatar'] ?? ''
]
]);
} else {
echo json_encode(['activa' => false]);
}
break;
}
+10 -2
View File
@@ -68,8 +68,8 @@
.btn-unirse {
border: none;
border-bottom: 3px solid #0c4891;
background-color: var(--kahoot-blue);
border-bottom: 3px solid #1f6f09;
background-color: #26890c;
color: white;
font-weight: 600;
border-radius: 8px;
@@ -105,3 +105,11 @@
border-color: var(--kahoot-purple);
box-shadow: 0 0 0 3px rgba(70, 23, 143, 0.15);
}
.jugador-host {
background-color: #fff3cd;
border: 1px solid #ffc107;
border-radius: 8px;
padding: 6px 10px;
font-weight: 600;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

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

+33 -35
View File
@@ -1,53 +1,51 @@
<?php
include 'cabecera.php';
?>
<!DOCTYPE html>
<html lang="es-ES">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<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>
<body>
<div class="container my-5">
<div class="row justify-content-center align-items-center g-4">
<!-- Botón Jugar (solo se muestra si está logueado) -->
<?php if ($isLoggedIn): ?>
<div class="col-12 col-lg-5 col-xl-4">
<a href="buscadorSala.php" class="btn btn-play-kahoot" id="btnJugar">
<i class="fa-solid fa-play"></i>
<span>¡JUGAR!</span>
</a>
</div>
<?php endif; ?>
<?php include 'cabecera.php'; ?>
<!-- Ranking -->
<div class="col-12 <?= $isLoggedIn ? 'col-lg-7 col-xl-8' : 'col-lg-8' ?>">
<div class="card ranking-card">
<div class="ranking-header">
<h3 class="m-0"><i class="fa-solid fa-trophy me-2"></i> RANKING GLOBAL DE JUGADORES</h3>
</div>
<div class="card-body">
<!-- Div datos de ranking -->
<div id="ranking-container" class="ranking-placeholder text-center p-4">
<i class="fa-solid fa-medal trophy-icon"></i>
<h4 class="fw-bold text-secondary">Cargando clasificación...</h4>
<p class="text-muted mb-0">Los mejores equipos y jugadores aparecerán aquí pronto.</p>
<div class="container my-5">
<div class="row justify-content-center align-items-center g-4">
<!-- Botón Jugar (oculto por defecto, JS lo muestra si hay sesión activa) -->
<div class="col-12 col-lg-5 col-xl-4 d-none" id="colBotonJugar">
<a href="buscadorSala.php" class="btn btn-play-kahoot" id="btnJugar">
<i class="fa-solid fa-play"></i>
<span>¡JUGAR!</span>
</a>
</div>
<!-- Ranking -->
<div class="col-12 col-lg-8" id="colRanking">
<div class="card ranking-card">
<div class="ranking-header">
<h3 class="m-0"><i class="fa-solid fa-trophy me-2"></i> RANKING GLOBAL DE JUGADORES</h3>
</div>
<div class="card-body">
<!-- Div datos de ranking -->
<div id="ranking-container" class="ranking-placeholder text-center p-4">
<i class="fa-solid fa-medal trophy-icon"></i>
<h4 class="fw-bold text-secondary">Cargando clasificación...</h4>
<p class="text-muted mb-0">Los mejores equipos y jugadores aparecerán aquí pronto.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- JS de Bootstrap -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<!-- JS de Bootstrap -->
<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>
</html>
+405 -73
View File
@@ -1,79 +1,411 @@
const btnCrearSala = document.getElementById("btnCrearSala");
let usuarioYaEstaEnEquipo = false;
const nombreSala = document.getElementById("nombreSala");
const nombreEquipo1 = document.getElementById("nombreEquipo1");
const nombreEquipo2 = document.getElementById("nombreEquipo2");
btnCrearSala.addEventListener("click", function () {
limpiarErrores();
const sala = nombreSala.value.trim();
const equipo1 = nombreEquipo1.value.trim();
const equipo2 = nombreEquipo2.value.trim();
let formularioValido = true;
if (sala === "") {
mostrarError(nombreSala, "El nombre de la sala es obligatorio.");
formularioValido = false;
}
if (equipo1 === "") {
mostrarError(nombreEquipo1, "El nombre del equipo 1 es obligatorio.");
formularioValido = false;
}
if (equipo2 === "") {
mostrarError(nombreEquipo2, "El nombre del equipo 2 es obligatorio.");
formularioValido = false;
}
if (!formularioValido) {
return;
}
console.log("Sala:", sala);
console.log("Equipo 1:", equipo1);
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;
$(document).ready(function () {
comprobarSalaUsuario();
});
function mostrarError(input, mensaje) {
input.classList.add("is-invalid");
// 1. Comprobar si el usuario actual ya pertenece a una sala
function comprobarSalaUsuario() {
$("#cargandoSalas").remove();
// 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();
}
$.ajax({
url: "controladores/ControladorEquipoxUsuario.php",
type: "POST",
dataType: "json",
data: { orden: "obtenerSalaUsuario" },
success: function (respuesta) {
if (respuesta.error || !respuesta.asociado) {
usuarioYaEstaEnEquipo = false;
$("#contenedorCrearSala").show();
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();
},
});
}
// 2. Cargar únicamente la sala en la que está metido el usuario
function cargarSalaUsuario(idPartida) {
$.ajax({
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);
},
});
}
// 3. Cargar la lista completa de todas las salas
function cargarSalas() {
$.ajax({
url: "controladores/controladorPartida.php",
type: "POST",
dataType: "json",
data: { orden: "listar" },
success: function (partidas) {
const contenedor = $("#contenedorSalas");
contenedor.empty();
if (!Array.isArray(partidas) || partidas.length === 0) {
contenedor.html(`
<div class="col-12 text-center">
<p class="text-muted">No hay salas disponibles actualmente.</p>
</div>
`);
return;
}
partidas.forEach(function (partida) {
cargarInformacionSala(partida);
});
},
error: function (xhr, status, error) {
console.error("Error al obtener las partidas:", error);
},
});
}
// 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) {
const esHost = jugador.idUsuario == partida.idUsuario;
jugadoresHTML += `
<div class="jugador border border-2 d-flex align-items-center justify-content-between ${
esHost ? "jugador-host" : ""
}">
<div>
<span class="avatar">${esHost ? "👑" : "👤"}</span>
${escapeHTML(jugador.nombreUsuario)}
</div>
${
esHost
? `<span class="badge bg-warning text-dark ms-2">HOST</span>`
: ""
}
</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-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
// Acciones disponibles si el usuario YA ESTÁ dentro de esta sala
let accionesSalaHTML = "";
if (usuarioYaEstaEnEquipo) {
let botonIniciarHTML = "";
// Solo el host puede iniciar la partida
if (partida.idUsuario == idUsuarioSesion) {
botonIniciarHTML = `
<a href="juego.php?idPartida=${partida.idPartida}"
class="btn btn-success btn-lg px-4">
🎮 ¡Iniciar Partida!
</a>
`;
}
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>
${botonIniciarHTML}
</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 text-white">
${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();
});
+217
View File
@@ -0,0 +1,217 @@
let idUsuarioSesion = null;
$(document).ready(function () {
// Comprobar la sesión activa al cargar la página
comprobarEstadoSesion();
// Evento Click: Login
$('#botonAceptarLogin').on('click', function () {
ejecutarLogin();
});
// Permitir Submit con tecla Enter en el formulario de Login
$('#formLogin').on('submit', function (e) {
e.preventDefault();
ejecutarLogin();
});
// Evento Click: Registro
$('#botonAceptarRegistro').on('click', function () {
ejecutarRegistro();
});
// Permitir Submit con tecla Enter en el formulario de Registro
$('#formRegistro').on('submit', function (e) {
e.preventDefault();
ejecutarRegistro();
});
});
/**
* Comprueba con el servidor si existe una sesión PHP
*/
function comprobarEstadoSesion() {
$.ajax({
url: 'controladores/controladorUsuario.php',
type: 'POST',
dataType: 'json',
data: { orden: 'comprobarSesion' },
success: function (respuesta) {
if (respuesta.activa) {
idUsuarioSesion = respuesta.usuario.idUsuario;
renderizarCabeceraConSesion(respuesta.usuario);
$('#colBotonJugar').removeClass('d-none');
} else {
renderizarCabeceraSinSesion();
$('#colBotonJugar').addClass('d-none');
}
},
error: function () {
renderizarCabeceraSinSesion();
}
});
}
/**
* Petición AJAX para iniciar sesión
*/
function ejecutarLogin() {
let email = $('#loginEmail').val().trim();
let contrasena = $('#loginPassword').val().trim();
$('#errorLogin').text('');
if (email === '' || contrasena === '') {
$('#errorLogin').text('Por favor, rellena todos los campos.');
return;
}
$.ajax({
url: 'controladores/controladorUsuario.php',
type: 'POST',
dataType: 'json',
data: {
orden: 'comprobarUsuario',
email: email,
contrasena: contrasena
},
success: function (respuesta) {
if (respuesta.error) {
$('#errorLogin').text(respuesta.error);
} else if (respuesta.exito) {
$('#modalLogin').modal('hide');
$('#formLogin')[0].reset();
// Cargar datos de la sesión actualizados
comprobarEstadoSesion();
}
},
error: function () {
$('#errorLogin').text('Error al conectar con el servidor.');
}
});
}
/**
* Petición AJAX para registrar un usuario
*/
function ejecutarRegistro() {
let nombre = $('#regNombre').val().trim();
let email = $('#regEmail').val().trim();
let pass = $('#regPassword').val().trim();
let passConfirm = $('#regPasswordConfirm').val().trim();
$('#errorRegistro').text('');
if (nombre === '' || email === '' || pass === '') {
$('#errorRegistro').text('Todos los campos son obligatorios.');
return;
}
if (pass !== passConfirm) {
$('#errorRegistro').text('Las contraseñas no coinciden.');
return;
}
$.ajax({
url: 'controladores/controladorUsuario.php',
type: 'POST',
dataType: 'json',
data: {
orden: 'registrarUsuario',
nombreUsuario: nombre,
email: email,
contrasena: pass
},
success: function (respuesta) {
if (respuesta.error) {
$('#errorRegistro').text(respuesta.error);
} else {
$('#modalRegistro').modal('hide');
$('#formRegistro')[0].reset();
// Autologin tras registrarse
$('#loginEmail').val(email);
$('#loginPassword').val(pass);
ejecutarLogin();
}
},
error: function () {
$('#errorRegistro').text('Error al procesar el registro.');
}
});
}
/**
* Petición AJAX para cerrar la sesión
*/
function cerrarSesion() {
$.ajax({
url: 'controladores/controladorUsuario.php',
type: 'POST',
dataType: 'json',
data: { orden: 'cerrarSesion' },
success: function () {
renderizarCabeceraSinSesion();
$('#colBotonJugar').addClass('d-none');
if (window.location.pathname.includes('perfil.php') || window.location.pathname.includes('buscadorSala.php')) {
window.location.href = 'index.php';
}
}
});
}
/**
* Renderiza la cabecera cuando HAY sesión iniciada
*/
function renderizarCabeceraConSesion(usuario) {
//Mete el avatar en cabecera
let avatarImg = (usuario.avatar && usuario.avatar !== '')
? usuario.avatar
: 'img/avatars/defaultProfile.jpeg';
// Refrescar avatar si se cambia
let avatarConCacheBuster = avatarImg + '?v=' + new Date().getTime();
let html = `
<div class="dropdown">
<button class="btn btn-outline-light dropdown-toggle d-flex align-items-center gap-2 rounded-pill px-3 py-1 fw-bold" type="button" id="userMenu" data-bs-toggle="dropdown" aria-expanded="false">
<img src="${avatarConCacheBuster}" alt="Avatar" class="rounded-circle border" style="width: 32px; height: 32px; object-fit: cover;">
<span>${escapeHtml(usuario.nombreUsuario)}</span>
</button>
<ul class="dropdown-menu dropdown-menu-end shadow border-0 mt-2" aria-labelledby="userMenu">
<li>
<a class="dropdown-item py-2 fw-semibold" href="perfil.php">
<i class="fa-solid fa-user me-2 text-primary"></i>Mi Perfil
</a>
</li>
<li><hr class="dropdown-divider"></li>
<li>
<button class="dropdown-item py-2 fw-semibold text-danger" onclick="cerrarSesion()">
<i class="fa-solid fa-right-from-bracket me-2"></i>Cerrar Sesión
</button>
</li>
</ul>
</div>
`;
$('#contenedorUsuarioCabecera').html(html);
}
/**
* Renderiza los botones en la cabecera cuando NO hay sesión (Iniciar sesión azul)
*/
function renderizarCabeceraSinSesion() {
let html = `
<button class="btn btn-primary rounded-pill px-4 fw-bold shadow-sm" data-bs-toggle="modal" data-bs-target="#modalLogin">
<i class="fa-solid fa-right-to-bracket me-1"></i> Iniciar sesión
</button>
<button class="btn btn-success rounded-pill px-4 fw-bold shadow-sm" data-bs-toggle="modal" data-bs-target="#modalRegistro">
<i class="fa-solid fa-user-plus me-1"></i> Registrarse
</button>
`;
$('#contenedorUsuarioCabecera').html(html);
}
function escapeHtml(texto) {
return $('<div>').text(texto).html();
}
+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();
}
+217 -45
View File
@@ -1,74 +1,246 @@
// =========================
// 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
// =========================
function cambiarNombre() {
let nuevoNombre = $("#nuevoNombre").val().trim();
const input = document.getElementById("nuevoNombre");
const nombre = document.getElementById("nombre");
if (nuevoNombre === "") {
return;
}
const nuevoNombre = input.value.trim();
$.ajax({
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);
if (nuevoNombre !== "") {
$("#nuevoNombre").val("");
nombre.textContent = nuevoNombre;
input.value = "";
if (typeof comprobarEstadoSesion === "function") {
comprobarEstadoSesion();
}
}
});
}
// =========================
// BORRAR NOMBRE
// =========================
function borrarNombre() {
document.getElementById("nuevoNombre").value = "";
document.getElementById("nuevoNombre").value = "";
}
// =========================
// ABRIR SELECTOR DE IMAGEN
// =========================
function seleccionarFoto() {
document.getElementById("inputFoto").click();
}
// =========================
// CAMBIAR FOTO
// =========================
document.getElementById("inputFoto").addEventListener(
"change",
function(event) {
function seleccionarFoto() {
$("#inputFoto").click();
}
const archivo = event.target.files[0];
$("#inputFoto").change(function () {
let archivo = this.files[0];
if (archivo) {
if (!archivo) {
return;
}
// Comprobamos que sea una imagen
if (!archivo.type.startsWith("image/")) {
// Comprobamos que sea una imagen
if (!archivo.type.startsWith("image/")) {
alert("El archivo seleccionado no es una imagen.");
$("#inputFoto").val("");
return;
}
alert("Por favor, selecciona una imagen.");
let datos = new FormData();
datos.append("avatar", archivo);
datos.append("orden", "cambiarAvatar");
return;
}
// Creamos una URL temporal
const imagenURL = URL.createObjectURL(archivo);
// Cambiamos la foto
document.getElementById("fotoPerfil").src = imagenURL;
}
$.ajax({
method: "POST",
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 en la página de perfil sin recargar
$("#fotoPerfil").attr(
"src",
respuesta.avatar + "?t=" + new Date().getTime()
);
// Actualizamos también el avatar superior en la cabecera
if (typeof comprobarEstadoSesion === "function") {
comprobarEstadoSesion();
}
}
);
});
});
// =========================
// 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");
}
},
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">
<title>Proyecto Trivial</title>
<link rel="stylesheet" href="css/juego.css">
<link rel="icon" type="image/svg+xml" href="img/favicon/favicon.svg">
</head>
<body>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

+110 -264
View File
@@ -1,158 +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>
<html lang="es">
<head>
<meta charset="UTF-8">
<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>
<!-- Bootstrap -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Bootstrap Icons -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<!-- Google Font: Fredoka -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<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 -->
<link rel="stylesheet" href="css/index.css">
<link rel="stylesheet" href="css/perfil.css">
<script src="js/jquery-4.0.0.min.js"></script>
</head>
<body>
<?php
include_once 'cabecera.php';
?>
<?php include_once 'cabecera.php'; ?>
<div class="perfil-container">
<div class="perfil-card">
<!-- ========================= -->
<!-- CABECERA -->
<!-- ========================= -->
<div class="perfil-header">
<i class="bi bi-person-circle"></i>
Mi perfil
</div>
<div class="perfil-content">
<div class="row align-items-center g-5">
<!-- ========================= -->
<!-- PERFIL -->
<!-- ========================= -->
<div class="col-md-6 text-center">
<!-- Nombre -->
<h1 id="nombre" class="nombre">
<?php echo $_SESSION['nombreUsuario'] ?>
<?= $nombreUsuario ?>
</h1>
<!-- ========================= -->
<!-- FOTO DE PERFIL -->
<!-- ========================= -->
<div class="foto-container">
<img
id="fotoPerfil"
src="https://i.pravatar.cc/300?img=47"
alt="Foto de perfil"
class="avatar rounded-circle">
<img id="fotoPerfil"
src="<?= $avatarUsuario ?>"
alt="Foto de perfil"
class="avatar rounded-circle">
<!-- Botón lápiz -->
<button
type="button"
class="btn-foto"
onclick="seleccionarFoto()"
title="Cambiar foto de perfil"
aria-label="Cambiar foto de perfil">
<button type="button"
class="btn-foto"
onclick="seleccionarFoto()"
title="Cambiar foto de perfil"
aria-label="Cambiar foto de perfil">
<i class="bi bi-pencil-fill"></i>
</button>
<!-- Input oculto -->
<input
type="file"
id="inputFoto"
accept="image/*"
hidden>
<input type="file"
id="inputFoto"
accept="image/*"
hidden>
</div>
<!-- ========================= -->
<!-- CAMBIAR NOMBRE -->
<!-- ========================= -->
<div class="formulario-nombre">
<label
for="nuevoNombre"
class="form-label">
<label for="nuevoNombre" class="form-label">
Cambia tu nombre
</label>
<input
type="text"
id="nuevoNombre"
class="form-control mb-3"
placeholder="Escribe tu nuevo nombre">
<input type="text"
id="nuevoNombre"
class="form-control mb-3"
placeholder="Escribe tu nuevo nombre">
<div class="d-flex justify-content-center gap-2">
<button
type="button"
class="btn-perfil-cambiar"
onclick="cambiarNombre()">
<button type="button"
class="btn-perfil-cambiar"
onclick="cambiarNombre()">
<i class="bi bi-check-lg"></i>
Cambiar nombre
</button>
<button
type="button"
class="btn-perfil-borrar"
onclick="borrarNombre()">
<button type="button"
class="btn-perfil-borrar"
onclick="borrarNombre()">
<i class="bi bi-x-lg"></i>
Borrar
</button>
</div>
@@ -161,11 +124,7 @@
</div>
<!-- ========================= -->
<!-- ESTADÍSTICAS -->
<!-- ========================= -->
<div class="col-md-6">
<div class="estadisticas">
@@ -175,60 +134,33 @@
Estadísticas
</h2>
<div class="estadistica estadistica-victorias">
<i class="bi bi-trophy-fill"></i>
&nbsp; Victorias:
<strong id="victorias">
</strong>
<strong id="victorias">0</strong>
</div>
<div class="estadistica estadistica-derrotas">
<i class="bi bi-x-circle-fill"></i>
&nbsp; Derrotas:
<strong id="derrotas">
</strong>
<strong id="derrotas">0</strong>
</div>
<div class="estadistica estadistica-aciertos">
<i class="bi bi-bullseye"></i>
&nbsp; Aciertos:
<strong id="aciertos">
</strong>
<strong id="aciertos">0</strong>
</div>
<!-- ========================= -->
<!-- CREAR PREGUNTA -->
<!-- ========================= -->
<div class="text-center mt-4">
<button
type="button"
class="btn btn-play-kahoot"
data-bs-toggle="modal"
data-bs-target="#modalCrearPregunta">
<button type="button"
class="btn btn-play-kahoot"
data-bs-toggle="modal"
data-bs-target="#modalCrearPregunta">
<i class="bi bi-plus-circle-fill"></i>
Crear pregunta
</button>
</div>
</div>
@@ -244,172 +176,118 @@
</div>
<!-- ================================================= -->
<!-- MODAL CREAR PREGUNTA -->
<!-- ================================================= -->
<div
class="modal fade"
id="modalCrearPregunta"
tabindex="-1"
aria-labelledby="modalCrearPreguntaLabel"
aria-hidden="true">
<div class="modal fade"
id="modalCrearPregunta"
tabindex="-1"
aria-labelledby="modalCrearPreguntaLabel"
aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content modal-kahoot">
<!-- CABECERA DEL MODAL -->
<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>
Crear pregunta
</h5>
<button
type="button"
class="btn-close btn-close-white"
data-bs-dismiss="modal"
aria-label="Cerrar">
<button type="button"
class="btn-close btn-close-white"
data-bs-dismiss="modal"
aria-label="Cerrar">
</button>
</div>
<!-- CUERPO DEL MODAL -->
<div class="modal-body p-4">
<form id="formCrearPregunta">
<!-- PREGUNTA -->
<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>
Pregunta
</label>
<textarea
id="pregunta"
name="pregunta"
class="form-control input-kahoot"
rows="3"
placeholder="Escribe aquí la pregunta..."
required></textarea>
<textarea id="pregunta"
name="pregunta"
class="form-control input-kahoot"
rows="3"
placeholder="Escribe aquí la pregunta..."
required></textarea>
</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 -->
<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>
Respuesta correcta
</label>
<input
type="text"
id="respuestaCorrecta"
name="respuestaCorrecta"
class="form-control input-kahoot"
placeholder="Escribe la respuesta correcta..."
required>
<input type="text"
id="respuestaCorrecta"
name="respuestaCorrecta"
class="form-control input-kahoot"
placeholder="Escribe la respuesta correcta..."
required>
</div>
<!-- RESPUESTAS INCORRECTAS -->
<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>
Respuestas incorrectas
</label>
<input type="text"
id="respuestaIncorrecta1"
name="respuestaIncorrecta1"
class="form-control input-kahoot mb-2"
placeholder="Respuesta incorrecta 1"
required>
<input
type="text"
id="respuestaIncorrecta1"
name="respuestaIncorrecta1"
class="form-control input-kahoot mb-2"
placeholder="Respuesta incorrecta 1"
required>
<input
type="text"
id="respuestaIncorrecta2"
name="respuestaIncorrecta2"
class="form-control input-kahoot mb-2"
placeholder="Respuesta incorrecta 2"
required>
<input
type="text"
id="respuestaIncorrecta3"
name="respuestaIncorrecta3"
class="form-control input-kahoot"
placeholder="Respuesta incorrecta 3"
required>
<input type="text"
id="respuestaIncorrecta2"
name="respuestaIncorrecta2"
class="form-control input-kahoot mb-2"
placeholder="Respuesta incorrecta 2"
required>
<input type="text"
id="respuestaIncorrecta3"
name="respuestaIncorrecta3"
class="form-control input-kahoot"
placeholder="Respuesta incorrecta 3"
required>
</div>
</form>
</div>
<!-- PIE DEL MODAL -->
<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>
Cancelar
</button>
<button
type="submit"
form="formCrearPregunta"
class="btn btn-kahoot-login">
<button type="submit" form="formCrearPregunta" class="btn btn-kahoot-login" id="btnCrearPregunta">
<i class="bi bi-check-lg me-1"></i>
Crear pregunta
</button>
</div>
</div>
@@ -418,42 +296,10 @@
</div>
<script>
$(document).ready(function() {
$.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);
}
});
});
</script>
<!-- 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 -->
<script src="js/perfil.js"></script>
</body>
+2
View File
@@ -7,6 +7,8 @@
<title>Trivial - Resultado final</title>
<link rel="icon" type="image/svg+xml" href="img/favicon/favicon.svg">
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet">
File diff suppressed because it is too large Load Diff