81 Commits

Author SHA1 Message Date
victordiamar8 5420c83b30 base de datos con insert partida corregido 2026-09-29 11:15:26 +02:00
victordiamar8 d28fbc7160 Mofificar base de datos y clase Partida 2026-09-29 10:13:25 +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
daniel 8d6272c664 Merge branch 'main' into frontend 2026-09-25 11:00:21 +02:00
dbvictor2002 3a888fc6eb Actualizar clases/ClasePartida.php 2026-09-25 10:48:31 +02:00
Isaac 859f86aeb1 funcionalidad de perfil (estadisticas y nombre) 2026-09-25 10:30:54 +02:00
v.rodriguezcamacho 67224911dc Controladores restantes 2 2026-09-25 10:30:44 +02:00
v.rodriguezcamacho 9657374edd Controladores restantes 2026-09-25 10:27:36 +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
Isaac 6b7e54f1ee Merge branch 'main' of https://git.desarrolloalcala.com/jorge/triviagmatico 2026-09-25 09:57:31 +02:00
Isaac 4ee0f619cf cierre de sesión 2026-09-25 09:57:05 +02:00
jorge 72dc4dec8f Nueva version BD con usuarios
Añadidas respuestas y 10 usuarios de prueba a la BD para hacer tets.
2026-09-25 09:56:16 +02:00
profesor 18ba294dc7 Actualizar README.md 2026-09-25 09:53:16 +02:00
Isaac ca5a5558b4 cierre de sesion 2026-09-25 09:52:18 +02:00
dbvictor2002 e081b831b4 Subir archivos a "mysqulito" 2026-09-25 09:43:36 +02:00
Isaac ab26f5fa9a Merge para login y registro 2026-09-25 09:43:12 +02:00
Isaac 5c1fa24ebf Merge branch 'main' of https://git.desarrolloalcala.com/jorge/triviagmatico 2026-09-25 09:41:34 +02:00
Isaac 35611746a6 Login y registro funcionales 2026-09-25 09:41:29 +02:00
jorge 956798b634 sql adaptado - test
Subido sql con todas las preguntas insertadas
2026-09-25 09:35:28 +02:00
v.rodriguezcamacho 9515a1e923 Merge branch 'main' of https://git.desarrolloalcala.com/jorge/triviagmatico 2026-09-25 09:29:00 +02:00
v.rodriguezcamacho 3ed1a747f7 add respuestas.sql to mysqulito 2026-09-25 09:28:51 +02:00
dbvictor2002 c95bc19155 Actualizar includes/conexionBD.php 2026-09-25 09:21:44 +02:00
dbvictor2002 b96a18b88b Actualizar includes/ConexionBD.php 2026-09-25 09:13:34 +02:00
dbvictor2002 c8f2f86364 Actualizar controladores/ControladorUsuario.php 2026-09-25 09:12:42 +02:00
dbvictor2002 5eccd108ef Actualizar controladores/ControladorEquipoxUsuario.php 2026-09-25 09:12:30 +02:00
v.rodriguezcamacho 6a72c7cafe Merge branch 'main' of https://git.desarrolloalcala.com/jorge/triviagmatico 2026-09-25 09:05:59 +02:00
dbvictor2002 8c5684aedc Actualizar controladores/controladorUsuario.php 2026-09-25 09:00:39 +02:00
v.rodriguezcamacho 8646f18782 Hecho merge de backend a main de claseUsuario y controladorUsuario 2026-09-25 08:58:53 +02:00
dbvictor2002 9fc1f6be24 Subir archivos a "clases" 2026-09-25 08:53:56 +02:00
margarita 0caa264961 actualizar ClaseUsuario y controladorUsuario 2026-09-25 08:52:12 +02:00
dbvictor2002 3d5aff18f4 Subir archivos a "clases" 2026-09-25 08:49:49 +02:00
dbvictor2002 17f3058ec7 Subir archivos a "clases" 2026-09-25 08:49:35 +02:00
dbvictor2002 08131b46e4 Subir archivos a "mysqulito" 2026-09-25 08:47:37 +02:00
v.rodriguezcamacho c52fab2d6c Merge branch 'backend' 2026-09-24 14:10:27 +02:00
margarita 22f86c2d6d añadir carpeta controlador y controladorUsuario 2026-09-24 14:00:24 +02:00
Isaac cb3b00fba3 Merge branch 'frontend'
Traemos resultados.php (pantalla final) a la main
2026-09-24 13:36:32 +02:00
v.rodriguezcamacho 9df7bd9d45 add controladorEquipoxUsuario.php 2026-09-24 13:27:11 +02:00
dbvictor2002 52a97dfd01 Subir archivos a "clases" 2026-09-24 12:52:42 +02:00
dbvictor2002 63e9c3ceab Subir archivos a "clases" 2026-09-24 12:52:32 +02:00
dbvictor2002 87fdf7285f Subir archivos a "clases" 2026-09-24 12:37:39 +02:00
dbvictor2002 9bcb06a651 Subir archivos a "clases" 2026-09-24 12:37:28 +02:00
dbvictor2002 b9dea2a3ca Actualizar clases/ClasePartida.php 2026-09-24 12:35:42 +02:00
dbvictor2002 cab040aaa1 Actualizar clases/ClaseEquipo.php 2026-09-24 12:35:28 +02:00
dbvictor2002 a3cd770956 Actualizar clases/ClaseCategoria.php 2026-09-24 12:35:15 +02:00
daniel db6e1304bf Merge branch 'main' into frontend 2026-09-24 12:29:13 +02:00
Isaac 38a091a2fd add modal crear pregunta 2026-09-24 11:36:37 +02:00
dbvictor2002 3348188d44 Subir archivos a "clases" 2026-09-24 11:21:34 +02:00
dbvictor2002 e102298961 Subir archivos a "clases" 2026-09-24 11:13:44 +02:00
dbvictor2002 d1c381d7ac Subir archivos a "clases" 2026-09-24 11:02:48 +02:00
dbvictor2002 ee781cb1e7 Subir archivos a "clases" 2026-09-24 10:49:38 +02:00
v.rodriguezcamacho f784c7bfff puesto de la misma manera los require en todas las clases 2026-09-24 10:43:11 +02:00
v.rodriguezcamacho 29a11a8514 añadido el BD en conexion.php en algunas clases 2026-09-24 10:39:45 +02:00
v.rodriguezcamacho a62d888953 meter claseUsuario en la carpeta clases 2026-09-24 10:12:19 +02:00
dbvictor2002 93ac0e9ec2 Subir archivos a "clases" 2026-09-24 10:07:25 +02:00
Isaac c603a3c0ba add resultados 2026-09-24 10:05:45 +02:00
victordiamar8 467a861873 claseVictorDiaz 2026-09-24 10:05:39 +02:00
Juanjo 39d0ef51be cambios en conexion base de datos 2026-09-24 09:56:18 +02:00
alexis afbf66c073 Add pantalla juego 2026-09-24 09:54:44 +02:00
margarita e257527321 renombrar clase 2026-09-24 09:53:43 +02:00
margarita 42c4785d98 clase Marga 2026-09-24 09:45:16 +02:00
Juanjo dd810ed2cb clases Juanjo 2026-09-24 09:40:09 +02:00
v.rodriguezcamacho 8d767e61e8 carpeta includes con conexionBD.php 2026-09-24 09:30:38 +02:00
40 changed files with 10225 additions and 726 deletions
+18 -2
View File
@@ -53,10 +53,26 @@ Equipos de Backend y Frontend.
# Notas sueltas
## Publicación en el servidor
Here are information to log into the database:
Configuración de acceso al servidor de producción:
- SSH/SCP/SFTP:
- Host: desarrolloalcala.com
- Puerto: 2222
- Usuario: alumnado
- Contraseña: epdsrntr\*\*
- Acceso WEB al panel de control:
- URL: http://desarrolloalcala.com
- Usuario: alumnado
- Contraseña: epdsrntr\*\*
- Acceso a PHPMyAdmin
- http://desarrolloalcala.com/phpmyadmin
- usuario: alumnado
- contraseña: epdsrntr\*\*
Here are information to log into the database:
- Type: mysql
- Database user: my_webapp
- Database name: my_webapp
- Password: 07tCqBO3B6Q3cncKMF2FHcpgsLjFTx
+60 -96
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">
<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 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
</button>
<button
type="button"
class="btn btn-kahoot-login"
id="btnCrearSala">
Crear sala
<button type="button" id="btnConfirmarAbandonar" class="btn btn-danger px-4 py-2">
Sí, salir
</button>
</div>
</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>
+21 -222
View File
@@ -1,191 +1,19 @@
<?php
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
// Comprobación de sesión
$isLoggedIn = isset($_SESSION['usuario']) && !empty($_SESSION['usuario']);
$username = $isLoggedIn ? $_SESSION['usuario'] : '';
?>
<!-- Bootstrap 5 CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- FontAwesome para iconos -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
<!-- Google Fonts para estilo Kahoot -->
<link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/css/index.css">
<style>
:root {
--kahoot-purple: #46178f;
--kahoot-blue: #1368ce;
--kahoot-red: #e21b3c;
--kahoot-yellow: #ffa602;
--kahoot-green: #26890c;
--kahoot-green-hover: #1f6f09;
}
body {
font-family: 'Fredoka', sans-serif;
background-color: #f2f2f2;
min-height: 100vh;
}
.navbar-kahoot {
background-color: var(--kahoot-purple);
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
.navbar-brand {
font-weight: 700;
font-size: 1.8rem;
color: #fff !important;
letter-spacing: 1px;
text-shadow: 2px 2px 0px rgba(0, 0, 0, 0.2);
}
.btn-kahoot-login {
background-color: var(--kahoot-blue);
color: white;
font-weight: 600;
border: none;
border-bottom: 4px solid #0c4891;
transition: all 0.2s ease;
}
.btn-kahoot-login:hover {
background-color: #0f56ab;
color: white;
transform: translateY(-2px);
}
.btn-kahoot-register {
background-color: var(--kahoot-green);
color: white;
font-weight: 600;
border: none;
border-bottom: 4px solid var(--kahoot-green-hover);
transition: all 0.2s ease;
}
.btn-kahoot-register:hover {
background-color: #2bb00f;
color: white;
transform: translateY(-2px);
}
.user-dropdown-btn {
background: rgba(255, 255, 255, 0.15);
color: white;
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: 50px;
padding: 8px 18px;
font-weight: 600;
transition: all 0.2s ease;
}
.user-dropdown-btn:hover,
.user-dropdown-btn:focus,
.user-dropdown-btn.show {
background: rgba(255, 255, 255, 0.3);
color: white;
border-color: #fff;
box-shadow: none;
}
.user-dropdown-menu {
border-radius: 15px;
border: none;
box-shadow: 0 10px 25px rgba(0,0,0,0.2);
padding: 10px;
min-width: 200px;
margin-top: 10px !important;
}
.user-dropdown-menu .dropdown-item {
border-radius: 10px;
font-weight: 600;
padding: 10px 15px;
transition: all 0.15s ease;
}
.user-dropdown-menu .dropdown-item:hover {
background-color: #f0eafb;
color: var(--kahoot-purple);
}
.user-dropdown-menu .dropdown-item.logout-item {
color: var(--kahoot-red);
}
.user-dropdown-menu .dropdown-item.logout-item:hover {
background-color: #fde8ea;
color: var(--kahoot-red);
}
.btn-play-kahoot {
background-color: var(--kahoot-green);
color: white;
font-size: 2.2rem;
font-weight: 700;
width: 100%;
padding: 30px 20px;
border-radius: 20px;
border: none;
border-bottom: 8px solid var(--kahoot-green-hover);
box-shadow: 0 8px 15px rgba(0,0,0,0.2);
transition: all 0.1s ease;
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
}
.btn-play-kahoot:hover {
background-color: #2bb00f;
color: white;
transform: translateY(-3px);
box-shadow: 0 12px 20px rgba(0,0,0,0.25);
}
.btn-play-kahoot:active {
transform: translateY(4px);
border-bottom: 2px solid var(--kahoot-green-hover);
}
.ranking-card {
border-radius: 20px;
border: none;
box-shadow: 0 8px 20px rgba(0,0,0,0.08);
overflow: hidden;
}
.ranking-header {
background-color: var(--kahoot-yellow);
color: #333;
padding: 15px 20px;
font-weight: 700;
}
.trophy-icon {
font-size: 3rem;
color: var(--kahoot-yellow);
margin-bottom: 10px;
}
/* Estilos modales */
.modal-content {
border-radius: 20px;
overflow: hidden;
}
</style>
<link rel="stylesheet" href="css/index.css">
<script src="js/jquery-4.0.0.min.js"></script>
<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>
@@ -193,41 +21,8 @@ $username = $isLoggedIn ? $_SESSION['usuario'] : '';
<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="logout.php">
<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>
@@ -250,14 +45,9 @@ $username = $isLoggedIn ? $_SESSION['usuario'] : '';
<label for="loginEmail">Correo electrónico</label>
</div>
<div class="form-floating mb-3">
<input type="password" class="form-control border-dark" id="loginPassword" name="password" placeholder="Contraseña" required>
<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>
@@ -282,7 +72,7 @@ $username = $isLoggedIn ? $_SESSION['usuario'] : '';
<div class="modal-body">
<form id="formRegistro">
<div class="form-floating mb-3">
<input type="text" class="form-control border-dark" id="regNombre" name="nombre" placeholder="Nombre" required>
<input type="text" class="form-control border-dark" id="regNombre" name="nombreUsuario" placeholder="Nombre" required>
<label for="regNombre">Nombre</label>
</div>
<div class="form-floating mb-3">
@@ -290,14 +80,21 @@ $username = $isLoggedIn ? $_SESSION['usuario'] : '';
<label for="regEmail">Correo electrónico</label>
</div>
<div class="form-floating mb-3">
<input type="password" class="form-control border-dark" id="regPassword" name="password" placeholder="Contraseña" required>
<input type="password" class="form-control border-dark" id="regPassword" name="contrasena" placeholder="Contraseña" required>
<label for="regPassword">Contraseña</label>
</div>
<div class="form-floating mb-3">
<input type="password" class="form-control border-dark" id="regPasswordConfirm" name="passwordConfirm" placeholder="Confirmar contraseña" required>
<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>
@@ -308,3 +105,5 @@ $username = $isLoggedIn ? $_SESSION['usuario'] : '';
</div>
</div>
</div>
<script src="js/cabecera.js"></script>
+149
View File
@@ -0,0 +1,149 @@
<?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/triviagmatico/includes/conexionBD.php';
class Categoria{
public $idCategoria;
public $nombreCategoria;
function __construct($idCategoria=null, $nombreCategoria=null){
$this->idCategoria = $idCategoria;
$this->nombreCategoria = $nombreCategoria;
}
function crear(){
$conexion = conexionBD();
if(is_array($conexion)){
return $conexion;
}else{
try{
$consulta = $conexion->prepare("INSERT INTO categoria (nombreCategoria) VALUES (:nombreCategoria)");
$consulta->bindParam(':nombreCategoria', $this->nombreCategoria);
$consulta->execute();
$respuesta = [
'exito' => 'Categoría creada correctamente',
'exito_tecnico' => $this->nombreCategoria
];
return $respuesta;
}catch(PDOException $error){
$respuesta = [
'error' => 'Ocurrió un error al guardar la categoría.',
'error_tecnico' => $error->getMessage()
];
$conexion = null;
return $respuesta;
}
}
}
function listar(){
$conexion = conexionBD();
if(is_array($conexion)){
return $conexion;
}else{
try{
$sql = 'SELECT * FROM categoria';
$consulta = $conexion->prepare($sql);
$consulta->execute();
$resultado = $consulta->fetchAll(PDO::FETCH_ASSOC);
return $resultado;
}catch(PDOException $error){
$respuesta = [
'error' => 'Ocurrió un error al obtener el listado de categorías.',
'error_tecnico' => $error->getMessage()
];
$conexion = null;
return $respuesta;
}
}
}
function buscar(){
$conexion = conexionBD();
if(is_array($conexion)){
return $conexion;
}else{
try{
$consulta = $conexion->prepare("SELECT * FROM categoria WHERE idCategoria = :idCategoria");
$consulta->bindParam(':idCategoria', $this->idCategoria);
$consulta->execute();
$resultado = $consulta->fetch(PDO::FETCH_ASSOC);
return $resultado;
}catch(PDOException $error){
$respuesta = [
'error' => 'Ocurrió un error al buscar la categoría.',
'error_tecnico' => $error->getMessage()
];
$conexion = null;
return $respuesta;
}
}
}
function borrar(){
$conexion = conexionBD();
if(is_array($conexion)){
return $conexion;
}else{
try{
$consulta = $conexion->prepare("DELETE FROM categoria WHERE idCategoria = :idCategoria");
$consulta->bindParam(':idCategoria', $this->idCategoria);
$consulta->execute();
if($consulta->rowCount() > 0){
$respuesta = [
'exito' => 'Se eliminó correctamente la categoría',
'exito_tecnico' => $this->idCategoria
];
}else{
$respuesta = [
'error' => 'No existe ninguna categoría con ese ID.',
'error_tecnico' => $this->idCategoria
];
}
return $respuesta;
}catch(PDOException $error){
$respuesta = [
'error' => 'Ocurrió un error al eliminar la categoría.',
'error_tecnico' => $error->getMessage()
];
$conexion = null;
return $respuesta;
}
}
}
}
?>
+154
View File
@@ -0,0 +1,154 @@
<?php
require_once __DIR__ . '/../includes/conexionBD.php';
class Equipo
{
public $idEquipo;
public $nombreEquipo;
function __construct($idEquipo = null, $nombreEquipo = null)
{
$this->idEquipo = $idEquipo;
$this->nombreEquipo = $nombreEquipo;
}
function crear()
{
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
} 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->idEquipo
];
return $respuesta;
} catch (PDOException $error) {
$respuesta = [
'error' => 'Ocurrió un error al guardar el equipo.',
'error_tecnico' => $error->getMessage()
];
$conexion = null;
return $respuesta;
}
}
}
function listar()
{
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
} else {
try {
$sql = 'SELECT * FROM equipo';
$consulta = $conexion->prepare($sql);
$consulta->execute();
$resultado = $consulta->fetchAll(PDO::FETCH_ASSOC);
return $resultado;
} catch (PDOException $error) {
$respuesta = [
'error' => 'Ocurrió un error al obtener el listado de equipos.',
'error_tecnico' => $error->getMessage()
];
$conexion = null;
return $respuesta;
}
}
}
function buscar()
{
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
} else {
try {
$consulta = $conexion->prepare("SELECT * FROM equipo WHERE idEquipo = :idEquipo");
$consulta->bindParam(':idEquipo', $this->idEquipo);
$consulta->execute();
$resultado = $consulta->fetch(PDO::FETCH_ASSOC);
return $resultado;
} catch (PDOException $error) {
$respuesta = [
'error' => 'Ocurrió un error al buscar el equipo.',
'error_tecnico' => $error->getMessage()
];
$conexion = null;
return $respuesta;
}
}
}
function borrar()
{
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
} else {
try {
$consulta = $conexion->prepare("DELETE FROM equipo WHERE idEquipo = :idEquipo");
$consulta->bindParam(':idEquipo', $this->idEquipo);
$consulta->execute();
if ($consulta->rowCount() > 0) {
$respuesta = [
'exito' => 'Se eliminó correctamente el equipo',
'exito_tecnico' => $this->idEquipo
];
} else {
$respuesta = [
'error' => 'No existe ningún equipo con ese ID.',
'error_tecnico' => $this->idEquipo
];
}
return $respuesta;
} catch (PDOException $error) {
$respuesta = [
'error' => 'Ocurrió un error al eliminar el equipo.',
'error_tecnico' => $error
];
$conexion = null;
return $respuesta;
}
}
}
}
+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()
];
}
}
}
+147
View File
@@ -0,0 +1,147 @@
<?php
require_once __DIR__ . '/../includes/conexionBD.php';
class EquipoxUsuario
{
public $idEquipoxUsuario;
public $idUsuario;
public $idEquipo;
public function __construct($idEquipoxUsuario = null, $idUsuario = null, $idEquipo = null)
{
$this->idEquipoxUsuario = $idEquipoxUsuario;
$this->idUsuario = $idUsuario;
$this->idEquipo = $idEquipo;
}
public function registrarUsuarioEnEquipo()
{
$conexion = conexionBD();
if (is_array($conexion)) return $conexion;
try {
$sql = "INSERT INTO equipoxusuario (idUsuario, idEquipo) VALUES (:idUsuario, :idEquipo)";
$consulta = $conexion->prepare($sql);
$consulta->bindParam(':idUsuario', $this->idUsuario);
$consulta->bindParam(':idEquipo', $this->idEquipo);
$consulta->execute();
return [
'exito' => 'Usuario vinculado al equipo correctamente.',
'exito_tecnico' => $conexion->lastInsertId()
];
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al unir al usuario con el equipo.',
'error_tecnico' => $error->getMessage()
];
}
}
public static function listarUsuariosPorEquipo($idEquipo)
{
$conexion = conexionBD();
if (is_array($conexion)) return $conexion;
try {
$sql = "SELECT u.* FROM equipoxusuario exu
INNER JOIN usuario u ON exu.idUsuario = u.idUsuario
WHERE exu.idEquipo = :idEquipo";
$consulta = $conexion->prepare($sql);
$consulta->bindParam(':idEquipo', $idEquipo);
$consulta->execute();
return $consulta->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al obtener los miembros del equipo.',
'error_tecnico' => $error->getMessage()
];
}
}
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()
];
}
}
}
+463
View File
@@ -0,0 +1,463 @@
<?php
require_once __DIR__ . '/../includes/conexionBD.php';
class Partida
{
public $idPartida;
public $nombrePartida;
public $idUsuario;
public $fechaCreacion;
public $fechaInicio;
public $fechaFin;
public function __construct(
$idPartida = null,
$nombrePartida = null,
$idUsuario = null,
$fechaCreacion = null,
$fechaInicio = null,
$fechaFin = null
) {
$this->idPartida = $idPartida;
$this->nombrePartida = $nombrePartida;
$this->idUsuario = $idUsuario;
$this->fechaCreacion = $fechaCreacion;
$this->fechaInicio = $fechaInicio;
$this->fechaFin = $fechaFin;
}
public function insertar()
{
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("INSERT INTO partida (nombrePartida,idUsuario) VALUES (:nombrePartida,:idUsuario)");
$consulta->bindParam(":nombrePartida", $this->nombrePartida);
$consulta->bindParam(":idUsuario", $this->idUsuario);
$consulta->execute();
return [
"exito" => "La partida se creó correctamente.",
"exito_tecnico" => $conexion->lastInsertId()
];
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al guardar la partida.",
'error_tecnico' => $error->getMessage()
];
}
}
public function listar(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("SELECT * FROM partida");
$consulta->execute();
return $consulta->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al obtener el listado.",
'error_tecnico' => $error->getMessage()
];
}
}
public function buscar(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("SELECT * FROM partida WHERE idPartida=:idPartida");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->execute();
return $consulta->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al buscar la partida.",
'error_tecnico' => $error->getMessage()
];
}
}
public function editar(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("UPDATE partida SET nombrePartida=:nombrePartida, idUsuario=:idUsuario WHERE idPartida=:idPartida");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->bindParam(":nombrePartida", $this->nombrePartida);
$consulta->bindParam(":idUsuario", $this->idUsuario);
$consulta->execute();
return [
"exito" => "La partida se editó correctamente.",
"exito_tecnico" => $this->idPartida
];
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al editar la partida.",
'error_tecnico' => $error->getMessage()
];
}
}
public function eliminar(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("DELETE FROM partida WHERE idPartida=:idPartida");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->execute();
return [
"exito" => "La partida se eliminó correctamente.",
"exito_tecnico" => $this->idPartida
];
} catch (PDOException $error) {
return [
"error" => "No se pudo eliminar la partida.",
'error_tecnico' => $error->getMessage()
];
}
}
public function iniciarPartida(){
$conexion = conexionBD();
if (is_array($conexion)){
return $conexion;
}
try {
$consulta = $conexion->prepare("UPDATE partida SET fechaInicio=NOW() WHERE idPartida=:idPartida AND fechaInicio IS NULL");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->execute();
return [
"exito" => "La partida ha comenzado.",
"exito_tecnico" => $this->idPartida
];
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al iniciar la partida.",
'error_tecnico' => $error->getMessage()
];
}
}
public function finalizar(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("UPDATE partida SET fechaFin=NOW() WHERE idPartida=:idPartida AND fechaFin IS NULL");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->execute();
return [
"exito" => "La partida se finalizó correctamente.",
"exito_tecnico" => $this->idPartida
];
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al finalizar la partida.",
'error_tecnico' => $error->getMessage()
];
}
}
//true si la partida ya tiene fecha de fin (fechaFin no es NULL)
//Devuelve false si la partida no existe
public function estaFinalizada() {
$datos = $this->buscar();
if (is_array($datos) && isset($datos["error"])) {
return $datos;
}
if (!$datos) {
return false;
}
return $datos["fechaFin"] !== null;
}
//Devuelve la partida más reciente del usuario que aún no ha
//terminado (fechaFin NULL), o false si no tiene ninguna.
//Incluye también las salas que todavía no han empezado.
public function partidaEnCursoDeUsuario(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("SELECT * FROM partida WHERE idUsuario=:idUsuario AND fechaFin IS NULL ORDER BY idPartida DESC LIMIT 1");
$consulta->bindParam(":idUsuario", $this->idUsuario);
$consulta->execute();
return $consulta->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al buscar la partida en curso.",
'error_tecnico' => $error->getMessage()
];
}
}
public function listarSalasAbiertas() {
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("SELECT p.idPartida, p.nombrePartida, e.idEquipo, e.nombreEquipo, u.idUsuario, u.nombreUsuario
FROM partida p INNER JOIN equipoxpartida exp ON exp.idPartida=p.idPartida INNER JOIN equipo e ON e.idEquipo=exp.idEquipo
LEFT JOIN equipoxusuario exu ON exu.idEquipo=e.idEquipo LEFT JOIN usuario u ON u.idUsuario=exu.idUsuario WHERE p.fechaInicio IS NULL
AND p.fechaFin IS NULL ORDER BY p.idPartida DESC, e.idEquipo ASC");
$consulta->execute();
return $consulta->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al recuperar las salas abiertas.",
'error_tecnico' => $error->getMessage()
];
}
}
/**
* Devuelve las preguntas asignadas a la partida, junto con el
* idPartidaxPregunta (necesario para guardar respuestas después).
*/
public function getPreguntas(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("SELECT pxp.idPartidaxPregunta, p.* FROM partidaxpregunta pxp INNER JOIN pregunta p ON pxp.idPregunta=p.idPregunta
WHERE pxp.idPartida=:idPartida ORDER BY pxp.idPartidaxPregunta");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->execute();
return $consulta->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al recuperar las preguntas de la partida.",
'error_tecnico' => $error->getMessage()
];
}
}
public function asignarPregunta($idPregunta) {
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("INSERT INTO partidaxpregunta (idPartida,idPregunta) VALUES (:idPartida,:idPregunta)");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->bindParam(":idPregunta", $idPregunta);
$consulta->execute();
return [
"exito" => "La pregunta se asignó correctamente.",
"exito_tecnico" => $conexion->lastInsertId()
];
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al asignar la pregunta.",
'error_tecnico' => $error->getMessage()
];
}
}
//Cuenta cuántas preguntas tiene la partida en total. Es la primera mitad de la comprobación "¿ha terminado el usuario de jugar?".
public function contarPreguntasAsignadas() {
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("SELECT COUNT(*) AS total FROM partidaxpregunta WHERE idPartida=:idPartida");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->execute();
$fila = $consulta->fetch(PDO::FETCH_ASSOC);
return (int)$fila["total"];
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al contar las preguntas.",
'error_tecnico' => $error->getMessage()
];
}
}
public function contarRespuestasUsuario($idUsuario){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("SELECT COUNT(*) AS total FROM respuestaalmacenada ra INNER JOIN partidaxpregunta pxp
ON ra.idPartidaxPregunta=pxp.idPartidaxPregunta WHERE pxp.idPartida=:idPartida AND ra.idUsuario=:idUsuario");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->bindParam(":idUsuario", $idUsuario);
$consulta->execute();
$fila = $consulta->fetch(PDO::FETCH_ASSOC);
return (int)$fila["total"];
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al contar las respuestas del usuario.",
'error_tecnico' => $error->getMessage()
];
}
}
/**
* Indica si ESTE usuario ya ha respondido todas las preguntas:
* compara cuántas preguntas tiene la partida contra cuántas ha
* respondido él. (La partida completa se marca con finalizar().)
*/
public function estaFinalizadaParaUsuario($idUsuario){
$totalPreguntas = $this->contarPreguntasAsignadas();
if (is_array($totalPreguntas)) {
return $totalPreguntas;
}
$totalRespondidas = $this->contarRespuestasUsuario($idUsuario);
if (is_array($totalRespondidas)) {
return $totalRespondidas;
}
return $totalPreguntas > 0 && $totalPreguntas === $totalRespondidas;
}
/**
* Partidas creadas por un usuario, de más reciente a más antigua.
*/
public function listarDelUsuario(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("SELECT * FROM partida WHERE idUsuario=:idUsuario ORDER BY idPartida DESC");
$consulta->bindParam(":idUsuario", $this->idUsuario);
$consulta->execute();
return $consulta->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al recuperar las partidas del usuario.",
'error_tecnico' => $error->getMessage()
];
}
}
public function preguntaAsignada($idPregunta) {
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("SELECT COUNT(*) AS total FROM partidaxpregunta WHERE idPartida=:idPartida AND idPregunta=:idPregunta");
$consulta->bindParam(":idPartida", $this->idPartida);
$consulta->bindParam(":idPregunta", $idPregunta);
$consulta->execute();
$fila = $consulta->fetch(PDO::FETCH_ASSOC);
return (int)$fila["total"] > 0;
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al comprobar la pregunta.",
'error_tecnico' => $error->getMessage()
];
}
}
/**
* 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){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("INSERT INTO equipoxpartida (idPartida, idEquipo) VALUES (:idPartida, :idEquipo)");
$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()
];
} catch (PDOException $error) {
return [
"error" => "Ocurrió un error al asignar el equipo a la partida.",
"error_tecnico" => $error->getMessage()
];
}
}
/**
* 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(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("SELECT exp.idEquipoxPartida, e.idEquipo, e.nombreEquipo FROM equipoxpartida exp
INNER JOIN equipo e ON exp.idEquipo = e.idEquipo 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 [
"error" => "Ocurrió un error al recuperar los equipos de la partida.",
"error_tecnico" => $error->getMessage()
];
}
}
/**
* 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(){
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$consulta = $conexion->prepare("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()
];
}
}
}
+113
View File
@@ -0,0 +1,113 @@
<?php
require_once __DIR__ . '/../includes/conexionBD.php';
class Pregunta {
private ?int $idPregunta;
private int $idCategoria;
private string $nombrePregunta;
private array $respuestas;
public function __construct(int $idCategoria = 0, string $nombrePregunta = "", ?int $idPregunta = null) {
$this->idPregunta = $idPregunta;
$this->idCategoria = $idCategoria;
$this->nombrePregunta = $nombrePregunta;
$this->respuestas = [];
}
public function getIdPregunta(): ?int { return $this->idPregunta; }
public function getIdCategoria(): int { return $this->idCategoria; }
public function setIdCategoria(int $idCategoria): void { $this->idCategoria = $idCategoria; }
public function getNombrePregunta(): string { return $this->nombrePregunta; }
public function setNombrePregunta(string $nombrePregunta): void { $this->nombrePregunta = $nombrePregunta; }
public function getRespuestas(): array { return $this->respuestas; }
public function guardar() {
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$sql = "INSERT INTO pregunta (idCategoria, nombrePregunta) VALUES (:idCat, :texto)";
$stmt = $conexion->prepare($sql);
$stmt->execute([
':idCat' => $this->idCategoria,
':texto' => $this->nombrePregunta
]);
$this->idPregunta = (int)$conexion->lastInsertId();
return [
'exito' => 'Pregunta guardada correctamente',
'exito_tecnico' => $this->idPregunta
];
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al guardar la pregunta.',
'error_tecnico' => $error->getMessage()
];
}
}
public function cargarRespuestas() {
if ($this->idPregunta === null) return;
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$sql = "SELECT idRespuesta, nombreRespuesta, correcta FROM respuesta WHERE idPregunta = :idPreg";
$stmt = $conexion->prepare($sql);
$stmt->execute([':idPreg' => $this->idPregunta]);
$this->respuestas = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al cargar las respuestas.',
'error_tecnico' => $error->getMessage()
];
}
}
public static function obtenerPorCategoria(int $idCategoria, int $limite = 10) {
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$sql = "SELECT * FROM pregunta WHERE idCategoria = :idCat ORDER BY RAND() LIMIT :limite";
$stmt = $conexion->prepare($sql);
$stmt->bindValue(':idCat', $idCategoria, PDO::PARAM_INT);
$stmt->bindValue(':limite', $limite, PDO::PARAM_INT);
$stmt->execute();
$preguntas = [];
while ($datos = $stmt->fetch(PDO::FETCH_ASSOC)) {
$preg = new Pregunta((int)$datos['idCategoria'], $datos['nombrePregunta'], (int)$datos['idPregunta']);
$preg->cargarRespuestas();
$preguntas[] = $preg;
}
return $preguntas;
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al obtener las preguntas aleatorias.',
'error_tecnico' => $error->getMessage()
];
}
}
}
+169
View File
@@ -0,0 +1,169 @@
<?php
require_once __DIR__ . '/../includes/conexionBD.php';
class Respuesta{
public $idRespuesta;
public $idPregunta;
public $nombreRespuesta;
public $correcta;
public function __construct($idRespuesta=null, $idPregunta=null, $nombreRespuesta=null, $correcta=null){
$this->idRespuesta=$idRespuesta;
$this->idPregunta=$idPregunta;
$this->nombreRespuesta=$nombreRespuesta;
$this->correcta=$correcta;
}//fin constructor
public function insertar(){
$conexion = conexionBD();
if(is_array($conexion)){
return $conexion;
}else{
try{
$consulta = $conexion->prepare("INSERT INTO respuesta (idPregunta, nombreRespuesta, correcta) VALUES (:idPregunta, :nombreRespuesta, :correcta)");
$consulta->bindParam(':idPregunta', $this->idPregunta);
$consulta->bindParam(':nombreRespuesta', $this->nombreRespuesta);
$consulta->bindParam(':correcta', $this->correcta);
$consulta->execute();
$respuesta = [
'exito' => 'La respuesta se guardó correctamente.',
'exito_tecnico' => $conexion->lastInsertId()
];
return $respuesta;
}catch(PDOException $error){
$respuesta = [
'error' => 'Ocurrió un error al guardar la respuesta.',
'error_tecnico' => $error->getMessage()
];
$conexion = null;
return $respuesta;
}
}
}//fin método insertar
public function listar(){
$conexion = conexionBD();
if(is_array($conexion)){
return $conexion;
}else{
try{
$consulta = $conexion->prepare("SELECT * FROM respuesta");
$consulta->execute();
return $consulta->fetchAll(PDO::FETCH_ASSOC);
}catch(PDOException $error){
$respuesta = [
'error' => 'Ocurrió un error al obtener el listado.',
'error_tecnico' => $error->getMessage()
];
$conexion = null;
return $respuesta;
}
}
}//fin método listar
public function eliminar(){
$conexion = conexionBD();
if(is_array($conexion)){
return $conexion;
}else{
try{
$consulta = $conexion->prepare("DELETE FROM respuesta WHERE idRespuesta=:idRespuesta");
$consulta->bindParam(':idRespuesta', $this->idRespuesta);
$consulta->execute();
$respuesta = [
'exito' => 'La respuesta se eliminó correctamente.',
'exito_tecnico' => $this->idRespuesta
];
return $respuesta;
}catch(PDOException $error){
$respuesta = [
'error' => 'No se pudo eliminar la respuesta.',
'error_tecnico' => $error->getMessage()
];
$conexion = null;
return $respuesta;
}
}
}//fin método eliminar
public function editar(){
$conexion = conexionBD();
if(is_array($conexion)){
return $conexion;
}else{
try{
$consulta = $conexion->prepare("UPDATE respuesta SET idPregunta=:idPregunta, nombreRespuesta=:nombreRespuesta, correcta=:correcta WHERE idRespuesta=:idRespuesta");
$consulta->bindParam(':idRespuesta', $this->idRespuesta);
$consulta->bindParam(':idPregunta', $this->idPregunta);
$consulta->bindParam(':nombreRespuesta', $this->nombreRespuesta);
$consulta->bindParam(':correcta', $this->correcta);
$consulta->execute();
$respuesta = [
'exito' => 'La respuesta se editó correctamente.',
'exito_tecnico' => $this->idRespuesta
];
return $respuesta;
}catch(PDOException $error){
$respuesta = [
'error' => 'Ocurrió un error al editar la respuesta.',
'error_tecnico' => $error->getMessage()
];
$conexion = null;
return $respuesta;
}
}
}//fin método editar
public function buscar(){
$conexion = conexionBD();
if(is_array($conexion)){
return $conexion;
}else{
try{
$consulta = $conexion->prepare("SELECT * FROM respuesta WHERE idRespuesta=:idRespuesta");
$consulta->bindParam(':idRespuesta', $this->idRespuesta);
$consulta->execute();
return $consulta->fetchAll(PDO::FETCH_ASSOC);
}catch(PDOException $error){
$respuesta = [
'error' => 'Ocurrió un error al buscar la respuesta.',
'error_tecnico' => $error->getMessage()
];
$conexion = null;
return $respuesta;
}
}
}//fin método buscar
public function listarPorPregunta(){//trae todas las respuestas posibles de una pregunta
$conexion = conexionBD();
if(is_array($conexion)){
return $conexion;
}else{
try{
$consulta = $conexion->prepare("SELECT * FROM respuesta WHERE idPregunta=:idPregunta");
$consulta->bindParam(':idPregunta', $this->idPregunta);
$consulta->execute();
$resultado = $consulta->fetchAll(PDO::FETCH_ASSOC);
if(!isset($resultado[0])){
$respuesta = [
'error' => 'La pregunta no tiene respuestas.'
];
return $respuesta;
}else{
return $resultado;
}
}catch(PDOException $error){
$respuesta = [
'error' => 'Ocurrió un error al obtener las respuestas de la pregunta.',
'error_tecnico' => $error->getMessage()
];
$conexion = null;
return $respuesta;
}
}
}//fin método listarPorPregunta
}//fin clase
?>
+76
View File
@@ -0,0 +1,76 @@
<?php
require_once __DIR__ . '/../includes/conexionBD.php';
// Clase encargada de registrar las respuestas de los jugadores en tiempo real durante la partida
class RespuestaAlmacenada {
public $idRespuestaAlmacenada;
public $idPartidaxPregunta;
public $idUsuario;
public $idRespuesta;
public function __construct($idRespuestaAlmacenada = null, $idPartidaxPregunta = null, $idUsuario = null, $idRespuesta = null) {
$this->idRespuestaAlmacenada = $idRespuestaAlmacenada;
$this->idPartidaxPregunta = $idPartidaxPregunta;
$this->idUsuario = $idUsuario;
$this->idRespuesta = $idRespuesta;
}
/**
* Guarda la respuesta que ha seleccionado un usuario en una pregunta de la partida.
*/
public function guardarRespuesta() {
$conexion = conexionBD();
if (is_array($conexion)) return $conexion;
try {
$sql = "INSERT INTO respuestaalmacenada (idPartidaxPregunta, idUsuario, idRespuesta)
VALUES (:idPartidaxPregunta, :idUsuario, :idRespuesta)";
$consulta = $conexion->prepare($sql);
$consulta->bindParam(':idPartidaxPregunta', $this->idPartidaxPregunta);
$consulta->bindParam(':idUsuario', $this->idUsuario);
$consulta->bindParam(':idRespuesta', $this->idRespuesta);
$consulta->execute();
return [
'exito' => 'Respuesta del usuario almacenada correctamente.',
'exito_tecnico' => $conexion->lastInsertId()
];
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al guardar la respuesta del jugador.',
'error_tecnico' => $error->getMessage()
];
}
}
/**
* Obtiene los aciertos totales de un usuario en una partida específica.
* Útil para calcular las estadísticas individuales al terminar el juego.
*/
public static function obtenerAciertosUsuarioEnPartida($idPartida, $idUsuario) {
$conexion = conexionBD();
if (is_array($conexion)) return $conexion;
try {
$sql = "SELECT COUNT(*) AS aciertos
FROM respuestaalmacenada ra
INNER JOIN partidaxpregunta pxp ON ra.idPartidaxPregunta = pxp.idPartidaxPregunta
INNER JOIN respuesta r ON ra.idRespuesta = r.idRespuesta
WHERE pxp.idPartida = :idPartida AND ra.idUsuario = :idUsuario AND r.correcta = 1";
$consulta = $conexion->prepare($sql);
$consulta->bindParam(':idPartida', $idPartida);
$consulta->bindParam(':idUsuario', $idUsuario);
$consulta->execute();
$resultado = $consulta->fetch(PDO::FETCH_ASSOC);
return (int)$resultado['aciertos'];
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al calcular los aciertos.',
'error_tecnico' => $error->getMessage()
];
}
}
}
+419
View File
@@ -0,0 +1,419 @@
<?php
require_once __DIR__ . '/../includes/conexionBD.php';
class Usuario
{
private ?int $idUsuario;
private string $nombreUsuario;
private string $contrasena;
private string $email;
private ?string $avatar;
private ?string $cookie;
private int $aciertos;
private int $victorias;
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,
?int $idUsuario = null
) {
$this->idUsuario = $idUsuario;
$this->nombreUsuario = $nombreUsuario;
$this->contrasena = $contrasena;
$this->email = $email;
$this->avatar = $avatar;
$this->cookie = $cookie;
$this->aciertos = $aciertos;
$this->victorias = $victorias;
$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 getContrasena(): string
{
return $this->contrasena;
}
public function setContrasena(string $contrasena): void
{
$this->contrasena = $contrasena;
}
public function getEmail(): string
{
return $this->email;
}
public function setEmail(string $email): void
{
$this->email = $email;
}
public function getAvatar(): ?string
{
return $this->avatar;
}
public function setAvatar(?string $avatar): void
{
$this->avatar = $avatar;
}
public function getCookie(): ?string
{
return $this->cookie;
}
public function setCookie(?string $cookie): void
{
$this->cookie = $cookie;
}
public function getAciertos(): int
{
return $this->aciertos;
}
public function setAciertos(int $aciertos): void
{
$this->aciertos = $aciertos;
}
public function getVictorias(): int
{
return $this->victorias;
}
public function setVictorias(int $victorias): void
{
$this->victorias = $victorias;
}
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)) {
return $conexion;
}
try {
$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([
':nombre' => $this->nombreUsuario,
':pass' => $passHash,
':email' => $this->email,
':avatar' => $this->avatar,
':cookie' => $this->cookie,
':aciertos' => $this->aciertos,
':victorias' => $this->victorias,
':derrotas' => $this->derrotas
]);
$this->idUsuario = (int)$conexion->lastInsertId();
return [
'exito' => 'Usuario registrado correctamente',
'exito_tecnico' => $this->idUsuario
];
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al registrar el usuario.',
'error_tecnico' => $error->getMessage()
];
}
}
public static function buscarPorId($id)
{
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$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'],
(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.',
'error_tecnico' => $error->getMessage()
];
}
}
public static function buscarPorEmail($email)
{
$conexion = conexionBD();
if (is_array($conexion)) {
return $conexion;
}
try {
$sql = "SELECT * FROM usuario WHERE email = :email";
$stmt = $conexion->prepare($sql);
$stmt->execute([':email' => $email]);
$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'],
(int)$datos['idUsuario']
);
}
return null; // No existe usuario con ese email
} catch (PDOException $error) {
return [
'error' => 'Ocurrió un error al buscar el usuario por email.',
'error_tecnico' => $error->getMessage()
];
}
}
public static function login($email, $contrasena)
{
$usuario = self::buscarPorEmail($email);
// El usuario no existe
if (!($usuario instanceof Usuario)) {
// Limpiamos posibles datos de sesión anteriores
unset($_SESSION['idUsuario']);
unset($_SESSION['email']);
unset($_SESSION['nombreUsuario']);
unset($_SESSION['avatar']);
return null;
}
// Comprobamos la contraseña
if (password_verify($contrasena, $usuario->getContrasena())) {
// Usuario validado correctamente
$_SESSION['idUsuario'] = $usuario->getIdUsuario();
$_SESSION['email'] = $usuario->getEmail();
$_SESSION['nombreUsuario'] = $usuario->getNombreUsuario();
$_SESSION['avatar'] = $usuario->getAvatar();
// Devolvemos el usuario como hasta ahora
return $usuario;
}
// Contraseña incorrecta
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 [];
}
}
}
+55
View File
@@ -0,0 +1,55 @@
<?php
session_start();
require_once '../clases/ClaseCategoria.php';
switch ($_POST['orden']) {
case 'crearCategoria':
$nombreCategoria = trim($_POST['nombreCategoria'] ?? '');
if ($nombreCategoria == '') {
echo json_encode(['error' => 'El nombre de la categoría es obligatorio']);
break;
}
$categoria = new Categoria(null, $nombreCategoria);
$resultado = $categoria->crear();
echo json_encode($resultado);
break;
case 'listarCategorias':
$categoria = new Categoria();
$resultado = $categoria->listar();
echo json_encode($resultado);
break;
case 'buscarCategoria':
$idCategoria = intval($_POST['idCategoria'] ?? 0);
$categoria = new Categoria($idCategoria);
$resultado = $categoria->buscar();
echo json_encode($resultado);
break;
case 'borrarCategoria':
$idCategoria = intval($_POST['idCategoria'] ?? 0);
$categoria = new Categoria($idCategoria);
$resultado = $categoria->borrar();
echo json_encode($resultado);
break;
}
+55
View File
@@ -0,0 +1,55 @@
<?php
session_start();
require_once '../clases/ClaseEquipo.php';
switch ($_POST['orden']) {
case 'crearEquipo':
$nombreEquipo = trim($_POST['nombreEquipo'] ?? '');
if ($nombreEquipo == '') {
echo json_encode(['error' => 'El nombre del equipo es obligatorio']);
break;
}
$equipo = new Equipo(null, $nombreEquipo);
$resultado = $equipo->crear();
echo json_encode($resultado);
break;
case 'listarEquipos':
$equipo = new Equipo();
$resultado = $equipo->listar();
echo json_encode($resultado);
break;
case 'buscarEquipo':
$idEquipo = intval($_POST['idEquipo'] ?? 0);
$equipo = new Equipo($idEquipo);
$resultado = $equipo->buscar();
echo json_encode($resultado);
break;
case 'borrarEquipo':
$idEquipo = intval($_POST['idEquipo'] ?? 0);
$equipo = new Equipo($idEquipo);
$resultado = $equipo->borrar();
echo json_encode($resultado);
break;
}
@@ -0,0 +1,90 @@
<?php
session_start();
require_once '../clases/ClaseEquipoxUsuario.php';
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);
if ($idEquipo <= 0) {
echo json_encode([
'error' => 'El ID del equipo proporcionado no es válido.'
]);
break;
}
$equipoxusuario = new EquipoxUsuario(
null,
$idUsuario,
$idEquipo
);
$resultado = $equipoxusuario->registrarUsuarioEnEquipo();
echo json_encode($resultado);
break;
case 'listarUsuariosPorEquipo':
$idEquipo = intval($_POST['idEquipo'] ?? 0);
if ($idEquipo <= 0) {
echo json_encode(['error' => 'ID de equipo no válido']);
break;
}
$equipoxusuario = new EquipoxUsuario();
$listado = $equipoxusuario->listarUsuariosPorEquipo($idEquipo);
//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;
}
File diff suppressed because it is too large Load Diff
+153
View File
@@ -0,0 +1,153 @@
<?php
session_start();
require_once '../clases/ClasePregunta.php';
require_once '../clases/ClaseRespuesta.php';
switch ($_POST['orden']) {
case 'crearPregunta':
$idCategoria = intval($_POST['idCategoria'] ?? 0);
$nombrePregunta = trim($_POST['nombrePregunta'] ?? '');
$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;
}
/*
* ==========================================
* 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);
$limite = intval($_POST['limite'] ?? 10);
$preguntas = Pregunta::obtenerPorCategoria($idCategoria, $limite);
// Si ha devuelto un array de errores (formato ['error'=>...]) lo mandamos tal cual
if (isset($preguntas['error'])) {
echo json_encode($preguntas);
break;
}
// Convertimos cada objeto Pregunta en un array simple para poder mandarlo en JSON
$listado = [];
foreach ($preguntas as $p) {
$listado[] = [
'idPregunta' => $p->getIdPregunta(),
'idCategoria' => $p->getIdCategoria(),
'nombrePregunta' => $p->getNombrePregunta(),
'respuestas' => $p->getRespuestas()
];
}
echo json_encode($listado);
break;
}
+71
View File
@@ -0,0 +1,71 @@
<?php
session_start();
require_once '../clases/ClaseRespuesta.php';
switch ($_POST['orden']) {
case 'crearRespuesta':
$idPregunta = intval($_POST['idPregunta'] ?? 0);
$nombreRespuesta = trim($_POST['nombreRespuesta'] ?? '');
$correcta = intval($_POST['correcta'] ?? 0);
if ($idPregunta <= 0 || $nombreRespuesta == '') {
echo json_encode(['error' => 'La pregunta y el texto de la respuesta son obligatorios']);
break;
}
$respuesta = new Respuesta(null, $idPregunta, $nombreRespuesta, $correcta);
$resultado = $respuesta->insertar();
echo json_encode($resultado);
break;
case 'listarRespuestas':
$respuesta = new Respuesta();
$resultado = $respuesta->listar();
echo json_encode($resultado);
break;
case 'listarRespuestasPorPregunta':
$idPregunta = intval($_POST['idPregunta'] ?? 0);
$respuesta = new Respuesta(null, $idPregunta);
$resultado = $respuesta->listarPorPregunta();
echo json_encode($resultado);
break;
case 'editarRespuesta':
$idRespuesta = intval($_POST['idRespuesta'] ?? 0);
$idPregunta = intval($_POST['idPregunta'] ?? 0);
$nombreRespuesta = trim($_POST['nombreRespuesta'] ?? '');
$correcta = intval($_POST['correcta'] ?? 0);
$respuesta = new Respuesta($idRespuesta, $idPregunta, $nombreRespuesta, $correcta);
$resultado = $respuesta->editar();
echo json_encode($resultado);
break;
case 'borrarRespuesta':
$idRespuesta = intval($_POST['idRespuesta'] ?? 0);
$respuesta = new Respuesta($idRespuesta);
$resultado = $respuesta->eliminar();
echo json_encode($resultado);
break;
}
@@ -0,0 +1,65 @@
<?php
session_start();
require_once '../clases/ClaseRespuestaAlmacenada.php';
switch ($_POST['orden']) {
case 'guardarRespuesta':
// Comprobamos que haya una sesión iniciada
if (isset($_SESSION['idUsuario'])) {
$respuestaAlmacenada = new RespuestaAlmacenada();
// Recogemos los datos de la respuesta
$respuestaAlmacenada->idPartidaxPregunta = $_POST['idPartidaxPregunta'];
$respuestaAlmacenada->idUsuario = $_SESSION['idUsuario'];
$respuestaAlmacenada->idRespuesta = $_POST['idRespuesta'];
// Guardamos la respuesta
$respuesta = $respuestaAlmacenada->guardarRespuesta();
} else {
$respuesta = [
'error' => 'No hay ninguna sesión iniciada.'
];
}
echo json_encode($respuesta);
break;
case 'obtenerAciertosUsuarioEnPartida':
// Comprobamos que haya una sesión iniciada
if (isset($_SESSION['idUsuario'])) {
$idPartida = $_POST['idPartida'];
$idUsuario = $_SESSION['idUsuario'];
// Obtenemos los aciertos del usuario en esa partida
$respuesta = RespuestaAlmacenada::obtenerAciertosUsuarioEnPartida(
$idPartida,
$idUsuario
);
} else {
$respuesta = [
'error' => 'No hay ninguna sesión iniciada.'
];
}
echo json_encode($respuesta);
break;
}//fin switch
?>
+252
View File
@@ -0,0 +1,252 @@
<?php
session_start();
require_once '../clases/ClaseUsuario.php';
switch ($_POST['orden']) {
case 'registrarUsuario':
$nombreUsuario = trim($_POST['nombreUsuario'] ?? '');
$email = trim($_POST['email'] ?? '');
$contrasena = $_POST['contrasena'] ?? '';
if ($nombreUsuario == '' || $email == '' || $contrasena == '') {
echo json_encode([
'error' => 'Todos los campos son obligatorios'
]);
break;
}
$usuarioExistente = Usuario::buscarPorEmail($email);
if ($usuarioExistente instanceof Usuario) {
echo json_encode([
'error' => 'Ya existe una cuenta con ese correo electrónico'
]);
break;
}
$usuario = new Usuario(
$nombreUsuario,
$contrasena,
$email,
'img/avatars/defaultProfile.jpeg'
);
$resultado = $usuario->registrar();
echo json_encode($resultado);
break;
case 'comprobarUsuario':
$email = trim($_POST['email'] ?? '');
$contrasena = $_POST['contrasena'] ?? '';
$resultado = Usuario::login($email, $contrasena);
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([
'exito' => 'Login correcto',
'idUsuario' => $resultado->getIdUsuario(),
'nombreUsuario' => $resultado->getNombreUsuario()
]);
} else {
echo json_encode([
'error' => 'Usuario o contraseña incorrectos'
]);
}
break;
case 'cerrarSesion':
// Limpiamos las variables de sesión
unset($_SESSION['idUsuario']);
unset($_SESSION['email']);
unset($_SESSION['nombreUsuario']);
// Destruimos la sesión
session_destroy();
echo json_encode([
'exito' => 'Sesión cerrada'
]);
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;
}
+66 -46
View File
@@ -5,44 +5,58 @@
--kahoot-yellow: #ffa602;
--kahoot-green: #26890c;
--kahoot-green-hover: #1f6f09;
}
}
body {
font-family: "Fredoka", sans-serif;
body {
font-family: 'Fredoka', sans-serif;
background-color: #f2f2f2;
min-height: 100vh;
}
}
.navbar-kahoot {
.navbar-kahoot {
background-color: var(--kahoot-purple);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
.navbar-brand {
.navbar-brand {
font-weight: 700;
font-size: 1.8rem;
color: #fff !important;
letter-spacing: 1px;
text-shadow: 2px 2px 0px rgba(0, 0, 0, 0.2);
}
}
.btn-kahoot-login {
.btn-kahoot-login {
background-color: var(--kahoot-blue);
color: white;
font-weight: 600;
border: none;
border-bottom: 4px solid #0c4891;
transition: all 0.2s ease;
}
}
.btn-kahoot-login:hover {
.btn-kahoot-login:hover {
background-color: #0f56ab;
color: white;
transform: translateY(-2px);
}
}
/* Estilos del Dropdown de usuario */
.user-dropdown-btn {
.btn-kahoot-register {
background-color: var(--kahoot-green);
color: white;
font-weight: 600;
border: none;
border-bottom: 4px solid var(--kahoot-green-hover);
transition: all 0.2s ease;
}
.btn-kahoot-register:hover {
background-color: #2bb00f;
color: white;
transform: translateY(-2px);
}
.user-dropdown-btn {
background: rgba(255, 255, 255, 0.15);
color: white;
border: 2px solid rgba(255, 255, 255, 0.3);
@@ -50,48 +64,48 @@ body {
padding: 8px 18px;
font-weight: 600;
transition: all 0.2s ease;
}
}
.user-dropdown-btn:hover,
.user-dropdown-btn:focus,
.user-dropdown-btn.show {
.user-dropdown-btn:hover,
.user-dropdown-btn:focus,
.user-dropdown-btn.show {
background: rgba(255, 255, 255, 0.3);
color: white;
border-color: #fff;
box-shadow: none;
}
}
.user-dropdown-menu {
.user-dropdown-menu {
border-radius: 15px;
border: none;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
box-shadow: 0 10px 25px rgba(0,0,0,0.2);
padding: 10px;
min-width: 200px;
margin-top: 10px !important;
}
}
.user-dropdown-menu .dropdown-item {
.user-dropdown-menu .dropdown-item {
border-radius: 10px;
font-weight: 600;
padding: 10px 15px;
transition: all 0.15s ease;
}
}
.user-dropdown-menu .dropdown-item:hover {
.user-dropdown-menu .dropdown-item:hover {
background-color: #f0eafb;
color: var(--kahoot-purple);
}
}
.user-dropdown-menu .dropdown-item.logout-item {
.user-dropdown-menu .dropdown-item.logout-item {
color: var(--kahoot-red);
}
}
.user-dropdown-menu .dropdown-item.logout-item:hover {
.user-dropdown-menu .dropdown-item.logout-item:hover {
background-color: #fde8ea;
color: var(--kahoot-red);
}
}
.btn-play-kahoot {
.btn-play-kahoot {
background-color: var(--kahoot-green);
color: white;
font-size: 2.2rem;
@@ -101,42 +115,48 @@ body {
border-radius: 20px;
border: none;
border-bottom: 8px solid var(--kahoot-green-hover);
box-shadow: 0 8px 15px rgba(0, 0, 0, 0.2);
box-shadow: 0 8px 15px rgba(0,0,0,0.2);
transition: all 0.1s ease;
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
}
}
.btn-play-kahoot:hover {
.btn-play-kahoot:hover {
background-color: #2bb00f;
color: white;
transform: translateY(-3px);
box-shadow: 0 12px 20px rgba(0, 0, 0, 0.25);
}
box-shadow: 0 12px 20px rgba(0,0,0,0.25);
}
.btn-play-kahoot:active {
.btn-play-kahoot:active {
transform: translateY(4px);
border-bottom: 2px solid var(--kahoot-green-hover);
}
}
.ranking-card {
.ranking-card {
border-radius: 20px;
border: none;
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
box-shadow: 0 8px 20px rgba(0,0,0,0.08);
overflow: hidden;
}
}
.ranking-header {
.ranking-header {
background-color: var(--kahoot-yellow);
color: #333;
padding: 15px 20px;
font-weight: 700;
}
}
.trophy-icon {
.trophy-icon {
font-size: 3rem;
color: var(--kahoot-yellow);
margin-bottom: 10px;
}
}
/* Estilos modales */
.modal-content {
border-radius: 20px;
overflow: hidden;
}
+119
View File
@@ -0,0 +1,119 @@
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background-color: #f2f2f2;
display: flex;
flex-direction: column;
height: 100vh;
justify-content: space-between;
padding: 20px;
}
/* Área de la Pregunta */
.question-container {
background-color: white;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
padding: 30px;
text-align: center;
font-size: 24px;
font-weight: bold;
color: #333;
margin-bottom: 20px;
flex-grow: 0;
}
/* Cuadrícula de Respuestas */
.answers-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 15px;
flex-grow: 1;
}
/* Botones de Respuesta Básicos */
.btn-answer {
border: none;
border-radius: 8px;
color: white;
font-size: 22px;
font-weight: bold;
display: flex;
align-items: center;
padding: 20px;
cursor: pointer;
transition: transform 0.1s ease, filter 0.1s ease;
box-shadow: 0 6px 0 rgba(0,0,0,0.2);
text-align: left;
}
.btn-answer:active {
transform: translateY(4px);
box-shadow: 0 2px 0 rgba(0,0,0,0.2);
}
/* Variaciones de Color y Formas */
.red {
background-color: #e21b3c;
}
.red:hover { filter: brightness(1.1); }
.blue {
background-color: #1368ce;
}
.blue:hover { filter: brightness(1.1); }
.yellow {
background-color: #d89e00;
}
.yellow:hover { filter: brightness(1.1); }
.green {
background-color: #26890c;
}
.green:hover { filter: brightness(1.1); }
/* Iconos Geométricos Simulados con CSS */
.shape {
display: inline-block;
width: 30px;
height: 30px;
margin-right: 20px;
flex-shrink: 0;
background-color: white;
}
.triangle {
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
.diamond {
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
}
.circle {
border-radius: 50%;
}
.square {
/* Por defecto es un cuadrado */
}
/* Adaptabilidad para Móviles */
@media (max-width: 768px) {
.answers-grid {
grid-template-columns: 1fr;
}
.question-container {
font-size: 20px;
padding: 20px;
}
.btn-answer {
font-size: 18px;
}
}
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

+29
View File
@@ -0,0 +1,29 @@
<?php
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 {
$dsn = "mysql:host=$servidor;port=$puerto;dbname=$bd;charset=utf8mb4";
$opciones = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
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()
];
}
}
?>
+14 -22
View File
@@ -1,39 +1,30 @@
<?php
session_start();
// Usuario logueado (CAMBIAR A NULL PARA CERRAR SESIÓN)
$_SESSION['usuario'] = "Alexis";
$isLoggedIn = isset($_SESSION['usuario']);
$username = $isLoggedIn ? $_SESSION['usuario'] : '';
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>
<link rel="icon" type="image/svg+xml" href="img/favicon/favicon.svg">
</head>
<body>
<div class="container my-5">
<?php include 'cabecera.php'; ?>
<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">
<!-- 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>
<?php endif; ?>
<!-- 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="ranking-header">
<h3 class="m-0"><i class="fa-solid fa-trophy me-2"></i> RANKING GLOBAL DE JUGADORES</h3>
@@ -50,10 +41,11 @@ include 'cabecera.php';
</div>
</div>
</div>
<!-- JS de Bootstrap -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</div>
<!-- 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>
+367 -66
View File
@@ -1,79 +1,380 @@
const btnCrearSala = document.getElementById("btnCrearSala");
let usuarioYaEstaEnEquipo = false;
const nombreSala = document.getElementById("nombreSala");
const nombreEquipo1 = document.getElementById("nombreEquipo1");
const nombreEquipo2 = document.getElementById("nombreEquipo2");
$(document).ready(function () {
comprobarSalaUsuario();
});
btnCrearSala.addEventListener("click", function () {
limpiarErrores();
// 1. Comprobar si el usuario actual ya pertenece a una sala
function comprobarSalaUsuario() {
$("#cargandoSalas").remove();
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;
$.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();
},
});
}
if (equipo1 === "") {
mostrarError(nombreEquipo1, "El nombre del equipo 1 es obligatorio.");
formularioValido = false;
// 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);
},
});
}
if (equipo2 === "") {
mostrarError(nombreEquipo2, "El nombre del equipo 2 es obligatorio.");
// 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();
formularioValido = false;
}
if (!formularioValido) {
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;
}
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;
});
function mostrarError(input, mensaje) {
input.classList.add("is-invalid");
// 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();
}
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) {
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();
});
+216
View File
@@ -0,0 +1,216 @@
$(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 activa.
*/
function comprobarEstadoSesion() {
$.ajax({
url: 'controladores/controladorUsuario.php',
type: 'POST',
dataType: 'json',
data: { orden: 'comprobarSesion' },
success: function (respuesta) {
if (respuesta.activa) {
renderizarCabeceraConSesion(respuesta.usuario);
// Si existe el contenedor del botón Jugar en index, lo mostramos
$('#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();
renderizarCabeceraConSesion({
idUsuario: respuesta.idUsuario,
nombreUsuario: respuesta.nombreUsuario,
avatar: respuesta.avatar
});
$('#colBotonJugar').removeClass('d-none');
}
},
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
$('#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 (Menú Perfil + Avatar)
*/
function renderizarCabeceraConSesion(usuario) {
let avatarImg = usuario.avatar ? usuario.avatar : 'img/avatars/defaultProfile.jpeg';
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="${avatarImg}" 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 originales:
* - "Iniciar Sesión" (Rojo -> btn-danger)
* - "Registrarse" (Verde -> btn-success)
*/
function renderizarCabeceraSinSesion() {
let html = `
<button class="btn btn-danger 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();
}
+2
View File
File diff suppressed because one or more lines are too long
+215 -36
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
// =========================
function cambiarNombre() {
let nuevoNombre = $("#nuevoNombre").val().trim();
const input = document.getElementById("nuevoNombre");
const nombre = document.getElementById("nombre");
$.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);
const nuevoNombre = input.value.trim();
if (nuevoNombre !== "") {
nombre.textContent = nuevoNombre;
input.value = "";
// Limpiamos el input
$("#nuevoNombre").val("");
}
});
}
// =========================
// BORRAR NOMBRE
// =========================
function borrarNombre() {
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/")) {
alert("El archivo seleccionado no es una imagen.");
alert("Por favor, selecciona una imagen.");
$("#inputFoto").val("");
return;
}
let datos = new FormData();
// Creamos una URL temporal
const imagenURL = URL.createObjectURL(archivo);
datos.append("avatar", archivo);
datos.append("orden", "cambiarAvatar");
$.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 sin recargar la página
$("#fotoPerfil").attr(
"src",
respuesta.avatar + "?t=" + new Date().getTime(),
);
}
});
});
// Cambiamos la foto
document.getElementById("fotoPerfil").src = imagenURL;
// =========================
// 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");
},
});
});
+46
View File
@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<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>
<!-- Contenedor de la Pregunta -->
<div class="question-container">
¿Cuál es el planeta más grande de nuestro sistema solar?
</div>
<!-- Contenedor de Respuestas (Estilo Kahoot) -->
<div class="answers-grid">
<button class="btn-answer red" onclick="checkAnswer('Marte')">
<span class="shape triangle"></span>
Marte
</button>
<button class="btn-answer blue" onclick="checkAnswer('Júpiter')">
<span class="shape diamond"></span>
Júpiter
</button>
<button class="btn-answer yellow" onclick="checkAnswer('Saturno')">
<span class="shape circle"></span>
Saturno
</button>
<button class="btn-answer green" onclick="checkAnswer('Tierra')">
<span class="shape square"></span>
Tierra
</button>
</div>
<script>
</script>
</body>
</html>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

+7 -10
View File
@@ -27,18 +27,17 @@ SET time_zone = "+00:00";
-- Table structure for table `preguntas`
--
CREATE TABLE `preguntas` (
CREATE TABLE `pregunta` (
`idPregunta` int NOT NULL,
`idDificultad` int DEFAULT NULL,
`idCategoria` int DEFAULT NULL,
`pregunta` varchar(200) DEFAULT NULL
`nombrePregunta` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
--
-- Dumping data for table `preguntas`
--
INSERT INTO `preguntas` (`idPregunta`, `idDificultad`, `idCategoria`, `pregunta`) VALUES
INSERT INTO `pregunta` (`idPregunta`, `idCategoria`, `nombrePregunta`) VALUES
(2140, 1, 4, '¿En qué año llegó Cristóbal Colón a América?'),
(2141, 1, 5, '¿Cuál es la capital de Francia?'),
(2142, 1, 6, '¿Qué planeta es conocido como el planeta rojo?'),
@@ -442,9 +441,8 @@ INSERT INTO `preguntas` (`idPregunta`, `idDificultad`, `idCategoria`, `pregunta`
--
-- Indexes for table `preguntas`
--
ALTER TABLE `preguntas`
ALTER TABLE `pregunta`
ADD PRIMARY KEY (`idPregunta`),
ADD KEY `idDificultad` (`idDificultad`),
ADD KEY `idCategoria` (`idCategoria`);
--
@@ -454,7 +452,7 @@ ALTER TABLE `preguntas`
--
-- AUTO_INCREMENT for table `preguntas`
--
ALTER TABLE `preguntas`
ALTER TABLE `pregunta`
MODIFY `idPregunta` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2535;
--
@@ -464,9 +462,8 @@ ALTER TABLE `preguntas`
--
-- Constraints for table `preguntas`
--
ALTER TABLE `preguntas`
ADD CONSTRAINT `preguntas_ibfk_1` FOREIGN KEY (`idDificultad`) REFERENCES `dificultades` (`idDificultad`),
ADD CONSTRAINT `preguntas_ibfk_2` FOREIGN KEY (`idCategoria`) REFERENCES `categorias` (`idCategoria`);
ALTER TABLE `pregunta`
ADD CONSTRAINT `preguntas_ibfk_2` FOREIGN KEY (`idCategoria`) REFERENCES `categoria` (`idCategoria`);
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+714
View File
@@ -0,0 +1,714 @@
/*M!999999\- enable the sandbox mode */
-- MariaDB dump 10.19-11.7.2-MariaDB, for Win64 (AMD64)
--
-- Host: localhost Database: triviagmatico
-- ------------------------------------------------------
-- Server version 10.4.32-MariaDB
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */;
--
-- Table structure for table `categoria`
--
DROP TABLE IF EXISTS `categoria`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `categoria` (
`idCategoria` int(11) NOT NULL AUTO_INCREMENT,
`nombreCategoria` varchar(50) NOT NULL,
PRIMARY KEY (`idCategoria`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `categoria`
--
LOCK TABLES `categoria` WRITE;
/*!40000 ALTER TABLE `categoria` DISABLE KEYS */;
INSERT INTO `categoria` VALUES
(4,'Historia'),
(5,'Geografía'),
(6,'Ciencia'),
(7,'Arte'),
(8,'Literatura'),
(9,'Deportes'),
(10,'Astronomía'),
(11,'Naturaleza'),
(12,'Cine'),
(13,'Música'),
(14,'Tecnología'),
(15,'Cultura'),
(16,'Gastronomía');
/*!40000 ALTER TABLE `categoria` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `equipo`
--
DROP TABLE IF EXISTS `equipo`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `equipo` (
`idEquipo` int(11) NOT NULL AUTO_INCREMENT,
`nombreEquipo` varchar(50) NOT NULL,
PRIMARY KEY (`idEquipo`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `equipo`
--
LOCK TABLES `equipo` WRITE;
/*!40000 ALTER TABLE `equipo` DISABLE KEYS */;
/*!40000 ALTER TABLE `equipo` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `equipoxpartida`
--
DROP TABLE IF EXISTS `equipoxpartida`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `equipoxpartida` (
`idEquipoxPartida` int(11) NOT NULL AUTO_INCREMENT,
`idPartida` int(11) DEFAULT NULL,
`idEquipo` int(11) DEFAULT NULL,
PRIMARY KEY (`idEquipoxPartida`),
KEY `FK idEquipo tabla equipo` (`idEquipo`),
KEY `FK idPartida tabla partida` (`idPartida`),
CONSTRAINT `FK idEquipo tabla equipo` FOREIGN KEY (`idEquipo`) REFERENCES `equipo` (`idEquipo`),
CONSTRAINT `FK idPartida tabla partida` FOREIGN KEY (`idPartida`) REFERENCES `partida` (`idPartida`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `equipoxpartida`
--
LOCK TABLES `equipoxpartida` WRITE;
/*!40000 ALTER TABLE `equipoxpartida` DISABLE KEYS */;
/*!40000 ALTER TABLE `equipoxpartida` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `equipoxusuario`
--
DROP TABLE IF EXISTS `equipoxusuario`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `equipoxusuario` (
`idEquipoxUsuario` int(11) NOT NULL AUTO_INCREMENT,
`idUsuario` int(11) NOT NULL,
`idEquipo` int(11) NOT NULL,
PRIMARY KEY (`idEquipoxUsuario`),
KEY `idUsuario` (`idUsuario`),
KEY `idEquipo` (`idEquipo`),
CONSTRAINT `equipoxusuario_ibfk_1` FOREIGN KEY (`idUsuario`) REFERENCES `usuario` (`idUsuario`),
CONSTRAINT `equipoxusuario_ibfk_2` FOREIGN KEY (`idEquipo`) REFERENCES `equipo` (`idEquipo`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `equipoxusuario`
--
LOCK TABLES `equipoxusuario` WRITE;
/*!40000 ALTER TABLE `equipoxusuario` DISABLE KEYS */;
/*!40000 ALTER TABLE `equipoxusuario` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `partida`
--
DROP TABLE IF EXISTS `partida`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `partida` (
`idPartida` int(11) NOT NULL AUTO_INCREMENT,
`nombrePartida` varchar(100) NOT NULL,
`idUsuario` int(11) NOT NULL,
PRIMARY KEY (`idPartida`),
KEY `FK idUsuario tabla usuario` (`idUsuario`),
CONSTRAINT `FK idUsuario tabla usuario` FOREIGN KEY (`idUsuario`) REFERENCES `usuario` (`idUsuario`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `partida`
--
LOCK TABLES `partida` WRITE;
/*!40000 ALTER TABLE `partida` DISABLE KEYS */;
/*!40000 ALTER TABLE `partida` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `partidaxpregunta`
--
DROP TABLE IF EXISTS `partidaxpregunta`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `partidaxpregunta` (
`idPartidaxPregunta` int(11) NOT NULL AUTO_INCREMENT,
`idPartida` int(11) NOT NULL,
`idPregunta` int(11) NOT NULL,
PRIMARY KEY (`idPartidaxPregunta`),
KEY `idPartida` (`idPartida`),
KEY `idPregunta` (`idPregunta`),
CONSTRAINT `partidaxpregunta_ibfk_1` FOREIGN KEY (`idPartida`) REFERENCES `partida` (`idPartida`),
CONSTRAINT `partidaxpregunta_ibfk_2` FOREIGN KEY (`idPregunta`) REFERENCES `pregunta` (`idPregunta`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `partidaxpregunta`
--
LOCK TABLES `partidaxpregunta` WRITE;
/*!40000 ALTER TABLE `partidaxpregunta` DISABLE KEYS */;
/*!40000 ALTER TABLE `partidaxpregunta` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `pregunta`
--
DROP TABLE IF EXISTS `pregunta`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `pregunta` (
`idPregunta` int(11) NOT NULL AUTO_INCREMENT,
`idCategoria` int(11) NOT NULL,
`nombrePregunta` varchar(255) NOT NULL,
PRIMARY KEY (`idPregunta`),
KEY `idCategoria` (`idCategoria`),
CONSTRAINT `pregunta_ibfk_1` FOREIGN KEY (`idCategoria`) REFERENCES `categoria` (`idCategoria`)
) ENGINE=InnoDB AUTO_INCREMENT=2535 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `pregunta`
--
LOCK TABLES `pregunta` WRITE;
/*!40000 ALTER TABLE `pregunta` DISABLE KEYS */;
INSERT INTO `pregunta` VALUES
(2140,4,'¿En qué año llegó Cristóbal Colón a América?'),
(2141,5,'¿Cuál es la capital de Francia?'),
(2142,6,'¿Qué planeta es conocido como el planeta rojo?'),
(2143,7,'¿Quién pintó la Mona Lisa?'),
(2144,5,'¿Cuál es el océano más grande del planeta?'),
(2145,6,'¿Cuál es el símbolo químico del oro?'),
(2146,8,'¿Quién escribió Don Quijote de la Mancha?'),
(2147,9,'¿Cuántos jugadores tiene un equipo de fútbol en el campo?'),
(2148,10,'¿Cuál es la estrella más cercana a la Tierra?'),
(2149,11,'¿Cuál es el animal terrestre más grande?'),
(2150,4,'¿Quién fue el primer emperador romano?'),
(2151,5,'¿Cuál es la capital de España?'),
(2152,6,'¿Qué gas es imprescindible para la respiración humana?'),
(2153,12,'¿Cómo se llama el protagonista de la saga cinematográfica Indiana Jones?'),
(2154,13,'¿Qué instrumento musical tiene teclas blancas y negras?'),
(2155,5,'¿Cuál es la montaña más alta del mundo?'),
(2156,4,'¿Qué civilización construyó las pirámides de Egipto?'),
(2157,6,'¿Cuál es la fórmula química del agua?'),
(2158,8,'¿Quién escribió Cien años de soledad?'),
(2159,9,'¿Cada cuántos años se celebran los Juegos Olímpicos?'),
(2160,14,'¿Qué significan las siglas CPU?'),
(2161,10,'¿Cuántos planetas tiene actualmente el sistema solar?'),
(2162,11,'¿Cuál es el animal más grande del planeta?'),
(2163,7,'¿Qué movimiento artístico fue desarrollado por Picasso y Braque?'),
(2164,15,'¿Cuántos días tiene un año bisiesto?'),
(2165,5,'¿Cuál es el país más grande del mundo por superficie?'),
(2166,4,'¿Quién fue conocido como el Libertador de gran parte de Sudamérica?'),
(2167,6,'¿Cuál es la unidad básica de la vida?'),
(2168,13,'¿Quién compuso la Novena Sinfonía?'),
(2169,9,'¿En qué deporte se utiliza una raqueta y una pelota amarilla?'),
(2170,4,'¿Qué muro cayó en 1989 simbolizando el fin de la Guerra Fría?'),
(2171,5,'¿Cuál es la capital de Japón?'),
(2172,6,'¿Qué órgano humano se encarga principalmente de bombear la sangre?'),
(2173,8,'¿Quién escribió Romeo y Julieta?'),
(2174,12,'¿Qué película incluye al personaje Darth Vader?'),
(2175,5,'¿Cuál es la capital de Italia?'),
(2176,6,'¿Qué fuerza mantiene a los planetas orbitando alrededor del Sol?'),
(2177,4,'¿Qué imperio construyó Machu Picchu?'),
(2178,11,'¿Cuál es el felino más grande del mundo?'),
(2179,14,'¿Qué dispositivo se utiliza para mover el cursor en un ordenador?'),
(2180,10,'¿Cuál es el planeta más grande del sistema solar?'),
(2181,13,'¿Qué cantante es conocido como el Rey del Pop?'),
(2182,9,'¿En qué deporte destacó Michael Jordan?'),
(2183,8,'¿Quién escribió La Odisea?'),
(2184,7,'¿Quién pintó La noche estrellada?'),
(2185,5,'¿En qué continente se encuentra Egipto?'),
(2186,6,'¿Qué científico formuló la teoría de la relatividad?'),
(2187,4,'¿Dónde nació la democracia antigua?'),
(2188,16,'¿Cuál es el ingrediente principal del guacamole?'),
(2189,15,'¿Cuántos continentes se reconocen habitualmente?'),
(2190,4,'¿En qué país se encuentra la ciudad antigua de Petra?'),
(2191,5,'¿Cuál es la capital de Portugal?'),
(2192,6,'¿Qué parte de la planta realiza principalmente la fotosíntesis?'),
(2193,12,'¿Quién dirigió la película Titanic?'),
(2194,13,'¿Qué grupo británico lanzó la canción Bohemian Rhapsody?'),
(2195,9,'¿En qué deporte se disputa el torneo de Wimbledon?'),
(2196,14,'¿Qué lenguaje se utiliza principalmente para estructurar páginas web?'),
(2197,10,'¿Cómo se llama nuestra galaxia?'),
(2198,11,'¿Cuál es el animal terrestre más rápido?'),
(2199,16,'¿De qué país es originaria la pizza moderna?'),
(2200,4,'¿Quién fue el primer presidente de Estados Unidos?'),
(2201,5,'¿Cuál es el desierto cálido más grande del mundo?'),
(2202,6,'¿Qué científico propuso las leyes del movimiento y la gravitación universal?'),
(2203,8,'¿Quién escribió El principito?'),
(2204,7,'¿Qué artista pintó los frescos de la Capilla Sixtina?'),
(2205,5,'¿Cuál es la capital de Alemania?'),
(2206,6,'¿Qué vitamina produce principalmente el cuerpo con la exposición al sol?'),
(2207,4,'¿Qué civilización desarrolló un calendario muy avanzado en Mesoamérica?'),
(2208,12,'¿Qué personaje vive en una piña bajo el mar?'),
(2209,13,'¿Qué instrumento toca normalmente un baterista?'),
(2210,9,'¿En qué país nació el fútbol moderno?'),
(2211,14,'¿Qué empresa creó el sistema operativo Windows?'),
(2212,10,'¿Qué planeta es famoso por sus anillos?'),
(2213,11,'¿Qué animal es conocido como el rey de la selva?'),
(2214,16,'¿Cuál es el ingrediente principal del sushi tradicional?'),
(2215,4,'¿Quién fue Napoleón Bonaparte?'),
(2216,5,'¿Cuál es la capital de Argentina?'),
(2217,6,'¿Qué elemento químico tiene el símbolo Fe?'),
(2218,8,'¿Quién escribió La metamorfosis?'),
(2219,7,'¿Qué artista español creó el personaje Don Quijote en ilustraciones famosas?'),
(2220,5,'¿Cuál es la capital de Canadá?'),
(2221,6,'¿Qué órgano del cuerpo humano permite respirar?'),
(2222,4,'¿Qué famoso faraón fue enterrado en una tumba encontrada casi intacta en 1922?'),
(2223,12,'¿Cómo se llama el ogro protagonista de una famosa saga de películas de animación?'),
(2224,13,'¿Qué compositor creó la ópera La flauta mágica?'),
(2225,9,'¿Cuántos puntos vale un triple en baloncesto?'),
(2226,14,'¿Qué significa la sigla WWW?'),
(2227,10,'¿Cuál es el planeta más cercano al Sol?'),
(2228,11,'¿Qué animal produce lana?'),
(2229,16,'¿Cuál es el ingrediente principal del hummus?'),
(2230,4,'¿Qué pueblo antiguo creó la democracia ateniense?'),
(2231,5,'¿Cuál es la capital de México?'),
(2232,6,'¿Qué científico desarrolló la teoría de la evolución por selección natural?'),
(2233,8,'¿Quién escribió Los viajes de Gulliver?'),
(2234,7,'¿Qué pintor español creó el cuadro Guernica?'),
(2235,5,'¿Cuál es la isla más grande del mundo?'),
(2236,6,'¿Cuántos huesos tiene aproximadamente un adulto?'),
(2237,4,'¿Quién fue Julio César?'),
(2238,12,'¿Qué actor interpretó a Jack en Titanic?'),
(2239,13,'¿Qué grupo musical formaron John Lennon y Paul McCartney?'),
(2240,5,'¿Cuál es la capital de Brasil?'),
(2241,6,'¿Qué parte del átomo tiene carga negativa?'),
(2242,4,'¿En qué país surgió la Revolución Industrial?'),
(2243,12,'¿Cómo se llama el ratón protagonista de Disney?'),
(2244,13,'¿Qué cantante española es conocida por la canción Despechá?'),
(2245,9,'¿Cuántos jugadores forman un equipo de baloncesto en pista?'),
(2246,14,'¿Qué empresa desarrolló el buscador Google?'),
(2247,10,'¿Cómo se llama el satélite natural de la Tierra?'),
(2248,11,'¿Qué animal es conocido por cambiar de color?'),
(2249,16,'¿Qué bebida se obtiene principalmente de la fermentación de la uva?'),
(2250,4,'¿Qué reina egipcia tuvo relación con Julio César y Marco Antonio?'),
(2251,5,'¿Cuál es la capital de Grecia?'),
(2252,6,'¿Qué científico descubrió la radiactividad junto con Pierre Curie?'),
(2253,8,'¿Quién escribió La Divina Comedia?'),
(2254,7,'¿Qué artista español creó el surrealismo con obras como La persistencia de la memoria?'),
(2255,5,'¿Cuál es el río que atraviesa Egipto?'),
(2256,6,'¿Qué planeta habitamos los seres humanos?'),
(2257,4,'¿Qué guerra enfrentó principalmente a Atenas y Esparta?'),
(2258,14,'¿Qué significa la sigla USB?'),
(2259,9,'¿En qué deporte se utiliza una portería y un balón con las manos?'),
(2260,5,'¿Cuál es la capital de Australia?'),
(2261,6,'¿Qué sangre circula por las arterias desde el corazón hacia el cuerpo?'),
(2262,4,'¿Qué pueblo construyó el Coliseo de Roma?'),
(2263,12,'¿Qué película cuenta la historia de un barco que choca contra un iceberg?'),
(2264,13,'¿Qué instrumento tiene seis cuerdas normalmente?'),
(2265,9,'¿En qué deporte se utiliza un bate y una pelota?'),
(2266,14,'¿Qué empresa creó el iPhone?'),
(2267,10,'¿Qué fenómeno ocurre cuando la Luna se interpone entre la Tierra y el Sol?'),
(2268,11,'¿Qué animal es conocido por tener una trompa larga?'),
(2269,16,'¿Cuál es el ingrediente principal de las tortillas mexicanas tradicionales?'),
(2270,4,'¿Qué explorador llegó a América en 1492?'),
(2271,5,'¿Cuál es la capital de Francia?'),
(2272,6,'¿Qué científico descubrió la penicilina?'),
(2273,8,'¿Quién escribió El Quijote?'),
(2274,7,'¿Qué material utiliza principalmente un escultor que trabaja con mármol?'),
(2275,5,'¿Cuál es el río más largo del mundo según muchas mediciones?'),
(2276,6,'¿Qué sentido permite percibir los sonidos?'),
(2277,4,'¿Qué civilización construyó las ciudades de Tikal y Palenque?'),
(2278,12,'¿Qué director creó la trilogía de El Señor de los Anillos en cine?'),
(2279,13,'¿Qué instrumento pertenece a la familia de viento?'),
(2280,9,'¿Qué país ganó el Mundial de fútbol de 2022?'),
(2281,14,'¿Qué dispositivo permite realizar llamadas y conectarse a internet?'),
(2282,10,'¿Qué nombre recibe el conjunto formado por una estrella y los cuerpos que orbitan a su alrededor?'),
(2283,11,'¿Cuál es el árbol que produce bellotas?'),
(2284,16,'¿Cuál es el ingrediente principal del gazpacho tradicional?'),
(2285,4,'¿Qué antigua ciudad fue sepultada por el volcán Vesubio?'),
(2286,5,'¿En qué continente está España?'),
(2287,6,'¿Qué parte del cerebro coordina principalmente el equilibrio?'),
(2288,8,'¿Qué personaje literario vive en una casa de Baker Street?'),
(2289,7,'¿Qué arquitecto diseñó la Sagrada Familia de Barcelona?'),
(2290,5,'¿Cuál es el país más poblado del mundo actualmente?'),
(2291,6,'¿Qué gas absorben las plantas durante la fotosíntesis?'),
(2292,4,'¿Quién fue conocido como el Gran Alejandro?'),
(2293,12,'¿Qué superhéroe tiene como identidad a Bruce Wayne?'),
(2294,13,'¿Qué compositor perdió la audición al final de su vida?'),
(2295,9,'¿Cuántos anillos tiene el símbolo olímpico?'),
(2296,14,'¿Qué empresa creó el sistema operativo Android?'),
(2297,10,'¿Qué estrella está en el centro del sistema solar?'),
(2298,11,'¿Qué mamífero es capaz de volar?'),
(2299,16,'¿Qué fruta se utiliza para hacer aceite de oliva?'),
(2300,4,'¿Qué tratado puso fin oficialmente a la Primera Guerra Mundial?'),
(2301,5,'¿Cuál es la capital de Turquía?'),
(2302,6,'¿Qué parte de la célula contiene el material genético?'),
(2303,8,'¿Quién escribió Frankenstein?'),
(2304,12,'¿Qué personaje dice la frase \'Hasta la vista, baby\'?'),
(2305,13,'¿Qué compositor creó Las cuatro estaciones?'),
(2306,9,'¿En qué deporte se utiliza un volante o pluma?'),
(2307,14,'¿Qué significa la sigla IA?'),
(2308,10,'¿Cómo se llama la explosión final de una estrella masiva?'),
(2309,11,'¿Qué animal es famoso por construir presas?'),
(2310,16,'¿Qué país es famoso por el plato llamado paella?'),
(2311,4,'¿Qué civilización utilizaba jeroglíficos?'),
(2312,5,'¿Cuál es la capital de Italia?'),
(2313,6,'¿Qué instrumento se utiliza para medir la temperatura?'),
(2314,8,'¿Quién creó al personaje de Harry Potter?'),
(2315,7,'¿Qué estilo artístico predominó en muchas catedrales medievales?'),
(2316,5,'¿Cuál es la montaña más alta de África?'),
(2317,6,'¿Cuántos sentidos tradicionales tiene el ser humano?'),
(2318,4,'¿Quién fue conocido como el rey del Imperio francés?'),
(2319,12,'¿Qué personaje es un ogro verde?'),
(2320,13,'¿Qué cantante es conocido como el Rey del Rock and Roll?'),
(2321,9,'¿Cuántos jugadores tiene un equipo de fútbol en el campo?'),
(2322,14,'¿Qué aparato se usa para imprimir documentos?'),
(2323,10,'¿Qué es un cometa?'),
(2324,11,'¿Cuál es el animal terrestre más grande?'),
(2325,16,'¿Qué país es famoso por el sushi?'),
(2326,4,'¿Qué muro cayó en 1989 simbolizando el fin de la Guerra Fría?'),
(2327,5,'¿Cuál es la capital de Japón?'),
(2328,6,'¿Qué científico formuló la teoría de la evolución?'),
(2329,8,'¿Quién escribió Romeo y Julieta?'),
(2330,7,'¿Qué pintor creó la Mona Lisa?'),
(2331,5,'¿Cuál es el océano más grande del planeta?'),
(2332,6,'¿Qué planeta es conocido como el planeta rojo?'),
(2333,4,'¿Qué civilización construyó las pirámides de Guiza?'),
(2334,12,'¿Qué película de animación tiene personajes llamados Woody y Buzz Lightyear?'),
(2335,13,'¿Qué instrumento tiene teclas blancas y negras?'),
(2336,9,'¿En qué deporte destacó Rafael Nadal?'),
(2337,14,'¿Qué red conecta ordenadores a nivel mundial?'),
(2338,10,'¿Qué instrumento permite observar objetos lejanos en el espacio?'),
(2339,11,'¿Qué ave no puede volar y vive en la Antártida?'),
(2340,16,'¿Qué ingrediente se obtiene de la leche y se usa en muchos postres?'),
(2341,4,'¿Quién fue el primer ser humano en pisar la Luna?'),
(2342,5,'¿Cuál es la capital de Rusia?'),
(2343,6,'¿Qué científico es considerado el padre de la física moderna?'),
(2344,8,'¿Qué detective fue creado por Arthur Conan Doyle?'),
(2345,7,'¿Qué movimiento artístico inició Pablo Picasso junto con Braque?'),
(2346,5,'¿Cuál es el país más grande del mundo por superficie?'),
(2347,6,'¿Qué órgano bombea la sangre por el cuerpo?'),
(2348,4,'¿Qué antigua ciudad griega fue famosa por sus guerreros?'),
(2349,12,'¿Qué saga cinematográfica incluye al personaje Darth Vader?'),
(2350,13,'¿Qué cantante interpretó la canción Thriller?'),
(2351,9,'¿Qué país ganó el Mundial de fútbol de 2010?'),
(2352,14,'¿Qué aparato convierte documentos físicos en archivos digitales?'),
(2353,10,'¿Cómo se llama la galaxia vecina más cercana a la Vía Láctea?'),
(2354,11,'¿Qué insecto produce miel?'),
(2355,16,'¿Qué especia es conocida como azafrán?'),
(2356,4,'¿Qué imperio tuvo su capital en Constantinopla?'),
(2357,5,'¿Cuál es la capital de Egipto?'),
(2358,6,'¿Qué unidad se utiliza para medir la fuerza?'),
(2359,8,'¿Qué escritor creó a Don Quijote de la Mancha?'),
(2360,7,'¿Qué color se obtiene al mezclar azul y amarillo?'),
(2361,5,'¿Cuál es la capital de Noruega?'),
(2362,6,'¿Cuál es el símbolo químico del oro?'),
(2363,4,'¿Qué faraón ordenó construir una de las mayores pirámides de Guiza?'),
(2364,12,'¿Qué actor interpretó a Iron Man en el Universo Marvel?'),
(2365,13,'¿Qué banda lanzó el álbum The Dark Side of the Moon?'),
(2366,9,'¿En qué deporte se utiliza una raqueta y una pelota amarilla?'),
(2367,14,'¿Qué significa la sigla CPU?'),
(2368,10,'¿Qué planeta tiene la Gran Mancha Roja?'),
(2369,11,'¿Cuál es el animal terrestre más alto?'),
(2370,16,'¿Qué bebida se prepara con granos tostados y molidos?'),
(2371,4,'¿Quién fue conocido como el Libertador de varios países sudamericanos?'),
(2372,5,'¿Cuál es la capital de Irlanda?'),
(2373,6,'¿Qué planeta está más cerca de la Tierra?'),
(2374,8,'¿Quién escribió La isla del tesoro?'),
(2375,7,'¿Qué artista pintó Las meninas?'),
(2376,5,'¿Qué país tiene forma alargada en la costa oeste de Sudamérica?'),
(2377,6,'¿Qué vitamina se asocia con los cítricos como la naranja?'),
(2378,4,'¿Qué acontecimiento comenzó en 1939?'),
(2379,12,'¿Cómo se llama el león protagonista de El Rey León?'),
(2380,13,'¿Qué instrumento toca un violinista?'),
(2381,9,'¿Qué piloto español ganó varios campeonatos de Fórmula 1?'),
(2382,14,'¿Qué empresa creó la consola PlayStation?'),
(2383,10,'¿Cuántos planetas tiene el sistema solar?'),
(2384,11,'¿Qué animal es conocido por su gran inteligencia marina?'),
(2385,16,'¿De qué país procede tradicionalmente el curry?'),
(2386,4,'¿Qué reina española apoyó el viaje de Colón?'),
(2387,5,'¿Cuál es la capital de España?'),
(2388,6,'¿Qué instrumento permite ver objetos muy pequeños?'),
(2389,8,'¿Quién escribió 20.000 leguas de viaje submarino?'),
(2390,5,'¿Cuál es la capital de Canadá?'),
(2391,6,'¿Qué planeta es famoso por sus anillos?'),
(2392,4,'¿Quién fue el primer emperador romano?'),
(2393,12,'¿Qué película ganó el Óscar a mejor película en 1998 y trata sobre un barco hundido?'),
(2394,13,'¿Cuántas notas musicales básicas hay en la escala occidental?'),
(2395,9,'¿En qué deporte destacó Michael Jordan?'),
(2396,14,'¿Qué empresa creó Windows?'),
(2397,10,'¿Qué planeta tarda aproximadamente 365 días en dar una vuelta al Sol?'),
(2398,11,'¿Qué animal es conocido como el rey de la selva?'),
(2399,16,'¿Qué ingrediente principal lleva el hummus tradicional?'),
(2400,4,'¿Qué revolución comenzó en Francia en 1789?'),
(2401,5,'¿Cuál es la capital de Portugal?'),
(2402,6,'¿Qué científico formuló las leyes del movimiento y la gravedad?'),
(2403,8,'¿Quién escribió El principito?'),
(2404,7,'¿Qué escultor creó el David de Florencia?'),
(2405,5,'¿En qué continente está Brasil?'),
(2406,6,'¿Qué gas necesitamos para respirar?'),
(2407,4,'¿Qué pueblo creó Machu Picchu?'),
(2408,12,'¿Qué saga tiene como protagonista a Harry Potter?'),
(2409,13,'¿Qué grupo británico cantaba Bohemian Rhapsody?'),
(2410,9,'¿Qué país organizó los Juegos Olímpicos de 1992?'),
(2411,14,'¿Qué lenguaje se utiliza habitualmente para crear páginas web junto con CSS y JavaScript?'),
(2412,10,'¿Qué nombre recibe una agrupación de estrellas que forma una figura aparente?'),
(2413,11,'¿Cuál es el animal terrestre más rápido?'),
(2414,16,'¿De qué país es originaria la pizza tradicional?'),
(2415,4,'¿Qué civilización inventó la democracia en Atenas?'),
(2416,5,'¿Cuál es la capital de Alemania?'),
(2417,6,'¿Cuál es la fórmula química del agua?'),
(2418,8,'¿Quién escribió 1984?'),
(2419,7,'¿En qué museo se encuentra la Mona Lisa?'),
(2420,12,'¿Cómo se llama el muñeco vaquero de Toy Story?'),
(2421,13,'¿Qué cantante fue conocido como el Rey del Pop?'),
(2422,9,'¿Cuánto dura un partido de fútbol profesional normalmente?'),
(2423,14,'¿Qué dispositivo se utiliza para mover el cursor del ordenador?'),
(2424,10,'¿Qué planeta es el más grande del sistema solar?'),
(2425,11,'¿Qué animal tiene rayas negras y blancas?'),
(2426,16,'¿Qué alimento producen las abejas?'),
(2427,4,'¿Quién fue el líder sudafricano que luchó contra el apartheid?'),
(2428,5,'¿Cuál es la montaña más alta del mundo?'),
(2429,6,'¿Qué órgano utilizamos principalmente para ver?'),
(2430,8,'¿Quién escribió La metamorfosis?'),
(2431,7,'¿Qué pintor español creó el cuadro Guernica?'),
(2432,5,'¿Cuál es la capital de Australia?'),
(2433,6,'¿Qué científico desarrolló la teoría de la relatividad?'),
(2434,4,'¿Qué explorador llegó a América en 1492?'),
(2435,12,'¿Cómo se llama el ogro protagonista de una famosa saga de animación?'),
(2436,13,'¿Qué compositor creó la Novena Sinfonía?'),
(2437,9,'¿En qué deporte se disputa el Tour de Francia?'),
(2438,14,'¿Qué empresa desarrolló el buscador Google?'),
(2439,10,'¿Qué cuerpo celeste orbita alrededor de la Tierra?'),
(2440,11,'¿Cuál es el animal más grande conocido actualmente?'),
(2441,16,'¿Qué plato español está hecho principalmente con arroz?'),
(2442,4,'¿Qué imperio construyó una gran red de carreteras en América del Sur?'),
(2443,5,'¿Cuál es la capital de Francia?'),
(2444,6,'¿Qué fuerza mantiene a los planetas orbitando alrededor del Sol?'),
(2445,8,'¿Quién escribió El señor de los anillos?'),
(2446,7,'¿Qué movimiento artístico está asociado con Salvador Dalí?'),
(2447,12,'¿Qué director creó la película E.T.?'),
(2448,13,'¿Qué instrumento suele tener seis cuerdas?'),
(2449,9,'¿Qué país inventó el judo?'),
(2450,14,'¿Qué dispositivo almacena archivos digitales?'),
(2451,10,'¿Qué planeta está más alejado del Sol?'),
(2452,11,'¿Qué árbol produce piñas?'),
(2453,16,'¿Qué fruta amarilla es rica en potasio?'),
(2454,4,'¿Qué ciudad fue conocida como la capital del Imperio romano?'),
(2455,5,'¿Cuál es el río más largo del mundo según muchas mediciones modernas?'),
(2456,6,'¿Qué científico descubrió la penicilina?'),
(2457,8,'¿Qué personaje vive aventuras junto a Sancho Panza?'),
(2458,7,'¿Qué edificio famoso diseñó Gaudí en Barcelona?'),
(2459,12,'¿Qué superhéroe lleva un escudo con una estrella?'),
(2460,13,'¿Qué instrumento toca normalmente un pianista?'),
(2461,9,'¿Cuántos jugadores forman un equipo de baloncesto en pista?'),
(2462,14,'¿Qué significa la sigla USB?'),
(2463,10,'¿Qué fenómeno ocurre cuando la Luna se interpone entre la Tierra y el Sol?'),
(2464,11,'¿Qué animal es conocido por cambiar de color para camuflarse?'),
(2465,16,'¿Cuál es el ingrediente principal del guacamole?'),
(2466,4,'¿Qué civilización construyó el Coliseo de Roma?'),
(2467,5,'¿Cuál es la capital de Italia?'),
(2468,6,'¿Qué elemento químico tiene el símbolo Fe?'),
(2469,8,'¿Qué escritor creó al personaje Sherlock Holmes?'),
(2470,7,'¿Qué famoso museo está situado en Madrid y alberga obras de Velázquez y Goya?'),
(2471,12,'¿Qué película de ciencia ficción presenta al personaje Neo?'),
(2472,13,'¿Qué banda británica estaba formada por John Lennon, Paul McCartney, George Harrison y Ringo Starr?'),
(2473,9,'¿Qué deporte practica un nadador?'),
(2474,14,'¿Qué empresa creó el iPhone?'),
(2475,10,'¿Cómo se llama nuestra galaxia?'),
(2476,11,'¿Qué animal doméstico suele llamarse el mejor amigo del hombre?'),
(2477,16,'¿Qué bebida se obtiene de las hojas del té?'),
(2478,4,'¿Qué líder impulsó la independencia de la India mediante la resistencia no violenta?'),
(2479,5,'¿Qué país tiene como capital Buenos Aires?'),
(2480,6,'¿Qué parte de la planta absorbe agua del suelo?'),
(2481,4,'¿Quién fue el emperador francés conocido por sus conquistas en Europa?'),
(2482,5,'¿Cuál es el desierto cálido más grande del mundo?'),
(2483,6,'¿Qué científico propuso la teoría de la evolución por selección natural?'),
(2484,8,'¿Quién escribió Romeo y Julieta?'),
(2485,7,'¿Qué pintor neerlandés creó La noche estrellada?'),
(2486,12,'¿Cómo se llama el protagonista de la saga Indiana Jones?'),
(2487,13,'¿Qué compositor fue conocido como el niño prodigio de la música clásica?'),
(2488,9,'¿En qué deporte se utiliza un bate y una pelota?'),
(2489,14,'¿Qué componente muestra imágenes en un ordenador?'),
(2490,10,'¿Qué estrella está en el centro del sistema solar?'),
(2491,11,'¿Qué mamífero pone huevos?'),
(2492,16,'¿Qué pasta italiana tiene forma de tubos?'),
(2493,4,'¿Qué muro cayó en Berlín en 1989?'),
(2494,5,'¿En qué continente está Japón?'),
(2495,6,'¿Qué parte del cuerpo humano contiene el cerebro?'),
(2496,8,'¿Qué personaje literario es un vampiro creado por Bram Stoker?'),
(2497,7,'¿Qué estilo arquitectónico tiene arcos apuntados y grandes vidrieras?'),
(2498,12,'¿Qué actor interpretó a Jack Sparrow?'),
(2499,13,'¿Qué instrumento tiene teclas blancas y negras?'),
(2500,9,'¿Qué tenista español ganó múltiples Roland Garros?'),
(2501,14,'¿Qué significa la palabra \'internet\' en relación con redes?'),
(2502,10,'¿Qué objeto espacial es un fragmento rocoso que orbita alrededor del Sol?'),
(2503,11,'¿Qué animal tiene una trompa larga?'),
(2504,16,'¿Qué alimento se obtiene de las uvas fermentadas?'),
(2505,4,'¿Quién fue conocido por la frase \'Tengo un sueño\'?'),
(2506,5,'¿Cuál es la capital de Grecia?'),
(2507,6,'¿Qué instrumento mide la temperatura?'),
(2508,8,'¿Quién escribió La divina comedia?'),
(2509,7,'¿Qué arquitecto diseñó la Casa Batlló de Barcelona?'),
(2510,6,'¿Qué científico formuló la teoría heliocéntrica que situaba al Sol en el centro?'),
(2511,4,'¿Qué antigua civilización construyó las pirámides de Egipto?'),
(2512,5,'¿Cuál es la capital de México?'),
(2513,6,'¿Qué estado del agua tiene forma sólida?'),
(2514,8,'¿Qué detective fue creado por Agatha Christie?'),
(2515,7,'¿Qué técnica artística utiliza pequeñas piezas de vidrio o piedra para crear imágenes?'),
(2516,12,'¿Qué película animada tiene como protagonista a una princesa llamada Elsa?'),
(2517,13,'¿Qué cantante es conocido como el Rey del Rock?'),
(2518,9,'¿Cuántos anillos tiene el símbolo olímpico?'),
(2519,14,'¿Qué sistema operativo utilizan muchos teléfonos móviles?'),
(2520,10,'¿Cómo se llama el primer hombre que viajó al espacio?'),
(2521,11,'¿Qué animal produce lana?'),
(2522,16,'¿Qué ingrediente da picor a muchos platos mexicanos?'),
(2523,4,'¿Qué documento inglés de 1215 limitó el poder del rey?'),
(2524,5,'¿Cuál es la isla más grande del mundo?'),
(2525,6,'¿Qué científico estudió la electricidad y los rayos con una cometa?'),
(2526,8,'¿Qué novela comienza con un personaje llamado Gregor Samsa?'),
(2527,7,'¿Qué material utiliza principalmente un escultor que trabaja con mármol?'),
(2528,12,'¿Qué saga cinematográfica está ambientada en la Tierra Media?'),
(2529,13,'¿Qué compositor creó Las cuatro estaciones?'),
(2530,9,'¿En qué deporte se usa una raqueta y un volante?'),
(2531,14,'¿Qué unidad se utiliza normalmente para medir almacenamiento digital?'),
(2532,10,'¿Qué planeta es conocido como el planeta rojo?'),
(2533,11,'¿Qué ave no puede volar y vive en la Antártida?'),
(2534,16,'¿Qué dulce español se consume tradicionalmente en Navidad?');
/*!40000 ALTER TABLE `pregunta` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `respuesta`
--
DROP TABLE IF EXISTS `respuesta`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `respuesta` (
`idRespuesta` int(11) NOT NULL AUTO_INCREMENT,
`idPregunta` int(11) NOT NULL,
`nombreRespuesta` varchar(255) NOT NULL,
`correcta` tinyint(1) DEFAULT 0,
PRIMARY KEY (`idRespuesta`),
KEY `idPregunta` (`idPregunta`),
CONSTRAINT `respuesta_ibfk_1` FOREIGN KEY (`idPregunta`) REFERENCES `pregunta` (`idPregunta`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `respuesta`
--
LOCK TABLES `respuesta` WRITE;
/*!40000 ALTER TABLE `respuesta` DISABLE KEYS */;
/*!40000 ALTER TABLE `respuesta` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `respuestaalmacenada`
--
DROP TABLE IF EXISTS `respuestaalmacenada`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `respuestaalmacenada` (
`idRespuestaAlmacenada` int(11) NOT NULL AUTO_INCREMENT,
`idPartidaxPregunta` int(11) NOT NULL,
`idUsuario` int(11) NOT NULL,
`idRespuesta` int(11) NOT NULL,
`primero` tinyint(1) DEFAULT 0,
PRIMARY KEY (`idRespuestaAlmacenada`),
KEY `idPartidaxPregunta` (`idPartidaxPregunta`),
KEY `idUsuario` (`idUsuario`),
KEY `idRespuesta` (`idRespuesta`),
CONSTRAINT `respuestaalmacenada_ibfk_1` FOREIGN KEY (`idPartidaxPregunta`) REFERENCES `partidaxpregunta` (`idPartidaxPregunta`) ON DELETE CASCADE,
CONSTRAINT `respuestaalmacenada_ibfk_2` FOREIGN KEY (`idUsuario`) REFERENCES `usuario` (`idUsuario`) ON DELETE CASCADE,
CONSTRAINT `respuestaalmacenada_ibfk_3` FOREIGN KEY (`idRespuesta`) REFERENCES `respuesta` (`idRespuesta`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `respuestaalmacenada`
--
LOCK TABLES `respuestaalmacenada` WRITE;
/*!40000 ALTER TABLE `respuestaalmacenada` DISABLE KEYS */;
/*!40000 ALTER TABLE `respuestaalmacenada` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `usuario`
--
DROP TABLE IF EXISTS `usuario`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `usuario` (
`idUsuario` int(11) NOT NULL AUTO_INCREMENT,
`nombreUsuario` varchar(50) NOT NULL,
`contrasena` varchar(100) NOT NULL,
`email` varchar(50) NOT NULL,
`avatar` varchar(200) DEFAULT NULL,
`cookie` varchar(200) DEFAULT NULL,
`aciertos` int(11) NOT NULL,
`victorias` int(11) NOT NULL,
`derrotas` int(11) NOT NULL,
PRIMARY KEY (`idUsuario`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `usuario`
--
LOCK TABLES `usuario` WRITE;
/*!40000 ALTER TABLE `usuario` DISABLE KEYS */;
/*!40000 ALTER TABLE `usuario` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Dumping routines for database 'triviagmatico'
--
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */;
-- Dump completed on 2026-09-25 9:33:39
+163 -92
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>
<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">
tuNombre
<?= $nombreUsuario ?>
</h1>
<!-- ========================= -->
<!-- FOTO DE PERFIL -->
<!-- ========================= -->
<div class="foto-container">
<img
id="fotoPerfil"
src="https://i.pravatar.cc/300?img=47"
<img id="fotoPerfil"
src="<?= $avatarUsuario ?>"
alt="Foto de perfil"
class="avatar rounded-circle">
<!-- Botón lápiz -->
<button
type="button"
<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"
<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"
<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"
<button type="button"
class="btn-perfil-cambiar"
onclick="cambiarNombre()">
<i class="bi bi-check-lg"></i>
Cambiar nombre
</button>
<button
type="button"
<button type="button"
class="btn-perfil-borrar"
onclick="borrarNombre()">
<i class="bi bi-x-lg"></i>
Borrar
</button>
</div>
@@ -160,11 +124,7 @@
</div>
<!-- ========================= -->
<!-- ESTADÍSTICAS -->
<!-- ========================= -->
<div class="col-md-6">
<div class="estadisticas">
@@ -174,40 +134,33 @@
Estadísticas
</h2>
<div class="estadistica estadistica-victorias">
<i class="bi bi-trophy-fill"></i>
&nbsp; Victorias:
<strong>
0
</strong>
<strong id="victorias">0</strong>
</div>
<div class="estadistica estadistica-derrotas">
<i class="bi bi-x-circle-fill"></i>
&nbsp; Derrotas:
<strong>
0
</strong>
<strong id="derrotas">0</strong>
</div>
<div class="estadistica estadistica-aciertos">
<i class="bi bi-bullseye"></i>
&nbsp; Aciertos:
<strong id="aciertos">0</strong>
</div>
<strong>
0
</strong>
<!-- CREAR PREGUNTA -->
<div class="text-center mt-4">
<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>
@@ -223,10 +176,128 @@
</div>
<!-- MODAL CREAR PREGUNTA -->
<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">
<div class="modal-header modal-kahoot-header">
<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>
</div>
<div class="modal-body p-4">
<form id="formCrearPregunta">
<!-- PREGUNTA -->
<div class="mb-4">
<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>
</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">
<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>
</div>
<!-- RESPUESTAS INCORRECTAS -->
<div class="mb-3">
<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="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>
<div class="modal-footer">
<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" id="btnCrearPregunta">
<i class="bi bi-check-lg me-1"></i>
Crear pregunta
</button>
</div>
</div>
</div>
</div>
<!-- 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>
+291
View File
@@ -0,0 +1,291 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<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">
<!-- Bootstrap Icons -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link
href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&display=swap"
rel="stylesheet">
<link rel="stylesheet" href="css/index.css">
</head>
<body>
<?php
include_once("cabecera.php");
?>
<main class="container py-5">
<!-- Título -->
<div class="text-center mb-5">
<div class="trophy-icon">
<i class="bi bi-trophy-fill"></i>
</div>
<h1 class="fw-bold">
¡Trivial terminado!
</h1>
<p class="text-muted fs-5 mb-0">
Estos son los resultados finales
</p>
</div>
<!-- Equipo ganador -->
<section class="row justify-content-center mb-5">
<div class="col-12 col-lg-8">
<div class="ranking-card">
<div class="ranking-header text-center">
<i class="bi bi-trophy-fill me-2"></i>
Equipo ganador
</div>
<div class="card-body text-center p-4">
<h2 class="fw-bold mb-2">
Los Cerebritos
</h2>
<div class="display-3 fw-bold mb-3">
850
<span class="fs-4 text-muted">
puntos
</span>
</div>
<p class="text-muted mb-0">
<i class="bi bi-stars me-1"></i>
¡Enhorabuena por la victoria!
</p>
</div>
</div>
</div>
</section>
<!-- Resultados de los dos equipos -->
<section class="row justify-content-center g-4">
<!-- EQUIPO GANADOR -->
<div class="col-12 col-lg-6">
<div class="ranking-card h-100">
<div class="ranking-header d-flex justify-content-between align-items-center">
<span>
Los Cerebritos
</span>
<span>
<i class="bi bi-trophy-fill"></i>
</span>
</div>
<div class="card-body p-4">
<div class="text-center mb-4">
<div class="fs-1 fw-bold">
850
</div>
<div class="text-muted">
puntos
</div>
</div>
<h5 class="fw-bold mb-3">
<i class="bi bi-people-fill me-2"></i>
Jugadores
</h5>
<ul class="list-group">
<li class="list-group-item">
1. Carlos
</li>
<li class="list-group-item">
2. Marta
</li>
<li class="list-group-item">
3. Pablo
</li>
<li class="list-group-item">
4. Laura
</li>
<li class="list-group-item">
5. David
</li>
<li class="list-group-item">
6. Ana
</li>
<li class="list-group-item">
7. Sergio
</li>
<li class="list-group-item">
8. Lucía
</li>
<li class="list-group-item">
9. Miguel
</li>
<li class="list-group-item">
10. Elena
</li>
</ul>
</div>
</div>
</div>
<!-- EQUIPO PERDEDOR -->
<div class="col-12 col-lg-6">
<div class="ranking-card h-100">
<!-- Cabecera plateada -->
<div
class="ranking-header d-flex justify-content-between align-items-center"
style="background-color: #c0c0c0;">
<span>
Los Campeones
</span>
<span>
<i class="bi bi-award-fill"></i>
</span>
</div>
<div class="card-body p-4">
<div class="text-center mb-4">
<div class="fs-1 fw-bold">
720
</div>
<div class="text-muted">
puntos
</div>
</div>
<h5 class="fw-bold mb-3">
<i class="bi bi-people-fill me-2"></i>
Jugadores
</h5>
<ul class="list-group">
<li class="list-group-item">
1. Javier
</li>
<li class="list-group-item">
2. Sofía
</li>
<li class="list-group-item">
3. Diego
</li>
<li class="list-group-item">
4. María
</li>
<li class="list-group-item">
5. Alejandro
</li>
<li class="list-group-item">
6. Paula
</li>
<li class="list-group-item">
7. Álvaro
</li>
<li class="list-group-item">
8. Carmen
</li>
</ul>
</div>
</div>
</div>
</section>
<!-- Volver al buscador -->
<div class="text-center mt-5">
<a
href="buscadorSala.php"
class="btn btn-play-kahoot">
<i class="bi bi-arrow-left-circle-fill"></i>
Volver al buscador de salas
</a>
</div>
</main>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js">
</script>
</body>
</html>