From 6a839b7d287c458aeaea984aa30b2abf40cfb6c7 Mon Sep 17 00:00:00 2001 From: mirrerror Date: Thu, 26 Oct 2023 21:05:04 +0300 Subject: [PATCH 01/17] update package-lock.json --- package-lock.json | 6 ++++ .../expensetrackerfaf/web/package-lock.json | 28 ++++++------------- 2 files changed, 14 insertions(+), 20 deletions(-) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..4cd0ed2 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "ExpenseTrackerFAF", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/package-lock.json b/src/main/java/com/faf223/expensetrackerfaf/web/package-lock.json index d332004..4c8d4c8 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/web/package-lock.json +++ b/src/main/java/com/faf223/expensetrackerfaf/web/package-lock.json @@ -656,9 +656,9 @@ } }, "node_modules/@sveltejs/kit": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.25.1.tgz", - "integrity": "sha512-pD8XsvNJNgTNkFngNlM60my/X8dXWPKVzN5RghEQr0NjGZmuCjy49AfFu2cGbZjNf5pBcqd2RCNMW912P5fkhA==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.27.0.tgz", + "integrity": "sha512-a1wPIq2uO3RsTmV+KbA4venOgCJDbfHTXFe+g7eJR3N8l46DSuulUONJ1qnk2EnZWYC1Uj3Wbp3US0WFocIzXg==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -669,12 +669,12 @@ "esm-env": "^1.0.0", "kleur": "^4.1.5", "magic-string": "^0.30.0", - "mime": "^3.0.0", + "mrmime": "^1.0.1", "sade": "^1.8.1", "set-cookie-parser": "^2.6.0", "sirv": "^2.0.2", "tiny-glob": "^0.2.9", - "undici": "~5.25.0" + "undici": "~5.26.2" }, "bin": { "svelte-kit": "svelte-kit.js" @@ -1759,18 +1759,6 @@ "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", "dev": true }, - "node_modules/mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -2470,9 +2458,9 @@ } }, "node_modules/undici": { - "version": "5.25.4", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.25.4.tgz", - "integrity": "sha512-450yJxT29qKMf3aoudzFpIciqpx6Pji3hEWaXqXmanbXF58LTAGCKxcJjxMXWu3iG+Mudgo3ZUfDB6YDFd/dAw==", + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.26.5.tgz", + "integrity": "sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw==", "dev": true, "dependencies": { "@fastify/busboy": "^2.0.0" -- 2.49.1 From 8f934bdf322dcd271f8bd83e82741a430b39007f Mon Sep 17 00:00:00 2001 From: mirrerror Date: Thu, 26 Oct 2023 21:55:11 +0300 Subject: [PATCH 02/17] fix cors --- .../expensetrackerfaf/config/CorsFilter.java | 39 +------------------ 1 file changed, 1 insertion(+), 38 deletions(-) diff --git a/src/main/java/com/faf223/expensetrackerfaf/config/CorsFilter.java b/src/main/java/com/faf223/expensetrackerfaf/config/CorsFilter.java index ed23357..59acdc8 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/config/CorsFilter.java +++ b/src/main/java/com/faf223/expensetrackerfaf/config/CorsFilter.java @@ -1,39 +1,2 @@ -package com.faf223.expensetrackerfaf.config; - -import jakarta.servlet.*; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; - -import java.io.IOException; - -@Component -@Order(Ordered.HIGHEST_PRECEDENCE) -public class CorsFilter implements Filter { - - @Override - public void destroy() { - } - - - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { - HttpServletResponse response = (HttpServletResponse) servletResponse; - response.setHeader("Access-Control-Allow-Origin", "*"); - response.setHeader("Access-Control-Allow-Credentials", "true"); - response.setHeader("Access-Control-Allow-Methods", "POST, GET, HEAD, OPTIONS"); - response.setHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"); - if ("OPTIONS".equalsIgnoreCase(((HttpServletRequest) servletRequest).getMethod())) { - response.setStatus(HttpServletResponse.SC_OK); - } else { - filterChain.doFilter(servletRequest, response); - } - - } - - @Override - public void init(FilterConfig config) { - } +package com.faf223.expensetrackerfaf.config;public class CorsFilter { } -- 2.49.1 From eca57b111a6e23eb53e991bdd821b071d9c1786f Mon Sep 17 00:00:00 2001 From: mirrerror Date: Thu, 26 Oct 2023 21:55:27 +0300 Subject: [PATCH 03/17] fix cors --- pom.xml | 12 ++++++ .../expensetrackerfaf/config/CorsConfig.java | 2 +- .../expensetrackerfaf/config/CorsFilter.java | 41 ++++++++++++++++++- .../config/SecurityConfiguration.java | 17 +++----- 4 files changed, 58 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index 5744dc1..862aa65 100644 --- a/pom.xml +++ b/pom.xml @@ -73,6 +73,18 @@ jakarta.validation-api 2.0.2 + + + org.springframework.security + spring-security-web + 6.1.5 + + + + org.springframework.security + spring-security-web + 6.1.5 + diff --git a/src/main/java/com/faf223/expensetrackerfaf/config/CorsConfig.java b/src/main/java/com/faf223/expensetrackerfaf/config/CorsConfig.java index 458f2ff..c98ccdf 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/config/CorsConfig.java +++ b/src/main/java/com/faf223/expensetrackerfaf/config/CorsConfig.java @@ -9,6 +9,6 @@ public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { - registry.addMapping("/**").allowedMethods("*"); + registry.addMapping("/**").allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH").allowedOrigins("http://localhost:5173/"); } } diff --git a/src/main/java/com/faf223/expensetrackerfaf/config/CorsFilter.java b/src/main/java/com/faf223/expensetrackerfaf/config/CorsFilter.java index 59acdc8..bb34047 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/config/CorsFilter.java +++ b/src/main/java/com/faf223/expensetrackerfaf/config/CorsFilter.java @@ -1,2 +1,39 @@ -package com.faf223.expensetrackerfaf.config;public class CorsFilter { -} +package com.faf223.expensetrackerfaf.config; + +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.io.IOException; + +@Component +@Order(Ordered.HIGHEST_PRECEDENCE) +public class CorsFilter implements Filter { + + @Override + public void destroy() { + } + + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + HttpServletResponse response = (HttpServletResponse) servletResponse; + response.setHeader("Access-Control-Allow-Origin", "*"); + response.setHeader("Access-Control-Allow-Credentials", "true"); + response.setHeader("Access-Control-Allow-Methods", "POST, GET, HEAD, OPTIONS"); + response.setHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"); + if ("OPTIONS".equalsIgnoreCase(((HttpServletRequest) servletRequest).getMethod())) { + response.setStatus(HttpServletResponse.SC_OK); + } else { + filterChain.doFilter(servletRequest, response); + } + + } + + @Override + public void init(FilterConfig config) { + } +} \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/config/SecurityConfiguration.java b/src/main/java/com/faf223/expensetrackerfaf/config/SecurityConfiguration.java index 7343ab9..5fb1804 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/config/SecurityConfiguration.java +++ b/src/main/java/com/faf223/expensetrackerfaf/config/SecurityConfiguration.java @@ -1,27 +1,21 @@ package com.faf223.expensetrackerfaf.config; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.oauth2.client.registration.ClientRegistration; -import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; -import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository; -import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; -import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; -import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; -import org.springframework.security.oauth2.core.AuthorizationGrantType; -import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames; -import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import java.util.Arrays; @Configuration @EnableWebSecurity @@ -35,6 +29,7 @@ public class SecurityConfiguration { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http + .cors(new CorsConfig()) .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(auth -> auth .requestMatchers("/api/v1/auth/**").permitAll() -- 2.49.1 From 7befb0dac796af17325ffe669816e2a17bf2b213 Mon Sep 17 00:00:00 2001 From: Daniel <59575049+lumijiez@users.noreply.github.com> Date: Fri, 27 Oct 2023 01:24:43 +0300 Subject: [PATCH 04/17] Update README.md --- README.md | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7a78351..c0770a5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,63 @@ -# ExpenseTrackerFAF +# Expense Tracker App + +## Description + +Expense Tracker is a web application that helps you keep track of your expenses and incomes. It provides a user-friendly interface to enter and visualize your financial data, making it easier to manage your finances. + +## Features + +- Single-page application for a smooth and responsive user experience. +- Reactive graph updates to visualize your financial data. +- Ability to add incomes and expenses to your account. +- Full-fledged authorization system to secure your data. +- Hosted database for seamless data storage and retrieval. + +## Tech Stack + +### Frontend + +- Svelte +- Chart.js +- Axios + +### Backend + +- Spring +- Spring Boot +- Spring Security + +### Database + +- MySQL +- phpMyAdmin + +## Installation Instructions + +To run the Expense Tracker application, follow these steps: + +1. Clone the project repository to your local machine. + +2. Install the required Maven dependencies for the backend. In the project directory, run: + +3. Run the backend Spring application to start the server. + +4. For the frontend, navigate to the `frontend` directory and run: + +```npm install``` +```npm run dev``` + +This will start the frontend development server and open the application in your web browser. + +Now you can access the Expense Tracker application at http://localhost:3000 and start tracking your expenses and incomes visually. + +Please note that you need to configure the database connection details and other environment-specific settings in the application properties before running the backend. + +### Configuration + +Make sure to update the configuration files with your specific database settings, security configurations, and other environment variables as needed. You can find these configuration files in the backend project. + +Feel free to customize the application further and adapt it to your specific use case. + +Happy expense tracking! + -Expense tracker project made in Spring by a group of senior full-stack Nobel winner students. -- 2.49.1 From 4fdd67fa2144c20ff089b945ca01aa13dd529a42 Mon Sep 17 00:00:00 2001 From: Daniel <59575049+lumijiez@users.noreply.github.com> Date: Fri, 27 Oct 2023 01:25:52 +0300 Subject: [PATCH 05/17] Update README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c0770a5..4cdc350 100644 --- a/README.md +++ b/README.md @@ -41,14 +41,15 @@ To run the Expense Tracker application, follow these steps: 3. Run the backend Spring application to start the server. -4. For the frontend, navigate to the `frontend` directory and run: +4. For the frontend, navigate to the `web` directory and run: -```npm install``` -```npm run dev``` +```bash +npm install +npm run dev``` This will start the frontend development server and open the application in your web browser. -Now you can access the Expense Tracker application at http://localhost:3000 and start tracking your expenses and incomes visually. +Now you can access the Expense Tracker application at http://localhost:5173/auth/login and start tracking your expenses and incomes visually. Please note that you need to configure the database connection details and other environment-specific settings in the application properties before running the backend. -- 2.49.1 From 4403d60dc6c4e05a2d787c5e73fdf7928d773bb9 Mon Sep 17 00:00:00 2001 From: Daniel <59575049+lumijiez@users.noreply.github.com> Date: Fri, 27 Oct 2023 01:27:07 +0300 Subject: [PATCH 06/17] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4cdc350..4d50ba3 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,8 @@ To run the Expense Tracker application, follow these steps: ```bash npm install -npm run dev``` +npm run dev +``` This will start the frontend development server and open the application in your web browser. -- 2.49.1 From 94ef63253e1c3231a74cbe26f10b2d0762d216da Mon Sep 17 00:00:00 2001 From: Daniel <59575049+lumijiez@users.noreply.github.com> Date: Fri, 27 Oct 2023 01:27:32 +0300 Subject: [PATCH 07/17] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 4d50ba3..2fa38ed 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,9 @@ To run the Expense Tracker application, follow these steps: ```bash npm install +``` + +```bash npm run dev ``` -- 2.49.1 From 1ea883ae5f335703d01554f271e647547a990b6b Mon Sep 17 00:00:00 2001 From: Dmitrii Cravcenco Date: Fri, 27 Oct 2023 16:25:44 +0300 Subject: [PATCH 08/17] Add expense/income deletion --- .../expensetrackerfaf/controller/ExpenseController.java | 5 +++++ .../expensetrackerfaf/controller/IncomeController.java | 5 +++++ .../com/faf223/expensetrackerfaf/service/ExpenseService.java | 4 ++++ .../com/faf223/expensetrackerfaf/service/IncomeService.java | 4 ++++ 4 files changed, 18 insertions(+) diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java b/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java index 0c6b710..6d5268c 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java +++ b/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java @@ -98,4 +98,9 @@ public class ExpenseController { if (!categories.isEmpty()) return ResponseEntity.ok(categories); else return ResponseEntity.notFound().build(); } + + @DeleteMapping("/expenses/{id}") + public void deleteCategory(@PathVariable long id) { + expenseService.deleteExpenseById(id); + } } \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java b/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java index e43b5ba..5bb6e20 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java +++ b/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java @@ -96,4 +96,9 @@ public class IncomeController { if (!categories.isEmpty()) return ResponseEntity.ok(categories); else return ResponseEntity.notFound().build(); } + + @DeleteMapping("/incomes/{id}") + public void deleteIncome(@PathVariable long id) { + incomeService.deleteIncomeById(id); + } } \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java b/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java index 4209fd6..7976a33 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java +++ b/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java @@ -40,4 +40,8 @@ public class ExpenseService implements ITransactionService { public Expense getTransactionById(long id) { return expenseRepository.findById(id).orElse(null); } + + public void deleteExpenseById(long id) { + expenseRepository.deleteById(id); + } } \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java b/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java index 8287d01..dcfb2e9 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java +++ b/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java @@ -40,4 +40,8 @@ public class IncomeService implements ITransactionService { public Income getTransactionById(long id) { return incomeRepository.findById(id).orElse(null); } + + public void deleteIncomeById(long id) { + incomeRepository.deleteById(id); + } } -- 2.49.1 From 55dc6125ad6ba2c95aa19b9e7e89e7907cc7ca84 Mon Sep 17 00:00:00 2001 From: Dmitrii Cravcenco Date: Fri, 27 Oct 2023 16:25:44 +0300 Subject: [PATCH 09/17] Add expense/income deletion --- .../expensetrackerfaf/controller/ExpenseController.java | 5 +++++ .../expensetrackerfaf/controller/IncomeController.java | 5 +++++ .../com/faf223/expensetrackerfaf/service/ExpenseService.java | 4 ++++ .../com/faf223/expensetrackerfaf/service/IncomeService.java | 4 ++++ 4 files changed, 18 insertions(+) diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java b/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java index 0c6b710..501035f 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java +++ b/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java @@ -98,4 +98,9 @@ public class ExpenseController { if (!categories.isEmpty()) return ResponseEntity.ok(categories); else return ResponseEntity.notFound().build(); } + + @DeleteMapping("/delete/{id}") + public void deleteCategory(@PathVariable long id) { + expenseService.deleteExpenseById(id); + } } \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java b/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java index e43b5ba..164ec9e 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java +++ b/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java @@ -96,4 +96,9 @@ public class IncomeController { if (!categories.isEmpty()) return ResponseEntity.ok(categories); else return ResponseEntity.notFound().build(); } + + @DeleteMapping("/delete/{id}") + public void deleteIncome(@PathVariable long id) { + incomeService.deleteIncomeById(id); + } } \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java b/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java index 4209fd6..7976a33 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java +++ b/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java @@ -40,4 +40,8 @@ public class ExpenseService implements ITransactionService { public Expense getTransactionById(long id) { return expenseRepository.findById(id).orElse(null); } + + public void deleteExpenseById(long id) { + expenseRepository.deleteById(id); + } } \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java b/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java index 8287d01..dcfb2e9 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java +++ b/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java @@ -40,4 +40,8 @@ public class IncomeService implements ITransactionService { public Income getTransactionById(long id) { return incomeRepository.findById(id).orElse(null); } + + public void deleteIncomeById(long id) { + incomeRepository.deleteById(id); + } } -- 2.49.1 From eb2d0e53dc15ef27d89178ad3c75bd35e4f2bd64 Mon Sep 17 00:00:00 2001 From: Dmitrii Cravcenco Date: Fri, 27 Oct 2023 17:53:00 +0300 Subject: [PATCH 10/17] Add expense/income update --- .../controller/ExpenseController.java | 14 +++++++++----- .../controller/IncomeController.java | 19 +++++++++++-------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java b/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java index 501035f..b6b8964 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java +++ b/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java @@ -61,14 +61,18 @@ public class ExpenseController { } - // TODO: has to be checked on auto extracting Uuid - @PatchMapping() - public ResponseEntity updateExpense(@RequestBody ExpenseCreationDTO expenseDTO, + // TODO: check if the expense belongs to the user + @PatchMapping("/update/{id}") + public ResponseEntity updateExpense(@PathVariable long id, @RequestBody ExpenseCreationDTO expenseDTO, BindingResult bindingResult) { - Expense expense = expenseMapper.toExpense(expenseDTO); + Expense expense = expenseService.getTransactionById(id); + ExpenseCategory category = expenseCategoryService.getCategoryById(expenseDTO.getExpenseCategory()); + expense.setCategory(category); + expense.setAmount(expenseDTO.getAmount()); + if (!bindingResult.hasErrors()) { expenseService.createOrUpdate(expense); - return ResponseEntity.ok(expenseMapper.toDto(expense)); + return ResponseEntity.status(HttpStatus.CREATED).build(); } else { return ResponseEntity.notFound().build(); } diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java b/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java index 164ec9e..cbe59c2 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java +++ b/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java @@ -3,9 +3,7 @@ package com.faf223.expensetrackerfaf.controller; import com.faf223.expensetrackerfaf.dto.IncomeCreationDTO; import com.faf223.expensetrackerfaf.dto.IncomeDTO; import com.faf223.expensetrackerfaf.dto.mappers.IncomeMapper; -import com.faf223.expensetrackerfaf.model.Income; -import com.faf223.expensetrackerfaf.model.IncomeCategory; -import com.faf223.expensetrackerfaf.model.User; +import com.faf223.expensetrackerfaf.model.*; import com.faf223.expensetrackerfaf.service.IncomeCategoryService; import com.faf223.expensetrackerfaf.service.IncomeService; import com.faf223.expensetrackerfaf.service.UserService; @@ -60,13 +58,18 @@ public class IncomeController { return ResponseEntity.notFound().build(); } - @PatchMapping() - public ResponseEntity updateIncome(@RequestBody IncomeCreationDTO incomeDTO, - BindingResult bindingResult) { - Income income = incomeMapper.toIncome(incomeDTO); + // TODO: check if the income belongs to the user, extract logic into service + @PatchMapping("/update/{id}") + public ResponseEntity updateIncome(@PathVariable long id, @RequestBody IncomeCreationDTO incomeDTO, + BindingResult bindingResult) { + Income income = incomeService.getTransactionById(id); + IncomeCategory category = incomeCategoryService.getCategoryById(incomeDTO.getIncomeCategory()); + income.setCategory(category); + income.setAmount(incomeDTO.getAmount()); + if (!bindingResult.hasErrors()) { incomeService.createOrUpdate(income); - return ResponseEntity.ok(incomeMapper.toDto(income)); + return ResponseEntity.status(HttpStatus.CREATED).build(); } else { return ResponseEntity.notFound().build(); } -- 2.49.1 From f635ca3cb7962adb354a22525c2404dc2b95f7e8 Mon Sep 17 00:00:00 2001 From: mirrerror Date: Fri, 27 Oct 2023 21:14:31 +0300 Subject: [PATCH 11/17] fix abstraction for previous commits --- .../faf223/expensetrackerfaf/controller/ExpenseController.java | 2 +- .../faf223/expensetrackerfaf/controller/IncomeController.java | 2 +- .../com/faf223/expensetrackerfaf/service/ExpenseService.java | 2 +- .../faf223/expensetrackerfaf/service/ITransactionService.java | 1 + .../com/faf223/expensetrackerfaf/service/IncomeService.java | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java b/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java index b6b8964..581a891 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java +++ b/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java @@ -105,6 +105,6 @@ public class ExpenseController { @DeleteMapping("/delete/{id}") public void deleteCategory(@PathVariable long id) { - expenseService.deleteExpenseById(id); + expenseService.deleteTransactionById(id); } } \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java b/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java index cbe59c2..37cb865 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java +++ b/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java @@ -102,6 +102,6 @@ public class IncomeController { @DeleteMapping("/delete/{id}") public void deleteIncome(@PathVariable long id) { - incomeService.deleteIncomeById(id); + incomeService.deleteTransactionById(id); } } \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java b/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java index 7976a33..9ce7961 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java +++ b/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java @@ -41,7 +41,7 @@ public class ExpenseService implements ITransactionService { return expenseRepository.findById(id).orElse(null); } - public void deleteExpenseById(long id) { + public void deleteTransactionById(long id) { expenseRepository.deleteById(id); } } \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/service/ITransactionService.java b/src/main/java/com/faf223/expensetrackerfaf/service/ITransactionService.java index 6219bef..bdfe091 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/service/ITransactionService.java +++ b/src/main/java/com/faf223/expensetrackerfaf/service/ITransactionService.java @@ -10,5 +10,6 @@ public interface ITransactionService { List getTransactions(); List getTransactionsByEmail(String email); IMoneyTransaction getTransactionById(long id); + void deleteTransactionById(long it); } diff --git a/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java b/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java index dcfb2e9..3ad7973 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java +++ b/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java @@ -41,7 +41,7 @@ public class IncomeService implements ITransactionService { return incomeRepository.findById(id).orElse(null); } - public void deleteIncomeById(long id) { + public void deleteTransactionById(long id) { incomeRepository.deleteById(id); } } -- 2.49.1 From acbb6285d9181e4daa3f770f98aa56593a4163e0 Mon Sep 17 00:00:00 2001 From: mirrerror Date: Mon, 13 Nov 2023 09:08:16 +0200 Subject: [PATCH 12/17] add possibility to get expenses by date and month --- .../controller/ExpenseController.java | 12 ++++++-- .../controller/IncomeController.java | 29 +++++++++++++++++++ .../repository/ExpenseRepository.java | 4 +++ .../repository/IncomeRepository.java | 4 +++ .../service/ExpenseService.java | 16 ++++++++++ .../service/ITransactionService.java | 4 +++ .../service/IncomeService.java | 17 +++++++++++ 7 files changed, 84 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java b/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java index b783918..54a7e38 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java +++ b/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java @@ -19,8 +19,11 @@ import org.springframework.security.core.userdetails.UserDetails; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; +import java.time.LocalDate; +import java.time.Month; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; @RestController @@ -80,14 +83,19 @@ public class ExpenseController { } @GetMapping("/personal-expenses") - public ResponseEntity> getExpensesByUser() { + public ResponseEntity> getExpensesByUser(@RequestParam Optional date, + @RequestParam Optional month) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication != null && authentication.getPrincipal() instanceof UserDetails userDetails) { String email = userDetails.getUsername(); - List expenses = expenseService.getTransactionsByEmail(email).stream().map(expenseMapper::toDto).collect(Collectors.toList()); + List expenses; + + expenses = date.map(localDate -> expenseService.getTransactionsByDate(localDate).stream().map(expenseMapper::toDto).toList()) + .orElseGet(() -> month.map(value -> expenseService.getTransactionsByMonth(value).stream().map(expenseMapper::toDto).toList()) + .orElseGet(() -> expenseService.getTransactionsByEmail(email).stream().map(expenseMapper::toDto).toList())); if (!expenses.isEmpty()) { return ResponseEntity.ok(expenses); diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java b/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java index caaf2d9..b6bd9cc 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java +++ b/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java @@ -1,5 +1,6 @@ package com.faf223.expensetrackerfaf.controller; +import com.faf223.expensetrackerfaf.dto.ExpenseDTO; import com.faf223.expensetrackerfaf.dto.IncomeCreationDTO; import com.faf223.expensetrackerfaf.dto.IncomeDTO; import com.faf223.expensetrackerfaf.dto.mappers.IncomeMapper; @@ -17,8 +18,11 @@ import org.springframework.security.core.userdetails.UserDetails; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; +import java.time.LocalDate; +import java.time.Month; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; @RestController @@ -96,6 +100,31 @@ public class IncomeController { return ResponseEntity.notFound().build(); } + @GetMapping("/personal-incomes") + public ResponseEntity> getExpensesByUser(@RequestParam Optional date, + @RequestParam Optional month) { + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + if (authentication != null && authentication.getPrincipal() instanceof UserDetails userDetails) { + + String email = userDetails.getUsername(); + List incomes; + + incomes = date.map(localDate -> incomeService.getTransactionsByDate(localDate).stream().map(incomeMapper::toDto).toList()) + .orElseGet(() -> month.map(value -> incomeService.getTransactionsByMonth(value).stream().map(incomeMapper::toDto).toList()) + .orElseGet(() -> incomeService.getTransactionsByEmail(email).stream().map(incomeMapper::toDto).toList())); + + if (!incomes.isEmpty()) { + return ResponseEntity.ok(incomes); + } else { + return ResponseEntity.ok(Collections.emptyList()); + } + } + + return ResponseEntity.notFound().build(); + } + @GetMapping("/categories") public ResponseEntity> getAllCategories() { List categories = incomeCategoryService.getAllCategories(); diff --git a/src/main/java/com/faf223/expensetrackerfaf/repository/ExpenseRepository.java b/src/main/java/com/faf223/expensetrackerfaf/repository/ExpenseRepository.java index f96f68e..e9bbaa7 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/repository/ExpenseRepository.java +++ b/src/main/java/com/faf223/expensetrackerfaf/repository/ExpenseRepository.java @@ -5,9 +5,13 @@ import com.faf223.expensetrackerfaf.model.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.time.LocalDate; import java.util.List; @Repository public interface ExpenseRepository extends JpaRepository { List findByUser(User user); + List findByDate(LocalDate date); + + List findByDateBetween(LocalDate start, LocalDate end); } diff --git a/src/main/java/com/faf223/expensetrackerfaf/repository/IncomeRepository.java b/src/main/java/com/faf223/expensetrackerfaf/repository/IncomeRepository.java index 3f4f94d..48b038d 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/repository/IncomeRepository.java +++ b/src/main/java/com/faf223/expensetrackerfaf/repository/IncomeRepository.java @@ -5,9 +5,13 @@ import com.faf223.expensetrackerfaf.model.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.time.LocalDate; import java.util.List; @Repository public interface IncomeRepository extends JpaRepository { List findByUser(User user); + List findByDate(LocalDate date); + + List findByDateBetween(LocalDate start, LocalDate end); } diff --git a/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java b/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java index 9ce7961..1dfb483 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java +++ b/src/main/java/com/faf223/expensetrackerfaf/service/ExpenseService.java @@ -8,6 +8,8 @@ import com.faf223.expensetrackerfaf.repository.ExpenseRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.time.LocalDate; +import java.time.Month; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -33,6 +35,20 @@ public class ExpenseService implements ITransactionService { return new ArrayList<>(); } + @Override + public List getTransactionsByDate(LocalDate date) { + return expenseRepository.findByDate(date); + } + + // TODO: store transaction month in a separate field in the DB and change this logic + @Override + public List getTransactionsByMonth(Month month) { + LocalDate startOfMonth = LocalDate.of(LocalDate.now().getYear(), month, 1); + LocalDate endOfMonth = startOfMonth.plusMonths(1).minusDays(1); + + return expenseRepository.findByDateBetween(startOfMonth, endOfMonth); + } + public List getTransactions() { return expenseRepository.findAll(); } diff --git a/src/main/java/com/faf223/expensetrackerfaf/service/ITransactionService.java b/src/main/java/com/faf223/expensetrackerfaf/service/ITransactionService.java index bdfe091..953fcee 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/service/ITransactionService.java +++ b/src/main/java/com/faf223/expensetrackerfaf/service/ITransactionService.java @@ -2,6 +2,8 @@ package com.faf223.expensetrackerfaf.service; import com.faf223.expensetrackerfaf.model.IMoneyTransaction; +import java.time.LocalDate; +import java.time.Month; import java.util.List; public interface ITransactionService { @@ -9,6 +11,8 @@ public interface ITransactionService { void createOrUpdate(IMoneyTransaction transaction); List getTransactions(); List getTransactionsByEmail(String email); + List getTransactionsByDate(LocalDate date); + List getTransactionsByMonth(Month month); IMoneyTransaction getTransactionById(long id); void deleteTransactionById(long it); diff --git a/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java b/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java index 3ad7973..6ae4479 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java +++ b/src/main/java/com/faf223/expensetrackerfaf/service/IncomeService.java @@ -1,6 +1,7 @@ package com.faf223.expensetrackerfaf.service; import com.faf223.expensetrackerfaf.model.Credential; +import com.faf223.expensetrackerfaf.model.Expense; import com.faf223.expensetrackerfaf.model.IMoneyTransaction; import com.faf223.expensetrackerfaf.model.Income; import com.faf223.expensetrackerfaf.repository.CredentialRepository; @@ -8,6 +9,8 @@ import com.faf223.expensetrackerfaf.repository.IncomeRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.time.LocalDate; +import java.time.Month; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -37,6 +40,20 @@ public class IncomeService implements ITransactionService { return new ArrayList<>(); } + @Override + public List getTransactionsByDate(LocalDate date) { + return incomeRepository.findByDate(date); + } + + // TODO: store transaction month in a separate field in the DB and change this logic + @Override + public List getTransactionsByMonth(Month month) { + LocalDate startOfMonth = LocalDate.of(LocalDate.now().getYear(), month, 1); + LocalDate endOfMonth = startOfMonth.plusMonths(1).minusDays(1); + + return incomeRepository.findByDateBetween(startOfMonth, endOfMonth); + } + public Income getTransactionById(long id) { return incomeRepository.findById(id).orElse(null); } -- 2.49.1 From 3ba95647b4d954cfe5f812eabe73242629bc385f Mon Sep 17 00:00:00 2001 From: mirrerror Date: Mon, 13 Nov 2023 10:11:44 +0200 Subject: [PATCH 13/17] add exception handling --- .../controller/ExpenseController.java | 20 +++++-- .../controller/GlobalExceptionHandler.java | 56 +++++++++++++++++++ .../controller/IncomeController.java | 47 +++++++--------- .../controller/UserController.java | 6 +- .../util/errors/ErrorResponse.java | 40 +++++++++++++ ...actionDoesNotBelongToTheUserException.java | 7 +++ .../TransactionNotCreatedException.java | 7 +++ .../TransactionNotUpdatedException.java | 7 +++ .../TransactionsNotFoundException.java | 7 +++ .../exceptions/UserNotFoundException.java | 7 +++ 10 files changed, 168 insertions(+), 36 deletions(-) create mode 100644 src/main/java/com/faf223/expensetrackerfaf/controller/GlobalExceptionHandler.java create mode 100644 src/main/java/com/faf223/expensetrackerfaf/util/errors/ErrorResponse.java create mode 100644 src/main/java/com/faf223/expensetrackerfaf/util/exceptions/TransactionDoesNotBelongToTheUserException.java create mode 100644 src/main/java/com/faf223/expensetrackerfaf/util/exceptions/TransactionNotCreatedException.java create mode 100644 src/main/java/com/faf223/expensetrackerfaf/util/exceptions/TransactionNotUpdatedException.java create mode 100644 src/main/java/com/faf223/expensetrackerfaf/util/exceptions/TransactionsNotFoundException.java create mode 100644 src/main/java/com/faf223/expensetrackerfaf/util/exceptions/UserNotFoundException.java diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java b/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java index 54a7e38..152b166 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java +++ b/src/main/java/com/faf223/expensetrackerfaf/controller/ExpenseController.java @@ -9,6 +9,10 @@ import com.faf223.expensetrackerfaf.model.User; import com.faf223.expensetrackerfaf.service.ExpenseCategoryService; import com.faf223.expensetrackerfaf.service.ExpenseService; import com.faf223.expensetrackerfaf.service.UserService; +import com.faf223.expensetrackerfaf.util.errors.ErrorResponse; +import com.faf223.expensetrackerfaf.util.exceptions.TransactionNotCreatedException; +import com.faf223.expensetrackerfaf.util.exceptions.TransactionNotUpdatedException; +import com.faf223.expensetrackerfaf.util.exceptions.TransactionsNotFoundException; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -41,7 +45,7 @@ public class ExpenseController { public ResponseEntity> getAllExpenses() { List expenses = expenseService.getTransactions().stream().map(expenseMapper::toDto).collect(Collectors.toList()); if (!expenses.isEmpty()) return ResponseEntity.ok(expenses); - else return ResponseEntity.notFound().build(); + else throw new TransactionsNotFoundException("Transactions not found"); } @PostMapping() @@ -49,6 +53,9 @@ public class ExpenseController { BindingResult bindingResult) { Expense expense = expenseMapper.toExpense(expenseDTO); + if(bindingResult.hasErrors()) + throw new TransactionNotCreatedException(ErrorResponse.from(bindingResult).getMessage()); + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication != null && authentication.getPrincipal() instanceof UserDetails userDetails) { @@ -61,7 +68,7 @@ public class ExpenseController { return ResponseEntity.status(HttpStatus.CREATED).build(); } - return ResponseEntity.notFound().build(); + throw new TransactionNotCreatedException("Could not create new expense"); } @@ -70,6 +77,9 @@ public class ExpenseController { public ResponseEntity updateExpense(@PathVariable long id, @RequestBody ExpenseCreationDTO expenseDTO, BindingResult bindingResult) { Expense expense = expenseService.getTransactionById(id); + + if(expense == null) throw new TransactionsNotFoundException("The expense has not been found"); + ExpenseCategory category = expenseCategoryService.getCategoryById(expenseDTO.getExpenseCategory()); expense.setCategory(category); expense.setAmount(expenseDTO.getAmount()); @@ -78,7 +88,7 @@ public class ExpenseController { expenseService.createOrUpdate(expense); return ResponseEntity.status(HttpStatus.CREATED).build(); } else { - return ResponseEntity.notFound().build(); + throw new TransactionNotUpdatedException(ErrorResponse.from(bindingResult).getMessage()); } } @@ -104,14 +114,14 @@ public class ExpenseController { } } - return ResponseEntity.notFound().build(); + throw new TransactionsNotFoundException("The expenses have not been found"); } @GetMapping("/categories") public ResponseEntity> getAllCategories() { List categories = expenseCategoryService.getAllCategories(); if (!categories.isEmpty()) return ResponseEntity.ok(categories); - else return ResponseEntity.notFound().build(); + else throw new TransactionsNotFoundException("The expenses have not been found"); } @DeleteMapping("/delete/{id}") diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/GlobalExceptionHandler.java b/src/main/java/com/faf223/expensetrackerfaf/controller/GlobalExceptionHandler.java new file mode 100644 index 0000000..e903c63 --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/controller/GlobalExceptionHandler.java @@ -0,0 +1,56 @@ +package com.faf223.expensetrackerfaf.controller; + +import com.faf223.expensetrackerfaf.util.errors.ErrorResponse; +import com.faf223.expensetrackerfaf.util.exceptions.TransactionDoesNotBelongToTheUserException; +import com.faf223.expensetrackerfaf.util.exceptions.TransactionNotCreatedException; +import com.faf223.expensetrackerfaf.util.exceptions.TransactionsNotFoundException; +import com.faf223.expensetrackerfaf.util.exceptions.UserNotFoundException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler + private ResponseEntity handleDoesNotBelongException(TransactionDoesNotBelongToTheUserException e) { + ErrorResponse response = new ErrorResponse( + e.getMessage(), + System.currentTimeMillis() + ); + + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + + @ExceptionHandler + private ResponseEntity handleTransactionNotCreatedException(TransactionNotCreatedException e) { + ErrorResponse response = new ErrorResponse( + e.getMessage(), + System.currentTimeMillis() + ); + + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + + @ExceptionHandler + private ResponseEntity handleTransactionsNotFoundException(TransactionsNotFoundException e) { + ErrorResponse response = new ErrorResponse( + e.getMessage(), + System.currentTimeMillis() + ); + + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + + @ExceptionHandler + private ResponseEntity handleUserNotFoundException(UserNotFoundException e) { + ErrorResponse response = new ErrorResponse( + e.getMessage(), + System.currentTimeMillis() + ); + + return new ResponseEntity<>(response, HttpStatus.NOT_FOUND); + } + +} diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java b/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java index b6bd9cc..3b9bdd8 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java +++ b/src/main/java/com/faf223/expensetrackerfaf/controller/IncomeController.java @@ -1,13 +1,18 @@ package com.faf223.expensetrackerfaf.controller; -import com.faf223.expensetrackerfaf.dto.ExpenseDTO; import com.faf223.expensetrackerfaf.dto.IncomeCreationDTO; import com.faf223.expensetrackerfaf.dto.IncomeDTO; import com.faf223.expensetrackerfaf.dto.mappers.IncomeMapper; -import com.faf223.expensetrackerfaf.model.*; +import com.faf223.expensetrackerfaf.model.Income; +import com.faf223.expensetrackerfaf.model.IncomeCategory; +import com.faf223.expensetrackerfaf.model.User; import com.faf223.expensetrackerfaf.service.IncomeCategoryService; import com.faf223.expensetrackerfaf.service.IncomeService; import com.faf223.expensetrackerfaf.service.UserService; +import com.faf223.expensetrackerfaf.util.errors.ErrorResponse; +import com.faf223.expensetrackerfaf.util.exceptions.TransactionNotCreatedException; +import com.faf223.expensetrackerfaf.util.exceptions.TransactionNotUpdatedException; +import com.faf223.expensetrackerfaf.util.exceptions.TransactionsNotFoundException; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -40,13 +45,17 @@ public class IncomeController { public ResponseEntity> getAllIncomes() { List incomes = incomeService.getTransactions().stream().map(incomeMapper::toDto).collect(Collectors.toList()); if (!incomes.isEmpty()) return ResponseEntity.ok(incomes); - else return ResponseEntity.notFound().build(); + else throw new TransactionsNotFoundException("Transactions not found"); } @PostMapping() public ResponseEntity createNewIncome(@RequestBody IncomeCreationDTO incomeDTO, BindingResult bindingResult) { Income income = incomeMapper.toIncome(incomeDTO); + + if(bindingResult.hasErrors()) + throw new TransactionNotCreatedException(ErrorResponse.from(bindingResult).getMessage()); + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication != null && authentication.getPrincipal() instanceof UserDetails userDetails) { @@ -55,12 +64,11 @@ public class IncomeController { User user = userService.getUserByEmail(email); income.setUser(user); - System.out.println(income); incomeService.createOrUpdate(income); return ResponseEntity.status(HttpStatus.CREATED).build(); } - return ResponseEntity.notFound().build(); + throw new TransactionNotCreatedException("Could not create new expense"); } // TODO: check if the income belongs to the user, extract logic into service @@ -68,6 +76,9 @@ public class IncomeController { public ResponseEntity updateIncome(@PathVariable long id, @RequestBody IncomeCreationDTO incomeDTO, BindingResult bindingResult) { Income income = incomeService.getTransactionById(id); + + if(income == null) throw new TransactionsNotFoundException("The income has not been found"); + IncomeCategory category = incomeCategoryService.getCategoryById(incomeDTO.getIncomeCategory()); income.setCategory(category); income.setAmount(incomeDTO.getAmount()); @@ -76,30 +87,10 @@ public class IncomeController { incomeService.createOrUpdate(income); return ResponseEntity.status(HttpStatus.CREATED).build(); } else { - return ResponseEntity.notFound().build(); + throw new TransactionNotUpdatedException(ErrorResponse.from(bindingResult).getMessage()); } } - @GetMapping("/personal-incomes") - public ResponseEntity> getIncomesByUser() { - - Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - - if (authentication != null && authentication.getPrincipal() instanceof UserDetails userDetails) { - - String email = userDetails.getUsername(); - List incomes = incomeService.getTransactionsByEmail(email).stream().map(incomeMapper::toDto).collect(Collectors.toList()); - - if (!incomes.isEmpty()) { - return ResponseEntity.ok(incomes); - } else { - return ResponseEntity.ok(Collections.emptyList()); - } - } - - return ResponseEntity.notFound().build(); - } - @GetMapping("/personal-incomes") public ResponseEntity> getExpensesByUser(@RequestParam Optional date, @RequestParam Optional month) { @@ -122,14 +113,14 @@ public class IncomeController { } } - return ResponseEntity.notFound().build(); + throw new TransactionsNotFoundException("The expenses have not been found"); } @GetMapping("/categories") public ResponseEntity> getAllCategories() { List categories = incomeCategoryService.getAllCategories(); if (!categories.isEmpty()) return ResponseEntity.ok(categories); - else return ResponseEntity.notFound().build(); + else throw new TransactionsNotFoundException("The expenses have not been found"); } @DeleteMapping("/delete/{id}") diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/UserController.java b/src/main/java/com/faf223/expensetrackerfaf/controller/UserController.java index 407f99c..c961523 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/controller/UserController.java +++ b/src/main/java/com/faf223/expensetrackerfaf/controller/UserController.java @@ -5,6 +5,7 @@ import com.faf223.expensetrackerfaf.dto.UserDTO; import com.faf223.expensetrackerfaf.dto.mappers.UserMapper; import com.faf223.expensetrackerfaf.model.User; import com.faf223.expensetrackerfaf.service.UserService; +import com.faf223.expensetrackerfaf.util.exceptions.UserNotFoundException; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -32,7 +33,7 @@ public class UserController { userService.updateUser(user); return ResponseEntity.ok(userMapper.toDto(user)); } else { - return ResponseEntity.notFound().build(); + throw new UserNotFoundException("The user has not been found"); } } @@ -43,9 +44,8 @@ public class UserController { if (authentication != null && authentication.getPrincipal() instanceof UserDetails userDetails) { User user = userService.getUserByEmail(userDetails.getUsername()); if (user != null) return ResponseEntity.ok(userMapper.toDto(user)); - else return ResponseEntity.notFound().build(); } - return ResponseEntity.notFound().build(); + throw new UserNotFoundException("The user has not been found"); } @GetMapping() diff --git a/src/main/java/com/faf223/expensetrackerfaf/util/errors/ErrorResponse.java b/src/main/java/com/faf223/expensetrackerfaf/util/errors/ErrorResponse.java new file mode 100644 index 0000000..e2f3dd7 --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/util/errors/ErrorResponse.java @@ -0,0 +1,40 @@ +package com.faf223.expensetrackerfaf.util.errors; + +import lombok.Data; +import org.springframework.validation.BindingResult; +import org.springframework.validation.FieldError; + +import java.util.List; + +@Data +public class ErrorResponse { + private String message; + private long timestamp; + + public ErrorResponse(String message, long timestamp) { + this.message = message; + this.timestamp = timestamp; + } + + public ErrorResponse(String message) { + this.message = message; + this.timestamp = System.currentTimeMillis(); + } + + public static ErrorResponse from(BindingResult bindingResult) { + if(bindingResult.hasErrors()) { + StringBuilder errorMessage = new StringBuilder(); + + List errors = bindingResult.getFieldErrors(); + for(FieldError fieldError : errors) + errorMessage.append(fieldError.getField()) + .append(" - ") + .append(fieldError.getDefaultMessage()) + .append(";"); + + return new ErrorResponse(errorMessage.toString(), System.currentTimeMillis()); + } + + return new ErrorResponse("No error message was provided", System.currentTimeMillis()); + } +} diff --git a/src/main/java/com/faf223/expensetrackerfaf/util/exceptions/TransactionDoesNotBelongToTheUserException.java b/src/main/java/com/faf223/expensetrackerfaf/util/exceptions/TransactionDoesNotBelongToTheUserException.java new file mode 100644 index 0000000..6cf8e46 --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/util/exceptions/TransactionDoesNotBelongToTheUserException.java @@ -0,0 +1,7 @@ +package com.faf223.expensetrackerfaf.util.exceptions; + +public class TransactionDoesNotBelongToTheUserException extends RuntimeException { + public TransactionDoesNotBelongToTheUserException(String message) { + super(message); + } +} diff --git a/src/main/java/com/faf223/expensetrackerfaf/util/exceptions/TransactionNotCreatedException.java b/src/main/java/com/faf223/expensetrackerfaf/util/exceptions/TransactionNotCreatedException.java new file mode 100644 index 0000000..f035f3a --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/util/exceptions/TransactionNotCreatedException.java @@ -0,0 +1,7 @@ +package com.faf223.expensetrackerfaf.util.exceptions; + +public class TransactionNotCreatedException extends RuntimeException { + public TransactionNotCreatedException(String message) { + super(message); + } +} diff --git a/src/main/java/com/faf223/expensetrackerfaf/util/exceptions/TransactionNotUpdatedException.java b/src/main/java/com/faf223/expensetrackerfaf/util/exceptions/TransactionNotUpdatedException.java new file mode 100644 index 0000000..0ffeff9 --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/util/exceptions/TransactionNotUpdatedException.java @@ -0,0 +1,7 @@ +package com.faf223.expensetrackerfaf.util.exceptions; + +public class TransactionNotUpdatedException extends RuntimeException { + public TransactionNotUpdatedException(String message) { + super(message); + } +} diff --git a/src/main/java/com/faf223/expensetrackerfaf/util/exceptions/TransactionsNotFoundException.java b/src/main/java/com/faf223/expensetrackerfaf/util/exceptions/TransactionsNotFoundException.java new file mode 100644 index 0000000..e001cc7 --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/util/exceptions/TransactionsNotFoundException.java @@ -0,0 +1,7 @@ +package com.faf223.expensetrackerfaf.util.exceptions; + +public class TransactionsNotFoundException extends RuntimeException { + public TransactionsNotFoundException(String message) { + super(message); + } +} diff --git a/src/main/java/com/faf223/expensetrackerfaf/util/exceptions/UserNotFoundException.java b/src/main/java/com/faf223/expensetrackerfaf/util/exceptions/UserNotFoundException.java new file mode 100644 index 0000000..808c0eb --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/util/exceptions/UserNotFoundException.java @@ -0,0 +1,7 @@ +package com.faf223.expensetrackerfaf.util.exceptions; + +public class UserNotFoundException extends RuntimeException { + public UserNotFoundException(String message) { + super(message); + } +} -- 2.49.1 From f1c8211f7af1b01a42a4cb75937436ab19a39221 Mon Sep 17 00:00:00 2001 From: mirrerror Date: Mon, 13 Nov 2023 10:15:11 +0200 Subject: [PATCH 14/17] stick to one error response class --- .../config/JwtAuthenticationFilter.java | 4 ++-- .../controller/auth/ErrorResponse.java | 16 ---------------- 2 files changed, 2 insertions(+), 18 deletions(-) delete mode 100644 src/main/java/com/faf223/expensetrackerfaf/controller/auth/ErrorResponse.java diff --git a/src/main/java/com/faf223/expensetrackerfaf/config/JwtAuthenticationFilter.java b/src/main/java/com/faf223/expensetrackerfaf/config/JwtAuthenticationFilter.java index 043f61f..a8c3870 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/config/JwtAuthenticationFilter.java +++ b/src/main/java/com/faf223/expensetrackerfaf/config/JwtAuthenticationFilter.java @@ -1,6 +1,6 @@ package com.faf223.expensetrackerfaf.config; -import com.faf223.expensetrackerfaf.controller.auth.ErrorResponse; +import com.faf223.expensetrackerfaf.util.errors.ErrorResponse; import com.fasterxml.jackson.databind.ObjectMapper; import io.jsonwebtoken.ExpiredJwtException; import jakarta.servlet.FilterChain; @@ -61,7 +61,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType("application/json"); - ErrorResponse errorResponse = new ErrorResponse("TokenExpired", "Your session has expired. Please log in again."); + ErrorResponse errorResponse = new ErrorResponse("Your session has expired. Please log in again."); ObjectMapper objectMapper = new ObjectMapper(); // You may need to import ObjectMapper response.getWriter().write(objectMapper.writeValueAsString(errorResponse)); diff --git a/src/main/java/com/faf223/expensetrackerfaf/controller/auth/ErrorResponse.java b/src/main/java/com/faf223/expensetrackerfaf/controller/auth/ErrorResponse.java deleted file mode 100644 index 54db638..0000000 --- a/src/main/java/com/faf223/expensetrackerfaf/controller/auth/ErrorResponse.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.faf223.expensetrackerfaf.controller.auth; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class ErrorResponse { - private String error; - private String message; - - public ErrorResponse(String error, String message) { - this.error = error; - this.message = message; - } -} -- 2.49.1 From 2d981c5af8f6e67d8ffd2fcd3b98249525421750 Mon Sep 17 00:00:00 2001 From: mirrerror Date: Mon, 13 Nov 2023 10:20:36 +0200 Subject: [PATCH 15/17] change error message --- .../expensetrackerfaf/config/JwtAuthenticationFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/faf223/expensetrackerfaf/config/JwtAuthenticationFilter.java b/src/main/java/com/faf223/expensetrackerfaf/config/JwtAuthenticationFilter.java index a8c3870..9d710a2 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/config/JwtAuthenticationFilter.java +++ b/src/main/java/com/faf223/expensetrackerfaf/config/JwtAuthenticationFilter.java @@ -61,7 +61,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType("application/json"); - ErrorResponse errorResponse = new ErrorResponse("Your session has expired. Please log in again."); + ErrorResponse errorResponse = new ErrorResponse("Your session has expired. Refresh your token."); ObjectMapper objectMapper = new ObjectMapper(); // You may need to import ObjectMapper response.getWriter().write(objectMapper.writeValueAsString(errorResponse)); -- 2.49.1 From 021be06f404ffc883708fa1642a765f94dcd1b8e Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 17 Nov 2023 12:57:36 +0200 Subject: [PATCH 16/17] Separated expenses and incomes frontend --- .../web/src/routes/dashboard/+page.svelte | 11 +- .../routes/dashboard/board/Dashboard.svelte | 103 +++++----- .../dashboard/board/ExpenseDashboard.svelte | 9 + .../dashboard/board/IncomeDashboard.svelte | 9 + .../board/{ => expenses}/graphs/Graph2.svelte | 2 +- .../board/{ => expenses}/graphs/Graph3.svelte | 2 +- .../dashboard/board/graphs/Graph1.svelte | 96 ---------- .../dashboard/board/infolists/Expenses.svelte | 76 -------- .../dashboard/board/infolists/Incomes.svelte | 75 -------- .../infolists/contents/ContentExpense.svelte | 175 ----------------- .../infolists/contents/ContentIncome.svelte | 177 ------------------ .../board/infolists/modals/Modal.svelte | 57 ------ .../dashboard/board/other/DashHeader.svelte | 66 ------- .../dashboard/board/other/DataMenu.svelte | 64 ------- .../dashboard/board/other/QuickInfobar.svelte | 71 ------- .../src/routes/dashboard/menu/SideMenu.svelte | 5 +- .../web/src/routes/dashboard/stores.js | 4 +- 17 files changed, 87 insertions(+), 915 deletions(-) create mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/ExpenseDashboard.svelte create mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/IncomeDashboard.svelte rename src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/{ => expenses}/graphs/Graph2.svelte (97%) rename src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/{ => expenses}/graphs/Graph3.svelte (96%) delete mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/graphs/Graph1.svelte delete mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/Expenses.svelte delete mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/Incomes.svelte delete mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/contents/ContentExpense.svelte delete mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/contents/ContentIncome.svelte delete mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/modals/Modal.svelte delete mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/other/DashHeader.svelte delete mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/other/DataMenu.svelte delete mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/other/QuickInfobar.svelte diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/+page.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/+page.svelte index 3be4a70..916c685 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/+page.svelte +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/+page.svelte @@ -1,11 +1,18 @@
- - + +
\ No newline at end of file + #dashboard { + font-family: 'Source Sans Pro', sans-serif; + background-color: rgb(245,242,243); + border-radius: 20px; + margin: 20px; + min-width: 100px; + display: flex; + flex:1 1 auto; + flex-direction: column; + align-items: stretch; + justify-content: stretch; + } + diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/ExpenseDashboard.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/ExpenseDashboard.svelte new file mode 100644 index 0000000..aa9e59f --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/ExpenseDashboard.svelte @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/IncomeDashboard.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/IncomeDashboard.svelte new file mode 100644 index 0000000..f58ddd5 --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/IncomeDashboard.svelte @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/graphs/Graph2.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/graphs/Graph2.svelte similarity index 97% rename from src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/graphs/Graph2.svelte rename to src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/graphs/Graph2.svelte index 9fb1a4a..e36cf8a 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/graphs/Graph2.svelte +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/graphs/Graph2.svelte @@ -1,7 +1,7 @@ - -
- -
- - diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/Expenses.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/Expenses.svelte deleted file mode 100644 index 0015c1f..0000000 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/Expenses.svelte +++ /dev/null @@ -1,76 +0,0 @@ - - -
- - -
-
    - {#each $expenseData as item} -
  • - {item.incomeCategory ? `${item.incomeCategory.name}: ` : `${item.expenseCategory.name}: `} - {item.incomeCategory ? `+${item.amount}$` : `-${item.amount}$`} - {`${item.date}`} -
  • - {/each} -
-
-
- - - diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/Incomes.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/Incomes.svelte deleted file mode 100644 index 2f4e2e5..0000000 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/Incomes.svelte +++ /dev/null @@ -1,75 +0,0 @@ - - -
- - -
-
    - {#each $incomeData as item} -
  • - {item.incomeCategory ? `${item.incomeCategory.name}: ` : `${item.expenseCategory.name}: `} - {item.incomeCategory ? `+${item.amount}$` : `-${item.amount}$`} - {`${item.date}`} -
  • - {/each} -
-
-
- - diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/contents/ContentExpense.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/contents/ContentExpense.svelte deleted file mode 100644 index bb57ce9..0000000 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/contents/ContentExpense.svelte +++ /dev/null @@ -1,175 +0,0 @@ - - -
-
-

Expenses

-
(showModal = true)} on:keydown={() => console.log("keydown")}> - + -
-
- -
-

Expense Details

-
- - -
- -
- - -
- - -
-
-
- - - diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/contents/ContentIncome.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/contents/ContentIncome.svelte deleted file mode 100644 index b8bf180..0000000 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/contents/ContentIncome.svelte +++ /dev/null @@ -1,177 +0,0 @@ - - -
-
-

Incomes

-
(showModal = true)} on:keydown={() => console.log("keydown")}> - + -
-
- -
-

Income Details

-
- - -
- -
- - -
- - -
-
-
- - - diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/modals/Modal.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/modals/Modal.svelte deleted file mode 100644 index fca4643..0000000 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/infolists/modals/Modal.svelte +++ /dev/null @@ -1,57 +0,0 @@ - - - - (showModal = false)} - on:click|self={() => dialog.close()} -> - -
- - -
-
- - diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/other/DashHeader.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/other/DashHeader.svelte deleted file mode 100644 index ed861b9..0000000 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/other/DashHeader.svelte +++ /dev/null @@ -1,66 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/other/DataMenu.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/other/DataMenu.svelte deleted file mode 100644 index f2f2009..0000000 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/other/DataMenu.svelte +++ /dev/null @@ -1,64 +0,0 @@ - - -
-
- - -
-
- -
-
- - -
-
- - \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/other/QuickInfobar.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/other/QuickInfobar.svelte deleted file mode 100644 index 5b6b490..0000000 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/other/QuickInfobar.svelte +++ /dev/null @@ -1,71 +0,0 @@ - - -
-
-
-
-
-
- - diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/menu/SideMenu.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/menu/SideMenu.svelte index 3f64a8a..3ded8c0 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/menu/SideMenu.svelte +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/menu/SideMenu.svelte @@ -2,6 +2,7 @@ import { onMount } from 'svelte'; import axios from 'axios'; import {deleteCookie, getCookie} from "svelte-cookie"; + export let onTabClick; let username; @@ -40,12 +41,12 @@ Profile -
+
onTabClick('expenses')} tabindex="0" role="button" class="sideMenuItem"> Expenses
-
+
onTabClick('incomes')} tabindex="0" role="button" class="sideMenuItem"> Incomes
diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/stores.js b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/stores.js index 05ce287..b25c279 100644 --- a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/stores.js +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/stores.js @@ -6,4 +6,6 @@ export const expenseData = writable([]); export const incomeTypes = writable([]); -export const expenseTypes = writable([]); \ No newline at end of file +export const expenseTypes = writable([]); + +export let selectedTab = writable('expenses'); \ No newline at end of file -- 2.49.1 From 4404eedeecf70018518381b80774a25d99547000 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 17 Nov 2023 12:58:04 +0200 Subject: [PATCH 17/17] Separated expenses and incomes frontend --- .../board/expenses/infolists/Expenses.svelte | 77 ++++++++ .../infolists/contents/ContentExpense.svelte | 175 +++++++++++++++++ .../expenses/infolists/modals/Modal.svelte | 57 ++++++ .../board/expenses/other/DashHeader.svelte | 66 +++++++ .../board/expenses/other/DataMenu.svelte | 60 ++++++ .../board/expenses/other/QuickInfobar.svelte | 71 +++++++ .../board/incomes/graphs/Graph1.svelte | 96 ++++++++++ .../board/incomes/graphs/Graph3.svelte | 80 ++++++++ .../board/incomes/infolists/Incomes.svelte | 76 ++++++++ .../infolists/contents/ContentIncome.svelte | 177 ++++++++++++++++++ .../incomes/infolists/modals/Modal.svelte | 57 ++++++ .../board/incomes/other/DashHeader.svelte | 66 +++++++ .../board/incomes/other/DataMenu.svelte | 60 ++++++ .../board/incomes/other/QuickInfobar.svelte | 71 +++++++ 14 files changed, 1189 insertions(+) create mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/Expenses.svelte create mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/contents/ContentExpense.svelte create mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/modals/Modal.svelte create mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/DashHeader.svelte create mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/DataMenu.svelte create mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/QuickInfobar.svelte create mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/graphs/Graph1.svelte create mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/graphs/Graph3.svelte create mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/infolists/Incomes.svelte create mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/infolists/contents/ContentIncome.svelte create mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/infolists/modals/Modal.svelte create mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/other/DashHeader.svelte create mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/other/DataMenu.svelte create mode 100644 src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/other/QuickInfobar.svelte diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/Expenses.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/Expenses.svelte new file mode 100644 index 0000000..1872400 --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/Expenses.svelte @@ -0,0 +1,77 @@ + + +
+ + +
+
    + {#each $expenseData as item} +
  • + {item.incomeCategory ? `${item.incomeCategory.name}: ` : `${item.expenseCategory.name}: `} + {item.incomeCategory ? `+${item.amount}$` : `-${item.amount}$`} + {`${item.date}`} +
  • + {/each} +
+
+
+ + + diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/contents/ContentExpense.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/contents/ContentExpense.svelte new file mode 100644 index 0000000..bd64722 --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/contents/ContentExpense.svelte @@ -0,0 +1,175 @@ + + +
+
+

Expenses

+
(showModal = true)} on:keydown={() => console.log("keydown")}> + + +
+
+ +
+

