Compra de Boletos
This commit is contained in:
parent
4aa177c5c5
commit
ce5c75fff4
|
@ -61,3 +61,30 @@ FROM conciertos c
|
|||
JOIN zonas z ON c.id_concierto = z.id_concierto
|
||||
WHERE c.id_concierto = 1;
|
||||
|
||||
-- Tabla Asientos
|
||||
CREATE TABLE asientos (
|
||||
id_asiento INT AUTO_INCREMENT PRIMARY KEY,
|
||||
id_zona INT NOT NULL,
|
||||
numero_asiento INT NOT NULL,
|
||||
estado ENUM('disponible', 'ocupado') NOT NULL DEFAULT 'disponible',
|
||||
FOREIGN KEY (id_zona) REFERENCES zonas(id_zona) ON DELETE CASCADE,
|
||||
UNIQUE (id_zona, numero_asiento) -- Para evitar asientos duplicados en la misma zona
|
||||
);
|
||||
DROP TABLE asientos;
|
||||
|
||||
-- Tabla Boletos
|
||||
CREATE TABLE boletos (
|
||||
id_boleto INT AUTO_INCREMENT PRIMARY KEY,
|
||||
id_concierto INT NOT NULL,
|
||||
id_zona INT NOT NULL,
|
||||
id_asiento INT NOT NULL,
|
||||
nombre_comprador VARCHAR(255) NOT NULL,
|
||||
precio DECIMAL(10,2) NOT NULL,
|
||||
fecha_concierto DATE NOT NULL,
|
||||
artista VARCHAR(255) NOT NULL,
|
||||
FOREIGN KEY (id_concierto) REFERENCES conciertos(id_concierto) ON DELETE CASCADE,
|
||||
FOREIGN KEY (id_zona) REFERENCES zonas(id_zona) ON DELETE CASCADE,
|
||||
FOREIGN KEY (id_asiento) REFERENCES asientos(id_asiento) ON DELETE CASCADE,
|
||||
UNIQUE (id_asiento) -- Evita que un asiento se venda dos veces
|
||||
);
|
||||
DROP TABLE boletos;
|
|
@ -2,43 +2,27 @@
|
|||
include 'conexion.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
if (!isset($_GET['id'])) {
|
||||
echo json_encode(["error" => "No se proporcionó un ID de concierto"]);
|
||||
if (!isset($_GET['id']) || !isset($_GET['zona'])) {
|
||||
echo json_encode(["error" => "Faltan parámetros"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$conciertoId = intval($_GET['id']);
|
||||
$nombreZona = $_GET['zona'];
|
||||
|
||||
$consulta = "SELECT nombre_zona, capacidad, precio FROM zonas WHERE id_concierto = ? ORDER BY FIELD(nombre_zona, 'General', 'Plata', 'Oro', 'VIP')";
|
||||
|
||||
$consulta = "SELECT numero_asiento FROM boletos WHERE id_concierto = ? AND nombre_zona = ?";
|
||||
$stmt = $conexionBD->prepare($consulta);
|
||||
if (!$stmt) {
|
||||
echo json_encode(["error" => "Error en la preparación de la consulta: " . $conexionBD->error]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt->bind_param('i', $conciertoId);
|
||||
$stmt->bind_param('is', $conciertoId, $nombreZona);
|
||||
$stmt->execute();
|
||||
$resultado = $stmt->get_result();
|
||||
|
||||
$zonas = [];
|
||||
$asientosOcupados = [];
|
||||
while ($fila = $resultado->fetch_assoc()) {
|
||||
$zonas[] = [
|
||||
'nombre_zona' => $fila['nombre_zona'],
|
||||
'capacidad' => $fila['capacidad'],
|
||||
'precio' => $fila['precio']
|
||||
];
|
||||
}
|
||||
|
||||
if (empty($zonas)) {
|
||||
echo json_encode(["error" => "No se encontraron zonas para este concierto"]);
|
||||
} else {
|
||||
echo json_encode($zonas, JSON_PRETTY_PRINT);
|
||||
$asientosOcupados[] = intval($fila['numero_asiento']);
|
||||
}
|
||||
|
||||
echo json_encode($asientosOcupados);
|
||||
$stmt->close();
|
||||
$conexionBD->close();
|
||||
?>
|
||||
?>
|
||||
|
|
|
@ -44,16 +44,28 @@ try {
|
|||
$id_concierto = $conexionBD->insert_id;
|
||||
$stmt->close();
|
||||
|
||||
// Insertar zonas
|
||||
// Insertar zonas y sus asientos
|
||||
$consulta_zonas = "INSERT INTO zonas (id_concierto, nombre_zona, capacidad, precio) VALUES (?, ?, ?, ?)";
|
||||
$stmt_zonas = $conexionBD->prepare($consulta_zonas);
|
||||
|
||||
|
||||
$consulta_asientos = "INSERT INTO asientos (id_zona, numero_asiento, estado) VALUES (?, ?, 'disponible')";
|
||||
$stmt_asientos = $conexionBD->prepare($consulta_asientos);
|
||||
|
||||
foreach ($zonas as $zona) {
|
||||
$stmt_zonas->bind_param("isid", $id_concierto, $zona['nombre_zona'], $zona['capacidad'], $zona['precio']);
|
||||
$stmt_zonas->execute();
|
||||
|
||||
$id_zona = $conexionBD->insert_id;
|
||||
|
||||
// Insertar asientos
|
||||
for ($i = 1; $i <= $zona['capacidad']; $i++) {
|
||||
$stmt_asientos->bind_param("ii", $id_zona, $i);
|
||||
$stmt_asientos->execute();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$stmt_zonas->close();
|
||||
$stmt_asientos->close();
|
||||
$conexionBD->commit();
|
||||
|
||||
echo json_encode(['insercionCorrecta' => true, 'id_concierto' => $id_concierto]);
|
||||
|
@ -64,3 +76,4 @@ try {
|
|||
}
|
||||
|
||||
$conexionBD->close();
|
||||
?>
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
|
145
css/zonas.css
145
css/zonas.css
|
@ -1,101 +1,82 @@
|
|||
.mapa-estadio {
|
||||
position: relative;
|
||||
width: 600px;
|
||||
height: 500px;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 50% 50% 0 0;
|
||||
margin: auto;
|
||||
/* Contenedor principal que divide la pantalla */
|
||||
.main-container {
|
||||
display: flex;
|
||||
height: 80vh; /* Ocupar 80% de la pantalla */
|
||||
gap: 20px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* Lado izquierdo (imagen + botones) */
|
||||
.cardIzq {
|
||||
flex: 2; /* Ocupar 2/3 del ancho */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-end;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.escenario {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 100%;
|
||||
height: 140px;
|
||||
background-color: black;
|
||||
color: white;
|
||||
text-align: center;
|
||||
line-height: 60px;
|
||||
font-weight: bold;
|
||||
border-radius: 10px 10px 0 0;
|
||||
}
|
||||
|
||||
.zona {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
border-radius: 50% 50% 0 0;
|
||||
}
|
||||
|
||||
.general {
|
||||
background-color: gray;
|
||||
.cardIzq img {
|
||||
width: 100%;
|
||||
height: 40%;
|
||||
bottom: 10%;
|
||||
left: 0;
|
||||
border-radius: 50% 50% 0 0;
|
||||
max-width: 600px;
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.plata {
|
||||
background-color: silver;
|
||||
width: 80%;
|
||||
height: 30%;
|
||||
bottom: 20%;
|
||||
left: 10%;
|
||||
border-radius: 50% 50% 0 0;
|
||||
}
|
||||
|
||||
.oro {
|
||||
background-color: gold;
|
||||
width: 60%;
|
||||
height: 25%;
|
||||
bottom: 30%;
|
||||
left: 20%;
|
||||
border-radius: 50% 50% 0 0;
|
||||
}
|
||||
|
||||
.vip {
|
||||
background-color: purple;
|
||||
width: 40%;
|
||||
height: 20%;
|
||||
bottom: 10%;
|
||||
left: 30%;
|
||||
border-radius: 50% 50% 0 0;
|
||||
}
|
||||
|
||||
.selected { border: 3px solid red; }
|
||||
|
||||
.asientos-container {
|
||||
display: none;
|
||||
margin-top: 20px;
|
||||
.zones-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
/* Lado derecho (tarjeta con info) */
|
||||
.cardDer {
|
||||
flex: 1; /* Ocupar 1/3 del ancho */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: #aab2b2;
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.zone-btn {
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.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 {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin: 5px;
|
||||
display: inline-block;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin: 5px;
|
||||
text-align: center;
|
||||
line-height: 30px;
|
||||
border-radius: 5px;
|
||||
line-height: 40px;
|
||||
font-size: 1.2em;
|
||||
border: 1px solid #000;
|
||||
cursor: pointer;
|
||||
background-color: green;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.asiento.seleccionado {
|
||||
background-color: #28a745;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.asiento.seleccionado { background-color: orange; }
|
||||
.asiento.ocupado {
|
||||
background-color: #dc3545;
|
||||
color: white;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
<!-- Navbar -->
|
||||
<nav>
|
||||
<a href="ventanaInsertarConcierto.html" class="navbar-brand">TicketFei</a>
|
||||
<a href="ventanaConciertos.html" class="navbar-brand">TicketFei</a>
|
||||
<div class="nav-links">
|
||||
<a href="ventanaInsertarConcierto.html">Crear Conciertos</a>
|
||||
<a href="ventanaConciertos.html">Ver Conciertos</a>
|
||||
|
|
Binary file not shown.
After ![]() (image error) Size: 62 KiB |
|
@ -19,7 +19,7 @@ formulario.addEventListener('submit', async (event) => {
|
|||
});
|
||||
const verificarCredenciales = await respuestaPeticion.json();
|
||||
if (verificarCredenciales.loginExitoso) {
|
||||
window.location.href = 'ventanaInsertarConcierto.html';
|
||||
window.location.href = 'ventanaConciertos.html';
|
||||
} else {
|
||||
notificacion.textContent ="Usuario o contraseña incorrecta";
|
||||
notificacion.style.color='#ffffff';
|
||||
|
|
|
@ -5,20 +5,20 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|||
alert("No se encontró el ID del concierto.");
|
||||
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 zonas = await respuesta.json();
|
||||
cargarZonas(zonas);
|
||||
cargarZonas(zonas, conciertoId);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
alert("Error al cargar los datos del concierto");
|
||||
}
|
||||
});
|
||||
|
||||
function cargarZonas(zonas) {
|
||||
function cargarZonas(zonas, conciertoId) {
|
||||
const container = document.getElementById('zonas-container');
|
||||
container.innerHTML = "";
|
||||
|
||||
|
@ -26,28 +26,43 @@ function cargarZonas(zonas) {
|
|||
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 = function() {
|
||||
div.onclick = async function () {
|
||||
document.querySelectorAll('.zona').forEach(el => el.classList.remove('selected'));
|
||||
div.classList.add('selected');
|
||||
mostrarAsientos(zona.capacidad);
|
||||
await mostrarAsientos(conciertoId, zona.nombre_zona, zona.capacidad);
|
||||
};
|
||||
container.appendChild(div);
|
||||
});
|
||||
}
|
||||
|
||||
function mostrarAsientos(capacidad) {
|
||||
async function mostrarAsientos(conciertoId, nombreZona, capacidad) {
|
||||
const asientosContainer = document.getElementById('asientos-container');
|
||||
asientosContainer.innerHTML = "";
|
||||
asientosContainer.style.display = "flex";
|
||||
|
||||
for (let i = 0; i < capacidad; i++) {
|
||||
let asiento = document.createElement('div');
|
||||
asiento.classList.add('asiento');
|
||||
asiento.textContent = i + 1;
|
||||
asiento.onclick = function() {
|
||||
asiento.classList.toggle('seleccionado');
|
||||
};
|
||||
asientosContainer.appendChild(asiento);
|
||||
|
||||
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();
|
||||
|
||||
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);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
alert("Error al cargar los asientos");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,11 +72,13 @@ document.getElementById("confirmarSeleccion").addEventListener("click", () => {
|
|||
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);
|
||||
|
||||
let asientosSeleccionados = Array.from(selectedAsientos).map(asiento => asiento.textContent.trim());
|
||||
alert(`Zona seleccionada: ${selectedZona.textContent}\nAsientos: ${asientosSeleccionados.join(', ')}`);
|
||||
});
|
||||
|
|
|
@ -6,12 +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>
|
||||
<script defer src="js/ventaBoletos.js"></script>
|
||||
<link rel="stylesheet" href="css/conciertos.css">
|
||||
<link rel="stylesheet" href="css/conciertos.css"> <!-- Aquí se incluye el CSS -->
|
||||
<link rel="stylesheet" href="css/zonas.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav>
|
||||
<a href="ventanaInsertarConcierto.html" class="navbar-brand">TicketFei</a>
|
||||
<div class="nav-links">
|
||||
|
@ -19,29 +17,42 @@
|
|||
<a href="ventanaConciertos.html">Ver Conciertos</a>
|
||||
<a href="#">Reporte Ventas</a>
|
||||
</div>
|
||||
<div class="search-container">
|
||||
<input type="search" id="buscadorColaborador" placeholder="Buscar...">
|
||||
<button id="buscadorBoton">Buscar</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container mt-4 text-center">
|
||||
<h2>Selecciona tu zona</h2>
|
||||
</div>
|
||||
|
||||
<div class="mapa-estadio">
|
||||
<div class="escenario">ESCENARIO</div>
|
||||
<div class="zona general" onclick="seleccionarZona('General')">General</div>
|
||||
<div class="zona plata" onclick="seleccionarZona('Plata')">Plata</div>
|
||||
<div class="zona oro" onclick="seleccionarZona('Oro')">Oro</div>
|
||||
<div class="zona vip" onclick="seleccionarZona('VIP')">VIP</div>
|
||||
<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>
|
||||
|
||||
<div class="cardDer">
|
||||
<div class="card">
|
||||
<h2 class="text-xl font-bold mb-4">Detalles de la Zona</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>
|
||||
</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>
|
||||
</div>
|
||||
|
||||
<script defer src="js/ventaBoletos.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<body>
|
||||
|
||||
<nav>
|
||||
<a href="ventanaInsertarConcierto.html" class="navbar-brand">TicketFei</a>
|
||||
<a href="ventanaConciertos.html" class="navbar-brand">TicketFei</a>
|
||||
<div class="nav-links">
|
||||
<a href="ventanaInsertarConcierto.html">Crear Conciertos</a>
|
||||
<a href="ventanaConciertos.html">Ver Conciertos</a>
|
||||
|
|
Loading…
Reference in New Issue