feat: Added grades
This commit is contained in:
@@ -0,0 +1,266 @@
|
||||
package cz.jzitnik.controllers;
|
||||
|
||||
import cz.jzitnik.router.Route;
|
||||
import cz.jzitnik.router.Router;
|
||||
import cz.jzitnik.query.QueryOptions;
|
||||
import cz.jzitnik.query.QueryResult;
|
||||
import io.github.tomhula.jecnaapi.data.timetable.Lesson;
|
||||
import io.github.tomhula.jecnaapi.data.timetable.LessonPeriod;
|
||||
import io.github.tomhula.jecnaapi.data.timetable.LessonSpot;
|
||||
import io.github.tomhula.jecnaapi.data.timetable.Timetable;
|
||||
import io.github.tomhula.jecnaapi.data.timetable.TimetablePage;
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.*;
|
||||
|
||||
import kotlinx.datetime.DayOfWeek;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Route(path = "/timetable", fxml = "/timetable.fxml")
|
||||
public class TimetableController extends DashboardBaseController {
|
||||
|
||||
@FXML
|
||||
private GridPane timetableGrid;
|
||||
|
||||
@FXML
|
||||
private ProgressIndicator loadingIndicator;
|
||||
|
||||
@FXML
|
||||
private ScrollPane scrollPane;
|
||||
|
||||
private TimetablePage currentPage;
|
||||
|
||||
@Override
|
||||
public void onNavigate(Map<String, Object> props) {
|
||||
super.onNavigate(props);
|
||||
loadTimetable();
|
||||
}
|
||||
|
||||
private void loadTimetable() {
|
||||
loadingIndicator.setVisible(true);
|
||||
scrollPane.setVisible(false);
|
||||
timetableGrid.getChildren().clear();
|
||||
|
||||
appState.getQueryClient().fetch("timetable:page", () -> {
|
||||
try {
|
||||
return appState.getClient().getTimetablePage().join();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}, QueryOptions.defaultOptions()).thenAccept(this::handleTimetableResult);
|
||||
}
|
||||
|
||||
private void handleTimetableResult(QueryResult<TimetablePage> result) {
|
||||
Platform.runLater(() -> {
|
||||
loadingIndicator.setVisible(false);
|
||||
|
||||
if (result.isSuccess() && result.getData().isPresent()) {
|
||||
scrollPane.setVisible(true);
|
||||
currentPage = result.getData().get();
|
||||
renderTimetable();
|
||||
} else {
|
||||
Label errorLabel = new Label("Failed to load timetable.");
|
||||
errorLabel.getStyleClass().addAll("text-danger", "title-3");
|
||||
timetableGrid.add(errorLabel, 0, 0);
|
||||
timetableGrid.setAlignment(Pos.CENTER);
|
||||
scrollPane.setVisible(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void renderTimetable() {
|
||||
timetableGrid.getChildren().clear();
|
||||
timetableGrid.getColumnConstraints().clear();
|
||||
timetableGrid.getRowConstraints().clear();
|
||||
timetableGrid.setAlignment(Pos.CENTER);
|
||||
|
||||
Timetable timetable = currentPage.getTimetable();
|
||||
List<LessonPeriod> periods = timetable.getLessonPeriods();
|
||||
List<DayOfWeek> days = timetable.getDaysSorted();
|
||||
|
||||
ColumnConstraints dayCol = new ColumnConstraints();
|
||||
dayCol.setMinWidth(120);
|
||||
timetableGrid.getColumnConstraints().add(dayCol);
|
||||
|
||||
for (int i = 0; i < periods.size(); i++) {
|
||||
LessonPeriod p = periods.get(i);
|
||||
VBox header = new VBox(2);
|
||||
header.setAlignment(Pos.CENTER);
|
||||
header.getStyleClass().add("timetable-header");
|
||||
|
||||
Label indexLbl = new Label(String.valueOf(i));
|
||||
indexLbl.getStyleClass().add("timetable-header-index");
|
||||
|
||||
Label timeLbl = new Label(p.toString());
|
||||
timeLbl.getStyleClass().add("timetable-header-time");
|
||||
|
||||
header.getChildren().addAll(indexLbl, timeLbl);
|
||||
|
||||
ColumnConstraints col = new ColumnConstraints();
|
||||
col.setMinWidth(110);
|
||||
timetableGrid.getColumnConstraints().add(col);
|
||||
|
||||
timetableGrid.add(header, i + 1, 0);
|
||||
}
|
||||
|
||||
int rowIndex = 1;
|
||||
for (DayOfWeek day : days) {
|
||||
VBox dayCell = new VBox();
|
||||
dayCell.setAlignment(Pos.CENTER_RIGHT);
|
||||
dayCell.getStyleClass().add("timetable-day-cell");
|
||||
|
||||
Label dayLabel = new Label(translateDay(day));
|
||||
dayLabel.getStyleClass().addAll("timetable-day-label", "title-3");
|
||||
dayCell.getChildren().add(dayLabel);
|
||||
|
||||
timetableGrid.add(dayCell, 0, rowIndex);
|
||||
|
||||
List<LessonSpot> spots = timetable.get(day);
|
||||
if (spots != null) {
|
||||
int colIndex = 1;
|
||||
for (LessonSpot spot : spots) {
|
||||
int span = spot.getPeriodSpan();
|
||||
|
||||
if (spot.isNotEmpty()) {
|
||||
VBox cell = createLessonCell(spot);
|
||||
timetableGrid.add(cell, colIndex, rowIndex, span, 1);
|
||||
} else {
|
||||
VBox emptyCell = new VBox();
|
||||
emptyCell.getStyleClass().add("timetable-cell-empty");
|
||||
timetableGrid.add(emptyCell, colIndex, rowIndex, span, 1);
|
||||
}
|
||||
|
||||
colIndex += span;
|
||||
}
|
||||
}
|
||||
|
||||
rowIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
private VBox createLessonCell(LessonSpot spot) {
|
||||
VBox cell = new VBox(5);
|
||||
cell.setAlignment(Pos.CENTER);
|
||||
cell.getStyleClass().addAll("card", "timetable-cell");
|
||||
|
||||
if (spot.getSize() == 1) {
|
||||
Lesson lesson = spot.getLesson(0);
|
||||
addLessonInfoToCell(cell, lesson);
|
||||
} else {
|
||||
VBox groupContainer = new VBox(5);
|
||||
groupContainer.setAlignment(Pos.CENTER);
|
||||
|
||||
for (int i = 0; i < spot.getSize(); i++) {
|
||||
Lesson lesson = spot.getLesson(i);
|
||||
VBox groupCell = new VBox(2);
|
||||
groupCell.setAlignment(Pos.CENTER);
|
||||
addLessonInfoToCell(groupCell, lesson);
|
||||
|
||||
if (lesson.getGroup() != null) {
|
||||
Label groupLbl = new Label(lesson.getGroup());
|
||||
groupLbl.getStyleClass().add("timetable-group-label");
|
||||
groupCell.getChildren().add(0, groupLbl);
|
||||
}
|
||||
|
||||
groupContainer.getChildren().add(groupCell);
|
||||
|
||||
if (i < spot.getSize() - 1) {
|
||||
Separator sep = new Separator(javafx.geometry.Orientation.HORIZONTAL);
|
||||
groupContainer.getChildren().add(sep);
|
||||
}
|
||||
}
|
||||
cell.getChildren().add(groupContainer);
|
||||
}
|
||||
|
||||
cell.setOnMouseClicked(e -> showLessonDetails(spot));
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
private void addLessonInfoToCell(VBox cell, Lesson lesson) {
|
||||
Label subjectLbl = new Label(lesson.getSubjectName().getShort() != null ? lesson.getSubjectName().getShort() : lesson.getSubjectName().getFull());
|
||||
subjectLbl.getStyleClass().add("timetable-subject");
|
||||
|
||||
HBox bottomInfo = new HBox(5);
|
||||
bottomInfo.setAlignment(Pos.CENTER);
|
||||
|
||||
if (lesson.getTeacherName() != null) {
|
||||
Label teacherLbl = new Label(lesson.getTeacherName().getShort() != null ? lesson.getTeacherName().getShort() : lesson.getTeacherName().getFull());
|
||||
teacherLbl.getStyleClass().add("timetable-teacher");
|
||||
bottomInfo.getChildren().add(teacherLbl);
|
||||
}
|
||||
|
||||
if (lesson.getClassroom() != null) {
|
||||
Label roomLbl = new Label(lesson.getClassroom());
|
||||
roomLbl.getStyleClass().add("timetable-room");
|
||||
bottomInfo.getChildren().add(roomLbl);
|
||||
}
|
||||
|
||||
cell.getChildren().addAll(subjectLbl, bottomInfo);
|
||||
}
|
||||
|
||||
private void showLessonDetails(LessonSpot spot) {
|
||||
Dialog<Void> dialog = new Dialog<>();
|
||||
dialog.setTitle("Detail hodiny");
|
||||
dialog.setHeaderText(null);
|
||||
dialog.getDialogPane().getButtonTypes().add(ButtonType.CLOSE);
|
||||
|
||||
VBox content = new VBox(15);
|
||||
content.setPadding(new Insets(20));
|
||||
|
||||
for (Lesson lesson : spot) {
|
||||
VBox lessonInfo = new VBox(5);
|
||||
lessonInfo.getStyleClass().add("timetable-detail-box");
|
||||
|
||||
Label title = new Label(lesson.getSubjectName().getFull());
|
||||
title.getStyleClass().add("title-3");
|
||||
lessonInfo.getChildren().add(title);
|
||||
|
||||
GridPane grid = new GridPane();
|
||||
grid.setHgap(10);
|
||||
grid.setVgap(5);
|
||||
|
||||
int row = 0;
|
||||
if (lesson.getTeacherName() != null) {
|
||||
grid.add(new Label("Učitel:"), 0, row);
|
||||
grid.add(new Label(lesson.getTeacherName().getFull()), 1, row++);
|
||||
}
|
||||
if (lesson.getClassroom() != null) {
|
||||
grid.add(new Label("Učebna:"), 0, row);
|
||||
grid.add(new Label(lesson.getClassroom()), 1, row++);
|
||||
}
|
||||
if (lesson.getGroup() != null) {
|
||||
grid.add(new Label("Skupina:"), 0, row);
|
||||
grid.add(new Label(lesson.getGroup()), 1, row++);
|
||||
}
|
||||
|
||||
lessonInfo.getChildren().add(grid);
|
||||
content.getChildren().add(lessonInfo);
|
||||
}
|
||||
|
||||
dialog.getDialogPane().setContent(content);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private String translateDay(DayOfWeek day) {
|
||||
return switch (day) {
|
||||
case MONDAY -> "Pondělí";
|
||||
case TUESDAY -> "Úterý";
|
||||
case WEDNESDAY -> "Středa";
|
||||
case THURSDAY -> "Čtvrtek";
|
||||
case FRIDAY -> "Pátek";
|
||||
case SATURDAY -> "Sobota";
|
||||
case SUNDAY -> "Neděle";
|
||||
};
|
||||
}
|
||||
|
||||
@FXML
|
||||
protected void onBackToDashboard() {
|
||||
Router.getInstance().navigate("/dashboard");
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
<!-- Row 0 -->
|
||||
<Button text="Známky" GridPane.rowIndex="0" GridPane.columnIndex="0" onAction="#onNavigateToGrades" styleClass="card"/>
|
||||
<Button text="Rozvrh" GridPane.rowIndex="0" GridPane.columnIndex="1" onAction="#onDoNothing" styleClass="card"/>
|
||||
<Button text="Rozvrh" GridPane.rowIndex="0" GridPane.columnIndex="1" onAction="#onNavigateToTimetable" styleClass="card"/>
|
||||
<Button text="Učitelé" GridPane.rowIndex="0" GridPane.columnIndex="2" onAction="#onDoNothing" styleClass="card"/>
|
||||
|
||||
<!-- Row 1 -->
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
<?import javafx.scene.control.ScrollPane?>
|
||||
<?import javafx.scene.layout.BorderPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.Region?>
|
||||
<?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.GradesController"
|
||||
style="-fx-background-color: linear-gradient(#0f1724, #071023);">
|
||||
style="-fx-background-color: linear-gradient(#0f1724, #071023);"
|
||||
stylesheets="@styles/grades.css">
|
||||
|
||||
<!-- Header -->
|
||||
<top>
|
||||
|
||||
@@ -51,74 +51,3 @@
|
||||
-fx-text-fill: transparent;
|
||||
}
|
||||
|
||||
/* Grades Styling */
|
||||
.subject-card {
|
||||
-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;
|
||||
}
|
||||
|
||||
.grade-badge {
|
||||
-fx-background-radius: 5px;
|
||||
-fx-min-width: 32px;
|
||||
-fx-min-height: 32px;
|
||||
-fx-alignment: center;
|
||||
-fx-padding: 2px 8px;
|
||||
}
|
||||
|
||||
.grade-small {
|
||||
-fx-min-height: 20px;
|
||||
-fx-max-height: 20px;
|
||||
-fx-min-width: 32px;
|
||||
-fx-opacity: 0.85;
|
||||
-fx-padding: 0px 8px;
|
||||
}
|
||||
|
||||
.grade-predicted {
|
||||
-fx-background-color: transparent !important;
|
||||
-fx-border-style: dashed;
|
||||
-fx-border-width: 1px;
|
||||
-fx-border-radius: 4px;
|
||||
-fx-opacity: 1.0;
|
||||
}
|
||||
.grade-predicted.grade-1 { -fx-border-color: #2ea043; }
|
||||
.grade-predicted.grade-1 .grade-text { -fx-text-fill: #2ea043; }
|
||||
.grade-predicted.grade-2 { -fx-border-color: #8957e5; }
|
||||
.grade-predicted.grade-2 .grade-text { -fx-text-fill: #8957e5; }
|
||||
.grade-predicted.grade-3 { -fx-border-color: #d29922; }
|
||||
.grade-predicted.grade-3 .grade-text { -fx-text-fill: #d29922; }
|
||||
.grade-predicted.grade-4 { -fx-border-color: #f85149; }
|
||||
.grade-predicted.grade-4 .grade-text { -fx-text-fill: #f85149; }
|
||||
.grade-predicted.grade-5 { -fx-border-color: #da3633; }
|
||||
.grade-predicted.grade-5 .grade-text { -fx-text-fill: #da3633; }
|
||||
.grade-predicted.grade-other { -fx-border-color: #6e7681; }
|
||||
.grade-predicted.grade-other .grade-text { -fx-text-fill: #6e7681; }
|
||||
|
||||
.grade-add-btn {
|
||||
-fx-background-color: rgba(255, 255, 255, 0.02);
|
||||
-fx-border-color: rgba(255, 255, 255, 0.2);
|
||||
-fx-border-style: dashed;
|
||||
-fx-border-radius: 5px;
|
||||
-fx-cursor: hand;
|
||||
}
|
||||
.grade-add-btn:hover {
|
||||
-fx-background-color: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.grade-small .grade-text {
|
||||
-fx-font-size: 0.85em;
|
||||
}
|
||||
|
||||
.grade-text {
|
||||
-fx-font-weight: bold;
|
||||
-fx-text-fill: #ffffff;
|
||||
}
|
||||
|
||||
.grade-1 { -fx-background-color: #2ea043; } /* Primer Green */
|
||||
.grade-2 { -fx-background-color: #8957e5; } /* Primer Purple */
|
||||
.grade-3 { -fx-background-color: #d29922; } /* Primer Yellow */
|
||||
.grade-4 { -fx-background-color: #f85149; } /* Primer Red */
|
||||
.grade-5 { -fx-background-color: #da3633; -fx-border-color: #ff7b72; -fx-border-width: 1px; -fx-border-radius: 4px; } /* Darker Red */
|
||||
.grade-other { -fx-background-color: #6e7681; } /* Primer Gray */
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
.subject-card {
|
||||
-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;
|
||||
}
|
||||
|
||||
.grade-badge {
|
||||
-fx-background-radius: 5px;
|
||||
-fx-min-width: 32px;
|
||||
-fx-min-height: 32px;
|
||||
-fx-alignment: center;
|
||||
-fx-padding: 2px 8px;
|
||||
}
|
||||
|
||||
.grade-small {
|
||||
-fx-min-height: 20px;
|
||||
-fx-max-height: 20px;
|
||||
-fx-min-width: 32px;
|
||||
-fx-opacity: 0.85;
|
||||
-fx-padding: 0px 8px;
|
||||
}
|
||||
|
||||
.grade-predicted {
|
||||
-fx-background-color: transparent !important;
|
||||
-fx-border-style: dashed;
|
||||
-fx-border-width: 1px;
|
||||
-fx-border-radius: 4px;
|
||||
-fx-opacity: 1.0;
|
||||
}
|
||||
.grade-predicted.grade-1 { -fx-border-color: #2ea043; }
|
||||
.grade-predicted.grade-1 .grade-text { -fx-text-fill: #2ea043; }
|
||||
.grade-predicted.grade-2 { -fx-border-color: #8957e5; }
|
||||
.grade-predicted.grade-2 .grade-text { -fx-text-fill: #8957e5; }
|
||||
.grade-predicted.grade-3 { -fx-border-color: #d29922; }
|
||||
.grade-predicted.grade-3 .grade-text { -fx-text-fill: #d29922; }
|
||||
.grade-predicted.grade-4 { -fx-border-color: #f85149; }
|
||||
.grade-predicted.grade-4 .grade-text { -fx-text-fill: #f85149; }
|
||||
.grade-predicted.grade-5 { -fx-border-color: #da3633; }
|
||||
.grade-predicted.grade-5 .grade-text { -fx-text-fill: #da3633; }
|
||||
.grade-predicted.grade-other { -fx-border-color: #6e7681; }
|
||||
.grade-predicted.grade-other .grade-text { -fx-text-fill: #6e7681; }
|
||||
|
||||
.grade-add-btn {
|
||||
-fx-background-color: rgba(255, 255, 255, 0.02);
|
||||
-fx-border-color: rgba(255, 255, 255, 0.2);
|
||||
-fx-border-style: dashed;
|
||||
-fx-border-radius: 5px;
|
||||
-fx-cursor: hand;
|
||||
}
|
||||
.grade-add-btn:hover {
|
||||
-fx-background-color: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.grade-small .grade-text {
|
||||
-fx-font-size: 0.85em;
|
||||
}
|
||||
|
||||
.grade-text {
|
||||
-fx-font-weight: bold;
|
||||
-fx-text-fill: #ffffff;
|
||||
}
|
||||
|
||||
.grade-1 { -fx-background-color: #2ea043; } /* Primer Green */
|
||||
.grade-2 { -fx-background-color: #8957e5; } /* Primer Purple */
|
||||
.grade-3 { -fx-background-color: #d29922; } /* Primer Yellow */
|
||||
.grade-4 { -fx-background-color: #f85149; } /* Primer Red */
|
||||
.grade-5 { -fx-background-color: #da3633; -fx-border-color: #ff7b72; -fx-border-width: 1px; -fx-border-radius: 4px; } /* Darker Red */
|
||||
.grade-other { -fx-background-color: #6e7681; } /* Primer Gray */
|
||||
@@ -0,0 +1,97 @@
|
||||
.timetable-header {
|
||||
-fx-padding: 10px;
|
||||
-fx-background-color: rgba(255, 255, 255, 0.03);
|
||||
-fx-background-radius: 8px;
|
||||
-fx-border-color: rgba(255, 255, 255, 0.05);
|
||||
-fx-border-radius: 8px;
|
||||
}
|
||||
|
||||
.timetable-header-index {
|
||||
-fx-text-fill: #8b949e;
|
||||
-fx-font-size: 11px;
|
||||
-fx-font-weight: bold;
|
||||
}
|
||||
|
||||
.timetable-header-time {
|
||||
-fx-text-fill: #c9d1d9;
|
||||
-fx-font-size: 13px;
|
||||
}
|
||||
|
||||
.timetable-day-cell {
|
||||
-fx-padding: 10px 15px 10px 10px;
|
||||
-fx-background-color: rgba(255, 255, 255, 0.03);
|
||||
-fx-background-radius: 8px;
|
||||
-fx-border-color: rgba(255, 255, 255, 0.05);
|
||||
-fx-border-radius: 8px;
|
||||
-fx-alignment: center-right;
|
||||
-fx-min-height: 80px;
|
||||
-fx-min-width: USE_PREF_SIZE;
|
||||
}
|
||||
|
||||
.timetable-day-label {
|
||||
-fx-text-fill: #ffffff;
|
||||
-fx-font-weight: bold;
|
||||
-fx-min-width: USE_PREF_SIZE;
|
||||
}
|
||||
|
||||
.timetable-cell {
|
||||
-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: 10px;
|
||||
-fx-min-width: 100px;
|
||||
-fx-min-height: 80px;
|
||||
-fx-pref-width: -1;
|
||||
-fx-pref-height: -1;
|
||||
-fx-alignment: center;
|
||||
-fx-cursor: hand;
|
||||
}
|
||||
|
||||
.timetable-cell: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);
|
||||
}
|
||||
|
||||
.timetable-cell-empty {
|
||||
-fx-background-color: transparent;
|
||||
-fx-border-color: rgba(255, 255, 255, 0.02);
|
||||
-fx-border-style: dashed;
|
||||
-fx-border-radius: 8px;
|
||||
-fx-min-height: 80px;
|
||||
}
|
||||
|
||||
.timetable-subject {
|
||||
-fx-text-fill: white;
|
||||
-fx-font-size: 14px;
|
||||
-fx-font-weight: bold;
|
||||
}
|
||||
|
||||
.timetable-teacher {
|
||||
-fx-text-fill: #8b949e;
|
||||
-fx-font-size: 11px;
|
||||
}
|
||||
|
||||
.timetable-room {
|
||||
-fx-text-fill: #58a6ff;
|
||||
-fx-font-size: 11px;
|
||||
-fx-font-weight: bold;
|
||||
}
|
||||
|
||||
.timetable-group-label {
|
||||
-fx-text-fill: #d29922;
|
||||
-fx-font-size: 10px;
|
||||
-fx-font-weight: bold;
|
||||
-fx-padding: 2px 4px;
|
||||
-fx-background-color: rgba(210, 153, 34, 0.15);
|
||||
-fx-background-radius: 4px;
|
||||
}
|
||||
|
||||
.timetable-detail-box {
|
||||
-fx-background-color: rgba(255, 255, 255, 0.05);
|
||||
-fx-padding: 15px;
|
||||
-fx-background-radius: 8px;
|
||||
-fx-border-color: rgba(255, 255, 255, 0.1);
|
||||
-fx-border-radius: 8px;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?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.GridPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
|
||||
<BorderPane xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="cz.jzitnik.controllers.TimetableController"
|
||||
style="-fx-background-color: linear-gradient(#0f1724, #071023);"
|
||||
stylesheets="@styles/timetable.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="Rozvrh" 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">
|
||||
<padding>
|
||||
<Insets top="20" right="30" bottom="30" left="30"/>
|
||||
</padding>
|
||||
<GridPane fx:id="timetableGrid" hgap="10" vgap="10" alignment="CENTER" />
|
||||
</ScrollPane>
|
||||
</StackPane>
|
||||
</center>
|
||||
|
||||
</BorderPane>
|
||||
Reference in New Issue
Block a user