Expense Details

+
+ + +
+ +
+ + +
+ + +
+
+
+ + + diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/modals/Modal.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/modals/Modal.svelte new file mode 100644 index 0000000..fca4643 --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/infolists/modals/Modal.svelte @@ -0,0 +1,57 @@ + + + + (showModal = false)} + on:click|self={() => dialog.close()} +> + +
+ + +
+
+ + diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/DashHeader.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/DashHeader.svelte new file mode 100644 index 0000000..ed861b9 --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/DashHeader.svelte @@ -0,0 +1,66 @@ + + + + + \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/DataMenu.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/DataMenu.svelte new file mode 100644 index 0000000..cb4257c --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/DataMenu.svelte @@ -0,0 +1,60 @@ + + +
+
+ +
+
+ +
+
+ +
+
+ + \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/QuickInfobar.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/QuickInfobar.svelte new file mode 100644 index 0000000..7fd226b --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/expenses/other/QuickInfobar.svelte @@ -0,0 +1,71 @@ + + +
+
+
+
+
+
+ + diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/graphs/Graph1.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/graphs/Graph1.svelte new file mode 100644 index 0000000..7cda792 --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/graphs/Graph1.svelte @@ -0,0 +1,96 @@ + + +
+ +
+ + diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/graphs/Graph3.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/graphs/Graph3.svelte new file mode 100644 index 0000000..c5c1fb6 --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/graphs/Graph3.svelte @@ -0,0 +1,80 @@ + + +
+ +
+ + diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/infolists/Incomes.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/infolists/Incomes.svelte new file mode 100644 index 0000000..a32769a --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/infolists/Incomes.svelte @@ -0,0 +1,76 @@ + + +
+ + +
+
    + {#each $incomeData as item} +
  • + {item.incomeCategory ? `${item.incomeCategory.name}: ` : `${item.expenseCategory.name}: `} + {item.incomeCategory ? `+${item.amount}$` : `-${item.amount}$`} + {`${item.date}`} +
  • + {/each} +
+
+
+ + diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/infolists/contents/ContentIncome.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/infolists/contents/ContentIncome.svelte new file mode 100644 index 0000000..309933e --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/infolists/contents/ContentIncome.svelte @@ -0,0 +1,177 @@ + + +
+
+

Incomes

+
(showModal = true)} on:keydown={() => console.log("keydown")}> + + +
+
+ +
+

Income Details

+
+ + +
+ +
+ + +
+ + +
+
+
+ + + diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/infolists/modals/Modal.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/infolists/modals/Modal.svelte new file mode 100644 index 0000000..fca4643 --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/infolists/modals/Modal.svelte @@ -0,0 +1,57 @@ + + + + (showModal = false)} + on:click|self={() => dialog.close()} +> + +
+ + +
+
+ + diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/other/DashHeader.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/other/DashHeader.svelte new file mode 100644 index 0000000..ed861b9 --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/other/DashHeader.svelte @@ -0,0 +1,66 @@ + + + + + \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/other/DataMenu.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/other/DataMenu.svelte new file mode 100644 index 0000000..1230a06 --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/other/DataMenu.svelte @@ -0,0 +1,60 @@ + + +
+
+ +
+
+ +
+
+ +
+
+ + \ No newline at end of file diff --git a/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/other/QuickInfobar.svelte b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/other/QuickInfobar.svelte new file mode 100644 index 0000000..7fd226b --- /dev/null +++ b/src/main/java/com/faf223/expensetrackerfaf/web/src/routes/dashboard/board/incomes/other/QuickInfobar.svelte @@ -0,0 +1,71 @@ + + +
+
+
+
+
+
+ + -- 2.49.1