diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..81229e8 Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..19af9e5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +git rm --cached .idea/workspace.xml +git rm --cached .idea/workspace.xml +git rm --cached bill-splitter-app.iml \ No newline at end of file diff --git a/.gitingnore b/.gitingnore index 9230d27..ecca007 100644 --- a/.gitingnore +++ b/.gitingnore @@ -1,43 +1,8 @@ -target/ -!.mvn/wrapper/maven-wrapper.jar -!/src/main//target/ -!/src/test//target/ - -IntelliJ IDEA -.idea/* -.idea/modules.xml -.idea/jarRepositories.xml -.idea/compiler.xml -.idea/libraries/ -*.iws -*.iml -*.ipr -.env - -Eclipse -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache - -NetBeans -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ -build/ -!/src/main//build/ -!/src/test//build/ - -VS Code -.vscode/ - -Mac OS -.DS_Store - -other files -users.csv \ No newline at end of file +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml \ No newline at end of file diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml deleted file mode 100644 index 3a78fb5..0000000 --- a/.idea/checkstyle-idea.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - 12.1.0 - JavaOnly - - - \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index b402903..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index 9e0b54e..0000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml deleted file mode 100644 index 712ab9d..0000000 --- a/.idea/jarRepositories.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 56c7380..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 0f41f74..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml deleted file mode 100644 index 65a1cc0..0000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { - "lastFilter": { - "state": "OPEN", - "assignee": "angelajj465" - } -} - { - "selectedUrlAndAccountId": { - "url": "https://github.com/amyjqian/Bill-Splitting-App.git", - "accountId": "1fdfdb60-dbec-49a9-89d9-230b5d7fac52" - } -} - { - "associatedIndex": 3 -} - - - - { - "keyToString": { - "Application.AppBuilder.executor": "Run", - "Application.Main.executor": "Run", - "Application.MyGroupFrame.executor": "Run", - "Application.Unnamed.executor": "Run", - "JUnit.ViewHistoryInteractorTest.executor": "Run", - "RunOnceActivity.ShowReadmeOnStart": "true", - "RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true", - "RunOnceActivity.git.unshallow": "true", - "git-widget-placeholder": "viewHistory", - "kotlin-language-version-configured": "true", - "project.structure.last.edited": "Modules", - "project.structure.proportion": "0.0", - "project.structure.side.proportion": "0.0" - } -} - - - - - - - - - - - - - - - - - - - - 1762785916007 - - - - \ No newline at end of file diff --git a/README.md b/README.md index d33a3a4..a955092 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ -# Bill-Splitting-App \ No newline at end of file +# Bill-Splitting-App + +Group Members: Amy Qian, Patricia Wan, Angela Jiang, Tan Tan, Katie Fruitman, Luxi Wang diff --git a/bill-splitter-app.iml b/bill-splitter-app.iml index 1c8be70..abe781f 100644 --- a/bill-splitter-app.iml +++ b/bill-splitter-app.iml @@ -2,11 +2,7 @@ - - + - - \ No newline at end of file diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 6b18681..0000000 --- a/pom.xml +++ /dev/null @@ -1,103 +0,0 @@ - - - - 4.0.0 - - com.group14 - bill-splitter-app - 1.0-SNAPSHOT - jar - - BillSplitterApp - A bill splitting and expense tracking app - - - 11 - 11 - UTF-8 - 5.10.1 - - - - - - org.junit.jupiter - junit-jupiter - ${junit.version} - test - - - - org.junit.jupiter - junit-jupiter-api - 5.10.1 - test - - - - org.junit.jupiter - junit-jupiter-engine - 5.10.1 - test - - - - com.squareup.okhttp3 - okhttp - 4.12.0 - - - - org.json - json - 20231013 - - - - io.github.cdimascio - dotenv-java - 3.0.0 - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - 11 - 11 - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.2.5 - - false - - - - - - - - . - - .env - - - - src/main/resources - - - - \ No newline at end of file diff --git a/src/main/java/app/AppBuilder.java b/src/main/java/app/AppBuilder.java deleted file mode 100644 index 2275807..0000000 --- a/src/main/java/app/AppBuilder.java +++ /dev/null @@ -1,31 +0,0 @@ -package app; - -import data_access.ViewHistoryDataAccessObject; -import interface_adapter.view_history.MyGroupViewModel; -import interface_adapter.view_history.ViewHistoryPresenter; -import interface_adapter.view_history.ViewHistoryController; -import use_case.view_history.ViewHistoryInteractor; -import io.github.cdimascio.dotenv.Dotenv; -import view.MyGroupFrame; - -import javax.swing.*; - -public class AppBuilder { - public static void main(String[] args) { - SwingUtilities.invokeLater(() -> { - MyGroupViewModel vm = new MyGroupViewModel("groupView"); - Dotenv dotenv = Dotenv.load(); - String apiKey = dotenv.get("SPLITWISE_API_KEY"); - - ViewHistoryPresenter presenter = new ViewHistoryPresenter(vm); - ViewHistoryDataAccessObject dao = new ViewHistoryDataAccessObject(apiKey); - ViewHistoryInteractor interactor = new ViewHistoryInteractor(dao, presenter); - ViewHistoryController controller = new ViewHistoryController(interactor); - - MyGroupFrame frame = new MyGroupFrame(vm, controller); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setSize(600, 400); - frame.setVisible(true); - }); - } -} diff --git a/src/main/java/app/Main.java b/src/main/java/app/Main.java deleted file mode 100644 index a9d522b..0000000 --- a/src/main/java/app/Main.java +++ /dev/null @@ -1,15 +0,0 @@ -package app; -import io.github.cdimascio.dotenv.Dotenv; - -public class Main { - - public static void main(String[] args) { - Dotenv dotenv = Dotenv.configure() - .directory(".") - .load(); - String apiKey = dotenv.get("SPLITWISE_API_KEY"); - - System.out.println("Loaded API_KEY = " + apiKey); - System.out.println("Working dir = " + System.getProperty("user.dir")); - } -} diff --git a/src/main/java/data_access/ViewHistoryDataAccessObject.java b/src/main/java/data_access/ViewHistoryDataAccessObject.java deleted file mode 100644 index 828bd8f..0000000 --- a/src/main/java/data_access/ViewHistoryDataAccessObject.java +++ /dev/null @@ -1,138 +0,0 @@ -package data_access; - -import entities.Expense; -import entities.User; -import okhttp3.*; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import use_case.view_history.ViewHistoryDataAccessInterface; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -public class ViewHistoryDataAccessObject implements ViewHistoryDataAccessInterface { - - private static final String BASE_URL = "https://secure.splitwise.com/api/v3.0/get_expenses?group_id="; - - private final OkHttpClient client = new OkHttpClient(); - private final String apiKey; - - public ViewHistoryDataAccessObject(String apiKey) { - this.apiKey = apiKey; - } - - @Override - public List getGroupExpenses(String groupId) { - - List result = new ArrayList<>(); - - Request request = new Request.Builder() - .url(BASE_URL + groupId) - .addHeader("Authorization", "Bearer " + apiKey) - .build(); - - try { - Response response = client.newCall(request).execute(); - String responseString = response.body().string(); - - if (!response.isSuccessful()) { - // throw new RuntimeException("API Error: " + response.code()); - int code = response.code(); - - if (code == 404) { - throw new IOException("Group not found"); - } else if (code == 401) { - throw new IOException("Unauthorized: invalid API key"); - } else if (code == 403) { - throw new IOException("Forbidden: not allowed to view this group"); - } else if (code >= 500) { - throw new IOException("Splitwise server error (" + code + ")"); - } else { - throw new IOException("API request failed (" + code + ")"); - } - } - - JSONObject root = new JSONObject(responseString); - JSONArray expenseArray = root.optJSONArray("expenses"); - if (expenseArray == null) { - return result; // no expenses - } - - for (int i = 0; i < expenseArray.length(); i++) { - JSONObject e = expenseArray.optJSONObject(i); - if (e != null) { - Expense exp = parseExpense(e); - if (exp != null) { - result.add(exp); - } - } - } - - return result; - - } catch (IOException e) { - throw new RuntimeException("Network failure: " + e.getMessage(),e); - } - } - - private Expense parseExpense(JSONObject json) { - try { - String id = json.optString("id", "no id"); - double amount = json.optDouble("cost",0.0); - String description = json.optString("description","(no description)"); - String date = json.optString("date", "(no date)"); - - // Who paid? - JSONObject createdByObj = json.optJSONObject("created_by"); - User paidBy; - - if (createdByObj != null) { - paidBy = new User( - String.valueOf(createdByObj.optInt("id", 0)), - createdByObj.optString("first_name", "Unknown"), - "" - ); - } else { - paidBy = new User("0", "Unknown", ""); - } - - // Participants - JSONArray userShares = json.optJSONArray("users"); - List participants = new ArrayList<>(); - - if (userShares != null) { - for (int i = 0; i < userShares.length(); i++) { - JSONObject shareEntry = userShares.optJSONObject(i); - if (shareEntry == null) continue; - - JSONObject u = shareEntry.optJSONObject("user"); - if (u == null) continue; - - User participant = new User( - String.valueOf(u.optInt("id", 0)), - u.optString("first_name", "Unknown"), - "" - ); - participants.add(participant); - } - } - - // build expense entity - Expense exp = new Expense(id, amount, description, paidBy, date); - - // Add participants - for (User u : participants) { - exp.addParticipant(u); - } - - return exp; - } catch (JSONException e) { - // unexpected missing field - System.err.println("Failed to parse expense: " + e.getMessage()); - return null; - } - } - -} diff --git a/src/main/java/entities/Expense.java b/src/main/java/entities/Expense.java deleted file mode 100644 index fc5e255..0000000 --- a/src/main/java/entities/Expense.java +++ /dev/null @@ -1,43 +0,0 @@ -package entities; -//changed this entity -import java.util.ArrayList; -import java.util.List; - -public class Expense { - private String id; - private String name; - private double amount; - private String description; - private User paidBy; - private List participants; - private boolean settled = false; - private String date; // creation date - - public Expense(String id, double amount, String description, User paidBy, String date) { - this.id = id; - this.amount = amount; - this.description = description; - this.paidBy = paidBy; - this.participants = new ArrayList<>(); - this.date = date; - } - - // Getters and setters - public String getId() { return id; } - public double getAmount() { return amount; } - public String getDescription() { return description; } - public User getPaidBy() { return paidBy; } - public List getParticipants() { return participants; } - public String getDate() { return date; } - - public void addParticipant(User user) { - if (!participants.contains(user)) { - participants.add(user); - } - } - - public double calculateEqualShare() { - if (participants.isEmpty()) return 0; - return amount / participants.size(); - } -} \ No newline at end of file diff --git a/src/main/java/entities/Group.java b/src/main/java/entities/Group.java deleted file mode 100644 index adadb86..0000000 --- a/src/main/java/entities/Group.java +++ /dev/null @@ -1,33 +0,0 @@ -package entities; - -import java.util.*; - -public class Group { - // Core properties - private String groupId; - private String groupName; - - // Members and relationships - private List members; - private List expenses; - private Map balances; // Track who owes whom - - - public Group(String groupId, String groupName) { - this.groupId = groupId; - this.groupName = groupName; - this.members = new ArrayList<>(); - this.expenses = new ArrayList<>(); - this.balances = new HashMap<>(); - - - } - public void addMember(User user) { - this.members.add(user); - } - - public List getExpenses() { - return expenses; - } - -} \ No newline at end of file diff --git a/src/main/java/entities/User.java b/src/main/java/entities/User.java deleted file mode 100644 index a69ab70..0000000 --- a/src/main/java/entities/User.java +++ /dev/null @@ -1,26 +0,0 @@ -package entities; -//changed this entity -public class User { - private String id; - private String name; - private String password; - - public User(String id, String name, String password) { - this.id = id; - this.name = name; - this.password = password; - } - - // Getters and setters - public String getId() { return id; } - public String getName() { return name; } - public String getPassword() { return password; } - - public void setName(String name) { this.name = name; } - public void setPassword(String email) { this.password = email; } - - @Override - public String toString() { - return name; - } -} \ No newline at end of file diff --git a/src/main/java/interface_adapter/view_history/MyGroupState.java b/src/main/java/interface_adapter/view_history/MyGroupState.java deleted file mode 100644 index c5b8290..0000000 --- a/src/main/java/interface_adapter/view_history/MyGroupState.java +++ /dev/null @@ -1,38 +0,0 @@ -package interface_adapter.view_history; - -import entities.Expense; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -public class MyGroupState { - private List expenses = new ArrayList<>(); - private String message = ""; - - public MyGroupState() {} - - public MyGroupState(MyGroupState other) { - this.expenses = new ArrayList<>(other.expenses); - this.message = other.message; - } - - public List getExpenses() { return expenses; } - public void setExpenses(List expenses) { this.expenses = new ArrayList<>(expenses); } - - public String getMessage() { return message; } - public void setMessage(String message) { this.message = message; } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof MyGroupState)) return false; - MyGroupState that = (MyGroupState) o; - return Objects.equals(expenses, that.expenses) && - Objects.equals(message, that.message); - } - - @Override - public int hashCode() { - return Objects.hash(expenses, message); - } -} diff --git a/src/main/java/interface_adapter/view_history/MyGroupViewModel.java b/src/main/java/interface_adapter/view_history/MyGroupViewModel.java deleted file mode 100644 index 2b6843b..0000000 --- a/src/main/java/interface_adapter/view_history/MyGroupViewModel.java +++ /dev/null @@ -1,33 +0,0 @@ -package interface_adapter.view_history; - -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; -import java.util.List; - -import entities.Expense; - -public class MyGroupViewModel { - private final PropertyChangeSupport support = new PropertyChangeSupport(this); - private MyGroupState state = new MyGroupState(); - - public MyGroupViewModel() {} - public MyGroupViewModel(String viewName) {} - - public MyGroupState getState() { return this.state; } - - public List getExpenses() { return state.getExpenses(); } - - public String getMessage() { return state.getMessage();} - - public void setExpenses(List expenses) { state.setExpenses(List.copyOf(expenses));} - - public void setMessage(String message) {state.setMessage(message);} - - public void firePropertyChanged() { - support.firePropertyChange("state", null, new MyGroupState(state)); - } - - public void addPropertyChangeListener(PropertyChangeListener listener) { - support.addPropertyChangeListener(listener); - } -} diff --git a/src/main/java/interface_adapter/view_history/ViewHistoryController.java b/src/main/java/interface_adapter/view_history/ViewHistoryController.java deleted file mode 100644 index c524bff..0000000 --- a/src/main/java/interface_adapter/view_history/ViewHistoryController.java +++ /dev/null @@ -1,18 +0,0 @@ -package interface_adapter.view_history; - -import use_case.view_history.ViewHistoryInputBoundary; -import use_case.view_history.ViewHistoryInputData; - -public class ViewHistoryController { - - private final ViewHistoryInputBoundary viewHistoryInputBoundary; - - public ViewHistoryController(ViewHistoryInputBoundary interactor) { - this.viewHistoryInputBoundary = interactor; - } - - public void execute(String groupId) { - ViewHistoryInputData inputData = new ViewHistoryInputData(groupId); - viewHistoryInputBoundary.execute(inputData); - } -} diff --git a/src/main/java/interface_adapter/view_history/ViewHistoryPresenter.java b/src/main/java/interface_adapter/view_history/ViewHistoryPresenter.java deleted file mode 100644 index 88f6ada..0000000 --- a/src/main/java/interface_adapter/view_history/ViewHistoryPresenter.java +++ /dev/null @@ -1,24 +0,0 @@ -package interface_adapter.view_history; - -import use_case.view_history.ViewHistoryOutputBoundary; -import use_case.view_history.ViewHistoryOutputData; - -public class ViewHistoryPresenter implements ViewHistoryOutputBoundary { - private final MyGroupViewModel viewModel; - - public ViewHistoryPresenter(MyGroupViewModel viewModel) { - this.viewModel = viewModel; - } - - public void prepareSuccessView(ViewHistoryOutputData outputData) { - viewModel.setExpenses(outputData.getExpenses()); - viewModel.setMessage(outputData.getMessage()); - viewModel.firePropertyChanged(); - } - - public void prepareFailedView(ViewHistoryOutputData outputData) { - viewModel.setMessage(outputData.getMessage()); - viewModel.firePropertyChanged(); - } -} - diff --git a/src/main/java/use_case/view_history/ViewHistoryDataAccessInterface.java b/src/main/java/use_case/view_history/ViewHistoryDataAccessInterface.java deleted file mode 100644 index e403925..0000000 --- a/src/main/java/use_case/view_history/ViewHistoryDataAccessInterface.java +++ /dev/null @@ -1,8 +0,0 @@ -package use_case.view_history; - -import entities.Expense; -import java.util.List; - -public interface ViewHistoryDataAccessInterface { - List getGroupExpenses(String groupId) throws Exception; -} diff --git a/src/main/java/use_case/view_history/ViewHistoryInputBoundary.java b/src/main/java/use_case/view_history/ViewHistoryInputBoundary.java deleted file mode 100644 index 3dc3b93..0000000 --- a/src/main/java/use_case/view_history/ViewHistoryInputBoundary.java +++ /dev/null @@ -1,5 +0,0 @@ -package use_case.view_history; - -public interface ViewHistoryInputBoundary { - void execute(ViewHistoryInputData inputData); -} diff --git a/src/main/java/use_case/view_history/ViewHistoryInputData.java b/src/main/java/use_case/view_history/ViewHistoryInputData.java deleted file mode 100644 index f75f154..0000000 --- a/src/main/java/use_case/view_history/ViewHistoryInputData.java +++ /dev/null @@ -1,13 +0,0 @@ -package use_case.view_history; - -public class ViewHistoryInputData { - private final String groupId; - - public ViewHistoryInputData(String groupId) { - this.groupId = groupId; - } - - public String getGroupId() { - return groupId; - } -} diff --git a/src/main/java/use_case/view_history/ViewHistoryInteractor.java b/src/main/java/use_case/view_history/ViewHistoryInteractor.java deleted file mode 100644 index 968c0ad..0000000 --- a/src/main/java/use_case/view_history/ViewHistoryInteractor.java +++ /dev/null @@ -1,52 +0,0 @@ -package use_case.view_history; - -import entities.Expense; -// import use_case.view_history.*; - -import java.util.List; - -public class ViewHistoryInteractor implements ViewHistoryInputBoundary{ - private final ViewHistoryDataAccessInterface viewHistoryDataAccessInterface; - private final ViewHistoryOutputBoundary viewHistoryOutputBoundary; - - public ViewHistoryInteractor(ViewHistoryDataAccessInterface viewHistoryDataAccessInterface, - ViewHistoryOutputBoundary viewHistoryOutputBoundary) { - this.viewHistoryDataAccessInterface = viewHistoryDataAccessInterface; - this.viewHistoryOutputBoundary = viewHistoryOutputBoundary; - } - public void execute(ViewHistoryInputData viewHistoryInputData) { - - String groupId = viewHistoryInputData.getGroupId(); - if (groupId == null || groupId.isBlank()) { - viewHistoryOutputBoundary.prepareFailedView( - new ViewHistoryOutputData(List.of(), "Invalid group ID.", false) - ); - return; - } - try { - // dao - List expenses = viewHistoryDataAccessInterface.getGroupExpenses(groupId); - - // empty expense - if (expenses == null) { - ViewHistoryOutputData outputData = - new ViewHistoryOutputData(null, "No history found.", false); - viewHistoryOutputBoundary.prepareFailedView(outputData); - return; - } - - // successful output - ViewHistoryOutputData outputData = - new ViewHistoryOutputData(expenses,"", true); - - viewHistoryOutputBoundary.prepareSuccessView(outputData); - - } catch (Exception e) { - // api failed - ViewHistoryOutputData outputData = - new ViewHistoryOutputData(List.of(), e.getMessage(), false); - viewHistoryOutputBoundary.prepareFailedView(outputData); - } - } - } - diff --git a/src/main/java/use_case/view_history/ViewHistoryOutputBoundary.java b/src/main/java/use_case/view_history/ViewHistoryOutputBoundary.java deleted file mode 100644 index a5bd2a7..0000000 --- a/src/main/java/use_case/view_history/ViewHistoryOutputBoundary.java +++ /dev/null @@ -1,6 +0,0 @@ -package use_case.view_history; - -public interface ViewHistoryOutputBoundary { - void prepareSuccessView(ViewHistoryOutputData outputData); - void prepareFailedView(ViewHistoryOutputData outputData); -} diff --git a/src/main/java/use_case/view_history/ViewHistoryOutputData.java b/src/main/java/use_case/view_history/ViewHistoryOutputData.java deleted file mode 100644 index 2a28da9..0000000 --- a/src/main/java/use_case/view_history/ViewHistoryOutputData.java +++ /dev/null @@ -1,23 +0,0 @@ -package use_case.view_history; - -import entities.Expense; - -import java.util.List; - -public class ViewHistoryOutputData { - // list of expenses, their amount and date - // error message if something goes wrong - private final List expenses; - private final String message; - private final boolean success; - - public ViewHistoryOutputData(List expenses, String message, boolean success) { - this.expenses = expenses; - this.message = message; - this.success = success; - } - - public List getExpenses() { return expenses; } - public String getMessage() { return message; } - public boolean isSuccess() { return success; } -} diff --git a/src/main/java/view/ExpenseDesc.java b/src/main/java/view/ExpenseDesc.java deleted file mode 100644 index 53cb4f2..0000000 --- a/src/main/java/view/ExpenseDesc.java +++ /dev/null @@ -1,45 +0,0 @@ -package view; - -import javax.swing.*; -import java.awt.*; - -public class ExpenseDesc extends JFrame { - - public ExpenseDesc() { - initializeUI(); - } - - private void initializeUI() { - setTitle("Add Expense"); - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - setSize(500, 300); - setLocationRelativeTo(null); - - JLabel titleLabel = new JLabel("Enter Amount and Description and Participants ", JLabel.CENTER); - JTextField amountField = new JTextField(10); - JTextField descField = new JTextField(10); - JTextField participantsField = new JTextField(10); - - JButton submitButton = new JButton("Submit"); - - // Simple panel with components - JPanel panel = new JPanel(); - panel.setLayout(new GridLayout(8, 1, 10, 10)); - - panel.add(titleLabel); - panel.add(new JLabel("Amount:")); - panel.add(amountField); - panel.add(new JLabel("Description:")); - panel.add(descField); - panel.add(new JLabel("Participants:")); - panel.add(participantsField); - panel.add(submitButton); - add(panel); - } - - public static void main(String[] args) { - SwingUtilities.invokeLater(() -> { - new ExpenseDesc().setVisible(true); - }); - } -} diff --git a/src/main/java/view/ExpenseFrame.java b/src/main/java/view/ExpenseFrame.java deleted file mode 100644 index 5ed3a18..0000000 --- a/src/main/java/view/ExpenseFrame.java +++ /dev/null @@ -1,44 +0,0 @@ -package view; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -public class ExpenseFrame extends JFrame { - - public ExpenseFrame() { - initializeUI(); - } - - private void initializeUI() { - setTitle("Bill Splitter - Group 14"); - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - setSize(600, 400); - setLocationRelativeTo(null); - - JLabel welcomeLabel = new JLabel("Split Expense Here", JLabel.CENTER); - JButton fixedExpense = new JButton("Fixed Expense"); - - // Simple button listener - fixedExpense.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - // Close current window - dispose(); - - // Open new screen - new ExpenseDesc().setVisible(true); - } - }); - - add(welcomeLabel, BorderLayout.NORTH); - add(fixedExpense, BorderLayout.CENTER); - } - - public static void main(String[] args) { - SwingUtilities.invokeLater(() -> { - new ExpenseFrame().setVisible(true); - }); - } -} \ No newline at end of file diff --git a/src/main/java/view/MainFrame.java b/src/main/java/view/MainFrame.java deleted file mode 100644 index 5796442..0000000 --- a/src/main/java/view/MainFrame.java +++ /dev/null @@ -1,27 +0,0 @@ -package view; - -import javax.swing.*; - -public class MainFrame extends JFrame { - - public MainFrame() { - initializeUI(); - } - - private void initializeUI() { - setTitle("Bill Splitter - Group 14"); - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - setSize(600, 400); - setLocationRelativeTo(null); - - // Add initial components - JLabel welcomeLabel = new JLabel("Welcome to Bill Splitter App!", JLabel.CENTER); - add(welcomeLabel); - } - - public static void main(String[] args) { - SwingUtilities.invokeLater(() -> { - new MainFrame().setVisible(true); - }); - } -} diff --git a/src/main/java/view/MyGroupFrame.java b/src/main/java/view/MyGroupFrame.java deleted file mode 100644 index f358c08..0000000 --- a/src/main/java/view/MyGroupFrame.java +++ /dev/null @@ -1,127 +0,0 @@ -package view; - -import interface_adapter.view_history.MyGroupViewModel; -import interface_adapter.view_history.ViewHistoryController; - -import javax.swing.*; -import javax.swing.table.DefaultTableModel; -import java.awt.*; - -public class MyGroupFrame extends JFrame { - - private final MyGroupViewModel myGroupViewModel; - - JTextField groupField = new JTextField("group14", 15); - JLabel errorLabel = new JLabel("", SwingConstants.CENTER); - - JTable expenseTable; - DefaultTableModel tableModel; - - public MyGroupFrame(MyGroupViewModel myGroupViewModel, ViewHistoryController viewHistoryController) { - this.myGroupViewModel = myGroupViewModel; - - setTitle("My Group"); - setLayout(new BorderLayout(10, 10)); - - // top section: groupName, Back, Refresh - // JLabel titleLabel = new JLabel("My Group", SwingConstants.CENTER); - JLabel groupLabel = new JLabel("Group:"); - groupField.setEditable(false); - - JButton backButton = new JButton("Back"); - JButton refreshHistoryButton = new JButton("Refresh History"); - - JPanel groupPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 5)); - groupPanel.add(groupLabel); - groupPanel.add(groupField); - groupPanel.add(refreshHistoryButton); - groupPanel.add(backButton); - - errorLabel.setForeground(Color.RED); - - JPanel northPanel = new JPanel(); - northPanel.setLayout(new BoxLayout(northPanel, BoxLayout.Y_AXIS)); - northPanel.add(groupPanel); - northPanel.add(errorLabel); - - add(northPanel, BorderLayout.NORTH); - - // table section - tableModel = new DefaultTableModel(new String[]{"Description", "Amount", "Date"}, 0); - expenseTable = new JTable(tableModel); - add(new JScrollPane(expenseTable), BorderLayout.CENTER); - - // bottom buttons - JButton newExpenseButton = new JButton("New Expense"); - JButton settleUpButton = new JButton("Settle Up"); - - JPanel footerPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 50, 10)); - footerPanel.add(newExpenseButton); - footerPanel.add(settleUpButton); - - add(footerPanel, BorderLayout.SOUTH); - - // event listeners - refreshHistoryButton.addActionListener(e -> { - viewHistoryController.execute(groupField.getText()); - }); - - // ViewModel listener - myGroupViewModel.addPropertyChangeListener(evt -> { - SwingUtilities.invokeLater(() -> { - updateErrorLabel(); - updateExpenseTable(); - }); - }); - - // button link - /* - newExpenseButton.addActionListener(e -> { - ExpenseFrame expenseFrame = new ExpenseFrame(); - expenseFrame.setVisible(true); - this.dispose(); // close MyGroupFrame if that’s your pattern - }); - - settleUpButton.addActionListener(e -> { - SettleUpPanel settlePanel = new SettleUpPanel(); - JFrame settleFrame = new JFrame("Settle Up"); - settleFrame.setVisible(true); - this.dispose(); - }); - - backButton.addActionListener(e -> { - GroupViewFrame gv = new GroupViewFrame(); - gv.setVisible(true); - this.dispose(); - }); - */ - } - - // helpers - private void updateErrorLabel() { - errorLabel.setText(myGroupViewModel.getMessage()); - } - - private void updateExpenseTable() { - // Clear table - tableModel.setRowCount(0); - - if (myGroupViewModel.getExpenses().isEmpty()) { - errorLabel.setText("No history found."); - return; - } - - myGroupViewModel.getExpenses().forEach(exp -> { - Object[] row = { - exp.getDescription(), - exp.getAmount(), - exp.getDate() - }; - tableModel.addRow(row); - }); - } - - public String getViewName() { - return "groupView"; - } -} diff --git a/src/test/java/use_case/view_history/ViewHistoryInteractorTest.java b/src/test/java/use_case/view_history/ViewHistoryInteractorTest.java deleted file mode 100644 index a3317d3..0000000 --- a/src/test/java/use_case/view_history/ViewHistoryInteractorTest.java +++ /dev/null @@ -1,116 +0,0 @@ -package use_case.view_history; - -import entities.Expense; -import entities.User; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.util.*; - -import static org.junit.jupiter.api.Assertions.*; - -class ViewHistoryInteractorTest { - - // Fake DAO - private static class FakeViewHistoryDAO implements ViewHistoryDataAccessInterface { - - Map> data = new HashMap<>(); - boolean throwException = false; - - @Override - public List getGroupExpenses(String groupId) throws Exception { - if (throwException) { - throw new Exception("DAO failure"); - } - return data.get(groupId); - } - } - - // Fake Presenter to capture output - private static class FakePresenter implements ViewHistoryOutputBoundary { - - ViewHistoryOutputData successData = null; - ViewHistoryOutputData failData = null; - - @Override - public void prepareSuccessView(ViewHistoryOutputData outputData) { - this.successData = outputData; - } - - @Override - public void prepareFailedView(ViewHistoryOutputData outputData) { - this.failData = outputData; - } - } - - private FakeViewHistoryDAO dao; - private FakePresenter presenter; - private ViewHistoryInteractor interactor; - - @BeforeEach - void setUp() { - dao = new FakeViewHistoryDAO(); - presenter = new FakePresenter(); - interactor = new ViewHistoryInteractor(dao, presenter); - } - - @Test - void testSuccessfulHistoryFetch() { - String gid = "group123"; - - // users - User A = new User("1","A", "123"); - User B = new User("2","B", "234"); - - - // Set up fake expenses - Expense e1 = new Expense("Dinner", 60.0, "A" ,A , "01-02-2025"); - Expense e2 = new Expense("Taxi", 30.0, "B", B, "01-02-2025"); - - dao.data.put(gid, Arrays.asList(e1, e2)); - - ViewHistoryInputData input = new ViewHistoryInputData(gid); - interactor.execute(input); - - assertNotNull(presenter.successData); - assertNull(presenter.failData); - assertEquals(2, presenter.successData.getExpenses().size()); - } - - @Test - void testGroupNotFound() { - // No group added - ViewHistoryInputData input = new ViewHistoryInputData("missingGroup"); - interactor.execute(input); - - assertNull(presenter.successData); - assertNotNull(presenter.failData); - assertFalse(presenter.failData.isSuccess()); - assertTrue(presenter.failData.getMessage().contains("No history found.")); - } - - @Test - void testDaoThrowsException() { - dao.throwException = true; - - ViewHistoryInputData input = new ViewHistoryInputData("anyGroup"); - interactor.execute(input); - - assertNull(presenter.successData); - assertNotNull(presenter.failData); - - assertFalse(presenter.failData.isSuccess()); - assertTrue(presenter.failData.getMessage().contains("DAO")); - } - - @Test - void testEmptyExpenseList() { - dao.data.put("emptyGroup", new ArrayList<>()); - - ViewHistoryInputData input = new ViewHistoryInputData("emptyGroup"); - interactor.execute(input); - - assertNotNull(presenter.successData); - assertEquals(0, presenter.successData.getExpenses().size()); - } -}