made it so staff cannot change the status of pets for desktop for adopted or owned
This commit is contained in:
@@ -164,6 +164,10 @@ public class PetDetailFragment extends Fragment {
|
||||
if (!InputValidator.isSpinnerSelected(binding.spinnerCustomer, "Owner")) return;
|
||||
if (!InputValidator.isSpinnerSelected(binding.spinnerStore, "Store")) return;
|
||||
}
|
||||
if ("Pending".equalsIgnoreCase(status)) {
|
||||
if (!InputValidator.isSpinnerSelected(binding.spinnerCustomer, "Owner")) return;
|
||||
if (!InputValidator.isSpinnerSelected(binding.spinnerStore, "Store")) return;
|
||||
}
|
||||
|
||||
PetDTO petDTO = new PetDTO();
|
||||
petDTO.setPetName(name);
|
||||
|
||||
@@ -126,7 +126,7 @@ public class PetProfileFragment extends Fragment {
|
||||
|
||||
String status = pet.getPetStatus();
|
||||
|
||||
if ("Adopted".equalsIgnoreCase(status) || "Owned".equalsIgnoreCase(status)) {
|
||||
if ("Adopted".equalsIgnoreCase(status) || "Owned".equalsIgnoreCase(status) || "Pending".equalsIgnoreCase(status)) {
|
||||
binding.layoutPetOwner.setVisibility(View.VISIBLE);
|
||||
if (pet.getCustomerName() != null && !pet.getCustomerName().isEmpty()) {
|
||||
binding.tvPetOwner.setText(pet.getCustomerName());
|
||||
@@ -137,7 +137,7 @@ public class PetProfileFragment extends Fragment {
|
||||
binding.layoutPetOwner.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if ("Available".equalsIgnoreCase(status) || "Adopted".equalsIgnoreCase(status)) {
|
||||
if ("Available".equalsIgnoreCase(status) || "Adopted".equalsIgnoreCase(status) || "Pending".equalsIgnoreCase(status)) {
|
||||
binding.layoutPetStore.setVisibility(View.VISIBLE);
|
||||
if (pet.getStoreName() != null && !pet.getStoreName().isEmpty()) {
|
||||
binding.tvPetStore.setText(pet.getStoreName());
|
||||
|
||||
@@ -271,6 +271,7 @@ public class AdoptionService {
|
||||
pet.setStore(null);
|
||||
} else if (ADOPTION_STATUS_PENDING.equalsIgnoreCase(adoptionStatus)) {
|
||||
pet.setPetStatus(PET_STATUS_PENDING);
|
||||
pet.setOwner(customer);
|
||||
} else {
|
||||
pet.setPetStatus(PET_STATUS_AVAILABLE);
|
||||
pet.setOwner(null);
|
||||
|
||||
@@ -10,6 +10,7 @@ public class UserResponse {
|
||||
private String phone;
|
||||
private String role;
|
||||
private Boolean active;
|
||||
private Integer loyaltyPoints;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
@@ -72,6 +73,14 @@ public class UserResponse {
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
public Integer getLoyaltyPoints() {
|
||||
return loyaltyPoints;
|
||||
}
|
||||
|
||||
public void setLoyaltyPoints(Integer loyaltyPoints) {
|
||||
this.loyaltyPoints = loyaltyPoints;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
@@ -13,21 +13,55 @@ import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.VBox;
|
||||
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.endpoints.CustomerApi;
|
||||
import org.example.petshopdesktop.api.endpoints.UserApi;
|
||||
import org.example.petshopdesktop.auth.UserSession;
|
||||
import org.example.petshopdesktop.util.ActivityLogger;
|
||||
import org.example.petshopdesktop.util.TableViewSupport;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class StaffAccountsController {
|
||||
|
||||
@FXML
|
||||
private VBox staffSection;
|
||||
|
||||
@FXML
|
||||
private TableView<UserResponse> tvCustomers;
|
||||
|
||||
@FXML
|
||||
private TableColumn<UserResponse, String> colCustomerUsername;
|
||||
|
||||
@FXML
|
||||
private TableColumn<UserResponse, String> colCustomerName;
|
||||
|
||||
@FXML
|
||||
private TableColumn<UserResponse, String> colCustomerEmail;
|
||||
|
||||
@FXML
|
||||
private TableColumn<UserResponse, String> colCustomerPhone;
|
||||
|
||||
@FXML
|
||||
private TableColumn<UserResponse, Object> colCustomerLoyaltyPoints;
|
||||
|
||||
@FXML
|
||||
private TableColumn<UserResponse, String> colCustomerStatus;
|
||||
|
||||
@FXML
|
||||
private TableColumn<UserResponse, Object> colCustomerCreated;
|
||||
|
||||
@FXML
|
||||
private TextField txtSearchCustomer;
|
||||
|
||||
@FXML
|
||||
private Button btnEditCustomer;
|
||||
|
||||
@FXML
|
||||
private TableView<UserResponse> tvStaff;
|
||||
|
||||
@@ -55,12 +89,6 @@ public class StaffAccountsController {
|
||||
@FXML
|
||||
private TextField txtSearch;
|
||||
|
||||
@FXML
|
||||
private Label lblError;
|
||||
|
||||
@FXML
|
||||
private Label lblStatus;
|
||||
|
||||
@FXML
|
||||
private Button btnRefresh;
|
||||
|
||||
@@ -70,11 +98,38 @@ public class StaffAccountsController {
|
||||
@FXML
|
||||
private Button btnEditAccount;
|
||||
|
||||
@FXML
|
||||
private Label lblError;
|
||||
|
||||
@FXML
|
||||
private Label lblStatus;
|
||||
|
||||
private final ObservableList<UserResponse> customerAccounts = FXCollections.observableArrayList();
|
||||
private FilteredList<UserResponse> filteredCustomers;
|
||||
|
||||
private final ObservableList<UserResponse> staffAccounts = FXCollections.observableArrayList();
|
||||
private FilteredList<UserResponse> filtered;
|
||||
private FilteredList<UserResponse> filteredStaff;
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
colCustomerUsername.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(data.getValue().getUsername()));
|
||||
colCustomerName.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(data.getValue().getFullName()));
|
||||
colCustomerEmail.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(data.getValue().getEmail()));
|
||||
colCustomerPhone.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(data.getValue().getPhone()));
|
||||
colCustomerLoyaltyPoints.setCellValueFactory(data -> new javafx.beans.property.SimpleObjectProperty<>(data.getValue().getLoyaltyPoints()));
|
||||
colCustomerStatus.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(data.getValue().getActive() != null && data.getValue().getActive() ? "Active" : "Inactive"));
|
||||
colCustomerCreated.setCellValueFactory(data -> new javafx.beans.property.SimpleObjectProperty<>(data.getValue().getCreatedAt()));
|
||||
|
||||
filteredCustomers = new FilteredList<>(customerAccounts, a -> true);
|
||||
TableViewSupport.bindSortedItems(tvCustomers, filteredCustomers);
|
||||
TableViewSupport.installDoubleClickAction(tvCustomers, this::openEditDialog);
|
||||
|
||||
tvCustomers.getSelectionModel().selectedItemProperty().addListener((obs, oldVal, newVal) ->
|
||||
btnEditCustomer.setDisable(newVal == null));
|
||||
btnEditCustomer.setDisable(true);
|
||||
|
||||
txtSearchCustomer.textProperty().addListener((obs, o, n) -> applyCustomerFilter(n));
|
||||
|
||||
colUsername.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(data.getValue().getUsername()));
|
||||
colName.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(data.getValue().getFullName()));
|
||||
colEmail.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(data.getValue().getEmail()));
|
||||
@@ -83,33 +138,39 @@ public class StaffAccountsController {
|
||||
colStatus.setCellValueFactory(data -> new javafx.beans.property.SimpleStringProperty(data.getValue().getActive() != null && data.getValue().getActive() ? "Active" : "Inactive"));
|
||||
colCreated.setCellValueFactory(data -> new javafx.beans.property.SimpleObjectProperty<>(data.getValue().getCreatedAt()));
|
||||
|
||||
filtered = new FilteredList<>(staffAccounts, a -> true);
|
||||
TableViewSupport.bindSortedItems(tvStaff, filtered);
|
||||
filteredStaff = new FilteredList<>(staffAccounts, a -> true);
|
||||
TableViewSupport.bindSortedItems(tvStaff, filteredStaff);
|
||||
TableViewSupport.installDoubleClickAction(tvStaff, this::openEditDialog);
|
||||
|
||||
txtSearch.textProperty().addListener((obs, o, n) -> applyFilter(n));
|
||||
|
||||
tvStaff.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> {
|
||||
if (btnEditAccount != null) {
|
||||
btnEditAccount.setDisable(newValue == null);
|
||||
}
|
||||
});
|
||||
|
||||
if (btnEditAccount != null) {
|
||||
tvStaff.getSelectionModel().selectedItemProperty().addListener((obs, oldVal, newVal) ->
|
||||
btnEditAccount.setDisable(newVal == null));
|
||||
btnEditAccount.setDisable(true);
|
||||
}
|
||||
|
||||
txtSearch.textProperty().addListener((obs, o, n) -> applyStaffFilter(n));
|
||||
|
||||
boolean isAdmin = UserSession.getInstance().isAdmin();
|
||||
staffSection.setVisible(isAdmin);
|
||||
staffSection.setManaged(isAdmin);
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
@FXML
|
||||
void btnRefreshClicked(ActionEvent event) {
|
||||
txtSearchCustomer.clear();
|
||||
txtSearch.clear();
|
||||
TableViewSupport.clearSort(tvCustomers);
|
||||
TableViewSupport.clearSort(tvStaff);
|
||||
refresh();
|
||||
TableViewSupport.flashStatus(lblStatus, "Refreshed");
|
||||
}
|
||||
|
||||
@FXML
|
||||
void btnEditCustomerClicked(ActionEvent event) {
|
||||
lblError.setText("");
|
||||
openEditDialog(tvCustomers.getSelectionModel().getSelectedItem());
|
||||
}
|
||||
|
||||
@FXML
|
||||
void btnCreateAccountClicked(ActionEvent event) {
|
||||
lblError.setText("");
|
||||
@@ -132,8 +193,7 @@ public class StaffAccountsController {
|
||||
@FXML
|
||||
void btnEditAccountClicked(ActionEvent event) {
|
||||
lblError.setText("");
|
||||
UserResponse selected = tvStaff.getSelectionModel().getSelectedItem();
|
||||
openEditDialog(selected);
|
||||
openEditDialog(tvStaff.getSelectionModel().getSelectedItem());
|
||||
}
|
||||
|
||||
private void openEditDialog(UserResponse selected) {
|
||||
@@ -154,7 +214,8 @@ public class StaffAccountsController {
|
||||
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());
|
||||
Stage owner = (tvStaff.getScene() != null) ? (Stage) tvStaff.getScene().getWindow() : (Stage) tvCustomers.getScene().getWindow();
|
||||
dialog.initOwner(owner);
|
||||
dialog.initModality(Modality.APPLICATION_MODAL);
|
||||
dialog.setTitle("Edit User Account");
|
||||
dialog.setScene(new Scene(loader.load()));
|
||||
@@ -164,31 +225,45 @@ public class StaffAccountsController {
|
||||
dialog.showAndWait();
|
||||
refresh();
|
||||
} catch (Exception e) {
|
||||
ActivityLogger.getInstance().logException("StaffAccountsController.btnEditAccountClicked", e, "Opening user edit dialog");
|
||||
ActivityLogger.getInstance().logException("StaffAccountsController.openEditDialog", e, "Opening user edit dialog");
|
||||
lblError.setText("Could not open user account editor.");
|
||||
}
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
lblError.setText("");
|
||||
tvCustomers.setDisable(true);
|
||||
tvStaff.setDisable(true);
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
UserSession session = UserSession.getInstance();
|
||||
List<UserResponse> users;
|
||||
if (session.isAdmin()) {
|
||||
users = UserApi.getInstance().listUsers(null);
|
||||
Comparator<UserResponse> byCreated = Comparator.comparing(
|
||||
UserResponse::getCreatedAt, Comparator.nullsLast(Comparator.reverseOrder()));
|
||||
|
||||
final List<UserResponse> customers;
|
||||
final List<UserResponse> staff;
|
||||
|
||||
if (UserSession.getInstance().isAdmin()) {
|
||||
List<UserResponse> allUsers = UserApi.getInstance().listUsers(null);
|
||||
customers = allUsers.stream()
|
||||
.filter(u -> "CUSTOMER".equalsIgnoreCase(u.getRole()))
|
||||
.sorted(byCreated)
|
||||
.collect(Collectors.toList());
|
||||
staff = allUsers.stream()
|
||||
.filter(u -> !"CUSTOMER".equalsIgnoreCase(u.getRole()))
|
||||
.sorted(byCreated)
|
||||
.collect(Collectors.toList());
|
||||
} else {
|
||||
users = CustomerApi.getInstance().listCustomers(null);
|
||||
customers = CustomerApi.getInstance().listCustomers(null).stream()
|
||||
.sorted(byCreated)
|
||||
.collect(Collectors.toList());
|
||||
staff = List.of();
|
||||
}
|
||||
|
||||
List<UserResponse> sortedUsers = users.stream()
|
||||
.sorted(Comparator.comparing(UserResponse::getCreatedAt, Comparator.nullsLast(Comparator.reverseOrder())))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Platform.runLater(() -> {
|
||||
staffAccounts.setAll(sortedUsers);
|
||||
customerAccounts.setAll(customers);
|
||||
staffAccounts.setAll(staff);
|
||||
tvCustomers.setDisable(false);
|
||||
tvStaff.setDisable(false);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
@@ -198,20 +273,34 @@ public class StaffAccountsController {
|
||||
lblError.setText(message == null || message.isBlank()
|
||||
? "Could not load user accounts."
|
||||
: "Could not load user accounts: " + message);
|
||||
tvCustomers.setDisable(false);
|
||||
tvStaff.setDisable(false);
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void applyFilter(String text) {
|
||||
private void applyCustomerFilter(String text) {
|
||||
String q = text == null ? "" : text.trim().toLowerCase();
|
||||
if (q.isEmpty()) {
|
||||
filtered.setPredicate(a -> true);
|
||||
filteredCustomers.setPredicate(a -> true);
|
||||
return;
|
||||
}
|
||||
filteredCustomers.setPredicate(a ->
|
||||
safe(a.getUsername()).contains(q)
|
||||
|| safe(a.getFullName()).contains(q)
|
||||
|| safe(a.getEmail()).contains(q)
|
||||
|| safe(a.getPhone()).contains(q)
|
||||
);
|
||||
}
|
||||
|
||||
filtered.setPredicate(a ->
|
||||
private void applyStaffFilter(String text) {
|
||||
String q = text == null ? "" : text.trim().toLowerCase();
|
||||
if (q.isEmpty()) {
|
||||
filteredStaff.setPredicate(a -> true);
|
||||
return;
|
||||
}
|
||||
filteredStaff.setPredicate(a ->
|
||||
safe(a.getUsername()).contains(q)
|
||||
|| safe(a.getFullName()).contains(q)
|
||||
|| safe(a.getEmail()).contains(q)
|
||||
|
||||
@@ -132,9 +132,7 @@ public class PetDialogController {
|
||||
}
|
||||
});
|
||||
|
||||
setFieldVisibility(vbCustomerField, false);
|
||||
setFieldVisibility(vbStoreField, false);
|
||||
setFieldVisibility(vbPriceField, true);
|
||||
updateStatusFieldVisibility(null);
|
||||
|
||||
loadSpecies();
|
||||
|
||||
@@ -174,18 +172,18 @@ public class PetDialogController {
|
||||
String speciesValue = cbPetSpecies.getValue() != null ? cbPetSpecies.getValue().trim() : "";
|
||||
if (speciesValue.isEmpty()) errorMsg += "Species is required\n";
|
||||
String selectedStatus = cbPetStatus.getValue();
|
||||
boolean needsPrice = !("Owned".equalsIgnoreCase(selectedStatus) || "Adopted".equalsIgnoreCase(selectedStatus));
|
||||
if (needsPrice) {
|
||||
errorMsg += Validator.isPresent(txtPetPrice.getText(), "Price");
|
||||
}
|
||||
if (cbPetStatus.getSelectionModel().getSelectedItem() == null){
|
||||
errorMsg += "Status is required";
|
||||
}
|
||||
if ("Owned".equalsIgnoreCase(selectedStatus) && cbCustomer.getValue() == null && UserSession.getInstance().isAdmin()) {
|
||||
errorMsg += "Customer is required for Owned status\n";
|
||||
boolean needsCustomer = "Owned".equalsIgnoreCase(selectedStatus)
|
||||
|| "Adopted".equalsIgnoreCase(selectedStatus)
|
||||
|| "Pending".equalsIgnoreCase(selectedStatus);
|
||||
boolean needsStore = requiresStore(selectedStatus);
|
||||
if (needsCustomer && cbCustomer.getValue() == null && UserSession.getInstance().isAdmin()) {
|
||||
errorMsg += "Customer is required for " + selectedStatus + " status\n";
|
||||
}
|
||||
boolean storeRequired = requiresStore(selectedStatus) && !"Adopted".equalsIgnoreCase(selectedStatus);
|
||||
if (storeRequired && cbStore.getValue() == null) {
|
||||
if (needsStore && cbStore.getValue() == null) {
|
||||
errorMsg += "Store is required for " + selectedStatus + " status\n";
|
||||
}
|
||||
|
||||
@@ -193,15 +191,11 @@ public class PetDialogController {
|
||||
errorMsg += Validator.isLessThanVarChars(txtPetName.getText(), "Pet Name", 50);
|
||||
errorMsg += Validator.isLessThanVarChars(speciesValue, "Species", 50);
|
||||
errorMsg += Validator.isLessThanVarChars(txtPetBreed.getText(), "Breed", 50);
|
||||
if (needsPrice) {
|
||||
errorMsg += Validator.isLessThanVarChars(txtPetPrice.getText(), "Price", 12);
|
||||
}
|
||||
errorMsg += Validator.isLessThanVarChars(txtPetAge.getText(), "Age", 11);
|
||||
|
||||
//Check validation (format)
|
||||
if (needsPrice) {
|
||||
errorMsg += Validator.isNonNegativeDouble(txtPetPrice.getText(), "Price");
|
||||
}
|
||||
errorMsg += Validator.isPositiveInteger(txtPetAge.getText(), "Age");
|
||||
|
||||
if(errorMsg.isEmpty()){
|
||||
@@ -263,9 +257,7 @@ public class PetDialogController {
|
||||
request.setPetSpecies(cbPetSpecies.getValue() != null ? cbPetSpecies.getValue().trim() : "");
|
||||
request.setPetBreed(txtPetBreed.getText());
|
||||
request.setPetStatus(cbPetStatus.getValue());
|
||||
String buildStatus = cbPetStatus.getValue();
|
||||
boolean buildNeedsPrice = !("Owned".equalsIgnoreCase(buildStatus) || "Adopted".equalsIgnoreCase(buildStatus));
|
||||
if (buildNeedsPrice && txtPetPrice.getText() != null && !txtPetPrice.getText().isBlank()) {
|
||||
if (txtPetPrice.getText() != null && !txtPetPrice.getText().isBlank()) {
|
||||
try {
|
||||
request.setPetPrice(new BigDecimal(txtPetPrice.getText()));
|
||||
} catch (NumberFormatException e) {
|
||||
@@ -282,7 +274,10 @@ public class PetDialogController {
|
||||
request.setPetAge(age);
|
||||
|
||||
String status = cbPetStatus.getValue();
|
||||
if (("Owned".equalsIgnoreCase(status) || "Adopted".equalsIgnoreCase(status)) && cbCustomer.getValue() != null) {
|
||||
boolean customerApplicable = "Owned".equalsIgnoreCase(status)
|
||||
|| "Adopted".equalsIgnoreCase(status)
|
||||
|| "Pending".equalsIgnoreCase(status);
|
||||
if (customerApplicable && cbCustomer.getValue() != null) {
|
||||
request.setCustomerId(cbCustomer.getValue().getId());
|
||||
}
|
||||
if (requiresStore(status) && cbStore.getValue() != null) {
|
||||
@@ -407,9 +402,17 @@ public class PetDialogController {
|
||||
}
|
||||
}
|
||||
updateStatusFieldVisibility(cbPetStatus.getValue());
|
||||
applyStatusLock();
|
||||
}
|
||||
}
|
||||
|
||||
private void applyStatusLock() {
|
||||
String status = cbPetStatus.getValue();
|
||||
boolean isRestricted = "Adopted".equalsIgnoreCase(status) || "Owned".equalsIgnoreCase(status);
|
||||
boolean isStaff = !UserSession.getInstance().isAdmin();
|
||||
cbPetStatus.setDisable(isRestricted && isStaff);
|
||||
}
|
||||
|
||||
public void setMode(String mode) {
|
||||
this.mode = mode;
|
||||
lblMode.setText(mode + " Pet");
|
||||
@@ -489,28 +492,27 @@ public class PetDialogController {
|
||||
}
|
||||
|
||||
private void updateStatusFieldVisibility(String status) {
|
||||
boolean statusNeedsCustomer = "Owned".equalsIgnoreCase(status) || "Adopted".equalsIgnoreCase(status);
|
||||
boolean needsCustomer = statusNeedsCustomer && UserSession.getInstance().isAdmin();
|
||||
boolean storeBased = requiresStore(status);
|
||||
boolean needsPrice = !statusNeedsCustomer;
|
||||
setFieldVisibility(vbCustomerField, needsCustomer);
|
||||
setFieldVisibility(vbStoreField, storeBased);
|
||||
setFieldVisibility(vbPriceField, needsPrice);
|
||||
if (status == null) {
|
||||
vbPriceField.setDisable(false);
|
||||
vbCustomerField.setDisable(true);
|
||||
vbStoreField.setDisable(false);
|
||||
return;
|
||||
}
|
||||
boolean isAdmin = UserSession.getInstance().isAdmin();
|
||||
boolean customerApplicable = "Owned".equalsIgnoreCase(status)
|
||||
|| "Adopted".equalsIgnoreCase(status)
|
||||
|| "Pending".equalsIgnoreCase(status);
|
||||
boolean isOwned = "Owned".equalsIgnoreCase(status);
|
||||
|
||||
vbPriceField.setDisable(false);
|
||||
vbCustomerField.setDisable(!customerApplicable || !isAdmin);
|
||||
vbStoreField.setDisable(isOwned);
|
||||
}
|
||||
|
||||
private boolean requiresStore(String status) {
|
||||
return "Available".equalsIgnoreCase(status)
|
||||
|| "Pending".equalsIgnoreCase(status)
|
||||
|| "Unadopted".equalsIgnoreCase(status)
|
||||
|| "Adopted".equalsIgnoreCase(status);
|
||||
}
|
||||
|
||||
private void setFieldVisibility(VBox field, boolean visible) {
|
||||
if (field == null) {
|
||||
return;
|
||||
}
|
||||
field.setVisible(visible);
|
||||
field.setManaged(visible);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.StaffAccountsController">
|
||||
<VBox spacing="16.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.StaffAccountsController">
|
||||
<padding>
|
||||
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
|
||||
</padding>
|
||||
@@ -25,22 +25,6 @@
|
||||
</font>
|
||||
</Label>
|
||||
<Region HBox.hgrow="ALWAYS" />
|
||||
<Button fx:id="btnCreateAccount" mnemonicParsing="false" onAction="#btnCreateAccountClicked" prefHeight="44.0" style="-fx-background-color: #FF6B6B; -fx-cursor: hand; -fx-background-radius: 8;" text="Create 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="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" />
|
||||
@@ -52,12 +36,91 @@
|
||||
</children>
|
||||
</HBox>
|
||||
|
||||
<!-- Customers Section -->
|
||||
<VBox spacing="10.0" VBox.vgrow="ALWAYS">
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" spacing="12.0">
|
||||
<children>
|
||||
<Label text="Customers" textFill="#2c3e50">
|
||||
<font>
|
||||
<Font name="System Bold" size="20.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Region HBox.hgrow="ALWAYS" />
|
||||
<Button fx:id="btnEditCustomer" mnemonicParsing="false" onAction="#btnEditCustomerClicked" prefHeight="40.0" style="-fx-background-color: #F4A261; -fx-cursor: hand; -fx-background-radius: 8;" text="Edit Customer" textFill="WHITE">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="20.0" right="20.0" top="10.0" />
|
||||
</padding>
|
||||
</Button>
|
||||
</children>
|
||||
</HBox>
|
||||
|
||||
<HBox alignment="CENTER_LEFT" spacing="10.0" style="-fx-background-color: white; -fx-background-radius: 14; -fx-border-width: 1; -fx-border-radius: 14; -fx-border-color: #e6e6e6;">
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="15.0" right="15.0" top="10.0" />
|
||||
</padding>
|
||||
<children>
|
||||
<TextField fx:id="txtSearch" promptText="Search users..." style="-fx-border-width: 0; -fx-background-color: transparent;" HBox.hgrow="ALWAYS">
|
||||
<TextField fx:id="txtSearchCustomer" promptText="Search customers..." style="-fx-border-width: 0; -fx-background-color: transparent;" HBox.hgrow="ALWAYS">
|
||||
<font>
|
||||
<Font size="15.0" />
|
||||
</font>
|
||||
</TextField>
|
||||
</children>
|
||||
</HBox>
|
||||
|
||||
<TableView fx:id="tvCustomers" style="-fx-background-color: white; -fx-background-radius: 12;" VBox.vgrow="ALWAYS">
|
||||
<columns>
|
||||
<TableColumn fx:id="colCustomerUsername" prefWidth="130.0" text="Username" />
|
||||
<TableColumn fx:id="colCustomerName" prefWidth="160.0" text="Name" />
|
||||
<TableColumn fx:id="colCustomerEmail" prefWidth="200.0" text="Email" />
|
||||
<TableColumn fx:id="colCustomerPhone" prefWidth="130.0" text="Phone" />
|
||||
<TableColumn fx:id="colCustomerLoyaltyPoints" prefWidth="120.0" text="Loyalty Points" />
|
||||
<TableColumn fx:id="colCustomerStatus" prefWidth="90.0" text="Status" />
|
||||
<TableColumn fx:id="colCustomerCreated" prefWidth="150.0" text="Created" />
|
||||
</columns>
|
||||
</TableView>
|
||||
</children>
|
||||
</VBox>
|
||||
|
||||
<!-- Staff Section (admin only) -->
|
||||
<VBox fx:id="staffSection" spacing="10.0" managed="false" visible="false" VBox.vgrow="ALWAYS">
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" spacing="12.0">
|
||||
<children>
|
||||
<Label text="Staff" textFill="#2c3e50">
|
||||
<font>
|
||||
<Font name="System Bold" size="20.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Region HBox.hgrow="ALWAYS" />
|
||||
<Button fx:id="btnCreateAccount" mnemonicParsing="false" onAction="#btnCreateAccountClicked" prefHeight="40.0" style="-fx-background-color: #FF6B6B; -fx-cursor: hand; -fx-background-radius: 8;" text="Create Account" textFill="WHITE">
|
||||
<font>
|
||||
<Font name="System Bold" size="14.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="20.0" right="20.0" top="10.0" />
|
||||
</padding>
|
||||
</Button>
|
||||
<Button fx:id="btnEditAccount" mnemonicParsing="false" onAction="#btnEditAccountClicked" prefHeight="40.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="10.0" left="20.0" right="20.0" top="10.0" />
|
||||
</padding>
|
||||
</Button>
|
||||
</children>
|
||||
</HBox>
|
||||
|
||||
<HBox alignment="CENTER_LEFT" spacing="10.0" style="-fx-background-color: white; -fx-background-radius: 14; -fx-border-width: 1; -fx-border-radius: 14; -fx-border-color: #e6e6e6;">
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="15.0" right="15.0" top="10.0" />
|
||||
</padding>
|
||||
<children>
|
||||
<TextField fx:id="txtSearch" promptText="Search staff..." style="-fx-border-width: 0; -fx-background-color: transparent;" HBox.hgrow="ALWAYS">
|
||||
<font>
|
||||
<Font size="15.0" />
|
||||
</font>
|
||||
@@ -76,7 +139,8 @@
|
||||
<TableColumn fx:id="colCreated" prefWidth="150.0" text="Created" />
|
||||
</columns>
|
||||
</TableView>
|
||||
|
||||
</children>
|
||||
</VBox>
|
||||
|
||||
<Label fx:id="lblStatus" text="" textFill="#64748b" visible="false" managed="true">
|
||||
<font>
|
||||
|
||||
Reference in New Issue
Block a user