diff --git a/src/main/java/edu/group5/app/control/DonationController.java b/src/main/java/edu/group5/app/control/DonationController.java index 97a1c9d..9118c7e 100644 --- a/src/main/java/edu/group5/app/control/DonationController.java +++ b/src/main/java/edu/group5/app/control/DonationController.java @@ -43,6 +43,7 @@ public void handleDonate() { User currentUser = appState.getCurrentUser(); Organization currentOrg = appState.getCurrentOrganization(); BigDecimal amount = appState.getCurrentDonationAmount(); + String paymentMethod = appState.getCurrentPaymentMethod(); if (currentUser == null) { System.err.println("Error: No user logged in"); @@ -60,17 +61,21 @@ public void handleDonate() { System.err.println("Error: Invalid donation amount"); return; } + if (paymentMethod == null) { + System.out.println("Error: Invalid payment method"); + return; + } // Create donation via service boolean success = service.donate( customer, currentOrg.orgNumber(), amount, - "Online" + paymentMethod ); if (success) { - System.out.println("Donation created: " + amount + " kr to " + currentOrg.name()); + System.out.println("Donation created: " + amount + " kr to " + currentOrg.name() + ", with payment method: " + paymentMethod); } else { System.err.println("Failed to create donation"); } diff --git a/src/main/java/edu/group5/app/model/AppState.java b/src/main/java/edu/group5/app/model/AppState.java index d8dd03a..73d5cfc 100644 --- a/src/main/java/edu/group5/app/model/AppState.java +++ b/src/main/java/edu/group5/app/model/AppState.java @@ -9,6 +9,7 @@ public class AppState { private User currentUser; private BigDecimal currentDonationAmount; private Organization currentOrganization; + private String currentDonation; public User getCurrentUser() { return this.currentUser; @@ -33,4 +34,12 @@ public BigDecimal getCurrentDonationAmount() { public void setCurrentDonationAmount(BigDecimal amount) { this.currentDonationAmount = amount; } + + public String getCurrentPaymentMethod() { + return this.currentDonation; + } + + public void setCurrentPaymentMethod(String paymentMethod){ + this.currentDonation = paymentMethod; + } } diff --git a/src/main/java/edu/group5/app/view/donationpage/DonationPageView.java b/src/main/java/edu/group5/app/view/donationpage/DonationPageView.java index 5087267..63d0493 100644 --- a/src/main/java/edu/group5/app/view/donationpage/DonationPageView.java +++ b/src/main/java/edu/group5/app/view/donationpage/DonationPageView.java @@ -16,10 +16,7 @@ import javafx.scene.Node; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class DonationPageView extends BorderPane { private final AppState appState; @@ -27,20 +24,35 @@ public class DonationPageView extends BorderPane { private final DonationController donationController; private final List allDonationElements = new ArrayList<>(); + private final List allPaymentElements = new ArrayList<>(); private final Map elementAmounts = new HashMap<>(); + private final Map elementPaymentMethods = new HashMap<>(); + + private BigDecimal selectedAmount = null; + private String selectedPaymentMethod = null; + private Button donateBtn; public DonationPageView(AppState appState, NavigationController nav, DonationController donationController) { this.appState = appState; this.nav = nav; this.donationController = donationController; - getStylesheets().add(getClass().getResource("/donationpage/donation.css").toExternalForm()); + getStylesheets().add(Objects.requireNonNull(getClass().getResource("/donationpage/donation.css")).toExternalForm()); VBox content = new VBox(); - content.getChildren().addAll(createDonationGrid(), createDonateSection()); + content.getChildren().addAll(createBackButton(), createDonationGrid(), createPaymentMethodSection(), createDonateSection()); setCenter(content); } + private HBox createBackButton() { + Button backBtn = new Button("←"); + backBtn.getStyleClass().add("back-button"); + backBtn.setOnAction(e -> nav.showOrganizationPage()); + + HBox container = new HBox(backBtn); + container.setPadding(new Insets(10, 0, 0, 10)); + return container; + } private TilePane createDonationGrid(){ TilePane body = new TilePane(); body.setAlignment(Pos.CENTER); @@ -104,7 +116,12 @@ private VBox createCustomButton() { box.setOnMouseClicked(e -> { try { - BigDecimal amount = new BigDecimal(amountField.getText().trim()); + String text = amountField.getText().trim(); + if (text.isEmpty()) { + return; + } + BigDecimal amount = new BigDecimal(text); + elementAmounts.put(box, amount); selectDonationElement(box); } catch (NumberFormatException exception) { @@ -115,14 +132,40 @@ private VBox createCustomButton() { allDonationElements.add(box); return box; } + + public HBox createPaymentMethodSection() { + Button appleBtn = new Button("Apple Pay"); + Button vippsBtn = new Button("Vipps"); + Button visaBtn = new Button("Visa"); + + for (Button btn : new Button[]{appleBtn, vippsBtn, visaBtn}) { + btn.getStyleClass().add("payment-method-button"); + + btn.setOnAction(e -> {selectPaymentMethod(btn);}); + allPaymentElements.add(btn); + } + + elementPaymentMethods.put(appleBtn, "Apple Pay"); + elementPaymentMethods.put(vippsBtn, "Vipps"); + elementPaymentMethods.put(visaBtn, "Visa"); + + HBox sectionPm = new HBox(appleBtn, vippsBtn, visaBtn); + sectionPm.setAlignment(Pos.CENTER); + sectionPm.setSpacing(20); + sectionPm.setPadding(new Insets(20, 20, 20, 20)); + return sectionPm; + } + private HBox createDonateSection() { - Button donateBtn = new Button("Donate"); + donateBtn = new Button("Donate"); donateBtn.getStyleClass().add("donate-button"); + + donateBtn.setDisable(true); + donateBtn.setOnAction(e -> donationController.handleDonate()); HBox section = new HBox(donateBtn); section.setAlignment(Pos.CENTER); - section.setPadding(new Insets(20, 0, 30, 0)); return section; } @@ -137,13 +180,30 @@ private void selectDonationElement(Node element) { // Extract and store the amount extractAndStoreAmount(element); } + private void selectPaymentMethod(Node element) { + for (Node node : allPaymentElements) { + node.getStyleClass().remove("payment-method-selected"); + } + element.getStyleClass().add("payment-method-selected"); + + extractAndStorePaymentMethod(element); + } private void extractAndStoreAmount(Node element) { BigDecimal amount = elementAmounts.get(element); if (amount != null) { + selectedAmount = amount; appState.setCurrentDonationAmount(amount); - } else { - System.err.println("Error: No amount found for selected element"); + updateDonationButtonState(); + } + } + + private void extractAndStorePaymentMethod(Node element) { + String paymentMethod = elementPaymentMethods.get(element); + if (paymentMethod != null) { + selectedPaymentMethod = paymentMethod; + appState.setCurrentPaymentMethod(paymentMethod); + updateDonationButtonState(); } } @@ -154,5 +214,8 @@ private BigDecimal parseAmount(String amountStr) { return BigDecimal.ZERO; } } + private void updateDonationButtonState() { + donateBtn.setDisable(selectedAmount == null || selectedPaymentMethod == null); + } } \ No newline at end of file diff --git a/src/main/java/edu/group5/app/view/organizationpage/OrganizationPageView.java b/src/main/java/edu/group5/app/view/organizationpage/OrganizationPageView.java index da8d1df..684a1a6 100644 --- a/src/main/java/edu/group5/app/view/organizationpage/OrganizationPageView.java +++ b/src/main/java/edu/group5/app/view/organizationpage/OrganizationPageView.java @@ -4,6 +4,7 @@ import edu.group5.app.control.NavigationController; import edu.group5.app.model.AppState; import edu.group5.app.model.organization.Organization; +import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.Button; import javafx.scene.control.Label; @@ -16,6 +17,8 @@ import javafx.scene.layout.VBox; import javafx.scene.text.Text; +import java.util.Objects; + public class OrganizationPageView extends BorderPane { private final AppState appState; private final NavigationController nav; @@ -26,24 +29,34 @@ public OrganizationPageView(AppState appState, NavigationController nav, Donatio this.nav = nav; this.donationController = donationController; - getStylesheets().add(getClass().getResource("/organizationpage/organizationpage.css").toExternalForm()); - setCenter(createBody()); + getStylesheets().add(Objects.requireNonNull(getClass().getResource("/organizationpage/organizationpage.css")).toExternalForm()); + + VBox content = new VBox(); + content.getChildren().addAll(createBackButton(), createBody()); + setCenter(content); } private ScrollPane createBody() { ScrollPane body = new ScrollPane(); body.setFitToWidth(true); - body.setFitToHeight(true) - ; + body.setFitToHeight(true); + VBox vBox = new VBox(); vBox.setId("main-container"); - vBox.getChildren().addAll( - createOrgSection() - ); + vBox.getChildren().addAll(createOrgSection()); body.setContent(vBox); return body; } + private HBox createBackButton() { + Button backBtn = new Button("←"); + backBtn.getStyleClass().add("back-button"); + backBtn.setOnAction(e -> nav.showCausesPage()); + + HBox container = new HBox(backBtn); + container.setPadding(new Insets(10, 0, 0, 10)); + return container; + } private HBox createOrgSection() { HBox orgSection = new HBox(); diff --git a/src/main/java/edu/group5/app/view/userpage/UserPageView.java b/src/main/java/edu/group5/app/view/userpage/UserPageView.java index c5d886d..b410761 100644 --- a/src/main/java/edu/group5/app/view/userpage/UserPageView.java +++ b/src/main/java/edu/group5/app/view/userpage/UserPageView.java @@ -12,6 +12,7 @@ import javafx.geometry.Pos; import javafx.scene.control.Button; import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.BorderPane; @@ -19,6 +20,7 @@ import javafx.scene.layout.VBox; import javafx.scene.text.Text; +import java.math.RoundingMode; import java.util.*; @@ -73,7 +75,6 @@ private HBox createProfileSection() { profile.setAlignment(Pos.CENTER_LEFT); return profile; } - private VBox createCausesSection() { Text title = new Text("YOUR SUPPORTED CAUSES"); title.getStyleClass().add("section-title"); @@ -99,8 +100,11 @@ private VBox createCausesSection() { } } } + ScrollPane scrollPane = new ScrollPane(causesBox); + scrollPane.setFitToWidth(true); + scrollPane.setPrefHeight(150); - return new VBox(10, title, causesBox); + return new VBox(10, title, scrollPane); } private VBox createDonationsSection() { @@ -125,13 +129,17 @@ private VBox createDonationsSection() { String orgName = (org != null) ? org.name() : "Unknown Organization"; Label donationLabel = new Label( - orgName + " • " + donation.amount() + " kr" + " • " + donation.date() + orgName + " • " + donation.amount().setScale(2, RoundingMode.HALF_UP) + " kr" + " • " + + donation.date() + " • " + donation.paymentMethod() ); donationsBox.getChildren().add(donationLabel); } } + ScrollPane scrollPane = new ScrollPane(donationsBox); + scrollPane.setFitToWidth(true); + scrollPane.setPrefHeight(200); - return new VBox(10, title, donationsBox); + return new VBox(10, title, scrollPane); } } diff --git a/src/main/resources/donationpage/donation.css b/src/main/resources/donationpage/donation.css index 32433df..74851a4 100644 --- a/src/main/resources/donationpage/donation.css +++ b/src/main/resources/donationpage/donation.css @@ -18,15 +18,24 @@ -fx-text-fill: white; -fx-border-color: #111; } +.donation-button-selected:hover { + -fx-background-color: #222; + -fx-border-color: #222; +} + +.donation-button-selected Text, +.donation-button-selected .donation-input { + -fx-fill: white; + -fx-border-color: transparent transparent white transparent; + -fx-text-fill: white; + -fx-prompt-text-fill: #ccc; +} + .donation-title { -fx-font-size: 18px; -fx-font-weight: bold; -fx-fill: #111; } -.donation-amount { - -fx-font-size: 18px; - -fx-fill: #111; -} .donation-input { -fx-font-size:16px; -fx-pref-width: 140px; @@ -51,3 +60,41 @@ -fx-background-color: #c02020; } +.payment-method-button { + -fx-background-color: #111; + -fx-text-fill: white; + -fx-font-size: 16px; + -fx-font-weight: bold; + -fx-pref-width: 180px; + -fx-pref-height: 45px; + -fx-background-radius: 6; + -fx-border-radius: 6; + -fx-cursor: hand; +} +.payment-method-button:hover { + -fx-background-color: #222; +} +.payment-method-selected, +.payment-method-selected:hover { + -fx-background-color: #e03030; +} +.donation-button-selected .donation-title, +.donation-button-selected .donation-amount { + -fx-fill: white; +} +.back-button { + -fx-background-color: white; + -fx-text-fill: black; + -fx-font-weight: bold; + -fx-font-size: 20px; + -fx-background-radius: 50; + -fx-padding: 4px 10px; + -fx-cursor: hand; + -fx-border-radius: 50; + -fx-border-color: black; + -fx-border-width: 2px; +} +.back-button:hover { + -fx-background-color: #333; + -fx-border-color:#333; +} \ No newline at end of file diff --git a/src/main/resources/organizationpage/organizationpage.css b/src/main/resources/organizationpage/organizationpage.css index a7276b5..8459526 100644 --- a/src/main/resources/organizationpage/organizationpage.css +++ b/src/main/resources/organizationpage/organizationpage.css @@ -28,4 +28,20 @@ #donate-button:hover { -fx-background-color: #c02020; +} +.back-button { + -fx-background-color: white; + -fx-text-fill: black; + -fx-font-weight: bold; + -fx-font-size: 20px; + -fx-background-radius: 50; + -fx-padding: 4px 10px; + -fx-cursor: hand; + -fx-border-radius: 50; + -fx-border-color: black; + -fx-border-width: 2px; +} +.back-button:hover { + -fx-background-color: #333; + -fx-border-color:#333; } \ No newline at end of file