merge fixes into main
This commit is contained in:
@@ -5,6 +5,7 @@ public class UserInfoResponse {
|
||||
private String username;
|
||||
private String email;
|
||||
private String fullName;
|
||||
private String phone;
|
||||
private String avatarUrl;
|
||||
private String role;
|
||||
private Long storeId;
|
||||
@@ -45,6 +46,14 @@ public class UserInfoResponse {
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public String getAvatarUrl() {
|
||||
return avatarUrl;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.example.petshopdesktop.api.dto.employee;
|
||||
|
||||
public class EmployeeRequest {
|
||||
private String username;
|
||||
private String password;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String email;
|
||||
private String phone;
|
||||
private String role;
|
||||
private Boolean active;
|
||||
|
||||
public String getUsername() { return username; }
|
||||
public void setUsername(String username) { this.username = username; }
|
||||
public String getPassword() { return password; }
|
||||
public void setPassword(String password) { this.password = password; }
|
||||
public String getFirstName() { return firstName; }
|
||||
public void setFirstName(String firstName) { this.firstName = firstName; }
|
||||
public String getLastName() { return lastName; }
|
||||
public void setLastName(String lastName) { this.lastName = lastName; }
|
||||
public String getEmail() { return email; }
|
||||
public void setEmail(String email) { this.email = email; }
|
||||
public String getPhone() { return phone; }
|
||||
public void setPhone(String phone) { this.phone = phone; }
|
||||
public String getRole() { return role; }
|
||||
public void setRole(String role) { this.role = role; }
|
||||
public Boolean getActive() { return active; }
|
||||
public void setActive(Boolean active) { this.active = active; }
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package org.example.petshopdesktop.api.dto.employee;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class EmployeeResponse {
|
||||
private Long employeeId;
|
||||
private Long userId;
|
||||
private String username;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String fullName;
|
||||
private String email;
|
||||
private String phone;
|
||||
private String role;
|
||||
private Boolean active;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
public Long getEmployeeId() { return employeeId; }
|
||||
public void setEmployeeId(Long employeeId) { this.employeeId = employeeId; }
|
||||
public Long getUserId() { return userId; }
|
||||
public void setUserId(Long userId) { this.userId = userId; }
|
||||
public String getUsername() { return username; }
|
||||
public void setUsername(String username) { this.username = username; }
|
||||
public String getFirstName() { return firstName; }
|
||||
public void setFirstName(String firstName) { this.firstName = firstName; }
|
||||
public String getLastName() { return lastName; }
|
||||
public void setLastName(String lastName) { this.lastName = lastName; }
|
||||
public String getFullName() { return fullName; }
|
||||
public void setFullName(String fullName) { this.fullName = fullName; }
|
||||
public String getEmail() { return email; }
|
||||
public void setEmail(String email) { this.email = email; }
|
||||
public String getPhone() { return phone; }
|
||||
public void setPhone(String phone) { this.phone = phone; }
|
||||
public String getRole() { return role; }
|
||||
public void setRole(String role) { this.role = role; }
|
||||
public Boolean getActive() { return active; }
|
||||
public void setActive(Boolean active) { this.active = active; }
|
||||
public LocalDateTime getCreatedAt() { return createdAt; }
|
||||
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
|
||||
public LocalDateTime getUpdatedAt() { return updatedAt; }
|
||||
public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; }
|
||||
}
|
||||
@@ -5,6 +5,7 @@ public class UserRequest {
|
||||
private String password;
|
||||
private String fullName;
|
||||
private String email;
|
||||
private String phone;
|
||||
private String role;
|
||||
private Boolean active;
|
||||
|
||||
@@ -43,6 +44,14 @@ public class UserRequest {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ public class UserResponse {
|
||||
private String username;
|
||||
private String fullName;
|
||||
private String email;
|
||||
private String phone;
|
||||
private String role;
|
||||
private Boolean active;
|
||||
private LocalDateTime createdAt;
|
||||
@@ -47,6 +48,14 @@ public class UserResponse {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPhone() {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.example.petshopdesktop.api.endpoints;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import org.example.petshopdesktop.api.ApiClient;
|
||||
import org.example.petshopdesktop.api.dto.common.PageResponse;
|
||||
import org.example.petshopdesktop.api.dto.employee.EmployeeRequest;
|
||||
import org.example.petshopdesktop.api.dto.employee.EmployeeResponse;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
public class EmployeeApi {
|
||||
private static final EmployeeApi INSTANCE = new EmployeeApi();
|
||||
private final ApiClient apiClient;
|
||||
|
||||
private EmployeeApi() {
|
||||
this.apiClient = ApiClient.getInstance();
|
||||
}
|
||||
|
||||
public static EmployeeApi getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public List<EmployeeResponse> listEmployees(String query) throws Exception {
|
||||
String path = "/api/v1/employees?page=0&size=1000";
|
||||
if (query != null && !query.isEmpty()) {
|
||||
path += "&q=" + URLEncoder.encode(query, StandardCharsets.UTF_8);
|
||||
}
|
||||
String response = apiClient.getRawResponse(path);
|
||||
PageResponse<EmployeeResponse> pageResponse = apiClient.getObjectMapper().readValue(
|
||||
response,
|
||||
new TypeReference<PageResponse<EmployeeResponse>>() {}
|
||||
);
|
||||
if (pageResponse == null) {
|
||||
throw new IllegalStateException("Null response from employees endpoint");
|
||||
}
|
||||
return pageResponse.getContent();
|
||||
}
|
||||
|
||||
public EmployeeResponse createEmployee(EmployeeRequest request) throws Exception {
|
||||
return apiClient.post("/api/v1/employees", request, EmployeeResponse.class);
|
||||
}
|
||||
|
||||
public EmployeeResponse updateEmployee(Long id, EmployeeRequest request) throws Exception {
|
||||
return apiClient.put("/api/v1/employees/" + id, request, EmployeeResponse.class);
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,8 @@ import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
import org.example.petshopdesktop.api.dto.user.UserResponse;
|
||||
import org.example.petshopdesktop.api.endpoints.UserApi;
|
||||
import org.example.petshopdesktop.api.dto.employee.EmployeeResponse;
|
||||
import org.example.petshopdesktop.api.endpoints.EmployeeApi;
|
||||
import org.example.petshopdesktop.auth.UserSession;
|
||||
import org.example.petshopdesktop.models.StaffAccount;
|
||||
import org.example.petshopdesktop.util.ActivityLogger;
|
||||
@@ -59,6 +59,9 @@ public class StaffAccountsController {
|
||||
@FXML
|
||||
private Button btnCreateAccount;
|
||||
|
||||
@FXML
|
||||
private Button btnEditAccount;
|
||||
|
||||
private final ObservableList<StaffAccount> staffAccounts = FXCollections.observableArrayList();
|
||||
private FilteredList<StaffAccount> filtered;
|
||||
|
||||
@@ -76,13 +79,26 @@ public class StaffAccountsController {
|
||||
|
||||
txtSearch.textProperty().addListener((obs, o, n) -> applyFilter(n));
|
||||
|
||||
tvStaff.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> {
|
||||
if (btnEditAccount != null) {
|
||||
btnEditAccount.setDisable(newValue == null);
|
||||
}
|
||||
});
|
||||
|
||||
if (!UserSession.getInstance().isAdmin()) {
|
||||
lblError.setText("Access restricted.");
|
||||
tvStaff.setDisable(true);
|
||||
btnCreateAccount.setDisable(true);
|
||||
if (btnEditAccount != null) {
|
||||
btnEditAccount.setDisable(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (btnEditAccount != null) {
|
||||
btnEditAccount.setDisable(true);
|
||||
}
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
@@ -110,14 +126,40 @@ public class StaffAccountsController {
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
void btnEditAccountClicked(ActionEvent event) {
|
||||
lblError.setText("");
|
||||
StaffAccount selected = tvStaff.getSelectionModel().getSelectedItem();
|
||||
if (selected == null) {
|
||||
lblError.setText("Select a staff account to edit.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/example/petshopdesktop/dialogviews/staff-edit-dialog-view.fxml"));
|
||||
Stage dialog = new Stage();
|
||||
dialog.initOwner(tvStaff.getScene().getWindow());
|
||||
dialog.initModality(Modality.APPLICATION_MODAL);
|
||||
dialog.setTitle("Edit Staff Account");
|
||||
dialog.setScene(new Scene(loader.load()));
|
||||
dialog.setResizable(false);
|
||||
var controller = (org.example.petshopdesktop.controllers.dialogcontrollers.StaffEditDialogController) loader.getController();
|
||||
controller.setStaffAccount(selected);
|
||||
dialog.showAndWait();
|
||||
refresh();
|
||||
} catch (Exception e) {
|
||||
ActivityLogger.getInstance().logException("StaffAccountsController.btnEditAccountClicked", e, "Opening staff edit dialog");
|
||||
lblError.setText("Could not open staff account editor.");
|
||||
}
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
lblError.setText("");
|
||||
tvStaff.setDisable(true);
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
List<UserResponse> users = UserApi.getInstance().listUsers(null);
|
||||
List<StaffAccount> accounts = users.stream()
|
||||
List<EmployeeResponse> employees = EmployeeApi.getInstance().listEmployees(null);
|
||||
List<StaffAccount> accounts = employees.stream()
|
||||
.map(this::mapToStaffAccount)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@@ -135,21 +177,23 @@ public class StaffAccountsController {
|
||||
}).start();
|
||||
}
|
||||
|
||||
private StaffAccount mapToStaffAccount(UserResponse user) {
|
||||
long id = user.getId() != null ? user.getId() : 0L;
|
||||
String username = user.getUsername();
|
||||
String fullName = user.getFullName() != null ? user.getFullName() : "";
|
||||
private StaffAccount mapToStaffAccount(EmployeeResponse employee) {
|
||||
long userId = employee.getUserId() != null ? employee.getUserId() : 0L;
|
||||
long employeeId = employee.getEmployeeId() != null ? employee.getEmployeeId() : 0L;
|
||||
String username = employee.getUsername();
|
||||
String fullName = employee.getFullName() != null ? employee.getFullName() : "";
|
||||
String[] names = splitFullName(fullName);
|
||||
String firstName = names[0];
|
||||
String lastName = names[1];
|
||||
String email = user.getEmail() != null ? user.getEmail() : "";
|
||||
String phone = "";
|
||||
boolean active = user.getActive() != null ? user.getActive() : false;
|
||||
Timestamp createdAt = user.getCreatedAt() != null
|
||||
? Timestamp.from(user.getCreatedAt().atZone(ZoneId.systemDefault()).toInstant())
|
||||
String email = employee.getEmail() != null ? employee.getEmail() : "";
|
||||
String phone = employee.getPhone() != null ? employee.getPhone() : "";
|
||||
String role = employee.getRole() != null ? employee.getRole() : "STAFF";
|
||||
boolean active = employee.getActive() != null ? employee.getActive() : false;
|
||||
Timestamp createdAt = employee.getCreatedAt() != null
|
||||
? Timestamp.from(employee.getCreatedAt().atZone(ZoneId.systemDefault()).toInstant())
|
||||
: null;
|
||||
|
||||
return new StaffAccount(id, id, username, firstName, lastName, email, phone, active, createdAt);
|
||||
return new StaffAccount(userId, employeeId, username, firstName, lastName, email, phone, role, active, createdAt);
|
||||
}
|
||||
|
||||
private String[] splitFullName(String fullName) {
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.PasswordField;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.stage.Stage;
|
||||
import org.example.petshopdesktop.Validator;
|
||||
import org.example.petshopdesktop.api.dto.employee.EmployeeRequest;
|
||||
import org.example.petshopdesktop.api.endpoints.EmployeeApi;
|
||||
import org.example.petshopdesktop.models.StaffAccount;
|
||||
import org.example.petshopdesktop.util.ActivityLogger;
|
||||
|
||||
public class StaffEditDialogController {
|
||||
|
||||
@FXML
|
||||
private TextField txtFirstName;
|
||||
|
||||
@FXML
|
||||
private TextField txtLastName;
|
||||
|
||||
@FXML
|
||||
private TextField txtEmail;
|
||||
|
||||
@FXML
|
||||
private TextField txtPhone;
|
||||
|
||||
@FXML
|
||||
private TextField txtUsername;
|
||||
|
||||
@FXML
|
||||
private PasswordField txtPassword;
|
||||
|
||||
@FXML
|
||||
private PasswordField txtPasswordConfirm;
|
||||
|
||||
@FXML
|
||||
private Label lblError;
|
||||
|
||||
@FXML
|
||||
private Button btnSave;
|
||||
|
||||
private StaffAccount staffAccount;
|
||||
|
||||
public void setStaffAccount(StaffAccount staffAccount) {
|
||||
this.staffAccount = staffAccount;
|
||||
txtFirstName.setText(staffAccount.getFirstName());
|
||||
txtLastName.setText(staffAccount.getLastName());
|
||||
txtEmail.setText(staffAccount.getEmail());
|
||||
txtPhone.setText(staffAccount.getPhone());
|
||||
txtUsername.setText(staffAccount.getUsername());
|
||||
}
|
||||
|
||||
@FXML
|
||||
void btnSaveClicked(ActionEvent event) {
|
||||
lblError.setText("");
|
||||
if (staffAccount == null) {
|
||||
lblError.setText("No staff account selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
String firstName = value(txtFirstName);
|
||||
String lastName = value(txtLastName);
|
||||
String email = value(txtEmail);
|
||||
String phone = value(txtPhone);
|
||||
String username = value(txtUsername);
|
||||
String password = txtPassword.getText() == null ? "" : txtPassword.getText().trim();
|
||||
String confirm = txtPasswordConfirm.getText() == null ? "" : txtPasswordConfirm.getText().trim();
|
||||
|
||||
if (firstName.isBlank() || lastName.isBlank()) {
|
||||
lblError.setText("First name and last name are required.");
|
||||
return;
|
||||
}
|
||||
if (email.isBlank()) {
|
||||
lblError.setText("Email is required.");
|
||||
return;
|
||||
}
|
||||
if (phone.isBlank()) {
|
||||
lblError.setText("Phone is required.");
|
||||
return;
|
||||
}
|
||||
String phoneError = Validator.isValidPhoneNumber(phone, "Phone");
|
||||
if (!phoneError.isEmpty()) {
|
||||
lblError.setText(phoneError.trim());
|
||||
return;
|
||||
}
|
||||
if (username.isBlank()) {
|
||||
lblError.setText("Username is required.");
|
||||
return;
|
||||
}
|
||||
if (!password.isEmpty() && password.length() < 6) {
|
||||
lblError.setText("Password must be at least 6 characters.");
|
||||
return;
|
||||
}
|
||||
if (!password.equals(confirm)) {
|
||||
lblError.setText("Passwords do not match.");
|
||||
return;
|
||||
}
|
||||
|
||||
btnSave.setDisable(true);
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
EmployeeRequest request = new EmployeeRequest();
|
||||
request.setUsername(username);
|
||||
request.setPassword(password.isEmpty() ? null : password);
|
||||
request.setFirstName(firstName);
|
||||
request.setLastName(lastName);
|
||||
request.setEmail(email);
|
||||
request.setPhone(phone);
|
||||
request.setRole(staffAccount.getRole());
|
||||
request.setActive(staffAccount.isActive());
|
||||
|
||||
EmployeeApi.getInstance().updateEmployee(staffAccount.getEmployeeId(), request);
|
||||
|
||||
Platform.runLater(this::close);
|
||||
} catch (Exception e) {
|
||||
ActivityLogger.getInstance().logException("StaffEditDialogController.btnSaveClicked", e, "Updating staff account");
|
||||
String msg = e.getMessage() == null ? "Could not update staff account." : e.getMessage();
|
||||
Platform.runLater(() -> {
|
||||
lblError.setText(msg);
|
||||
btnSave.setDisable(false);
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@FXML
|
||||
void btnCancelClicked(ActionEvent event) {
|
||||
close();
|
||||
}
|
||||
|
||||
private void close() {
|
||||
Stage stage = (Stage) btnSave.getScene().getWindow();
|
||||
stage.close();
|
||||
}
|
||||
|
||||
private static String value(TextField tf) {
|
||||
return tf.getText() == null ? "" : tf.getText().trim();
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,9 @@ import javafx.scene.control.Label;
|
||||
import javafx.scene.control.PasswordField;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.stage.Stage;
|
||||
import org.example.petshopdesktop.api.dto.user.UserRequest;
|
||||
import org.example.petshopdesktop.api.endpoints.UserApi;
|
||||
import org.example.petshopdesktop.api.dto.employee.EmployeeRequest;
|
||||
import org.example.petshopdesktop.api.endpoints.EmployeeApi;
|
||||
import org.example.petshopdesktop.Validator;
|
||||
import org.example.petshopdesktop.util.ActivityLogger;
|
||||
|
||||
public class StaffRegisterDialogController {
|
||||
@@ -49,6 +50,7 @@ public class StaffRegisterDialogController {
|
||||
String firstName = value(txtFirstName);
|
||||
String lastName = value(txtLastName);
|
||||
String email = value(txtEmail);
|
||||
String phone = value(txtPhone);
|
||||
String username = value(txtUsername);
|
||||
String password = txtPassword.getText() == null ? "" : txtPassword.getText();
|
||||
String confirm = txtPasswordConfirm.getText() == null ? "" : txtPasswordConfirm.getText();
|
||||
@@ -61,6 +63,15 @@ public class StaffRegisterDialogController {
|
||||
lblError.setText("Email is required.");
|
||||
return;
|
||||
}
|
||||
if (phone.isBlank()) {
|
||||
lblError.setText("Phone is required.");
|
||||
return;
|
||||
}
|
||||
String phoneError = Validator.isValidPhoneNumber(phone, "Phone");
|
||||
if (!phoneError.isEmpty()) {
|
||||
lblError.setText(phoneError.trim());
|
||||
return;
|
||||
}
|
||||
if (username.isBlank()) {
|
||||
lblError.setText("Username is required.");
|
||||
return;
|
||||
@@ -78,15 +89,17 @@ public class StaffRegisterDialogController {
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
UserRequest request = new UserRequest();
|
||||
EmployeeRequest request = new EmployeeRequest();
|
||||
request.setUsername(username);
|
||||
request.setPassword(password);
|
||||
request.setFullName(firstName + " " + lastName);
|
||||
request.setFirstName(firstName);
|
||||
request.setLastName(lastName);
|
||||
request.setEmail(email);
|
||||
request.setPhone(phone);
|
||||
request.setRole("STAFF");
|
||||
request.setActive(true);
|
||||
|
||||
UserApi.getInstance().createUser(request);
|
||||
EmployeeApi.getInstance().createEmployee(request);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
Alert alert = new Alert(Alert.AlertType.INFORMATION);
|
||||
|
||||
@@ -10,10 +10,11 @@ public class StaffAccount {
|
||||
private final String lastName;
|
||||
private final String email;
|
||||
private final String phone;
|
||||
private final String role;
|
||||
private final boolean active;
|
||||
private final Timestamp createdAt;
|
||||
|
||||
public StaffAccount(long userId, long employeeId, String username, String firstName, String lastName, String email, String phone, boolean active, Timestamp createdAt) {
|
||||
public StaffAccount(long userId, long employeeId, String username, String firstName, String lastName, String email, String phone, String role, boolean active, Timestamp createdAt) {
|
||||
this.userId = userId;
|
||||
this.employeeId = employeeId;
|
||||
this.username = username;
|
||||
@@ -21,6 +22,7 @@ public class StaffAccount {
|
||||
this.lastName = lastName;
|
||||
this.email = email;
|
||||
this.phone = phone;
|
||||
this.role = role;
|
||||
this.active = active;
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
@@ -59,6 +61,10 @@ public class StaffAccount {
|
||||
return phone;
|
||||
}
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
<?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.PasswordField?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.Region?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox spacing="14.0" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.StaffEditDialogController">
|
||||
<padding>
|
||||
<Insets bottom="18.0" left="18.0" right="18.0" top="18.0" />
|
||||
</padding>
|
||||
<children>
|
||||
<Label text="Edit Staff Account" textFill="#2C3E50">
|
||||
<font>
|
||||
<Font name="System Bold" size="18.0" />
|
||||
</font>
|
||||
</Label>
|
||||
|
||||
<Label fx:id="lblError" text="" textFill="#FF6B6B" wrapText="true" />
|
||||
|
||||
<HBox spacing="10.0">
|
||||
<children>
|
||||
<VBox spacing="6.0" HBox.hgrow="ALWAYS">
|
||||
<children>
|
||||
<Label text="First Name" />
|
||||
<TextField fx:id="txtFirstName" promptText="First name" />
|
||||
</children>
|
||||
</VBox>
|
||||
<VBox spacing="6.0" HBox.hgrow="ALWAYS">
|
||||
<children>
|
||||
<Label text="Last Name" />
|
||||
<TextField fx:id="txtLastName" promptText="Last name" />
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
</HBox>
|
||||
|
||||
<HBox spacing="10.0">
|
||||
<children>
|
||||
<VBox spacing="6.0" HBox.hgrow="ALWAYS">
|
||||
<children>
|
||||
<Label text="Email" />
|
||||
<TextField fx:id="txtEmail" promptText="name@petshop.com" />
|
||||
</children>
|
||||
</VBox>
|
||||
<VBox spacing="6.0" HBox.hgrow="ALWAYS">
|
||||
<children>
|
||||
<Label text="Phone" />
|
||||
<TextField fx:id="txtPhone" promptText="123-456-7890" />
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
</HBox>
|
||||
|
||||
<HBox spacing="10.0">
|
||||
<children>
|
||||
<VBox spacing="6.0" HBox.hgrow="ALWAYS">
|
||||
<children>
|
||||
<Label text="Username" />
|
||||
<TextField fx:id="txtUsername" promptText="username" />
|
||||
</children>
|
||||
</VBox>
|
||||
<VBox spacing="6.0" HBox.hgrow="ALWAYS">
|
||||
<children>
|
||||
<Label text="New Password" />
|
||||
<PasswordField fx:id="txtPassword" promptText="leave blank to keep current" />
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
</HBox>
|
||||
|
||||
<HBox spacing="10.0">
|
||||
<children>
|
||||
<VBox spacing="6.0" HBox.hgrow="ALWAYS">
|
||||
<children>
|
||||
<Label text="Confirm Password" />
|
||||
<PasswordField fx:id="txtPasswordConfirm" promptText="confirm new password" />
|
||||
</children>
|
||||
</VBox>
|
||||
<Region HBox.hgrow="ALWAYS" />
|
||||
</children>
|
||||
</HBox>
|
||||
|
||||
<HBox alignment="CENTER_RIGHT" spacing="10.0">
|
||||
<children>
|
||||
<Button mnemonicParsing="false" onAction="#btnCancelClicked" text="Cancel" />
|
||||
<Button fx:id="btnSave" mnemonicParsing="false" onAction="#btnSaveClicked" style="-fx-background-color: #4ECDC4; -fx-text-fill: white; -fx-cursor: hand;" text="Save" />
|
||||
</children>
|
||||
</HBox>
|
||||
</children>
|
||||
</VBox>
|
||||
@@ -33,6 +33,14 @@
|
||||
<Insets bottom="12.0" left="24.0" right="24.0" top="12.0" />
|
||||
</padding>
|
||||
</Button>
|
||||
<Button fx:id="btnEditAccount" mnemonicParsing="false" onAction="#btnEditAccountClicked" prefHeight="44.0" style="-fx-background-color: #F4A261; -fx-cursor: hand; -fx-background-radius: 8;" text="Edit Account" textFill="WHITE">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="12.0" left="24.0" right="24.0" top="12.0" />
|
||||
</padding>
|
||||
</Button>
|
||||
<Button fx:id="btnRefresh" mnemonicParsing="false" onAction="#btnRefreshClicked" prefHeight="44.0" prefWidth="118.0" style="-fx-background-color: #4ECDC4; -fx-cursor: hand; -fx-background-radius: 8;" text="Refresh" textFill="WHITE">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0" />
|
||||
|
||||
Reference in New Issue
Block a user