diff --git a/.gitignore b/.gitignore
index 650c91720..1a73a2c8e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,4 +29,7 @@ bin/
.vscode/
### Mac OS ###
-.DS_Store
\ No newline at end of file
+.DS_Store
+
+### API KEY ###
+.env
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 94a25f7f4..35eb1ddfb 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 5e1d8b77c..7fa7754db 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,13 @@
-# Note Application
+# Travel Advisors
+
+## Team Members
+
+- Teddy Yang (teddyyang8)
+- Yasmina Mimassi (yasmatopia)
+- Shirley Zhang (shirleyyzhang)
+- Ray Fang (rayf5372)
+- Sean Woo (seanwoo12)
+## Starter Readme Below
This is a minimal example demonstrating usage of the
password-protected user part of the API used in lab 5.
diff --git a/accessibility-report.md b/accessibility-report.md
new file mode 100644
index 000000000..bb8c4a461
--- /dev/null
+++ b/accessibility-report.md
@@ -0,0 +1,33 @@
+The following paragraphs summarises how features in our program adhere to the Principle of Universal Design.
+
+Principle 1: Equitable Use
+
+The TravelAdvisor provides activity recommendations based on user-selected interests, benefiting all users equally. The activity suggestions are based solely on personal preferences in our profile creating feature, and our interest-selecting feature allows the users to enter any interest they may have, ensuring a diverse group of users can interact equitably. The profile creation and sign-up processes are identical for all users, fostering an equal and inclusive experience.
+
+Principle 2: Flexibility in Use
+
+Users can save places they are interested in and access them later, providing flexibility in how they interact with the app. The save places feature allows users to add different types of information, such as reviews and ratings, based on their preferences. Additionally, the interest-selection feature offers flexibility similar to a Google search, allowing users to input any interest they have.
+
+Principle 3: Simple and Intuitive Use
+
+The user interface follows a straightforward flow—users create a profile, select preferences, and receive personalized recommendations. Clear labels for text fields and buttons make the interface intuitive and easy to use. The platform delivers the intended service efficiently, without requiring extensive effort or comprehension from the user.
+
+Principle 4: Perceptible Information
+
+We use JSwing to present views, combining both textual and visual elements to enhance information accessibility. Labels, buttons, and other interface components are clearly labeled across all views, ensuring that users can easily perceive and understand the information and actions available.
+
+Principle 5: Tolerance in Error
+
+Error messages are displayed if, for instance, users try to create a profile with a username that already exists. This helps users easily identify and correct their mistakes.
+
+Principle 6: Low Physical Effort
+
+All elements of the user interface are designed to be simple to use and minimize repetitive actions. Users can navigate through different views intuitively, with large buttons and clear text fields. Features like the "New Search" button allow users to return to the search view directly after seeing suggested locations, reducing unnecessary steps and physical effort.
+
+Principle 7: Size and Space for Approach and Use
+
+All views in the TravelAdvisor provide a clean and well-organized layout, with adequate spacing between buttons and text fields, ensuring ease of interaction without feeling cramped. A future development goal is to integrate user accessibility tools, such as text-to-speech, to further enhance accessibility for all users.
+
+Our program is designed to be used by anyone interested in exploring new places or discovering interesting parts of their city. Our primary target audience for marketing would be frequent travelers, as they are more likely to be dissatisfied with generic interest recommendations found on platforms like Google Maps and would appreciate a more personalized experience. Another potential target audience could be local explorers—people who enjoy uncovering hidden gems within their own city. These users may be looking for unique recommendations that go beyond the popular tourist spots, tailored specifically to their personal interests. Additionally, our program could appeal to individuals who have specific niche hobbies, such as vinyl lovers seeking second-hand record stores, or history enthusiasts searching for lesser-known historical sites.
+
+When considering the medical model of disability, one demographic that is less likely to use our program would be individuals with visual impairment. In our program, individuals with visual impairments may face challenges since all features currently rely on visual cues, such as reading labels, navigating buttons, and being redirected to external pages. This reliance on visual interaction presents a significant barrier for visually impaired users, who might find it difficult or even impossible to use the program without external assistance.
diff --git a/src/main/java/app/CalendarUseCaseFactory.java b/src/main/java/app/CalendarUseCaseFactory.java
new file mode 100644
index 000000000..60dcc7f63
--- /dev/null
+++ b/src/main/java/app/CalendarUseCaseFactory.java
@@ -0,0 +1,55 @@
+package app;
+
+import interface_adapter.ViewManagerModel;
+import interface_adapter.add_to_calendar.AddToCalendarController;
+import interface_adapter.add_to_calendar.AddToCalendarPresenter;
+import interface_adapter.add_to_calendar.AddToCalendarViewModel;
+import interface_adapter.location.LocationViewModel;
+import use_case.add_to_calendar.AddToCalendarDataAccessInterface;
+import use_case.add_to_calendar.AddToCalendarInputBoundary;
+import use_case.add_to_calendar.AddToCalendarInteractor;
+import use_case.add_to_calendar.AddToCalendarOutputBoundary;
+import view.CalendarView;
+
+/**
+ * This class contains the static factory function for creating the CalendarView.
+ */
+public class CalendarUseCaseFactory {
+
+ /** Prevent instantiation. */
+ private CalendarUseCaseFactory() {
+
+ }
+
+ /**
+ * Factory function for creating the CalendarView.
+ * @param viewManagerModel the ViewManagerModel to inject
+ * @param calendarViewModel the AddToCalendarViewModel to inject
+ * @param calendarDataAccessObject the AddToCalendarDataAccessObject to inject
+ * @param locationViewModel the LocationViewModel to inject
+ * @return the LocationView created for the provided input classes.
+ */
+ public static CalendarView create(ViewManagerModel viewManagerModel,
+ AddToCalendarViewModel calendarViewModel,
+ AddToCalendarDataAccessInterface calendarDataAccessObject,
+ LocationViewModel locationViewModel) {
+ final AddToCalendarController calendarController = createCalendarUseCase(viewManagerModel,
+ calendarViewModel, calendarDataAccessObject, locationViewModel);
+
+ return new CalendarView(calendarViewModel, calendarController);
+ }
+
+ private static AddToCalendarController createCalendarUseCase(
+ ViewManagerModel viewManagerModel,
+ AddToCalendarViewModel calendarViewModel,
+ AddToCalendarDataAccessInterface calendarDataAccessObject,
+ LocationViewModel locationViewModel) {
+ final AddToCalendarOutputBoundary calendarOutputBoundary = new AddToCalendarPresenter(calendarViewModel,
+ viewManagerModel, locationViewModel);
+ final AddToCalendarInputBoundary calendarInteractor = new AddToCalendarInteractor(calendarDataAccessObject,
+ calendarOutputBoundary);
+
+ return new AddToCalendarController(calendarInteractor);
+ }
+
+}
diff --git a/src/main/java/app/LocationUseCaseFactory.java b/src/main/java/app/LocationUseCaseFactory.java
new file mode 100644
index 000000000..6ec20dc30
--- /dev/null
+++ b/src/main/java/app/LocationUseCaseFactory.java
@@ -0,0 +1,62 @@
+package app;
+
+import interface_adapter.ViewManagerModel;
+import interface_adapter.location.LocationController;
+import interface_adapter.location.LocationPresenter;
+import interface_adapter.location.LocationViewModel;
+import interface_adapter.suggestlocation.SuggestedLocationsViewModel;
+import use_case.locations.LocationDataAccessInterface;
+import use_case.locations.LocationsInputBoundary;
+import use_case.locations.LocationsInteractor;
+import use_case.locations.LocationsOutputBoundary;
+import use_case.user_profile.UserProfileDataAccessInterface;
+import view.LocationView;
+
+/**
+ * This class contains the static factory function for creating the LocationView.
+ */
+public class LocationUseCaseFactory {
+
+ /** Prevent instantiation. */
+ private LocationUseCaseFactory() {
+
+ }
+
+ /**
+ * Factory function for creating the LocationView.
+ * @param viewManagerModel the ViewManagerModel to inject
+ * @param locationViewModel the LocationViewModel to inject
+ * @param suggestedLocationsViewModel the SuggestedLocationsViewModel to inject
+ * @param locationDataAccessObject the LocationDataAccessInterface to inject
+ * @param userDataAccessObject the UserProfileDataAccessInterface to inject
+ * @return the LocationView created for the provided input classes.
+ */
+ public static LocationView create(
+ ViewManagerModel viewManagerModel,
+ LocationViewModel locationViewModel,
+ SuggestedLocationsViewModel suggestedLocationsViewModel,
+ LocationDataAccessInterface locationDataAccessObject,
+ UserProfileDataAccessInterface userDataAccessObject) {
+
+ final LocationController locationController = createLocationUseCase(viewManagerModel, locationViewModel,
+ suggestedLocationsViewModel, locationDataAccessObject, userDataAccessObject);
+
+ return new LocationView(locationViewModel, locationController);
+ }
+
+ private static LocationController createLocationUseCase(
+ ViewManagerModel viewManagerModel,
+ LocationViewModel locationViewModel,
+ SuggestedLocationsViewModel suggestedLocationsViewModel,
+ LocationDataAccessInterface locationDataAccessObject,
+ UserProfileDataAccessInterface userDataAccessObject) {
+
+ final LocationsOutputBoundary locationsOutputBoundary = new LocationPresenter(locationViewModel,
+ suggestedLocationsViewModel, viewManagerModel);
+ final LocationsInputBoundary locationInteractor = new LocationsInteractor(locationDataAccessObject,
+ locationsOutputBoundary, userDataAccessObject);
+
+ return new LocationController(locationInteractor);
+ }
+
+}
diff --git a/src/main/java/app/LoginUseCaseFactory.java b/src/main/java/app/LoginUseCaseFactory.java
new file mode 100644
index 000000000..7d58eb83b
--- /dev/null
+++ b/src/main/java/app/LoginUseCaseFactory.java
@@ -0,0 +1,66 @@
+package app;
+
+import interface_adapter.ViewManagerModel;
+import interface_adapter.location.LocationViewModel;
+import interface_adapter.signup.SignupViewModel;
+import interface_adapter.user_profile.UserProfileViewModel;
+import interface_adapter.login.LoginController;
+import interface_adapter.login.LoginPresenter;
+import interface_adapter.login.LoginViewModel;
+import use_case.login.LoginInputBoundary;
+import use_case.login.LoginInteractor;
+import use_case.login.LoginOutputBoundary;
+import use_case.login.LoginUserDataAccessInterface;
+import view.LoginView;
+
+/**
+ * This class contains the static factory function for creating the LoginView.
+ */
+public final class LoginUseCaseFactory {
+
+ /** Prevent instantiation. */
+ private LoginUseCaseFactory() {
+
+ }
+
+ /**
+ * Factory function for creating the LoginView.
+ * @param viewManagerModel the ViewManagerModel to inject into the LoginView
+ * @param loginViewModel the LoginViewModel to inject into the LoginView
+ * @param userProfileViewModel the LoggedInViewModel to inject into the LoginView
+ * @param locationViewModel the LocationViewModel to inject into the LoginView
+ * @param userDataAccessObject the LoginUserDataAccessInterface to inject into the LoginView
+ * @param signupViewModel the SignupViewModel to inject into the LoginView
+ * @return the LoginView created for the provided input classes
+ */
+ public static LoginView create(
+ ViewManagerModel viewManagerModel,
+ LoginViewModel loginViewModel,
+ UserProfileViewModel userProfileViewModel,
+ LocationViewModel locationViewModel,
+ LoginUserDataAccessInterface userDataAccessObject,
+ SignupViewModel signupViewModel) {
+
+ final LoginController loginController = createLoginUseCase(viewManagerModel, loginViewModel,
+ userProfileViewModel, locationViewModel, userDataAccessObject, signupViewModel);
+ return new LoginView(loginViewModel, loginController);
+
+ }
+
+ private static LoginController createLoginUseCase(
+ ViewManagerModel viewManagerModel,
+ LoginViewModel loginViewModel,
+ UserProfileViewModel userProfileViewModel,
+ LocationViewModel locationViewModel,
+ LoginUserDataAccessInterface userDataAccessObject,
+ SignupViewModel signUpViewModel) {
+
+ // Notice how we pass this method's parameters to the Presenter.
+ final LoginOutputBoundary loginOutputBoundary = new LoginPresenter(viewManagerModel,
+ userProfileViewModel, loginViewModel, locationViewModel, signUpViewModel);
+ final LoginInputBoundary loginInteractor = new LoginInteractor(
+ userDataAccessObject, loginOutputBoundary);
+
+ return new LoginController(loginInteractor);
+ }
+}
diff --git a/src/main/java/app/MainNoteApplication.java b/src/main/java/app/MainNoteApplication.java
deleted file mode 100644
index c37860156..000000000
--- a/src/main/java/app/MainNoteApplication.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package app;
-
-import data_access.DBNoteDataAccessObject;
-import use_case.note.NoteDataAccessInterface;
-
-/**
- * An application where we can view and add to a note stored by a user.
- *
- * This is a minimal example of using the password-protected user API from lab 5,
- * but demonstrating the endpoint allowing you to store an arbitrary JSON object.
- * This functionality could be used in any project where your team wants to persist
- * data which is then accessible across devices.
- *
The code is intentionally somewhat incomplete to leave work to be done if your
- * team were to choose to work on a project which would require similar functionality.
- * For example, we have intentionally not created a full "Note" entity here, but
- * rather just represented a note as a string.
- *
- * The ViewManager code has also been removed, since this minimal program only requires a single
- * view. Your team may wish to bring back the ViewManager or make your own implementation of supporting
- * switching between views depending on your project.
- */
-public class MainNoteApplication {
-
- /**
- * The main entry point of the application.
- *
- * The program will show you the note currently saved in the system.
- * You are able to edit it and then save it to the system. You can refresh
- * to update the note to reflect what was saved most recently. This
- * uses the API from lab, so there is one database storing the note,
- * which means that if anyone updates the note, that is what you will
- * see when you refresh.
- *
- * You can generalize the code to allow you to
- * specify which "user" to save the note for, which will allow your team
- * to store information specific to your team which is password-protected.
- * The username and password used in this application are currently for
- * user jonathan_calver2, but you can change that. As you did in lab 3,
- * you will likely want to store password information locally rather than
- * in your repo. Or you can require the user to enter their credentials
- * in your application; it just depends on what your program's main
- * functionality.
- *
- * @param args commandline arguments are ignored
- */
- public static void main(String[] args) {
-
- // create the data access and inject it into our builder!
- final NoteDataAccessInterface noteDataAccess = new DBNoteDataAccessObject();
-
- final NoteAppBuilder builder = new NoteAppBuilder();
- builder.addNoteDAO(noteDataAccess)
- .addNoteView()
- .addNoteUseCase().build().setVisible(true);
- }
-}
diff --git a/src/main/java/app/MainWithDB.java b/src/main/java/app/MainWithDB.java
new file mode 100644
index 000000000..d6d5ff536
--- /dev/null
+++ b/src/main/java/app/MainWithDB.java
@@ -0,0 +1,111 @@
+package app;
+
+import data_access.DBCoordinatesDataAccessObject;
+import java.awt.*;
+
+import javax.swing.*;
+
+import data_access.DBLocationDataAccessObject;
+import data_access.InMemoryCalendarDataAccessObject;
+import data_access.InMemoryUserDataAccessObject;
+import data_access.InMemoryCalendarDataAccessObject;
+import entity.SuggestedPlaceFactory;
+import interface_adapter.ViewManagerModel;
+import interface_adapter.add_to_calendar.AddToCalendarViewModel;
+import interface_adapter.location.LocationViewModel;
+import interface_adapter.selectedlocation.SelectedLocationsViewModel;
+import interface_adapter.suggestlocation.SuggestedLocationsViewModel;
+import view.LocationView;
+import view.SelectedLocationView;
+import view.SuggestedLocationsView;
+import view.ViewManager;
+
+import javax.swing.*;
+import java.awt.*;
+import interface_adapter.login.LoginViewModel;
+import interface_adapter.signup.SignupViewModel;
+import interface_adapter.suggestlocation.SuggestedLocationsViewModel;
+import view.CalendarView;
+import view.LocationView;
+import view.SuggestedLocationsView;
+import view.ViewManager;
+import interface_adapter.user_profile.UserProfileViewModel;
+import view.*;
+
+/**
+ * The version of Main with an external database used to persist user data.
+ */
+public class MainWithDB {
+
+ /**
+ * The main method for starting the program with an external database used to persist user data.
+ * @param args input to main
+ */
+ public static void main(String[] args) {
+ // Build the main program window, the main panel containing the
+ // various cards, and the layout, and stitch them together.
+
+ // The main application window.
+ final JFrame application = new JFrame("Location Suggester");
+ application.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+
+ final CardLayout cardLayout = new CardLayout();
+
+ final JPanel views = new JPanel(cardLayout);
+ application.add(views);
+
+ final ViewManagerModel viewManagerModel = new ViewManagerModel();
+ new ViewManager(views, cardLayout, viewManagerModel);
+
+ final LoginViewModel loginViewModel = new LoginViewModel();
+ final SignupViewModel signupViewModel = new SignupViewModel();
+ final LocationViewModel locationViewModel = new LocationViewModel();
+ final SuggestedLocationsViewModel suggestedLocationsViewModel = new SuggestedLocationsViewModel();
+ final AddToCalendarViewModel calendarViewModel = new AddToCalendarViewModel();
+ final SelectedLocationsViewModel selectedLocationsViewModel = new SelectedLocationsViewModel();
+ final UserProfileViewModel userProfileViewModel = new UserProfileViewModel();
+ // add any future view models here in the same way
+
+ final DBLocationDataAccessObject locationDataAccessObject = new DBLocationDataAccessObject(
+ new SuggestedPlaceFactory());
+ final InMemoryCalendarDataAccessObject calendarDataAccessObject = new InMemoryCalendarDataAccessObject();
+ final DBCoordinatesDataAccessObject coordinatesDataAccessObject = new DBCoordinatesDataAccessObject();
+ final InMemoryUserDataAccessObject userDataAccessObject = new InMemoryUserDataAccessObject();
+
+ final SignupView signupView = SignupUseCaseFactory.create(viewManagerModel, loginViewModel,
+ signupViewModel, userDataAccessObject);
+ views.add(signupView, signupView.getViewName());
+
+ final LoginView loginView = LoginUseCaseFactory.create(viewManagerModel, loginViewModel,
+ userProfileViewModel, locationViewModel, userDataAccessObject, signupViewModel);
+ views.add(loginView, loginView.getViewName());
+
+ final LocationView locationView = LocationUseCaseFactory.create(viewManagerModel, locationViewModel,
+ suggestedLocationsViewModel, locationDataAccessObject, userDataAccessObject);
+ views.add(locationView, locationView.getViewName());
+
+ final SuggestedLocationsView suggestedLocationsView = SuggestedLocationsUseCaseFactory.create(viewManagerModel,
+ suggestedLocationsViewModel, calendarViewModel, selectedLocationsViewModel, coordinatesDataAccessObject,
+ calendarDataAccessObject, locationViewModel);
+ views.add(suggestedLocationsView, suggestedLocationsView.getViewName());
+
+ final SelectedLocationView selectedLocationView = SelectedLocationsUseCaseFactory.create(viewManagerModel,
+ selectedLocationsViewModel, coordinatesDataAccessObject, locationViewModel);
+ views.add(selectedLocationView, selectedLocationView.getViewName());
+
+ final CalendarView calendarView = CalendarUseCaseFactory.create(viewManagerModel, calendarViewModel,
+ calendarDataAccessObject, locationViewModel);
+ views.add(calendarView, calendarView.getViewName());
+
+ final UserProfileView userProfileView = UserProfileUseCaseFactory.create(viewManagerModel,
+ userProfileViewModel, userDataAccessObject);
+ views.add(userProfileView, userProfileView.getViewName());
+
+ viewManagerModel.setState(signupView.getViewName());
+ viewManagerModel.firePropertyChanged();
+
+ application.pack();
+ application.setVisible(true);
+ }
+}
+
diff --git a/src/main/java/app/NoteAppBuilder.java b/src/main/java/app/NoteAppBuilder.java
deleted file mode 100644
index a68cb9ad6..000000000
--- a/src/main/java/app/NoteAppBuilder.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package app;
-
-import javax.swing.JFrame;
-import javax.swing.WindowConstants;
-
-import interface_adapter.note.NoteController;
-import interface_adapter.note.NotePresenter;
-import interface_adapter.note.NoteViewModel;
-import use_case.note.NoteDataAccessInterface;
-import use_case.note.NoteInteractor;
-import use_case.note.NoteOutputBoundary;
-import view.NoteView;
-
-/**
- * Builder for the Note Application.
- */
-public class NoteAppBuilder {
- public static final int HEIGHT = 300;
- public static final int WIDTH = 400;
- private NoteDataAccessInterface noteDAO;
- private NoteViewModel noteViewModel = new NoteViewModel();
- private NoteView noteView;
- private NoteInteractor noteInteractor;
-
- /**
- * Sets the NoteDAO to be used in this application.
- * @param noteDataAccess the DAO to use
- * @return this builder
- */
- public NoteAppBuilder addNoteDAO(NoteDataAccessInterface noteDataAccess) {
- noteDAO = noteDataAccess;
- return this;
- }
-
- /**
- * Creates the objects for the Note Use Case and connects the NoteView to its
- * controller.
- *
This method must be called after addNoteView!
- * @return this builder
- * @throws RuntimeException if this method is called before addNoteView
- */
- public NoteAppBuilder addNoteUseCase() {
- final NoteOutputBoundary noteOutputBoundary = new NotePresenter(noteViewModel);
- noteInteractor = new NoteInteractor(
- noteDAO, noteOutputBoundary);
-
- final NoteController controller = new NoteController(noteInteractor);
- if (noteView == null) {
- throw new RuntimeException("addNoteView must be called before addNoteUseCase");
- }
- noteView.setNoteController(controller);
- return this;
- }
-
- /**
- * Creates the NoteView and underlying NoteViewModel.
- * @return this builder
- */
- public NoteAppBuilder addNoteView() {
- noteViewModel = new NoteViewModel();
- noteView = new NoteView(noteViewModel);
- return this;
- }
-
- /**
- * Builds the application.
- * @return the JFrame for the application
- */
- public JFrame build() {
- final JFrame frame = new JFrame();
- frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
- frame.setTitle("Note Application");
- frame.setSize(WIDTH, HEIGHT);
-
- frame.add(noteView);
-
- // refresh so that the note will be visible when we start the program
- noteInteractor.executeRefresh();
-
- return frame;
-
- }
-}
diff --git a/src/main/java/app/SelectedLocationsUseCaseFactory.java b/src/main/java/app/SelectedLocationsUseCaseFactory.java
new file mode 100644
index 000000000..de2b0d3b4
--- /dev/null
+++ b/src/main/java/app/SelectedLocationsUseCaseFactory.java
@@ -0,0 +1,58 @@
+package app;
+
+import data_access.DBCoordinatesDataAccessObject;
+import interface_adapter.ViewManagerModel;
+import interface_adapter.location.LocationViewModel;
+import interface_adapter.selectedlocation.SelectedLocationsController;
+import interface_adapter.selectedlocation.SelectedLocationsPresenter;
+import interface_adapter.selectedlocation.SelectedLocationsViewModel;
+import interface_adapter.suggestlocation.SuggestedLocationsViewModel;
+import use_case.selected_locations.SelectedLocationsInputBoundary;
+import use_case.selected_locations.SelectedLocationsInteractor;
+import use_case.selected_locations.SelectedLocationsOutputBoundary;
+import view.SelectedLocationView;
+
+/**
+ * This class contains the static factory function for creating the SelectedLocationView.
+ */
+public class SelectedLocationsUseCaseFactory {
+
+ /** Prevent instantiation. */
+ private SelectedLocationsUseCaseFactory() {
+
+ }
+
+ /**
+ * Factory function for creating the LocationView.
+ * @param viewManagerModel the ViewManagerModel to inject
+ * @param selectedLocationsViewModel the SelectedLocationsViewModel to inject
+ * @param locationViewModel the LocationViewModel to inject
+ * @param coordinatesDataAccessObject the DBCoordinatesDataAccessObject to inject.
+ * @return the LocationView created for the provided input classes.
+ */
+ public static SelectedLocationView create(
+ ViewManagerModel viewManagerModel,
+ SelectedLocationsViewModel selectedLocationsViewModel,
+ DBCoordinatesDataAccessObject coordinatesDataAccessObject,
+ LocationViewModel locationViewModel) {
+
+ final SelectedLocationsController selectedLocationsController =
+ createSelectedLocationUseCase(viewManagerModel, selectedLocationsViewModel,
+ coordinatesDataAccessObject, locationViewModel);
+ return new SelectedLocationView(selectedLocationsViewModel,
+ selectedLocationsController);
+ }
+
+ private static SelectedLocationsController createSelectedLocationUseCase(
+ ViewManagerModel viewManagerModel,
+ SelectedLocationsViewModel selectedLocationsViewModel,
+ DBCoordinatesDataAccessObject coordinatesDataAccessObject,
+ LocationViewModel locationViewModel) {
+ final SelectedLocationsOutputBoundary selectedLocationsOutputBoundary = new SelectedLocationsPresenter(
+ selectedLocationsViewModel, viewManagerModel, locationViewModel);
+ final SelectedLocationsInputBoundary selectedLocationsInteractor = new SelectedLocationsInteractor(
+ selectedLocationsOutputBoundary, coordinatesDataAccessObject);
+
+ return new SelectedLocationsController(selectedLocationsInteractor);
+ }
+}
diff --git a/src/main/java/app/SignupUseCaseFactory.java b/src/main/java/app/SignupUseCaseFactory.java
new file mode 100644
index 000000000..fafc1303b
--- /dev/null
+++ b/src/main/java/app/SignupUseCaseFactory.java
@@ -0,0 +1,61 @@
+package app;
+
+import entity.UserFactory;
+import interface_adapter.login.LoginViewModel;
+import interface_adapter.signup.SignupController;
+import interface_adapter.signup.SignupPresenter;
+import interface_adapter.signup.SignupViewModel;
+import interface_adapter.ViewManagerModel;
+import use_case.signup.SignupInputBoundary;
+import use_case.signup.SignupInteractor;
+import use_case.signup.SignupOutputBoundary;
+import use_case.signup.SignupUserDataAccessInterface;
+import view.SignupView;
+
+/**
+ * Factory for creating the Signup use case.
+ */
+public final class SignupUseCaseFactory {
+
+ /** Prevent instantiation. */
+ private SignupUseCaseFactory() {
+
+ }
+
+ /**
+ * Factory method for creating the SignupView.
+ *
+ * @param viewManagerModel the ViewManagerModel
+ * @param loginViewModel the log in view model
+ * @param signupViewModel the sign up view model
+ * @param userDataAccessObject the user DAO
+ * @return a SignupView instance
+ */
+ public static SignupView create(ViewManagerModel viewManagerModel, LoginViewModel loginViewModel,
+ SignupViewModel signupViewModel,
+ SignupUserDataAccessInterface userDataAccessObject) {
+
+ final SignupController signupController = createUserSignupUseCase(viewManagerModel, signupViewModel,
+ loginViewModel, userDataAccessObject);
+ return new SignupView(signupController, signupViewModel);
+ }
+
+ private static SignupController createUserSignupUseCase(ViewManagerModel viewManagerModel,
+ SignupViewModel signupViewModel,
+ LoginViewModel loginViewModel,
+ SignupUserDataAccessInterface userDataAccessObject) {
+
+ // Notice how we pass this method's parameters to the Presenter.
+ final SignupOutputBoundary signupOutputBoundary = new SignupPresenter(viewManagerModel,
+ signupViewModel, loginViewModel);
+
+ final UserFactory userFactory = new UserFactory();
+
+ final SignupInputBoundary userSignupInteractor = new SignupInteractor(
+ userDataAccessObject, signupOutputBoundary, userFactory);
+
+ return new SignupController(userSignupInteractor);
+ }
+}
+
+
diff --git a/src/main/java/app/SuggestedLocationsUseCaseFactory.java b/src/main/java/app/SuggestedLocationsUseCaseFactory.java
new file mode 100644
index 000000000..4006503a0
--- /dev/null
+++ b/src/main/java/app/SuggestedLocationsUseCaseFactory.java
@@ -0,0 +1,117 @@
+package app;
+
+import interface_adapter.ViewManagerModel;
+import interface_adapter.add_to_calendar.AddToCalendarPresenter;
+import interface_adapter.location.LocationViewModel;
+import interface_adapter.selectedlocation.SelectedLocationsPresenter;
+import interface_adapter.selectedlocation.SelectedLocationsViewModel;
+import interface_adapter.add_to_calendar.AddToCalendarController;
+import interface_adapter.add_to_calendar.AddToCalendarViewModel;
+import interface_adapter.suggestlocation.SuggestedLocationsController;
+import interface_adapter.suggestlocation.SuggestedLocationsPresenter;
+import interface_adapter.suggestlocation.SuggestedLocationsViewModel;
+import use_case.add_to_calendar.AddToCalendarDataAccessInterface;
+import use_case.add_to_calendar.AddToCalendarInputBoundary;
+import use_case.add_to_calendar.AddToCalendarInteractor;
+import use_case.add_to_calendar.AddToCalendarOutputBoundary;
+import use_case.selected_locations.CoordinateDataAccessInterface;
+import use_case.selected_locations.SelectedLocationsInputBoundary;
+import use_case.selected_locations.SelectedLocationsInteractor;
+import use_case.selected_locations.SelectedLocationsOutputBoundary;
+import use_case.suggested_locations.SuggestedLocationsInteractor;
+import use_case.suggested_locations.SuggestedLocationsInputBoundary;
+import interface_adapter.selectedlocation.SelectedLocationsController;
+import use_case.suggested_locations.SuggestedLocationsOutputBoundary;
+import view.SuggestedLocationsView;
+
+/**
+ * This class contains the static factory function for creating the SuggestedLocationView.
+ */
+public class SuggestedLocationsUseCaseFactory {
+
+ /** Prevent instantiation. */
+ private SuggestedLocationsUseCaseFactory() {
+
+ }
+
+ /**
+ * Factory function for creating the LocationView.
+ * @param viewManagerModel the ViewManagerModel to inject
+ * @param suggestedLocationsViewModel the SuggestedLocationsViewModel to inject
+ * @param selectedLocationsViewModel the SelectedLocationsViewModel to inject
+ * @param calendarViewModel the CalendarViewModel to inject
+ * @param coordinateDataAccessObject the CoordinateDataAccessInterface to inject
+ * @param calendarDataAccessObject the AddToCalendarDataAccessInterface to inject
+ * @param locationViewModel the LocationViewModel to inject
+ * @return the LocationView created for the provided input classes.
+ */
+ public static SuggestedLocationsView create(
+ ViewManagerModel viewManagerModel,
+ SuggestedLocationsViewModel suggestedLocationsViewModel,
+ AddToCalendarViewModel calendarViewModel,
+ SelectedLocationsViewModel selectedLocationsViewModel,
+ CoordinateDataAccessInterface coordinateDataAccessObject,
+ AddToCalendarDataAccessInterface calendarDataAccessObject,
+ LocationViewModel locationViewModel) {
+
+ final SelectedLocationsController selectedLocationController = createSelectedLocationUseCase(viewManagerModel,
+ selectedLocationsViewModel, coordinateDataAccessObject, locationViewModel);
+
+ final SuggestedLocationsController suggestedLocationsController = createSuggestedLocationUseCase(
+ viewManagerModel,
+ suggestedLocationsViewModel,
+ calendarViewModel,
+ selectedLocationsViewModel);
+
+ final AddToCalendarController calendarController = createAddToCalendarUseCase(viewManagerModel,
+ calendarViewModel, calendarDataAccessObject, locationViewModel);
+
+ return new SuggestedLocationsView(suggestedLocationsViewModel, suggestedLocationsController, calendarViewModel,
+ calendarController, selectedLocationsViewModel, selectedLocationController);
+ }
+
+ private static SuggestedLocationsController createSuggestedLocationUseCase(
+ ViewManagerModel viewManagerModel,
+ SuggestedLocationsViewModel suggestedLocationsViewModel,
+ AddToCalendarViewModel calendarViewModel,
+ SelectedLocationsViewModel selectedLocationsViewModel) {
+
+ final SuggestedLocationsOutputBoundary suggestedLocationsOutputBoundary = new SuggestedLocationsPresenter(
+ viewManagerModel, suggestedLocationsViewModel, calendarViewModel, selectedLocationsViewModel);
+
+ final SuggestedLocationsInputBoundary suggestedLocationsInteractor = new SuggestedLocationsInteractor(
+ suggestedLocationsOutputBoundary);
+
+ return new SuggestedLocationsController(suggestedLocationsInteractor);
+ }
+
+ private static SelectedLocationsController createSelectedLocationUseCase(
+ ViewManagerModel viewManagerModel,
+ SelectedLocationsViewModel selectedLocationsViewModel,
+ CoordinateDataAccessInterface coordinatesDataAccessObject,
+ LocationViewModel locationViewModel) {
+ final SelectedLocationsOutputBoundary selectedLocationsOutputBoundary = new SelectedLocationsPresenter(
+ selectedLocationsViewModel, viewManagerModel, locationViewModel);
+ final SelectedLocationsInputBoundary selectedLocationsInteractor = new SelectedLocationsInteractor(
+ selectedLocationsOutputBoundary, coordinatesDataAccessObject);
+
+ return new SelectedLocationsController(selectedLocationsInteractor);
+ }
+
+ private static AddToCalendarController createAddToCalendarUseCase(
+ ViewManagerModel viewManagerModel,
+ AddToCalendarViewModel calendarViewModel,
+ AddToCalendarDataAccessInterface calendarDataAccessObject,
+ LocationViewModel locationViewModel) {
+
+ final AddToCalendarOutputBoundary calendarOutputBoundary = new AddToCalendarPresenter(calendarViewModel,
+ viewManagerModel, locationViewModel);
+
+ final AddToCalendarInputBoundary calendarInteractor = new AddToCalendarInteractor(calendarDataAccessObject,
+ calendarOutputBoundary);
+
+ return new AddToCalendarController(calendarInteractor);
+ }
+}
+
+
diff --git a/src/main/java/app/UserProfileUseCaseFactory.java b/src/main/java/app/UserProfileUseCaseFactory.java
new file mode 100644
index 000000000..8b89f5dc6
--- /dev/null
+++ b/src/main/java/app/UserProfileUseCaseFactory.java
@@ -0,0 +1,54 @@
+package app;
+
+import data_access.InMemoryUserDataAccessObject;
+import interface_adapter.ViewManagerModel;
+import interface_adapter.user_profile.UserProfileController;
+import interface_adapter.user_profile.UserProfilePresenter;
+import interface_adapter.user_profile.UserProfileViewModel;
+import use_case.user_profile.UserProfileDataAccessInterface;
+import use_case.user_profile.UserProfileInputBoundary;
+import use_case.user_profile.UserProfileInteractor;
+import use_case.user_profile.UserProfileOutputBoundary;
+import view.SuggestedLocationsView;
+import view.UserProfileView;
+
+/**
+ * Factory for creating the User Profile use case.
+ */
+public final class UserProfileUseCaseFactory {
+
+ /** Prevent instantiation. */
+ private UserProfileUseCaseFactory() {
+ }
+
+ /**
+ * Factory function for creating the LocationView.
+ * @param viewManagerModel the ViewManagerModel to inject
+ * @param userProfileViewModel the SuggestedLocationsViewModel to inject
+ * @param userDataAccessObject the In memory user data access object
+ * @return the LocationView created for the provided input classes.
+ */
+ public static UserProfileView create(
+ ViewManagerModel viewManagerModel,
+ UserProfileViewModel userProfileViewModel,
+ UserProfileDataAccessInterface userDataAccessObject) {
+
+ final UserProfileController userProfileController = createUserProfileUseCase(viewManagerModel,
+ userProfileViewModel, userDataAccessObject);
+
+ return new UserProfileView(userProfileController, userProfileViewModel);
+ }
+
+ private static UserProfileController createUserProfileUseCase(
+ ViewManagerModel viewManagerModel,
+ UserProfileViewModel userProfileViewModel,
+ UserProfileDataAccessInterface userDataAccessObject) {
+
+ final UserProfileOutputBoundary userProfileOutputBoundary = new UserProfilePresenter(
+ viewManagerModel, userProfileViewModel);
+ final UserProfileInputBoundary userProfileInteractor = new UserProfileInteractor(userDataAccessObject,
+ userProfileOutputBoundary);
+
+ return new UserProfileController(userProfileInteractor);
+ }
+}
diff --git a/src/main/java/data_access/DBCoordinatesDataAccessObject.java b/src/main/java/data_access/DBCoordinatesDataAccessObject.java
new file mode 100644
index 000000000..1581e28a1
--- /dev/null
+++ b/src/main/java/data_access/DBCoordinatesDataAccessObject.java
@@ -0,0 +1,64 @@
+package data_access;
+
+import java.io.IOException;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import entity.Place;
+import okhttp3.HttpUrl;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import use_case.DataAccessException;
+import use_case.selected_locations.CoordinateDataAccessInterface;
+
+/**
+ * The DAO for accessing places using Google Places API.
+ */
+public class DBCoordinatesDataAccessObject implements CoordinateDataAccessInterface {
+ private static final String API_KEY = System.getenv("API_KEY");
+
+ @Override
+ public String searchCoordinates(Place place) throws DataAccessException {
+ final OkHttpClient client = new OkHttpClient().newBuilder()
+ .build();
+ final HttpUrl url = HttpUrl.parse("https://maps.googleapis"
+ + ".com/maps/api/geocode/json").newBuilder()
+ .addQueryParameter("key", API_KEY)
+ .addQueryParameter("address", place.getAddress())
+ .build();
+ // POST METHOD
+ final Request request = new Request.Builder()
+ .url(url)
+ .build();
+ try (Response response = client.newCall(request).execute()) {
+ final JSONObject responseBody = new JSONObject(response.body().string());
+
+ if (responseBody.has("results")) {
+ final StringBuilder coordinates = new StringBuilder();
+ final JSONArray jsonArray = responseBody.getJSONArray("results");
+ final JSONObject firstResult = jsonArray.getJSONObject(0);
+ final JSONObject geometry = firstResult.getJSONObject("geometry");
+ final JSONObject location = geometry.getJSONObject("location");
+
+ final double lat = location.getDouble("lat");
+ final double lng = location.getDouble("lng");
+
+ coordinates.append(lat).append(",").append(lng);
+ return coordinates.toString();
+ }
+ else if (responseBody.has("error_message")) {
+ throw new DataAccessException("API Error: " + responseBody.getJSONObject("error_message")
+ .getString("message"));
+ }
+ else {
+ throw new DataAccessException("Unexpected API response format.");
+ }
+ }
+ catch (IOException | JSONException | DataAccessException ex) {
+ throw new DataAccessException(ex.getMessage());
+ }
+ }
+}
diff --git a/src/main/java/data_access/DBLocationDataAccessObject.java b/src/main/java/data_access/DBLocationDataAccessObject.java
new file mode 100644
index 000000000..c1ec0328d
--- /dev/null
+++ b/src/main/java/data_access/DBLocationDataAccessObject.java
@@ -0,0 +1,94 @@
+package data_access;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import entity.Place;
+import entity.PlaceFactory;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+import use_case.DataAccessException;
+import use_case.locations.LocationDataAccessInterface;
+
+/**
+ * The DAO for accessing places using Google Places API.
+ */
+public class DBLocationDataAccessObject implements LocationDataAccessInterface {
+ private static final String API_HEADER = "X-Goog-Api-Key";
+ private static final String API_FIELD = "X-Goog-FieldMask";
+ private static final String FIELDS = "places.displayName,places.formattedAddress";
+ private static final String CONTENT_TYPE_LABEL = "Content-Type";
+ private static final String CONTENT_TYPE_JSON = "application/json";
+ private static final String API_KEY = System.getenv("API_KEY");
+ private static final String API_URL = "https://places.googleapis.com/v1/places:searchText";
+ private static final String LEFT_ARROW = "<";
+ private static final String RIGHT_ARROW = ">";
+ private final PlaceFactory placeFactory;
+
+ public DBLocationDataAccessObject(PlaceFactory placeFactory) {
+ this.placeFactory = placeFactory;
+ }
+
+ @Override
+ public List searchLocation(String address, String locationType) throws DataAccessException {
+ final OkHttpClient client = new OkHttpClient().newBuilder()
+ .build();
+
+ final JSONObject requestBody = new JSONObject();
+ requestBody.put("textQuery", locationType + " near " + address);
+ final RequestBody body = RequestBody.create(
+ requestBody.toString(), MediaType.parse(CONTENT_TYPE_JSON));
+ // POST METHOD
+ final Request request = new Request.Builder()
+ .url(API_URL)
+ .post(body)
+ .addHeader(CONTENT_TYPE_LABEL, CONTENT_TYPE_JSON)
+ .addHeader(API_HEADER, API_KEY)
+ .addHeader(API_FIELD, FIELDS)
+ .build();
+ try (Response response = client.newCall(request).execute()) {
+
+ final JSONObject responseBody = new JSONObject(response.body().string());
+
+ if (responseBody.has("places")) {
+ final StringBuilder places = new StringBuilder();
+ final JSONArray jsonArray = responseBody.getJSONArray("places");
+ for (int i = 0; i < jsonArray.length(); i++) {
+ final JSONObject jsonObject =
+ jsonArray.getJSONObject(i);
+ places.append(jsonObject.getString("formattedAddress")).append(RIGHT_ARROW).append(jsonObject
+ .getJSONObject("displayName").getString("text")).append(LEFT_ARROW);
+ }
+ final String placesString = places.toString();
+
+ final String[] locationsList = placesString.split(LEFT_ARROW);
+ final List suggestedPlaces = new ArrayList<>();
+ for (String location : locationsList) {
+ final Place place = placeFactory.create(location.split(RIGHT_ARROW)[1],
+ location.split(RIGHT_ARROW)[0]);
+ suggestedPlaces.add(place);
+ }
+ return suggestedPlaces;
+
+ }
+ else if (responseBody.has("error")) {
+ throw new DataAccessException("API Error: " + responseBody.getJSONObject("error").getString("message"));
+ }
+ else {
+ throw new DataAccessException("Unexpected API response format.");
+ }
+ }
+ catch (IOException | JSONException | DataAccessException ex) {
+ throw new DataAccessException(ex.getMessage());
+ }
+ }
+
+}
diff --git a/src/main/java/data_access/DBNoteDataAccessObject.java b/src/main/java/data_access/DBNoteDataAccessObject.java
deleted file mode 100644
index dadb0cab0..000000000
--- a/src/main/java/data_access/DBNoteDataAccessObject.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package data_access;
-
-import java.io.IOException;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import entity.User;
-import okhttp3.MediaType;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.RequestBody;
-import okhttp3.Response;
-import use_case.note.DataAccessException;
-import use_case.note.NoteDataAccessInterface;
-
-/**
- * The DAO for accessing notes stored in the database.
- *
This class demonstrates how your group can use the password-protected user
- * endpoints of the API used in lab 5 to store persistent data in your program.
- *
- *
You can also refer to the lab 5 code for signing up a new user and other use cases.
- *
- * See
- *
- * the documentation
- * of the API for more details.
- */
-public class DBNoteDataAccessObject implements NoteDataAccessInterface {
- private static final int SUCCESS_CODE = 200;
- private static final int CREDENTIAL_ERROR = 401;
- private static final String CONTENT_TYPE_LABEL = "Content-Type";
- private static final String CONTENT_TYPE_JSON = "application/json";
- private static final String STATUS_CODE_LABEL = "status_code";
- private static final String USERNAME = "username";
- private static final String PASSWORD = "password";
- private static final String MESSAGE = "message";
-
- @Override
- public String saveNote(User user, String note) throws DataAccessException {
- final OkHttpClient client = new OkHttpClient().newBuilder()
- .build();
-
- // POST METHOD
- final MediaType mediaType = MediaType.parse(CONTENT_TYPE_JSON);
- final JSONObject requestBody = new JSONObject();
- requestBody.put(USERNAME, user.getName());
- requestBody.put(PASSWORD, user.getPassword());
- final JSONObject extra = new JSONObject();
- extra.put("note", note);
- requestBody.put("info", extra);
- final RequestBody body = RequestBody.create(requestBody.toString(), mediaType);
- final Request request = new Request.Builder()
- .url("http://vm003.teach.cs.toronto.edu:20112/modifyUserInfo")
- .method("PUT", body)
- .addHeader(CONTENT_TYPE_LABEL, CONTENT_TYPE_JSON)
- .build();
- try {
- final Response response = client.newCall(request).execute();
-
- final JSONObject responseBody = new JSONObject(response.body().string());
-
- if (responseBody.getInt(STATUS_CODE_LABEL) == SUCCESS_CODE) {
- return loadNote(user);
- }
- else if (responseBody.getInt(STATUS_CODE_LABEL) == CREDENTIAL_ERROR) {
- throw new DataAccessException("message could not be found or password was incorrect");
- }
- else {
- throw new DataAccessException("database error: " + responseBody.getString(MESSAGE));
- }
- }
- catch (IOException | JSONException ex) {
- throw new DataAccessException(ex.getMessage());
- }
- }
-
- @Override
- public String loadNote(User user) throws DataAccessException {
- // Make an API call to get the user object.
- final String username = user.getName();
- final OkHttpClient client = new OkHttpClient().newBuilder().build();
- final Request request = new Request.Builder()
- .url(String.format("http://vm003.teach.cs.toronto.edu:20112/user?username=%s", username))
- .addHeader("Content-Type", CONTENT_TYPE_JSON)
- .build();
- try {
- final Response response = client.newCall(request).execute();
-
- final JSONObject responseBody = new JSONObject(response.body().string());
-
- if (responseBody.getInt(STATUS_CODE_LABEL) == SUCCESS_CODE) {
- final JSONObject userJSONObject = responseBody.getJSONObject("user");
- final JSONObject data = userJSONObject.getJSONObject("info");
- return data.getString("note");
- }
- else {
- throw new DataAccessException(responseBody.getString(MESSAGE));
- }
- }
- catch (IOException | JSONException ex) {
- throw new RuntimeException(ex);
- }
- }
-}
diff --git a/src/main/java/data_access/InMemoryCalendarDataAccessObject.java b/src/main/java/data_access/InMemoryCalendarDataAccessObject.java
new file mode 100644
index 000000000..372312d8f
--- /dev/null
+++ b/src/main/java/data_access/InMemoryCalendarDataAccessObject.java
@@ -0,0 +1,31 @@
+package data_access;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import entity.Place;
+import use_case.add_to_calendar.AddToCalendarDataAccessInterface;
+
+/**
+ * In-memory implementation of the DAO for storing calendar data. This implementation does
+ * NOT persist data between runs of the program.
+ */
+public class InMemoryCalendarDataAccessObject implements AddToCalendarDataAccessInterface {
+
+ private final Map calendarItems = new HashMap<>();
+
+ @Override
+ public boolean hasLocation(Place location) {
+ return calendarItems.containsKey(location);
+ }
+
+ @Override
+ public boolean hasTime(String time) {
+ return calendarItems.containsValue(time);
+ }
+
+ @Override
+ public void save(Place location, String time) {
+ calendarItems.put(location, time);
+ }
+}
diff --git a/src/main/java/data_access/InMemoryUserDataAccessObject.java b/src/main/java/data_access/InMemoryUserDataAccessObject.java
new file mode 100644
index 000000000..1faa11526
--- /dev/null
+++ b/src/main/java/data_access/InMemoryUserDataAccessObject.java
@@ -0,0 +1,74 @@
+package data_access;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import entity.Place;
+import entity.User;
+import use_case.DataAccessException;
+import use_case.login.LoginUserDataAccessInterface;
+import use_case.signup.SignupUserDataAccessInterface;
+import use_case.user_profile.UserProfileDataAccessInterface;
+
+/**
+ * In-memory implementation for storing user data for both sign-up and user profile.
+ */
+public class InMemoryUserDataAccessObject implements SignupUserDataAccessInterface,
+ LoginUserDataAccessInterface, UserProfileDataAccessInterface {
+
+ private static final String USER_NOT_FOUND = "User not found.";
+ private final Map userDatabase = new HashMap<>();
+
+ @Override
+ public void save(User user) {
+ userDatabase.put(user.getName(), user);
+ }
+
+ @Override
+ public User get(String username) {
+ return userDatabase.get(username);
+ }
+
+ @Override
+ public User getUser(String username) throws DataAccessException {
+ final User user = userDatabase.get(username);
+ if (user == null) {
+ throw new DataAccessException(USER_NOT_FOUND);
+ }
+ return user;
+ }
+
+ @Override
+ public boolean existsByName(String username) {
+ return userDatabase.containsKey(username);
+ }
+
+ @Override
+ public void savePlaces(String username, Map> places) throws DataAccessException {
+ final User user = getUser(username);
+ if (user != null) {
+ user.getSavedPlaces().putAll(places);
+ }
+ else {
+ throw new DataAccessException(USER_NOT_FOUND);
+ }
+ }
+
+ @Override
+ public Map> getSavedPlaces(String username) throws DataAccessException {
+ final User user = getUser(username);
+ if (user != null) {
+ return user.getSavedPlaces();
+ }
+ else {
+ throw new DataAccessException(USER_NOT_FOUND);
+ }
+ }
+
+ // This method is added to fulfill the requirement of SignupUserDataAccessInterface
+ @Override
+ public User getSignupUser(String username) throws DataAccessException {
+ return getUser(username);
+ }
+}
diff --git a/src/main/java/entity/DislikedLocationFilter.java b/src/main/java/entity/DislikedLocationFilter.java
new file mode 100644
index 000000000..62c1ea342
--- /dev/null
+++ b/src/main/java/entity/DislikedLocationFilter.java
@@ -0,0 +1,16 @@
+package entity;
+
+import java.util.Set;
+
+public class DislikedLocationFilter implements LocationFilterStrategy {
+ private Set dislikedLocations;
+
+ public DislikedLocationFilter(Set dislikedLocations) {
+ this.dislikedLocations = dislikedLocations;
+ }
+
+ @Override
+ public boolean filter(String location) {
+ return !dislikedLocations.contains(location);
+ }
+}
diff --git a/src/main/java/entity/LocationFilterContext.java b/src/main/java/entity/LocationFilterContext.java
new file mode 100644
index 000000000..cef58a9a9
--- /dev/null
+++ b/src/main/java/entity/LocationFilterContext.java
@@ -0,0 +1,17 @@
+package entity;
+
+public class LocationFilterContext {
+ private LocationFilterStrategy strategy;
+
+ public LocationFilterContext(LocationFilterStrategy strategy) {
+ this.strategy = strategy;
+ }
+
+ public void setStrategy(LocationFilterStrategy strategy) {
+ this.strategy = strategy;
+ }
+
+ public boolean applyFilter(String location) {
+ return strategy.filter(location);
+ }
+}
diff --git a/src/main/java/entity/LocationFilterStrategy.java b/src/main/java/entity/LocationFilterStrategy.java
new file mode 100644
index 000000000..d0b27e733
--- /dev/null
+++ b/src/main/java/entity/LocationFilterStrategy.java
@@ -0,0 +1,8 @@
+package entity;
+
+/**
+ * The representation of a filter in our program.
+ */
+public interface LocationFilterStrategy {
+ boolean filter(String location);
+}
diff --git a/src/main/java/entity/Place.java b/src/main/java/entity/Place.java
new file mode 100644
index 000000000..e916838d0
--- /dev/null
+++ b/src/main/java/entity/Place.java
@@ -0,0 +1,20 @@
+package entity;
+
+/**
+ * The representation of a place in our program.
+ */
+public interface Place {
+ /**
+ * Returns the address of the place.
+ *
+ * @return the address of the place.
+ */
+ String getName();
+
+ /**
+ * Returns the address of the place.
+ *
+ * @return the address of the place.
+ */
+ String getAddress();
+}
diff --git a/src/main/java/entity/PlaceFactory.java b/src/main/java/entity/PlaceFactory.java
new file mode 100644
index 000000000..135c32c1c
--- /dev/null
+++ b/src/main/java/entity/PlaceFactory.java
@@ -0,0 +1,14 @@
+package entity;
+
+/**
+ * Factory for creating places.
+ */
+public interface PlaceFactory {
+ /**
+ * Creates a new Place.
+ * @param name the name of the new place
+ * @param address the address of the new place
+ * @return the new place
+ */
+ Place create(String name, String address);
+}
diff --git a/src/main/java/entity/SavedLocationFilter.java b/src/main/java/entity/SavedLocationFilter.java
new file mode 100644
index 000000000..02948ec99
--- /dev/null
+++ b/src/main/java/entity/SavedLocationFilter.java
@@ -0,0 +1,16 @@
+package entity;
+
+import java.util.Set;
+
+public class SavedLocationFilter implements LocationFilterStrategy {
+ private Set savedLocations;
+
+ public SavedLocationFilter(Set savedLocations) {
+ this.savedLocations = savedLocations;
+ }
+
+ @Override
+ public boolean filter(String location) {
+ return savedLocations.contains(location);
+ }
+}
diff --git a/src/main/java/entity/SavedPlace.java b/src/main/java/entity/SavedPlace.java
new file mode 100644
index 000000000..9b74e9cf0
--- /dev/null
+++ b/src/main/java/entity/SavedPlace.java
@@ -0,0 +1,38 @@
+
+package entity;
+
+/**
+ * An implementation of the Place interface.
+ */
+public class SavedPlace implements Place {
+
+ private final String name;
+ private final String address;
+ private final String review;
+ private final boolean rating;
+
+ public SavedPlace(String name, String address, String review, boolean rating) {
+ this.name = name;
+ this.address = address;
+ this.review = review;
+ this.rating = rating;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String getAddress() {
+ return address;
+ }
+
+ public String getReview() {
+ return review;
+ }
+
+ public boolean getRating() {
+ return rating;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/entity/SavedPlaceFactory.java b/src/main/java/entity/SavedPlaceFactory.java
new file mode 100644
index 000000000..722093cf8
--- /dev/null
+++ b/src/main/java/entity/SavedPlaceFactory.java
@@ -0,0 +1,12 @@
+package entity;
+
+/**
+ * Factory for creating SuggestedPlace objects.
+ */
+public class SavedPlaceFactory implements PlaceFactory {
+
+ @Override
+ public Place create(String name, String address) {
+ return new SavedPlace(name, address, "", true);
+ }
+}
diff --git a/src/main/java/entity/SuggestedPlace.java b/src/main/java/entity/SuggestedPlace.java
new file mode 100644
index 000000000..e3b092b53
--- /dev/null
+++ b/src/main/java/entity/SuggestedPlace.java
@@ -0,0 +1,26 @@
+
+package entity;
+
+/**
+ * An implementation of the Place interface.
+ */
+public class SuggestedPlace implements Place {
+
+ private final String name;
+ private final String address;
+
+ public SuggestedPlace(String name, String address) {
+ this.name = name;
+ this.address = address;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String getAddress() {
+ return address;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/entity/SuggestedPlaceFactory.java b/src/main/java/entity/SuggestedPlaceFactory.java
new file mode 100644
index 000000000..83b81bb6c
--- /dev/null
+++ b/src/main/java/entity/SuggestedPlaceFactory.java
@@ -0,0 +1,12 @@
+package entity;
+
+/**
+ * Factory for creating SuggestedPlace objects.
+ */
+public class SuggestedPlaceFactory implements PlaceFactory {
+
+ @Override
+ public Place create(String name, String address) {
+ return new SuggestedPlace(name, address);
+ }
+}
diff --git a/src/main/java/entity/User.java b/src/main/java/entity/User.java
index e0c57e9a6..9d5833990 100644
--- a/src/main/java/entity/User.java
+++ b/src/main/java/entity/User.java
@@ -1,5 +1,9 @@
package entity;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
/**
* The representation of a password-protected user for our program.
*/
@@ -7,10 +11,12 @@ public class User {
private final String name;
private final String password;
+ private final Map> savedPlaces;
- public User(String name, String password) {
+ public User(String name, String password, HashMap> savedPlaces) {
this.name = name;
this.password = password;
+ this.savedPlaces = savedPlaces;
}
public String getName() {
@@ -21,4 +27,7 @@ public String getPassword() {
return password;
}
+ public Map> getSavedPlaces() {
+ return savedPlaces;
+ }
}
diff --git a/src/main/java/entity/UserFactory.java b/src/main/java/entity/UserFactory.java
new file mode 100644
index 000000000..500e11e8f
--- /dev/null
+++ b/src/main/java/entity/UserFactory.java
@@ -0,0 +1,20 @@
+package entity;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Factory for creating User entities.
+ */
+public class UserFactory {
+
+ /**
+ * Create a new user with the given username and password.
+ * @param username the user's username
+ * @param password the user's password
+ * @return a new User instance
+ */
+ public User create(String username, String password) {
+ return new User(username, password, new HashMap>());
+ }
+}
diff --git a/src/main/java/interface_adapter/ViewManagerModel.java b/src/main/java/interface_adapter/ViewManagerModel.java
new file mode 100644
index 000000000..99dc0ffe5
--- /dev/null
+++ b/src/main/java/interface_adapter/ViewManagerModel.java
@@ -0,0 +1,14 @@
+package interface_adapter;
+
+/**
+ * Model for the View Manager. Its state is the name of the View which
+ * is currently active. An initial state of "" is used.
+ */
+public class ViewManagerModel extends ViewModel {
+
+ public ViewManagerModel() {
+ super("view manager");
+ this.setState("");
+ }
+
+}
diff --git a/src/main/java/interface_adapter/ViewModel.java b/src/main/java/interface_adapter/ViewModel.java
index 130d797a1..f4ceddcf5 100644
--- a/src/main/java/interface_adapter/ViewModel.java
+++ b/src/main/java/interface_adapter/ViewModel.java
@@ -45,6 +45,7 @@ public void firePropertyChanged() {
* Fires a property changed event for the state of this ViewModel, which
* allows the user to specify a different propertyName. This can be useful
* when a class is listening for multiple kinds of property changes.
+ *
*
For example, the LoggedInView listens for two kinds of property changes;
* it can use the property name to distinguish which property has changed.
* @param propertyName the label for the property that was changed
diff --git a/src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java
new file mode 100644
index 000000000..9841903b3
--- /dev/null
+++ b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarController.java
@@ -0,0 +1,39 @@
+package interface_adapter.add_to_calendar;
+
+import java.util.Map;
+
+import entity.Place;
+import use_case.DataAccessException;
+import use_case.add_to_calendar.AddToCalendarInputBoundary;
+import use_case.add_to_calendar.AddToCalendarInputData;
+
+/**
+ * The AddToCalendarController class handles user input related to adding locations to calendar.
+ * It interacts with the AddToCalendarInputBoundary to process the input and perform actions.
+ */
+public class AddToCalendarController {
+
+ private final AddToCalendarInputBoundary addToCalendarInteractor;
+
+ public AddToCalendarController(AddToCalendarInputBoundary calendarInteractor) {
+ this.addToCalendarInteractor = calendarInteractor;
+ }
+
+ /**
+ * Executes the show calendar.
+ * @param addToCalendarData the locations and time map to add.
+ * @throws DataAccessException if data cannot be accessed
+ */
+ public void execute(Map addToCalendarData) throws DataAccessException {
+ final AddToCalendarInputData calendarInputData = new AddToCalendarInputData(addToCalendarData);
+
+ addToCalendarInteractor.execute(calendarInputData);
+ }
+
+ /**
+ * Executes the switch to location view.
+ */
+ public void switchToLocationView() {
+ addToCalendarInteractor.switchToLocationView();
+ }
+}
diff --git a/src/main/java/interface_adapter/add_to_calendar/AddToCalendarPresenter.java b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarPresenter.java
new file mode 100644
index 000000000..343d4d72c
--- /dev/null
+++ b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarPresenter.java
@@ -0,0 +1,49 @@
+package interface_adapter.add_to_calendar;
+
+import interface_adapter.ViewManagerModel;
+import interface_adapter.location.LocationViewModel;
+import use_case.add_to_calendar.AddToCalendarOutputBoundary;
+import use_case.add_to_calendar.AddToCalendarOutputData;
+
+/**
+ * The Presenter for the Add to Calendar Use Case.
+ */
+public class AddToCalendarPresenter implements AddToCalendarOutputBoundary {
+
+ private final AddToCalendarViewModel calendarViewModel;
+ private final ViewManagerModel viewManagerModel;
+ private final LocationViewModel locationViewModel;
+
+ public AddToCalendarPresenter(AddToCalendarViewModel calendarViewModel, ViewManagerModel viewManagerModel,
+ LocationViewModel locationViewModel) {
+ this.calendarViewModel = calendarViewModel;
+ this.viewManagerModel = viewManagerModel;
+ this.locationViewModel = locationViewModel;
+ }
+
+
+ @Override
+ public void prepareSuccessView(AddToCalendarOutputData outputData) {
+ // On success, switch to the Calendar view.
+ final AddToCalendarState calendarState = calendarViewModel.getState();
+ calendarState.setCalendarItems(outputData.getcalendarItems());
+ this.calendarViewModel.setState(calendarState);
+ this.calendarViewModel.firePropertyChanged();
+
+ this.viewManagerModel.setState(calendarViewModel.getViewName());
+ this.viewManagerModel.firePropertyChanged();
+ }
+
+ @Override
+ public void prepareFailView(String errorMessage) {
+ final AddToCalendarState calendarState = calendarViewModel.getState();
+ calendarState.setAddError(errorMessage);
+ calendarViewModel.firePropertyChanged();
+ }
+
+ @Override
+ public void switchToLocationView() {
+ viewManagerModel.setState(locationViewModel.getViewName());
+ viewManagerModel.firePropertyChanged();
+ }
+}
diff --git a/src/main/java/interface_adapter/add_to_calendar/AddToCalendarState.java b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarState.java
new file mode 100644
index 000000000..5f4aeb659
--- /dev/null
+++ b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarState.java
@@ -0,0 +1,29 @@
+package interface_adapter.add_to_calendar;
+
+import java.util.Map;
+
+import entity.Place;
+
+/**
+ * The state representing calendar-related data, including locations, times, and any error messages.
+ */
+public class AddToCalendarState {
+ private Map calendarItems;
+ private String addError;
+
+ public Map getCalendarItems() {
+ return calendarItems;
+ }
+
+ public String getAddError() {
+ return addError;
+ }
+
+ public void setCalendarItems(Map calendarItems) {
+ this.calendarItems = calendarItems;
+ }
+
+ public void setAddError(String addError) {
+ this.addError = addError;
+ }
+}
diff --git a/src/main/java/interface_adapter/add_to_calendar/AddToCalendarViewModel.java b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarViewModel.java
new file mode 100644
index 000000000..f4b9ee9f9
--- /dev/null
+++ b/src/main/java/interface_adapter/add_to_calendar/AddToCalendarViewModel.java
@@ -0,0 +1,14 @@
+package interface_adapter.add_to_calendar;
+
+import interface_adapter.ViewModel;
+
+/**
+ * The View Model for the Add to Calendar View.
+ */
+public class AddToCalendarViewModel extends ViewModel {
+
+ public AddToCalendarViewModel() {
+ super("Calendar");
+ setState(new AddToCalendarState());
+ }
+}
diff --git a/src/main/java/interface_adapter/location/LocationController.java b/src/main/java/interface_adapter/location/LocationController.java
new file mode 100644
index 000000000..64614657b
--- /dev/null
+++ b/src/main/java/interface_adapter/location/LocationController.java
@@ -0,0 +1,35 @@
+package interface_adapter.location;
+
+import use_case.DataAccessException;
+import use_case.locations.LocationsInputBoundary;
+import use_case.locations.LocationsInputData;
+
+/**
+ * The LocationController class handles user input related to locations.
+ * It interacts with the LocationInputBoundary to process the input and
+ * perform actions such as setting the city, address, and interests,
+ * as well as executing save or refresh operations.
+ */
+public class LocationController {
+
+ private final LocationsInputBoundary locationInput;
+
+ public LocationController(LocationsInputBoundary locationInteractor) {
+ this.locationInput = locationInteractor;
+ }
+
+ /**
+ * Executes the show location.
+ * @param address the location to show.
+ * @param locationType the type of location to search.
+ * @param currentFilter the type of filter to search with.
+ * @param username the username of the current user.
+ * @throws DataAccessException if data cannot be accessed
+ */
+ public void execute(String address, String locationType, String currentFilter, String username) throws DataAccessException {
+ final LocationsInputData locationInputData = new LocationsInputData(
+ address, locationType, username);
+
+ locationInput.execute(locationInputData, currentFilter);
+ }
+}
diff --git a/src/main/java/interface_adapter/location/LocationPresenter.java b/src/main/java/interface_adapter/location/LocationPresenter.java
new file mode 100644
index 000000000..781ad81f7
--- /dev/null
+++ b/src/main/java/interface_adapter/location/LocationPresenter.java
@@ -0,0 +1,44 @@
+package interface_adapter.location;
+
+import interface_adapter.ViewManagerModel;
+import interface_adapter.suggestlocation.SuggestedLocationsState;
+import interface_adapter.suggestlocation.SuggestedLocationsViewModel;
+import use_case.locations.LocationsOutputBoundary;
+import use_case.locations.LocationsOutputData;
+
+/**
+ * The Presenter for the Location Use Case.
+ */
+public class LocationPresenter implements LocationsOutputBoundary {
+
+ private final LocationViewModel locationViewModel;
+ private final SuggestedLocationsViewModel suggestedLocationsViewModel;
+ private final ViewManagerModel viewManagerModel;
+
+ public LocationPresenter(LocationViewModel locationViewModel,
+ SuggestedLocationsViewModel suggestedLocationsViewModel,
+ ViewManagerModel viewManagerModel) {
+ this.locationViewModel = locationViewModel;
+ this.suggestedLocationsViewModel = suggestedLocationsViewModel;
+ this.viewManagerModel = viewManagerModel;
+ }
+
+ @Override
+ public void prepareSuccessView(LocationsOutputData response) {
+ // On success, switch to the suggested locations view.
+ final SuggestedLocationsState suggestedLocationsState = suggestedLocationsViewModel.getState();
+ suggestedLocationsState.setSuggestedLocations(response.getLocations());
+ this.suggestedLocationsViewModel.setState(suggestedLocationsState);
+ this.suggestedLocationsViewModel.firePropertyChanged();
+
+ this.viewManagerModel.setState(suggestedLocationsViewModel.getViewName());
+ this.viewManagerModel.firePropertyChanged();
+ }
+
+ @Override
+ public void prepareFailView(String error) {
+ final LocationState locationState = locationViewModel.getState();
+ locationState.setError(error);
+ locationViewModel.firePropertyChanged();
+ }
+}
diff --git a/src/main/java/interface_adapter/location/LocationState.java b/src/main/java/interface_adapter/location/LocationState.java
new file mode 100644
index 000000000..d3c061d0c
--- /dev/null
+++ b/src/main/java/interface_adapter/location/LocationState.java
@@ -0,0 +1,45 @@
+package interface_adapter.location;
+
+/**
+ * The state representing location-related data, including city, address, keywords,
+ * suggested locations, and any error messages.
+ */
+public class LocationState {
+ private String address = "";
+ private String locationType = "";
+ private String username = "";
+ private String error;
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public String getLocationType() {
+ return locationType;
+ }
+
+ public void setLocationType(String locationType) {
+ this.locationType = locationType;
+ }
+
+ public String getError() {
+ return error;
+ }
+
+ public void setError(String error) {
+ this.error = error;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+}
+
diff --git a/src/main/java/interface_adapter/location/LocationViewModel.java b/src/main/java/interface_adapter/location/LocationViewModel.java
new file mode 100644
index 000000000..6af84c69b
--- /dev/null
+++ b/src/main/java/interface_adapter/location/LocationViewModel.java
@@ -0,0 +1,13 @@
+package interface_adapter.location;
+
+import interface_adapter.ViewModel;
+
+/**
+ * The ViewModel for the LocationView.
+ */
+public class LocationViewModel extends ViewModel {
+ public LocationViewModel() {
+ super("Search Locations");
+ setState(new LocationState());
+ }
+}
diff --git a/src/main/java/interface_adapter/login/LoginController.java b/src/main/java/interface_adapter/login/LoginController.java
new file mode 100644
index 000000000..6f58ab10b
--- /dev/null
+++ b/src/main/java/interface_adapter/login/LoginController.java
@@ -0,0 +1,32 @@
+package interface_adapter.login;
+
+import use_case.login.LoginInputBoundary;
+import use_case.login.LoginInputData;
+
+/**
+ * The controller for the Login Use Case.
+ */
+public class LoginController {
+
+ private final LoginInputBoundary loginUseCaseInteractor;
+
+ public LoginController(LoginInputBoundary loginUseCaseInteractor) {
+ this.loginUseCaseInteractor = loginUseCaseInteractor;
+ }
+
+ /**
+ * Executes the Login Use Case.
+ * @param username the username of the user logging in
+ * @param password the password of the user logging in
+ */
+ public void execute(String username, String password) {
+ final LoginInputData loginInputData = new LoginInputData(
+ username, password);
+
+ loginUseCaseInteractor.execute(loginInputData);
+ }
+
+ public void switchToSignUpView() {
+ loginUseCaseInteractor.switchToSignUpView();
+ }
+}
diff --git a/src/main/java/interface_adapter/login/LoginPresenter.java b/src/main/java/interface_adapter/login/LoginPresenter.java
new file mode 100644
index 000000000..6f04e738b
--- /dev/null
+++ b/src/main/java/interface_adapter/login/LoginPresenter.java
@@ -0,0 +1,63 @@
+package interface_adapter.login;
+
+import interface_adapter.ViewManagerModel;
+import interface_adapter.location.LocationState;
+import interface_adapter.location.LocationViewModel;
+import interface_adapter.signup.SignupViewModel;
+import interface_adapter.user_profile.UserProfileState;
+import interface_adapter.user_profile.UserProfileViewModel;
+import use_case.login.LoginOutputBoundary;
+import use_case.login.LoginOutputData;
+
+/**
+ * The Presenter for the Login Use Case.
+ */
+public class LoginPresenter implements LoginOutputBoundary {
+
+ private final LoginViewModel loginViewModel;
+ private final UserProfileViewModel userProfileViewModel;
+ private final LocationViewModel locationViewModel;
+ private final ViewManagerModel viewManagerModel;
+ private final SignupViewModel signUpViewModel;
+
+ public LoginPresenter(ViewManagerModel viewManagerModel,
+ UserProfileViewModel userProfileViewModel,
+ LoginViewModel loginViewModel,
+ LocationViewModel locationViewModel,
+ SignupViewModel signUpViewModel) {
+ this.viewManagerModel = viewManagerModel;
+ this.userProfileViewModel = userProfileViewModel;
+ this.loginViewModel = loginViewModel;
+ this.locationViewModel = locationViewModel;
+ this.signUpViewModel = signUpViewModel;
+ }
+
+ @Override
+ public void prepareSuccessView(LoginOutputData response) {
+ // On success, switch to the logged in view.
+
+ final UserProfileState userProfileState = userProfileViewModel.getState();
+ userProfileState.setUsername(response.getUsername());
+ this.userProfileViewModel.setState(userProfileState);
+ this.userProfileViewModel.firePropertyChanged();
+ final LocationState locationState = locationViewModel.getState();
+ locationState.setUsername(response.getUsername());
+ this.locationViewModel.setState(locationState);
+
+ this.viewManagerModel.setState(locationViewModel.getViewName());
+ this.viewManagerModel.firePropertyChanged();
+ }
+
+ @Override
+ public void prepareFailView(String error) {
+ final LoginState loginState = loginViewModel.getState();
+ loginState.setLoginError(error);
+ loginViewModel.firePropertyChanged();
+ }
+
+ @Override
+ public void switchToSignUpView() {
+ viewManagerModel.setState(signUpViewModel.getViewName());
+ viewManagerModel.firePropertyChanged();
+ }
+}
diff --git a/src/main/java/interface_adapter/login/LoginState.java b/src/main/java/interface_adapter/login/LoginState.java
new file mode 100644
index 000000000..e42632034
--- /dev/null
+++ b/src/main/java/interface_adapter/login/LoginState.java
@@ -0,0 +1,35 @@
+package interface_adapter.login;
+
+/**
+ * The state for the Login View Model.
+ */
+public class LoginState {
+ private String username = "";
+ private String loginError;
+ private String password = "";
+
+ public String getUsername() {
+ return username;
+ }
+
+ public String getLoginError() {
+ return loginError;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public void setLoginError(String usernameError) {
+ this.loginError = usernameError;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+}
diff --git a/src/main/java/interface_adapter/login/LoginViewModel.java b/src/main/java/interface_adapter/login/LoginViewModel.java
new file mode 100644
index 000000000..41bea7a2e
--- /dev/null
+++ b/src/main/java/interface_adapter/login/LoginViewModel.java
@@ -0,0 +1,15 @@
+package interface_adapter.login;
+
+import interface_adapter.ViewModel;
+
+/**
+ * The View Model for the Login View.
+ */
+public class LoginViewModel extends ViewModel {
+
+ public LoginViewModel() {
+ super("log in");
+ setState(new LoginState());
+ }
+
+}
diff --git a/src/main/java/interface_adapter/note/NoteController.java b/src/main/java/interface_adapter/note/NoteController.java
deleted file mode 100644
index e3e5dfb32..000000000
--- a/src/main/java/interface_adapter/note/NoteController.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package interface_adapter.note;
-
-import use_case.note.NoteInputBoundary;
-
-/**
- * Controller for our Note related Use Cases.
- */
-public class NoteController {
-
- private final NoteInputBoundary noteInteractor;
-
- public NoteController(NoteInputBoundary noteInteractor) {
- this.noteInteractor = noteInteractor;
- }
-
- /**
- * Executes the Note related Use Cases.
- * @param note the note to be recorded
- */
- public void execute(String note) {
- if (note != null) {
- noteInteractor.executeSave(note);
- }
- else {
- noteInteractor.executeRefresh();
- }
- }
-}
diff --git a/src/main/java/interface_adapter/note/NotePresenter.java b/src/main/java/interface_adapter/note/NotePresenter.java
deleted file mode 100644
index d4e416165..000000000
--- a/src/main/java/interface_adapter/note/NotePresenter.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package interface_adapter.note;
-
-import use_case.note.NoteOutputBoundary;
-
-/**
- * The presenter for our Note viewing and editing program.
- */
-public class NotePresenter implements NoteOutputBoundary {
-
- private final NoteViewModel noteViewModel;
-
- public NotePresenter(NoteViewModel noteViewModel) {
- this.noteViewModel = noteViewModel;
- }
-
- /**
- * Prepares the success view for the Note related Use Cases.
- *
- * @param note the output data
- */
- @Override
- public void prepareSuccessView(String note) {
- noteViewModel.getState().setNote(note);
- noteViewModel.getState().setError(null);
- noteViewModel.firePropertyChanged();
- }
-
- /**
- * Prepares the failure view for the Note related Use Cases.
- *
- * @param errorMessage the explanation of the failure
- */
- @Override
- public void prepareFailView(String errorMessage) {
- noteViewModel.getState().setError(errorMessage);
- noteViewModel.firePropertyChanged();
- }
-}
diff --git a/src/main/java/interface_adapter/note/NoteState.java b/src/main/java/interface_adapter/note/NoteState.java
deleted file mode 100644
index c5b2234d6..000000000
--- a/src/main/java/interface_adapter/note/NoteState.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package interface_adapter.note;
-
-/**
- * The State for a note.
- *
For this example, a note is simplay a string.
- */
-public class NoteState {
- private String note = "";
- private String error;
-
- public String getNote() {
- return note;
- }
-
- public void setNote(String note) {
- this.note = note;
- }
-
- public void setError(String errorMessage) {
- this.error = errorMessage;
- }
-
- public String getError() {
- return error;
- }
-}
diff --git a/src/main/java/interface_adapter/note/NoteViewModel.java b/src/main/java/interface_adapter/note/NoteViewModel.java
deleted file mode 100644
index 6e185d0fa..000000000
--- a/src/main/java/interface_adapter/note/NoteViewModel.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package interface_adapter.note;
-
-import interface_adapter.ViewModel;
-
-/**
- * The ViewModel for the NoteView.
- */
-public class NoteViewModel extends ViewModel {
- public NoteViewModel() {
- super("note");
- setState(new NoteState());
- }
-}
diff --git a/src/main/java/interface_adapter/reviewlocation/ReviewLocationController.java b/src/main/java/interface_adapter/reviewlocation/ReviewLocationController.java
new file mode 100644
index 000000000..9467f0ca5
--- /dev/null
+++ b/src/main/java/interface_adapter/reviewlocation/ReviewLocationController.java
@@ -0,0 +1,6 @@
+package interface_adapter.reviewlocation;
+
+public class ReviewLocationController {
+
+
+}
diff --git a/src/main/java/interface_adapter/reviewlocation/ReviewLocationPresenter.java b/src/main/java/interface_adapter/reviewlocation/ReviewLocationPresenter.java
new file mode 100644
index 000000000..9f9f8673f
--- /dev/null
+++ b/src/main/java/interface_adapter/reviewlocation/ReviewLocationPresenter.java
@@ -0,0 +1,4 @@
+package interface_adapter.reviewlocation;
+
+public class ReviewLocationPresenter {
+}
diff --git a/src/main/java/interface_adapter/reviewlocation/ReviewLocationState.java b/src/main/java/interface_adapter/reviewlocation/ReviewLocationState.java
new file mode 100644
index 000000000..82b4be804
--- /dev/null
+++ b/src/main/java/interface_adapter/reviewlocation/ReviewLocationState.java
@@ -0,0 +1,4 @@
+package interface_adapter.reviewlocation;
+
+public class ReviewLocationState {
+}
diff --git a/src/main/java/interface_adapter/reviewlocation/ReviewLocationViewModel.java b/src/main/java/interface_adapter/reviewlocation/ReviewLocationViewModel.java
new file mode 100644
index 000000000..ba8f46319
--- /dev/null
+++ b/src/main/java/interface_adapter/reviewlocation/ReviewLocationViewModel.java
@@ -0,0 +1,4 @@
+package interface_adapter.reviewlocation;
+
+public class ReviewLocationViewModel {
+}
diff --git a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java
new file mode 100644
index 000000000..918ca9dc7
--- /dev/null
+++ b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsController.java
@@ -0,0 +1,32 @@
+package interface_adapter.selectedlocation;
+
+
+import entity.Place;
+import use_case.DataAccessException;
+import use_case.selected_locations.SelectedLocationsInputBoundary;
+import use_case.selected_locations.SelectedLocationsInputData;
+
+import java.util.List;
+
+public class SelectedLocationsController {
+
+ private final SelectedLocationsInputBoundary selectedLocationsInteractor;
+
+ public SelectedLocationsController(SelectedLocationsInputBoundary selectedLocationsInteractor) {
+ this.selectedLocationsInteractor = selectedLocationsInteractor;
+ }
+
+ public void execute(List selectedLocations) throws DataAccessException {
+ final SelectedLocationsInputData selectedLocationsInputData =
+ new SelectedLocationsInputData(selectedLocations);
+ selectedLocationsInteractor.execute(selectedLocationsInputData);
+ }
+
+ /**
+ * Switches to the location view.
+ */
+ public void switchToLocationView() {
+ selectedLocationsInteractor.switchToLocationView();
+ }
+
+}
diff --git a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java
new file mode 100644
index 000000000..f7f7cf8af
--- /dev/null
+++ b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsPresenter.java
@@ -0,0 +1,43 @@
+package interface_adapter.selectedlocation;
+
+import interface_adapter.ViewManagerModel;
+import interface_adapter.location.LocationViewModel;
+import interface_adapter.suggestlocation.SuggestedLocationsState;
+import use_case.selected_locations.SelectedLocationsOutputBoundary;
+import use_case.selected_locations.SelectedLocationsOutputData;
+
+public class SelectedLocationsPresenter implements SelectedLocationsOutputBoundary {
+ private final SelectedLocationsViewModel selectedLocationsViewModel;
+ private final ViewManagerModel viewManagerModel;
+ private final LocationViewModel locationViewModel;
+
+ public SelectedLocationsPresenter(SelectedLocationsViewModel selectedLocationsViewModel,
+ ViewManagerModel viewManagerModel,
+ LocationViewModel locationViewModel) {
+ this.selectedLocationsViewModel = selectedLocationsViewModel;
+ this.viewManagerModel = viewManagerModel;
+ this.locationViewModel = locationViewModel;
+ }
+
+ @Override
+ public void prepareSuccessView(SelectedLocationsOutputData outputData) {
+ final SelectedLocationsState selectedLocationsState =
+ selectedLocationsViewModel.getState();
+ selectedLocationsState.setPlaceToCoordinates(outputData.getLocationCoordinatesMap());
+ this.selectedLocationsViewModel.setState(selectedLocationsState);
+ this.selectedLocationsViewModel.firePropertyChanged();
+ this.viewManagerModel.setState(selectedLocationsViewModel.getViewName());
+ this.viewManagerModel.firePropertyChanged();
+ }
+
+ @Override
+ public void prepareFailView(String errorMessage) {
+
+ }
+
+ @Override
+ public void switchToLocationView() {
+ viewManagerModel.setState(locationViewModel.getViewName());
+ viewManagerModel.firePropertyChanged();
+ }
+}
diff --git a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsState.java b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsState.java
new file mode 100644
index 000000000..60a7b6a21
--- /dev/null
+++ b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsState.java
@@ -0,0 +1,42 @@
+package interface_adapter.selectedlocation;
+
+import entity.Place;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The state representing selected location-related data, including a list of
+ * selected locations.
+ */
+public class SelectedLocationsState {
+
+ private List selectedLocations;
+ private Map placeToCoordinates;
+ private String error;
+
+ public List getSelectedLocations() {
+ return selectedLocations;
+ }
+
+ public void setSelectedLocations(List selectedLocations) {
+ this.selectedLocations = selectedLocations;
+ }
+
+ public void setPlaceToCoordinates(Map placeToCoordinates) {
+ this.placeToCoordinates = placeToCoordinates;
+ }
+
+ public Map getPlaceToCoordinates() {
+ return placeToCoordinates;
+ }
+
+ public String getError() {
+ return error;
+ }
+
+ public void setError(String error) {
+ this.error = error;
+ }
+
+}
diff --git a/src/main/java/interface_adapter/selectedlocation/SelectedLocationsViewModel.java b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsViewModel.java
new file mode 100644
index 000000000..6cd0c904e
--- /dev/null
+++ b/src/main/java/interface_adapter/selectedlocation/SelectedLocationsViewModel.java
@@ -0,0 +1,17 @@
+package interface_adapter.selectedlocation;
+
+import interface_adapter.ViewModel;
+import entity.Place;
+
+import java.util.List;
+
+/**
+ * The ViewModel for the SelectedLocationsView.
+ */
+public class SelectedLocationsViewModel extends ViewModel {
+ public SelectedLocationsViewModel() {
+ super("Selected Locations");
+ setState(new SelectedLocationsState());
+ }
+
+}
diff --git a/src/main/java/interface_adapter/signup/SignupController.java b/src/main/java/interface_adapter/signup/SignupController.java
new file mode 100644
index 000000000..d6ed9c4a8
--- /dev/null
+++ b/src/main/java/interface_adapter/signup/SignupController.java
@@ -0,0 +1,34 @@
+package interface_adapter.signup;
+
+import use_case.signup.SignupInputBoundary;
+import use_case.signup.SignupInputData;
+
+/**
+ * Controller for the Signup use case.
+ */
+public class SignupController {
+ private final SignupInputBoundary signupInteractor;
+
+ public SignupController(SignupInputBoundary signupInteractor) {
+ this.signupInteractor = signupInteractor;
+ }
+
+ /**
+ * Executes the Signup use case with the provided information.
+ *
+ * @param username the username
+ * @param password the password
+ * @param repeatPassword the repeated password
+ */
+ public void execute(String username, String password, String repeatPassword) {
+ final SignupInputData inputData = new SignupInputData(username, password, repeatPassword);
+ signupInteractor.execute(inputData);
+ }
+
+ /**
+ * Switches to the login view.
+ */
+ public void switchToLoginView() {
+ signupInteractor.switchToLoginView();
+ }
+}
diff --git a/src/main/java/interface_adapter/signup/SignupPresenter.java b/src/main/java/interface_adapter/signup/SignupPresenter.java
new file mode 100644
index 000000000..d8216ec02
--- /dev/null
+++ b/src/main/java/interface_adapter/signup/SignupPresenter.java
@@ -0,0 +1,50 @@
+package interface_adapter.signup;
+
+import interface_adapter.ViewManagerModel;
+import interface_adapter.login.LoginState;
+import interface_adapter.login.LoginViewModel;
+import use_case.signup.SignupOutputBoundary;
+import use_case.signup.SignupOutputData;
+
+/**
+ * Presenter for the signup use case.
+ */
+public class SignupPresenter implements SignupOutputBoundary {
+
+ private final SignupViewModel signupViewModel;
+ private final LoginViewModel loginViewModel;
+ private final ViewManagerModel viewManagerModel;
+
+ public SignupPresenter(ViewManagerModel viewManagerModel,
+ SignupViewModel signupViewModel,
+ LoginViewModel loginViewModel) {
+ this.viewManagerModel = viewManagerModel;
+ this.signupViewModel = signupViewModel;
+ this.loginViewModel = loginViewModel;
+ }
+
+ @Override
+ public void prepareSuccessView(SignupOutputData response) {
+ // On success, switch to the login view.
+ final LoginState loginState = loginViewModel.getState();
+ loginState.setUsername(response.getUsername());
+ this.loginViewModel.setState(loginState);
+ loginViewModel.firePropertyChanged();
+
+ viewManagerModel.setState(loginViewModel.getViewName());
+ viewManagerModel.firePropertyChanged();
+ }
+
+ @Override
+ public void prepareFailView(String error) {
+ final SignupState signupState = signupViewModel.getState();
+ signupState.setUsernameError(error);
+ signupViewModel.firePropertyChanged();
+ }
+
+ @Override
+ public void switchToLoginView() {
+ viewManagerModel.setState(loginViewModel.getViewName());
+ viewManagerModel.firePropertyChanged();
+ }
+}
diff --git a/src/main/java/interface_adapter/signup/SignupState.java b/src/main/java/interface_adapter/signup/SignupState.java
new file mode 100644
index 000000000..ead93994c
--- /dev/null
+++ b/src/main/java/interface_adapter/signup/SignupState.java
@@ -0,0 +1,67 @@
+package interface_adapter.signup;
+
+public class SignupState {
+ private String username = "";
+ private String usernameError;
+ private String password = "";
+ private String passwordError;
+ private String repeatPassword = "";
+ private String repeatPasswordError;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public String getUsernameError() {
+ return usernameError;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public String getPasswordError() {
+ return passwordError;
+ }
+
+ public String getRepeatPassword() {
+ return repeatPassword;
+ }
+
+ public String getRepeatPasswordError() {
+ return repeatPasswordError;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public void setUsernameError(String usernameError) {
+ this.usernameError = usernameError;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public void setPasswordError(String passwordError) {
+ this.passwordError = passwordError;
+ }
+
+ public void setRepeatPassword(String repeatPassword) {
+ this.repeatPassword = repeatPassword;
+ }
+
+ public void setRepeatPasswordError(String repeatPasswordError) {
+ this.repeatPasswordError = repeatPasswordError;
+ }
+
+ @Override
+ public String toString() {
+ return "SignupState{"
+ + "username='" + username + '\''
+ + ", password='" + password + '\''
+ + ", repeatPassword='" + repeatPassword + '\''
+ + '}';
+ }
+}
diff --git a/src/main/java/interface_adapter/signup/SignupViewModel.java b/src/main/java/interface_adapter/signup/SignupViewModel.java
new file mode 100644
index 000000000..df3903f7e
--- /dev/null
+++ b/src/main/java/interface_adapter/signup/SignupViewModel.java
@@ -0,0 +1,68 @@
+package interface_adapter.signup;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import interface_adapter.ViewModel;
+
+
+/**
+ * ViewModel for the signup process, holding state for the signup view.
+ */
+public class SignupViewModel extends ViewModel {
+// private String username;
+// private String errorMessage;
+// private final PropertyChangeSupport support;
+
+ public SignupViewModel() {
+ super("sign up");
+ setState(new SignupState());
+ }
+//
+// public String getUsername() {
+// return username;
+// }
+//
+// /**
+// * Sets the username and notifies listeners of the change.
+// *
+// * @param username the username
+// */
+// public void setUsername(String username) {
+// final String oldUsername = this.username;
+// this.username = username;
+// support.firePropertyChange("username", oldUsername, username);
+// }
+//
+// /**
+// * Sets the error message and notifies listeners of the change.
+// *
+// * @param errorMessage the error message
+// */
+// public void setErrorMessage(String errorMessage) {
+// final String oldErrorMessage = this.errorMessage;
+// this.errorMessage = errorMessage;
+// support.firePropertyChange("errorMessage", oldErrorMessage, errorMessage);
+// }
+//
+// /**
+// * Adds a property change listener.
+// *
+// * @param listener the listener
+// */
+// public void addPropertyChangeListener(PropertyChangeListener listener) {
+// support.addPropertyChangeListener(listener);
+// }
+//
+// /**
+// * Removes a property change listener.
+// *
+// * @param listener the listener
+// */
+// public void removePropertyChangeListener(PropertyChangeListener listener) {
+// support.removePropertyChangeListener(listener);
+// }
+//
+// public SignupState getState() {
+// return
+// }
+}
diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java
new file mode 100644
index 000000000..4e601078b
--- /dev/null
+++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsController.java
@@ -0,0 +1,33 @@
+package interface_adapter.suggestlocation;
+
+import java.util.List;
+import java.util.Map;
+
+import entity.Place;
+import use_case.DataAccessException;
+import use_case.suggested_locations.SuggestedLocationsInputBoundary;
+import use_case.suggested_locations.SuggestedLocationsInputData;
+
+/**
+ * The SuggestedLocationsController class handles user input related to suggested locations.
+ */
+public class SuggestedLocationsController {
+
+ private final SuggestedLocationsInputBoundary suggestedLocationsInteractor;
+
+ public SuggestedLocationsController(SuggestedLocationsInputBoundary suggestedLocationsInteractor) {
+ this.suggestedLocationsInteractor = suggestedLocationsInteractor;
+ }
+
+ /**
+ * Executes the suggested locations' operation.
+ * @param calendarItems the calendarItems produced.
+ * @throws DataAccessException if data cannot be accessed.
+ */
+ public void execute(Map calendarItems) throws DataAccessException {
+ final SuggestedLocationsInputData suggestedLocationInputData = new SuggestedLocationsInputData(
+ calendarItems);
+
+ suggestedLocationsInteractor.execute(suggestedLocationInputData);
+ }
+}
diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java
new file mode 100644
index 000000000..61df96697
--- /dev/null
+++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsPresenter.java
@@ -0,0 +1,65 @@
+package interface_adapter.suggestlocation;
+
+import interface_adapter.ViewManagerModel;
+import interface_adapter.selectedlocation.SelectedLocationsViewModel;
+import interface_adapter.add_to_calendar.AddToCalendarState;
+import interface_adapter.add_to_calendar.AddToCalendarViewModel;
+import use_case.locations.LocationsOutputData;
+import use_case.suggested_locations.SuggestedLocationsOutputBoundary;
+import use_case.suggested_locations.SuggestedLocationsOutputData;
+import interface_adapter.selectedlocation.SelectedLocationsState;
+
+/**
+ * The presenter for the suggested locations use case.
+ */
+public class SuggestedLocationsPresenter implements SuggestedLocationsOutputBoundary {
+
+ private final ViewManagerModel viewManagerModel;
+ private final SuggestedLocationsViewModel suggestedLocationsViewModel;
+ private final SelectedLocationsViewModel selectedLocationViewModel;
+ private final AddToCalendarViewModel addToCalendarViewModel;
+
+ public SuggestedLocationsPresenter(ViewManagerModel viewManagerModel,
+ SuggestedLocationsViewModel suggestedLocationsViewModel,
+ AddToCalendarViewModel addToCalendarViewModel,
+ SelectedLocationsViewModel selectedLocationViewModel) {
+ this.viewManagerModel = viewManagerModel;
+ this.suggestedLocationsViewModel = suggestedLocationsViewModel;
+ this.addToCalendarViewModel = addToCalendarViewModel;
+ this.selectedLocationViewModel = selectedLocationViewModel;
+ }
+
+ @Override
+ public void prepareSuccessView(SuggestedLocationsOutputData response) {
+ // On success, switch to the Calendar view.
+
+ final AddToCalendarState calendarState = addToCalendarViewModel.getState();
+// calendarState.setCalendarItems(response.getCalendarItems());
+ this.addToCalendarViewModel.setState(calendarState);
+ this.addToCalendarViewModel.firePropertyChanged();
+
+ this.viewManagerModel.setState(addToCalendarViewModel.getViewName());
+ this.viewManagerModel.firePropertyChanged();
+ }
+
+// @Override
+ public void placeholderForSeansCode(SuggestedLocationsOutputData response) {
+ // On success, switch to the selected locations view.
+
+ final SelectedLocationsState selectedLocationState =
+ selectedLocationViewModel.getState();
+ selectedLocationState.setSelectedLocations(response.getSelectedLocations());
+ this.selectedLocationViewModel.setState(selectedLocationState);
+ this.selectedLocationViewModel.firePropertyChanged();
+
+ this.viewManagerModel.setState(selectedLocationViewModel.getViewName());
+ this.viewManagerModel.firePropertyChanged();
+ }
+
+ @Override
+ public void prepareFailView(String error) {
+ final SuggestedLocationsState suggestedLocationState = suggestedLocationsViewModel.getState();
+ suggestedLocationState.setError(error);
+ suggestedLocationsViewModel.firePropertyChanged();
+ }
+}
diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java
new file mode 100644
index 000000000..fa2a3e461
--- /dev/null
+++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsState.java
@@ -0,0 +1,41 @@
+package interface_adapter.suggestlocation;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import entity.Place;
+
+/**
+ * The state representing suggested location-related data, including a list of suggested locations.
+ */
+public class SuggestedLocationsState {
+ private List suggestedLocations = new ArrayList<>();
+ private Map calendarItems = new HashMap<>();
+ private String error;
+
+ public List getSuggestedLocations() {
+ return suggestedLocations;
+ }
+
+ public void setSuggestedLocations(List suggestedLocations) {
+ this.suggestedLocations = suggestedLocations;
+ }
+
+ public Map getCalendarItems() {
+ return calendarItems;
+ }
+
+ public void setCalendarItems(Map calendarItems) {
+ this.calendarItems = calendarItems;
+ }
+
+ public String getError() {
+ return error;
+ }
+
+ public void setError(String error) {
+ this.error = error;
+ }
+}
diff --git a/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsViewModel.java b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsViewModel.java
new file mode 100644
index 000000000..a17bb17fd
--- /dev/null
+++ b/src/main/java/interface_adapter/suggestlocation/SuggestedLocationsViewModel.java
@@ -0,0 +1,13 @@
+package interface_adapter.suggestlocation;
+
+import interface_adapter.ViewModel;
+
+/**
+ * The ViewModel for the SuggestedLocationsView.
+ */
+public class SuggestedLocationsViewModel extends ViewModel {
+ public SuggestedLocationsViewModel() {
+ super("Suggested Locations");
+ setState(new SuggestedLocationsState());
+ }
+}
diff --git a/src/main/java/interface_adapter/user_profile/UserProfileController.java b/src/main/java/interface_adapter/user_profile/UserProfileController.java
new file mode 100644
index 000000000..736d02b61
--- /dev/null
+++ b/src/main/java/interface_adapter/user_profile/UserProfileController.java
@@ -0,0 +1,36 @@
+package interface_adapter.user_profile;
+
+import java.util.List;
+import java.util.Map;
+
+import entity.Place;
+import use_case.user_profile.UserProfileInputBoundary;
+
+/**
+ * Controller for the User Profile use case.
+ */
+public class UserProfileController {
+ private final UserProfileInputBoundary userProfileInteractor;
+
+ public UserProfileController(UserProfileInputBoundary userProfileInteractor) {
+ this.userProfileInteractor = userProfileInteractor;
+ }
+
+ /**
+ * Saves the places for the given username.
+ *
+ * @param username the username
+ * @param places the places to be saved, represented as a map with the place name as the key
+ * and a list of place objects as the value
+ */
+ public void savePlaces(String username, Map> places) {
+ userProfileInteractor.savePlaces(username, places);
+ }
+
+ /**
+ * Logs out the user.
+ */
+ public void logOut() {
+ userProfileInteractor.logOut();
+ }
+}
diff --git a/src/main/java/interface_adapter/user_profile/UserProfilePresenter.java b/src/main/java/interface_adapter/user_profile/UserProfilePresenter.java
new file mode 100644
index 000000000..e73b819bf
--- /dev/null
+++ b/src/main/java/interface_adapter/user_profile/UserProfilePresenter.java
@@ -0,0 +1,29 @@
+package interface_adapter.user_profile;
+
+import interface_adapter.ViewManagerModel;
+import use_case.user_profile.UserProfileOutputBoundary;
+
+/**
+ * Presenter for user profile creation.
+ */
+public class UserProfilePresenter implements UserProfileOutputBoundary {
+ private final ViewManagerModel viewManagerModel;
+ private final UserProfileViewModel userViewModel;
+
+ public UserProfilePresenter(ViewManagerModel viewManagerModel, UserProfileViewModel userViewModel) {
+ this.viewManagerModel = viewManagerModel;
+ this.userViewModel = userViewModel;
+ }
+
+ @Override
+ public void prepareSuccessView(String message) {
+ //teddy u can implement this for urs
+ }
+
+ @Override
+ public void prepareFailView(String errorMessage) {
+ final UserProfileState userProfileState = userViewModel.getState();
+ userProfileState.setError(errorMessage);
+ userViewModel.firePropertyChanged();
+ }
+}
diff --git a/src/main/java/interface_adapter/user_profile/UserProfileState.java b/src/main/java/interface_adapter/user_profile/UserProfileState.java
new file mode 100644
index 000000000..1424d3682
--- /dev/null
+++ b/src/main/java/interface_adapter/user_profile/UserProfileState.java
@@ -0,0 +1,49 @@
+package interface_adapter.user_profile;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import entity.Place;
+
+/**
+ * Represents the state of a user.
+ */
+public class UserProfileState {
+ private String username = "";
+ private Map> savedPlaces = new HashMap<>();
+ private String error;
+
+ public UserProfileState(UserProfileState copy) {
+ username = copy.username;
+ savedPlaces = copy.savedPlaces;
+ }
+
+ public UserProfileState() {
+
+ }
+
+ public String getName() {
+ return username;
+ }
+
+ public Map> getSavedPlaces() {
+ return savedPlaces;
+ }
+
+ public void setSavedPlaces(Map> savedPlaces) {
+ this.savedPlaces = savedPlaces;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getError() {
+ return error;
+ }
+
+ public void setError(String error) {
+ this.error = error;
+ }
+}
diff --git a/src/main/java/interface_adapter/user_profile/UserProfileViewModel.java b/src/main/java/interface_adapter/user_profile/UserProfileViewModel.java
new file mode 100644
index 000000000..d050dea1a
--- /dev/null
+++ b/src/main/java/interface_adapter/user_profile/UserProfileViewModel.java
@@ -0,0 +1,36 @@
+package interface_adapter.user_profile;
+
+import interface_adapter.ViewModel;
+
+/**
+ * View model for the user profile.
+ */
+public class UserProfileViewModel extends ViewModel {
+
+ public UserProfileViewModel() {
+ super("User Profile");
+ setState(new UserProfileState());
+ }
+// private String successMessage;
+// private String errorMessage;
+//
+// public UserProfileViewModel() {
+// super("User Profile");
+// }
+//
+// public String getSuccessMessage() {
+// return successMessage;
+// }
+//
+// public void setSuccessMessage(String successMessage) {
+// this.successMessage = successMessage;
+// }
+//
+// public String getErrorMessage() {
+// return errorMessage;
+// }
+//
+// public void setErrorMessage(String errorMessage) {
+// this.errorMessage = errorMessage;
+// }
+}
diff --git a/src/main/java/use_case/note/DataAccessException.java b/src/main/java/use_case/DataAccessException.java
similarity index 89%
rename from src/main/java/use_case/note/DataAccessException.java
rename to src/main/java/use_case/DataAccessException.java
index b8c17920d..59cf779b3 100644
--- a/src/main/java/use_case/note/DataAccessException.java
+++ b/src/main/java/use_case/DataAccessException.java
@@ -1,4 +1,4 @@
-package use_case.note;
+package use_case;
/**
* Exception thrown when there is an error with accessing data.
diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarDataAccessInterface.java b/src/main/java/use_case/add_to_calendar/AddToCalendarDataAccessInterface.java
new file mode 100644
index 000000000..13f07fc05
--- /dev/null
+++ b/src/main/java/use_case/add_to_calendar/AddToCalendarDataAccessInterface.java
@@ -0,0 +1,32 @@
+package use_case.add_to_calendar;
+
+import entity.Place;
+
+/**
+ * Interface for the AddToCalendar DAO. It consists of methods for adding locations to the calendar.
+ */
+public interface AddToCalendarDataAccessInterface {
+
+ /**
+ * Checks if the given Place exists.
+ * @param location the name of the location to look for.
+ * @return true if a Place with the given name exists; false otherwise
+ */
+ boolean hasLocation(Place location);
+
+ /**
+ * Checks if the given time is available.
+ * @param time the time of the visit to look for
+ * @return true if the timeslot is already full; false otherwise
+ */
+ boolean hasTime(String time);
+
+ /**
+ * Saves the location and time to calendar.
+ * @param location the location to save
+ * @param time the time to save
+ */
+ void save(Place location, String time);
+
+
+}
diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarInputBoundary.java b/src/main/java/use_case/add_to_calendar/AddToCalendarInputBoundary.java
new file mode 100644
index 000000000..aec1930cf
--- /dev/null
+++ b/src/main/java/use_case/add_to_calendar/AddToCalendarInputBoundary.java
@@ -0,0 +1,23 @@
+package use_case.add_to_calendar;
+
+import use_case.DataAccessException;
+
+/**
+* The Add to Calendar Use Case.
+*/
+public interface AddToCalendarInputBoundary {
+
+ /**
+ * Execute the Add To Calendar Use Case.
+ *
+ * @param addToCalendarInputData the input data for this use case
+ * @throws DataAccessException if data cannot be accessed at any time
+ */
+ void execute(AddToCalendarInputData addToCalendarInputData) throws DataAccessException;
+
+ /**
+ * Execute the switch to location view.
+ */
+ void switchToLocationView();
+
+}
diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarInputData.java b/src/main/java/use_case/add_to_calendar/AddToCalendarInputData.java
new file mode 100644
index 000000000..a81445c4e
--- /dev/null
+++ b/src/main/java/use_case/add_to_calendar/AddToCalendarInputData.java
@@ -0,0 +1,21 @@
+package use_case.add_to_calendar;
+
+import java.util.Map;
+
+import entity.Place;
+
+/**
+ * The input data for the Add to Calendar Use Case.
+ */
+public class AddToCalendarInputData {
+
+ private final Map addToCalendarPlace;
+
+ public AddToCalendarInputData(Map addToCalendarPlace) {
+ this.addToCalendarPlace = addToCalendarPlace;
+ }
+
+ public Map getAddToCalendarPlace() {
+ return addToCalendarPlace;
+ }
+}
diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarInteractor.java b/src/main/java/use_case/add_to_calendar/AddToCalendarInteractor.java
new file mode 100644
index 000000000..a3a94f763
--- /dev/null
+++ b/src/main/java/use_case/add_to_calendar/AddToCalendarInteractor.java
@@ -0,0 +1,42 @@
+package use_case.add_to_calendar;
+
+import java.util.Map;
+
+import entity.Place;
+import use_case.DataAccessException;
+
+/**
+ * The Add to Calendar Interactor.
+ */
+public class AddToCalendarInteractor implements AddToCalendarInputBoundary {
+ private final AddToCalendarDataAccessInterface calendarDataAccessObject;
+ private final AddToCalendarOutputBoundary calendarPresenter;
+
+ public AddToCalendarInteractor(AddToCalendarDataAccessInterface calendarDataAccessObject,
+ AddToCalendarOutputBoundary calendarPresenter) {
+ this.calendarDataAccessObject = calendarDataAccessObject;
+ this.calendarPresenter = calendarPresenter;
+ }
+
+ @Override
+ public void execute(AddToCalendarInputData addToCalendarInputData) throws DataAccessException {
+ final Map addToCalendarPlace = addToCalendarInputData.getAddToCalendarPlace();
+ for (Map.Entry entry : addToCalendarPlace.entrySet()) {
+ final Place location = entry.getKey();
+ final String time = entry.getValue();
+ if (calendarDataAccessObject.hasTime(time)) {
+ calendarPresenter.prepareFailView(time + " is already full.");
+ }
+ else {
+ calendarDataAccessObject.save(location, time);
+ }
+ }
+ final AddToCalendarOutputData addToCalendarOutputData = new AddToCalendarOutputData(addToCalendarPlace);
+ calendarPresenter.prepareSuccessView(addToCalendarOutputData);
+ }
+
+ @Override
+ public void switchToLocationView() {
+ calendarPresenter.switchToLocationView();
+ }
+}
diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarOutputBoundary.java b/src/main/java/use_case/add_to_calendar/AddToCalendarOutputBoundary.java
new file mode 100644
index 000000000..7abf6266e
--- /dev/null
+++ b/src/main/java/use_case/add_to_calendar/AddToCalendarOutputBoundary.java
@@ -0,0 +1,24 @@
+package use_case.add_to_calendar;
+
+/**
+ * The output boundary for the Add to Calendar Use Case.
+ */
+public interface AddToCalendarOutputBoundary {
+
+ /**
+ * Prepares the success view for the AddToCalendar Use Case.
+ * @param outputData the output data
+ */
+ void prepareSuccessView(AddToCalendarOutputData outputData);
+
+ /**
+ * Prepares the failure view for the AddToCalendar Use Case.
+ * @param errorMessage the explanation of the failure
+ */
+ void prepareFailView(String errorMessage);
+
+ /**
+ * Execute the switch to location view.
+ */
+ void switchToLocationView();
+}
diff --git a/src/main/java/use_case/add_to_calendar/AddToCalendarOutputData.java b/src/main/java/use_case/add_to_calendar/AddToCalendarOutputData.java
new file mode 100644
index 000000000..153eb5aa5
--- /dev/null
+++ b/src/main/java/use_case/add_to_calendar/AddToCalendarOutputData.java
@@ -0,0 +1,21 @@
+package use_case.add_to_calendar;
+
+import java.util.Map;
+
+import entity.Place;
+
+/**
+ * The output data for the Add to Calendar Use Case.
+ */
+public class AddToCalendarOutputData {
+
+ private final Map calendarItems;
+
+ public AddToCalendarOutputData(Map addToCalendarPlace) {
+ this.calendarItems = addToCalendarPlace;
+ }
+
+ public Map getcalendarItems() {
+ return calendarItems;
+ }
+}
diff --git a/src/main/java/use_case/locations/LocationDataAccessInterface.java b/src/main/java/use_case/locations/LocationDataAccessInterface.java
new file mode 100644
index 000000000..b6a40331c
--- /dev/null
+++ b/src/main/java/use_case/locations/LocationDataAccessInterface.java
@@ -0,0 +1,23 @@
+package use_case.locations;
+
+import java.util.List;
+
+import entity.Place;
+import use_case.DataAccessException;
+
+/**
+ * Interface for the LocationDAO. It consists of methods for
+ * searching locations
+ */
+public interface LocationDataAccessInterface {
+
+ /**
+ * Gets a list of locations based on address given.
+ * @param address address the user gives
+ * @param locationType the type of location
+ * @return a list of locations
+ * @throws DataAccessException if the location can not be loaded for any reason
+ */
+ List searchLocation(String address, String locationType) throws DataAccessException;
+
+}
diff --git a/src/main/java/use_case/locations/LocationsInputBoundary.java b/src/main/java/use_case/locations/LocationsInputBoundary.java
new file mode 100644
index 000000000..838406368
--- /dev/null
+++ b/src/main/java/use_case/locations/LocationsInputBoundary.java
@@ -0,0 +1,17 @@
+package use_case.locations;
+
+import use_case.DataAccessException;
+
+/**
+ * The Suggest Locations Use Case.
+ */
+public interface LocationsInputBoundary {
+ /**
+ * Execute the Suggest Locations Use Case.
+ *
+ * @param locationsInputData the input data for this use case
+ * @param currentFilter
+ * @throws DataAccessException if data cannot be accessed at any time
+ */
+ void execute(LocationsInputData locationsInputData, String currentFilter) throws DataAccessException;
+}
diff --git a/src/main/java/use_case/locations/LocationsInputData.java b/src/main/java/use_case/locations/LocationsInputData.java
new file mode 100644
index 000000000..86b44a84f
--- /dev/null
+++ b/src/main/java/use_case/locations/LocationsInputData.java
@@ -0,0 +1,30 @@
+package use_case.locations;
+
+/**
+ * The input data for the Suggest Locations Use Case.
+ */
+public class LocationsInputData {
+
+ private final String address;
+ private final String locationType;
+ private final String username;
+
+ public LocationsInputData(String address, String locationType, String username) {
+ this.address = address;
+ this.locationType = locationType;
+ this.username = username;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public String getLocationType() {
+ return locationType;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+}
diff --git a/src/main/java/use_case/locations/LocationsInteractor.java b/src/main/java/use_case/locations/LocationsInteractor.java
new file mode 100644
index 000000000..d8a805436
--- /dev/null
+++ b/src/main/java/use_case/locations/LocationsInteractor.java
@@ -0,0 +1,52 @@
+package use_case.locations;
+
+import data_access.InMemoryUserDataAccessObject;
+import entity.Place;
+import interface_adapter.user_profile.UserProfileState;
+import use_case.DataAccessException;
+import entity.User;
+import use_case.user_profile.UserProfileDataAccessInterface;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The Suggest Locations Interactor.
+ */
+public class LocationsInteractor implements LocationsInputBoundary {
+ private final LocationDataAccessInterface placeDataAccessObject;
+ private final LocationsOutputBoundary placePresenter;
+ private final UserProfileDataAccessInterface userDataAccessObject;
+
+ public LocationsInteractor(LocationDataAccessInterface suggestLocationsPlaceDataAccessInterface,
+ LocationsOutputBoundary locationsOutputBoundary,
+ UserProfileDataAccessInterface userDataAccessObject) {
+ this.placeDataAccessObject = suggestLocationsPlaceDataAccessInterface;
+ this.placePresenter = locationsOutputBoundary;
+ this.userDataAccessObject = userDataAccessObject;
+ }
+
+ @Override
+ public void execute(LocationsInputData locationsInputData, String currentFilter) throws DataAccessException {
+ final List suggestedPlaces = placeDataAccessObject
+ .searchLocation(locationsInputData.getAddress(), locationsInputData.getLocationType());
+
+ if ("None".equals(currentFilter)) {
+ final LocationsOutputData locationsOutputData = new LocationsOutputData(placeDataAccessObject
+ .searchLocation(locationsInputData.getAddress(), locationsInputData.getLocationType()),
+ false);
+ placePresenter.prepareSuccessView(locationsOutputData);
+ } else if ("Remove Saved Locations".equals(currentFilter)) {
+ for (Place place : suggestedPlaces) {
+ final User user = userDataAccessObject.getUser(locationsInputData.getUsername());
+ for (Map.Entry> entry : user.getSavedPlaces().entrySet()) {
+ if (entry.getValue().contains(place)) {
+ suggestedPlaces.remove(place);
+ }
+ }
+ }
+ final LocationsOutputData locationsOutputData = new LocationsOutputData(suggestedPlaces, false);
+ placePresenter.prepareSuccessView(locationsOutputData);
+ }
+ }
+}
diff --git a/src/main/java/use_case/locations/LocationsOutputBoundary.java b/src/main/java/use_case/locations/LocationsOutputBoundary.java
new file mode 100644
index 000000000..904014a0b
--- /dev/null
+++ b/src/main/java/use_case/locations/LocationsOutputBoundary.java
@@ -0,0 +1,18 @@
+package use_case.locations;
+
+/**
+ * The output boundary for the Suggest Locations Use Case.
+ */
+public interface LocationsOutputBoundary {
+ /**
+ * Prepares the success view for the Suggest Locations Use Case.
+ * @param outputData the output data
+ */
+ void prepareSuccessView(LocationsOutputData outputData);
+
+ /**
+ * Prepares the failure view for the SuggestLocations Use Case.
+ * @param errorMessage the explanation of the failure
+ */
+ void prepareFailView(String errorMessage);
+}
diff --git a/src/main/java/use_case/locations/LocationsOutputData.java b/src/main/java/use_case/locations/LocationsOutputData.java
new file mode 100644
index 000000000..01d04795f
--- /dev/null
+++ b/src/main/java/use_case/locations/LocationsOutputData.java
@@ -0,0 +1,23 @@
+package use_case.locations;
+
+import java.util.List;
+
+import entity.Place;
+
+/**
+ * Output Data for the Suggest Locations Use Case.
+ */
+public class LocationsOutputData {
+
+ private final List locations;
+ private final boolean useCaseFailed;
+
+ public LocationsOutputData(List locations, boolean useCaseFailed) {
+ this.locations = locations;
+ this.useCaseFailed = useCaseFailed;
+ }
+
+ public List getLocations() {
+ return locations;
+ }
+}
diff --git a/src/main/java/use_case/login/LoginInputBoundary.java b/src/main/java/use_case/login/LoginInputBoundary.java
new file mode 100644
index 000000000..cb696b1e8
--- /dev/null
+++ b/src/main/java/use_case/login/LoginInputBoundary.java
@@ -0,0 +1,18 @@
+package use_case.login;
+
+/**
+ * Input Boundary for actions which are related to logging in.
+ */
+public interface LoginInputBoundary {
+
+ /**
+ * Executes the login use case.
+ * @param loginInputData the input data
+ */
+ void execute(LoginInputData loginInputData);
+
+ /**
+ * Executes the switch back to sign up view
+ */
+ void switchToSignUpView();
+}
diff --git a/src/main/java/use_case/login/LoginInputData.java b/src/main/java/use_case/login/LoginInputData.java
new file mode 100644
index 000000000..363316832
--- /dev/null
+++ b/src/main/java/use_case/login/LoginInputData.java
@@ -0,0 +1,24 @@
+package use_case.login;
+
+/**
+ * The Input Data for the Login Use Case.
+ */
+public class LoginInputData {
+
+ private final String username;
+ private final String password;
+
+ public LoginInputData(String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ String getUsername() {
+ return username;
+ }
+
+ String getPassword() {
+ return password;
+ }
+
+}
diff --git a/src/main/java/use_case/login/LoginInteractor.java b/src/main/java/use_case/login/LoginInteractor.java
new file mode 100644
index 000000000..a856b9f56
--- /dev/null
+++ b/src/main/java/use_case/login/LoginInteractor.java
@@ -0,0 +1,44 @@
+package use_case.login;
+
+import entity.User;
+import use_case.user_profile.UserProfileDataAccessInterface;
+
+/**
+ * The Login Interactor.
+ */
+public class LoginInteractor implements LoginInputBoundary {
+ private final LoginUserDataAccessInterface userDataAccessObject;
+ private final LoginOutputBoundary loginPresenter;
+
+ public LoginInteractor(LoginUserDataAccessInterface userDataAccessInterface,
+ LoginOutputBoundary loginOutputBoundary) {
+ this.userDataAccessObject = userDataAccessInterface;
+ this.loginPresenter = loginOutputBoundary;
+ }
+
+ @Override
+ public void execute(LoginInputData loginInputData) {
+ final String username = loginInputData.getUsername();
+ final String password = loginInputData.getPassword();
+ if (!userDataAccessObject.existsByName(username)) {
+ loginPresenter.prepareFailView(username + ": Account does not exist.");
+ }
+ else {
+ final String pwd = userDataAccessObject.get(username).getPassword();
+ if (!password.equals(pwd)) {
+ loginPresenter.prepareFailView("Incorrect password for \"" + username + "\".");
+ }
+ else {
+
+ final User user = userDataAccessObject.get(loginInputData.getUsername());
+ final LoginOutputData loginOutputData = new LoginOutputData(user.getName(), false);
+ loginPresenter.prepareSuccessView(loginOutputData);
+ }
+ }
+ }
+
+ @Override
+ public void switchToSignUpView() {
+ loginPresenter.switchToSignUpView();
+ }
+}
diff --git a/src/main/java/use_case/login/LoginOutputBoundary.java b/src/main/java/use_case/login/LoginOutputBoundary.java
new file mode 100644
index 000000000..81c6934f3
--- /dev/null
+++ b/src/main/java/use_case/login/LoginOutputBoundary.java
@@ -0,0 +1,23 @@
+package use_case.login;
+
+/**
+ * The output boundary for the Login Use Case.
+ */
+public interface LoginOutputBoundary {
+ /**
+ * Prepares the success view for the Login Use Case.
+ * @param outputData the output data
+ */
+ void prepareSuccessView(LoginOutputData outputData);
+
+ /**
+ * Prepares the failure view for the Login Use Case.
+ * @param errorMessage the explanation of the failure
+ */
+ void prepareFailView(String errorMessage);
+
+ /**
+ * Switches to the SignUp View.
+ */
+ void switchToSignUpView();
+}
diff --git a/src/main/java/use_case/login/LoginOutputData.java b/src/main/java/use_case/login/LoginOutputData.java
new file mode 100644
index 000000000..3ea119a8f
--- /dev/null
+++ b/src/main/java/use_case/login/LoginOutputData.java
@@ -0,0 +1,20 @@
+package use_case.login;
+
+/**
+ * Output Data for the Login Use Case.
+ */
+public class LoginOutputData {
+
+ private final String username;
+ private final boolean useCaseFailed;
+
+ public LoginOutputData(String username, boolean useCaseFailed) {
+ this.username = username;
+ this.useCaseFailed = useCaseFailed;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+}
diff --git a/src/main/java/use_case/login/LoginUserDataAccessInterface.java b/src/main/java/use_case/login/LoginUserDataAccessInterface.java
new file mode 100644
index 000000000..60e744d78
--- /dev/null
+++ b/src/main/java/use_case/login/LoginUserDataAccessInterface.java
@@ -0,0 +1,29 @@
+package use_case.login;
+
+import entity.User;
+
+/**
+ * DAO for the Login Use Case.
+ */
+public interface LoginUserDataAccessInterface {
+
+ /**
+ * Checks if the given username exists.
+ * @param username the username to look for
+ * @return true if a user with the given username exists; false otherwise
+ */
+ boolean existsByName(String username);
+
+ /**
+ * Saves the user.
+ * @param user the user to save
+ */
+ void save(User user);
+
+ /**
+ * Returns the user with the given username.
+ * @param username the username to look up
+ * @return the user with the given username
+ */
+ User get(String username);
+}
diff --git a/src/main/java/use_case/note/NoteDataAccessInterface.java b/src/main/java/use_case/note/NoteDataAccessInterface.java
deleted file mode 100644
index b71597828..000000000
--- a/src/main/java/use_case/note/NoteDataAccessInterface.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package use_case.note;
-
-import entity.User;
-
-/**
- * Interface for the NoteDAO. It consists of methods for
- * both loading and saving a note.
- */
-public interface NoteDataAccessInterface {
-
- /**
- * Saves a note for a given user. This will replace any existing note.
- *