diff --git a/.gitignore b/.gitignore
index 650c91720..de35550b8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@ out/
!**/src/main/**/out/
!**/src/test/**/out/
.idea/easycode.ignore
+.env
target/
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index 712ab9d98..7f6fdadd1 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -1,11 +1,21 @@
+
+
+
+
+
+
+
+
+
+
@@ -16,5 +26,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 5e1d8b77c..853dea7e5 100644
--- a/README.md
+++ b/README.md
@@ -1,36 +1,116 @@
-# Note Application
+# ZenTask
-This is a minimal example demonstrating usage of the
-password-protected user part of the API used in lab 5.
+## Authors of the Project
+1. Iguehi Akhimien - GitHub username: iguehi.akhimien
+2. Jenna Zhang - GitHub username: stickycorner
+3. Prisha Patel - GitHub username: PrishaPatel24
+4. Liza Kochel - GitHub username: lizakochel
-You can find more information about the API endpoints in
-[the documentation](https://www.postman.com/cloudy-astronaut-813156/csc207-grade-apis-demo/documentation/fg3zkjm/5-password-protected-user).
+## Summary of the Project
+This project focuses on building a productivity app that allows the user to take notes, make a checklist list, and add events to their calendar.
+This project was made to serve students, working professionals or anyone who want to better manage life.
+Life can be hectic. Our goal is to create peace for the user, allowing them to manage life from one point.
+From the onset of the project, the vision was to find a way to make a student's productivity convenient and all in one place.
+So, the authors of the project created a "one-stop" life-management dashboard.
-If your team is considering an application for which it would be convenient to
-store data in something like a database, you may find that the API calls demonstrated
-here will be useful in your project, as this will allow you to store
-an arbitrary JSON object associated with a username and password.
+### User Benefits:
+* As a user, you can create a note within the program (although not save it permanently) to probably note down things you do not want to forget.
+To help you, we have included a couple of features, such as translating text to a preferred language and completing your notes using Artificial Intelligence.
+* As a user, you can also make a checklist of all your important tasks or things you do not want to procrastinate.
+To keep track of things, you can tick off tasks as you go about completing them.
+* As a user, you can see your upcoming events at a view while planning to complete your tasks on your checklist or when you are planning time to revisit what you noted down.
-In this application, a single note has a name (the "username" in terms of the API) and the note
-can be read by anyone who knows the name — but only edited by someone who
-knows the password for it.
+**ZenTask brings everything together!**
-You can see the documentation in the various files for more information.
+## Table of Contents
+1. Features of the Software ([Jump to Features of the Software](#features-of-the-software))
+2. Installation Instructions ([Jump to Installation Instructions](#installation-instructions))
+3. Usage Guide ([Jump to Usage Guide](#usage-guide))
+4. License ([Jump to License](#license))
+5. Feedback ([Jump to Feedback](#feedback))
+6. Contributions ([Jump to Contributions](#contributions))
-## Testing
-The repo also includes an example of a use case interactor test, as well as
-an example of an end-to-end test which automates button clicks and inspects
-the contents of the actual views. This is something we discussed in the lectures
-about testing in CA but had not provided a code example of before. Note, one
-could also inspect the contents of the ViewModel objects instead when testing
-CA to make a similar test which would be less dependent on the details of the
-specific UI implementation.
+## Features of the Software
+There are three major components of this software: Calendar, Checklist and Notes.
+So, upon running the program, the user first sees "Welcome to your Dashboard"
+__// TODO: add a screenshot__
+On the left of the Dashboard, the user sees three tabs: Calendar, Notes and Checklist.
-## Project Starter Code
+### Calendar
+The user can easily migrate to the Calendar tab by clicking on it.
+__// TODO: add a screenshot__
+Now, the user is on the Calendar tab. They are prompted to enter their __Google Email__.
+__// TODO: add a screenshot__
+This displays the upcoming events the user has added in on their Google calendar.
+The details displayed are the event summary, location, start time, and description.
-Your team may choose to use this repo as starter code for your project. You could
-also use the lab 5 code — or start from an empty repo if your team prefers.
+__Note regarding Calendar Usage:__ Since we are unable to release our private project credentials, you should add your
+own service account credentials in a json file somewhere in the project and add the path to the file in the CalendarRequest section.
+Change the SERVICE_ACCOUNT_KEY_FILE attribute to the path and the calender should be properly
+integrated to use your new own Google project credentials.
-If you choose to use one of the repositories we have provided, you can either make
-a fork of it or copy the subset of code you want into a completely new repository.
+### Notes
+The user can also go to the Notes tab by clicking the menu on the left of their view.
+__// TODO: add a screenshot__
+Now, the user is on the Notes tab.
+On the left side of the user's view, they can create a new note by simply typing into the provided area that says "*_Create Note_*"
+The user also has the option of uploading text from an already existing file.
+__// I am thinking of any style functions and undo, and redo...//__
+As additional functionalities, the user can translate existing text on their notes to either French, Spanish, Russian.
+Also, the user can prompt AI to complete the note based on what the user has written.
+
+### Checklist
+The user can move to the Checklist tab by clicking the menu on the left of their view.
+__// TODO: add a screenshot__
+Now, the user is on the Checklist tab.
+On the user's view, the user will see add task.
+__// TODO: add a screenshot__
+This will allow the user to make a new checklist or add new tasks to an already existing checklist.
+
+
+## Installation Instructions
+As the user, you should ensure that their IDE is working and already setup. If you need any help setting up,
+[visit here](https://www.jetbrains.com/help/idea/getting-started.html). The program can be run on any OS.
+To run the program, there are two options:
+1. __Through the IDE:__
+ 1. First, you have to clone the repo, by using [this URL](https://github.com/PrishaPatel24/ZenTask.git).
+ 2. Then, run the MainNoteApplication found in the src/main/java/app of the project through the IDE.
+2. __Through the terminal:__
+ 1. First, you have to clone the repo, by using [this URL](https://github.com/PrishaPatel24/ZenTask.git).
+ 2. Navigate to the directory where the MainNoteApplication is on, in your File Manager
+ (ensure the directory is like .../ZenTask/src/main/java/app).
+ 3. Then, open the terminal there.
+ 4. In you terminal, compile the program by using `javac MainNoteApplication.java`
+ 5. Then, run the application, using `java MainNoteApplication`
+ 6. You should see your Dashboard. __// TODO: add a screenshot__
+
+## Usage Guide
+To use the software, the user should navigate the tabs using the menu found on the left of the view.
+__// TODO: add a screenshot__
+
+## License
+To view the License consistent with the details and use of this program, please refer to the file name **LICENSE** in the project directory.
+
+## Feedback
+As a user, you can give feedback on the software, using [this link](https://forms.gle/mA2Q9dh3G84v8RdW7).
+Please, take your time to carefully fill out the form and should expect a follow-up with 2-3 business days.
+
+## Contributions
+All contributions to the project are welcome.
+To contribute to the project, you have to follow these steps:
+1. Make a fork of the [project](https://github.com/PrishaPatel24/ZenTask) on GitHub by right-clicking _Fork_ found on the top right of the GitHub page.
+Then, create a new fork. __// TODO: add a screenshot__
+2. Then, clone the repo and work from your IDE.
+3. Do not forget to add a branch protection rule, especially if you are working with other people. Ensure everyone has their branch.
+Then, they will need to make a pull request on your own fork of the repository ([do this through the IDE](https://www.jetbrains.com/help/idea/work-with-github-pull-requests.html#create-pull-request)),
+explaining in detail what changes they have made, and perform a [code review](https://swimm.io/learn/code-reviews/ultimate-10-step-code-review-checklist).
+4. To add your contributions to this project, you have to make a merge request.
+5. To make a merge request, first navigate to the back to [this project's repository](https://github.com/PrishaPatel24/ZenTask).
+6. Then, on top of the GitHub page, click on _Pull Requests_. __// TODO: add a screenshot__
+7. Click on the green button on the left of the GitHub page to create a _New pull request_.
+8. Then, set the base repository to [this project's repository](https://github.com/PrishaPatel24/ZenTask) and set base to _main_.
+9. Similarly, set the head repository to be your fork of the repository and set base to main.
+10. Then, click on the green button, _Create pull request_. __// TODO: add a screenshot__
+11. In the pull request, add a title that properly summarizes the content of the "contribution".
+Also, add a proper description that contain what changes you made or things you added, what files your worked on and why this contribution is meaningful and beneficial.
diff --git a/accessibility-report.md b/accessibility-report.md
new file mode 100644
index 000000000..05f09c34d
--- /dev/null
+++ b/accessibility-report.md
@@ -0,0 +1,39 @@
+## 1. Principles of Universal Design
+- Equitable Use: The translation feature allows users who speak other languages to interact with our program. Since the
+ interface is easy to use and straightforward, users with varying levels of technical knowledge can use the program.
+- Flexibility in Use: The program has multiple functionalities, including note-taking, checklists for tasks, a calendar
+ for event management, language translation, and AI-assisted completion. Users can choose how they interact with the
+ program, whether they organize tasks, translate content, or write notes. This accommodates different workflows and
+ user needs.
+- Simple and Intuitive Use: The program has clearly-labeled buttons like "Translate", "Complete Notes With AI", and "Add
+ Task" so that users can intuitively navigate the app. The checklist and calendar are straightforward and allow users to
+ add tasks or events without much effort.
+- Perceptible Information: Information is presented visually through text areas, dropdown menus, and buttons, which makes
+ the program easy to understand. For example, the dropdown menu for language selection is simple and easy to locate,
+ and the translation output is displayed in a separate area so that users can distinguish between the original text and
+ the translated text.
+- Tolerance for Error: If users attempt to translate notes that are too long, the program provides feedback ("Exceeded
+ character limit") instead of crashing. The checklist and calendar features allow users to update or remove entries so
+ that mistakes can be easily fixed.
+- Low Physical Effort: Tasks such as adding events to the calendar, updating the checklist, or translating text are
+ simplified and made more efficient for the user. The AI-assisted note completion feature helps users save time and effort
+ by automatically filling in ideas or suggestions, so that users don’t have to type it all out themselves.
+- Size and Space for Approach and Use: The program can be used on standard desktop or laptop screens and has well-spaced
+ buttons and input fields that are easy to access. The dropdown menu and text areas are appropriately sized so that it's
+ user-friendly.
+
+## 2. Marketing
+If we were to sell or license ZenTask to customers, we would primarily market our program to students and professionals.
+Since it has note-taking and translation features, our program would be particularly useful for multilingual users,
+exchange students or students studying foreign languages, and professionals who are working in multicultural environments
+or abroad. The "Complete Notes with AI" feature is helpful for students and writers needing additional assistance, and
+the checklist and calendar features can be used by anyone with a busy schedule that could benefit from organizing their
+tasks, deadlines, and scheduled events.
+
+## 3. Demographic Challenges
+This program may be less likely to be used by those who are visually impaired since this program does not have
+screen readers or voice navigation to make it more suitable for those users. Implementing a text-to-speech feature
+would help reach a wider audience of users and make it more accessible. This program is also less likely to be
+used by those with dyslexia or reading impairments since it does not include spell-checking and the size of the text cannot
+be increased. To accommodate for these users, in the future we could implement a feature that allows people to create
+text by speaking instead of typing.
diff --git a/pom.xml b/pom.xml
index 527f61e36..322ba7eb1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,98 @@
note-application1.0-SNAPSHOT
+
+
+ central
+ https://repo.maven.apache.org/maven2
+
+
+ google-maven-repository
+ https://maven-central.storage-download.googleapis.com/maven2/
+
+
+ dynomakeRepository
+ https://maven.dynomake.space/releases
+
+
+
+
+ io.github.cdimascio
+ dotenv-java
+ 3.0.0
+
+
+
+ com.cohere
+ cohere-java
+ 1.4.1
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.13.0
+
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.13.0
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ 2.13.0
+
+
+
+ com.google.oauth-client
+ google-oauth-client
+ 1.34.1
+
+
+
+ com.google.api-client
+ google-api-client
+ 1.34.0
+
+
+
+ com.google.oauth-client
+ google-oauth-client-java6
+ 1.23.0
+
+
+
+ com.google.oauth-client
+ google-oauth-client-jetty
+ 1.34.1
+
+
+
+ com.google.apis
+ google-api-services-calendar
+ v3-rev20240705-2.0.0
+
+
+
+ com.google.http-client
+ google-http-client-jackson2
+ 1.34.0
+
+
+
+ org.mortbay.jetty
+ jetty
+ 6.1.26
+
+
+
+ com.google.cloud
+ google-cloud-aiplatform
+ 3.35.0
+ org.json
@@ -27,6 +118,11 @@
4.13.1test
+
+ space.dynomake
+ libretranslate-java
+ 1.0.9
+
diff --git a/src/main/java/app/MainNoteApplication.java b/src/main/java/app/MainNoteApplication.java
index c37860156..04b6fa36b 100644
--- a/src/main/java/app/MainNoteApplication.java
+++ b/src/main/java/app/MainNoteApplication.java
@@ -1,56 +1,163 @@
package app;
-import data_access.DBNoteDataAccessObject;
-import use_case.note.NoteDataAccessInterface;
+import data_access.InMemoryNoteDataAccessObject;
+import interface_adapter.add_task.AddTaskController;
+import interface_adapter.add_task.AddTaskPresenter;
+import interface_adapter.add_task.TaskViewModel;
+
+import interface_adapter.note.NoteController;
+import interface_adapter.note.NotePresenter;
+import interface_adapter.note.NoteViewModel;
+
+import interface_adapter.ai.AiController;
+import interface_adapter.ai.AiPresenter;
+
+import interface_adapter.calendar.CalendarController;
+import interface_adapter.calendar.CalendarPresenter;
+import interface_adapter.translation.TranslationController;
+import interface_adapter.translation.TranslationPresenter;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.*;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+
+import use_cases.add_task.AddTaskInputBoundary;
+import use_cases.add_task.AddTaskInteractor;
+import use_cases.add_task.AddTaskOutputBoundary;
+
+import use_cases.note.NoteInputBoundary;
+import use_cases.note.NoteInteractor;
+import use_cases.note.NoteOutputBoundary;
+
+import use_cases.ai.AiInputBoundary;
+import use_cases.ai.AiInteractor;
+import use_cases.ai.AiOutputBoundary;
+import use_cases.ai.AiRequest;
+
+import use_cases.calendar.CalendarInputBoundary;
+import use_cases.calendar.CalendarInteractor;
+import use_cases.calendar.CalendarOutputBoundary;
+import use_cases.calendar.CalendarRequest;
+
+import use_cases.note.TranslationInputBoundary;
+import use_cases.note.TranslationInteractor;
+import use_cases.note.TranslationOutputBoundary;
+
+import view.CalendarView;
+import view.ChecklistView;
+import view.DashboardView;
+import view.NotesView;
/**
- * 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.
+ * The main application to boot the program.
*/
public class MainNoteApplication {
+ static final int WIDTH = 1100;
+ static final int HEIGHT = 500;
- /**
- * 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) {
+ SwingUtilities.invokeLater(() -> {
+ final CardLayout cardLayout = new CardLayout();
+ final JPanel cardPanel = new JPanel(cardLayout);
+
+ final JPanel dashboardPanel = new DashboardView();
+ final JPanel notesPanel = createNotes();
+ final JPanel calendarPanel;
+ try {
+ calendarPanel = createCalendar();
+ }
+ catch (GeneralSecurityException | IOException exception) {
+ throw new RuntimeException(exception);
+ }
+ final JPanel checklistPanel = createChecklist();
+
+ cardPanel.add(dashboardPanel, "Dashboard");
+ cardPanel.add(notesPanel, "Notes");
+ cardPanel.add(calendarPanel, "Calendar");
+ cardPanel.add(checklistPanel, "Checklist");
- // create the data access and inject it into our builder!
- final NoteDataAccessInterface noteDataAccess = new DBNoteDataAccessObject();
+ final JPanel buttonPanel = getButtonPanel(cardLayout, cardPanel);
+
+ final JPanel mainPanel = new JPanel(new BorderLayout());
+ mainPanel.add(buttonPanel, BorderLayout.WEST);
+ mainPanel.add(cardPanel, BorderLayout.CENTER);
+
+ final JFrame frame = new JFrame("ZenTask");
+ frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+ frame.setSize(WIDTH, HEIGHT);
+ frame.setContentPane(mainPanel);
+ frame.setVisible(true);
+ });
+ }
+
+ @NotNull
+ private static JPanel getButtonPanel(CardLayout cardLayout, JPanel cardPanel) {
+ final JButton showCalendarButton = new JButton("Calendar");
+ showCalendarButton.addActionListener(event -> cardLayout.show(cardPanel, "Calendar"));
+
+ final JButton showNotesButton = new JButton("Notes");
+ showNotesButton.addActionListener(event -> cardLayout.show(cardPanel, "Notes"));
+
+ final JButton showChecklistButton = new JButton("Checklist");
+ showChecklistButton.addActionListener(event -> cardLayout.show(cardPanel, "Checklist"));
+
+ final JPanel buttonPanel = new JPanel();
+ buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS));
+
+ buttonPanel.add(showCalendarButton);
+ buttonPanel.add(showNotesButton);
+ buttonPanel.add(showChecklistButton);
+ return buttonPanel;
+ }
+
+ private static JPanel createDashboard() {
+ final JPanel dashboardPanel = new JPanel();
+ dashboardPanel.add(new JLabel("Welcome to your Dashboard"));
+ return dashboardPanel;
+ }
+
+ private static JPanel createCalendar() throws GeneralSecurityException, IOException {
+ final CalendarView calendarView = new CalendarView();
+ final CalendarOutputBoundary calendarPresenter = new CalendarPresenter(calendarView);
+ final CalendarInputBoundary calendarInteractor = new CalendarInteractor(calendarPresenter, new CalendarRequest());
+ final CalendarController calendarController = new CalendarController(calendarInteractor);
+ calendarView.setCalendarController(calendarController);
+ return calendarView;
+ }
+
+ private static JPanel createNotes() {
+ final NoteViewModel noteViewModel = new NoteViewModel();
+ final NoteOutputBoundary notePresenter = new NotePresenter(noteViewModel);
+ final InMemoryNoteDataAccessObject inMemoryNoteDAO = new InMemoryNoteDataAccessObject();
+ final NoteInputBoundary noteInteractor = new NoteInteractor(notePresenter, inMemoryNoteDAO);
+ final NoteController controller = new NoteController(noteInteractor);
+ final NotesView notesView = new NotesView(noteViewModel);
+ notesView.setNoteController(controller);
+
+ final AiOutputBoundary aiPresenter = new AiPresenter(notesView);
+ final AiRequest aiRequest = new AiRequest();
+ final AiInputBoundary aiInteractor = new AiInteractor(aiPresenter, aiRequest);
+ final AiController aiController = new AiController(aiInteractor);
+ notesView.setAiController(aiController);
+
+ final TranslationOutputBoundary translationPresenter = new TranslationPresenter(notesView);
+ final TranslationInputBoundary translationInteractor = new TranslationInteractor(translationPresenter);
+ final TranslationController translationController = new TranslationController(translationInteractor);
+ notesView.setTranslationController(translationController);
+
+ return notesView;
+ }
- final NoteAppBuilder builder = new NoteAppBuilder();
- builder.addNoteDAO(noteDataAccess)
- .addNoteView()
- .addNoteUseCase().build().setVisible(true);
+ private static JPanel createChecklist() {
+ final TaskViewModel taskViewModel = new TaskViewModel();
+ final AddTaskOutputBoundary addTaskPresenter = new AddTaskPresenter(taskViewModel);
+ final AddTaskInputBoundary addTaskUseCaseInteractor = new AddTaskInteractor(addTaskPresenter);
+ final AddTaskController controller = new AddTaskController(addTaskUseCaseInteractor);
+ final ChecklistView checklistView = new ChecklistView(taskViewModel);
+ checklistView.setTaskController(controller);
+ taskViewModel.firePropertyChanged();
+ return checklistView;
}
}
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/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/InMemoryNoteDataAccessObject.java b/src/main/java/data_access/InMemoryNoteDataAccessObject.java
new file mode 100644
index 000000000..15958b748
--- /dev/null
+++ b/src/main/java/data_access/InMemoryNoteDataAccessObject.java
@@ -0,0 +1,31 @@
+package data_access;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import entity.Note;
+import use_cases.note.NoteDataAccessInterface;
+
+/**
+ * This class implements storage of notes within a single run of the program.
+ * This does not persist data between runs of the program.
+ */
+public class InMemoryNoteDataAccessObject implements NoteDataAccessInterface {
+ private final Map notes;
+
+ public InMemoryNoteDataAccessObject() {
+ this.notes = new HashMap<>();
+ }
+
+ @Override
+ public void saveNote(String title, String note) {
+ this.notes.put(title, note);
+ }
+
+ @Override
+ public List getNotes() {
+ return new ArrayList<>(this.notes.keySet());
+ }
+}
diff --git a/src/main/java/entity/Events.java b/src/main/java/entity/Events.java
new file mode 100644
index 000000000..8104bd544
--- /dev/null
+++ b/src/main/java/entity/Events.java
@@ -0,0 +1,37 @@
+package entity;
+
+import com.google.api.services.calendar.model.EventDateTime;
+
+/**
+ * The representation of a calendar event for our program.
+ */
+public class Events {
+
+ private final String name;
+ private final EventDateTime datetime;
+ private final String location;
+ private final String notes;
+
+ public Events(String name, EventDateTime datetime, String location, String notes) {
+ this.name = name;
+ this.datetime = datetime;
+ this.location = location;
+ this.notes = notes;
+ }
+
+ public String getEventName() {
+ return name;
+ }
+
+ public String getEventDatetime() {
+ return datetime.getDateTime().toString();
+ }
+
+ public String getEventLocation() {
+ return location;
+ }
+
+ public String getEventNotes() {
+ return notes;
+ }
+}
diff --git a/src/main/java/entity/Note.java b/src/main/java/entity/Note.java
new file mode 100644
index 000000000..1e90e7415
--- /dev/null
+++ b/src/main/java/entity/Note.java
@@ -0,0 +1,32 @@
+package entity;
+
+/**
+ * The representation of a note file for this program.
+ */
+public class Note {
+
+ private String content;
+ private String title;
+
+ public Note(String content, String title) {
+ this.content = content;
+ this.title = title;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setContent(String newContent) {
+ this.content = newContent;
+ }
+
+ public void setTitle(String newTitle) {
+ this.title = newTitle;
+ }
+
+}
diff --git a/src/main/java/entity/Task.java b/src/main/java/entity/Task.java
new file mode 100644
index 000000000..39076e8f3
--- /dev/null
+++ b/src/main/java/entity/Task.java
@@ -0,0 +1,18 @@
+package entity;
+
+/**
+ * The representation of a task for this program.
+ */
+public class Task {
+
+ private final String description;
+
+ public Task(String description) {
+ this.description = description;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+}
diff --git a/src/main/java/entity/User.java b/src/main/java/entity/User.java
deleted file mode 100644
index e0c57e9a6..000000000
--- a/src/main/java/entity/User.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package entity;
-
-/**
- * The representation of a password-protected user for our program.
- */
-public class User {
-
- private final String name;
- private final String password;
-
- public User(String name, String password) {
- this.name = name;
- this.password = password;
- }
-
- public String getName() {
- return name;
- }
-
- public String getPassword() {
- return password;
- }
-
-}
diff --git a/src/main/java/interface_adapter/add_task/AddTaskController.java b/src/main/java/interface_adapter/add_task/AddTaskController.java
new file mode 100644
index 000000000..f9c41b674
--- /dev/null
+++ b/src/main/java/interface_adapter/add_task/AddTaskController.java
@@ -0,0 +1,24 @@
+package interface_adapter.add_task;
+
+import use_cases.add_task.AddTaskInputBoundary;
+import use_cases.add_task.AddTaskInputData;
+
+/**
+ * The controller for the add_task Use Case.
+ */
+public class AddTaskController {
+ private final AddTaskInputBoundary addTaskUseCaseInteractor;
+
+ public AddTaskController(AddTaskInputBoundary addTaskUseCaseInteractor) {
+ this.addTaskUseCaseInteractor = addTaskUseCaseInteractor;
+ }
+
+ /**
+ * Executes the add_task Use Case.
+ * @param description the task description
+ */
+ public void execute(String description) {
+ final AddTaskInputData addTaskInputData = new AddTaskInputData(description);
+ addTaskUseCaseInteractor.execute(addTaskInputData);
+ }
+}
diff --git a/src/main/java/interface_adapter/add_task/AddTaskPresenter.java b/src/main/java/interface_adapter/add_task/AddTaskPresenter.java
new file mode 100644
index 000000000..4596fbb99
--- /dev/null
+++ b/src/main/java/interface_adapter/add_task/AddTaskPresenter.java
@@ -0,0 +1,34 @@
+package interface_adapter.add_task;
+
+import use_cases.add_task.AddTaskOutputBoundary;
+import use_cases.add_task.AddTaskOutputData;
+
+/**
+ * The presenter for the add_task use case.
+ */
+public class AddTaskPresenter implements AddTaskOutputBoundary {
+ private final TaskViewModel taskViewModel;
+
+ public AddTaskPresenter(TaskViewModel taskViewModel) {
+ this.taskViewModel = taskViewModel;
+ }
+
+ @Override
+ public void prepareSuccessView(AddTaskOutputData response) {
+ // On success, add task to the view.
+
+ final TaskState taskState = taskViewModel.getState();
+ taskState.addTask(response.getDescription());
+ taskState.setError(null);
+ this.taskViewModel.setState(taskState);
+ taskViewModel.firePropertyChanged();
+ }
+
+ // Will not need fail view (there's no way to fail adding a task)
+ @Override
+ public void prepareFailView(String error) {
+ final TaskState taskState = taskViewModel.getState();
+ taskState.setError(error);
+ taskViewModel.firePropertyChanged();
+ }
+}
diff --git a/src/main/java/interface_adapter/add_task/TaskState.java b/src/main/java/interface_adapter/add_task/TaskState.java
new file mode 100644
index 000000000..5c93ad91e
--- /dev/null
+++ b/src/main/java/interface_adapter/add_task/TaskState.java
@@ -0,0 +1,38 @@
+package interface_adapter.add_task;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import entity.Task;
+
+/**
+ * The State for a task.
+ */
+public class TaskState {
+ private List tasks;
+ private String error;
+
+ public TaskState() {
+ tasks = new ArrayList<>();
+ }
+
+ public List getList() {
+ return tasks;
+ }
+
+ /**
+ * Adds new Task object to the list of tasks.
+ * @param description of the task to be added
+ */
+ public void addTask(String description) {
+ this.tasks.add(new Task(description));
+ }
+
+ public void setError(String errorMessage) {
+ this.error = errorMessage;
+ }
+
+ public String getError() {
+ return error;
+ }
+}
diff --git a/src/main/java/interface_adapter/add_task/TaskViewModel.java b/src/main/java/interface_adapter/add_task/TaskViewModel.java
new file mode 100644
index 000000000..378a969bc
--- /dev/null
+++ b/src/main/java/interface_adapter/add_task/TaskViewModel.java
@@ -0,0 +1,13 @@
+package interface_adapter.add_task;
+
+import interface_adapter.ViewModel;
+
+/**
+ * The ViewModel for the TaskView.
+ */
+public class TaskViewModel extends ViewModel {
+ public TaskViewModel() {
+ super("task");
+ setState(new TaskState());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/interface_adapter/ai/AiController.java b/src/main/java/interface_adapter/ai/AiController.java
new file mode 100644
index 000000000..764d0581a
--- /dev/null
+++ b/src/main/java/interface_adapter/ai/AiController.java
@@ -0,0 +1,23 @@
+package interface_adapter.ai;
+
+import entity.Note;
+import use_cases.ai.AiInputBoundary;
+
+/**
+ * The controller for the AI use case.
+ */
+public class AiController {
+ private final AiInputBoundary aiInteractor;
+
+ public AiController(AiInputBoundary aiInputBoundary) {
+ this.aiInteractor = aiInputBoundary;
+ }
+
+ /**
+ * Generates the AI response from a given note.
+ * @param note The note in the JTextArea written by the user.
+ */
+ public void generateResponse(Note note) {
+ aiInteractor.generateResponse(note);
+ }
+}
diff --git a/src/main/java/interface_adapter/ai/AiPresenter.java b/src/main/java/interface_adapter/ai/AiPresenter.java
new file mode 100644
index 000000000..e9137d935
--- /dev/null
+++ b/src/main/java/interface_adapter/ai/AiPresenter.java
@@ -0,0 +1,24 @@
+package interface_adapter.ai;
+
+import entity.Note;
+import use_cases.ai.AiOutputBoundary;
+import view.NotesView;
+
+/**
+ * The stupid AiPresenter for this use case, intended to update the view.
+ */
+public class AiPresenter implements AiOutputBoundary {
+ private final NotesView notesView;
+
+ public AiPresenter(NotesView notesView) {
+ this.notesView = notesView;
+ }
+
+ /**
+ * Tasked with updating the view of the program with the response.
+ * @param note The final output from the AI.
+ */
+ public void updateNote(Note note) {
+ notesView.displayNewNote(note);
+ }
+}
diff --git a/src/main/java/interface_adapter/calendar/CalendarController.java b/src/main/java/interface_adapter/calendar/CalendarController.java
new file mode 100644
index 000000000..0513939df
--- /dev/null
+++ b/src/main/java/interface_adapter/calendar/CalendarController.java
@@ -0,0 +1,27 @@
+package interface_adapter.calendar;
+
+import use_cases.calendar.CalendarInputBoundary;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+
+/**
+ * The controller for the calendar use case.
+ */
+public class CalendarController {
+ private final CalendarInputBoundary calendarUseCaseInteractor;
+
+ public CalendarController(CalendarInputBoundary calendarUseCaseInteractor) {
+ this.calendarUseCaseInteractor = calendarUseCaseInteractor;
+ }
+
+ /**
+ * Executes the calendar Use Case.
+ * @param email the email of user.
+ * @throws GeneralSecurityException for Google account.
+ * @throws IOException for Google login.
+ */
+ public void execute(String email) throws GeneralSecurityException, IOException {
+ calendarUseCaseInteractor.execute(email);
+ }
+}
diff --git a/src/main/java/interface_adapter/calendar/CalendarPresenter.java b/src/main/java/interface_adapter/calendar/CalendarPresenter.java
new file mode 100644
index 000000000..f8bd4ced4
--- /dev/null
+++ b/src/main/java/interface_adapter/calendar/CalendarPresenter.java
@@ -0,0 +1,22 @@
+package interface_adapter.calendar;
+
+import entity.Events;
+import use_cases.calendar.CalendarOutputBoundary;
+import view.CalendarView;
+
+import java.util.List;
+
+/**
+ * The presenter for the calendar use case.
+ */
+public class CalendarPresenter implements CalendarOutputBoundary {
+ private CalendarView calendarView;
+
+ public CalendarPresenter(CalendarView calendarView) {
+ this.calendarView = calendarView;
+ }
+
+ public void prepareSuccessView(List events) {
+ calendarView.displayEvents(events);
+ }
+}
diff --git a/src/main/java/interface_adapter/note/NoteController.java b/src/main/java/interface_adapter/note/NoteController.java
index e3e5dfb32..86dde9d7f 100644
--- a/src/main/java/interface_adapter/note/NoteController.java
+++ b/src/main/java/interface_adapter/note/NoteController.java
@@ -1,6 +1,7 @@
package interface_adapter.note;
-import use_case.note.NoteInputBoundary;
+import use_cases.note.NoteInputBoundary;
+import use_cases.note.NoteInputData;
/**
* Controller for our Note related Use Cases.
@@ -15,14 +16,12 @@ public NoteController(NoteInputBoundary noteInteractor) {
/**
* Executes the Note related Use Cases.
- * @param note the note to be recorded
+ * @param content the content of the note being worked on
+ * @param title the title of the note
*/
- public void execute(String note) {
- if (note != null) {
- noteInteractor.executeSave(note);
- }
- else {
- noteInteractor.executeRefresh();
- }
+ public void execute(String content, String title) {
+ final NoteInputData newNote = new NoteInputData(content, title);
+ noteInteractor.execute(newNote);
}
+
}
diff --git a/src/main/java/interface_adapter/note/NotePresenter.java b/src/main/java/interface_adapter/note/NotePresenter.java
index d4e416165..8dac7c53e 100644
--- a/src/main/java/interface_adapter/note/NotePresenter.java
+++ b/src/main/java/interface_adapter/note/NotePresenter.java
@@ -1,6 +1,6 @@
package interface_adapter.note;
-import use_case.note.NoteOutputBoundary;
+import use_cases.note.NoteOutputBoundary;
/**
* The presenter for our Note viewing and editing program.
diff --git a/src/main/java/interface_adapter/note/NoteState.java b/src/main/java/interface_adapter/note/NoteState.java
index c5b2234d6..a44b799f4 100644
--- a/src/main/java/interface_adapter/note/NoteState.java
+++ b/src/main/java/interface_adapter/note/NoteState.java
@@ -2,7 +2,6 @@
/**
* The State for a note.
- *
For this example, a note is simplay a string.
*/
public class NoteState {
private String note = "";
diff --git a/src/main/java/interface_adapter/translation/TranslationController.java b/src/main/java/interface_adapter/translation/TranslationController.java
new file mode 100644
index 000000000..63b3e4b61
--- /dev/null
+++ b/src/main/java/interface_adapter/translation/TranslationController.java
@@ -0,0 +1,25 @@
+package interface_adapter.translation;
+
+import use_cases.note.TranslationInputData;
+import use_cases.note.TranslationInputBoundary;
+
+/**
+ * Controller for translation use case.
+ */
+public class TranslationController {
+ private final TranslationInputBoundary translationInteractor;
+
+ public TranslationController(TranslationInputBoundary translationInteractor) {
+ this.translationInteractor = translationInteractor;
+ }
+
+ /**
+ * Handles the user clicking the translate button.
+ * @param textToTranslate text to be translated
+ * @param selectedLanguage language to translate to
+ */
+ public void translateNote(String textToTranslate, String selectedLanguage) {
+ final TranslationInputData inputData = new TranslationInputData(textToTranslate, selectedLanguage);
+ translationInteractor.translateNote(inputData);
+ }
+}
diff --git a/src/main/java/interface_adapter/translation/TranslationPresenter.java b/src/main/java/interface_adapter/translation/TranslationPresenter.java
new file mode 100644
index 000000000..b18171e24
--- /dev/null
+++ b/src/main/java/interface_adapter/translation/TranslationPresenter.java
@@ -0,0 +1,25 @@
+package interface_adapter.translation;
+
+import use_cases.note.TranslationOutputData;
+import use_cases.note.TranslationOutputBoundary;
+import view.NotesView;
+
+/**
+ * Presenter for translation use case.
+ */
+public class TranslationPresenter implements TranslationOutputBoundary {
+ private final NotesView notesView;
+
+ public TranslationPresenter(NotesView notesView) {
+ this.notesView = notesView;
+ }
+
+ /**
+ * updates translation.
+ * @param outputData translated content
+ */
+ public void updateTranslation(TranslationOutputData outputData) {
+ final String translatedText = outputData.getTranslatedText();
+ notesView.updateTranslation(translatedText);
+ }
+}
diff --git a/src/main/java/use_case/note/DataAccessException.java b/src/main/java/use_case/note/DataAccessException.java
deleted file mode 100644
index b8c17920d..000000000
--- a/src/main/java/use_case/note/DataAccessException.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package use_case.note;
-
-/**
- * Exception thrown when there is an error with accessing data.
- */
-public class DataAccessException extends Exception {
- public DataAccessException(String string) {
- super(string);
- }
-}
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.
- *
The password of the user must match that of the user saved in the system.
- * @param user the user information associated with the note
- * @param note the note to be saved
- * @return the contents of the note
- * @throws DataAccessException if the user's note can not be saved for any reason
- */
- String saveNote(User user, String note) throws DataAccessException;
-
- /**
- * Returns the note associated with the user. The password
- * is not checked, so anyone can read the information.
- * @param user the user information associated with the note
- * @return the contents of the note
- * @throws DataAccessException if the user's note can not be loaded for any reason
- */
- String loadNote(User user) throws DataAccessException;
-
-}
diff --git a/src/main/java/use_case/note/NoteInteractor.java b/src/main/java/use_case/note/NoteInteractor.java
deleted file mode 100644
index 369e9309a..000000000
--- a/src/main/java/use_case/note/NoteInteractor.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package use_case.note;
-
-import entity.User;
-
-/**
- * The "Use Case Interactor" for our two note-related use cases of refreshing
- * the contents of the note and saving the contents of the note. Since they
- * are closely related, we have combined them here for simplicity.
- */
-public class NoteInteractor implements NoteInputBoundary {
-
- private final NoteDataAccessInterface noteDataAccessInterface;
- private final NoteOutputBoundary noteOutputBoundary;
- // Note: this program has it hardcoded which user object it is getting data for;
- // you could change this if you wanted to generalize the code. For example,
- // you might allow a user of the program to create a new note, which you
- // could store as a "user" through the API OR you might maintain all notes
- // in a JSON object stored in one common "user" stored through the API.
- private final User user = new User("jonathan_calver2", "abc123");
-
- public NoteInteractor(NoteDataAccessInterface noteDataAccessInterface,
- NoteOutputBoundary noteOutputBoundary) {
- this.noteDataAccessInterface = noteDataAccessInterface;
- this.noteOutputBoundary = noteOutputBoundary;
- }
-
- /**
- * Executes the refresh note use case.
- *
- */
- @Override
- public void executeRefresh() {
- try {
-
- final String note = noteDataAccessInterface.loadNote(user);
- noteOutputBoundary.prepareSuccessView(note);
- }
- catch (DataAccessException ex) {
- noteOutputBoundary.prepareFailView(ex.getMessage());
- }
- }
-
- /**
- * Executes the save note use case.
- *
- * @param note the input data
- */
- @Override
- public void executeSave(String note) {
- try {
-
- final String updatedNote = noteDataAccessInterface.saveNote(user, note);
- noteOutputBoundary.prepareSuccessView(updatedNote);
- }
- catch (DataAccessException ex) {
- noteOutputBoundary.prepareFailView(ex.getMessage());
- }
- }
-}
diff --git a/src/main/java/use_cases/add_task/AddTaskInputBoundary.java b/src/main/java/use_cases/add_task/AddTaskInputBoundary.java
new file mode 100644
index 000000000..6ce1c7d97
--- /dev/null
+++ b/src/main/java/use_cases/add_task/AddTaskInputBoundary.java
@@ -0,0 +1,12 @@
+package use_cases.add_task;
+
+/**
+ * Input Boundary for actions which are related to adding tasks.
+ */
+public interface AddTaskInputBoundary {
+ /**
+ * Executes the add_task use case.
+ * @param addTaskInputData the input data
+ */
+ void execute(AddTaskInputData addTaskInputData);
+}
diff --git a/src/main/java/use_cases/add_task/AddTaskInputData.java b/src/main/java/use_cases/add_task/AddTaskInputData.java
new file mode 100644
index 000000000..9bd23a36f
--- /dev/null
+++ b/src/main/java/use_cases/add_task/AddTaskInputData.java
@@ -0,0 +1,13 @@
+package use_cases.add_task;
+
+public class AddTaskInputData {
+ private final String description;
+
+ public AddTaskInputData(String description) {
+ this.description = description;
+ }
+
+ String getDescription() {
+ return description;
+ }
+}
diff --git a/src/main/java/use_cases/add_task/AddTaskInteractor.java b/src/main/java/use_cases/add_task/AddTaskInteractor.java
new file mode 100644
index 000000000..b35c20ef7
--- /dev/null
+++ b/src/main/java/use_cases/add_task/AddTaskInteractor.java
@@ -0,0 +1,19 @@
+package use_cases.add_task;
+
+/**
+ * The add_task Interactor.
+ */
+public class AddTaskInteractor implements AddTaskInputBoundary {
+ private final AddTaskOutputBoundary addTaskPresenter;
+
+ public AddTaskInteractor(AddTaskOutputBoundary addTaskOutputBoundary) {
+ this.addTaskPresenter = addTaskOutputBoundary;
+ }
+
+ @Override
+ public void execute(AddTaskInputData addTaskInputData) {
+ final String description = addTaskInputData.getDescription();
+ final AddTaskOutputData addTaskOutputData = new AddTaskOutputData(description, false);
+ addTaskPresenter.prepareSuccessView(addTaskOutputData);
+ }
+}
diff --git a/src/main/java/use_cases/add_task/AddTaskOutputBoundary.java b/src/main/java/use_cases/add_task/AddTaskOutputBoundary.java
new file mode 100644
index 000000000..f17bf92e0
--- /dev/null
+++ b/src/main/java/use_cases/add_task/AddTaskOutputBoundary.java
@@ -0,0 +1,18 @@
+package use_cases.add_task;
+
+/**
+ * The output boundary for the add_task Use Case.
+ */
+public interface AddTaskOutputBoundary {
+ /**
+ * Prepares the success view for the add_task Use Case.
+ * @param outputData the output data
+ */
+ void prepareSuccessView(AddTaskOutputData outputData);
+
+ /**
+ * Prepares the failure view for the add_task Use Case.
+ * @param errorMessage the explanation of the failure
+ */
+ void prepareFailView(String errorMessage);
+}
diff --git a/src/main/java/use_cases/add_task/AddTaskOutputData.java b/src/main/java/use_cases/add_task/AddTaskOutputData.java
new file mode 100644
index 000000000..723894028
--- /dev/null
+++ b/src/main/java/use_cases/add_task/AddTaskOutputData.java
@@ -0,0 +1,22 @@
+package use_cases.add_task;
+
+import entity.Task;
+
+/**
+ * Output Data for the add_task Use Case.
+ */
+public class AddTaskOutputData {
+
+ private final Task task;
+ private final boolean useCaseFailed;
+
+ public AddTaskOutputData(String description, boolean useCaseFailed) {
+ this.task = new Task(description);
+ this.useCaseFailed = useCaseFailed;
+ }
+
+ public String getDescription() {
+ return task.getDescription();
+ }
+
+}
diff --git a/src/main/java/use_cases/ai/AiInputBoundary.java b/src/main/java/use_cases/ai/AiInputBoundary.java
new file mode 100644
index 000000000..e6b0a8149
--- /dev/null
+++ b/src/main/java/use_cases/ai/AiInputBoundary.java
@@ -0,0 +1,15 @@
+package use_cases.ai;
+
+import entity.Note;
+
+/**
+ * AiInputBoundary involved in the AI prompt use case.
+ */
+public interface AiInputBoundary {
+
+ /**
+ * Generates AI response.
+ * @param note The modified prompt going into the AI."
+ */
+ void generateResponse(Note note);
+}
diff --git a/src/main/java/use_cases/ai/AiInteractor.java b/src/main/java/use_cases/ai/AiInteractor.java
new file mode 100644
index 000000000..1ccae8ae0
--- /dev/null
+++ b/src/main/java/use_cases/ai/AiInteractor.java
@@ -0,0 +1,29 @@
+package use_cases.ai;
+
+import entity.Note;
+
+/**
+ * The class that will implement the different functions of AI in the program.
+ * It will generate a completed written version of the current note.
+ */
+public class AiInteractor implements AiInputBoundary {
+ private final AiOutputBoundary aiOutputBoundary;
+ private final AiRequest aiRequest;
+
+ // take in note panel in attribute or in parameter to the method, defining interfaces, etc
+ // decide on functions for the calendar, load events, oauth 2 login, edit/modify events?
+
+ public AiInteractor(AiOutputBoundary aiOutputBoundary, AiRequest aiRequest) {
+ this.aiOutputBoundary = aiOutputBoundary;
+ this.aiRequest = aiRequest;
+ }
+
+ /**
+ * Auto-complete the current notes written by the user with AI.
+ * @param currNote The call to the AI to complete the current note.
+ */
+ public void generateResponse(Note currNote) {
+ final String newNoteContent = aiRequest.generateNotes(currNote.getContent());
+ aiOutputBoundary.updateNote(new Note(newNoteContent, "NA"));
+ }
+}
diff --git a/src/main/java/use_cases/ai/AiOutputBoundary.java b/src/main/java/use_cases/ai/AiOutputBoundary.java
new file mode 100644
index 000000000..5e0db4c9f
--- /dev/null
+++ b/src/main/java/use_cases/ai/AiOutputBoundary.java
@@ -0,0 +1,14 @@
+package use_cases.ai;
+
+import entity.Note;
+
+/**
+ * The output boundary for the AI use case.
+ */
+public interface AiOutputBoundary {
+ /**
+ * Add the AI generated completed note into the current note.
+ * @param note The final output from the AI.
+ */
+ void updateNote(Note note);
+}
diff --git a/src/main/java/use_cases/ai/AiRequest.java b/src/main/java/use_cases/ai/AiRequest.java
new file mode 100644
index 000000000..b10532fa9
--- /dev/null
+++ b/src/main/java/use_cases/ai/AiRequest.java
@@ -0,0 +1,30 @@
+package use_cases.ai;
+
+import java.util.List;
+
+import com.cohere.api.Cohere;
+import com.cohere.api.requests.ChatRequest;
+import com.cohere.api.types.NonStreamedChatResponse;
+
+/**
+ * This class handles the content in and out of the Cohere AI.
+ */
+public class AiRequest {
+ /**
+ * The method meant to polish user notes.
+ * @param prompt The current notes.
+ * @return The text result from the Cohere AI.
+ */
+ public String generateNotes(String prompt) {
+ final String apiKey = "UBKSlAcJBhvwitbUnMrhGkutx3SkV2ZpSpMssN8h";
+ final Cohere cohere = Cohere.builder().token(apiKey).clientName("snippet").build();
+
+ final NonStreamedChatResponse response = cohere.chat(
+ ChatRequest.builder()
+ .message("Improve these notes by editing for concision and "
+ + "adding more related content " + prompt)
+ .chatHistory(
+ List.of()).build());
+ return response.getText();
+ }
+}
diff --git a/src/main/java/use_cases/calendar/CalendarInputBoundary.java b/src/main/java/use_cases/calendar/CalendarInputBoundary.java
new file mode 100644
index 000000000..cf88b1917
--- /dev/null
+++ b/src/main/java/use_cases/calendar/CalendarInputBoundary.java
@@ -0,0 +1,15 @@
+package use_cases.calendar;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+
+/**
+ * The input boundary taking in an event.
+ */
+public interface CalendarInputBoundary {
+ /**
+ * Executes the calendar use case.
+ * @param email to be executed
+ */
+ void execute(String email) throws GeneralSecurityException, IOException;
+}
diff --git a/src/main/java/use_cases/calendar/CalendarInteractor.java b/src/main/java/use_cases/calendar/CalendarInteractor.java
new file mode 100644
index 000000000..d2c5d60f8
--- /dev/null
+++ b/src/main/java/use_cases/calendar/CalendarInteractor.java
@@ -0,0 +1,33 @@
+package use_cases.calendar;
+
+import entity.Events;
+import com.google.api.services.calendar.model.Event;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class CalendarInteractor implements CalendarInputBoundary {
+ private final CalendarOutputBoundary calendarPresenter;
+ private final CalendarRequest calendarRequest;
+ private final List events;
+
+ public CalendarInteractor(CalendarOutputBoundary calendarOutputBoundary, CalendarRequest calendarRequest) {
+ this.calendarPresenter = calendarOutputBoundary;
+ this.calendarRequest = calendarRequest;
+ this.events = new ArrayList();
+ }
+
+ public void execute(String email) throws GeneralSecurityException, IOException {
+ final List retResult = calendarRequest.getCalendarEvents(email);
+ for (Event value : retResult) {
+ final Events event = new Events(value.getSummary(),
+ value.getStart(), value.getLocation(), value.getDescription()
+ );
+ events.add(event);
+ }
+ System.out.println("finished processing API");
+ calendarPresenter.prepareSuccessView(events);
+ }
+}
diff --git a/src/main/java/use_cases/calendar/CalendarOutputBoundary.java b/src/main/java/use_cases/calendar/CalendarOutputBoundary.java
new file mode 100644
index 000000000..3ad6f88cc
--- /dev/null
+++ b/src/main/java/use_cases/calendar/CalendarOutputBoundary.java
@@ -0,0 +1,16 @@
+package use_cases.calendar;
+
+import java.util.List;
+
+import entity.Events;
+
+/**
+ * The output boundary for the calendar use case.
+ */
+public interface CalendarOutputBoundary {
+ /**
+ * Prepares the success view for the calendar Use Case.
+ * @param events the output data as a list of events
+ */
+ void prepareSuccessView(List events);
+}
diff --git a/src/main/java/use_cases/calendar/CalendarRequest.java b/src/main/java/use_cases/calendar/CalendarRequest.java
new file mode 100644
index 000000000..d26614809
--- /dev/null
+++ b/src/main/java/use_cases/calendar/CalendarRequest.java
@@ -0,0 +1,96 @@
+package use_cases.calendar;
+
+import java.io.*;
+import java.security.GeneralSecurityException;
+import java.util.Collections;
+import java.util.List;
+
+import com.google.api.client.auth.oauth2.Credential;
+import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
+import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
+import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
+import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
+import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
+import com.google.api.client.http.javanet.NetHttpTransport;
+import com.google.api.client.json.JsonFactory;
+import com.google.api.client.json.gson.GsonFactory;
+import com.google.api.client.util.DateTime;
+import com.google.api.client.util.store.FileDataStoreFactory;
+import com.google.api.services.calendar.Calendar;
+import com.google.api.services.calendar.CalendarScopes;
+import com.google.api.services.calendar.model.Event;
+import com.google.api.services.calendar.model.Events;
+import com.google.auth.http.HttpCredentialsAdapter;
+import com.google.auth.oauth2.GoogleCredentials;
+
+// keep the unused imports for now, this whole import api stuff for google is so
+// finicky that i almost had a shed a tear when i realized all the imports were finally in order
+
+/**
+ * A sample request to the calendar.
+ */
+public class CalendarRequest {
+ /**
+ * Application name.
+ */
+ private static final String APPLICATION_NAME = "Google Calendar API Java Quickstart";
+ /**
+ * Global instance of the JSON factory.
+ */
+ private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
+ /**
+ * Directory to store authorization tokens for this application.
+ */
+ private static final String SERVICE_ACCOUNT_KEY_FILE = "YOUR_KEY_HERE";
+
+ /**
+ * Creates credentials.
+ *
+ * @return Calendar.
+ * @throws GeneralSecurityException exception.
+ * @throws IOException exception.
+ */
+ public static Calendar getCalendarService() throws GeneralSecurityException, IOException {
+ // Load the service account key JSON file
+ final FileInputStream serviceAccountStream = new FileInputStream(SERVICE_ACCOUNT_KEY_FILE);
+
+ // Build the service account credentials
+ final GoogleCredentials credentials = GoogleCredentials.fromStream(serviceAccountStream)
+ .createScoped(List.of("https://www.googleapis.com/auth/calendar"));
+
+ // Construct the Calendar service object
+ return new Calendar.Builder(GoogleNetHttpTransport.newTrustedTransport(), JSON_FACTORY,
+ new HttpCredentialsAdapter(credentials)).setApplicationName(APPLICATION_NAME).build();
+ }
+
+ /**
+ * Retrieves calendar events, first 10 of them.
+ *
+ * @param email The email address of Google account.
+ * @return List of events.
+ * @throws GeneralSecurityException exception.
+ * @throws IOException exception.
+ */
+ public List getCalendarEvents(String email) throws GeneralSecurityException, IOException {
+ final Calendar service = getCalendarService();
+
+ // List the next 10 events from the primary calendar.
+ final DateTime now = new DateTime(System.currentTimeMillis());
+ final Events events = service.events().list(email).setMaxResults(10).setTimeMin(now)
+ .setOrderBy("startTime").setSingleEvents(true).execute();
+ final List items = events.getItems();
+ if (items.isEmpty()) {
+ System.out.println("No upcoming events found.");
+ } else {
+ System.out.println("Upcoming events:");
+ for (Event event : items) {
+ DateTime start = event.getStart().getDateTime();
+ if (start == null) {
+ start = event.getStart().getDate();
+ }
+ System.out.printf("%s (%s)\n", event.getSummary(), start);
+ }
+ }
+ return items;
+ }
+}
diff --git a/src/main/java/use_cases/note/NoteDataAccessInterface.java b/src/main/java/use_cases/note/NoteDataAccessInterface.java
new file mode 100644
index 000000000..bd89b6b78
--- /dev/null
+++ b/src/main/java/use_cases/note/NoteDataAccessInterface.java
@@ -0,0 +1,25 @@
+package use_cases.note;
+
+import java.util.List;
+
+import entity.Note;
+
+/**
+ * Interface for the NoteDAO. It consists of methods for
+ * both loading and saving a note.
+ */
+public interface NoteDataAccessInterface {
+
+ /**
+ * Saves a note.
+ * @param title the title associated with the note.
+ * @param note the note to be saved.
+ */
+ void saveNote(String title, String note);
+
+ /**
+ * Creates an "in-memory" database of all notes saved in the program.
+ * @return a list of the titles of all notes that have been saved.
+ */
+ List getNotes();
+}
diff --git a/src/main/java/use_case/note/NoteInputBoundary.java b/src/main/java/use_cases/note/NoteInputBoundary.java
similarity index 58%
rename from src/main/java/use_case/note/NoteInputBoundary.java
rename to src/main/java/use_cases/note/NoteInputBoundary.java
index b41da9bf5..5b8cdbb67 100644
--- a/src/main/java/use_case/note/NoteInputBoundary.java
+++ b/src/main/java/use_cases/note/NoteInputBoundary.java
@@ -1,4 +1,4 @@
-package use_case.note;
+package use_cases.note;
/**
* The Input Boundary for our note-related use cases. Since they are closely related,
@@ -6,14 +6,10 @@
*/
public interface NoteInputBoundary {
- /**
- * Executes the refresh note use case.
- */
- void executeRefresh();
-
/**
* Executes the save note use case.
- * @param message the input data
+ * @param noteInputData the note being worked on.
*/
- void executeSave(String message);
+ void execute(NoteInputData noteInputData);
+
}
diff --git a/src/main/java/use_cases/note/NoteInputData.java b/src/main/java/use_cases/note/NoteInputData.java
new file mode 100644
index 000000000..b4ca76c1d
--- /dev/null
+++ b/src/main/java/use_cases/note/NoteInputData.java
@@ -0,0 +1,22 @@
+package use_cases.note;
+
+/**
+ * The input data for the Notes Use Case.
+ */
+public class NoteInputData {
+ private final String title;
+ private final String content;
+
+ public NoteInputData(String title, String content) {
+ this.title = title;
+ this.content = content;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public String getContent() {
+ return content;
+ }
+}
diff --git a/src/main/java/use_cases/note/NoteInteractor.java b/src/main/java/use_cases/note/NoteInteractor.java
new file mode 100644
index 000000000..3552e149e
--- /dev/null
+++ b/src/main/java/use_cases/note/NoteInteractor.java
@@ -0,0 +1,26 @@
+package use_cases.note;
+
+/**
+ * The "Use Case Interactor" for our two note-related use cases of refreshing
+ * the contents of the note and saving the contents of the note. Since they
+ * are closely related, we have combined them here for simplicity.
+ */
+public class NoteInteractor implements NoteInputBoundary {
+
+ private final NoteOutputBoundary notePresenter;
+ private final NoteDataAccessInterface inMemoryNoteDataAccessObject;
+
+ public NoteInteractor(NoteOutputBoundary noteOutputBoundary, NoteDataAccessInterface inMemoryNoteDAO) {
+ this.notePresenter = noteOutputBoundary;
+ this.inMemoryNoteDataAccessObject = inMemoryNoteDAO;
+ }
+
+ @Override
+ public void execute(NoteInputData noteInputData) {
+ this.inMemoryNoteDataAccessObject.saveNote(noteInputData.getTitle(), noteInputData.getContent());
+
+ final NoteOutputData noteOutputData = new NoteOutputData(noteInputData.getTitle(), false);
+ this.notePresenter.prepareSuccessView(noteOutputData.getContent());
+ }
+}
+
diff --git a/src/main/java/use_case/note/NoteOutputBoundary.java b/src/main/java/use_cases/note/NoteOutputBoundary.java
similarity index 94%
rename from src/main/java/use_case/note/NoteOutputBoundary.java
rename to src/main/java/use_cases/note/NoteOutputBoundary.java
index c0c2bb1d0..2e00e5442 100644
--- a/src/main/java/use_case/note/NoteOutputBoundary.java
+++ b/src/main/java/use_cases/note/NoteOutputBoundary.java
@@ -1,4 +1,4 @@
-package use_case.note;
+package use_cases.note;
/**
* The output boundary for the Login Use Case.
diff --git a/src/main/java/use_cases/note/NoteOutputData.java b/src/main/java/use_cases/note/NoteOutputData.java
new file mode 100644
index 000000000..59d4d5487
--- /dev/null
+++ b/src/main/java/use_cases/note/NoteOutputData.java
@@ -0,0 +1,23 @@
+package use_cases.note;
+
+/**
+ * The Output data for the Notes Use Case.
+ */
+public class NoteOutputData {
+
+ private final String content;
+ private final boolean useCaseFailed;
+
+ public NoteOutputData(String title, boolean useCaseFailed) {
+ this.content = title;
+ this.useCaseFailed = useCaseFailed;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public boolean isUseCaseFailed() {
+ return useCaseFailed;
+ }
+}
diff --git a/src/main/java/use_cases/note/TranslationFactory.java b/src/main/java/use_cases/note/TranslationFactory.java
new file mode 100644
index 000000000..0953c8461
--- /dev/null
+++ b/src/main/java/use_cases/note/TranslationFactory.java
@@ -0,0 +1,47 @@
+package use_cases.note;
+
+import space.dynomake.libretranslate.Language;
+import space.dynomake.libretranslate.Translator;
+
+/**
+ * Class for note translation.
+ */
+public class TranslationFactory {
+
+ /**
+ * Translates text from english to other language.
+ *
+ * @param inputData the input data containing the text to translate and the selected language
+ * @return NoteOutputData containing the translation
+ */
+ public static TranslationOutputData translate(TranslationInputData inputData) {
+ final int characterLimit = 2000;
+ final String textToTranslate = inputData.getTextToTranslate();
+ final String selectedLanguage = inputData.getSelectedLanguage();
+
+ // checking if length of text exceeds char limit
+ if (textToTranslate.length() > characterLimit) {
+ return new TranslationOutputData("Exceeded character limit");
+ }
+
+ final String translation;
+ switch (selectedLanguage) {
+ case "Russian":
+ translation = Translator.translate(Language.ENGLISH, Language.RUSSIAN, textToTranslate);
+ break;
+ case "French":
+ translation = Translator.translate(Language.ENGLISH, Language.FRENCH, textToTranslate);
+ break;
+ case "Spanish":
+ translation = Translator.translate(Language.ENGLISH, Language.SPANISH, textToTranslate);
+ break;
+ case "Arabic":
+ translation = Translator.translate(Language.ENGLISH, Language.ARABIC, textToTranslate);
+ break;
+ default:
+ translation = textToTranslate;
+ }
+
+ return new TranslationOutputData(translation);
+ }
+}
diff --git a/src/main/java/use_cases/note/TranslationInputBoundary.java b/src/main/java/use_cases/note/TranslationInputBoundary.java
new file mode 100644
index 000000000..a4b23e010
--- /dev/null
+++ b/src/main/java/use_cases/note/TranslationInputBoundary.java
@@ -0,0 +1,13 @@
+package use_cases.note;
+
+/**
+ * InputBoundary for translation use case.
+ */
+public interface TranslationInputBoundary {
+ /**
+ * Translates note.
+ *
+ * @param inputData contains text to be translated and selected language
+ */
+ void translateNote(TranslationInputData inputData);
+}
diff --git a/src/main/java/use_cases/note/TranslationInputData.java b/src/main/java/use_cases/note/TranslationInputData.java
new file mode 100644
index 000000000..f1a8f1da3
--- /dev/null
+++ b/src/main/java/use_cases/note/TranslationInputData.java
@@ -0,0 +1,22 @@
+package use_cases.note;
+
+/**
+ * The Note Input Data contains the text to translate and the selected language to translate to.
+ */
+public class TranslationInputData {
+ private final String textToTranslate;
+ private final String selectedLanguage;
+
+ public TranslationInputData(String textToTranslate, String selectedLanguage) {
+ this.textToTranslate = textToTranslate;
+ this.selectedLanguage = selectedLanguage;
+ }
+
+ public String getTextToTranslate() {
+ return textToTranslate;
+ }
+
+ public String getSelectedLanguage() {
+ return selectedLanguage;
+ }
+}
diff --git a/src/main/java/use_cases/note/TranslationInteractor.java b/src/main/java/use_cases/note/TranslationInteractor.java
new file mode 100644
index 000000000..ad6533794
--- /dev/null
+++ b/src/main/java/use_cases/note/TranslationInteractor.java
@@ -0,0 +1,23 @@
+package use_cases.note;
+
+/**
+ * Interactor for translation use case.
+ */
+public class TranslationInteractor implements TranslationInputBoundary {
+ private final TranslationOutputBoundary outputBoundary;
+
+ public TranslationInteractor(TranslationOutputBoundary outputBoundary) {
+
+ this.outputBoundary = outputBoundary;
+ }
+
+ /**
+ * Translates input data.
+ *
+ * @param inputData contains text to be translated and selected language
+ */
+ public void translateNote(TranslationInputData inputData) {
+ final TranslationOutputData outputData = TranslationFactory.translate(inputData);
+ outputBoundary.updateTranslation(outputData);
+ }
+}
diff --git a/src/main/java/use_cases/note/TranslationOutputBoundary.java b/src/main/java/use_cases/note/TranslationOutputBoundary.java
new file mode 100644
index 000000000..f67f66146
--- /dev/null
+++ b/src/main/java/use_cases/note/TranslationOutputBoundary.java
@@ -0,0 +1,12 @@
+package use_cases.note;
+
+/**
+ * OutputBoundary for translation use case.
+ */
+public interface TranslationOutputBoundary {
+ /**
+ * presents the translated text.
+ * @param outputData translated content
+ */
+ void updateTranslation(TranslationOutputData outputData);
+}
diff --git a/src/main/java/use_cases/note/TranslationOutputData.java b/src/main/java/use_cases/note/TranslationOutputData.java
new file mode 100644
index 000000000..a8efa5735
--- /dev/null
+++ b/src/main/java/use_cases/note/TranslationOutputData.java
@@ -0,0 +1,16 @@
+package use_cases.note;
+
+/**
+ * The Note Output Data contains the translated text.
+ */
+public class TranslationOutputData {
+ private final String translatedText;
+
+ public TranslationOutputData(String translatedText) {
+ this.translatedText = translatedText;
+ }
+
+ public String getTranslatedText() {
+ return translatedText;
+ }
+}
diff --git a/src/main/java/view/CalendarView.java b/src/main/java/view/CalendarView.java
new file mode 100644
index 000000000..08870276c
--- /dev/null
+++ b/src/main/java/view/CalendarView.java
@@ -0,0 +1,73 @@
+package view;
+
+import javax.swing.*;
+
+import entity.Events;
+import interface_adapter.calendar.CalendarController;
+
+import java.awt.*;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The view for the calendar use case.
+ */
+public class CalendarView extends JPanel {
+ private final JLabel promptLabel;
+ private final JButton loginButton;
+ private final JPanel weekPanel;
+ private CalendarController calendarController;
+
+ public CalendarView() throws GeneralSecurityException, IOException {
+ this.promptLabel = new JLabel("Please access your Google account:");
+ this.loginButton = new JButton("Enter Email");
+ this.weekPanel = new JPanel();
+
+ loginButton.addActionListener(
+ evt -> {
+ if (evt.getSource().equals(loginButton)) {
+ loginButton.setVisible(false);
+ final String email = JOptionPane.showInputDialog(this,
+ "Enter Email:", "Google Account", JOptionPane.PLAIN_MESSAGE);
+ if (email != null && !email.trim().isEmpty()) {
+ try {
+ calendarController.execute(email);
+ }
+ catch (GeneralSecurityException | IOException exception) {
+ throw new RuntimeException(exception);
+ }
+ }
+ }
+ }
+ );
+ this.add(this.promptLabel);
+ this.add(this.loginButton);
+ }
+
+ /**
+ * Displays events in the view based on the data from the API.
+ * @param events list of events from the API
+ */
+ public void displayEvents(List events) {
+ weekPanel.setLayout(new BoxLayout(weekPanel, BoxLayout.Y_AXIS));
+ for (Events event : events) {
+ final JPanel eventPanel = new JPanel();
+ eventPanel.add(new JLabel(event.getEventName()));
+ eventPanel.add(new JLabel(event.getEventLocation()));
+ eventPanel.add(new JLabel(event.getEventDatetime()));
+ eventPanel.add(new JLabel(event.getEventNotes()));
+ weekPanel.add(eventPanel);
+ }
+ this.promptLabel.setText("Please access your Google account:");
+ this.add(this.weekPanel);
+ promptLabel.setVisible(false);
+ }
+
+ public void setCalendarController(CalendarController calendarController) {
+ this.calendarController = calendarController;
+ }
+}
diff --git a/src/main/java/view/ChecklistView.java b/src/main/java/view/ChecklistView.java
new file mode 100644
index 000000000..ff323885d
--- /dev/null
+++ b/src/main/java/view/ChecklistView.java
@@ -0,0 +1,72 @@
+package view;
+
+import interface_adapter.add_task.AddTaskController;
+import interface_adapter.add_task.TaskState;
+import interface_adapter.add_task.TaskViewModel;
+
+import javax.swing.*;
+import java.awt.*;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+
+/**
+ * The View for when the user is viewing a checklist in the program.
+ */
+public class ChecklistView extends JPanel implements PropertyChangeListener {
+
+ private final TaskViewModel taskViewModel;
+ private AddTaskController addTaskController;
+
+ private final JPanel checklistPanel;
+ private final JButton addTaskButton;
+
+ public ChecklistView(TaskViewModel taskViewModel) {
+ this.taskViewModel = taskViewModel;
+ this.taskViewModel.addPropertyChangeListener(this);
+
+ this.checklistPanel = new JPanel();
+ this.addTaskButton = new JButton("Add Task +");
+
+ checklistPanel.setLayout(new BoxLayout(checklistPanel, BoxLayout.Y_AXIS));
+ checklistPanel.add(new JLabel("Tasks:"));
+ checklistPanel.add(addTaskButton);
+
+ this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ this.add(checklistPanel);
+
+ addTaskButton.addActionListener(evt -> {
+ if (evt.getSource().equals(addTaskButton)) {
+ final String taskDescription = JOptionPane.showInputDialog(this,
+ "Enter Task Description:", "New Task", JOptionPane.PLAIN_MESSAGE);
+ if (taskDescription != null && !taskDescription.trim().isEmpty()) {
+ addTaskController.execute(taskDescription.trim());
+ }
+ }
+ });
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ final TaskState state = (TaskState) evt.getNewValue();
+
+ if (state.getError() != null) {
+ JOptionPane.showMessageDialog(this, state.getError(),
+ "Error", JOptionPane.ERROR_MESSAGE);
+ }
+ final JPanel taskPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
+ if (!state.getList().isEmpty()) {
+ final JCheckBox taskCheckBox = new JCheckBox((state.getList().get(state.getList().size() - 1))
+ .getDescription());
+ taskPanel.add(taskCheckBox);
+ }
+ checklistPanel.add(taskPanel);
+
+ checklistPanel.revalidate();
+ checklistPanel.repaint();
+ }
+
+ public void setTaskController(AddTaskController controller) {
+ this.addTaskController = controller;
+ }
+}
diff --git a/src/main/java/view/DashboardView.java b/src/main/java/view/DashboardView.java
new file mode 100644
index 000000000..2a2c36fc7
--- /dev/null
+++ b/src/main/java/view/DashboardView.java
@@ -0,0 +1,15 @@
+package view;
+
+import javax.swing.*;
+
+/**
+ * Default open screen for the program.
+ */
+public class DashboardView extends JPanel {
+ private final JLabel welcomeText;
+
+ public DashboardView() {
+ welcomeText = new JLabel("Welcome to your Dashboard.");
+ this.add(welcomeText);
+ }
+}
diff --git a/src/main/java/view/NoteView.java b/src/main/java/view/NoteView.java
deleted file mode 100644
index 331d76493..000000000
--- a/src/main/java/view/NoteView.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package view;
-
-import java.awt.Component;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-
-import javax.swing.BoxLayout;
-import javax.swing.JButton;
-import javax.swing.JLabel;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JTextArea;
-
-import interface_adapter.note.NoteController;
-import interface_adapter.note.NoteState;
-import interface_adapter.note.NoteViewModel;
-
-/**
- * The View for when the user is viewing a note in the program.
- */
-public class NoteView extends JPanel implements ActionListener, PropertyChangeListener {
-
- private final NoteViewModel noteViewModel;
-
- private final JLabel noteName = new JLabel("note for jonathan_calver2");
- private final JTextArea noteInputField = new JTextArea();
-
- private final JButton saveButton = new JButton("Save");
- private final JButton refreshButton = new JButton("Refresh");
- private NoteController noteController;
-
- public NoteView(NoteViewModel noteViewModel) {
-
- noteName.setAlignmentX(Component.CENTER_ALIGNMENT);
- this.noteViewModel = noteViewModel;
- this.noteViewModel.addPropertyChangeListener(this);
-
- final JPanel buttons = new JPanel();
- buttons.add(saveButton);
- buttons.add(refreshButton);
-
- saveButton.addActionListener(
- evt -> {
- if (evt.getSource().equals(saveButton)) {
- noteController.execute(noteInputField.getText());
-
- }
- }
- );
-
- refreshButton.addActionListener(
- evt -> {
- if (evt.getSource().equals(refreshButton)) {
- noteController.execute(null);
-
- }
- }
- );
-
- this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
-
- this.add(noteName);
- this.add(noteInputField);
- this.add(buttons);
- }
-
- /**
- * React to a button click that results in evt.
- * @param evt the ActionEvent to react to
- */
- public void actionPerformed(ActionEvent evt) {
- System.out.println("Click " + evt.getActionCommand());
- }
-
- @Override
- public void propertyChange(PropertyChangeEvent evt) {
- final NoteState state = (NoteState) evt.getNewValue();
- setFields(state);
- if (state.getError() != null) {
- JOptionPane.showMessageDialog(this, state.getError(),
- "Error", JOptionPane.ERROR_MESSAGE);
- }
- }
-
- private void setFields(NoteState state) {
- noteInputField.setText(state.getNote());
- }
-
- public void setNoteController(NoteController controller) {
- this.noteController = controller;
- }
-}
-
diff --git a/src/main/java/view/NotesView.java b/src/main/java/view/NotesView.java
new file mode 100644
index 000000000..39a8aeb0a
--- /dev/null
+++ b/src/main/java/view/NotesView.java
@@ -0,0 +1,281 @@
+package view;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import javax.swing.JComboBox;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JFileChooser;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JSplitPane;
+import javax.swing.JTextArea;
+
+import entity.Note;
+import org.jetbrains.annotations.NotNull;
+
+import interface_adapter.ai.AiController;
+import interface_adapter.translation.TranslationController;
+
+import interface_adapter.note.NoteController;
+import interface_adapter.note.NoteState;
+import interface_adapter.note.NoteViewModel;
+
+/**
+ * This class sets up the view of the Notes Use Case.
+ */
+public class NotesView extends JPanel implements ActionListener, PropertyChangeListener {
+ static final int DIVIDER = 400;
+
+ private final NoteViewModel noteViewModel;
+ private AiController aiController;
+ private NoteController noteController;
+ private TranslationController translationController;
+
+ private JLabel noteName;
+ private JTextArea noteInputField;
+ private JTextArea outputArea;
+
+ private JButton saveNoteButton;
+ private JButton uploadButton;
+ private JButton clearButton;
+ private JButton deleteButton;
+
+ private JTextArea notesTextArea;
+
+ private JPanel notePanel;
+ private JPanel editPanel;
+ private JPanel savePanel;
+
+ private JSplitPane splitPane;
+
+ public NotesView(NoteViewModel noteViewModel) {
+ this.noteViewModel = noteViewModel;
+ this.noteViewModel.addPropertyChangeListener(this);
+
+ this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+
+ setUpUi();
+
+ }
+
+ private void setUpUi() {
+ initializeComponents();
+ setUpActionListeners();
+ buildUi();
+ }
+
+ private void initializeComponents() {
+ notePanel = new JPanel();
+ editPanel = new JPanel();
+ savePanel = new JPanel();
+
+ noteName = new JLabel("New Note");
+
+ noteInputField = new JTextArea();
+ noteInputField.setText("Create New Note...");
+
+ saveNoteButton = new JButton("Save Note");
+ uploadButton = new JButton("Upload");
+ clearButton = new JButton("Clear");
+ deleteButton = new JButton("Delete");
+
+ }
+
+ private void setUpActionListeners() {
+ saveNoteButton.addActionListener(this::saveNote);
+ uploadButton.addActionListener(this::uploadText);
+ clearButton.addActionListener(this::clearText);
+ deleteButton.addActionListener(this::deleteNote);
+
+ }
+
+ private void saveNote(ActionEvent actionEvent) {
+ if (actionEvent.getSource().equals(saveNoteButton)) {
+ final String newNoteName = JOptionPane.showInputDialog("Enter new note name");
+ noteName.setText(newNoteName);
+ noteController.execute(noteInputField.getText(), noteName.getText());
+
+ }
+
+ }
+
+ private void uploadText(ActionEvent actionEvent) {
+ if (actionEvent.getSource().equals(uploadButton)) {
+ final JFileChooser fileChooser = new JFileChooser();
+ fileChooser.setDialogTitle("Upload");
+ final int returnVal = fileChooser.showOpenDialog(this);
+ final File selectedFile = fileChooser.getSelectedFile();
+ if (returnVal == JFileChooser.APPROVE_OPTION) {
+ try (BufferedReader reader = new BufferedReader(new FileReader(selectedFile))) {
+ noteInputField.setText("");
+ String line;
+ while ((line = reader.readLine()) != null) {
+ noteInputField.append(line);
+ noteInputField.append("\n");
+ }
+ }
+ catch (IOException exception) {
+ JOptionPane.showMessageDialog(this, exception.getMessage(),
+ "Error", JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ }
+
+ }
+
+ private void clearText(ActionEvent evt) {
+ if (evt.getSource().equals(clearButton)) {
+ noteController.execute(noteInputField.getText(), noteName.getText());
+ }
+
+ }
+
+ private void deleteNote(ActionEvent evt) {
+ if (evt.getSource().equals(deleteButton)) {
+ noteController.execute(noteInputField.getText(), noteName.getText());
+ noteName.setText("New Note");
+ }
+
+ }
+
+ private void buildUi() {
+ notePanel.setLayout(new BoxLayout(notePanel, BoxLayout.Y_AXIS));
+
+ noteName.setAlignmentX(Component.CENTER_ALIGNMENT);
+ notePanel.add(noteName);
+
+ noteInputField.setLineWrap(true);
+ noteInputField.setWrapStyleWord(true);
+ notePanel.add(noteInputField);
+
+ editPanel.add(uploadButton);
+ editPanel.add(clearButton);
+ editPanel.add(deleteButton);
+ notePanel.add(editPanel);
+
+ savePanel.add(saveNoteButton);
+ notePanel.add(savePanel);
+
+ final JPanel functionalityPanel = getjPanel();
+
+ splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, notePanel, functionalityPanel);
+ splitPane.setDividerLocation(DIVIDER);
+
+
+ this.add(splitPane);
+
+ }
+
+ @NotNull
+ private JPanel getjPanel() {
+ final JPanel panel = new JPanel();
+ panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+
+ final JPanel tools = new JPanel();
+
+ final JButton aiButton = new JButton("Complete Notes With AI");
+ aiButton.addActionListener(
+ evt -> {
+ if (evt.getSource().equals(aiButton)) {
+ aiController.generateResponse(new Note(noteInputField.getText(), "NA"));
+ // Jenna, you may need to call some method since you cannot create an instance of Note here.
+
+ }
+ }
+ );
+ tools.add(aiButton);
+
+ // Dropdown menu
+ final String[] languages = {"Russian", "French", "Spanish", "Arabic"};
+ final JComboBox languageDropdown = new JComboBox<>(languages);
+ languageDropdown.setVisible(false);
+ tools.add(languageDropdown);
+
+ final JButton languageButton = new JButton("Translate");
+ languageButton.addActionListener(
+ evt -> {
+ if (evt.getSource().equals(languageButton)) {
+ if (!languageDropdown.isVisible()) {
+ languageDropdown.setVisible(true);
+ }
+ else {
+ final String selectedLanguage = (String) languageDropdown.getSelectedItem();
+ final String textInput = notesTextArea.getText();
+ translationController.translateNote(textInput, selectedLanguage);
+ languageDropdown.setVisible(false);
+ }
+ }
+ }
+ );
+ tools.add(languageButton);
+
+ outputArea = new JTextArea();
+ outputArea.setEditable(false);
+
+ panel.add(outputArea);
+ panel.add(tools);
+ return panel;
+ }
+
+ /**
+ * React to a button click that results in evt.
+ * @param evt the ActionEvent to react to
+ */
+ public void actionPerformed(ActionEvent evt) {
+ System.out.println("Click " + evt.getActionCommand());
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ final NoteState state = (NoteState) evt.getNewValue();
+ setFields(state);
+ if (state.getError() != null) {
+ JOptionPane.showMessageDialog(this, state.getError(),
+ "Error", JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ private void setFields(NoteState state) {
+ noteInputField.setText(state.getNote());
+ }
+
+ public void setNoteController(NoteController controller) {
+ this.noteController = controller;
+ }
+
+ /**
+ * updates the translation.
+ * @param translatedText text that has been translated
+ */
+ public void updateTranslation(String translatedText) {
+ outputArea.setText(translatedText);
+ }
+
+ public void setTranslationController(TranslationController translationController) {
+ this.translationController = translationController;
+ }
+
+ public void setAiController(AiController aiController) {
+ this.aiController = aiController;
+ }
+
+ /**
+ * Updates the display of the un-editable text area.
+ * @param newNote The new note to display.
+ */
+ public void displayNewNote(Note newNote) {
+ outputArea.setText(newNote.getContent());
+ }
+ // add methods for other controllers here
+}
diff --git a/src/test/java/app/MainNoteApplicationTest.java b/src/test/java/app/MainNoteApplicationTest.java
deleted file mode 100644
index 025d970e2..000000000
--- a/src/test/java/app/MainNoteApplicationTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-package app;
-
-import entity.User;
-import org.junit.Before;
-import org.junit.Test;
-import use_case.note.NoteDataAccessInterface;
-
-import javax.swing.*;
-import java.awt.*;
-
-import static java.lang.Thread.sleep;
-import static org.junit.Assert.*;
-
-public class MainNoteApplicationTest {
-
- private JFrame app;
-
- @Before
- public void setUp() {
-
- // create the data access and inject it into our builder!
- final NoteDataAccessInterface noteDataAccess = new NoteDataAccessInterface() {
-
- private String note = "test";
-
- @Override
- public String saveNote(User user, String note) {
- this.note = note;
- return note;
- }
-
- @Override
- public String loadNote(User user) {
- return note;
- }
- };
-
- final NoteAppBuilder builder = new NoteAppBuilder();
- app = builder.addNoteDAO(noteDataAccess)
- .addNoteView()
- .addNoteUseCase().build();
-
- app.setVisible(true);
-
- }
-
- /**
- * This is an example of an end-to-end test with a mocked database.
- *
The code creates the application and directly tests to see that the GUI
- * is updated as expected when the buttons and UI elements are interacted with.
- *
- * You can run the test to visually see what happens.
- */
- @Test
- public void testEndToEnd() {
-
- Component[] components = ((JPanel)app.getRootPane().getContentPane().getComponents()[0]).getComponents();
- JTextArea textArea = null;
- for (Component component : components) {
- if (component instanceof JTextArea) {
- textArea = (JTextArea) component;
- assertEquals("test", textArea.getText());
-
- }
- }
-
- textArea.setText("test test");
-
-
- JButton save = null;
- JButton load = null;
- for (Component component : components) {
- if (component instanceof JPanel) {
- for (Component c : ((JPanel) component).getComponents()) {
- if (c instanceof JButton) {
- if (save != null) {
- load = (JButton) c;
- }
- else {
- save = (JButton) c;
- }
- }
- }
- }
- }
-
- save.doClick();
- assertEquals("test test", textArea.getText());
- textArea.setText("");
-
- System.out.println("cleared text; about to refresh...");
- // pause execution for a bit so we can visually see the changes on the screen
- try {
- sleep(1500);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
-
- load.doClick();
- assertEquals("test test", textArea.getText());
-
- System.out.println("after refresh!");
-
- // pause execution for a bit so we can visually see the changes on the screen
- try {
- sleep(1500);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
-
- }
-}
\ No newline at end of file
diff --git a/src/test/java/entity/EventsTest.java b/src/test/java/entity/EventsTest.java
new file mode 100644
index 000000000..2219a71c3
--- /dev/null
+++ b/src/test/java/entity/EventsTest.java
@@ -0,0 +1,35 @@
+package entity;
+
+import com.google.api.client.util.DateTime;
+import com.google.api.services.calendar.model.EventDateTime;
+import org.junit.Test;
+
+public class EventsTest {
+ @Test
+ public void getEventNameTest() {
+ final Events testEvents = new Events("test name", new EventDateTime().setDateTime(new DateTime("2024-12-02T09:00:00.000-05:00")),
+ "test location", "extra notes go here");
+ assert testEvents.getEventName().equals("test name");
+ }
+
+ @Test
+ public void getEventLocationTest() {
+ final Events testEvents = new Events("test name", new EventDateTime().setDateTime(new DateTime("2024-12-02T09:00:00.000-05:00")),
+ "test location", "extra notes go here");
+ assert testEvents.getEventLocation().equals("test location");
+ }
+
+ @Test
+ public void getDateTimeTest() {
+ final Events testEvents = new Events("test name", new EventDateTime().setDateTime(new DateTime("2024-12-02T09:00:00.000-05:00")),
+ "test location", "extra notes go here");
+ assert testEvents.getEventDatetime().equals("2024-12-02T09:00:00.000-05:00");
+ }
+
+ @Test
+ public void getNoteTest() {
+ final Events testEvents = new Events("test name", new EventDateTime().setDateTime(new DateTime("2024-12-02T09:00:00.000-05:00")),
+ "test location", "extra notes go here");
+ assert testEvents.getEventNotes().equals("extra notes go here");
+ }
+}
diff --git a/src/test/java/entity/NoteTest.java b/src/test/java/entity/NoteTest.java
new file mode 100644
index 000000000..42405b940
--- /dev/null
+++ b/src/test/java/entity/NoteTest.java
@@ -0,0 +1,24 @@
+package entity;
+
+import org.junit.Test;
+
+public class NoteTest {
+ @Test
+ public void getContentTest() {
+ final Note testNote = new Note("content of note is here", "2024-11-18");
+ assert testNote.getContent().equals("content of note is here");
+ }
+
+ @Test
+ public void setContentTest() {
+ final Note testNote = new Note("content of note is here", "2024-11-18");
+ testNote.setContent("new note content");
+ assert testNote.getContent().equals("new note content");
+ }
+
+ @Test
+ public void getDateTest() {
+ final Note testNote = new Note("content of note is here", "2024-11-18");
+ assert testNote.getTitle().equals("2024-11-18");
+ }
+}
diff --git a/src/test/java/entity/TaskTest.java b/src/test/java/entity/TaskTest.java
new file mode 100644
index 000000000..f4b77d938
--- /dev/null
+++ b/src/test/java/entity/TaskTest.java
@@ -0,0 +1,11 @@
+package entity;
+
+import org.junit.Test;
+
+public class TaskTest {
+ @Test
+ public void getTaskDescriptionTest() {
+ final Task testTask = new Task("title of task");
+ assert testTask.getDescription().equals("title of task");
+ }
+}
diff --git a/src/test/java/use_case/note/NoteInteractorTest.java b/src/test/java/use_case/note/NoteInteractorTest.java
deleted file mode 100644
index a3ed466b6..000000000
--- a/src/test/java/use_case/note/NoteInteractorTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package use_case.note;
-
-import entity.User;
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-public class NoteInteractorTest {
-
- @Test
- public void testExecuteRefreshSuccess() {
-
- NoteDataAccessInterface noteDAO = new NoteDataAccessInterface() {
-
-
- @Override
- public String saveNote(User user, String note) {
- return "";
- }
-
-
- @Override
- public String loadNote(User user) {
- return "test";
- }
- };
-
- NoteOutputBoundary noteOB = new NoteOutputBoundary() {
- @Override
- public void prepareSuccessView(String message) {
- assertEquals("test", message);
- }
-
- @Override
- public void prepareFailView(String errorMessage) {
- fail(errorMessage);
- }
- };
-
- NoteInteractor noteInteractor = new NoteInteractor(noteDAO, noteOB);
-
- noteInteractor.executeRefresh();
-
-
- }
-}
\ No newline at end of file
diff --git a/src/test/java/use_cases/add_task/AddTaskInteractorTest.java b/src/test/java/use_cases/add_task/AddTaskInteractorTest.java
new file mode 100644
index 000000000..3d607f51e
--- /dev/null
+++ b/src/test/java/use_cases/add_task/AddTaskInteractorTest.java
@@ -0,0 +1,30 @@
+package use_cases.add_task;
+
+import entity.Task;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class AddTaskInteractorTest {
+
+ @Test
+ public void successTest() {
+
+ final AddTaskInputData inputData = new AddTaskInputData("test description");
+
+ AddTaskOutputBoundary addTaskOB = new AddTaskOutputBoundary() {
+ @Override
+ public void prepareSuccessView(AddTaskOutputData outputData) {
+ assertEquals("test description", outputData.getDescription());
+ }
+
+ @Override
+ public void prepareFailView(String errorMessage) {
+ fail("Use case failure is unexpected.");
+ }
+ };
+ AddTaskInteractor addTaskInteractor = new AddTaskInteractor(addTaskOB);
+ addTaskInteractor.execute(inputData);
+ }
+}
diff --git a/src/test/java/use_cases/ai/AiInteractorTest.java b/src/test/java/use_cases/ai/AiInteractorTest.java
new file mode 100644
index 000000000..e34941543
--- /dev/null
+++ b/src/test/java/use_cases/ai/AiInteractorTest.java
@@ -0,0 +1,25 @@
+package use_cases.ai;
+
+import entity.Note;
+import org.junit.Test;
+import use_cases.add_task.AddTaskInputData;
+import use_cases.add_task.AddTaskInteractor;
+import use_cases.add_task.AddTaskOutputBoundary;
+import use_cases.add_task.AddTaskOutputData;
+
+import static org.junit.Assert.*;
+
+public class AiInteractorTest {
+
+ @Test
+ public void successTest() {
+ AiOutputBoundary aiOutputBoundary = new AiOutputBoundary() {
+ @Override
+ public void updateNote(Note note) {
+ assertNotNull(note);
+ }
+ };
+ AiInteractor aiInteractor = new AiInteractor(aiOutputBoundary, new AiRequest());
+ aiInteractor.generateResponse(new Note("testing Note!", "Note title"));
+ }
+}
diff --git a/src/test/java/use_cases/calendar/CalendarInteractorTest.java b/src/test/java/use_cases/calendar/CalendarInteractorTest.java
new file mode 100644
index 000000000..4b6f1e37f
--- /dev/null
+++ b/src/test/java/use_cases/calendar/CalendarInteractorTest.java
@@ -0,0 +1,31 @@
+package use_cases.calendar;
+
+import entity.Note;
+import org.junit.Test;
+import entity.Events;
+import use_cases.ai.AiInteractor;
+import use_cases.ai.AiOutputBoundary;
+import use_cases.ai.AiRequest;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+
+public class CalendarInteractorTest {
+
+ @Test
+ public void successTest() throws GeneralSecurityException, IOException {
+ CalendarOutputBoundary calendarOutputBoundary = new CalendarOutputBoundary() {
+ @Override
+ public void prepareSuccessView(List events) {
+ assertNotNull(events);
+ }
+ };
+ CalendarInteractor calendarInteractor = new CalendarInteractor(calendarOutputBoundary, new CalendarRequest());
+ calendarInteractor.execute("jennazhang.jz@gmail.com");
+ }
+
+}
diff --git a/src/test/java/use_cases/note/NoteInteractorTest.java b/src/test/java/use_cases/note/NoteInteractorTest.java
new file mode 100644
index 000000000..9c9ed6960
--- /dev/null
+++ b/src/test/java/use_cases/note/NoteInteractorTest.java
@@ -0,0 +1,32 @@
+package use_cases.note;
+
+import data_access.InMemoryNoteDataAccessObject;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class NoteInteractorTest {
+
+ @Test
+ public void testExecuteSaveSuccess() {
+ NoteInputData inputData = new NoteInputData("Test note", "This is a sample note! " +
+ "This tests to see if the note is properly saved. ");
+ NoteDataAccessInterface noteDataAccess = new InMemoryNoteDataAccessObject();
+ noteDataAccess.saveNote(inputData.getTitle(), inputData.getContent());
+
+ NoteOutputBoundary successPresenter = new NoteOutputBoundary() {
+ @Override
+ public void prepareSuccessView(String message) {
+ assertEquals("Use case success is expected","This is a sample note! This tests to see if the note is properly saved. ", inputData.getContent());
+ }
+
+ @Override
+ public void prepareFailView(String errorMessage) {
+ fail("Use case failure is unexpected.");
+ }
+ };
+
+ NoteInputBoundary noteInteractor = new NoteInteractor(successPresenter, noteDataAccess);
+ noteInteractor.execute(inputData);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/use_cases/note/TranslationInteractorTest.java b/src/test/java/use_cases/note/TranslationInteractorTest.java
new file mode 100644
index 000000000..b198cd34b
--- /dev/null
+++ b/src/test/java/use_cases/note/TranslationInteractorTest.java
@@ -0,0 +1,109 @@
+package use_cases.note;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class TranslationInteractorTest {
+
+ @Test
+ public void testTranslate2Russian() {
+ final TranslationInputData inputData = new TranslationInputData("Hello world", "Russian");
+
+ TranslationOutputBoundary outputBoundary = new TranslationOutputBoundary() {
+ @Override
+ public void updateTranslation(TranslationOutputData outputData) {
+ assertEquals("Привет мир", outputData.getTranslatedText());
+ }
+ };
+ TranslationInteractor translationInteractor = new TranslationInteractor(outputBoundary);
+ translationInteractor.translateNote(inputData);
+ }
+
+ @Test
+ public void testTranslate2Spanish() {
+ final TranslationInputData inputData = new TranslationInputData("Welcome everyone", "Spanish");
+
+ TranslationOutputBoundary outputBoundary = new TranslationOutputBoundary() {
+ @Override
+ public void updateTranslation(TranslationOutputData outputData) {
+ assertEquals("Bienvenido a todos", outputData.getTranslatedText());
+ }
+ };
+ TranslationInteractor translationInteractor = new TranslationInteractor(outputBoundary);
+ translationInteractor.translateNote(inputData);
+ }
+
+ @Test
+ public void testTranslate2French() {
+ final TranslationInputData inputData = new TranslationInputData("Hello everyone", "French");
+
+ TranslationOutputBoundary outputBoundary = new TranslationOutputBoundary() {
+ @Override
+ public void updateTranslation(TranslationOutputData outputData) {
+ assertEquals("Bonjour à tous", outputData.getTranslatedText());
+ }
+ };
+ TranslationInteractor translationInteractor = new TranslationInteractor(outputBoundary);
+ translationInteractor.translateNote(inputData);
+ }
+
+ @Test
+ public void testTranslate2Arabic() {
+ final TranslationInputData inputData = new TranslationInputData("Please and thank you", "Arabic");
+
+ TranslationOutputBoundary outputBoundary = new TranslationOutputBoundary() {
+ @Override
+ public void updateTranslation(TranslationOutputData outputData) {
+ assertEquals("من فضلك وشكرا لكم", outputData.getTranslatedText());
+ }
+ };
+ TranslationInteractor translationInteractor = new TranslationInteractor(outputBoundary);
+ translationInteractor.translateNote(inputData);
+ }
+
+ @Test
+ public void testLanguageNotInDropdown() {
+ // If selected language is not part of the dropdown list, should output original text
+ final TranslationInputData inputData = new TranslationInputData("Hello everyone", "Italian");
+
+ TranslationOutputBoundary outputBoundary = new TranslationOutputBoundary() {
+ @Override
+ public void updateTranslation(TranslationOutputData outputData) {
+ assertEquals("Hello everyone", outputData.getTranslatedText());
+ }
+ };
+ TranslationInteractor translationInteractor = new TranslationInteractor(outputBoundary);
+ translationInteractor.translateNote(inputData);
+ }
+
+ @Test
+ public void testTranslateEmptyString() {
+ // Empty string should return empty string
+ final TranslationInputData inputData = new TranslationInputData(" ", "French");
+
+ TranslationOutputBoundary outputBoundary = new TranslationOutputBoundary() {
+ @Override
+ public void updateTranslation(TranslationOutputData outputData) {
+ assertEquals("", outputData.getTranslatedText());
+ }
+ };
+ TranslationInteractor translationInteractor = new TranslationInteractor(outputBoundary);
+ translationInteractor.translateNote(inputData);
+ }
+
+ @Test
+ public void testExceededCharLimit() {
+ String text = "hello ".repeat(400);
+ final TranslationInputData inputData = new TranslationInputData(text, "Spanish");
+
+ TranslationOutputBoundary outputBoundary = new TranslationOutputBoundary() {
+ @Override
+ public void updateTranslation(TranslationOutputData outputData) {
+ assertEquals("Exceeded character limit", outputData.getTranslatedText());
+ }
+ };
+ TranslationInteractor translationInteractor = new TranslationInteractor(outputBoundary);
+ translationInteractor.translateNote(inputData);
+ }
+}
\ No newline at end of file