diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..0aeb184 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +es-abdelmoneim.hany2019@alexu.edu.eg. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/backend/src/main/java/com/barmjz/productivityapp/Folder/Folder.java b/backend/src/main/java/com/barmjz/productivityapp/Folder/Folder.java index 39d43c8..82346e5 100644 --- a/backend/src/main/java/com/barmjz/productivityapp/Folder/Folder.java +++ b/backend/src/main/java/com/barmjz/productivityapp/Folder/Folder.java @@ -45,7 +45,11 @@ public class Folder { private Date CreatedDate; private Date modifiedDate; - @ManyToOne(fetch = FetchType.LAZY, optional = false) + @ManyToOne( + optional = false, + cascade = CascadeType.ALL + ) + @OnDelete(action = OnDeleteAction.CASCADE) @JoinColumn( name = "user_id", referencedColumnName = "id" diff --git a/backend/src/main/java/com/barmjz/productivityapp/Note/NoteController.java b/backend/src/main/java/com/barmjz/productivityapp/Note/NoteController.java index f5fd095..956671c 100644 --- a/backend/src/main/java/com/barmjz/productivityapp/Note/NoteController.java +++ b/backend/src/main/java/com/barmjz/productivityapp/Note/NoteController.java @@ -1,7 +1,6 @@ package com.barmjz.productivityapp.Note; -import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.AllArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -27,13 +26,13 @@ public ResponseEntity createNote(@RequestParam("folderId") Long folderId, } @PutMapping("/modify") - public ResponseEntity modifyNote(@RequestParam("noteId") Long noteId, @RequestBody ObjectNode objectNode) { + public ResponseEntity modifyNote(@RequestParam("folderId") Long folderId, @RequestBody String modifiedNote) { try { - String title = objectNode.get("title").asText(); - String content = objectNode.get("content").asText(); - return ResponseEntity.status(HttpStatus.OK).body(noteManager.modifyNote(noteId, title, content)); + System.out.println(modifiedNote); +// return ResponseEntity.status(HttpStatus.OK).body(noteManager.modifyNote(modifiedNote, folderId)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null); } catch (Exception exception) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Fuck"); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null); } } diff --git a/backend/src/main/java/com/barmjz/productivityapp/Note/NoteManager.java b/backend/src/main/java/com/barmjz/productivityapp/Note/NoteManager.java index 323c108..61851d0 100644 --- a/backend/src/main/java/com/barmjz/productivityapp/Note/NoteManager.java +++ b/backend/src/main/java/com/barmjz/productivityapp/Note/NoteManager.java @@ -39,18 +39,24 @@ public Note createNote(Long folderId, String noteTitle){ return newNote; } - public String modifyNote(Long noteId, String title, String content){ - if(noteId == null || !noteRepo.existsById(noteId)) + public Note modifyNote(Note modifiedNote, Long folderId){ + if(modifiedNote == null || modifiedNote.getId() == null) + throw new NullPointerException("note is null"); + if(!noteRepo.existsById(modifiedNote.getId())) throw new NoSuchElementException("note not found"); - Note existedNote = noteRepo.getReferenceById(noteId); - if( (noteRepo.existsByTitleAndFolder_Id(title,existedNote.getFolder().getId())) && - (!noteRepo.findByTitleAndFolder_Id(title,existedNote.getFolder().getId()).getId().equals(existedNote.getId()))) - throw new IllegalStateException("note new title already exist"); - existedNote.setTitle(title); - existedNote.setContent(content); +// if(!noteRepo.findByTitleAndFolder_Id(modifiedNote.getTitle(),folderId) +// .getId().equals(modifiedNote.getId())) +// throw new IllegalStateException("note title already exist"); + Note existedNote = noteRepo.getReferenceById(modifiedNote.getId()); + // need more efficient way + existedNote.setTitle(modifiedNote.getTitle()); + existedNote.setContent(modifiedNote.getContent()); existedNote.setModifiedDate(new Date()); + existedNote.setStarred(modifiedNote.isStarred()); + existedNote.setColor(modifiedNote.getColor()); + existedNote.setFontSize(modifiedNote.getFontSize()); noteRepo.save(existedNote); - return "note modified"; + return existedNote; } public List getFolderNotes(Long folderId){ @@ -74,8 +80,8 @@ public List getUserStarredNotes(Long userId){ public Note moveNote(Long newFolderId, Long noteId){ if(noteId == null || newFolderId == null || !folderRepo.existsFolderById(newFolderId) || !noteRepo.existsById(noteId)) throw new NoSuchElementException("not found"); - Note note = noteRepo.findById(noteId).get(); - note.setFolder(folderRepo.findById(newFolderId).get()); + Note note = noteRepo.getReferenceById(noteId); + note.setFolder(folderRepo.getReferenceById(newFolderId)); noteRepo.save(note); return note; } diff --git a/backend/src/main/java/com/barmjz/productivityapp/todo_task_category/task/TaskService.java b/backend/src/main/java/com/barmjz/productivityapp/todo_task_category/task/TaskService.java index 32c5240..f2dab8f 100644 --- a/backend/src/main/java/com/barmjz/productivityapp/todo_task_category/task/TaskService.java +++ b/backend/src/main/java/com/barmjz/productivityapp/todo_task_category/task/TaskService.java @@ -36,6 +36,10 @@ public TaskService(UserRepo userRepo, CategoryRepo categoryRepo, OneTimeTaskRepo this.repeatedTaskRepo = repeatedTaskRepo; } + @Autowired + + + public Task getTask(Long taskId){ if (oneTimeTaskRepo.existsById(taskId)) return oneTimeTaskRepo.findById(taskId).orElse(null); diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index 9ba29f8..b95b7b7 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -1,10 +1,10 @@ spring.datasource.url=jdbc:mysql://localhost:3306/prod_schema spring.datasource.username=root -spring.datasource.password=root +spring.datasource.password=1000*1000 spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.formate_sql=true spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver spring.jpa.show-sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL55Dialect rsa.private-key=classpath:certs/private.pem -rsa.public-key=classpath:certs/public.pem +rsa.public-key=classpath:certs/public.pem \ No newline at end of file diff --git a/backend/src/test/java/com/barmjz/productivityapp/Folder/GetUserFolderTest.java b/backend/src/test/java/com/barmjz/productivityapp/Folder/GetUserFolderTest.java index 2731245..de7235b 100644 --- a/backend/src/test/java/com/barmjz/productivityapp/Folder/GetUserFolderTest.java +++ b/backend/src/test/java/com/barmjz/productivityapp/Folder/GetUserFolderTest.java @@ -71,7 +71,6 @@ void getExistedUserFolders(){ @Test void getNonExistedUserFolders(){ - userRepo.save(user1); folderRepo.save(folder1); folderRepo.save(folder2); assertThatThrownBy(() -> folderManager.getUserFolders(user1.getId()+3)) diff --git a/backend/src/test/java/com/barmjz/productivityapp/Note/CreateNoteTest.java b/backend/src/test/java/com/barmjz/productivityapp/Note/CreateNoteTest.java index 6ce8fc8..6f65174 100644 --- a/backend/src/test/java/com/barmjz/productivityapp/Note/CreateNoteTest.java +++ b/backend/src/test/java/com/barmjz/productivityapp/Note/CreateNoteTest.java @@ -3,7 +3,6 @@ import com.barmjz.productivityapp.Folder.Folder; import com.barmjz.productivityapp.Folder.FolderRepo; import com.barmjz.productivityapp.user.User; -import com.barmjz.productivityapp.user.UserRepo; import lombok.Data; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -20,11 +19,9 @@ @DataJpaTest class CreateNoteTest { - @Autowired UserRepo userRepo; @Autowired FolderRepo folderRepo; @Autowired NoteRepo noteRepo; NoteManager noteManager; - User user; Folder folder; Note note1; Note note2; @@ -36,16 +33,14 @@ void setUp() { folderRepo.deleteAll(); noteRepo.deleteAll(); date = new Date(); - user = User.builder() - .email("user1@gmail.com") - .password("pass") - .firstName("userFirst") - .lastName("userLast") - .build(); - userRepo.save(user); folder = Folder.builder() .name("folder") - .user(user) + .user(User.builder() + .email("user1@gmail.com") + .password("pass") + .firstName("userFirst") + .lastName("userLast") + .build()) .CreatedDate(date) .modifiedDate(date) .build(); diff --git a/backend/src/test/java/com/barmjz/productivityapp/Note/GetNoteTest.java b/backend/src/test/java/com/barmjz/productivityapp/Note/GetNoteTest.java index ec04ebe..6fec96a 100644 --- a/backend/src/test/java/com/barmjz/productivityapp/Note/GetNoteTest.java +++ b/backend/src/test/java/com/barmjz/productivityapp/Note/GetNoteTest.java @@ -102,7 +102,7 @@ void getStarredNotes(){ note2 = noteManager.createNote(folder2.getId(),"note2"); note2.setContent("content2"); noteManager.alterStar(note2.getId()); - noteManager.modifyNote(note2.getId(), note2.getTitle(), note2.getContent()); + noteManager.modifyNote(note2, note2.getFolder().getId()); assertThat(note2.isStarred()).isTrue(); assertThat(noteRepo.findById(note2.getId()).get().getContent()).isEqualTo("content2"); List starredNotes = new ArrayList<>(); diff --git a/backend/src/test/java/com/barmjz/productivityapp/Note/ModifyNoteTest.java b/backend/src/test/java/com/barmjz/productivityapp/Note/ModifyNoteTest.java index 6beed93..b331f66 100644 --- a/backend/src/test/java/com/barmjz/productivityapp/Note/ModifyNoteTest.java +++ b/backend/src/test/java/com/barmjz/productivityapp/Note/ModifyNoteTest.java @@ -3,7 +3,6 @@ import com.barmjz.productivityapp.Folder.Folder; import com.barmjz.productivityapp.Folder.FolderRepo; import com.barmjz.productivityapp.user.User; -import com.barmjz.productivityapp.user.UserRepo; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -19,8 +18,8 @@ @DataJpaTest class ModifyNoteTest { - @Autowired UserRepo userRepo; - @Autowired FolderRepo folderRepo; + @Autowired + FolderRepo folderRepo; @Autowired NoteRepo noteRepo; NoteManager noteManager; Folder folder; @@ -34,16 +33,14 @@ void setUp() { folderRepo.deleteAll(); noteRepo.deleteAll(); date = new Date(); - User user = User.builder() - .email("user1@gmail.com") - .password("pass") - .firstName("userFirst") - .lastName("userLast") - .build(); - userRepo.save(user); folder = Folder.builder() .name("folder") - .user(user) + .user(User.builder() + .email("user1@gmail.com") + .password("pass") + .firstName("userFirst") + .lastName("userLast") + .build()) .CreatedDate(date) .modifiedDate(date) .build(); @@ -61,16 +58,19 @@ void modifyNote(){ .folder(folder) .createdDate(date) .modifiedDate(date) + .fontSize(8) .build(); - noteManager.modifyNote(note2.getId(), note2.getTitle(), note2.getContent()); + noteManager.modifyNote(note2, folder.getId()); assertThat(noteRepo.findById(note1.getId()).get().getContent()).isEqualTo("note 1 content"); + assertThat(noteRepo.findById(note1.getId()).get().getFontSize()).isEqualTo(8); +// assertThat(noteRepo.findById(note1.getId()).get()).isEqualTo(note2); } @Test void invalidModifiedNote(){ - assertThatThrownBy(() -> noteManager.modifyNote(null, "new title", "new content")) - .isInstanceOf(NoSuchElementException.class) - .hasMessageContaining("note not found"); + assertThatThrownBy(() -> noteManager.modifyNote(null, folder.getId())) + .isInstanceOf(NullPointerException.class) + .hasMessageContaining("note is null"); } @Test @@ -85,8 +85,9 @@ void modifyNonExistedNote(){ .folder(folder) .createdDate(date) .modifiedDate(date) + .fontSize(8) .build(); - assertThatThrownBy(() -> noteManager.modifyNote(note2.getId(),note2.getTitle(), note2.getContent())) + assertThatThrownBy(() -> noteManager.modifyNote(note2,folder.getId())) .isInstanceOf(NoSuchElementException.class) .hasMessageContaining("note not found"); } diff --git a/frontend/App.js b/frontend/App.js index 7c1b195..0715e44 100644 --- a/frontend/App.js +++ b/frontend/App.js @@ -1,18 +1,43 @@ -import 'react-native-gesture-handler'; import * as React from "react"; -import { StatusBar } from "expo-status-bar"; +import { Home } from "./components/Home"; +import { Login } from "./components/Login"; +import { PasswordRecovery } from "./components/PasswordRecovery"; +import { SignUp } from "./components/SignUp"; +import TodoScreen from "./components/TodoScreen"; +import MindMapScreen from "./components/MindMapScreen"; +import { Notes } from "./components/notes-component/Notes-Main"; +import { StatusBar } from 'expo-status-bar'; +import { NavigationContainer } from "@react-navigation/native"; +import { createNativeStackNavigator } from "@react-navigation/native-stack"; import { NativeBaseProvider } from "native-base"; import { AuthContextProvider } from "./store/auth-context"; import { theme } from "./UI/theme"; -import AppNavigation from "./AppNavigation"; + + +const Stack = createNativeStackNavigator(); + export default function App() { return ( - - + + + + + + + + + + {/* */} + + + ); diff --git a/frontend/AppNavigation.js b/frontend/AppNavigation.js deleted file mode 100644 index f085cc2..0000000 --- a/frontend/AppNavigation.js +++ /dev/null @@ -1,71 +0,0 @@ -import React, { useContext } from "react"; -import { VStack } from "native-base"; -import AuthContext from "./store/auth-context"; - -import { NavigationContainer } from "@react-navigation/native"; -import { createNativeStackNavigator } from "@react-navigation/native-stack"; -import { createDrawerNavigator } from "@react-navigation/drawer"; - -const Stack = createNativeStackNavigator(); -const Drawer = createDrawerNavigator(); - -import { Home } from "./components/home-component/Home"; -import { Login } from "./components/login-component/LoginScreen"; -import { PasswordRecovery } from "./components/login-component/PasswordRecoveryScreen"; -import { SignUp } from "./components/login-component/SignUpScreen"; -import { Notes } from "./components/notes-component/NotesScreen"; -import TodoScreen from "./components/todo-component/TodoScreen"; -import MindMapScreen from "./components/mindmap-component/MindMapScreen"; - -const AppNavigation = () => { - const auth = useContext(AuthContext); - - return ( - - {auth.isLoggedIn ? ( - - - - - - - ) : ( - - - - - - )} - - ); -}; - -import { - DrawerContentScrollView, - DrawerItemList, - DrawerItem, -} from "@react-navigation/drawer"; -import { Ionicons } from "@expo/vector-icons"; - -function CustomDrawerContent(props) { - const auth = useContext(AuthContext); - - return ( - - - - - - } - labelStyle={{ marginLeft: -25 }} - onPress={() => auth.logout()} - /> - - ); -} -export default AppNavigation; diff --git a/frontend/UI/NavigationButton.js b/frontend/UI/NavigationButton.js deleted file mode 100644 index f6c807e..0000000 --- a/frontend/UI/NavigationButton.js +++ /dev/null @@ -1,20 +0,0 @@ -import React from "react"; -import { IconButton, HamburgerIcon } from "native-base"; -import { DrawerActions, useNavigation } from "@react-navigation/native"; - -export const NavigationButton = ({ navigation }) => { - const navigate = useNavigation(); - - const toggleDrawer = () => { - navigate.dispatch(DrawerActions.toggleDrawer()); - }; - - return ( - } - > - Toggle - - ); -}; diff --git a/frontend/api/notes.api.js b/frontend/api/notes.api.js index 4b5b041..22b1a31 100644 --- a/frontend/api/notes.api.js +++ b/frontend/api/notes.api.js @@ -105,43 +105,21 @@ export const getFolders = async (token) => { return response; } - export const editNote = async (noteId, title, content, token) => { - const url = `${BACKEND_URL}/note/modify?noteId=${noteId}`; + export const editNote = async (note, folderId, token) => { + const url = `${BACKEND_URL}/note/modify?folderId=${folderId}`; - const stringBody = { - title: `${title}`, - content: `${content}` - } - - const response = await fetch(url, { - method: "PUT", - headers: { "Content-type": "application/json", Authorization: `Bearer ${token}` }, - body: JSON.stringify(stringBody), - }).catch((error) => { - throw new Error("Problem connecting with the server!"); - }); - - if (response.status !== 200) { - const message = "I don't Know Yet"; - throw new Error(message); - } - - return response; - } - - export const MoveNoteToFolder = async (newFolderId, noteId, token) => { - const url = `${BACKEND_URL}/note/moveNote?newFolderId=${newFolderId}¬eId=${noteId}`; + console.log("Note", note) const response = await fetch(url, { method: "PUT", headers: { "Content-type": "application/json", Authorization: `Bearer ${token}` }, + body: note, }).catch((error) => { throw new Error("Problem connecting with the server!"); }); - console.log(response.headers) if (response.status !== 200) { - const message = "I don't know yet."; + const message = "Folder has the same name as this"; throw new Error(message); } diff --git a/frontend/babel.config.js b/frontend/babel.config.js index 99860ab..2900afe 100644 --- a/frontend/babel.config.js +++ b/frontend/babel.config.js @@ -1,10 +1,6 @@ -module.exports = function (api) { +module.exports = function(api) { api.cache(true); return { - presets: ["babel-preset-expo"], - plugins: [ - "@babel/plugin-proposal-export-namespace-from", - "react-native-reanimated/plugin", - ], + presets: ['babel-preset-expo'], }; }; diff --git a/frontend/components/home-component/Home.js b/frontend/components/Home.js similarity index 68% rename from frontend/components/home-component/Home.js rename to frontend/components/Home.js index 9e65c97..901bc0a 100644 --- a/frontend/components/home-component/Home.js +++ b/frontend/components/Home.js @@ -1,10 +1,9 @@ import { useContext, useState, useEffect } from "react"; -import { Text, View } from "react-native"; -import AuthContext from "../../store/auth-context"; -import { getUser } from "../../api/user.api"; -import { NavigationButton } from "../../UI/NavigationButton"; +import { Button, Text, View } from "react-native"; +import AuthContext from "../store/auth-context"; +import { getUser } from "../api/user.api"; -export const Home = () => { +export const Home = ({ navigation }) => { const [name, setName] = useState(""); const auth = useContext(AuthContext); @@ -22,12 +21,13 @@ export const Home = () => { return ( - Welcome Home 😁 {auth.isLoggedIn && Hello, {name}} {auth.isLoggedIn && ( logged in Token = {auth.token} )} +