feat: Implemented rooms
This commit is contained in:
@@ -0,0 +1,128 @@
|
|||||||
|
package cz.jzitnik.controllers;
|
||||||
|
|
||||||
|
import cz.jzitnik.router.Route;
|
||||||
|
import cz.jzitnik.router.Router;
|
||||||
|
import cz.jzitnik.query.QueryOptions;
|
||||||
|
import io.github.tomhula.jecnaapi.data.room.Room;
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.layout.*;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Route(path = "/classroom_detail", fxml = "/classroom_detail.fxml")
|
||||||
|
public class ClassroomDetailController extends DashboardBaseController {
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private ProgressIndicator loadingIndicator;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private ScrollPane scrollPane;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Label headerNameLabel;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private GridPane detailsGrid;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private GridPane timetableGrid;
|
||||||
|
|
||||||
|
private String roomCode;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNavigate(Map<String, Object> props) {
|
||||||
|
super.onNavigate(props);
|
||||||
|
|
||||||
|
roomCode = (String) props.get("code");
|
||||||
|
if (roomCode == null || roomCode.isEmpty()) {
|
||||||
|
onBack();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadRoom();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadRoom() {
|
||||||
|
loadingIndicator.setVisible(true);
|
||||||
|
scrollPane.setVisible(false);
|
||||||
|
detailsGrid.getChildren().clear();
|
||||||
|
|
||||||
|
appState.getQueryClient().fetch("room:" + roomCode, () -> {
|
||||||
|
try {
|
||||||
|
return appState.getClient().getRoom(roomCode).join();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, QueryOptions.defaultOptions()).thenAccept(result -> {
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
loadingIndicator.setVisible(false);
|
||||||
|
|
||||||
|
if (result.isSuccess() && result.getData().isPresent()) {
|
||||||
|
renderRoom(result.getData().get());
|
||||||
|
scrollPane.setVisible(true);
|
||||||
|
} else {
|
||||||
|
headerNameLabel.setText("Chyba");
|
||||||
|
detailsGrid.add(new Label("Failed to load room details."), 0, 0);
|
||||||
|
scrollPane.setVisible(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderRoom(Room room) {
|
||||||
|
headerNameLabel.setText(room.getName());
|
||||||
|
|
||||||
|
int row = 0;
|
||||||
|
row = addDetailRow("Název", room.getName(), row);
|
||||||
|
row = addDetailRow("Kód", room.getRoomCode(), row);
|
||||||
|
row = addDetailRow("Patro", room.getFloor(), row);
|
||||||
|
row = addDetailRow("Domovská učebna pro", room.getHomeroomOf(), row);
|
||||||
|
|
||||||
|
if (room.getManager() != null) {
|
||||||
|
Hyperlink managerLink = new Hyperlink(room.getManager().getFullName());
|
||||||
|
managerLink.getStyleClass().add("teacher-link");
|
||||||
|
managerLink.setOnAction(e -> {
|
||||||
|
Router.getInstance().navigate("/teacher_profile", Map.of("tag", room.getManager().getTag()));
|
||||||
|
});
|
||||||
|
detailsGrid.add(new Label("Správce:"), 0, row);
|
||||||
|
detailsGrid.add(managerLink, 1, row++);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timetableGrid != null) {
|
||||||
|
if (room.getTimetable() != null) {
|
||||||
|
cz.jzitnik.util.TimetableRenderer.renderTimetable(timetableGrid, room.getTimetable());
|
||||||
|
} else {
|
||||||
|
timetableGrid.getChildren().clear();
|
||||||
|
timetableGrid.getColumnConstraints().clear();
|
||||||
|
timetableGrid.getRowConstraints().clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int addDetailRow(String labelText, String value, int row) {
|
||||||
|
if (value == null || value.isBlank()) {
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
Label lbl = new Label(labelText + ":");
|
||||||
|
lbl.getStyleClass().add("text-muted");
|
||||||
|
|
||||||
|
Label val = new Label(value);
|
||||||
|
val.getStyleClass().addAll("text-light", "text-bold");
|
||||||
|
val.setWrapText(true);
|
||||||
|
|
||||||
|
detailsGrid.add(lbl, 0, row);
|
||||||
|
detailsGrid.add(val, 1, row);
|
||||||
|
|
||||||
|
return row + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
@Override
|
||||||
|
protected void onBack() {
|
||||||
|
Router.getInstance().navigate("/classrooms");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
package cz.jzitnik.controllers;
|
||||||
|
|
||||||
|
import cz.jzitnik.router.Route;
|
||||||
|
import cz.jzitnik.router.Router;
|
||||||
|
import cz.jzitnik.query.QueryOptions;
|
||||||
|
import io.github.tomhula.jecnaapi.data.room.RoomReference;
|
||||||
|
import io.github.tomhula.jecnaapi.data.room.RoomsPage;
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.geometry.Pos;
|
||||||
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.layout.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Route(path = "/classrooms", fxml = "/classrooms.fxml")
|
||||||
|
public class ClassroomsController extends DashboardBaseController {
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private ProgressIndicator loadingIndicator;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private ScrollPane scrollPane;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private FlowPane classroomsFlow;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private TextField searchField;
|
||||||
|
|
||||||
|
private List<RoomReference> allRooms = new ArrayList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNavigate(Map<String, Object> props) {
|
||||||
|
super.onNavigate(props);
|
||||||
|
|
||||||
|
searchField.textProperty().addListener((obs, oldVal, newVal) -> {
|
||||||
|
filterRooms(newVal);
|
||||||
|
});
|
||||||
|
|
||||||
|
loadRooms();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadRooms() {
|
||||||
|
loadingIndicator.setVisible(true);
|
||||||
|
scrollPane.setVisible(false);
|
||||||
|
classroomsFlow.getChildren().clear();
|
||||||
|
|
||||||
|
appState.getQueryClient().fetch("rooms:page", () -> {
|
||||||
|
try {
|
||||||
|
return appState.getClient().getRoomsPage().join();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, QueryOptions.defaultOptions()).thenAccept(result -> {
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
loadingIndicator.setVisible(false);
|
||||||
|
|
||||||
|
if (result.isSuccess() && result.getData().isPresent()) {
|
||||||
|
RoomsPage page = result.getData().get();
|
||||||
|
allRooms = new ArrayList<>(page.getRoomReferences());
|
||||||
|
// Sort by name
|
||||||
|
allRooms.sort((r1, r2) -> r1.getName().compareToIgnoreCase(r2.getName()));
|
||||||
|
filterRooms(searchField.getText());
|
||||||
|
scrollPane.setVisible(true);
|
||||||
|
} else {
|
||||||
|
Label errorLabel = new Label("Failed to load rooms.");
|
||||||
|
errorLabel.getStyleClass().addAll("text-danger", "title-3");
|
||||||
|
classroomsFlow.getChildren().add(errorLabel);
|
||||||
|
scrollPane.setVisible(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void filterRooms(String query) {
|
||||||
|
classroomsFlow.getChildren().clear();
|
||||||
|
|
||||||
|
String lowerQuery = query == null ? "" : query.toLowerCase();
|
||||||
|
|
||||||
|
List<RoomReference> filtered = allRooms.stream()
|
||||||
|
.filter(r -> r.getName().toLowerCase().contains(lowerQuery) || r.getRoomCode().toLowerCase().contains(lowerQuery))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
if (filtered.isEmpty()) {
|
||||||
|
Label empty = new Label("Nenalezena žádná učebna.");
|
||||||
|
empty.getStyleClass().addAll("text-muted", "title-3");
|
||||||
|
classroomsFlow.getChildren().add(empty);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (RoomReference room : filtered) {
|
||||||
|
VBox card = new VBox(5);
|
||||||
|
card.setAlignment(Pos.CENTER);
|
||||||
|
card.getStyleClass().addAll("card", "classroom-card");
|
||||||
|
|
||||||
|
Label nameLbl = new Label(room.getName());
|
||||||
|
nameLbl.getStyleClass().addAll("title-4", "text-light");
|
||||||
|
|
||||||
|
Label codeLbl = new Label(room.getRoomCode());
|
||||||
|
codeLbl.getStyleClass().addAll("text-muted");
|
||||||
|
|
||||||
|
card.getChildren().addAll(nameLbl, codeLbl);
|
||||||
|
|
||||||
|
card.setOnMouseClicked(e -> {
|
||||||
|
Router.getInstance().navigate("/classroom_detail", Map.of("code", room.getRoomCode()));
|
||||||
|
});
|
||||||
|
|
||||||
|
classroomsFlow.getChildren().add(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
protected void onBackToDashboard() {
|
||||||
|
Router.getInstance().navigate("/dashboard");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ public class DashboardBaseController implements Routable {
|
|||||||
protected void onNavigateToTeachers() { Router.getInstance().navigate("/teachers"); }
|
protected void onNavigateToTeachers() { Router.getInstance().navigate("/teachers"); }
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
protected void onNavigateToRooms() { Router.getInstance().navigate("/rooms"); }
|
protected void onNavigateToClassrooms() { Router.getInstance().navigate("/classrooms"); }
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
protected void onNavigateToAbsences() { Router.getInstance().navigate("/absences"); }
|
protected void onNavigateToAbsences() { Router.getInstance().navigate("/absences"); }
|
||||||
|
|||||||
@@ -187,8 +187,14 @@ public class TimetableRenderer {
|
|||||||
grid.add(teacherLbl, 1, row++);
|
grid.add(teacherLbl, 1, row++);
|
||||||
}
|
}
|
||||||
if (lesson.getClassroom() != null) {
|
if (lesson.getClassroom() != null) {
|
||||||
|
Hyperlink roomLink = new Hyperlink(lesson.getClassroom());
|
||||||
|
roomLink.getStyleClass().addAll("teacher-link");
|
||||||
|
roomLink.setOnAction(e -> {
|
||||||
|
dialog.close();
|
||||||
|
Router.getInstance().navigate("/classroom_detail", Map.of("code", lesson.getClassroom()));
|
||||||
|
});
|
||||||
grid.add(new Label("Učebna:"), 0, row);
|
grid.add(new Label("Učebna:"), 0, row);
|
||||||
grid.add(new Label(lesson.getClassroom()), 1, row++);
|
grid.add(roomLink, 1, row++);
|
||||||
}
|
}
|
||||||
if (lesson.getGroup() != null) {
|
if (lesson.getGroup() != null) {
|
||||||
grid.add(new Label("Skupina:"), 0, row);
|
grid.add(new Label("Skupina:"), 0, row);
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.control.Button?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.control.ProgressIndicator?>
|
||||||
|
<?import javafx.scene.control.ScrollPane?>
|
||||||
|
<?import javafx.scene.layout.BorderPane?>
|
||||||
|
<?import javafx.scene.layout.ColumnConstraints?>
|
||||||
|
<?import javafx.scene.layout.GridPane?>
|
||||||
|
<?import javafx.scene.layout.HBox?>
|
||||||
|
<?import javafx.scene.layout.StackPane?>
|
||||||
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
|
||||||
|
<BorderPane xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1"
|
||||||
|
fx:controller="cz.jzitnik.controllers.ClassroomDetailController"
|
||||||
|
style="-fx-background-color: linear-gradient(#0f1724, #071023);"
|
||||||
|
stylesheets="@styles/classrooms.css">
|
||||||
|
|
||||||
|
<top>
|
||||||
|
<HBox spacing="15" alignment="CENTER_LEFT" style="-fx-background-color: rgba(255, 255, 255, 0.05); -fx-padding: 15 25;">
|
||||||
|
<Button text="← Zpět" onAction="#onBack" styleClass="flat, small" />
|
||||||
|
<Label fx:id="headerNameLabel" text="Učebna" styleClass="title-2, text-light" />
|
||||||
|
</HBox>
|
||||||
|
</top>
|
||||||
|
|
||||||
|
<center>
|
||||||
|
<StackPane>
|
||||||
|
<ProgressIndicator fx:id="loadingIndicator" maxWidth="50" maxHeight="50" />
|
||||||
|
|
||||||
|
<ScrollPane fx:id="scrollPane" fitToWidth="true" style="-fx-background: transparent; -fx-background-color: transparent;" visible="false">
|
||||||
|
<StackPane alignment="TOP_CENTER">
|
||||||
|
<padding>
|
||||||
|
<Insets top="30" right="30" bottom="30" left="30"/>
|
||||||
|
</padding>
|
||||||
|
|
||||||
|
<VBox spacing="25" alignment="TOP_CENTER" maxWidth="1000">
|
||||||
|
|
||||||
|
<GridPane fx:id="detailsGrid" hgap="20" vgap="15" styleClass="classroom-details-grid" maxWidth="800">
|
||||||
|
<columnConstraints>
|
||||||
|
<javafx.scene.layout.ColumnConstraints minWidth="150" halignment="RIGHT" />
|
||||||
|
<javafx.scene.layout.ColumnConstraints hgrow="ALWAYS" />
|
||||||
|
</columnConstraints>
|
||||||
|
</GridPane>
|
||||||
|
|
||||||
|
<VBox spacing="10" alignment="TOP_CENTER" styleClass="classroom-timetable-container">
|
||||||
|
<Label text="Rozvrh učebny" styleClass="title-2, text-light" />
|
||||||
|
<ScrollPane vbarPolicy="NEVER" hbarPolicy="AS_NEEDED" fitToHeight="true" fitToWidth="true" style="-fx-background: transparent; -fx-background-color: transparent;">
|
||||||
|
<GridPane fx:id="timetableGrid" hgap="10" vgap="10" alignment="CENTER" />
|
||||||
|
</ScrollPane>
|
||||||
|
</VBox>
|
||||||
|
|
||||||
|
</VBox>
|
||||||
|
</StackPane>
|
||||||
|
</ScrollPane>
|
||||||
|
</StackPane>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
</BorderPane>
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.control.Button?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.control.ProgressIndicator?>
|
||||||
|
<?import javafx.scene.control.ScrollPane?>
|
||||||
|
<?import javafx.scene.control.TextField?>
|
||||||
|
<?import javafx.scene.layout.BorderPane?>
|
||||||
|
<?import javafx.scene.layout.FlowPane?>
|
||||||
|
<?import javafx.scene.layout.HBox?>
|
||||||
|
<?import javafx.scene.layout.Region?>
|
||||||
|
<?import javafx.scene.layout.StackPane?>
|
||||||
|
|
||||||
|
<BorderPane xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1"
|
||||||
|
fx:controller="cz.jzitnik.controllers.ClassroomsController"
|
||||||
|
style="-fx-background-color: linear-gradient(#0f1724, #071023);"
|
||||||
|
stylesheets="@styles/classrooms.css">
|
||||||
|
|
||||||
|
<top>
|
||||||
|
<HBox spacing="15" alignment="CENTER_LEFT" style="-fx-background-color: rgba(255, 255, 255, 0.05); -fx-padding: 15 25;">
|
||||||
|
<Button text="← Zpět" onAction="#onBackToDashboard" styleClass="flat, small" />
|
||||||
|
<Label text="Učebny" styleClass="title-2, text-light" />
|
||||||
|
<Region HBox.hgrow="ALWAYS" />
|
||||||
|
<TextField fx:id="searchField" promptText="Hledat učebnu..." styleClass="search-field" />
|
||||||
|
</HBox>
|
||||||
|
</top>
|
||||||
|
|
||||||
|
<center>
|
||||||
|
<StackPane>
|
||||||
|
<ProgressIndicator fx:id="loadingIndicator" maxWidth="50" maxHeight="50" />
|
||||||
|
|
||||||
|
<ScrollPane fx:id="scrollPane" fitToWidth="true" style="-fx-background: transparent; -fx-background-color: transparent;" visible="false">
|
||||||
|
<StackPane alignment="TOP_CENTER">
|
||||||
|
<padding>
|
||||||
|
<Insets top="20" right="30" bottom="30" left="30"/>
|
||||||
|
</padding>
|
||||||
|
<FlowPane fx:id="classroomsFlow" hgap="15" vgap="15" alignment="CENTER" maxWidth="900" />
|
||||||
|
</StackPane>
|
||||||
|
</ScrollPane>
|
||||||
|
</StackPane>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
</BorderPane>
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
<Button text="Učitelé" GridPane.rowIndex="0" GridPane.columnIndex="2" onAction="#onNavigateToTeachers" styleClass="card"/>
|
<Button text="Učitelé" GridPane.rowIndex="0" GridPane.columnIndex="2" onAction="#onNavigateToTeachers" styleClass="card"/>
|
||||||
|
|
||||||
<!-- Row 1 -->
|
<!-- Row 1 -->
|
||||||
<Button text="Učebny" GridPane.rowIndex="1" GridPane.columnIndex="0" onAction="#onDoNothing" styleClass="card"/>
|
<Button text="Učebny" GridPane.rowIndex="1" GridPane.columnIndex="0" onAction="#onNavigateToClassrooms" styleClass="card"/>
|
||||||
<Button text="Absence" GridPane.rowIndex="1" GridPane.columnIndex="1" onAction="#onNavigateToAbsences" styleClass="card"/>
|
<Button text="Absence" GridPane.rowIndex="1" GridPane.columnIndex="1" onAction="#onNavigateToAbsences" styleClass="card"/>
|
||||||
<Button text="Mimořádný rozvrh" GridPane.rowIndex="1" GridPane.columnIndex="2" onAction="#onDoNothing" styleClass="card"/>
|
<Button text="Mimořádný rozvrh" GridPane.rowIndex="1" GridPane.columnIndex="2" onAction="#onDoNothing" styleClass="card"/>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.control.Button?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.control.ProgressIndicator?>
|
||||||
|
<?import javafx.scene.control.ScrollPane?>
|
||||||
|
<?import javafx.scene.control.TextField?>
|
||||||
|
<?import javafx.scene.layout.BorderPane?>
|
||||||
|
<?import javafx.scene.layout.FlowPane?>
|
||||||
|
<?import javafx.scene.layout.HBox?>
|
||||||
|
<?import javafx.scene.layout.Region?>
|
||||||
|
<?import javafx.scene.layout.StackPane?>
|
||||||
|
|
||||||
|
<BorderPane xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1"
|
||||||
|
fx:controller="cz.jzitnik.controllers.RoomsController"
|
||||||
|
style="-fx-background-color: linear-gradient(#0f1724, #071023);"
|
||||||
|
stylesheets="@styles/rooms.css">
|
||||||
|
|
||||||
|
<top>
|
||||||
|
<HBox spacing="15" alignment="CENTER_LEFT" style="-fx-background-color: rgba(255, 255, 255, 0.05); -fx-padding: 15 25;">
|
||||||
|
<Button text="← Zpět" onAction="#onBackToDashboard" styleClass="flat, small" />
|
||||||
|
<Label text="Učebny" styleClass="title-2, text-light" />
|
||||||
|
<Region HBox.hgrow="ALWAYS" />
|
||||||
|
<TextField fx:id="searchField" promptText="Hledat učebnu..." styleClass="search-field" />
|
||||||
|
</HBox>
|
||||||
|
</top>
|
||||||
|
|
||||||
|
<center>
|
||||||
|
<StackPane>
|
||||||
|
<ProgressIndicator fx:id="loadingIndicator" maxWidth="50" maxHeight="50" />
|
||||||
|
|
||||||
|
<ScrollPane fx:id="scrollPane" fitToWidth="true" style="-fx-background: transparent; -fx-background-color: transparent;" visible="false">
|
||||||
|
<StackPane alignment="TOP_CENTER">
|
||||||
|
<padding>
|
||||||
|
<Insets top="20" right="30" bottom="30" left="30"/>
|
||||||
|
</padding>
|
||||||
|
<FlowPane fx:id="roomsFlow" hgap="15" vgap="15" alignment="CENTER" maxWidth="900" />
|
||||||
|
</StackPane>
|
||||||
|
</ScrollPane>
|
||||||
|
</StackPane>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
</BorderPane>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
.classroom-card {
|
||||||
|
-fx-min-width: 220px;
|
||||||
|
-fx-min-height: 100px;
|
||||||
|
-fx-background-color: rgba(30, 40, 56, 0.7);
|
||||||
|
-fx-border-color: rgba(255, 255, 255, 0.05);
|
||||||
|
-fx-border-radius: 8px;
|
||||||
|
-fx-background-radius: 8px;
|
||||||
|
-fx-padding: 15px 20px;
|
||||||
|
-fx-cursor: hand;
|
||||||
|
-fx-alignment: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-card:hover {
|
||||||
|
-fx-background-color: rgba(45, 55, 71, 0.9);
|
||||||
|
-fx-border-color: rgba(255, 255, 255, 0.15);
|
||||||
|
-fx-effect: dropshadow(two-pass-box, rgba(0,0,0,0.3), 8, 0.0, 0, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.classroom-details-grid {
|
||||||
|
-fx-background-color: rgba(255, 255, 255, 0.03);
|
||||||
|
-fx-padding: 25px;
|
||||||
|
-fx-background-radius: 12px;
|
||||||
|
-fx-border-color: rgba(255, 255, 255, 0.05);
|
||||||
|
-fx-border-radius: 12px;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user