Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@
<version>3.46.1.0</version>
</dependency>

<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.17.2</version>
</dependency>

</dependencies>

<build>
Expand All @@ -73,6 +79,19 @@
<version>3.5.4</version>
</plugin>

<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<configuration>
<mainClass>app.Main</mainClass>
<options>
<option>-Dfile.encoding=UTF-8</option>
<option>-Dstdout.encoding=UTF-8</option>
</options>
</configuration>
</plugin>

</plugins>
</build>
</project>
10 changes: 7 additions & 3 deletions src/main/java/app/Main.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
package app;

import domain.organization.Organization;
import domain.organization.OrganizationDetails;
import integration.InnsamlingskontrollenClient;
import application.security.PasswordHasher;
import application.user.UserRegister;
import domain.donation.Donation;
import domain.user.User;
import integration.security.Sha256PasswordHasher;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.List;

import persistence.DonationDao;
import persistence.OrganizationDao;
import persistence.UserDao;
import persistence.UserRepository;
import persistence.db.Database;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
Expand All @@ -30,6 +29,11 @@ public static void main(String[] args) {
public void start(Stage stage) throws Exception {
Database.initializeDatabase();
System.out.println("DB path: " + new java.io.File("givehope.db").getAbsolutePath());
OrganizationDetails details = InnsamlingskontrollenClient.fetchDetails(
"https://www.innsamlingskontrollen.no/organisasjoner/caritas-norge/"
);
System.out.println("Description: " + details.getDescription());
System.out.println("Logo: " + details.getLogoUrl());
OrganizationDao orgDao = new OrganizationDao();
Organization[] orgs = InnsamlingskontrollenClient.fetchOrganizations();
for (Organization org : orgs) {
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/domain/organization/OrganizationDetails.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package domain.organization;

public class OrganizationDetails {
private String description;
private String logoUrl;

public OrganizationDetails(String description, String logoUrl) {
this.description = description;
this.logoUrl = logoUrl;
}

public String getDescription() {
return description;
}

public String getLogoUrl() {
return logoUrl;
}
}
41 changes: 41 additions & 0 deletions src/main/java/integration/InnsamlingskontrollenClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;

import com.fasterxml.jackson.databind.ObjectMapper;
import domain.organization.Organization;
import domain.organization.OrganizationDetails;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;


public class InnsamlingskontrollenClient {

Expand All @@ -24,4 +29,40 @@ public static Organization[] fetchOrganizations() throws Exception {

return mapper.readValue(response.body(), Organization[].class);
}

public static OrganizationDetails fetchDetails(String url) {
try {
org.jsoup.Connection conn = Jsoup.connect(url);
conn.timeout(10000);
Document doc = conn.get();
doc.charset(StandardCharsets.UTF_8);
System.out.println(doc.select("section.information").text());

String description = "";
System.out.println("Section size: " + doc.select("section.information div > p").size());
for (org.jsoup.nodes.Element p : doc.select("section.information div > p")) {
System.out.println("P element: " + p.text());
if (!p.text().isBlank()) {
description = p.text();
break;
}
}

if (description.isBlank()) {
String sectionText = doc.select("section.information").text();
if (!sectionText.isBlank()) {
int lesmerIndex = sectionText.indexOf("Les mer");
description = lesmerIndex > 0
? sectionText.substring(0, lesmerIndex).trim()
: sectionText;
}
}

String logoUrl = doc.select("img[src*=logo]").attr("src");

return new OrganizationDetails(description, logoUrl);
} catch (Exception e) {
return new OrganizationDetails("", "");
}
}
}
54 changes: 54 additions & 0 deletions src/main/java/ui/controller/MainController.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
import application.user.UserRegister;
import application.user.UserSignIn;
import domain.organization.Organization;
import domain.organization.OrganizationDetails;
import integration.InnsamlingskontrollenClient;
import integration.security.Sha256PasswordHasher;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import persistence.UserDao;
import ui.DonationSession;
import ui.Page;
Expand All @@ -24,6 +27,9 @@ public class MainController {
@FXML
private NavbarController navbarController;

@FXML
private VBox overlay;

private DonationSession donationSession;
private DonationFlowController donationFlowController;

Expand Down Expand Up @@ -79,6 +85,13 @@ public void loadPage(Page page) throws IOException {
if (controller instanceof DonationSessionAware c) {
c.setDonationSession(donationSession);
}
if (controller instanceof OrganizationController c) {
c.setOnDonate(org -> {
try { loadDonationPage(org); }
catch (IOException e) { throw new RuntimeException(e); }
});
c.setOnShowDetail(org -> showOrganizationDetail(org));
}

mainPane.setCenter(root);
navbarController.setActivePage(page);
Expand All @@ -89,4 +102,45 @@ public void loadPage(Page page) throws IOException {
public void loadDonationPage(Organization org) throws IOException {
donationFlowController.start(org);
}

public void showOrganizationDetail(Organization org) {
try {
FXMLLoader loader = new FXMLLoader(
getClass().getResource("/view/OrganizationDetail.fxml"));
Parent root = loader.load();

OrganizationDetails details =
InnsamlingskontrollenClient.fetchDetails(org.getUrl());

OrganizationDetailController controller = loader.getController();
controller.setOrganization(org, details);
controller.setOnClose(() -> {
overlay.setVisible(false);
overlay.setManaged(false);
overlay.getChildren().clear();
});
controller.setOnDonate(o -> {
overlay.setVisible(false);
overlay.setManaged(false);
overlay.getChildren().clear();
try {
loadDonationPage(o);
} catch (IOException e) {
throw new RuntimeException(e);
}
});

overlay.getChildren().clear();
overlay.getChildren().add(root);
overlay.setVisible(true);
overlay.setManaged(true);
overlay.setStyle("-fx-background-color: rgba(0,0,0,0.5);");
overlay.setMaxWidth(Double.MAX_VALUE);
overlay.setMaxHeight(Double.MAX_VALUE);
overlay.setAlignment(javafx.geometry.Pos.CENTER);

} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
11 changes: 10 additions & 1 deletion src/main/java/ui/controller/OrganizationController.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public class OrganizationController implements NavigationAware{

private Consumer<Page> onNavigate;
private Consumer<Organization> onDonate;
private Consumer<Organization> onShowDetail;


public void setOnNavigate(Consumer<Page> onNavigate) {
this.onNavigate = onNavigate;
Expand All @@ -46,10 +48,16 @@ public void setOnDonate(Consumer<Organization> onDonate) {
this.onDonate = onDonate;
}

public void setOnShowDetail(Consumer<Organization> onShowDetail) {
this.onShowDetail = onShowDetail;
}

public void initialize() {
try {
OrganizationDao dao = new OrganizationDao();
allOrgs = dao.getAll();
allOrgs = dao.getAll().stream()
.filter(org -> "approved".equals(org.getStatus()))
.collect(Collectors.toList());
System.out.println("Fetched: " + allOrgs.size() + " organizations");
filtrertOrgs = new ArrayList<>(allOrgs);
showPage();
Expand Down Expand Up @@ -119,6 +127,7 @@ private VBox createCard(Organization org) {
donateBtn.setMaxWidth(Double.MAX_VALUE);
donateBtn.setOnAction(e -> onDonate.accept(org));

card.setOnMouseClicked(e -> onShowDetail.accept(org));
card.getChildren().addAll(name, orgnr, status, donateBtn);
return card;
}
Expand Down
102 changes: 102 additions & 0 deletions src/main/java/ui/controller/OrganizationDetailController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package ui.controller;

import domain.organization.Organization;
import domain.organization.OrganizationDetails;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import ui.Page;

import java.awt.Desktop;
import java.net.URI;
import java.util.function.Consumer;

public class OrganizationDetailController {

@FXML private Label nameLabel;
@FXML private Label orgNumberLabel;
@FXML private Label verifiedLabel;
@FXML private Label descriptionLabel;
@FXML private ImageView logoImageView;
@FXML private Hyperlink readMoreLink;


private Organization organization;
private Consumer<Organization> onDonate;
private Runnable onClose;

public void setOrganization(Organization org, OrganizationDetails details) {
this.organization = org;
nameLabel.setText(org.getName());
orgNumberLabel.setText("Org.nr: " + org.getOrgNumber());
verifiedLabel.setText(org.isPreApproved() ? "✓ Forhåndsgodkjent" : "✓ Verified");

if (details.getDescription() != null && !details.getDescription().isBlank()) {
String description = details.getDescription();
if (description.length() > 300) {
int lastPeriod = description.lastIndexOf(".", 300);
description = lastPeriod > 0
? description.substring(0, lastPeriod + 1)
: description.substring(0, 300) + "...";
readMoreLink.setVisible(true);
readMoreLink.setManaged(true);
}
descriptionLabel.setText(description);
} else {
descriptionLabel.setText("No description available.");
}



if (details.getLogoUrl() != null && !details.getLogoUrl().isBlank()) {
try {
Image image = new Image(details.getLogoUrl(), true);
image.errorProperty().addListener((obs, old, error) -> {
if (error) {
logoImageView.setVisible(false);
}
});
logoImageView.setImage(image);
} catch (Exception e) {
logoImageView.setVisible(false);
}
} else {
logoImageView.setVisible(false);
}
}

public void setOnDonate(Consumer<Organization> onDonate) {
this.onDonate = onDonate;
}

public void setOnClose(Runnable onClose) {
this.onClose = onClose;
}

@FXML
public void handleClose() {
if (onClose != null) onClose.run();
}

@FXML
public void handleDonate() {
if (onDonate != null) onDonate.accept(organization);
}

@FXML
public void handleVisitWebsite() {
try {
Desktop.getDesktop().browse(new URI(organization.getUrl()));
} catch (Exception e) {
e.printStackTrace();
}
}

@FXML
public void handleReadMore() {
handleVisitWebsite();
}
}
23 changes: 0 additions & 23 deletions src/main/resources/css/Donation.css
Original file line number Diff line number Diff line change
Expand Up @@ -96,27 +96,4 @@
.success-icon {
-fx-font-size: 48px;
-fx-text-fill: #2d6a4f;
}

.secondary-button {
-fx-background-color: transparent;
-fx-border-color: #1e3a8a;
-fx-border-width: 1.5;
-fx-border-radius: 6;
-fx-background-radius: 6;
-fx-text-fill: #1e3a8a;
-fx-font-weight: bold;
-fx-padding: 10 24 10 24;
-fx-cursor: hand;
-fx-font-size: 14px;
}

.secondary-button:hover {
-fx-background-color: #f0f4ff;
}

.secondary-button:pressed {
-fx-background-color: #dce6f7;
-fx-scale-x: 0.97;
-fx-scale-y: 0.97;
}
Loading