|
17 | 17 | import java.time.LocalDateTime; |
18 | 18 | import java.time.format.DateTimeFormatter; |
19 | 19 | import java.time.format.DateTimeParseException; |
| 20 | +import java.util.HashMap; |
20 | 21 | import java.util.List; |
| 22 | +import java.util.Map; |
21 | 23 | import java.util.function.Consumer; |
22 | 24 | import javafx.application.Platform; |
23 | 25 | import javafx.beans.property.SimpleObjectProperty; |
@@ -455,35 +457,90 @@ private void onBanUser() { |
455 | 457 | showStatus("Admin accounts cannot be banned.", true); |
456 | 458 | return; |
457 | 459 | } |
458 | | - TextInputDialog dlg = |
459 | | - new TextInputDialog(LocalDateTime.now().plusDays(7).format(BAN_EXPIRY_FMT)); |
460 | | - dlg.setTitle("Ban User"); |
461 | | - dlg.setHeaderText("Enter automatic unban date and time (DD/MM/YYYY HH:MM):"); |
462 | | - dlg.showAndWait() |
463 | | - .ifPresent( |
464 | | - expiryText -> { |
465 | | - try { |
466 | | - LocalDateTime expiry = LocalDateTime.parse(expiryText.trim(), BAN_EXPIRY_FMT); |
467 | | - LocalDateTime now = LocalDateTime.now(); |
468 | | - if (!expiry.isAfter(now)) { |
469 | | - showStatus( |
470 | | - "Unban time must be later than the current date and time.", true); |
471 | | - return; |
472 | | - } |
473 | | - long durationSeconds = |
474 | | - Math.max(1, java.time.Duration.between(now, expiry).getSeconds()); |
475 | | - appState.restUserService.banUser(user.getId(), durationSeconds); |
476 | | - refreshUsers(); |
477 | | - showStatus("User banned until " + expiry.format(BAN_EXPIRY_FMT) + ".", false); |
478 | | - } catch (DateTimeParseException e) { |
479 | | - showStatus("Use DD/MM/YYYY HH:MM, e.g. 25/12/2026 14:30.", true); |
480 | | - } catch (Exception e) { |
481 | | - showStatus(e.getMessage(), true); |
482 | | - } |
483 | | - }); |
| 460 | + showBanDialog(user); |
484 | 461 | }); |
485 | 462 | } |
486 | 463 |
|
| 464 | + private void showBanDialog(User user) { |
| 465 | + Dialog<Map<String, Object>> dlg = new Dialog<>(); |
| 466 | + dlg.setTitle("Ban User"); |
| 467 | + dlg.setHeaderText("Ban user \"" + user.getUsername() + "\""); |
| 468 | + |
| 469 | + GridPane grid = new GridPane(); |
| 470 | + grid.setHgap(10); |
| 471 | + grid.setVgap(10); |
| 472 | + grid.setPadding(new Insets(20, 20, 10, 20)); |
| 473 | + |
| 474 | + javafx.scene.control.CheckBox permanentCheckBox = |
| 475 | + new javafx.scene.control.CheckBox("Permanent ban"); |
| 476 | + javafx.scene.control.TextField dateField = |
| 477 | + new javafx.scene.control.TextField(LocalDateTime.now().plusDays(7).format(BAN_EXPIRY_FMT)); |
| 478 | + dateField.setPromptText("DD/MM/YYYY HH:MM"); |
| 479 | + Label dateLabel = new Label("Unban date and time:"); |
| 480 | + |
| 481 | + grid.add(permanentCheckBox, 0, 0, 2, 1); |
| 482 | + grid.add(dateLabel, 0, 1); |
| 483 | + grid.add(dateField, 1, 1); |
| 484 | + |
| 485 | + permanentCheckBox |
| 486 | + .selectedProperty() |
| 487 | + .addListener( |
| 488 | + (obs, oldVal, newVal) -> { |
| 489 | + dateLabel.setDisable(newVal); |
| 490 | + dateField.setDisable(newVal); |
| 491 | + if (newVal) { |
| 492 | + dateLabel.setStyle("-fx-opacity: 0.4;"); |
| 493 | + dateField.setStyle("-fx-opacity: 0.4;"); |
| 494 | + } else { |
| 495 | + dateLabel.setStyle(""); |
| 496 | + dateField.setStyle(""); |
| 497 | + } |
| 498 | + }); |
| 499 | + |
| 500 | + dlg.getDialogPane().setContent(grid); |
| 501 | + ButtonType banBtn = new ButtonType("Ban", ButtonBar.ButtonData.OK_DONE); |
| 502 | + dlg.getDialogPane().getButtonTypes().addAll(banBtn, ButtonType.CANCEL); |
| 503 | + |
| 504 | + dlg.setResultConverter( |
| 505 | + btn -> { |
| 506 | + if (btn != banBtn) return null; |
| 507 | + Map<String, Object> result = new HashMap<>(); |
| 508 | + result.put("permanent", permanentCheckBox.isSelected()); |
| 509 | + result.put("dateText", dateField.getText()); |
| 510 | + return result; |
| 511 | + }); |
| 512 | + |
| 513 | + dlg.showAndWait() |
| 514 | + .ifPresent( |
| 515 | + result -> { |
| 516 | + try { |
| 517 | + boolean permanent = (boolean) result.get("permanent"); |
| 518 | + if (permanent) { |
| 519 | + appState.restUserService.banUser(user.getId(), 0, true); |
| 520 | + refreshUsers(); |
| 521 | + showStatus("User banned permanently.", false); |
| 522 | + } else { |
| 523 | + String dateText = (String) result.get("dateText"); |
| 524 | + LocalDateTime expiry = LocalDateTime.parse(dateText.trim(), BAN_EXPIRY_FMT); |
| 525 | + LocalDateTime now = LocalDateTime.now(); |
| 526 | + if (!expiry.isAfter(now)) { |
| 527 | + showStatus("Unban time must be later than the current date and time.", true); |
| 528 | + return; |
| 529 | + } |
| 530 | + long durationSeconds = |
| 531 | + Math.max(1, java.time.Duration.between(now, expiry).getSeconds()); |
| 532 | + appState.restUserService.banUser(user.getId(), durationSeconds, false); |
| 533 | + refreshUsers(); |
| 534 | + showStatus("User banned until " + expiry.format(BAN_EXPIRY_FMT) + ".", false); |
| 535 | + } |
| 536 | + } catch (DateTimeParseException e) { |
| 537 | + showStatus("Use DD/MM/YYYY HH:MM, e.g. 25/12/2026 14:30.", true); |
| 538 | + } catch (Exception e) { |
| 539 | + showStatus(e.getMessage(), true); |
| 540 | + } |
| 541 | + }); |
| 542 | + } |
| 543 | + |
487 | 544 | @FXML |
488 | 545 | private void onUnbanUser() { |
489 | 546 | withSelectedUser( |
|
0 commit comments