diff --git a/spending.db b/spending.db new file mode 100644 index 0000000..a720f82 Binary files /dev/null and b/spending.db differ diff --git a/src/main/java/edu/ucsd/spendingtracker/.DS_Store b/src/main/java/edu/ucsd/spendingtracker/.DS_Store new file mode 100644 index 0000000..6feb894 Binary files /dev/null and b/src/main/java/edu/ucsd/spendingtracker/.DS_Store differ diff --git a/src/main/java/edu/ucsd/spendingtracker/App.java b/src/main/java/edu/ucsd/spendingtracker/App.java index 7d2f29b..80241a4 100644 --- a/src/main/java/edu/ucsd/spendingtracker/App.java +++ b/src/main/java/edu/ucsd/spendingtracker/App.java @@ -1,6 +1,13 @@ package edu.ucsd.spendingtracker; +import edu.ucsd.spendingtracker.view.charts.*; + +import java.util.ArrayList; +import java.util.List; + +import edu.ucsd.spendingtracker.datasource.IDataSource; import edu.ucsd.spendingtracker.datasource.InMemoryDataSource; +import edu.ucsd.spendingtracker.datasource.SqlDataSource; import edu.ucsd.spendingtracker.model.Model; import edu.ucsd.spendingtracker.presenter.PresenterManager; import edu.ucsd.spendingtracker.presenter.SpendingPresenter; @@ -14,7 +21,7 @@ public class App extends Application { @Override public void start(Stage primaryStage) { - InMemoryDataSource dataSource = InMemoryDataSource.getDefaultDataSource(); + IDataSource dataSource = new SqlDataSource(); ExpenseRepository repository = new ExpenseRepository(dataSource); Model sharedModel = new Model(repository); @@ -22,8 +29,12 @@ public void start(Stage primaryStage) { SpendingView spendingView = new SpendingView(); SummaryView summaryView = new SummaryView(); + List chartProviders = new ArrayList<>(); + chartProviders.add(new BarChartProvider()); + chartProviders.add(new PieChartProvider()); + SpendingPresenter listPresenter = new SpendingPresenter(sharedModel, spendingView); - SummaryPresenter summaryPresenter = new SummaryPresenter(sharedModel, summaryView); + SummaryPresenter summaryPresenter = new SummaryPresenter(sharedModel, summaryView, chartProviders); PresenterManager manager = new PresenterManager(); manager.defineInteractions(primaryStage, "Spending Tracker", listPresenter, summaryPresenter); diff --git a/src/main/java/edu/ucsd/spendingtracker/datasource/IDataSource.java b/src/main/java/edu/ucsd/spendingtracker/datasource/IDataSource.java new file mode 100644 index 0000000..07fa1f5 --- /dev/null +++ b/src/main/java/edu/ucsd/spendingtracker/datasource/IDataSource.java @@ -0,0 +1,12 @@ +package edu.ucsd.spendingtracker.datasource; +import java.util.List; +import edu.ucsd.spendingtracker.model.Expense; + +public interface IDataSource { + List getExpenses(); + + void addExpense(Expense expense); + + void deleteExpense(int id); + +} diff --git a/src/main/java/edu/ucsd/spendingtracker/datasource/InMemoryDataSource.java b/src/main/java/edu/ucsd/spendingtracker/datasource/InMemoryDataSource.java index c71abcd..8c9e24c 100644 --- a/src/main/java/edu/ucsd/spendingtracker/datasource/InMemoryDataSource.java +++ b/src/main/java/edu/ucsd/spendingtracker/datasource/InMemoryDataSource.java @@ -6,29 +6,22 @@ import edu.ucsd.spendingtracker.model.Category; import edu.ucsd.spendingtracker.model.Expense; -public class InMemoryDataSource { +public class InMemoryDataSource implements IDataSource { private List expenses = new ArrayList<>(); - public InMemoryDataSource() { - } - + @Override public List getExpenses() { return List.copyOf(expenses); } + @Override public void addExpense(Expense expense) { expenses.add(expense); } - public final static List DEFAULT_EXPENSES = List.of( - new Expense("Groceries", Category.FOOD, 150.75), - new Expense("Utilities", Category.UTILITIES, 80.50), - new Expense("Gas", Category.TRANSPORT, 60.00)); - - public static InMemoryDataSource getDefaultDataSource() { - InMemoryDataSource dataSource = new InMemoryDataSource(); - dataSource.expenses.addAll(DEFAULT_EXPENSES); - return dataSource; + @Override + public void deleteExpense(int expenseId){ + expenses.removeIf(expense -> expense.getId() == expenseId); } } diff --git a/src/main/java/edu/ucsd/spendingtracker/datasource/SqlDataSource.java b/src/main/java/edu/ucsd/spendingtracker/datasource/SqlDataSource.java new file mode 100644 index 0000000..b1b82ee --- /dev/null +++ b/src/main/java/edu/ucsd/spendingtracker/datasource/SqlDataSource.java @@ -0,0 +1,66 @@ +package edu.ucsd.spendingtracker.datasource; + + +import edu.ucsd.spendingtracker.model.*; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; + + +public class SqlDataSource implements IDataSource { + private final String url = "jdbc:sqlite:spending.db"; + + + public SqlDataSource() { + try (Connection conn = DriverManager.getConnection(url)) { + conn.createStatement().execute( + "CREATE TABLE IF NOT EXISTS expenses (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, category TEXT, amount REAL)"); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + + @Override + public List getExpenses() { + List list = new ArrayList<>(); + try (Connection conn = DriverManager.getConnection(url); + ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM expenses")) { + while (rs.next()) { + list.add(new Expense(rs.getInt("id"), rs.getString("name"), + Category.valueOf(rs.getString("category")), rs.getDouble("amount"))); + } + } catch (SQLException e) { + e.printStackTrace(); + } + return list; + } + + + @Override + public void addExpense(Expense e) { + try (Connection conn = DriverManager.getConnection(url); + PreparedStatement ps = conn.prepareStatement("INSERT INTO expenses(name, category, amount) VALUES(?,?,?)")) { + ps.setString(1, e.getName()); + ps.setString(2, e.getCategory().name()); + ps.setDouble(3, e.getAmount()); + ps.executeUpdate(); + } catch (SQLException err) { + err.printStackTrace(); + } + } + + + @Override + public void deleteExpense(int id) { + try (Connection conn = DriverManager.getConnection(url); + PreparedStatement ps = conn.prepareStatement("DELETE FROM expenses WHERE id = ?")) { + ps.setInt(1, id); + ps.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + } +} + + diff --git a/src/main/java/edu/ucsd/spendingtracker/model/Expense.java b/src/main/java/edu/ucsd/spendingtracker/model/Expense.java index 3b73dca..c6d7c03 100644 --- a/src/main/java/edu/ucsd/spendingtracker/model/Expense.java +++ b/src/main/java/edu/ucsd/spendingtracker/model/Expense.java @@ -4,8 +4,16 @@ public class Expense { private String name; private Category category; private double amount; + private int id; - public Expense(String name, Category category, double amount) { + public Expense(int id, String name, Category category, double amount) { + this.name = name; + this.category = category; + this.amount = amount; + this.id = id; + } + + public Expense( String name, Category category, double amount) { this.name = name; this.category = category; this.amount = amount; @@ -22,6 +30,10 @@ public Category getCategory() { public double getAmount() { return amount; } + + public int getId(){ + return id; + } } diff --git a/src/main/java/edu/ucsd/spendingtracker/model/Model.java b/src/main/java/edu/ucsd/spendingtracker/model/Model.java index 97e5c80..0f4c2bc 100644 --- a/src/main/java/edu/ucsd/spendingtracker/model/Model.java +++ b/src/main/java/edu/ucsd/spendingtracker/model/Model.java @@ -21,4 +21,8 @@ public List getExpenses() { public double getTotalSpending() { return repository.getTotal(); } + + public void deleteExpense(int id){ + repository.deleteExpense(id); + } } \ No newline at end of file diff --git a/src/main/java/edu/ucsd/spendingtracker/presenter/SpendingPresenter.java b/src/main/java/edu/ucsd/spendingtracker/presenter/SpendingPresenter.java index 171568d..1090995 100644 --- a/src/main/java/edu/ucsd/spendingtracker/presenter/SpendingPresenter.java +++ b/src/main/java/edu/ucsd/spendingtracker/presenter/SpendingPresenter.java @@ -14,6 +14,18 @@ public SpendingPresenter(Model model, SpendingView view) { onShowSummary.run(); }); + this.view.setOnDelete(id -> { + model.deleteExpense(id); + updateView(); + }); + + this.view.getOpenModalButton().setOnAction(e -> { + view.showAddExpenseModal(newExpense -> { + model.addExpense(newExpense); + updateView(); + }); + }); + updateView(); } @@ -27,9 +39,9 @@ public String getViewTitle() { } public void updateView() { - int i = 1; + view.clearList(); for (Expense e : model.getExpenses()) { - view.addExpenseRow(i++, e.getName(), e.getCategory().name(), + view.addExpenseRow(e.getId(), e.getName(), e.getCategory().name(), e.getCategory().color, e.getAmount()); } } diff --git a/src/main/java/edu/ucsd/spendingtracker/presenter/SummaryPresenter.java b/src/main/java/edu/ucsd/spendingtracker/presenter/SummaryPresenter.java index ff4f4d9..9beeb6d 100644 --- a/src/main/java/edu/ucsd/spendingtracker/presenter/SummaryPresenter.java +++ b/src/main/java/edu/ucsd/spendingtracker/presenter/SummaryPresenter.java @@ -1,18 +1,34 @@ package edu.ucsd.spendingtracker.presenter; -import edu.ucsd.spendingtracker.model.Model; + +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import edu.ucsd.spendingtracker.model.*; import edu.ucsd.spendingtracker.view.SummaryView; +import edu.ucsd.spendingtracker.view.charts.IChartProvider; +import javafx.scene.Node; public class SummaryPresenter extends AbstractPresenter { private Runnable onBack; + private final List chartProviders; - public SummaryPresenter(Model model, SummaryView view) { + public SummaryPresenter(Model model, SummaryView view, List chartProviders) { super(model, view); + this.chartProviders = chartProviders; + this.view.getChartSelector().getItems().addAll(this.chartProviders); + + if (!this.chartProviders.isEmpty()) { + this.view.getChartSelector().setValue(this.chartProviders.get(0)); + } this.view.getBackButton().setOnAction(e -> { if (onBack != null) onBack.run(); }); + + this.view.getChartSelector().setOnAction(e -> updateView()); } public void setOnBack(Runnable action) { @@ -21,7 +37,28 @@ public void setOnBack(Runnable action) { @Override public void updateView() { + List expenses = model.getExpenses(); + Map totals = new TreeMap<>(); + + for (Category cat : Category.values()){ + totals.put(cat, 0.0); + } + + for (Expense expense : expenses) { + Category category = expense.getCategory(); + double amount = expense.getAmount(); + + totals.put(category, totals.get(category) + amount); + } + view.setTotal(model.getTotalSpending()); + + IChartProvider selectedProvider = view.getChartSelector().getValue(); + + if (selectedProvider != null) { + Node chartNode = selectedProvider.createChart(totals); + view.setChartDisplay(chartNode); + } } @Override diff --git a/src/main/java/edu/ucsd/spendingtracker/repository/ExpenseRepository.java b/src/main/java/edu/ucsd/spendingtracker/repository/ExpenseRepository.java index 91f5f8e..18c590c 100644 --- a/src/main/java/edu/ucsd/spendingtracker/repository/ExpenseRepository.java +++ b/src/main/java/edu/ucsd/spendingtracker/repository/ExpenseRepository.java @@ -1,13 +1,15 @@ package edu.ucsd.spendingtracker.repository; import java.util.List; + +import edu.ucsd.spendingtracker.datasource.IDataSource; import edu.ucsd.spendingtracker.datasource.InMemoryDataSource; import edu.ucsd.spendingtracker.model.Expense; public class ExpenseRepository { - private final InMemoryDataSource dataSource; + private IDataSource dataSource; - public ExpenseRepository(InMemoryDataSource dataSource) { + public ExpenseRepository(IDataSource dataSource) { this.dataSource = dataSource; } @@ -26,5 +28,9 @@ public double getTotal() { } return total; } + + public void deleteExpense(int id){ + dataSource.deleteExpense(id); + } } diff --git a/src/main/java/edu/ucsd/spendingtracker/view/SpendingView.java b/src/main/java/edu/ucsd/spendingtracker/view/SpendingView.java index b9dab5f..2eb233b 100644 --- a/src/main/java/edu/ucsd/spendingtracker/view/SpendingView.java +++ b/src/main/java/edu/ucsd/spendingtracker/view/SpendingView.java @@ -1,23 +1,43 @@ package edu.ucsd.spendingtracker.view; import javafx.geometry.*; +import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.*; import javafx.scene.text.*; +import javafx.stage.Modality; +import javafx.stage.Stage; +import java.util.function.Consumer; + +import edu.ucsd.spendingtracker.model.Category; +import edu.ucsd.spendingtracker.model.Expense; + public class SpendingView extends BorderPane { private VBox listContainer; private Button summaryButton; + private Button openAddModalBtn; + private Consumer onDeleteHandler; public SpendingView() { - VBox headerBox = new VBox(10); + VBox headerBox = new VBox(15); headerBox.setAlignment(Pos.CENTER); headerBox.setPadding(new Insets(20)); Text title = new Text("Spending Tracker"); - title.setStyle("-fx-font-weight: bold; -fx-font-size: 24;"); + title.setStyle("-fx-font-weight: bold; -fx-font-size: 26;"); + + HBox navBox = new HBox(10); + navBox.setAlignment(Pos.CENTER); + summaryButton = new Button("View Summary"); - headerBox.getChildren().addAll(title, summaryButton); + openAddModalBtn = new Button("Add New Expense +"); + openAddModalBtn.setStyle("-fx-background-color: #2E7D32; -fx-text-fill: white; -fx-font-weight: bold;"); + + navBox.getChildren().addAll(openAddModalBtn, summaryButton); + headerBox.getChildren().addAll(title, navBox); + + listContainer = new VBox(5); ScrollPane scroller = new ScrollPane(listContainer); @@ -30,7 +50,7 @@ public SpendingView() { this.setStyle("-fx-background-color: #FFFFFF;"); } - public void addExpenseRow(int idx, String name, String catName, String color, double amount) { + public void addExpenseRow(int id, String name, String catName, String color, double amount) { HBox row = new HBox(10); row.setPrefSize(450, 40); row.setPadding(new Insets(5, 10, 5, 10)); @@ -47,12 +67,74 @@ public void addExpenseRow(int idx, String name, String catName, String color, do Label amtL = new Label("$" + String.format("%.2f", amount)); amtL.setPrefWidth(80); amtL.setAlignment(Pos.CENTER_RIGHT); + Button deleteBtn = new Button("X"); + + deleteBtn.setStyle("-fx-background-color: #ff6961; -fx-text-fill: white;"); + deleteBtn.setOnAction(e -> { + if (onDeleteHandler != null) onDeleteHandler.accept(id); + }); - row.getChildren().addAll(new Label(idx + "."), nameL, catL, amtL); + + + row.getChildren().addAll(nameL, catL, amtL, deleteBtn); listContainer.getChildren().add(row); } public Button getSummaryButton() { return summaryButton; } + + + public void showAddExpenseModal(Consumer onSave){ + Stage modal = new Stage(); + + modal.initModality(Modality.APPLICATION_MODAL); + // Blocks the main window + modal.setTitle("Add New Expense"); + + + VBox layout = new VBox(15); + layout.setPadding(new Insets(20)); + layout.setAlignment(Pos.CENTER); + + + TextField nameField = new TextField(); + nameField.setPromptText("Expense Name"); + TextField amountField = new TextField(); + amountField.setPromptText("Amount"); + ComboBox categoryBox = new ComboBox<>(); + categoryBox.getItems().setAll(Category.values()); + + + Button saveBtn = new Button("Save Expense"); + saveBtn.setOnAction(e -> { + try { + double amount = Double.parseDouble(amountField.getText()); + onSave.accept(new Expense(nameField.getText(), categoryBox.getValue(), amount)); + modal.close(); + } catch (NumberFormatException ex) { + amountField.setStyle("-fx-border-color: red;"); + } + }); + + + layout.getChildren().addAll(new Label("Expense Details"), nameField, amountField, categoryBox, saveBtn); + modal.setScene(new Scene(layout, 300, 250)); + modal.showAndWait(); + } + + public void clearList() { + listContainer.getChildren().clear(); + } + + + public void setOnDelete(Consumer handler) { + this.onDeleteHandler = handler; + } + + + public Button getOpenModalButton() { + return openAddModalBtn; + } + } diff --git a/src/main/java/edu/ucsd/spendingtracker/view/SummaryView.java b/src/main/java/edu/ucsd/spendingtracker/view/SummaryView.java index 1bf0e9c..b9b0e9f 100644 --- a/src/main/java/edu/ucsd/spendingtracker/view/SummaryView.java +++ b/src/main/java/edu/ucsd/spendingtracker/view/SummaryView.java @@ -1,5 +1,9 @@ package edu.ucsd.spendingtracker.view; +import javafx.scene.Node; + +import edu.ucsd.spendingtracker.view.charts.IChartProvider; +import javafx.util.StringConverter; import javafx.geometry.*; import javafx.scene.control.*; import javafx.scene.layout.*; @@ -7,24 +11,59 @@ public class SummaryView extends VBox { private Label totalLabel = new Label(); private Button backButton = new Button("Back to Expenses"); + private final ComboBox chartSelector = new ComboBox<>(); + private final StackPane chartContainer = new StackPane(); public SummaryView() { this.setAlignment(Pos.CENTER); this.setSpacing(20); + this.setPadding(new Insets(30)); this.setStyle("-fx-background-color: #FFFFFF;"); - Label title = new Label("Total Spending"); + Label title = new Label("Spending Analysis"); title.setStyle("-fx-font-size: 20px; -fx-font-weight: bold;"); totalLabel.setStyle("-fx-font-size: 32px; -fx-text-fill: #2E7D32;"); - this.getChildren().addAll(title, totalLabel, backButton); + chartSelector.setPromptText("Select Visualisation Type"); + chartSelector.setPrefWidth(200); + + chartSelector.setConverter(new StringConverter(){ + @Override + public String toString(IChartProvider provider){ + if (provider == null) return "" ; + else return provider.getDisplayName(); + } + + @Override + public IChartProvider fromString(String string){ + return null; + } + }); + + chartContainer.setPrefSize(400, 300); + chartContainer.setStyle("-fx-border-color: #EEEEEE; -fx-border-width-1; -fx-border-radius: 5;"); + + backButton.setStyle("-fx-background-color: #757575; -fx-text-fill: white;"); + + this.getChildren().addAll(title, totalLabel, new Label("View Mode:"), chartSelector, chartContainer, backButton); + } + + public void setChartDisplay(Node chartNode){ + chartContainer.getChildren().clear(); + if(chartNode != null){ + chartContainer.getChildren().add(chartNode); + } } public void setTotal(double total) { totalLabel.setText("$" + String.format("%.2f", total)); } - /// Hello + public Button getBackButton() { return backButton; } + + public ComboBox getChartSelector(){ + return chartSelector; + } } \ No newline at end of file diff --git a/src/main/java/edu/ucsd/spendingtracker/view/charts/BarChartProvider.java b/src/main/java/edu/ucsd/spendingtracker/view/charts/BarChartProvider.java new file mode 100644 index 0000000..63c6f6b --- /dev/null +++ b/src/main/java/edu/ucsd/spendingtracker/view/charts/BarChartProvider.java @@ -0,0 +1,41 @@ + +package edu.ucsd.spendingtracker.view.charts; +import java.util.Map; + +import edu.ucsd.spendingtracker.model.*; +import javafx.scene.Node; +import javafx.scene.chart.*; + +public class BarChartProvider implements IChartProvider{ + + @Override + public Node createChart(Map data){ + CategoryAxis xAxis = new CategoryAxis(); + NumberAxis yAxis = new NumberAxis(); + BarChart chart = new BarChart<>(xAxis, yAxis); + + XYChart.Series series = new XYChart.Series<>(); + + data.forEach((cat, sum) -> { + series.getData().add(new XYChart.Data<>(cat.name(), sum)); + }); + + chart.getData().add(series); + + for(XYChart.Data entry : series.getData()){ + String color = Category.valueOf(entry.getXValue()).color; + Node bar = entry.getNode(); + if(bar != null){ + bar.setStyle("-fx-bar-fill:" + color + ";"); + } + } + + chart.setLegendVisible(false); + return (Node)chart; + } + + @Override + public String getDisplayName(){ + return "Bar Chart"; + } +} \ No newline at end of file diff --git a/src/main/java/edu/ucsd/spendingtracker/view/charts/IChartProvider.java b/src/main/java/edu/ucsd/spendingtracker/view/charts/IChartProvider.java new file mode 100644 index 0000000..bcb2349 --- /dev/null +++ b/src/main/java/edu/ucsd/spendingtracker/view/charts/IChartProvider.java @@ -0,0 +1,11 @@ +package edu.ucsd.spendingtracker.view.charts; + +import edu.ucsd.spendingtracker.model.Category; +import javafx.scene.Node; +import java.util.Map; + +public interface IChartProvider { + Node createChart(Map data); // dictionary + + String getDisplayName(); +} diff --git a/src/main/java/edu/ucsd/spendingtracker/view/charts/PieChartProvider.java b/src/main/java/edu/ucsd/spendingtracker/view/charts/PieChartProvider.java new file mode 100644 index 0000000..fd08c39 --- /dev/null +++ b/src/main/java/edu/ucsd/spendingtracker/view/charts/PieChartProvider.java @@ -0,0 +1,39 @@ + +package edu.ucsd.spendingtracker.view.charts; +import java.util.Map; + +import edu.ucsd.spendingtracker.model.*; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.scene.Node; +import javafx.scene.chart.*; + +public class PieChartProvider implements IChartProvider{ + + @Override + public Node createChart(Map data){ + + ObservableList list = FXCollections.observableArrayList(); + data.forEach((cat, sum) -> { + list.add(new PieChart.Data(cat.name(), sum)); + }); + + PieChart pieChart = new PieChart(list); + + for(PieChart.Data entry : list){ + String color = Category.valueOf(entry.getName()).color; + Node slice = entry.getNode(); + if(slice != null){ + slice.setStyle("-fx-pie-color:" + color + ";"); + } + } + + pieChart.setLegendVisible(false); + return (Node)pieChart; + } + + @Override + public String getDisplayName(){ + return "Pie Chart"; + } +} diff --git a/src/main/java/edu/ucsd/spendingtracker/view/charts/testing.java b/src/main/java/edu/ucsd/spendingtracker/view/charts/testing.java new file mode 100644 index 0000000..6983227 --- /dev/null +++ b/src/main/java/edu/ucsd/spendingtracker/view/charts/testing.java @@ -0,0 +1,15 @@ +package edu.ucsd.spendingtracker.view.charts; + +import javafx.scene.chart.*; + +public class testing { + + public static void getNametest(){ + PieChart.Data n = new PieChart.Data("thing", 4); + System.out.println(n.getName()); + } + + public static void main(String[] args){ + getNametest(); + } +} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index e85b8df..79db889 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -2,6 +2,8 @@ requires javafx.controls; requires javafx.fxml; requires java.sql; + requires javafx.graphics; + requires javafx.base; opens edu.ucsd.spendingtracker to javafx.fxml; exports edu.ucsd.spendingtracker; diff --git a/target/classes/edu/ucsd/spendingtracker/.DS_Store b/target/classes/edu/ucsd/spendingtracker/.DS_Store new file mode 100644 index 0000000..6feb894 Binary files /dev/null and b/target/classes/edu/ucsd/spendingtracker/.DS_Store differ diff --git a/target/classes/edu/ucsd/spendingtracker/App.class b/target/classes/edu/ucsd/spendingtracker/App.class index ad685f9..10353e4 100644 Binary files a/target/classes/edu/ucsd/spendingtracker/App.class and b/target/classes/edu/ucsd/spendingtracker/App.class differ diff --git a/target/classes/edu/ucsd/spendingtracker/datasource/IDataSource.class b/target/classes/edu/ucsd/spendingtracker/datasource/IDataSource.class new file mode 100644 index 0000000..b287ede Binary files /dev/null and b/target/classes/edu/ucsd/spendingtracker/datasource/IDataSource.class differ diff --git a/target/classes/edu/ucsd/spendingtracker/datasource/InMemoryDataSource.class b/target/classes/edu/ucsd/spendingtracker/datasource/InMemoryDataSource.class index 6c7de2f..8cb9b52 100644 Binary files a/target/classes/edu/ucsd/spendingtracker/datasource/InMemoryDataSource.class and b/target/classes/edu/ucsd/spendingtracker/datasource/InMemoryDataSource.class differ diff --git a/target/classes/edu/ucsd/spendingtracker/datasource/SqlDataSource.class b/target/classes/edu/ucsd/spendingtracker/datasource/SqlDataSource.class new file mode 100644 index 0000000..e7333e6 Binary files /dev/null and b/target/classes/edu/ucsd/spendingtracker/datasource/SqlDataSource.class differ diff --git a/target/classes/edu/ucsd/spendingtracker/model/Expense.class b/target/classes/edu/ucsd/spendingtracker/model/Expense.class index eeb02a3..2b9c5f1 100644 Binary files a/target/classes/edu/ucsd/spendingtracker/model/Expense.class and b/target/classes/edu/ucsd/spendingtracker/model/Expense.class differ diff --git a/target/classes/edu/ucsd/spendingtracker/model/Model.class b/target/classes/edu/ucsd/spendingtracker/model/Model.class index dee4092..0906d80 100644 Binary files a/target/classes/edu/ucsd/spendingtracker/model/Model.class and b/target/classes/edu/ucsd/spendingtracker/model/Model.class differ diff --git a/target/classes/edu/ucsd/spendingtracker/presenter/SpendingPresenter.class b/target/classes/edu/ucsd/spendingtracker/presenter/SpendingPresenter.class index 1efeb89..00cb9fd 100644 Binary files a/target/classes/edu/ucsd/spendingtracker/presenter/SpendingPresenter.class and b/target/classes/edu/ucsd/spendingtracker/presenter/SpendingPresenter.class differ diff --git a/target/classes/edu/ucsd/spendingtracker/presenter/SummaryPresenter.class b/target/classes/edu/ucsd/spendingtracker/presenter/SummaryPresenter.class index d3d99c7..651f705 100644 Binary files a/target/classes/edu/ucsd/spendingtracker/presenter/SummaryPresenter.class and b/target/classes/edu/ucsd/spendingtracker/presenter/SummaryPresenter.class differ diff --git a/target/classes/edu/ucsd/spendingtracker/repository/ExpenseRepository.class b/target/classes/edu/ucsd/spendingtracker/repository/ExpenseRepository.class index a94d74d..20ba5ac 100644 Binary files a/target/classes/edu/ucsd/spendingtracker/repository/ExpenseRepository.class and b/target/classes/edu/ucsd/spendingtracker/repository/ExpenseRepository.class differ diff --git a/target/classes/edu/ucsd/spendingtracker/view/SpendingView.class b/target/classes/edu/ucsd/spendingtracker/view/SpendingView.class index 321c15c..57b9ad7 100644 Binary files a/target/classes/edu/ucsd/spendingtracker/view/SpendingView.class and b/target/classes/edu/ucsd/spendingtracker/view/SpendingView.class differ diff --git a/target/classes/edu/ucsd/spendingtracker/view/SummaryView$1.class b/target/classes/edu/ucsd/spendingtracker/view/SummaryView$1.class new file mode 100644 index 0000000..24b093e Binary files /dev/null and b/target/classes/edu/ucsd/spendingtracker/view/SummaryView$1.class differ diff --git a/target/classes/edu/ucsd/spendingtracker/view/SummaryView.class b/target/classes/edu/ucsd/spendingtracker/view/SummaryView.class index b936786..00aea11 100644 Binary files a/target/classes/edu/ucsd/spendingtracker/view/SummaryView.class and b/target/classes/edu/ucsd/spendingtracker/view/SummaryView.class differ diff --git a/target/classes/edu/ucsd/spendingtracker/view/charts/BarChartProvider.class b/target/classes/edu/ucsd/spendingtracker/view/charts/BarChartProvider.class new file mode 100644 index 0000000..a57d318 Binary files /dev/null and b/target/classes/edu/ucsd/spendingtracker/view/charts/BarChartProvider.class differ diff --git a/target/classes/edu/ucsd/spendingtracker/view/charts/IChartProvider.class b/target/classes/edu/ucsd/spendingtracker/view/charts/IChartProvider.class new file mode 100644 index 0000000..27dc553 Binary files /dev/null and b/target/classes/edu/ucsd/spendingtracker/view/charts/IChartProvider.class differ diff --git a/target/classes/edu/ucsd/spendingtracker/view/charts/PieChartProvider.class b/target/classes/edu/ucsd/spendingtracker/view/charts/PieChartProvider.class new file mode 100644 index 0000000..1965f81 Binary files /dev/null and b/target/classes/edu/ucsd/spendingtracker/view/charts/PieChartProvider.class differ diff --git a/target/classes/edu/ucsd/spendingtracker/view/charts/testing.class b/target/classes/edu/ucsd/spendingtracker/view/charts/testing.class new file mode 100644 index 0000000..fd385b1 Binary files /dev/null and b/target/classes/edu/ucsd/spendingtracker/view/charts/testing.class differ diff --git a/target/classes/module-info.class b/target/classes/module-info.class index 02f23fd..b56aa2a 100644 Binary files a/target/classes/module-info.class and b/target/classes/module-info.class differ