despliegue de asientos

This commit is contained in:
Alain Vasquez Ramirez 2025-03-08 13:11:18 -06:00
parent 5dd40f9760
commit eb197ed9d7
7 changed files with 371 additions and 149 deletions

View File

@ -30,7 +30,6 @@ CREATE TABLE conciertos (
capacidad_total INT NOT NULL
);
INSERT INTO conciertos (nombre_concierto, artista, fecha, calle, colonia, numero_direccion, codigo_postal, estado, capacidad_total)
VALUES ('Linux Fest', 'Junior H', '2025-06-15', 'Av. Xalapa', 'Obrero Campesina', 's/n', '91020', 'Veracruz', 5000);
SELECT * FROM conciertos;
DROP TABLE conciertos;
-- Zona
@ -42,11 +41,7 @@ CREATE TABLE zonas (
precio DECIMAL(10,2) NOT NULL,
FOREIGN KEY (id_concierto) REFERENCES conciertos(id_concierto) ON DELETE CASCADE
);
INSERT INTO zonas (id_concierto, nombre_zona, capacidad, precio) VALUES
(1, 'General', 20000, 800.00),
(1, 'Plata', 15000, 1500.00),
(1, 'Oro', 10000, 2500.00),
(1, 'VIP', 5000, 5000.00);
DROP TABLE zonas;
-- Obtener todos los conciertos con sus zonas y precios
SELECT c.id_concierto, c.nombre_concierto, c.artista, c.fecha,

View File

@ -0,0 +1,22 @@
<?php
include 'conexion.php';
header('Content-Type: application/json');
$data = json_decode(file_get_contents("php://input"), true);
if (!isset($data['asientos']) || !is_array($data['asientos'])) {
echo json_encode(["error" => "Datos inválidos"]);
exit;
}
foreach ($data['asientos'] as $idAsiento) {
$consulta = "UPDATE asientos SET estado = 'ocupado' WHERE id_asiento = ?";
$stmt = $conexionBD->prepare($consulta);
$stmt->bind_param("i", $idAsiento);
$stmt->execute();
}
echo json_encode(["success" => true]);
exit;
?>

View File

