Change Credentials UI implemented.
This commit is contained in:
@@ -0,0 +1,160 @@
|
|||||||
|
package org.to.telegramfinalproject.UI;
|
||||||
|
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.layout.Pane;
|
||||||
|
import javafx.scene.layout.StackPane;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
|
||||||
|
public class ChangeCredentialsController {
|
||||||
|
|
||||||
|
@FXML private VBox credentialsCard;
|
||||||
|
@FXML private Pane overlayBackground;
|
||||||
|
@FXML private TextField usernameField;
|
||||||
|
@FXML private Label usernameLabel;
|
||||||
|
|
||||||
|
@FXML private Label passwordLabel;
|
||||||
|
@FXML private PasswordField passwordField;
|
||||||
|
@FXML private TextField visiblePasswordField;
|
||||||
|
@FXML private Button togglePasswordBtn;
|
||||||
|
|
||||||
|
@FXML private Label confirmPasswordLabel;
|
||||||
|
@FXML private PasswordField confirmPasswordField;
|
||||||
|
@FXML private TextField visibleConfirmPasswordField;
|
||||||
|
@FXML private Button toggleConfirmBtn;
|
||||||
|
|
||||||
|
@FXML private Button cancelButton;
|
||||||
|
@FXML private Button saveButton;
|
||||||
|
@FXML private Button closeButton;
|
||||||
|
|
||||||
|
private boolean passwordVisible = false;
|
||||||
|
private boolean confirmVisible = false;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private void initialize() {
|
||||||
|
// Toggle password visibility
|
||||||
|
togglePasswordBtn.setOnAction(e -> togglePasswordVisibility());
|
||||||
|
toggleConfirmBtn.setOnAction(e -> toggleConfirmVisibility());
|
||||||
|
|
||||||
|
saveButton.setOnAction(e -> validateAndSave());
|
||||||
|
|
||||||
|
// Close the overlay
|
||||||
|
closeButton.setOnAction(e ->
|
||||||
|
MainController.getInstance().closeOverlay(credentialsCard.getParent()));
|
||||||
|
cancelButton.setOnAction(e ->
|
||||||
|
MainController.getInstance().closeOverlay(credentialsCard.getParent()));
|
||||||
|
overlayBackground.setOnMouseClicked(e ->
|
||||||
|
MainController.getInstance().closeOverlay(credentialsCard.getParent())
|
||||||
|
);
|
||||||
|
|
||||||
|
// Reset error when typing
|
||||||
|
usernameField.textProperty().addListener((obs, o, n) -> removeError(usernameField, usernameLabel));
|
||||||
|
|
||||||
|
passwordField.textProperty().addListener((obs, o, n) -> {
|
||||||
|
visiblePasswordField.setText(n); // keep synced
|
||||||
|
removeError(passwordField, passwordLabel);
|
||||||
|
removeError(visiblePasswordField, passwordLabel);
|
||||||
|
});
|
||||||
|
visiblePasswordField.textProperty().addListener((obs, o, n) -> {
|
||||||
|
passwordField.setText(n);
|
||||||
|
removeError(passwordField, passwordLabel);
|
||||||
|
removeError(visiblePasswordField, passwordLabel);
|
||||||
|
});
|
||||||
|
|
||||||
|
confirmPasswordField.textProperty().addListener((obs, o, n) -> {
|
||||||
|
visibleConfirmPasswordField.setText(n);
|
||||||
|
removeError(confirmPasswordField, confirmPasswordLabel);
|
||||||
|
removeError(visibleConfirmPasswordField, confirmPasswordLabel);
|
||||||
|
});
|
||||||
|
visibleConfirmPasswordField.textProperty().addListener((obs, o, n) -> {
|
||||||
|
confirmPasswordField.setText(n);
|
||||||
|
removeError(confirmPasswordField, confirmPasswordLabel);
|
||||||
|
removeError(visibleConfirmPasswordField, confirmPasswordLabel);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Auto_focus password field when overlay opens
|
||||||
|
Platform.runLater(() -> usernameField.requestFocus());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void togglePasswordVisibility() {
|
||||||
|
passwordVisible = !passwordVisible;
|
||||||
|
visiblePasswordField.setText(passwordField.getText());
|
||||||
|
visiblePasswordField.setVisible(passwordVisible);
|
||||||
|
visiblePasswordField.setManaged(passwordVisible);
|
||||||
|
|
||||||
|
passwordField.setVisible(!passwordVisible);
|
||||||
|
passwordField.setManaged(!passwordVisible);
|
||||||
|
|
||||||
|
togglePasswordBtn.setText(passwordVisible ? "👁" : "👁");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void toggleConfirmVisibility() {
|
||||||
|
confirmVisible = !confirmVisible;
|
||||||
|
visibleConfirmPasswordField.setText(confirmPasswordField.getText());
|
||||||
|
visibleConfirmPasswordField.setVisible(confirmVisible);
|
||||||
|
visibleConfirmPasswordField.setManaged(confirmVisible);
|
||||||
|
|
||||||
|
confirmPasswordField.setVisible(!confirmVisible);
|
||||||
|
confirmPasswordField.setManaged(!confirmVisible);
|
||||||
|
|
||||||
|
toggleConfirmBtn.setText(confirmVisible ? "👁" : "👁");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateAndSave() {
|
||||||
|
boolean hasError = false;
|
||||||
|
|
||||||
|
// --- Username check ---
|
||||||
|
if (usernameField.getText().trim().isEmpty()) {
|
||||||
|
addError(usernameField, usernameLabel);
|
||||||
|
hasError = true;
|
||||||
|
} else {
|
||||||
|
removeError(usernameField, usernameLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Password check ---
|
||||||
|
String pwd = passwordVisible ? visiblePasswordField.getText().trim() : passwordField.getText().trim();
|
||||||
|
if (pwd.isEmpty()) {
|
||||||
|
addError(passwordField, passwordLabel);
|
||||||
|
addError(visiblePasswordField, passwordLabel);
|
||||||
|
hasError = true;
|
||||||
|
} else {
|
||||||
|
removeError(passwordField, passwordLabel);
|
||||||
|
removeError(visiblePasswordField, passwordLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Confirm password check ---
|
||||||
|
String confirm = confirmVisible ? visibleConfirmPasswordField.getText().trim() : confirmPasswordField.getText().trim();
|
||||||
|
if (confirm.isEmpty()) {
|
||||||
|
addError(confirmPasswordField, confirmPasswordLabel);
|
||||||
|
addError(visibleConfirmPasswordField, confirmPasswordLabel);
|
||||||
|
hasError = true;
|
||||||
|
} else if (!confirm.equals(pwd)) {
|
||||||
|
addError(confirmPasswordField, confirmPasswordLabel);
|
||||||
|
addError(visibleConfirmPasswordField, confirmPasswordLabel);
|
||||||
|
hasError = true;
|
||||||
|
} else {
|
||||||
|
removeError(confirmPasswordField, confirmPasswordLabel);
|
||||||
|
removeError(visibleConfirmPasswordField, confirmPasswordLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasError) return;
|
||||||
|
|
||||||
|
// TODO: send to server
|
||||||
|
System.out.println("Saving new credentials...");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addError(TextField field, Label label) {
|
||||||
|
if (!field.getStyleClass().contains("error-input")) {
|
||||||
|
field.getStyleClass().add("error-input");
|
||||||
|
}
|
||||||
|
if (!label.getStyleClass().contains("error-label")) {
|
||||||
|
label.getStyleClass().add("error-label");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeError(TextField field, Label label) {
|
||||||
|
field.getStyleClass().remove("error-input");
|
||||||
|
label.getStyleClass().remove("error-label");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,12 +2,16 @@ package org.to.telegramfinalproject.UI;
|
|||||||
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.fxml.FXMLLoader;
|
||||||
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.layout.Pane;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class CheckPasswordController {
|
public class CheckPasswordController {
|
||||||
|
|
||||||
@FXML private VBox checkPasswordCard;
|
@FXML private VBox checkPasswordCard;
|
||||||
@@ -103,9 +107,8 @@ public class CheckPasswordController {
|
|||||||
visiblePasswordField.getStyleClass().remove("error");
|
visiblePasswordField.getStyleClass().remove("error");
|
||||||
passwordLabel.getStyleClass().remove("error");
|
passwordLabel.getStyleClass().remove("error");
|
||||||
|
|
||||||
// TODO: go to change credentials scene
|
// Go to the next scene
|
||||||
System.out.println("Password OK → go to next scene");
|
openChangeCredentials();
|
||||||
// MainController.getInstance().showOverlay("/org/to/telegramfinalproject/Fxml/change_credentials.fxml");
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Error → add error styles
|
// Error → add error styles
|
||||||
@@ -142,4 +145,18 @@ public class CheckPasswordController {
|
|||||||
icon.setFitHeight(16);
|
icon.setFitHeight(16);
|
||||||
backButton.setGraphic(icon);
|
backButton.setGraphic(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void openChangeCredentials() {
|
||||||
|
try {
|
||||||
|
FXMLLoader loader = new FXMLLoader(getClass().getResource(
|
||||||
|
"/org/to/telegramfinalproject/Fxml/change_credentials.fxml"));
|
||||||
|
Node overlay = loader.load();
|
||||||
|
|
||||||
|
// Show new overlay
|
||||||
|
MainController.getInstance().showOverlay(overlay);
|
||||||
|
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1068,3 +1068,14 @@
|
|||||||
.blocked-list .list-cell:hover {
|
.blocked-list .list-cell:hover {
|
||||||
-fx-background-color: #2a3a4a;
|
-fx-background-color: #2a3a4a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Error label */
|
||||||
|
.label.error-label {
|
||||||
|
-fx-text-fill: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Error input */
|
||||||
|
.error-input {
|
||||||
|
-fx-border-color: red;
|
||||||
|
-fx-border-radius: 6;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1060,3 +1060,13 @@
|
|||||||
-fx-background-radius: 4; /* soft rounded edges */
|
-fx-background-radius: 4; /* soft rounded edges */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Error label */
|
||||||
|
.label.error-label {
|
||||||
|
-fx-text-fill: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Error input */
|
||||||
|
.error-input {
|
||||||
|
-fx-border-color: red;
|
||||||
|
-fx-border-radius: 6;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.scene.layout.*?>
|
||||||
|
<?import javafx.scene.control.*?>
|
||||||
|
|
||||||
|
<StackPane xmlns:fx="http://javafx.com/fxml"
|
||||||
|
fx:controller="org.to.telegramfinalproject.UI.ChangeCredentialsController"
|
||||||
|
styleClass="overlay-root">
|
||||||
|
|
||||||
|
<!-- Dimmed background -->
|
||||||
|
<Pane fx:id="overlayBackground" styleClass="overlay-background"/>
|
||||||
|
|
||||||
|
<!-- Main card -->
|
||||||
|
<VBox fx:id="credentialsCard"
|
||||||
|
styleClass="privacy-card"
|
||||||
|
spacing="16"
|
||||||
|
alignment="TOP_CENTER"
|
||||||
|
prefWidth="380" maxWidth="380"
|
||||||
|
prefHeight="280" maxHeight="280">
|
||||||
|
|
||||||
|
<!-- ===== Header ===== -->
|
||||||
|
<HBox alignment="CENTER_LEFT" spacing="10" styleClass="privacy-header">
|
||||||
|
<Label text="Change Credentials" styleClass="privacy-title"/>
|
||||||
|
<Pane HBox.hgrow="ALWAYS"/>
|
||||||
|
<Button fx:id="closeButton" styleClass="icon-button" text="✕"/>
|
||||||
|
</HBox>
|
||||||
|
|
||||||
|
<Separator/>
|
||||||
|
|
||||||
|
<!-- ===== Form ===== -->
|
||||||
|
<VBox spacing="10" alignment="CENTER_LEFT" styleClass="privacy-form">
|
||||||
|
|
||||||
|
<!-- New Username -->
|
||||||
|
<Label fx:id="usernameLabel" text="New Username" styleClass="password-label"/>
|
||||||
|
<TextField fx:id="usernameField"
|
||||||
|
promptText="Enter new username"
|
||||||
|
styleClass="privacy-input"/>
|
||||||
|
|
||||||
|
<!-- New Password -->
|
||||||
|
<Label fx:id="passwordLabel" text="New Password" styleClass="password-label"/>
|
||||||
|
|
||||||
|
<HBox alignment="CENTER_LEFT" spacing="4" styleClass="privacy-item">
|
||||||
|
<PasswordField fx:id="passwordField"
|
||||||
|
promptText="Enter new password"
|
||||||
|
styleClass="privacy-input"
|
||||||
|
HBox.hgrow="ALWAYS"/>
|
||||||
|
<TextField fx:id="visiblePasswordField"
|
||||||
|
promptText="Enter new password"
|
||||||
|
styleClass="privacy-input"
|
||||||
|
visible="false" managed="false"
|
||||||
|
HBox.hgrow="ALWAYS"/>
|
||||||
|
<Button fx:id="togglePasswordBtn"
|
||||||
|
text="👁"
|
||||||
|
styleClass="toggle-visibility-btn"/>
|
||||||
|
</HBox>
|
||||||
|
|
||||||
|
<!-- Confirm Password -->
|
||||||
|
<Label fx:id="confirmPasswordLabel" text="Confirm Password" styleClass="password-label"/>
|
||||||
|
|
||||||
|
<HBox alignment="CENTER_LEFT" spacing="4" styleClass="privacy-item">
|
||||||
|
<PasswordField fx:id="confirmPasswordField"
|
||||||
|
promptText="Re-enter new password"
|
||||||
|
styleClass="privacy-input"
|
||||||
|
HBox.hgrow="ALWAYS"/>
|
||||||
|
<TextField fx:id="visibleConfirmPasswordField"
|
||||||
|
promptText="Re-enter new password"
|
||||||
|
styleClass="privacy-input"
|
||||||
|
visible="false" managed="false"
|
||||||
|
HBox.hgrow="ALWAYS"/>
|
||||||
|
<Button fx:id="toggleConfirmBtn"
|
||||||
|
text="👁"
|
||||||
|
styleClass="toggle-visibility-btn"/>
|
||||||
|
</HBox>
|
||||||
|
</VBox>
|
||||||
|
|
||||||
|
<!-- ===== Footer ===== -->
|
||||||
|
<HBox alignment="CENTER_RIGHT" spacing="12">
|
||||||
|
<Button fx:id="cancelButton" text="Cancel" styleClass="footer-button"/>
|
||||||
|
<Button fx:id="saveButton" text="Save" styleClass="action-button"/>
|
||||||
|
</HBox>
|
||||||
|
</VBox>
|
||||||
|
</StackPane>
|
||||||
Reference in New Issue
Block a user