version 09/03/25
This commit is contained in:
commit
437aa1ef06
.gitignoreREADME.md
bd
controladores
actualizar_concierto.phpcerrar_sesion.phpcomprar_asiento.phpconcierto_zonas.phpconciertos.phpconexion.phpeliminar_concierto.phpinsertar_concierto.phplogin.phpobtener_asiento.phpobtener_concierto.php
css
conciertos.css
editarConciertos.htmlfonts/Frutiger Bold Italic
formulario.csslogin.cssmodalActualizar.cssmodalEliminar.cssventanaBoletos.cssventanaPrincipal.cssimg
index.htmljs
ventaBoletos.htmlventanaConciertos.htmlventanaInsertarConcierto.html
|
@ -0,0 +1,10 @@
|
|||
# ---> NetBeans
|
||||
**/nbproject/private/
|
||||
**/nbproject/Makefile-*.mk
|
||||
**/nbproject/Package-*.bash
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
nbdist/
|
||||
.nb-gradle/
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
# Proyecto TicketFei
|
||||
|
||||
Descripcion del Proyecto a realizar:
|
||||
|
||||
Para el desarrollo de la aplicación de venta de boletos, se utilizarán HTML, CSS, JavaScript y PHP, ya que permiten construir una solución web eficiente, accesible y fácil de gestionar.Esta combinación de tecnologías garantiza una aplicación funcional, dinámica y escalable, cumpliendo con los requisitos del proyecto.
|
||||
|
||||
Funcionalidades:
|
||||
HU01: Selección y Venta de Boletos
|
||||
|
||||
HU02: Generación de Reporte de Ventas
|
||||
|
||||
HU03: Gestión de Eventos y Conciertos
|
||||
|
||||
HU04: Cancelación de Venta de Boletos
|
||||
|
||||
HU05: Edición de Boletos Vendidos o Reservados
|
||||
|
||||
HU06: Búsqueda y Filtrado de Boletos
|
||||
## Autores
|
||||
|
||||
- [@FernandoEscobar](https://git.gumoio.com/fernando.escobar)
|
||||
- [@AxelVasquez](https://git.gumoio.com/axel.vasquez)
|
||||
- [@JorgeOrtega](https://git.gumoio.com/jorge.ortega)
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
create database TicketFei;
|
||||
CREATE USER 'desarrolloTicketFei'@'localhost' IDENTIFIED BY 'password';
|
||||
GRANT CREATE,ALTER,DROP,INSERT,UPDATE,DELETE,SELECT,CREATE VIEW,REFERENCES on TicketFei.* to 'desarrolloTicketFei'@'localhost';
|
||||
GRANT LOCK TABLES, PROCESS ON *.* TO 'desarrolloTicketFei'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
|
@ -0,0 +1,85 @@
|
|||
USE TicketFei;
|
||||
|
||||
CREATE TABLE usuarios (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
nombre VARCHAR(255) NOT NULL,
|
||||
apellidoPaterno VARCHAR(255) NOT NULL,
|
||||
apellidoMaterno VARCHAR(255) NOT NULL,
|
||||
usuario VARCHAR(255) NOT NULL,
|
||||
contraseña VARCHAR(255) NOT NULL
|
||||
);
|
||||
INSERT INTO usuarios (nombre, apellidoPaterno, apellidoMaterno, usuario, contraseña) VALUES
|
||||
('Aaron', 'Bonilla', 'Gonzalez', 's22', '123'),
|
||||
('Carlos', 'Palestina', 'Alducin', 's23', '123'),
|
||||
('Miguel', 'Diaz', 'Villa', 's24', '123');
|
||||
|
||||
SELECT * FROM usuarios;
|
||||
DROP TABLE usuarios;
|
||||
|
||||
-- concierto
|
||||
CREATE TABLE conciertos (
|
||||
id_concierto INT AUTO_INCREMENT PRIMARY KEY,
|
||||
nombre_concierto VARCHAR(255) NOT NULL,
|
||||
artista VARCHAR(255) NOT NULL,
|
||||
fecha DATE NOT NULL,
|
||||
calle VARCHAR(255) NOT NULL,
|
||||
colonia VARCHAR(255) NOT NULL,
|
||||
numero_direccion VARCHAR(255) NOT NULL,
|
||||
codigo_postal VARCHAR(10) NOT NULL,
|
||||
estado VARCHAR(255) NOT NULL,
|
||||
capacidad_total INT NOT NULL
|
||||
);
|
||||
INSERT INTO conciertos (nombre_concierto, artista, fecha, calle, colonia, numero_direccion, codigo_postal, estado, capacidad_total)
|
||||
SELECT * FROM conciertos;
|
||||
DROP TABLE conciertos;
|
||||
-- Zona
|
||||
CREATE TABLE zonas (
|
||||
id_zona INT AUTO_INCREMENT PRIMARY KEY,
|
||||
id_concierto INT NOT NULL,
|
||||
nombre_zona ENUM('General', 'Plata', 'Oro', 'VIP') NOT NULL,
|
||||
capacidad INT NOT NULL,
|
||||
precio DECIMAL(10,2) NOT NULL,
|
||||
FOREIGN KEY (id_concierto) REFERENCES conciertos(id_concierto) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
DROP TABLE zonas;
|
||||
-- Obtener todos los conciertos con sus zonas y precios
|
||||
SELECT c.id_concierto, c.nombre_concierto, c.artista, c.fecha,
|
||||
z.nombre_zona, z.capacidad, z.precio
|
||||
FROM conciertos c
|
||||
JOIN zonas z ON c.id_concierto = z.id_concierto;
|
||||
|
||||
-- Consultar un concierto específico con sus zonas
|
||||
SELECT c.nombre_concierto, c.artista, c.fecha,
|
||||
z.nombre_zona, z.capacidad, z.precio
|
||||
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;
|
|
@ -0,0 +1,55 @@
|
|||
-- MySQL dump 10.13 Distrib 8.0.34, for Win64 (x86_64)
|
||||
--
|
||||
-- Host: 127.0.0.1 Database: ticketfei
|
||||
-- ------------------------------------------------------
|
||||
-- Server version 8.0.34
|
||||
|
||||
/*!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 */;
|
||||
/*!50503 SET NAMES utf8 */;
|
||||
/*!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' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
|
||||
--
|
||||
-- Table structure for table `usuarios`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `usuarios`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `usuarios` (
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`nombre` varchar(255) NOT NULL,
|
||||
`apellidoPaterno` varchar(255) NOT NULL,
|
||||
`apellidoMaterno` varchar(255) NOT NULL,
|
||||
`usuario` varchar(255) NOT NULL,
|
||||
`contraseña` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `usuarios`
|
||||
--
|
||||
|
||||
LOCK TABLES `usuarios` WRITE;
|
||||
/*!40000 ALTER TABLE `usuarios` DISABLE KEYS */;
|
||||
INSERT INTO `usuarios` VALUES (1,'Aaron','Bonilla','Gonzalez','s22','123'),(2,'Carlos','Palestina','Alducin','s23','123'),(3,'Miguel','Diaz','Villa','s24','123');
|
||||
/*!40000 ALTER TABLE `usuarios` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
/*!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 */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
|
||||
-- Dump completed on 2025-02-19 10:38:05
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
include 'conexion.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['id'])) {
|
||||
$id = intval($_GET['id']);
|
||||
$consulta = "SELECT * FROM conciertos WHERE id_concierto = ?";
|
||||
$stmt = $conexionBD->prepare($consulta);
|
||||
$stmt->bind_param("i", $id);
|
||||
$stmt->execute();
|
||||
$resultado = $stmt->get_result();
|
||||
$concierto = $resultado->fetch_assoc();
|
||||
|
||||
if ($concierto) {
|
||||
$consulta_zonas = "SELECT * FROM zonas WHERE id_concierto = ?";
|
||||
$stmt_zonas = $conexionBD->prepare($consulta_zonas);
|
||||
$stmt_zonas->bind_param("i", $id);
|
||||
$stmt_zonas->execute();
|
||||
$resultado_zonas = $stmt_zonas->get_result();
|
||||
while ($zona = $resultado_zonas->fetch_assoc()) {
|
||||
$concierto['zonas'][] = $zona;
|
||||
}
|
||||
echo json_encode($concierto);
|
||||
} else {
|
||||
echo json_encode(["error" => "Concierto no encontrado"]);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$datos = json_decode(file_get_contents("php://input"), true);
|
||||
if (!$datos || !isset($datos['id'])) {
|
||||
echo json_encode(["actualizacionCorrecta" => false, "error" => "Datos incompletos"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Actualizar la información del concierto
|
||||
$consulta = "UPDATE conciertos SET nombre_concierto=?, artista=?, fecha=?, calle=?, colonia=?, numero_direccion=?, codigo_postal=?, estado=?, capacidad_total=? WHERE id_concierto=?";
|
||||
$stmt = $conexionBD->prepare($consulta);
|
||||
$stmt->bind_param("ssssssissi",
|
||||
$datos['nombre_concierto'],
|
||||
$datos['artista'],
|
||||
$datos['fecha'],
|
||||
$datos['calle'],
|
||||
$datos['colonia'],
|
||||
$datos['numero_direccion'],
|
||||
$datos['codigo_postal'],
|
||||
$datos['estado'],
|
||||
$datos['capacidad_total'],
|
||||
$datos['id']
|
||||
);
|
||||
$stmt->execute();
|
||||
|
||||
// Actualizar la información de las zonas
|
||||
foreach ($datos['zonas'] as $zona) {
|
||||
$consulta_zonas = "UPDATE zonas SET capacidad=?, precio=? WHERE id_concierto=? AND nombre_zona=?";
|
||||
$stmt_zona = $conexionBD->prepare($consulta_zonas);
|
||||
$stmt_zona->bind_param("idis",
|
||||
$zona['capacidad'],
|
||||
$zona['precio'],
|
||||
$datos['id'],
|
||||
$zona['nombre_zona']
|
||||
);
|
||||
$stmt_zona->execute();
|
||||
}
|
||||
|
||||
echo json_encode(["actualizacionCorrecta" => true]);
|
||||
exit;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
include 'conexion.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
session_start();
|
||||
|
||||
session_unset();
|
||||
session_destroy();
|
||||
|
||||
echo json_encode(['success' => true]);
|
||||
} else {
|
||||
http_response_code(405);
|
||||
echo json_encode(['success' => false, 'message' => 'Método no permitido']);
|
||||
}
|
||||
|
||||
if (isset($conexionBD)) {
|
||||
$conexionBD->close();
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
include 'conexion.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$rawData = file_get_contents("php://input");
|
||||
$data = json_decode($rawData, true);
|
||||
|
||||
if (!isset($data['asientos']) || !is_array($data['asientos'])) {
|
||||
echo json_encode(["error" => "Datos inválidos"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$conexionBD->begin_transaction();
|
||||
|
||||
try {
|
||||
foreach ($data['asientos'] as $idAsiento) {
|
||||
// Verificar si el asiento sigue disponible
|
||||
$stmtVerificar = $conexionBD->prepare("SELECT estado FROM asientos WHERE id_asiento = ?");
|
||||
$stmtVerificar->bind_param("i", $idAsiento);
|
||||
$stmtVerificar->execute();
|
||||
$resultado = $stmtVerificar->get_result()->fetch_assoc();
|
||||
|
||||
if (!$resultado || $resultado['estado'] !== 'disponible') {
|
||||
throw new Exception("El asiento ID $idAsiento ya está ocupado o no existe.");
|
||||
}
|
||||
|
||||
// Marcar el asiento como ocupado
|
||||
$stmtActualizar = $conexionBD->prepare("UPDATE asientos SET estado = 'ocupado' WHERE id_asiento = ?");
|
||||
$stmtActualizar->bind_param("i", $idAsiento);
|
||||
$stmtActualizar->execute();
|
||||
}
|
||||
|
||||
$conexionBD->commit();
|
||||
echo json_encode(["success" => true]);
|
||||
} catch (Exception $e) {
|
||||
$conexionBD->rollback();
|
||||
echo json_encode(["error" => $e->getMessage()]);
|
||||
}
|
||||
exit;
|
||||
?>
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
include 'conexion.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
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;
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
include 'conexion.php';
|
||||
|
||||
header('Content-Type: application/json'); // Asegurar que el contenido es JSON
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
$consulta = "SELECT c.id_concierto, c.nombre_concierto, c.artista, c.fecha, c.calle, c.colonia, c.numero_direccion, c.codigo_postal, c.estado, c.capacidad_total,
|
||||
z.nombre_zona, z.capacidad AS capacidad_zona, z.precio
|
||||
FROM conciertos c
|
||||
LEFT JOIN zonas z ON c.id_concierto = z.id_concierto
|
||||
ORDER BY c.id_concierto,
|
||||
FIELD(z.nombre_zona, 'General', 'Plata', 'Oro', 'VIP')";
|
||||
|
||||
$resultado = $conexionBD->query($consulta);
|
||||
|
||||
if (!$resultado) {
|
||||
echo json_encode(["error" => "Error en la consulta SQL: " . $conexionBD->error]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$conciertos = [];
|
||||
|
||||
while ($fila = $resultado->fetch_assoc()) {
|
||||
$id_concierto = $fila['id_concierto'];
|
||||
if (!isset($conciertos[$id_concierto])) {
|
||||
$conciertos[$id_concierto] = [
|
||||
'id' => $id_concierto,
|
||||
'nombre_concierto' => $fila['nombre_concierto'],
|
||||
'artista' => $fila['artista'],
|
||||
'fecha' => $fila['fecha'],
|
||||
'direccion' => $fila['calle'] . ', ' . $fila['colonia'] . ', ' . $fila['numero_direccion'] . ', CP: ' . $fila['codigo_postal'] . ', ' . $fila['estado'],
|
||||
'capacidad_total' => $fila['capacidad_total'],
|
||||
'zonas' => []
|
||||
];
|
||||
}
|
||||
|
||||
if (!empty($fila['nombre_zona'])) {
|
||||
$conciertos[$id_concierto]['zonas'][] = [
|
||||
'nombre_zona' => $fila['nombre_zona'],
|
||||
'capacidad' => $fila['capacidad_zona'],
|
||||
'precio' => $fila['precio']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Convertir el array a JSON y enviarlo
|
||||
echo json_encode(array_values($conciertos), JSON_PRETTY_PRINT);
|
||||
|
||||
$conexionBD->close();
|
||||
?>
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
// Valores para la conexión
|
||||
$direccion = "localhost:3306";
|
||||
$nombreBD = "TicketFei";
|
||||
$usuario = "desarrolloTicketFei";
|
||||
$password = "password";
|
||||
|
||||
// Obtener conexión
|
||||
$conexionBD = new mysqli($direccion, $usuario, $password, $nombreBD);
|
||||
|
||||
// Verificar si hay un error en la conexión
|
||||
if ($conexionBD->connect_error) {
|
||||
die(json_encode(["error" => "Error en la conexión: " . $conexionBD->connect_error]));
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
include 'conexion.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$datos = json_decode(file_get_contents("php://input"), true);
|
||||
|
||||
if (!isset($datos['id'])) {
|
||||
echo json_encode(["eliminacionCorrecta" => false, "error" => "ID de concierto no proporcionado"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = intval($datos['id']);
|
||||
|
||||
// Eliminar las zonas relacionadas con el concierto
|
||||
$consulta_zonas = "DELETE FROM zonas WHERE id_concierto = ?";
|
||||
$stmt_zonas = $conexionBD->prepare($consulta_zonas);
|
||||
$stmt_zonas->bind_param("i", $id);
|
||||
$stmt_zonas->execute();
|
||||
|
||||
// Eliminar el concierto
|
||||
$consulta = "DELETE FROM conciertos WHERE id_concierto = ?";
|
||||
$stmt = $conexionBD->prepare($consulta);
|
||||
$stmt->bind_param("i", $id);
|
||||
$stmt->execute();
|
||||
|
||||
if ($stmt->affected_rows > 0) {
|
||||
echo json_encode(["eliminacionCorrecta" => true]);
|
||||
} else {
|
||||
echo json_encode(["eliminacionCorrecta" => false, "error" => "No se pudo eliminar el concierto"]);
|
||||
}
|
||||
exit;
|
||||
} else {
|
||||
echo json_encode(["error" => "Método no permitido"]);
|
||||
exit;
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
include 'conexion.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
// Leer el JSON enviado
|
||||
$datos = json_decode(file_get_contents("php://input"), true);
|
||||
|
||||
if ($datos === null) {
|
||||
echo json_encode(['insercionCorrecta' => false, 'error' => 'Error al decodificar JSON']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Verificar que los datos requeridos estén presentes
|
||||
if (!isset($datos['nombre_concierto'], $datos['zonas'])) {
|
||||
echo json_encode(['insercionCorrecta' => false, 'error' => 'Faltan datos requeridos']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Extraer valores
|
||||
$nombre_concierto = $datos['nombre_concierto'];
|
||||
$artista = $datos['artista'];
|
||||
$fecha = $datos['fecha'];
|
||||
$calle = $datos['calle'];
|
||||
$colonia = $datos['colonia'];
|
||||
$numero_direccion = $datos['numero_direccion'];
|
||||
$codigo_postal = $datos['codigo_postal'];
|
||||
$estado = $datos['estado'];
|
||||
$capacidad_total = $datos['capacidad_total'];
|
||||
$zonas = $datos['zonas'];
|
||||
|
||||
$conexionBD->begin_transaction();
|
||||
|
||||
try {
|
||||
// Insertar el concierto
|
||||
$consulta = "INSERT INTO conciertos (nombre_concierto, artista, fecha, calle, colonia, numero_direccion, codigo_postal, estado, capacidad_total)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
$stmt = $conexionBD->prepare($consulta);
|
||||
$stmt->bind_param("ssssssssi", $nombre_concierto, $artista, $fecha, $calle, $colonia, $numero_direccion, $codigo_postal, $estado, $capacidad_total);
|
||||
$stmt->execute();
|
||||
|
||||
$id_concierto = $conexionBD->insert_id;
|
||||
$stmt->close();
|
||||
|
||||
// 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]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
$conexionBD->rollback();
|
||||
echo json_encode(['insercionCorrecta' => false, 'error' => $e->getMessage()]);
|
||||
}
|
||||
|
||||
$conexionBD->close();
|
||||
?>
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
session_start();
|
||||
include 'conexion.php';
|
||||
|
||||
$usuario = $_POST['usuario'];
|
||||
$password = $_POST['password'];
|
||||
|
||||
// Prepara la consulta
|
||||
$consulta = "SELECT id, nombre, apellidoPaterno, apellidoMaterno, usuario FROM usuarios WHERE usuario = ? AND contraseña = ?";
|
||||
|
||||
$consultaPreparada = $conexionBD->prepare($consulta);
|
||||
$consultaPreparada->bind_param("ss", $usuario, $password);
|
||||
$consultaPreparada->execute();
|
||||
$resultado = $consultaPreparada->get_result();
|
||||
|
||||
// Verifica si se encontró un colaborador con las credenciales correctas
|
||||
if ($resultado->num_rows > 0) {
|
||||
$fila = $resultado->fetch_assoc();
|
||||
|
||||
// Guarda el ID y el usuario en la sesión
|
||||
$_SESSION['usuarios_id'] = $fila['id'];
|
||||
$_SESSION['usuarios_nombre'] = $fila['nombre'];
|
||||
|
||||
echo json_encode(['loginExitoso' => true, 'usuarios_id' => $fila['id'], 'usuarios_nombre' => $fila['nombre']]);
|
||||
} else {
|
||||
// Credenciales incorrectas
|
||||
echo json_encode(['loginExitoso' => false, 'error' => 'Credenciales inválidas']);
|
||||
}
|
||||
|
||||
$consultaPreparada->close();
|
||||
$conexionBD->close();
|
||||
?>
|
|
@ -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;
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
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" => "ID de concierto no proporcionado"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = intval($_GET['id']);
|
||||
$consulta = "SELECT * FROM conciertos WHERE id_concierto = ?";
|
||||
$stmt = $conexionBD->prepare($consulta);
|
||||
$stmt->bind_param("i", $id);
|
||||
$stmt->execute();
|
||||
$resultado = $stmt->get_result();
|
||||
$concierto = $resultado->fetch_assoc();
|
||||
|
||||
if (!$concierto) {
|
||||
echo json_encode(["error" => "Concierto no encontrado"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$consulta_zonas = "SELECT * FROM zonas WHERE id_concierto = ?";
|
||||
$stmt_zonas = $conexionBD->prepare($consulta_zonas);
|
||||
$stmt_zonas->bind_param("i", $id);
|
||||
$stmt_zonas->execute();
|
||||
$resultado_zonas = $stmt_zonas->get_result();
|
||||
|
||||
$concierto['zonas'] = [];
|
||||
while ($zona = $resultado_zonas->fetch_assoc()) {
|
||||
$concierto['zonas'][] = $zona;
|
||||
}
|
||||
|
||||
echo json_encode($concierto);
|
||||
exit;
|
|
@ -0,0 +1,186 @@
|
|||
body {
|
||||
background-color: #12122B;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
color: #E3E3E3;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
nav {
|
||||
background-color: #12122B;
|
||||
padding: 1rem 2rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.3);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-size: 1.8rem;
|
||||
font-weight: bold;
|
||||
color: #E3E3E3;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 25px;
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
color: #E3E3E3;
|
||||
text-decoration: none;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 500;
|
||||
transition: color 0.3s;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.nav-links a:hover {
|
||||
color: #AAAA91;
|
||||
border-bottom: 3px solid #AAAA91;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
display: flex;
|
||||
background: #383845;
|
||||
padding: 10px;
|
||||
border-radius: 6px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search-container input {
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: #E3E3E3;
|
||||
outline: none;
|
||||
padding: 8px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.search-container button {
|
||||
background: #AAAA91;
|
||||
border: none;
|
||||
padding: 8px 12px;
|
||||
color: #12122B;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.search-container button:hover {
|
||||
background: #848478;
|
||||
}
|
||||
|
||||
#listaConciertos {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
|
||||
gap: 24px;
|
||||
padding: 40px;
|
||||
max-width: 1300px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.concierto-card {
|
||||
background-color: #383845;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.3);
|
||||
transition: transform 0.3s ease-in-out, box-shadow 0.3s ease-in-out;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.concierto-card:hover {
|
||||
transform: translateY(-6px);
|
||||
box-shadow: 0px 10px 20px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.concierto-card img {
|
||||
width: 100%;
|
||||
height: 180px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 16px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 1.3rem;
|
||||
font-weight: bold;
|
||||
color: #E3E3E3;
|
||||
}
|
||||
|
||||
.card-text {
|
||||
font-size: 1rem;
|
||||
color: #C4C4C4;
|
||||
}
|
||||
|
||||
.btn-comprar {
|
||||
width: 100%;
|
||||
background: #5CB85C;
|
||||
color: #12122B;
|
||||
font-weight: bold;
|
||||
padding: 12px;
|
||||
border-radius: 8px;
|
||||
transition: background 0.3s;
|
||||
text-align: center;
|
||||
display: block;
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.btn-comprar:hover {
|
||||
background: #4CAF50;
|
||||
}
|
||||
|
||||
/* Contenedor del menú */
|
||||
.menu-container {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
/* Botón de los tres puntos */
|
||||
.menu-btn {
|
||||
background: #12122B;
|
||||
border: none;
|
||||
font-size: 20px;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
padding: 5px 10px;
|
||||
border-radius: 30%;
|
||||
}
|
||||
|
||||
.menu {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
right: 0;
|
||||
background: #383845;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
/* Opciones del menú */
|
||||
.menu button {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
background: #383845;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.menu button:hover {
|
||||
background: #3e3e48;
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,188 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta http-equiv="refresh" content="5;url=http://fontsgeek.com/fonts/frutiger-bold-italic?ref=readme">
|
||||
<title>Frutiger Bold ItalicFontsgeek</title>
|
||||
<style>
|
||||
/* -------------------------------------
|
||||
GLOBAL
|
||||
------------------------------------- */
|
||||
* {
|
||||
margin:0;
|
||||
padding:0;
|
||||
font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
|
||||
font-size: 100%;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
-webkit-font-smoothing:antialiased;
|
||||
-webkit-text-size-adjust:none;
|
||||
width: 100%!important;
|
||||
height: 100%;
|
||||
background:#DDD;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------
|
||||
ELEMENTS
|
||||
------------------------------------- */
|
||||
a {
|
||||
color: #348eda;
|
||||
}
|
||||
|
||||
.btn-primary, .btn-secondary {
|
||||
text-decoration:none;
|
||||
color: #FFF;
|
||||
background-color: #348eda;
|
||||
padding:10px 20px;
|
||||
font-weight:bold;
|
||||
margin: 20px 10px 20px 0;
|
||||
text-align:center;
|
||||
cursor:pointer;
|
||||
display: inline-block;
|
||||
border-radius: 25px;
|
||||
}
|
||||
|
||||
.btn-secondary{
|
||||
background: #aaa;
|
||||
}
|
||||
|
||||
.last {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.first{
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------
|
||||
BODY
|
||||
------------------------------------- */
|
||||
table.body-wrap {
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
table.body-wrap .container{
|
||||
border: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------
|
||||
FOOTER
|
||||
------------------------------------- */
|
||||
table.footer-wrap {
|
||||
width: 100%;
|
||||
clear:both!important;
|
||||
}
|
||||
|
||||
.footer-wrap .container p {
|
||||
font-size:12px;
|
||||
color:#666;
|
||||
|
||||
}
|
||||
|
||||
table.footer-wrap a{
|
||||
color: #999;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------
|
||||
TYPOGRAPHY
|
||||
------------------------------------- */
|
||||
h1,h2,h3{
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; line-height: 1.1; margin-bottom:15px; color:#000;
|
||||
margin: 40px 0 10px;
|
||||
line-height: 1.2;
|
||||
font-weight:200;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 36px;
|
||||
}
|
||||
h2 {
|
||||
font-size: 28px;
|
||||
}
|
||||
h3 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
p, ul {
|
||||
margin-bottom: 10px;
|
||||
font-weight: normal;
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
ul li {
|
||||
margin-left:5px;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------
|
||||
RESPONSIVENESS
|
||||
Nuke it from orbit. It's the only way to be sure.
|
||||
------------------------------------------------------ */
|
||||
|
||||
/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */
|
||||
.container {
|
||||
display:block!important;
|
||||
max-width:600px!important;
|
||||
margin:0 auto!important; /* makes it centered */
|
||||
clear:both!important;
|
||||
}
|
||||
|
||||
/* This should also be a block element, so that it will fill 100% of the .container */
|
||||
.content {
|
||||
padding:20px;
|
||||
max-width:600px;
|
||||
margin:0 auto;
|
||||
display:block;
|
||||
}
|
||||
|
||||
/* Let's make sure tables in the content area are 100% wide */
|
||||
.content table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#f6f6f6">
|
||||
|
||||
<!-- body -->
|
||||
<table class="body-wrap">
|
||||
<tr>
|
||||
<td></td>
|
||||
<td class="container" bgcolor="#FFFFFF">
|
||||
|
||||
<!-- content -->
|
||||
<div class="content">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<h1>Frutiger Bold Italic</h1>
|
||||
<p>This font was downloaded from <a href="http://fontsgeek.com?ref=readme">fontsgeek.com</a> . You can visit <a href="http://fontsgeek.com?ref=readme">fontsgeek.com</a> for thousands of free fonts.</p>
|
||||
<p><a href="http://fontsgeek.com/fonts/frutiger-bold-italic?ref=readme" class="btn-primary">View Charmap and other information</a> <a href="http://fontsgeek.com?ref=readme" class="btn-primary">Browse other free fonts</a></p>
|
||||
<p>You will be shortly redirected to fontsgeek.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- /content -->
|
||||
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- /body -->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,129 @@
|
|||
body {
|
||||
background-color: #12122B;
|
||||
color: #E3E3E3;
|
||||
font-family: Arial, sans-serif;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* Navbar */
|
||||
.navbar-brand {
|
||||
font-size: 1.8rem;
|
||||
font-weight: bold;
|
||||
color: #E3E3E3;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 25px;
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
color: #E3E3E3;
|
||||
text-decoration: none;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 500;
|
||||
transition: color 0.3s;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.nav-links a:hover {
|
||||
color: #AAAA91;
|
||||
border-bottom: 3px solid #AAAA91;
|
||||
}
|
||||
|
||||
/* Contenedor */
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: 50px auto;
|
||||
padding: 30px;
|
||||
background-color: #1E1E30;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* Formularios */
|
||||
.mb-3 {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: bold;
|
||||
color: #C4C4C4;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
background-color: #282828;
|
||||
color: #E3E3E3;
|
||||
border: 1px solid #444;
|
||||
border-radius: 6px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
background-color: #333;
|
||||
border-color: #AAAA91;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Botones */
|
||||
.btn {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
border-radius: 8px;
|
||||
transition: background 0.3s;
|
||||
margin-top: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.next-btn {
|
||||
background: #5CB85C;
|
||||
color: #12122B;
|
||||
}
|
||||
|
||||
.next-btn:hover {
|
||||
background: #4CAF50;
|
||||
}
|
||||
|
||||
.prev-btn {
|
||||
background: #444;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.prev-btn:hover {
|
||||
background: #666;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
background: #5CB85C;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.submit-btn:hover {
|
||||
background: #4CAF50;
|
||||
}
|
||||
.btn next-btn {
|
||||
background: #5CB85C;
|
||||
}
|
||||
/* Zonas */
|
||||
fieldset {
|
||||
border: 2px solid #444;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
legend {
|
||||
font-weight: bold;
|
||||
color: #E3E3E3;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
/* Ocultar pasos */
|
||||
.d-none {
|
||||
display: none;
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
body {
|
||||
background-color: #12122B;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
.container {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Frutiger';
|
||||
src: url('fonts/Frutiger Bold Italic/Frutiger Bold Italic.ttf') format('truetype');
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: 'Frutiger', sans-serif;
|
||||
color: #ffffff;
|
||||
font-size: 100px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: 'Frutiger', sans-serif;
|
||||
color: #ffffff;
|
||||
font-size: 24px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #ffffff;
|
||||
font-size: 24px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
|
||||
.card {
|
||||
background-color: #1E1E30;
|
||||
padding: 30px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.datos {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: left;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.datos label {
|
||||
font-size: 14px;
|
||||
color: #ffffff;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.datos input {
|
||||
padding: 10px;
|
||||
border: 1px solid #495057;
|
||||
border-radius: 5px;
|
||||
background-color: #343a40;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.boton {
|
||||
text-align: center;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
#btnIniciarSesion {
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
background-color: #5CB85C;
|
||||
border: none;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#btnIniciarSesion:hover {
|
||||
background-color: #4CAF50;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.182);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.modal-contenido {
|
||||
background: #343d46;
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
modal-contenido p{
|
||||
color: black;
|
||||
}
|
||||
|
||||
.btn-modal {
|
||||
padding: 10px 20px;
|
||||
background: #1c1b2b;
|
||||
color: white;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.btn-modal:hover {
|
||||
background: #0056b3;
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.modal-contenido {
|
||||
background: #25253e;
|
||||
width: 300px;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.modal-contenido p {
|
||||
color: #ffffff;
|
||||
font-size: 16px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
|
||||
.btn-modal {
|
||||
margin-top: 10px;
|
||||
padding: 10px 20px;
|
||||
background: #1c1b2b;
|
||||
color: white;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
font-size: 14px;
|
||||
transition: background 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.btn-modal:hover {
|
||||
background: #0056b3;
|
||||
}
|
||||
|
||||
.modal-confirmacion {
|
||||
background: #2b2b3a;
|
||||
width: 320px;
|
||||
padding: 25px;
|
||||
border-radius: 12px;
|
||||
text-align: center;
|
||||
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
#btnCancelarEliminar {
|
||||
background: #5a6268;
|
||||
}
|
||||
|
||||
#btnCancelarEliminar:hover {
|
||||
background: #444b50;
|
||||
}
|
||||
|
||||
#btnConfirmarEliminar{
|
||||
background-color: #f5524c;
|
||||
}
|
||||
|
||||
#btnConfirmarEliminar:hover{
|
||||
background: #c9302c;
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
/* Contenedor principal */
|
||||
.main-container {
|
||||
display: flex;
|
||||
height: 80vh;
|
||||
gap: 20px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* Lado izquierdo */
|
||||
.cardIzq {
|
||||
flex: 2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.cardIzq img {
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
height: 400px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.cardIzq h2 {
|
||||
font-size: 44px;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.zones-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
margin-top: 15px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Lado derecho (tarjetas en columna) */
|
||||
.cardDer {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column; /* Se colocan en columna */
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 20px; /* Espacio entre las tarjetas */
|
||||
}
|
||||
|
||||
.card {
|
||||
background: #1E1E30;
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
box-shadow: 0px 6px 12px rgba(0, 0, 0, 0.3);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Estilos para cada asiento */
|
||||
.asiento {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
transition: all 0.2s ease;
|
||||
user-select: none;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
/* Iconos dentro de los asientos */
|
||||
.asiento i {
|
||||
font-size: 24px; /* Ajusta el tamaño del icono */
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
body {
|
||||
background-color: #aab2b2;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.btn-outline-light {
|
||||
border-color: 5CB85C;
|
||||
}
|
||||
|
||||
.btn-outline-light:hover {
|
||||
background-color: 4CAF50;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.card {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #343a40;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #5CB85C;
|
||||
border-color: #5CB85C;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: #4CAF50;
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background-color: #dc3545;
|
||||
border-color: #a71d2a;
|
||||
}
|
||||
|
||||
.btn-danger:hover {
|
||||
background-color: #a71d2a;
|
||||
}
|
||||
.contenedor-conciertos {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.tarjeta-concierto {
|
||||
background-color: #343a40;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1);
|
||||
width: 90%;
|
||||
max-width: 600px;
|
||||
margin: auto;
|
||||
}
|
||||
.tarjeta-concierto p, h2, h3, li {
|
||||
color:#ffff
|
||||
}
|
||||
#tituloListaConciertos{
|
||||
color:#343a40
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Editar Concierto</title>
|
||||
<link rel="stylesheet" href="css/conciertos.css">
|
||||
<link rel="stylesheet" href="css/formulario.css">
|
||||
<link rel="stylesheet" href="css/modalActualizar.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Navbar -->
|
||||
<nav>
|
||||
<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>
|
||||
<a href="#">Reporte Ventas</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Contenedor -->
|
||||
<div class="container">
|
||||
<h2 class="text-center">Editar Concierto</h2>
|
||||
<form id="formulario">
|
||||
|
||||
<!-- Paso 1: Datos generales -->
|
||||
<div id="paso1">
|
||||
<div class="mb-3">
|
||||
<label for="nombre_concierto">Nombre del Concierto:</label>
|
||||
<input type="text" id="nombre_concierto" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="artista">Artista:</label>
|
||||
<input type="text" id="artista" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="fecha">Fecha del Concierto:</label>
|
||||
<input type="date" id="fecha" required>
|
||||
</div>
|
||||
<button type="button" class="btn next-btn" onclick="siguientePaso(2)">Siguiente</button>
|
||||
</div>
|
||||
|
||||
<!-- Paso 2: Dirección -->
|
||||
<div id="paso2" class="d-none">
|
||||
<div class="mb-3">
|
||||
<label for="calle">Calle:</label>
|
||||
<input type="text" id="calle" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="colonia">Colonia:</label>
|
||||
<input type="text" id="colonia" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="numero_direccion">Número exterior:</label>
|
||||
<input type="text" id="numero_direccion" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="codigo_postal">Código Postal:</label>
|
||||
<input type="text" id="codigo_postal" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="estado">Estado:</label>
|
||||
<input type="text" id="estado" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="capacidad_total">Capacidad Total:</label>
|
||||
<input type="number" id="capacidad_total" required>
|
||||
</div>
|
||||
<button type="button" class="btn prev-btn" onclick="siguientePaso(1)">Anterior</button>
|
||||
<button type="button" class="btn next-btn" onclick="siguientePaso(3)">Siguiente</button>
|
||||
</div>
|
||||
|
||||
<!-- Paso 3: Zonas -->
|
||||
<div id="paso3" class="d-none">
|
||||
<fieldset>
|
||||
<legend>Zonas</legend>
|
||||
|
||||
<div class="mb-3">
|
||||
<label>Zona General - Capacidad:</label>
|
||||
<input type="number" id="capacidad_general" required oninput="actualizarCapacidad()">
|
||||
<label>Precio:</label>
|
||||
<input type="number" step="0.01" id="precio_general" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label>Zona Plata - Capacidad:</label>
|
||||
<input type="number" id="capacidad_plata" required oninput="actualizarCapacidad()">
|
||||
<label>Precio:</label>
|
||||
<input type="number" step="0.01" id="precio_plata" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label>Zona Oro - Capacidad:</label>
|
||||
<input type="number" id="capacidad_oro" required oninput="actualizarCapacidad()">
|
||||
<label>Precio:</label>
|
||||
<input type="number" step="0.01" id="precio_oro" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label>Zona VIP - Capacidad:</label>
|
||||
<input type="number" id="capacidad_vip" required oninput="actualizarCapacidad()">
|
||||
<label>Precio:</label>
|
||||
<input type="number" step="0.01" id="precio_vip" required>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<!-- Agregar capacidad disponible -->
|
||||
<p>Capacidad disponible: <span id="capacidad_disponible">0</span></p>
|
||||
|
||||
<button type="button" class="btn prev-btn" onclick="siguientePaso(2)">Anterior</button>
|
||||
<button type="submit" class="btn submit-btn">Actualizar Concierto</button>
|
||||
</div>
|
||||
</form>
|
||||
<div id="mensaje" class="mt-3 text-center"></div>
|
||||
</div>
|
||||
|
||||
<div id="modalMensaje" class="modal">
|
||||
<div class="modal-contenido">
|
||||
<p id="modalTexto"></p>
|
||||
<button id="cerrarModal" class="btn-modal">Cerrar</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="js/editarConcierto.js"></script>
|
||||
</body>
|
||||
</html>
|
Binary file not shown.
After ![]() (image error) Size: 32 KiB |
Binary file not shown.
After ![]() (image error) Size: 112 KiB |
Binary file not shown.
After ![]() (image error) Size: 62 KiB |
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Login</title>
|
||||
<link rel="stylesheet" href="css/login.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>TicketFei</h1>
|
||||
<h2>Inicio de sesión</h2>
|
||||
<div class="card">
|
||||
<form id="formularioLogin">
|
||||
<div class="datos">
|
||||
<label for="user">Usuario</label>
|
||||
<input type="text" id="user" name="user" placeholder="Ingresa tu usuario" required>
|
||||
</div>
|
||||
<div class="datos">
|
||||
<label for="pw">Contraseña</label>
|
||||
<input type="password" id="pw" name="pw" placeholder="Ingresa tu contraseña" required>
|
||||
</div>
|
||||
<div class="boton">
|
||||
<input type="submit" id="btnIniciarSesion" value="Ingresar">
|
||||
</div>
|
||||
</form>
|
||||
<div id="mensaje"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/login.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,188 @@
|
|||
document.addEventListener("DOMContentLoaded", () => {
|
||||
cargarConciertos();
|
||||
});
|
||||
|
||||
const listaConciertos = document.getElementById("listaConciertos");
|
||||
const buscadorBoton = document.getElementById("buscadorBoton");
|
||||
const buscadorInput = document.getElementById("buscadorColaborador");
|
||||
const modal = document.getElementById("modalMensaje");
|
||||
const modalTexto = document.getElementById("modalTexto");
|
||||
const cerrarModal = document.getElementById("cerrarModal");
|
||||
const modalConfirmacion = document.getElementById("modalConfirmacion");
|
||||
const modalConfirmarTexto = document.getElementById("modalConfirmarTexto");
|
||||
const btnConfirmarEliminar = document.getElementById("btnConfirmarEliminar");
|
||||
const btnCancelarEliminar = document.getElementById("btnCancelarEliminar");
|
||||
let conciertoIdEliminar = null; // Para almacenar el ID del concierto a eliminar
|
||||
|
||||
// Ocultar modales al inicio
|
||||
modal.style.display = "none";
|
||||
modalConfirmacion.style.display = "none";
|
||||
|
||||
// Función para mostrar modal de mensaje (confirmación de eliminación exitosa)
|
||||
function mostrarModal(mensaje) {
|
||||
modalTexto.textContent = mensaje;
|
||||
modal.style.display = "flex";
|
||||
setTimeout(() => {
|
||||
modal.style.display = "none";
|
||||
}, 2000); // Se cierra automáticamente en 2 segundos
|
||||
}
|
||||
|
||||
// Función para mostrar el modal de confirmación antes de eliminar
|
||||
function mostrarModalConfirmacion(id) {
|
||||
conciertoIdEliminar = id;
|
||||
modalConfirmarTexto.textContent = "¿Estás seguro de que deseas eliminar este concierto?";
|
||||
modalConfirmacion.style.display = "flex";
|
||||
}
|
||||
|
||||
// Evento para cerrar el modal de confirmación sin eliminar
|
||||
btnCancelarEliminar.addEventListener("click", () => {
|
||||
modalConfirmacion.style.display = "none";
|
||||
});
|
||||
|
||||
// Evento para confirmar eliminación
|
||||
btnConfirmarEliminar.addEventListener("click", async () => {
|
||||
if (conciertoIdEliminar) {
|
||||
await eliminarConcierto(conciertoIdEliminar);
|
||||
}
|
||||
modalConfirmacion.style.display = "none"; // Cierra el modal después de eliminar
|
||||
});
|
||||
|
||||
// Evento para cerrar el modal de mensaje manualmente
|
||||
cerrarModal.addEventListener("click", () => {
|
||||
modal.style.display = "none";
|
||||
});
|
||||
|
||||
window.addEventListener("click", (event) => {
|
||||
if (event.target === modal) {
|
||||
modal.style.display = "none";
|
||||
}
|
||||
if (event.target === modalConfirmacion) {
|
||||
modalConfirmacion.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
async function cargarConciertos(filtro = "") {
|
||||
try {
|
||||
const respuesta = await fetch('controladores/conciertos.php');
|
||||
if (!respuesta.ok) throw new Error("Error al cargar conciertos");
|
||||
|
||||
const conciertos = await respuesta.json();
|
||||
listaConciertos.innerHTML = "";
|
||||
|
||||
const conciertosFiltrados = filtro
|
||||
? conciertos.filter(c => c.nombre_concierto.toLowerCase().includes(filtro.toLowerCase()))
|
||||
: conciertos;
|
||||
|
||||
if (conciertosFiltrados.length === 0) {
|
||||
listaConciertos.innerHTML = `<p class="text-red-500 text-center">No se encontraron conciertos.</p>`;
|
||||
return;
|
||||
}
|
||||
|
||||
let tarjetas = [];
|
||||
|
||||
conciertosFiltrados.forEach((concierto) => {
|
||||
const tarjeta = document.createElement("div");
|
||||
tarjeta.classList.add("concierto-card");
|
||||
|
||||
let zonasHTML = "";
|
||||
if (concierto.zonas.length > 0) {
|
||||
zonasHTML = `<ul class="text-sm text-gray-300 mt-2">`;
|
||||
concierto.zonas.forEach(zona => {
|
||||
zonasHTML += `<li>🔹 ${zona.nombre_zona}: <b>${zona.capacidad} asientos</b> - $${zona.precio}</li>`;
|
||||
});
|
||||
zonasHTML += `</ul>`;
|
||||
}
|
||||
|
||||
tarjeta.innerHTML = `
|
||||
<div class="menu-container">
|
||||
<button class="menu-btn">⋮</button>
|
||||
<div class="menu">
|
||||
<button class="edit" data-id="${concierto.id}">Editar</button>
|
||||
<button class="delete" data-id="${concierto.id}">Eliminar</button>
|
||||
</div>
|
||||
</div>
|
||||
<img src="img/concierto_${concierto.id}.jpg" alt="Concierto" class="card-img">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title">${concierto.nombre_concierto}</h3>
|
||||
<p class="card-text">🎤 ${concierto.artista}</p>
|
||||
<p class="card-text">📅 ${concierto.fecha}</p>
|
||||
<p class="card-text">📍 ${concierto.direccion || 'No definida'}</p>
|
||||
<p class="card-text">🎟 ${concierto.capacidad_total} Asistentes</p>
|
||||
${zonasHTML}
|
||||
</div>
|
||||
<button class="btn-comprar" data-id="${concierto.id}">Comprar Boletos</button>
|
||||
`;
|
||||
|
||||
// Evento para editar
|
||||
tarjeta.querySelector(".edit").addEventListener("click", () => {
|
||||
window.location.href = `editarConciertos.html?id=${concierto.id}`;
|
||||
});
|
||||
|
||||
// Evento para eliminar usando el modal de confirmación
|
||||
tarjeta.querySelector(".delete").addEventListener("click", (e) => {
|
||||
const id = e.target.dataset.id;
|
||||
mostrarModalConfirmacion(id);
|
||||
});
|
||||
|
||||
tarjeta.querySelector(".btn-comprar").addEventListener("click", (e) => {
|
||||
const id = e.target.dataset.id;
|
||||
window.location.href = `ventaBoletos.html?id=${id}`;
|
||||
});
|
||||
|
||||
listaConciertos.appendChild(tarjeta);
|
||||
tarjetas.push(tarjeta);
|
||||
});
|
||||
|
||||
gsap.fromTo(
|
||||
tarjetas,
|
||||
{ opacity: 0, scale: 0.9 },
|
||||
{ opacity: 1, scale: 1, duration: 0.6, stagger: 0.2, ease: "power3.out" }
|
||||
);
|
||||
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
listaConciertos.innerHTML = `<p class="text-red-500">No se pudieron cargar los conciertos.</p>`;
|
||||
}
|
||||
}
|
||||
|
||||
buscadorBoton.addEventListener('click', (event) => {
|
||||
event.preventDefault();
|
||||
const termino = buscadorInput.value.trim();
|
||||
cargarConciertos(termino);
|
||||
});
|
||||
|
||||
document.addEventListener("click", (e) => {
|
||||
if (e.target.classList.contains("menu-btn")) {
|
||||
e.stopPropagation();
|
||||
let menu = e.target.nextElementSibling;
|
||||
menu.style.display = menu.style.display === "block" ? "none" : "block";
|
||||
} else {
|
||||
document.querySelectorAll(".menu").forEach(menu => {
|
||||
menu.style.display = "none";
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/** 🔹 Función para eliminar el concierto usando modal */
|
||||
async function eliminarConcierto(id) {
|
||||
try {
|
||||
const respuesta = await fetch("controladores/eliminar_concierto.php", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify({ id })
|
||||
});
|
||||
|
||||
const resultado = await respuesta.json();
|
||||
if (resultado.eliminacionCorrecta) {
|
||||
mostrarModal("Concierto eliminado correctamente");
|
||||
cargarConciertos(); // Recargar la lista
|
||||
} else {
|
||||
mostrarModal("Error al eliminar el concierto");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
mostrarModal("Error de conexión con el servidor");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const formulario = document.getElementById("formulario");
|
||||
const mensajeDiv = document.getElementById("mensaje");
|
||||
let capacidadTotal = 0;
|
||||
|
||||
function siguientePaso(paso) {
|
||||
document.querySelectorAll("[id^='paso']").forEach(p => p.classList.add("d-none"));
|
||||
document.getElementById(`paso${paso}`).classList.remove("d-none");
|
||||
|
||||
if (paso === 3) {
|
||||
capacidadTotal = parseInt(document.getElementById("capacidad_total").value) || 0;
|
||||
const capacidadDisponible = document.getElementById("capacidad_disponible");
|
||||
if (capacidadDisponible) {
|
||||
capacidadDisponible.textContent = capacidadTotal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function actualizarCapacidad() {
|
||||
let asignado = 0;
|
||||
["capacidad_general", "capacidad_plata", "capacidad_oro", "capacidad_vip"].forEach(id => {
|
||||
const input = document.getElementById(id);
|
||||
if (input) {
|
||||
asignado += parseInt(input.value) || 0;
|
||||
}
|
||||
});
|
||||
|
||||
const restante = capacidadTotal - asignado;
|
||||
const capacidadDisponible = document.getElementById("capacidad_disponible");
|
||||
if (capacidadDisponible) {
|
||||
capacidadDisponible.textContent = restante < 0 ? "Excede la capacidad total" : restante;
|
||||
}
|
||||
}
|
||||
|
||||
formulario.addEventListener("submit", async (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const capacidadDisponible = document.getElementById("capacidad_disponible");
|
||||
if (capacidadDisponible && parseInt(capacidadDisponible.textContent) < 0) {
|
||||
mensajeDiv.innerHTML = '<div class="alert alert-danger">Error: La suma de capacidades de zonas no puede exceder la capacidad total.</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
// 🔹 Construir objeto JSON con todas las zonas
|
||||
const datosConcierto = {
|
||||
nombre_concierto: document.getElementById("nombre_concierto").value.trim(),
|
||||
artista: document.getElementById("artista").value.trim(),
|
||||
fecha: document.getElementById("fecha").value,
|
||||
calle: document.getElementById("calle").value.trim(),
|
||||
colonia: document.getElementById("colonia").value.trim(),
|
||||
numero_direccion: document.getElementById("numero_direccion").value.trim(),
|
||||
codigo_postal: document.getElementById("codigo_postal").value.trim(),
|
||||
estado: document.getElementById("estado").value.trim(),
|
||||
capacidad_total: capacidadTotal,
|
||||
zonas: [
|
||||
{
|
||||
nombre_zona: "General",
|
||||
capacidad: parseInt(document.getElementById("capacidad_general").value) || 0,
|
||||
precio: parseFloat(document.getElementById("precio_general").value) || 0
|
||||
},
|
||||
{
|
||||
nombre_zona: "Plata",
|
||||
capacidad: parseInt(document.getElementById("capacidad_plata").value) || 0,
|
||||
precio: parseFloat(document.getElementById("precio_plata").value) || 0
|
||||
},
|
||||
{
|
||||
nombre_zona: "Oro",
|
||||
capacidad: parseInt(document.getElementById("capacidad_oro").value) || 0,
|
||||
precio: parseFloat(document.getElementById("precio_oro").value) || 0
|
||||
},
|
||||
{
|
||||
nombre_zona: "VIP",
|
||||
capacidad: parseInt(document.getElementById("capacidad_vip").value) || 0,
|
||||
precio: parseFloat(document.getElementById("precio_vip").value) || 0
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
console.log("Enviando datos:", JSON.stringify(datosConcierto)); // Depuración
|
||||
|
||||
try {
|
||||
const respuesta = await fetch("controladores/insertar_concierto.php", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(datosConcierto)
|
||||
});
|
||||
|
||||
const resultado = await respuesta.json();
|
||||
console.log("Respuesta del servidor:", resultado); // Depuración
|
||||
|
||||
if (!resultado.insercionCorrecta) {
|
||||
throw new Error(resultado.error || "Error al guardar el concierto");
|
||||
}
|
||||
|
||||
mensajeDiv.innerHTML = '<div class="alert alert-success">Concierto registrado correctamente.</div>';
|
||||
|
||||
setTimeout(() => {
|
||||
window.location.href = "ventanaConciertos.html";
|
||||
}, 2000);
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error:", error);
|
||||
mensajeDiv.innerHTML = `<div class="alert alert-danger">Error: ${error.message}</div>`;
|
||||
}
|
||||
});
|
||||
|
||||
window.siguientePaso = siguientePaso;
|
||||
window.actualizarCapacidad = actualizarCapacidad;
|
||||
});
|
|
@ -0,0 +1,194 @@
|
|||
const params = new URLSearchParams(window.location.search);
|
||||
const conciertoId = params.get("id");
|
||||
const formulario = document.getElementById("formulario");
|
||||
const modal = document.getElementById("modalMensaje");
|
||||
const modalTexto = document.getElementById("modalTexto");
|
||||
const cerrarModal = document.getElementById("cerrarModal");
|
||||
let capacidadTotal = 0;
|
||||
|
||||
modal.style.display = "none";
|
||||
|
||||
function mostrarModal(mensaje) {
|
||||
modalTexto.textContent = mensaje;
|
||||
modal.style.display = "flex";
|
||||
}
|
||||
|
||||
cerrarModal.addEventListener("click", () => {
|
||||
modal.style.display = "none";
|
||||
});
|
||||
|
||||
window.addEventListener("click", (event) => {
|
||||
if (event.target === modal) {
|
||||
modal.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
function siguientePaso(paso) {
|
||||
document.querySelectorAll("[id^='paso']").forEach(p => p.classList.add("d-none"));
|
||||
document.getElementById(`paso${paso}`).classList.remove("d-none");
|
||||
|
||||
if (paso === 3) {
|
||||
capacidadTotal = parseInt(document.getElementById("capacidad_total").value) || 0;
|
||||
document.getElementById("capacidad_disponible").textContent = capacidadTotal;
|
||||
// ✅ Llamar a actualizar capacidad después de cargar los datos
|
||||
actualizarCapacidad();
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ Función para actualizar la capacidad disponible
|
||||
function actualizarCapacidad() {
|
||||
let sumaZonas = 0;
|
||||
["capacidad_general", "capacidad_plata", "capacidad_oro", "capacidad_vip"].forEach(id => {
|
||||
sumaZonas += parseInt(document.getElementById(id).value) || 0;
|
||||
});
|
||||
|
||||
let capacidadDisponibleElement = document.getElementById("capacidad_disponible");
|
||||
let restante = capacidadTotal - sumaZonas;
|
||||
|
||||
if (restante < 0) {
|
||||
capacidadDisponibleElement.textContent = "⚠️ Excede la capacidad total";
|
||||
capacidadDisponibleElement.style.color = "red";
|
||||
} else if (restante > 0) {
|
||||
capacidadDisponibleElement.textContent = `⚠️ Faltan ${restante} lugares`;
|
||||
capacidadDisponibleElement.style.color = "orange";
|
||||
} else {
|
||||
capacidadDisponibleElement.textContent = `✅ Todo correcto`;
|
||||
capacidadDisponibleElement.style.color = "green";
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ Función para validar la capacidad antes de actualizar
|
||||
function validarCapacidadZonas() {
|
||||
let sumaZonas = 0;
|
||||
["capacidad_general", "capacidad_plata", "capacidad_oro", "capacidad_vip"].forEach(id => {
|
||||
sumaZonas += parseInt(document.getElementById(id).value) || 0;
|
||||
});
|
||||
|
||||
let capacidadTotalInput = parseInt(document.getElementById("capacidad_total").value);
|
||||
|
||||
if (sumaZonas < capacidadTotalInput) {
|
||||
mostrarModal(`⚠️ Error: La suma de las capacidades es menor`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sumaZonas > capacidadTotalInput) {
|
||||
mostrarModal(`⚠️ Error: La suma de las capacidades es mayor`);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ✅ Bloquear la actualización si la validación no pasa
|
||||
formulario.addEventListener("submit", async (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (!validarCapacidadZonas()) {
|
||||
return; // 🚫 Bloquear la actualización si la validación falla
|
||||
}
|
||||
|
||||
await actualizarConcierto(conciertoId);
|
||||
});
|
||||
|
||||
// ✅ Función para cargar los datos del concierto
|
||||
async function cargarDatosConcierto(id) {
|
||||
try {
|
||||
const respuesta = await fetch(`/ProyectoTicketFei/controladores/obtener_concierto.php?id=${id}`);
|
||||
if (!respuesta.ok) throw new Error("Error al cargar los datos del concierto");
|
||||
|
||||
const concierto = await respuesta.json();
|
||||
|
||||
document.getElementById("nombre_concierto").value = concierto.nombre_concierto;
|
||||
document.getElementById("artista").value = concierto.artista;
|
||||
document.getElementById("fecha").value = concierto.fecha;
|
||||
document.getElementById("calle").value = concierto.calle;
|
||||
document.getElementById("colonia").value = concierto.colonia;
|
||||
document.getElementById("numero_direccion").value = concierto.numero_direccion;
|
||||
document.getElementById("codigo_postal").value = concierto.codigo_postal;
|
||||
document.getElementById("estado").value = concierto.estado;
|
||||
document.getElementById("capacidad_total").value = concierto.capacidad_total;
|
||||
capacidadTotal = parseInt(concierto.capacidad_total); // Guardar la capacidad total
|
||||
|
||||
if (concierto.zonas && concierto.zonas.length > 0) {
|
||||
concierto.zonas.forEach(zona => {
|
||||
switch (zona.nombre_zona) {
|
||||
case "General":
|
||||
document.getElementById("capacidad_general").value = zona.capacidad;
|
||||
document.getElementById("precio_general").value = zona.precio;
|
||||
break;
|
||||
case "Plata":
|
||||
document.getElementById("capacidad_plata").value = zona.capacidad;
|
||||
document.getElementById("precio_plata").value = zona.precio;
|
||||
break;
|
||||
case "Oro":
|
||||
document.getElementById("capacidad_oro").value = zona.capacidad;
|
||||
document.getElementById("precio_oro").value = zona.precio;
|
||||
break;
|
||||
case "VIP":
|
||||
document.getElementById("capacidad_vip").value = zona.capacidad;
|
||||
document.getElementById("precio_vip").value = zona.precio;
|
||||
break;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.warn("⚠️ No se encontraron zonas para este concierto.");
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error("❌ Error en cargarDatosConcierto:", error);
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ Función para actualizar el concierto
|
||||
async function actualizarConcierto(id) {
|
||||
if (!validarCapacidadZonas()) return; // 🚫 Bloquear la actualización si la validación falla
|
||||
|
||||
const datosConcierto = {
|
||||
id: id,
|
||||
nombre_concierto: document.getElementById("nombre_concierto").value.trim(),
|
||||
artista: document.getElementById("artista").value.trim(),
|
||||
fecha: document.getElementById("fecha").value,
|
||||
calle: document.getElementById("calle").value.trim(),
|
||||
colonia: document.getElementById("colonia").value.trim(),
|
||||
numero_direccion: document.getElementById("numero_direccion").value.trim(),
|
||||
codigo_postal: document.getElementById("codigo_postal").value.trim(),
|
||||
estado: document.getElementById("estado").value.trim(),
|
||||
capacidad_total: document.getElementById("capacidad_total").value,
|
||||
zonas: [
|
||||
{ nombre_zona: "General", capacidad: document.getElementById("capacidad_general").value, precio: document.getElementById("precio_general").value },
|
||||
{ nombre_zona: "Plata", capacidad: document.getElementById("capacidad_plata").value, precio: document.getElementById("precio_plata").value },
|
||||
{ nombre_zona: "Oro", capacidad: document.getElementById("capacidad_oro").value, precio: document.getElementById("precio_oro").value },
|
||||
{ nombre_zona: "VIP", capacidad: document.getElementById("capacidad_vip").value, precio: document.getElementById("precio_vip").value }
|
||||
]
|
||||
};
|
||||
|
||||
try {
|
||||
const respuesta = await fetch("/ProyectoTicketFei/controladores/actualizar_concierto.php", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(datosConcierto)
|
||||
});
|
||||
|
||||
const resultado = await respuesta.json();
|
||||
if (resultado.actualizacionCorrecta) {
|
||||
mostrarModal("✅ Concierto actualizado correctamente");
|
||||
setTimeout(() => {
|
||||
window.location.href = "ventanaConciertos.html";
|
||||
}, 2000);
|
||||
} else {
|
||||
mostrarModal("⚠️ Error al actualizar el concierto");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
mostrarModal("⚠️ Error de conexión con el servidor");
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ Llamar a cargar los datos cuando la página cargue
|
||||
(async function () {
|
||||
if (conciertoId) {
|
||||
await cargarDatosConcierto(conciertoId);
|
||||
}
|
||||
})();
|
|
@ -0,0 +1,32 @@
|
|||
const formulario = document.getElementById('formularioLogin');
|
||||
const notificacion = document.getElementById('mensaje');
|
||||
|
||||
formulario.addEventListener('submit', async (event) => {
|
||||
|
||||
event.preventDefault();
|
||||
const usuario = document.getElementById("user").value;
|
||||
const password = document.getElementById("pw").value;
|
||||
|
||||
const data = new FormData();
|
||||
data.append('usuario', usuario);
|
||||
data.append('password', password);
|
||||
|
||||
try {
|
||||
|
||||
const respuestaPeticion = await fetch('controladores/login.php', {
|
||||
method: 'POST',
|
||||
body: data
|
||||
});
|
||||
const verificarCredenciales = await respuestaPeticion.json();
|
||||
if (verificarCredenciales.loginExitoso) {
|
||||
window.location.href = 'ventanaConciertos.html';
|
||||
} else {
|
||||
notificacion.textContent ="Usuario o contraseña incorrecta";
|
||||
notificacion.style.color='#ffffff';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
notificacion.textContent = 'Lo sentimos, el servicio no está disponible por el momento.';
|
||||
notificacion.style.color = '#ff0000';
|
||||
}
|
||||
});
|
|
@ -0,0 +1,137 @@
|
|||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const conciertoId = params.get("id");
|
||||
|
||||
if (!conciertoId) {
|
||||
console.error("Error: No se proporcionó un ID de concierto en la URL.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
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);
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error al obtener los datos del concierto:", error);
|
||||
}
|
||||
});
|
||||
|
||||
async function cargarDatosZona(zona) {
|
||||
if (!zona) {
|
||||
console.error("Error: Datos de zona no disponibles");
|
||||
return;
|
||||
}
|
||||
|
||||
// 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 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();
|
||||
|
||||
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}`);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
document.getElementById("comprarBoletos").disabled = asientosSeleccionados.size === 0;
|
||||
}
|
||||
|
||||
document.getElementById("comprarBoletos").addEventListener("click", async () => {
|
||||
if (asientosSeleccionados.size === 0) return;
|
||||
|
||||
try {
|
||||
const respuesta = await fetch("controladores/comprar_asiento.php", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ asientos: Array.from(asientosSeleccionados) })
|
||||
});
|
||||
|
||||
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 al comprar boletos:", error);
|
||||
}
|
||||
});
|
|
@ -0,0 +1,63 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<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">
|
||||
<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>
|
||||
<a href="ventanaInsertarConcierto.html" class="navbar-brand">TicketFei</a>
|
||||
<div class="nav-links">
|
||||
<a href="ventanaInsertarConcierto.html">Crear Conciertos</a>
|
||||
<a href="ventanaConciertos.html">Ver Conciertos</a>
|
||||
<a href="#">Reporte Ventas</a>
|
||||
</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 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 del concierto</h2>
|
||||
<div id="zona-info" class="space-y-2">
|
||||
<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>
|
||||
|
||||
<!-- 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>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,49 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Registro de Conciertos</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">
|
||||
<link rel="stylesheet" href="css/modalEliminar.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav>
|
||||
<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>
|
||||
<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 id="listaConciertos"></div>
|
||||
|
||||
<!-- Modal de mensaje -->
|
||||
<div id="modalMensaje" class="modal">
|
||||
<div id="modalPanel" class="modal-contenido">
|
||||
<p id="modalTexto"></p>
|
||||
<button id="cerrarModal" class="btn-modal">Cerrar</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal de confirmación -->
|
||||
<div id="modalConfirmacion" class="modal">
|
||||
<div class="modal-contenido">
|
||||
<p id="modalConfirmarTexto"></p>
|
||||
<button id="btnCancelarEliminar" class="btn-modal">Cancelar</button>
|
||||
<button id="btnConfirmarEliminar" class="btn-modal">Eliminar</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="js/conciertos.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,117 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Registrar Concierto</title>
|
||||
<link rel="stylesheet" href="css/conciertos.css">
|
||||
<link rel="stylesheet" href="css/formulario.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Navbar -->
|
||||
<nav>
|
||||
<a href="ventanaInsertarConcierto.html" class="navbar-brand">TicketFei</a>
|
||||
<div class="nav-links">
|
||||
<a href="ventanaInsertarConcierto.html">Crear Conciertos</a>
|
||||
<a href="ventanaConciertos.html">Ver Conciertos</a>
|
||||
<a href="#">Reporte Ventas</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Contenedor -->
|
||||
<div class="container">
|
||||
<h2 class="text-center">Registrar Concierto</h2>
|
||||
<form id="formulario">
|
||||
|
||||
<!-- Paso 1: Datos generales -->
|
||||
<div id="paso1">
|
||||
<div class="mb-3">
|
||||
<label for="nombre_concierto">Nombre del Concierto:</label>
|
||||
<input type="text" id="nombre_concierto" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="artista">Artista:</label>
|
||||
<input type="text" id="artista" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="fecha">Fecha del Concierto:</label>
|
||||
<input type="date" id="fecha" required>
|
||||
</div>
|
||||
<button type="button" class="btn next-btn" onclick="siguientePaso(2)">Siguiente</button>
|
||||
</div>
|
||||
|
||||
<!-- Paso 2: Dirección -->
|
||||
<div id="paso2" class="d-none">
|
||||
<div class="mb-3">
|
||||
<label for="calle">Calle:</label>
|
||||
<input type="text" id="calle" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="colonia">Colonia:</label>
|
||||
<input type="text" id="colonia" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="numero_direccion">Número exterior:</label>
|
||||
<input type="text" id="numero_direccion" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="codigo_postal">Código Postal:</label>
|
||||
<input type="text" id="codigo_postal" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="estado">Estado:</label>
|
||||
<input type="text" id="estado" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="capacidad_total">Capacidad Total:</label>
|
||||
<input type="number" id="capacidad_total" required>
|
||||
</div>
|
||||
<button type="button" class="btn prev-btn" onclick="siguientePaso(1)">Anterior</button>
|
||||
<button type="button" class="btn next-btn" onclick="siguientePaso(3)">Siguiente</button>
|
||||
</div>
|
||||
|
||||
<!-- Paso 3: Zonas -->
|
||||
<div id="paso3" class="d-none">
|
||||
<fieldset>
|
||||
<legend>Zonas</legend>
|
||||
|
||||
|
||||
<div class="mb-3">
|
||||
<label>Zona General - Capacidad:</label>
|
||||
<input type="number" id="capacidad_general" required oninput="actualizarCapacidad()">
|
||||
<label>Precio:</label>
|
||||
<input type="number" step="0.01" id="precio_general" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label>Zona Plata - Capacidad:</label>
|
||||
<input type="number" id="capacidad_plata" required oninput="actualizarCapacidad()">
|
||||
<label>Precio:</label>
|
||||
<input type="number" step="0.01" id="precio_plata" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label>Zona Oro - Capacidad:</label>
|
||||
<input type="number" id="capacidad_oro" required oninput="actualizarCapacidad()">
|
||||
<label>Precio:</label>
|
||||
<input type="number" step="0.01" id="precio_oro" required>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label>Zona VIP - Capacidad:</label>
|
||||
<input type="number" id="capacidad_vip" required oninput="actualizarCapacidad()">
|
||||
<label>Precio:</label>
|
||||
<input type="number" step="0.01" id="precio_vip" required>
|
||||
</div>
|
||||
</fieldset>
|
||||
<button type="button" class="btn prev-btn" onclick="siguientePaso(2)">Anterior</button>
|
||||
<button type="submit" class="btn submit-btn">Crear Concierto</button>
|
||||
</div>
|
||||
</form>
|
||||
<div id="mensaje" class="mt-3 text-center"></div>
|
||||
</div>
|
||||
|
||||
<script src="js/crearConciertos.js"></script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue