Skip to content

Commit

Permalink
exposed new APIs, updated existing API contract, modified the UI desi…
Browse files Browse the repository at this point in the history
…gn and other changes
  • Loading branch information
pradipmudi committed Dec 23, 2023
1 parent 78fe5c6 commit c80417d
Show file tree
Hide file tree
Showing 12 changed files with 484 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,21 @@ public ResponseEntity<List<MonthlyReport>> getReport(@ModelAttribute ReportReque
}

@GetMapping("/{month}")
public ResponseEntity<List<ExpenseEntity>> getExpenseByMonth(@PathVariable Month month) {
return new ResponseEntity<>(expenseManagementService.getExpensesByMonth(month), HttpStatus.OK);
public ResponseEntity<List<ExpenseEntity>> getExpenseByMonth(
@PathVariable Month month,
@RequestParam(name = "page", required = false) Integer page,
@RequestParam(name = "itemsPerPage", required = false) Integer itemsPerPage,
@RequestParam(name = "sortField", required = false) String sortField,
@RequestParam(name = "sortOrder", required = false) String sortOrder
) {
try {
// Update the service method to handle new parameters
List<ExpenseEntity> expenses = expenseManagementService.getExpensesByMonth(month, page, itemsPerPage, sortField, sortOrder);

return new ResponseEntity<>(expenses, HttpStatus.OK);
} catch (RuntimeException e) {
throw e;
}
}

@GetMapping
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/expensys/controller/ExpensysController.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ public String index() {
public String addExpense(){
return "addexpense";
}
@GetMapping("/expenses")
public String expensesByMonth(){
return "showExpenseByMonth";
}
}
18 changes: 0 additions & 18 deletions src/main/java/com/expensys/controller/ReportController.java

This file was deleted.

3 changes: 0 additions & 3 deletions src/main/java/com/expensys/service/ExpenseService.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,6 @@ private List<Expense> prepareExpenseListFromExpenseEntityList(List<ExpenseEntity
Expense expense = new Expense(Month.valueOf(String.valueOf(expenseEntity.getDate().getMonth())), expenseEntity.getItem(), category, expenseEntity.getSpent(), expenseEntity.getSpentBy());
expenseList.add(expense);
}
// for (Expense expense : expenseList) {
// logger.info("expense -> {}",expense);
// }
return expenseList;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
import com.expensys.model.Expense;
import com.expensys.model.request.ReportRequest;
import com.expensys.model.response.MonthlyReport;
import com.expensys.repository.CategoryMappingRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
Expand All @@ -17,16 +15,9 @@
@Service
public class MainCategoryReportService implements ICategoryReportService {
private static final Logger logger = LoggerFactory.getLogger(MainCategoryReportService.class);
private final CategoryMappingRepository categoryMappingRepository;

@Autowired
public MainCategoryReportService(CategoryMappingRepository categoryMappingRepository) {
this.categoryMappingRepository = categoryMappingRepository;
}

@Override
public List<MonthlyReport> prepareReport(ReportRequest reportRequest, List<Expense> expenseList) {

expenseList = expenseList.stream().filter(expense -> MAIN_CATEGORIES.contains(expense.getCategory())).toList();
return ExpenseToReportConvertor.getInstance().prepareReportListFromExpenseList(expenseList, reportRequest);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
import com.expensys.model.Expense;
import com.expensys.model.request.ReportRequest;
import com.expensys.model.response.MonthlyReport;
import com.expensys.repository.CategoryMappingRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
Expand All @@ -17,12 +15,6 @@
@Service
public class SubCategoryReportService implements ICategoryReportService{
private static final Logger logger = LoggerFactory.getLogger(SubCategoryReportService.class);
private final CategoryMappingRepository categoryMappingRepository;

@Autowired
public SubCategoryReportService(CategoryMappingRepository categoryMappingRepository) {
this.categoryMappingRepository = categoryMappingRepository;
}

@Override
public List<MonthlyReport> prepareReport(ReportRequest reportRequest, List<Expense> expenseList) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
import java.time.LocalDate;
import java.util.List;

import static java.util.Collections.reverseOrder;
import static java.util.Comparator.comparing;

@Service
public class ExpenseManagementService {
Logger logger = LoggerFactory.getLogger(ExpenseManagementService.class);
Expand Down Expand Up @@ -44,8 +47,24 @@ public List<ExpenseEntity> getExpenseByDateRange(LocalDate startDate, LocalDate
return expenseService.getExpenseByDateRange(startDate, endDate);
}

public List<ExpenseEntity> getExpensesByMonth(Month month){
return expenseService.getExpenseEntitiesByMonth(month);
public List<ExpenseEntity> getExpensesByMonth(Month month, Integer page, Integer itemsPerPage, String sortField, String sortOrder){
List<ExpenseEntity> sortedExpenses = expenseService.getExpenseEntitiesByMonth(month)
.stream()
.sorted(comparing(ExpenseEntity::getDate, reverseOrder())
.thenComparing(ExpenseEntity::getId, reverseOrder()))
.toList();
logger.info("sortedExpenses -> {}",sortedExpenses);

if(page == null || itemsPerPage == null) return sortedExpenses;

int startIndex = (page-1) * itemsPerPage;
int endIndex = startIndex+itemsPerPage;

if(startIndex > sortedExpenses.size() || endIndex > sortedExpenses.size()){
throw new RuntimeException("No data available for pageNo: "+page);
}
return sortedExpenses.subList(startIndex, endIndex);

}

}
232 changes: 232 additions & 0 deletions src/main/resources/static/css/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
/* CSS Reset */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

/* Global styling */
body {
font-family: 'Arial', sans-serif;
margin: 0;
padding: 0;
background: #ecf0f1; /* Clouds background */
color: #333; /* Dark gray text */
transition: background-color 0.3s ease-in-out;
}

/* Headings */
h1, h2 {
text-align: center;
}

h1 {
font-size: 48px;
margin-top: 20px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
color: #3498db; /* Dodger blue */
transition: color 0.3s ease-in-out;
}

h2 {
font-size: 30px;
margin: 0;
color: #3498db; /* Dodger blue */
}

/* Form elements */
section#filter-options {
background-color: #fff;
padding: 10px 0;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
text-align: center;
}

label {
font-weight: bold;
}

select {
font-size: 14px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
background: #f2f2f2;
}

select:hover {
border-color: #2980b9; /* Darker blue on hover */
}

/* Additional Elements */
#loadingSpinner {
display: block;
margin: 20px auto;
border: 8px solid rgba(0, 0, 0, 0.1);
border-radius: 50%;
border-top: 8px solid #333;
width: 50px;
height: 50px;
animation: spin 1s linear infinite;
}

#errorMessage {
display: block;
margin: 20px auto;
padding: 20px;
background-color: #e74c3c; /* Alizarin crimson */
color: #fff;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
text-align: center;
}

/* Pagination controls */
.pagination {
text-align: center;
margin: 20px 0;
}

.pagination button {
background-color: #3498db; /* Dodger blue */
color: #fff;
padding: 12px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
margin: 0 10px;
transition: background 0.3s ease-in-out;
}

.pagination button:hover {
background-color: #2980b9; /* Darker blue on hover */
transform: scale(1.05); /* Add scale effect on hover */
}

.current-page {
margin: 0 10px;
font-size: 18px;
font-weight: bold;
color: #3498db; /* Dodger blue */
transition: color 0.3s ease-in-out;
}

/* Tables */
table {
width: 100%;
border-collapse: collapse;
margin: 50px auto;
background-color: #fff;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
border-radius: 10px;
overflow: hidden;
transition: box-shadow 0.3s ease-in-out;
color: #333; /* Dark gray text */
}

th, td {
padding: 15px;
text-align: left;
border-bottom: 1px solid #ccc;
font-size: 18px;
transition: background-color 0.3s ease-in-out;
}

th {
background-color: #3498db; /* Dodger blue */
color: #fff;
box-shadow: 0 4px 4px rgba(0, 0, 0, 0.1);
}

tr:nth-child(even) {
background-color: #f9f9f9; /* Light gray background for even rows */
}

tr:hover {
background-color: #e0e0e0; /* Slightly darker gray on hover */
}

/* Sorting icons */
.sort-icon {
display: inline-block;
margin-left: 5px;
font-size: 16px;
transition: transform 0.3s ease-in-out;
}

.sortable:hover .sort-icon {
transform: scale(1.2);
}

/* Pagination controls at the top and bottom */
.pagination-controls {
text-align: center;
margin: 20px 0;
}

.pagination-controls button {
background-color: #3498db; /* Dodger blue */
color: #fff;
padding: 12px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
margin: 0 10px;
transition: background 0.3s ease-in-out;
}

.pagination-controls button:hover {
background-color: #2980b9; /* Darker blue on hover */
transform: scale(1.05); /* Add scale effect on hover */
}

.pagination-controls .current-page {
margin: 0 10px;
font-size: 18px;
font-weight: bold;
color: #3498db; /* Dodger blue */
transition: color 0.3s ease-in-out;
}

/* Responsive styles */
@media only screen and (max-width: 768px) {
select {
width: 100%;
max-width: calc(100% - 40px);
}

table {
max-width: calc(100% - 40px);
overflow-x: auto;
}

th, td {
font-size: 14px;
word-break: break-all;
padding: 15px;
text-align: left;
}

h1 {
font-size: 36px;
}

h2 {
font-size: 26px;
}

.pagination-controls button {
padding: 10px 20px;
font-size: 14px;
margin: 0 5px;
}
}

/* Loading Spinner Animation */
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
Loading

0 comments on commit c80417d

Please sign in to comment.