@ -3,26 +3,109 @@ include 'conexion.php';
header('Content-Type: application/json');
if (!isset($_GET['id']) || !isset($_GET['zona'])) {
echo json_encode(["error" => "Faltan parámetros"]);
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
// Verificar si es solicitud de concierto
if (isset($_GET['id_concierto'])) {
$idConcierto = intval($_GET['id_concierto']);
// Obtener la información del concierto
$consultaConcierto = "SELECT * FROM conciertos WHERE id_concierto = ?";
$stmt = $conexionBD->prepare($consultaConcierto);
$stmt->bind_param("i", $idConcierto);
$stmt->execute();
$resultadoConcierto = $stmt->get_result();
$concierto = $resultadoConcierto->fetch_assoc();
if (!$concierto) {
echo json_encode(["error" => "Concierto no encontrado"]);
exit;
}
// Obtener zonas del concierto
$consultaZonas = "SELECT * FROM zonas WHERE id_concierto = ?";
$stmtZonas = $conexionBD->prepare($consultaZonas);
$stmtZonas->bind_param("i", $idConcierto);
$stmtZonas->execute();
$resultadoZonas = $stmtZonas->get_result();
$zonas = [];
while ($zona = $resultadoZonas->fetch_assoc()) {
// Contar asientos disponibles y ocupados
$consultaAsientos = "SELECT estado FROM asientos WHERE id_zona = ?";
$stmtAsientos = $conexionBD->prepare($consultaAsientos);
$stmtAsientos->bind_param("i", $zona['id_zona']);
$stmtAsientos->execute();
$resultadoAsientos = $stmtAsientos->get_result();
$asientos_disponibles = 0;
$asientos_ocupados = 0;
while ($asiento = $resultadoAsientos->fetch_assoc()) {
if ($asiento['estado'] === 'disponible') {
$asientos_disponibles++;
} else {
$asientos_ocupados++;
}
}
// Agregar datos de asientos a la zona
$zona['asientos_disponibles'] = $asientos_disponibles;
$zona['asientos_ocupados'] = $asientos_ocupados;
$zonas[] = $zona;
}
// Agregar las zonas al concierto
$concierto['zonas'] = $zonas;
echo json_encode($concierto);
exit;
}
// Verificar si es solicitud de zona
if (isset($_GET['id_zona'])) {
$idZona = intval($_GET['id_zona']);
// Obtener la información de la zona específica
$consultaZona = "SELECT * FROM zonas WHERE id_zona = ?";
$stmtZona = $conexionBD->prepare($consultaZona);
$stmtZona->bind_param("i", $idZona);
$stmtZona->execute();
$resultadoZona = $stmtZona->get_result();
$zona = $resultadoZona->fetch_assoc();
if (!$zona) {
echo json_encode(["error" => "Zona no encontrada"]);
exit;
}
// Obtener asientos de la zona
$consultaAsientos = "SELECT estado FROM asientos WHERE id_zona = ?";
$stmtAsientos = $conexionBD->prepare($consultaAsientos);
$stmtAsientos->bind_param("i", $idZona);
$stmtAsientos->execute();
$resultadoAsientos = $stmtAsientos->get_result();
$asientos_disponibles = 0;
$asientos_ocupados = 0;
while ($asiento = $resultadoAsientos->fetch_assoc()) {
if ($asiento['estado'] === 'disponible') {
$asientos_disponibles++;
} else {
$asientos_ocupados++;
}
}
// Agregar información de asientos a la zona
$zona['asientos_disponibles'] = $asientos_disponibles;
$zona['asientos_ocupados'] = $asientos_ocupados;
echo json_encode($zona);
exit;
}
echo json_encode(["error" => "Solicitud incorrecta"]);
exit;
}
$conciertoId = intval($_GET['id']);
$nombreZona = $_GET['zona'];
$consulta = "SELECT numero_asiento FROM boletos WHERE id_concierto = ? AND nombre_zona = ?";
$stmt = $conexionBD->prepare($consulta);
$stmt->bind_param('is', $conciertoId, $nombreZona);
$stmt->execute();
$resultado = $stmt->get_result();
$asientosOcupados = [];
while ($fila = $resultado->fetch_assoc()) {
$asientosOcupados[] = intval($fila['numero_asiento']);
}
echo json_encode($asientosOcupados);
$stmt->close();
$conexionBD->close();
?>

View File

@ -0,0 +1,27 @@
<?php
include 'conexion.php';
header('Content-Type: application/json');
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['id_zona'])) {
$idZona = intval($_GET['id_zona']);
// Consultar los asientos de la zona específica
$consultaAsientos = "SELECT id_asiento, estado FROM asientos WHERE id_zona = ?";
$stmtAsientos = $conexionBD->prepare($consultaAsientos);
$stmtAsientos->bind_param("i", $idZona);
$stmtAsientos->execute();
$resultadoAsientos = $stmtAsientos->get_result();
$asientos = [];
while ($asiento = $resultadoAsientos->fetch_assoc()) {
$asientos[] = $asiento;
}
echo json_encode($asientos);
exit;
} else {
echo json_encode(["error" => "Parámetro id_zona faltante"]);
exit;
}
?>

View File

