Skip to content

Commit

Permalink
update[DonationPage]: Refactor donation selection, add confirmation d…
Browse files Browse the repository at this point in the history
…ialog, and improve custom amount UI
  • Loading branch information
Fredrik Marjoni committed Apr 12, 2026
1 parent 4edd823 commit 5767aaa
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 44 deletions.
54 changes: 47 additions & 7 deletions src/main/java/edu/group5/app/control/DonationController.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
import java.util.Map;
import java.util.Set;

import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;

public class DonationController {
private final AppState appState;
private final NavigationController nav;
Expand All @@ -38,26 +41,55 @@ public Set<Integer> getUniqueOrgs() {
return uniqueOrgs;
}

public void handleDonate() {
// Get session data from MainController
public void requestDonationConfirmation() {
// Get session data
User currentUser = appState.getCurrentUser();
Organization currentOrg = appState.getCurrentOrganization();
BigDecimal amount = appState.getCurrentDonationAmount();

// Validate before showing dialog
if (currentUser == null) {
System.err.println("Error: No user logged in");
showError("Error: No user logged in");
return;
}
if (!(currentUser instanceof Customer customer)) {
System.err.println("Error: Only customers can donate");
if (!(currentUser instanceof Customer)) {
showError("Error: Only customers can donate");
return;
}
if (currentOrg == null) {
System.err.println("Error: No organization selected");
showError("Error: No organization selected");
return;
}
if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
System.err.println("Error: Invalid donation amount");
showError("Please select a donation amount first");
return;
}

// Show confirmation dialog
Alert confirmDialog = new Alert(Alert.AlertType.CONFIRMATION);
confirmDialog.setTitle("Confirm Donation");
confirmDialog.setHeaderText("Confirm Your Donation");
confirmDialog.setContentText(
"Organization: " + currentOrg.name() + "\n" +
"Amount: " + amount + " kr\n\n" +
"Are you sure you want to proceed?"
);

// If user clicks OK, process donation
if (confirmDialog.showAndWait().orElse(ButtonType.CANCEL) == ButtonType.OK) {
handleDonate();
}
// If Cancel, dialog just closes and nothing happens
}

private void handleDonate() {
// This now only handles the actual donation processing
User currentUser = appState.getCurrentUser();
Organization currentOrg = appState.getCurrentOrganization();
BigDecimal amount = appState.getCurrentDonationAmount();

if (!(currentUser instanceof Customer customer)) {
System.err.println("Error: Only customers can donate");
return;
}

Expand All @@ -81,4 +113,12 @@ public void handleDonate() {
// Navigate to payment complete
nav.showPaymentCompletePage();
}

private void showError(String message) {
Alert errorAlert = new Alert(Alert.AlertType.WARNING);
errorAlert.setTitle("Donation Error");
errorAlert.setHeaderText("Cannot Process Donation");
errorAlert.setContentText(message);
errorAlert.showAndWait();
}
}
104 changes: 67 additions & 37 deletions src/main/java/edu/group5/app/view/donationpage/DonationPageView.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import edu.group5.app.model.AppState;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.TilePane;
Expand All @@ -16,18 +16,14 @@
import javafx.scene.Node;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DonationPageView extends BorderPane {
private final AppState appState;
private final NavigationController nav;
private final DonationController donationController;

private final List<Node> allDonationElements = new ArrayList<>();
private final Map<Object, BigDecimal> elementAmounts = new HashMap<>();
private Node currentlySelected = null;
private TextField customAmountField;

public DonationPageView(AppState appState, NavigationController nav, DonationController donationController) {
this.appState = appState;
Expand All @@ -38,6 +34,12 @@ public DonationPageView(AppState appState, NavigationController nav, DonationCon

VBox content = new VBox();
content.getChildren().addAll(createDonationGrid(), createDonateSection());

content.setOnMouseClicked(e -> {
if (e.getTarget() == content) {
clearSelection();
}
});
setCenter(content);

}
Expand Down Expand Up @@ -75,14 +77,12 @@ public Button createDonationButton(String title, String amount) {
button.getStyleClass().add("donation-button");

BigDecimal parsedAmount = parseAmount(amount);
elementAmounts.put(button, parsedAmount);
button.setUserData(parsedAmount);

button.setOnAction(e -> {
selectDonationElement(button);
});
allDonationElements.add(button);
button.setOnAction(e -> selectDonation(button));
return button;
}

private VBox createCustomButton() {
Text titleText = new Text("Custom Donation");
titleText.getStyleClass().add("donation-title");
Expand All @@ -93,8 +93,10 @@ private VBox createCustomButton() {
Text krText = new Text("kr");
krText.getStyleClass().add("donation-amount");

TextField amountField = new TextField();
this.customAmountField = new TextField();
TextField amountField = customAmountField;
amountField.getStyleClass().add("donation-input");
amountField.setPromptText("Enter amount");

amountRow.getChildren().addAll(amountField, krText);

Expand All @@ -103,48 +105,76 @@ private VBox createCustomButton() {
box.getStyleClass().add("donation-button");

box.setOnMouseClicked(e -> {
try {
BigDecimal amount = new BigDecimal(amountField.getText().trim());
elementAmounts.put(box, amount);
selectDonationElement(box);
} catch (NumberFormatException exception) {
System.err.println("Invalid custom donation amount: " + amountField.getText());
}
selectDonation(box);
amountField.requestFocus();
});

amountField.setOnMouseClicked(e ->
{
selectDonation(box);
amountField.requestFocus();
});

allDonationElements.add(box);
// NEW: On text field input - update the amount in real-time
amountField.textProperty().addListener((obs, oldVal, newVal) -> {
if (!newVal.trim().isEmpty()) {
try {
BigDecimal amount = new BigDecimal(newVal.trim());
box.setUserData(amount);
updateDonationAmount(amount);
} catch (NumberFormatException ignored) {
// User is still typing, silently ignore
}
} else {
box.setUserData(null);
if (currentlySelected == box) {
updateDonationAmount(null);
}
}
});
return box;
}

private HBox createDonateSection() {
Button donateBtn = new Button("Donate");
donateBtn.getStyleClass().add("donate-button");
donateBtn.setOnAction(e -> donationController.handleDonate());
donateBtn.setOnAction(e -> donationController.requestDonationConfirmation());

HBox section = new HBox(donateBtn);
Button clearBtn = new Button("Clear");
clearBtn.getStyleClass().add("clear-button");
clearBtn.setOnAction(e -> clearSelection());

HBox section = new HBox(20, clearBtn, donateBtn);
section.setAlignment(Pos.CENTER);
section.setPadding(new Insets(20, 0, 30, 0));
return section;
}

private void selectDonationElement(Node element) {
// Remove selected class from all elements
for (Node node : allDonationElements) {
node.getStyleClass().remove("donation-button-selected");
private void selectDonation(Node element) {
if (currentlySelected != null) {
currentlySelected.getStyleClass().remove("donation-button-selected");
}
currentlySelected = element;
currentlySelected.getStyleClass().add("donation-button-selected");

element.getStyleClass().add("donation-button-selected");

// Extract and store the amount
extractAndStoreAmount(element);
BigDecimal amount = (BigDecimal) element.getUserData();
updateDonationAmount(amount);
}

private void extractAndStoreAmount(Node element) {
BigDecimal amount = elementAmounts.get(element);
if (amount != null) {
appState.setCurrentDonationAmount(amount);
} else {
System.err.println("Error: No amount found for selected element");
private void clearSelection() {
if (currentlySelected != null) {
currentlySelected.getStyleClass().remove("donation-button-selected");
currentlySelected = null;
updateDonationAmount(null);
}

if (customAmountField != null) {
customAmountField.clear();
}
}

private void updateDonationAmount(BigDecimal amount) {
appState.setCurrentDonationAmount(amount);
}

private BigDecimal parseAmount(String amountStr) {
Expand Down
38 changes: 38 additions & 0 deletions src/main/resources/donationpage/donation.css
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,42 @@

.donate-button:hover {
-fx-background-color: #c02020;
}

.clear-button {
-fx-pref-height: 55px;
-fx-background-color: #f0f0f0;
-fx-text-fill: #333;
-fx-font-size: 16px;
-fx-font-weight: bold;
-fx-background-radius: 8;
-fx-cursor: hand;
-fx-padding: 0 30 0 30;
-fx-border-color: #ccc;
-fx-border-width: 1;
}

.clear-button:hover {
-fx-background-color: #e0e0e0;
}

.clear-button:pressed {
-fx-background-color: #d0d0d0;
}

.donation-button-selected .donation-title {
-fx-fill: white;
}

.donation-button-selected .donation-amount {
-fx-fill: white;
}

.donation-button-selected .donation-input {
-fx-text-fill: white;
}

.donation-button-selected .donation-input:focused {
-fx-text-fill: white;
-fx-border-color: transparent transparent white transparent;
}

0 comments on commit 5767aaa

Please sign in to comment.