From 86cda061d84b55f8b761298edd75bd00b662172a Mon Sep 17 00:00:00 2001 From: Felipe Murguia <murguialeal@proton.me> Date: Sun, 9 Mar 2025 16:45:02 -0600 Subject: [PATCH] Beta 0.1 Funcional --- pom.xml | 25 +-- src/main/java/module-info.java | 2 +- .../saladeconciertos/EscogerEvento.java | 97 ++++++++++ .../saladeconciertos/PDFGenerator.java | 2 +- .../saladeconciertos/VentaBoletos.java | 174 ++++++++++++------ .../example/saladeconciertos/VentanaPago.java | 5 +- src/main/resources/styles.css | 35 ++-- 7 files changed, 250 insertions(+), 90 deletions(-) create mode 100644 src/main/java/org/example/saladeconciertos/EscogerEvento.java diff --git a/pom.xml b/pom.xml index 031ac2f..a5d5f46 100644 --- a/pom.xml +++ b/pom.xml @@ -12,24 +12,28 @@ <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <junit.version>5.10.2</junit.version> + <javafx.version>21</javafx.version> <itext.version>9.1.0</itext.version> </properties> <dependencies> + + <dependency> + <groupId>org.openjfx</groupId> + <artifactId>javafx-fxml</artifactId> + <version>${javafx.version}</version> + </dependency> + <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>21</version> </dependency> + <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> - <dependency> - <groupId>org.openjfx</groupId> - <artifactId>javafx-fxml</artifactId> - <version>21</version> - </dependency> <dependency> <groupId>org.junit.jupiter</groupId> @@ -37,22 +41,20 @@ <version>${junit.version}</version> <scope>test</scope> </dependency> + <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> - <dependency> - <groupId>org.example</groupId> - <artifactId>SalaDeConciertos</artifactId> - <version>1.0-SNAPSHOT</version> - </dependency> + <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>3.0.3</version> </dependency> + </dependencies> <build> @@ -75,8 +77,7 @@ <!-- Default configuration for running with: mvn clean javafx:run --> <id>default-cli</id> <configuration> - <mainClass>org.example.saladeconciertos/org.example.saladeconciertos.HelloApplication - </mainClass> + <mainClass>org.example.saladeconciertos/org.example.saladeconciertos.VentaBoletos</mainClass> <launcher>app</launcher> <jlinkZipName>app</jlinkZipName> <jlinkImageName>app</jlinkImageName> diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index bec50b9..d37237a 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,10 +1,10 @@ module org.example.saladeconciertos { requires javafx.controls; requires javafx.fxml; + requires javafx.graphics; requires java.sql; requires org.apache.pdfbox; - opens org.example.saladeconciertos to javafx.fxml; exports org.example.saladeconciertos; } \ No newline at end of file diff --git a/src/main/java/org/example/saladeconciertos/EscogerEvento.java b/src/main/java/org/example/saladeconciertos/EscogerEvento.java new file mode 100644 index 0000000..2995b9f --- /dev/null +++ b/src/main/java/org/example/saladeconciertos/EscogerEvento.java @@ -0,0 +1,97 @@ +package org.example.saladeconciertos; + +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.VBox; +import javafx.stage.Stage; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +public class EscogerEvento { + // Datos de conexión a la base de datos + private static final String DB_URL = "jdbc:mysql://sql10.freesqldatabase.com:3306/sql10766655"; + private static final String DB_USER = "sql10766655"; + private static final String DB_PASSWORD = "7BZbRjEkXZ"; + + // Método para mostrar la ventana de selección de eventos + public void mostrarVentanaSeleccionEvento(Stage mainStage, VentaBoletos ventaBoletos) { + // Crear y configurar el label para seleccionar un evento + Label selectEventLabel = new Label("Seleccione un evento:"); + selectEventLabel.getStyleClass().add("label"); + + // Crear y configurar el ComboBox para listar los eventos + ComboBox<String> eventComboBox = new ComboBox<>(); + + // Crear y configurar el label para mostrar el evento seleccionado + Label selectedEventLabel = new Label("Evento seleccionado: Ninguno"); + selectedEventLabel.getStyleClass().add("label"); + + // Crear y configurar el botón de confirmación + Button confirmButton = new Button("Confirmar"); + confirmButton.getStyleClass().add("button"); + + // Cargar eventos desde la base de datos + try (Connection conexion = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) { + String query = "SELECT id, nombre FROM conciertos"; + Statement statement = conexion.createStatement(); + ResultSet resultSet = statement.executeQuery(query); + + // Añadir los eventos al ComboBox + while (resultSet.next()) { + int id = resultSet.getInt("id"); + String nombre = resultSet.getString("nombre"); + eventComboBox.getItems().add(id + " - " + nombre); + } + } catch (SQLException e) { + System.out.println("Error al cargar los eventos."); + e.printStackTrace(); + } + + // Actualizar el label cuando se selecciona un evento + eventComboBox.setOnAction(e -> { + String selectedEvent = eventComboBox.getValue(); + if (selectedEvent != null) { + selectedEventLabel.setText("Evento seleccionado: " + selectedEvent); + } + }); + + // Acción del botón de confirmación + confirmButton.setOnAction(e -> { + String selectedEvent = eventComboBox.getValue(); + if (selectedEvent != null) { + int eventId = Integer.parseInt(selectedEvent.split(" - ")[0]); + ventaBoletos.setEventId(eventId); + ventaBoletos.cargarInformacionEvento(); + ventaBoletos.mostrarVentanaVentaBoletos(mainStage); + } else { + ventaBoletos.mostrarAlerta("Advertencia", "No se ha seleccionado un evento", "Por favor, seleccione un evento."); + } + }); + + // Agregar el logo de la aplicación + ImageView logo = new ImageView(new Image(getClass().getResourceAsStream("/logo.png"))); + logo.setFitWidth(100); + logo.setFitHeight(100); + + // Crear y configurar el layout principal + VBox layout = new VBox(20, logo, selectEventLabel, eventComboBox, selectedEventLabel, confirmButton); + layout.setAlignment(Pos.CENTER); + layout.setPadding(new Insets(20)); + + // Crear y configurar la escena + Scene scene = new Scene(layout, 400, 300); + scene.getStylesheets().add(getClass().getResource("/styles.css").toExternalForm()); + mainStage.setScene(scene); + mainStage.show(); + } +} \ No newline at end of file diff --git a/src/main/java/org/example/saladeconciertos/PDFGenerator.java b/src/main/java/org/example/saladeconciertos/PDFGenerator.java index dba32d8..4a2ffac 100644 --- a/src/main/java/org/example/saladeconciertos/PDFGenerator.java +++ b/src/main/java/org/example/saladeconciertos/PDFGenerator.java @@ -7,11 +7,11 @@ import org.apache.pdfbox.pdmodel.font.Standard14Fonts; import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; -import java.io.File; import java.io.IOException; public class PDFGenerator { + // Método para generar un PDF con los detalles del ticket public static void generarPDF(String eventName, String eventDate, String clientName, double totalPrice, String qrImagePath) { // Ruta donde se guardará el PDF String downloadsPath = System.getProperty("user.home") + "/Downloads/"; diff --git a/src/main/java/org/example/saladeconciertos/VentaBoletos.java b/src/main/java/org/example/saladeconciertos/VentaBoletos.java index 39d41c3..e901f85 100644 --- a/src/main/java/org/example/saladeconciertos/VentaBoletos.java +++ b/src/main/java/org/example/saladeconciertos/VentaBoletos.java @@ -6,11 +6,14 @@ import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; -import javafx.scene.control.Alert; // Nuevo: Importación para usar Alert -import javafx.scene.image.Image; // Nuevo: Importación para usar Image -import javafx.scene.image.ImageView; // Nuevo: Importación para usar ImageView +import javafx.scene.control.Alert; +import javafx.scene.effect.DropShadow; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.BorderPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; +import javafx.scene.paint.Color; import javafx.stage.Stage; import java.sql.*; @@ -24,47 +27,59 @@ public class VentaBoletos extends Application { private static final String DB_USER = "sql10766655"; private static final String DB_PASSWORD = "7BZbRjEkXZ"; private List<Integer> selectedSeats = new ArrayList<>(); - private Map<Integer, Double> seatPrices = new HashMap<>(); // Nuevo: Mapa para almacenar precios de asientos - private String eventName = ""; // Nuevo: Variable para almacenar el nombre del evento - private String eventDate = ""; // Nuevo: Variable para almacenar la fecha del evento - private GridPane seatGrid; // Nuevo: Referencia a la cuadrícula de asientos - private Stage mainStage; // Nuevo: Referencia al Stage principal + private Map<Integer, Double> seatPrices = new HashMap<>(); + private String eventName = ""; + private String eventDate = ""; + private int eventId = 0; + private GridPane seatGrid; + private Stage mainStage; @Override public void start(Stage mainStage) { - this.mainStage = mainStage; // Nuevo: Guardar referencia al Stage principal + this.mainStage = mainStage; + EscogerEvento escogerEvento = new EscogerEvento(); + escogerEvento.mostrarVentanaSeleccionEvento(mainStage, this); + } + + public void setEventId(int eventId) { + this.eventId = eventId; + } + + public void cargarInformacionEvento() { + try (Connection conexion = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) { + String eventQuery = "SELECT nombre, fecha FROM conciertos WHERE id = ?"; + PreparedStatement eventStatement = conexion.prepareStatement(eventQuery); + eventStatement.setInt(1, eventId); + ResultSet eventResultSet = eventStatement.executeQuery(); + + if (eventResultSet.next()) { + eventName = eventResultSet.getString("nombre"); + eventDate = eventResultSet.getString("fecha"); + } + } catch (SQLException e) { + System.out.println("Error al cargar la información del evento."); + e.printStackTrace(); + } + } + + public void mostrarVentanaVentaBoletos(Stage mainStage) { int totalSeats = 0; Map<Integer, String> seatStatus = new HashMap<>(); - try { - Connection conexion = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD); - System.out.println("Conexión realizada correctamente"); - - // Nuevo: Obtener información del evento (nombre y fecha) - String eventQuery = "SELECT nombre, fecha FROM conciertos WHERE id = 1"; - Statement eventStatement = conexion.createStatement(); - ResultSet eventResultSet = eventStatement.executeQuery(eventQuery); - - if (eventResultSet.next()) { - eventName = eventResultSet.getString("nombre"); // Nuevo: Almacenar nombre del evento - eventDate = eventResultSet.getString("fecha"); // Nuevo: Almacenar fecha del evento - } - - // Nuevo: Obtener información de los asientos (precio base y estado) - String seatQuery = "SELECT a.id, a.precio_base, b.status FROM asientos a JOIN boleto b ON a.id = b.id_asiento WHERE b.idevento = 1"; - Statement seatStatement = conexion.createStatement(); - ResultSet seatResultSet = seatStatement.executeQuery(seatQuery); + try (Connection conexion = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) { + String seatQuery = "SELECT a.id, a.precio_base, b.status FROM asientos a JOIN boleto b ON a.id = b.id_asiento WHERE b.idevento = ?"; + PreparedStatement seatStatement = conexion.prepareStatement(seatQuery); + seatStatement.setInt(1, eventId); + ResultSet seatResultSet = seatStatement.executeQuery(); while (seatResultSet.next()) { int seatId = seatResultSet.getInt("id"); - double precio = seatResultSet.getDouble("precio_base"); // Nuevo: Obtener precio del asiento + double precio = seatResultSet.getDouble("precio_base"); String status = seatResultSet.getString("status"); seatStatus.put(seatId, status); - seatPrices.put(seatId, precio); // Nuevo: Almacenar precio del asiento en el mapa + seatPrices.put(seatId, precio); totalSeats++; } - - conexion.close(); } catch (SQLException e) { System.out.println("Error en la conexión a la base de datos."); e.printStackTrace(); @@ -72,19 +87,26 @@ public class VentaBoletos extends Application { mainStage.setTitle("Gestión de Boletos"); - // Nuevo: Título y logo - Label titleLabel = new Label("Sala de Conciertos"); - titleLabel.getStyleClass().add("title"); // Nuevo: Aplicar clase CSS + // Modificado: Título con el nombre del evento + Label titleLabel = new Label(eventName); + titleLabel.getStyleClass().add("title"); - ImageView logo = new ImageView(new Image(getClass().getResourceAsStream("/logo.png"))); // Nuevo: Cargar imagen del logo - logo.setFitWidth(100); // Nuevo: Ajustar ancho del logo - logo.setFitHeight(100); // Nuevo: Ajustar altura del logo + // Agregar el logo de la aplicación + ImageView logo = new ImageView(new Image(getClass().getResourceAsStream("/logo.png"))); + logo.setFitWidth(100); + logo.setFitHeight(100); + // Crear y configurar el label de bienvenida Label welcomeLabel = new Label("Seleccione sus asientos"); - seatGrid = new GridPane(); // Nuevo: Inicializar la cuadrícula de asientos - seatGrid.getStyleClass().add("seat-grid"); // Nuevo: Aplicar clase CSS + seatGrid = new GridPane(); + seatGrid.getStyleClass().add("seat-grid"); + seatGrid.setHgap(10); // Espaciado horizontal entre celdas + seatGrid.setVgap(10); // Espaciado vertical entre celdas + seatGrid.setPadding(new Insets(20)); // Padding alrededor del GridPane + + // Crear y configurar el botón de confirmación Button confirmButton = new Button("Confirmar Compra"); - confirmButton.getStyleClass().add("button"); // Nuevo: Aplicar clase CSS + confirmButton.getStyleClass().add("button"); int cols = 5; int rows = (int) Math.ceil((double) totalSeats / cols); @@ -92,8 +114,13 @@ public class VentaBoletos extends Application { for (int seatNumber = 1; seatNumber <= totalSeats; seatNumber++) { int row = (seatNumber - 1) / cols; int col = (seatNumber - 1) % cols; - Button seatButton = new Button("Asiento " + seatNumber); - seatButton.getStyleClass().add("seat-button"); // Nuevo: Aplicar clase CSS + char rowLetter = (char) ('A' + row); + String seatLabel = rowLetter + String.valueOf(col + 1); + Button seatButton = new Button(seatLabel); + seatButton.getStyleClass().add("seat-button"); + seatButton.setMinSize(80, 40); // Tamaño mínimo de cada botón + seatButton.setMaxSize(80, 40); // Tamaño máximo de cada botón + seatButton.setPadding(new Insets(10)); // Padding dentro de cada botón int finalSeatNumber = seatNumber; if ("vendido".equals(seatStatus.getOrDefault(finalSeatNumber, "disponible"))) { @@ -102,7 +129,7 @@ public class VentaBoletos extends Application { seatButton.setOnAction(e -> { if (!selectedSeats.contains(finalSeatNumber)) { selectedSeats.add(finalSeatNumber); - seatButton.setStyle("-fx-background-color: #45a049;"); // Nuevo: Cambiar color a verde más oscuro + seatButton.setStyle("-fx-background-color: #45a049;"); } else { selectedSeats.remove(Integer.valueOf(finalSeatNumber)); seatButton.setStyle(""); @@ -112,7 +139,6 @@ public class VentaBoletos extends Application { seatGrid.add(seatButton, col, row); } - // Nuevo: Lógica para el botón de confirmar compra confirmButton.setOnAction(e -> { if (selectedSeats.isEmpty()) { mostrarAlerta("Advertencia", "No se han seleccionado asientos", "Por favor, seleccione al menos un asiento."); @@ -122,23 +148,45 @@ public class VentaBoletos extends Application { final String finalEventName = eventName; final String finalEventDate = eventDate; - VentanaPago ventanaPago = new VentanaPago(this); // Nuevo: Crear ventana de pago + VentanaPago ventanaPago = new VentanaPago(this); ventanaPago.mostrarVentanaPago(finalSelectedSeats, finalSeatPrices, finalEventName, finalEventDate); } }); - // Nuevo: Layout principal con logo, título, cuadrícula y botón - VBox mainLayout = new VBox(20, logo, titleLabel, welcomeLabel, seatGrid, confirmButton); - mainLayout.setAlignment(Pos.TOP_CENTER); // Nuevo: Centrar elementos - mainLayout.setPadding(new Insets(20)); // Nuevo: Agregar padding + // Nuevo: Botón para regresar a la ventana de selección de eventos + Button backButton = new Button("Regresar"); + backButton.getStyleClass().add("button"); + backButton.setOnAction(e -> { + EscogerEvento escogerEvento = new EscogerEvento(); + escogerEvento.mostrarVentanaSeleccionEvento(mainStage, this); + }); - Scene mainScene = new Scene(mainLayout, 600, 500); // Nuevo: Aumentar tamaño de la ventana - mainScene.getStylesheets().add(getClass().getResource("/styles.css").toExternalForm()); // Nuevo: Aplicar CSS + // Añadir sombra al botón "Regresar" + DropShadow shadow = new DropShadow(); + shadow.setColor(Color.rgb(0, 0, 0, 0.25)); + shadow.setRadius(10); + shadow.setOffsetX(0); + shadow.setOffsetY(2); + backButton.setEffect(shadow); + + // Colocar el botón "Regresar" en la esquina superior izquierda + BorderPane borderPane = new BorderPane(); + borderPane.setPadding(new Insets(10)); + borderPane.setTop(backButton); + BorderPane.setAlignment(backButton, Pos.TOP_LEFT); + + VBox mainLayout = new VBox(20, logo, titleLabel, welcomeLabel, seatGrid, confirmButton); + mainLayout.setAlignment(Pos.TOP_CENTER); + mainLayout.setPadding(new Insets(20)); + + borderPane.setCenter(mainLayout); + + Scene mainScene = new Scene(borderPane, 540, 600); + mainScene.getStylesheets().add(getClass().getResource("/styles.css").toExternalForm()); mainStage.setScene(mainScene); mainStage.show(); } - // Nuevo: Método para refrescar la interfaz después de una compra public void refrescarInterfaz() { selectedSeats.clear(); Map<Integer, String> seatStatus = cargarEstadoAsientos(); @@ -151,8 +199,13 @@ public class VentaBoletos extends Application { for (int seatNumber = 1; seatNumber <= totalSeats; seatNumber++) { int row = (seatNumber - 1) / cols; int col = (seatNumber - 1) % cols; - Button seatButton = new Button("Asiento " + seatNumber); - seatButton.getStyleClass().add("seat-button"); // Nuevo: Aplicar clase CSS + char rowLetter = (char) ('A' + row); + String seatLabel = rowLetter + String.valueOf(col + 1); + Button seatButton = new Button(seatLabel); + seatButton.getStyleClass().add("seat-button"); + seatButton.setMinSize(80, 40); // Tamaño mínimo de cada botón + seatButton.setMaxSize(80, 40); // Tamaño máximo de cada botón + seatButton.setPadding(new Insets(10)); // Padding dentro de cada botón int finalSeatNumber = seatNumber; if ("vendido".equals(seatStatus.getOrDefault(finalSeatNumber, "disponible"))) { @@ -161,7 +214,7 @@ public class VentaBoletos extends Application { seatButton.setOnAction(e -> { if (!selectedSeats.contains(finalSeatNumber)) { selectedSeats.add(finalSeatNumber); - seatButton.setStyle("-fx-background-color: #45a049;"); // Nuevo: Cambiar color a verde más oscuro + seatButton.setStyle("-fx-background-color: #45a049;"); } else { selectedSeats.remove(Integer.valueOf(finalSeatNumber)); seatButton.setStyle(""); @@ -172,14 +225,14 @@ public class VentaBoletos extends Application { } } - // Nuevo: Método para cargar el estado de los asientos desde la base de datos private Map<Integer, String> cargarEstadoAsientos() { Map<Integer, String> seatStatus = new HashMap<>(); try (Connection conexion = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) { - String query = "SELECT id_asiento, status FROM boleto WHERE idevento = 1"; - Statement statement = conexion.createStatement(); - ResultSet resultSet = statement.executeQuery(query); + String query = "SELECT id_asiento, status FROM boleto WHERE idevento = ?"; + PreparedStatement statement = conexion.prepareStatement(query); + statement.setInt(1, eventId); + ResultSet resultSet = statement.executeQuery(); while (resultSet.next()) { int seatId = resultSet.getInt("id_asiento"); @@ -194,8 +247,7 @@ public class VentaBoletos extends Application { return seatStatus; } - // Nuevo: Método para mostrar alertas - private void mostrarAlerta(String titulo, String encabezado, String contenido) { + public void mostrarAlerta(String titulo, String encabezado, String contenido) { Alert alert = new Alert(Alert.AlertType.WARNING); alert.setTitle(titulo); alert.setHeaderText(encabezado); diff --git a/src/main/java/org/example/saladeconciertos/VentanaPago.java b/src/main/java/org/example/saladeconciertos/VentanaPago.java index e407ea9..384037c 100644 --- a/src/main/java/org/example/saladeconciertos/VentanaPago.java +++ b/src/main/java/org/example/saladeconciertos/VentanaPago.java @@ -6,8 +6,6 @@ import javafx.scene.layout.VBox; import javafx.stage.Stage; import javafx.geometry.Insets; import javafx.geometry.Pos; -import javafx.scene.layout.Priority; -import javafx.scene.layout.Region; import java.sql.*; import java.util.List; import java.util.Map; @@ -38,11 +36,14 @@ public class VentanaPago { // Detalles del evento Label eventLabel = new Label("Evento: " + eventName); + eventLabel.getStyleClass().add("label"); // Aplicar clase CSS Label dateLabel = new Label("Fecha: " + eventDate); + dateLabel.getStyleClass().add("label"); // Aplicar clase CSS // Calcular el precio total double totalPrice = selectedSeats.stream().mapToInt(seat -> seat).mapToDouble(seatPrices::get).sum(); Label totalLabel = new Label("Total a pagar: $" + String.format("%.2f", totalPrice)); + totalLabel.getStyleClass().add("label"); // Aplicar clase CSS // Campo para ingresar el nombre del cliente TextField nameField = new TextField(); diff --git a/src/main/resources/styles.css b/src/main/resources/styles.css index 3cd6d3e..26b8037 100644 --- a/src/main/resources/styles.css +++ b/src/main/resources/styles.css @@ -1,20 +1,24 @@ /* styles.css */ +@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); + .root { - -fx-background-color: #f4f4f4; /* Fondo claro */ + -fx-font-family: 'Roboto', 'Helvetica Neue', 'Arial', sans-serif; + -fx-background-color: rgba(248, 248, 248, 0.9); /* Fondo con transparencia */ } .seat-button { - -fx-background-color: #4CAF50; /* Verde */ - -fx-text-fill: white; + -fx-background-color: #e0e0e0; + -fx-text-fill: #333; -fx-font-size: 14px; - -fx-font-weight: bold; -fx-padding: 10px; - -fx-border-radius: 5px; - -fx-background-radius: 5px; + -fx-background-radius: 10px; + -fx-border-radius: 10px; + -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.25), 10, 0, 0, 2); } .seat-button:disabled { - -fx-background-color: #f44336; /* Rojo para asientos vendidos */ + -fx-background-color: #d0d0d0; + -fx-text-fill: #999; } .seat-grid { @@ -38,19 +42,24 @@ .title { -fx-font-size: 24px; -fx-font-weight: bold; - -fx-text-fill: #333333; + -fx-text-fill: #333; } .button { - -fx-background-color: #2196F3; /* Azul */ + -fx-background-color: #007aff; -fx-text-fill: white; -fx-font-size: 14px; - -fx-font-weight: bold; -fx-padding: 10px 20px; - -fx-border-radius: 5px; - -fx-background-radius: 5px; + -fx-background-radius: 10px; + -fx-border-radius: 10px; + -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.25), 10, 0, 0, 2); } .button:hover { - -fx-background-color: #1976D2; /* Azul más oscuro al pasar el mouse */ + -fx-background-color: #005bb5; +} + +.label { + -fx-font-size: 16px; + -fx-text-fill: #333; } \ No newline at end of file