@ -1,14 +1,14 @@
/* Contenedor principal que divide la pantalla */
/* Contenedor principal */
.main-container {
display: flex;
height: 80vh; /* Ocupar 80% de la pantalla */
height: 80vh;
gap: 20px;
padding: 20px;
}
/* Lado izquierdo (imagen + botones) */
/* Lado izquierdo */
.cardIzq {
flex: 2; /* Ocupar 2/3 del ancho */
flex: 2;
display: flex;
flex-direction: column;
align-items: center;
@ -21,23 +21,27 @@
margin-bottom: 20px;
}
.cardIzq h2{
.cardIzq h2 {
font-size: 44px;
margin: 20px;
}
.zones-container {
display: flex;
gap: 10px;
flex-wrap: wrap;
justify-content: space-around;
margin-top: 15px;
width: 100%;
}
/* Lado derecho (tarjeta con info) */
/* Lado derecho (tarjetas en columna) */
.cardDer {
flex: 1; /* Ocupar 1/3 del ancho */
flex: 1;
display: flex;
flex-direction: column; /* Se colocan en columna */
align-items: center;
justify-content: center;
gap: 20px; /* Espacio entre las tarjetas */
}
.card {
@ -47,54 +51,83 @@
width: 100%;
max-width: 300px;
box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.3);
color:#ffffff;
color: #ffffff;
}
.zone-btn {
/* Botón centrado en la parte inferior */
.button-container {
position: relative;
width: 100%;
text-align: center;
margin-top: 20px;
}
#comprarBoletos {
padding: 10px 20px;
border-radius: 8px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
transition: all 0.3s ease;
border: none;
background-color: #5e17eb;
color: white;
position: absolute;
left: 50%;
transform: translateX(-50%);
}
#comprarBoletos:hover {
background-color: #4c11c9;
}
/* Contenedor de asientos dentro de la tarjeta */
.asientos-container {
display: grid;
grid-template-columns: repeat(5, 1fr); /* 5 columnas por fila */
gap: 10px;
justify-content: center;
width: 100%;
padding: 10px;
margin-left: 10px;
margin-right: 10px;
}
/* Estilos para cada asiento */
.asiento {
display: flex;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
border-radius: 8px;
cursor: pointer;
font-size: 18px;
color: white;
transition: 0.5s;
font-weight: bold;
transition: all 0.2s ease;
user-select: none;
border: 1px solid #ccc;
}
.zone-btn p{
padding: 10px;
/* Iconos dentro de los asientos */
.asiento i {
font-size: 24px; /* Ajusta el tamaño del icono */
}
.zone-btn:hover {
transform: scale(1.1);
}
.vip-zone { background-color: #5e17eb; }
.oro-zone { background-color: #d5ce2d; }
.plata-zone { background-color: #737373; }
.general-zone { background-color: #725e2b; color: rgb(255, 255, 255); }
.asiento {
display: inline-block;
width: 40px;
height: 40px;
margin: 5px;
text-align: center;
line-height: 40px;
font-size: 1.2em;
border: 1px solid #000;
cursor: pointer;
background-color: #f8f9fa;
border-radius: 5px;
}
.asiento.seleccionado {
/* Asientos disponibles */
.asiento.disponible {
background-color: #28a745;
color: white;
}
/* Asientos ocupados */
.asiento.ocupado {
background-color: #dc3545;
color: white;
cursor: not-allowed;
}
/* Asientos seleccionados */
.asiento.seleccionado {
background-color: #007bff;
color: white;
transform: scale(1.1);
box-shadow: 0 0 5px rgba(255, 255, 255, 0.5);
}

View File

@ -1,83 +1,140 @@
document.addEventListener("DOMContentLoaded", async () => {
const urlParams = new URLSearchParams(window.location.search);
const conciertoId = urlParams.get("id");
const params = new URLSearchParams(window.location.search);
const conciertoId = params.get("id");
if (!conciertoId) {
alert("No se encontró el ID del concierto.");
console.error("Error: No se proporcionó un ID de concierto en la URL.");
return;
}
try {
const respuesta = await fetch(`controladores/concierto_zonas.php?id=${conciertoId}`);
if (!respuesta.ok) throw new Error("Error al cargar las zonas del concierto");
const respuesta = await fetch(`controladores/concierto_zonas.php?id_concierto=${conciertoId}`);
if (!respuesta.ok) throw new Error("Error al cargar los datos del concierto");
const concierto = await respuesta.json();
if (concierto.error) {
console.error(`Error: ${concierto.error}`);
return;
}
// Mostrar información del concierto
document.getElementById("nombre_concierto").textContent = concierto.nombre_concierto;
document.getElementById("artista").textContent = `Artista: ${concierto.artista}`;
document.getElementById("fecha").textContent = `Fecha: ${concierto.fecha}`;
// Mostrar zonas del concierto
const zonasContainer = document.getElementById("zonas-container");
zonasContainer.innerHTML = "";
if (!concierto.zonas || concierto.zonas.length === 0) {
console.error("No se encontraron zonas para este concierto.");
return;
}
concierto.zonas.forEach(zona => {
const zonaBtn = document.createElement("button");
zonaBtn.classList.add("boton-zona");
zonaBtn.textContent = `Ver Zona ${zona.nombre_zona}`;
zonaBtn.dataset.idZona = zona.id_zona;
zonaBtn.addEventListener("click", () => cargarDatosZona(zona));
zonasContainer.appendChild(zonaBtn);
});
const zonas = await respuesta.json();
cargarZonas(zonas, conciertoId);
} catch (error) {
console.error(error);
console.error("Error al obtener los datos del concierto:", error);
}
});
function cargarZonas(zonas, conciertoId) {
const container = document.getElementById('zonas-container');
container.innerHTML = "";
async function cargarDatosZona(zona) {
if (!zona) {
console.error("Error: Datos de zona no disponibles");
return;
}
zonas.forEach(zona => {
let div = document.createElement('div');
div.classList.add('zona', zona.nombre_zona.toLowerCase());
div.textContent = `${zona.nombre_zona} - ${zona.capacidad} asientos - $${zona.precio}`;
div.onclick = async function () {
document.querySelectorAll('.zona').forEach(el => el.classList.remove('selected'));
div.classList.add('selected');
await mostrarAsientos(conciertoId, zona.nombre_zona, zona.capacidad);
};
container.appendChild(div);
});
// Mostrar información de la zona
document.getElementById("zonaNombre").textContent = `Zona: ${zona.nombre_zona || 'N/A'}`;
document.getElementById("zonaCapacidad").textContent = `Capacidad: ${zona.capacidad || 'N/A'}`;
document.getElementById("zonaPrecio").textContent = `Precio: $${zona.precio || 'N/A'}`;
document.getElementById("asientosDisponibles").textContent = `Disponibles: ${zona.asientos_disponibles ?? 0}`;
document.getElementById("asientosOcupados").textContent = `Ocupados: ${zona.asientos_ocupados ?? 0}`;
// Cargar los asientos disponibles
await cargarAsientos(zona.id_zona);
}
async function mostrarAsientos(conciertoId, nombreZona, capacidad) {
const asientosContainer = document.getElementById('asientos-container');
asientosContainer.innerHTML = "";
asientosContainer.style.display = "flex";
async function cargarAsientos(idZona) {
try {
const respuesta = await fetch(`controladores/obtener_asiento.php?id_zona=${idZona}`);
if (!respuesta.ok) throw new Error("Error al cargar los asientos");
const asientos = await respuesta.json();
// Seleccionamos el contenedor de asientos dentro de la tarjeta de "Asientos"
const asientosContainer = document.getElementById("asientos-container");
asientosContainer.innerHTML = ""; // Limpiar antes de agregar nuevos
asientos.forEach(asiento => {
const asientoDiv = document.createElement("div");
asientoDiv.classList.add("asiento", asiento.estado);
asientoDiv.dataset.idAsiento = asiento.id_asiento;
asientoDiv.setAttribute("title", `Asiento #${asiento.id_asiento}`);
// Agregar el icono de Bootstrap Icons
const icono = document.createElement("i");
icono.classList.add("bi", "bi-person-fill");
if (asiento.estado === "disponible") {
asientoDiv.appendChild(icono);
asientoDiv.addEventListener("click", () => seleccionarAsiento(asientoDiv, asiento.id_asiento));
} else {
icono.style.opacity = "0.3"; // Opacidad para los asientos ocupados
asientoDiv.appendChild(icono);
}
asientosContainer.appendChild(asientoDiv);
});
} catch (error) {
console.error("Error al obtener los asientos:", error);
}
}
const asientosSeleccionados = new Set();
function seleccionarAsiento(elemento, idAsiento) {
if (asientosSeleccionados.has(idAsiento)) {
asientosSeleccionados.delete(idAsiento);
elemento.classList.remove("seleccionado");
} else {
asientosSeleccionados.add(idAsiento);
elemento.classList.add("seleccionado");
}
// Habilitar el botón de compra si hay al menos un asiento seleccionado
document.getElementById("comprarBoletos").disabled = asientosSeleccionados.size === 0;
}
document.getElementById("comprarBoletos").addEventListener("click", async () => {
if (asientosSeleccionados.size === 0) return;
try {
const respuesta = await fetch(`controladores/asientos_ocupados.php?id=${conciertoId}&zona=${nombreZona}`);
if (!respuesta.ok) throw new Error("Error al cargar los asientos ocupados");
const asientosOcupados = await respuesta.json();
const respuesta = await fetch("controladores/comprar_asientos.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ asientos: Array.from(asientosSeleccionados) })
});
for (let i = 1; i <= capacidad; i++) {
let asiento = document.createElement('div');
asiento.classList.add('asiento');
asiento.innerHTML = `<i class="bi bi-person-fill"></i> ${i}`;
if (asientosOcupados.includes(i)) {
asiento.classList.add('ocupado');
} else {
asiento.onclick = function () {
asiento.classList.toggle('seleccionado');
};
}
asientosContainer.appendChild(asiento);
const resultado = await respuesta.json();
if (resultado.success) {
alert("Compra realizada con éxito.");
location.reload();
} else {
alert("Error al realizar la compra.");
}
} catch (error) {
console.error(error);
alert("Error al cargar los asientos");
console.error("Error al comprar boletos:", error);
}
}
document.getElementById("confirmarSeleccion").addEventListener("click", () => {
let selectedZona = document.querySelector('.zona.selected');
if (!selectedZona) {
alert("No has seleccionado ninguna zona.");
return;
}
let selectedAsientos = document.querySelectorAll('.asiento.seleccionado');
if (selectedAsientos.length === 0) {
alert("No has seleccionado ningún asiento.");
return;
}
let asientosSeleccionados = Array.from(selectedAsientos).map(asiento => asiento.textContent.trim());
alert(`Zona seleccionada: ${selectedZona.textContent}\nAsientos: ${asientosSeleccionados.join(', ')}`);
});

View File

@ -6,8 +6,10 @@
<title>Compra de Boletos</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
<link rel="stylesheet" href="css/conciertos.css"> <!-- Aquí se incluye el CSS -->
<link rel="stylesheet" href="css/conciertos.css">
<link rel="stylesheet" href="css/ventanaBoletos.css">
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css">
</head>
<body>
<nav>
@ -19,38 +21,41 @@
</div>
</nav>
<!-- Contenedor principal -->
<div class="main-container">
<div class="cardIzq">
<h2>Zonas del Concierto</h2>
<img src="img/mapa.png" alt="Mapa de zonas del concierto">
<div class="zones-container">
<button class="zone-btn vip-zone" onclick="seleccionarZona('vip')">Zona VIP</button>
<button class="zone-btn oro-zone" onclick="seleccionarZona('oro')">Zona ORO</button>
<button class="zone-btn plata-zone" onclick="seleccionarZona('plata')">Zona PLATA</button>
<button class="zone-btn general-zone" onclick="seleccionarZona('general')">Zona GENERAL</button>
</div>
<div id="zonas-container" class="zones-container"></div>
</div>
<!-- Lado derecho con tarjetas -->
<div class="cardDer">
<div class="card">
<h2 class="text-xl font-bold mb-4">Detalles de la Zona</h2>
<h2 class="text-xl font-bold mb-4">Detalles del concierto</h2>
<div id="zona-info" class="space-y-2">
<p><strong>Zona:</strong> <span id="zona-nombre">-</span></p>
<p><strong>Capacidad:</strong> <span id="zona-capacidad">-</span></p>
<p><strong>Precio por asiento:</strong> $<span id="zona-precio">-</span></p>
<h2 id="nombre_concierto">Nombre del Concierto</h2>
<p id="artista">Artista: </p>
<p id="fecha">Fecha: </p>
<h2 id="zonaNombre">Zona</h2>
<p id="zonaCapacidad">Capacidad: </p>
<p id="zonaPrecio">Precio: </p>
<p id="asientosDisponibles">Disponibles: </p>
<p id="asientosOcupados">Ocupados: </p>
</div>
</div>
<!-- Tarjeta para los asientos dentro de la columna derecha -->
<div class="card">
<h2 class="text-xl font-bold mb-4">Asientos</h2>
<div id="asientos-container" class="asientos-container"></div>
</div>
</div>
</div>
<div id="zonas-container"></div>
<div id="asientos-container" class="asientos-container"></div>
<div class="text-center mt-3">
<button class="btn btn-primary" id="confirmarSeleccion">Confirmar selección</button>
<!-- Contenedor del botón centrado en la parte inferior -->
<div class="button-container">
<button id="comprarBoletos" class="btn btn-primary" disabled>Comprar Asientos</button>
</div>
<script defer src="js/ventaBoletos.js"></script>