From b929833e7a774555e76a71dfe26fe7fb9899f679 Mon Sep 17 00:00:00 2001 From: JacobLef Date: Sun, 21 Dec 2025 18:02:56 -0500 Subject: [PATCH 1/2] Remove unnecessary comments from frontend hooks. --- frontend/src/hooks/useEmployeeDashboard.ts | 60 ++++++------ frontend/src/hooks/useEmployerList.ts | 101 ++++++++++++--------- 2 files changed, 85 insertions(+), 76 deletions(-) diff --git a/frontend/src/hooks/useEmployeeDashboard.ts b/frontend/src/hooks/useEmployeeDashboard.ts index 87e509c..9336fe3 100644 --- a/frontend/src/hooks/useEmployeeDashboard.ts +++ b/frontend/src/hooks/useEmployeeDashboard.ts @@ -1,10 +1,10 @@ -import { useState, useEffect } from 'react'; -import { getEmployee } from '../api/employees'; -import { getTrainingsByPerson, getExpiredTrainings } from '../api/training'; -import { getPayrollHistory } from '../api/payroll'; -import type { Employee } from '../types/employee'; -import type { Training } from '../types/training'; -import type { Paycheck } from '../types/payroll'; +import { useState, useEffect } from "react"; +import { getEmployee } from "../api/employees"; +import { getTrainingsByPerson, getExpiredTrainings } from "../api/training"; +import { getPayrollHistory } from "../api/payroll"; +import type { Employee } from "../types/employee"; +import type { Training } from "../types/training"; +import type { Paycheck } from "../types/payroll"; interface EmployeeDashboardStats { upcomingTrainings: number; @@ -20,13 +20,13 @@ const calculateNextPayDate = (paychecks: Paycheck[]): string | null => { const lastPayDate = new Date(paychecks[0].payDate); const nextPayDate = new Date(lastPayDate); - nextPayDate.setDate(nextPayDate.getDate() + DAYS_BETWEEN_PAYCHEKS); + nextPayDate.setDate(nextPayDate.getDate() + DAYS_BETWEEN_PAYCHEKS); - return nextPayDate.toISOString().split('T')[0]; + return nextPayDate.toISOString().split("T")[0]; }; const findLastBonus = (paychecks: Paycheck[]): number | null => { - const withBonus = paychecks.find(p => p.bonus !== null && p.bonus > 0); + const withBonus = paychecks.find((p) => p.bonus !== null && p.bonus > 0); return withBonus?.bonus ?? null; }; @@ -39,42 +39,39 @@ export const useEmployeeDashboard = (employeeId: number) => { upcomingTrainings: 0, expiredTrainings: 0, nextPayDate: null, - lastBonus: null + lastBonus: null, }); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchDashboardData = async () => { - setLoading(true) + setLoading(true); try { - const [empRes, trainingRes, expiredRes, paycheckRes] = await Promise.all([ - getEmployee(employeeId), - getTrainingsByPerson(employeeId), - getExpiredTrainings(employeeId), - getPayrollHistory(employeeId) - ]); + const [empRes, trainingRes, expiredRes, paycheckRes] = + await Promise.all([ + getEmployee(employeeId), + getTrainingsByPerson(employeeId), + getExpiredTrainings(employeeId), + getPayrollHistory(employeeId), + ]); setEmployee(empRes.data); - setTrainings(trainingRes.data) - setExpiredTrainings(expiredRes.data) - setRecentPaychecks(paycheckRes.data) + setTrainings(trainingRes.data); + setExpiredTrainings(expiredRes.data); + setRecentPaychecks(paycheckRes.data); - // Calculate pending trainings: not completed, not expired, not expiring soon const now = new Date(); const pendingTrainings = trainingRes.data.filter((t: Training) => { if (t.completed || t.expired) return false; - // If no expiry date, it's pending if (!t.expiryDate) return true; - // If expiry date is more than 30 days away, it's pending const expiryDate = new Date(t.expiryDate); const daysUntilExpiry = Math.ceil( - (expiryDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24) + (expiryDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24), ); return daysUntilExpiry > 30; }).length; - // Calculate expired trainings: only non-completed expired trainings const expiredTrainingsCount = trainingRes.data.filter((t: Training) => { return !t.completed && t.expired; }).length; @@ -83,11 +80,11 @@ export const useEmployeeDashboard = (employeeId: number) => { upcomingTrainings: pendingTrainings, expiredTrainings: expiredTrainingsCount, nextPayDate: calculateNextPayDate(paycheckRes.data), - lastBonus: findLastBonus(paycheckRes.data) + lastBonus: findLastBonus(paycheckRes.data), }); } catch (error) { - console.error('Failed to load employee dashboard', error); - setError('Failed to laod dashboard data'); + console.error("Failed to load employee dashboard", error); + setError("Failed to laod dashboard data"); } finally { setLoading(false); } @@ -105,6 +102,7 @@ export const useEmployeeDashboard = (employeeId: number) => { recentPaychecks, stats, loading, - error + error, }; -}; \ No newline at end of file +}; + diff --git a/frontend/src/hooks/useEmployerList.ts b/frontend/src/hooks/useEmployerList.ts index c834419..7cb4d4e 100644 --- a/frontend/src/hooks/useEmployerList.ts +++ b/frontend/src/hooks/useEmployerList.ts @@ -1,15 +1,21 @@ -import { useState, useEffect, useMemo, useCallback } from 'react'; -import { getEmployersByBusiness, getAllEmployers } from '../api/employers'; -import { getEmployer } from '../api/employers'; -import type { Employer } from '../types/employer'; -import { PersonStatus } from '../types/person_status'; - -type SortField = 'name' | 'salary' | 'hireDate' | 'title' | 'department' | 'directReportsCount'; -type SortDirection = 'asc' | 'desc'; +import { useState, useEffect, useMemo, useCallback } from "react"; +import { getEmployersByBusiness, getAllEmployers } from "../api/employers"; +import { getEmployer } from "../api/employers"; +import type { Employer } from "../types/employer"; +import { PersonStatus } from "../types/person_status"; + +type SortField = + | "name" + | "salary" + | "hireDate" + | "title" + | "department" + | "directReportsCount"; +type SortDirection = "asc" | "desc"; interface Filters { search: string; - status: PersonStatus | 'ALL'; + status: PersonStatus | "ALL"; department: string; sortBy: SortField; sortDirection: SortDirection; @@ -21,27 +27,27 @@ export const useEmployerList = () => { const [error, setError] = useState(null); const [selectedIds, setSelectedIds] = useState>(new Set()); const [filters, setFilters] = useState({ - search: '', - status: 'ALL', - department: '', - sortBy: 'name', - sortDirection: 'asc', + search: "", + status: "ALL", + department: "", + sortBy: "name", + sortDirection: "asc", }); // Load business ID from user const loadBusinessId = useCallback(async (): Promise => { try { - const userStr = localStorage.getItem('user'); + const userStr = localStorage.getItem("user"); if (!userStr) return null; const user = JSON.parse(userStr); - if (user.role === 'EMPLOYER' && user.businessPersonId) { + if (user.role === "EMPLOYER" && user.businessPersonId) { const response = await getEmployer(user.businessPersonId); return response.data.companyId; } return null; } catch (error) { - console.error('Failed to load business ID:', error); + console.error("Failed to load business ID:", error); return null; } }, []); @@ -52,14 +58,14 @@ export const useEmployerList = () => { setError(null); try { const businessId = await loadBusinessId(); - const response = businessId + const response = businessId ? await getEmployersByBusiness(businessId) : await getAllEmployers(); setEmployers(response.data); } catch (err: unknown) { const error = err as { response?: { data?: { message?: string } } }; - setError(error.response?.data?.message || 'Failed to load employers'); - console.error('Error fetching employers:', err); + setError(error.response?.data?.message || "Failed to load employers"); + console.error("Error fetching employers:", err); } finally { setLoading(false); } @@ -77,22 +83,22 @@ export const useEmployerList = () => { if (filters.search) { const searchLower = filters.search.toLowerCase(); result = result.filter( - emp => + (emp) => emp.name.toLowerCase().includes(searchLower) || emp.email.toLowerCase().includes(searchLower) || emp.title.toLowerCase().includes(searchLower) || - emp.department.toLowerCase().includes(searchLower) + emp.department.toLowerCase().includes(searchLower), ); } // Apply status filter - if (filters.status !== 'ALL') { - result = result.filter(emp => emp.status === filters.status); + if (filters.status !== "ALL") { + result = result.filter((emp) => emp.status === filters.status); } // Apply department filter if (filters.department) { - result = result.filter(emp => emp.department === filters.department); + result = result.filter((emp) => emp.department === filters.department); } // Apply sorting @@ -101,27 +107,27 @@ export const useEmployerList = () => { let bValue: string | number; switch (filters.sortBy) { - case 'name': + case "name": aValue = a.name.toLowerCase(); bValue = b.name.toLowerCase(); break; - case 'salary': + case "salary": aValue = a.salary; bValue = b.salary; break; - case 'hireDate': + case "hireDate": aValue = new Date(a.hireDate).getTime(); bValue = new Date(b.hireDate).getTime(); break; - case 'title': + case "title": aValue = a.title.toLowerCase(); bValue = b.title.toLowerCase(); break; - case 'department': + case "department": aValue = a.department.toLowerCase(); bValue = b.department.toLowerCase(); break; - case 'directReportsCount': + case "directReportsCount": aValue = a.directReportsCount; bValue = b.directReportsCount; break; @@ -129,8 +135,8 @@ export const useEmployerList = () => { return 0; } - if (aValue < bValue) return filters.sortDirection === 'asc' ? -1 : 1; - if (aValue > bValue) return filters.sortDirection === 'asc' ? 1 : -1; + if (aValue < bValue) return filters.sortDirection === "asc" ? -1 : 1; + if (aValue > bValue) return filters.sortDirection === "asc" ? 1 : -1; return 0; }); @@ -139,7 +145,7 @@ export const useEmployerList = () => { // Selection handlers const toggleSelect = useCallback((id: number) => { - setSelectedIds(prev => { + setSelectedIds((prev) => { const next = new Set(prev); if (next.has(id)) { next.delete(id); @@ -154,7 +160,7 @@ export const useEmployerList = () => { if (selectedIds.size === filteredAndSortedEmployers.length) { setSelectedIds(new Set()); } else { - setSelectedIds(new Set(filteredAndSortedEmployers.map(emp => emp.id))); + setSelectedIds(new Set(filteredAndSortedEmployers.map((emp) => emp.id))); } }, [selectedIds.size, filteredAndSortedEmployers]); @@ -163,23 +169,29 @@ export const useEmployerList = () => { }, []); // Filter handlers - const updateFilter = useCallback((key: keyof Filters, value: string | PersonStatus | SortField | SortDirection) => { - setFilters(prev => ({ ...prev, [key]: value })); - }, []); + const updateFilter = useCallback( + ( + key: keyof Filters, + value: string | PersonStatus | SortField | SortDirection, + ) => { + setFilters((prev) => ({ ...prev, [key]: value })); + }, + [], + ); const clearFilters = useCallback(() => { setFilters({ - search: '', - status: 'ALL', - department: '', - sortBy: 'name', - sortDirection: 'asc', + search: "", + status: "ALL", + department: "", + sortBy: "name", + sortDirection: "asc", }); }, []); // Get unique departments for filter const departments = useMemo(() => { - const deptSet = new Set(employers.map(emp => emp.department)); + const deptSet = new Set(employers.map((emp) => emp.department)); return Array.from(deptSet).sort(); }, [employers]); @@ -202,4 +214,3 @@ export const useEmployerList = () => { clearFilters, }; }; - From 4e0126368bf277c26215270899f1b72a21a77a57 Mon Sep 17 00:00:00 2001 From: JacobLef Date: Mon, 22 Dec 2025 11:37:35 -0500 Subject: [PATCH 2/2] Update the training servce implementation to remove the uncessary convert from DTO method. --- .../src/main/java/app/training/Training.java | 34 ++------ .../app/training/TrainingServiceImpl.java | 77 +++++-------------- frontend/src/api/businesses.ts | 22 +++--- frontend/src/api/employees.ts | 29 ++++--- frontend/src/hooks/useEmployeePayroll.ts | 29 ++++--- 5 files changed, 69 insertions(+), 122 deletions(-) diff --git a/backend/src/main/java/app/training/Training.java b/backend/src/main/java/app/training/Training.java index 75cd40e..ff1b245 100644 --- a/backend/src/main/java/app/training/Training.java +++ b/backend/src/main/java/app/training/Training.java @@ -3,7 +3,6 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; - import app.business.BusinessPerson; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -50,18 +49,12 @@ public class Training { @Column(name = "created_at", nullable = false, updatable = false) private LocalDateTime createdAt; - // -------------------- Constructors -------------------- - public Training() { this.createdAt = LocalDateTime.now(); } - public Training( - String trainingName, - String description, - LocalDate completionDate, - LocalDate expiryDate, - boolean required) { + public Training(String trainingName, String description, LocalDate completionDate, + LocalDate expiryDate, boolean required) { this.trainingName = trainingName; this.description = description; this.completionDate = completionDate; @@ -77,8 +70,6 @@ protected void onCreate() { } } - // -------------------- Business Logic -------------------- - /** * Check if the training is completed. A training is considered completed if completionDate is not * null. @@ -101,8 +92,6 @@ public long getRemainingDays() { return ChronoUnit.DAYS.between(LocalDate.now(), expiryDate); } - // -------------------- Getters / Setters -------------------- - public Long getId() { return id; } @@ -165,20 +154,9 @@ public LocalDateTime getCreatedAt() { @Override public String toString() { - return "Training{" - + "id=" - + id - + ", trainingName='" - + trainingName - + '\'' - + ", personType=" - + (person != null ? person.getPersonType() : "null") - + ", personName=" - + (person != null ? person.getName() : "null") - + ", required=" - + required - + ", expired=" - + isExpired() - + '}'; + return "Training{" + "id=" + id + ", trainingName='" + trainingName + '\'' + ", personType=" + + (person != null ? person.getPersonType() : "null") + ", personName=" + + (person != null ? person.getName() : "null") + ", required=" + required + ", expired=" + + isExpired() + '}'; } } diff --git a/backend/src/main/java/app/training/TrainingServiceImpl.java b/backend/src/main/java/app/training/TrainingServiceImpl.java index f9d27c3..a76b15c 100644 --- a/backend/src/main/java/app/training/TrainingServiceImpl.java +++ b/backend/src/main/java/app/training/TrainingServiceImpl.java @@ -1,11 +1,8 @@ package app.training; import java.util.List; -import java.util.stream.Collectors; - import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - import app.business.BusinessPerson; import app.business.BusinessPersonRepository; import app.common.exception.ResourceNotFoundException; @@ -20,18 +17,16 @@ public class TrainingServiceImpl implements TrainingService { private final TrainingRepository trainingRepository; private final BusinessPersonRepository businessPersonRepository; - public TrainingServiceImpl( - TrainingRepository trainingRepository, BusinessPersonRepository businessPersonRepository) { + public TrainingServiceImpl(TrainingRepository trainingRepository, + BusinessPersonRepository businessPersonRepository) { this.trainingRepository = trainingRepository; this.businessPersonRepository = businessPersonRepository; } @Override public TrainingDTO addTraining(Long personId, CreateTrainingRequest request) { - BusinessPerson person = - businessPersonRepository - .findById(personId) - .orElseThrow(() -> new ResourceNotFoundException("Person", "id", personId)); + BusinessPerson person = businessPersonRepository.findById(personId) + .orElseThrow(() -> new ResourceNotFoundException("Person", "id", personId)); Training training = createTrainingFromRequest(request); training.setPerson(person); Training saved = trainingRepository.save(training); @@ -39,12 +34,8 @@ public TrainingDTO addTraining(Long personId, CreateTrainingRequest request) { } private Training createTrainingFromRequest(CreateTrainingRequest request) { - return new Training( - request.trainingName(), - request.description(), - request.completionDate(), - request.expiryDate(), - request.required()); + return new Training(request.trainingName(), request.description(), request.completionDate(), + request.expiryDate(), request.required()); } @Override @@ -54,9 +45,7 @@ public List getTrainingsByPerson(Long personId) { throw new ResourceNotFoundException("Person", "id", personId); } - return trainingRepository.findByPersonId(personId).stream() - .map(this::convertToDTO) - .collect(Collectors.toList()); + return trainingRepository.findByPersonId(personId).stream().map(this::convertToDTO).toList(); } @Override @@ -66,28 +55,22 @@ public List getExpiredTrainings(Long personId) { throw new ResourceNotFoundException("Person", "id", personId); } - return trainingRepository.findByPersonId(personId).stream() - .filter(Training::isExpired) - .map(this::convertToDTO) - .collect(Collectors.toList()); + return trainingRepository.findByPersonId(personId).stream().filter(Training::isExpired) + .map(this::convertToDTO).toList(); } @Override @Transactional(readOnly = true) public TrainingDTO getTrainingById(Long trainingId) { - Training training = - trainingRepository - .findById(trainingId) - .orElseThrow(() -> new ResourceNotFoundException("Training", "id", trainingId)); + Training training = trainingRepository.findById(trainingId) + .orElseThrow(() -> new ResourceNotFoundException("Training", "id", trainingId)); return convertToDTO(training); } @Override public TrainingDTO updateTraining(Long trainingId, UpdateTrainingRequest request) { - Training training = - trainingRepository - .findById(trainingId) - .orElseThrow(() -> new ResourceNotFoundException("Training", "id", trainingId)); + Training training = trainingRepository.findById(trainingId) + .orElseThrow(() -> new ResourceNotFoundException("Training", "id", trainingId)); if (request.trainingName() != null) { training.setTrainingName(request.trainingName()); } @@ -120,38 +103,18 @@ public void deleteTraining(Long trainingId) { @Override @Transactional(readOnly = true) public List getAllTrainings() { - return trainingRepository.findAll().stream() - .map(this::convertToDTO) - .collect(Collectors.toList()); - } - - // -------------------- Helper Methods -------------------- - - private Training createTrainingFromDTO(TrainingDTO dto) { - return new Training( - dto.getTrainingName(), - dto.getDescription(), - dto.getCompletionDate(), - dto.getExpiryDate(), - dto.isRequired()); + return trainingRepository.findAll().stream().map(this::convertToDTO).toList(); } private TrainingDTO convertToDTO(Training training) { - TrainingDTO.Builder builder = - TrainingDTO.builder() - .withId(training.getId()) - .withTrainingName(training.getTrainingName()) - .withDescription(training.getDescription()) - .withCompletionDate(training.getCompletionDate()) - .withExpiryDate(training.getExpiryDate()) - .withRequired(training.isRequired()) - .withCompleted(training.isCompleted()) - .withExpired(training.isExpired()) - .withCreatedAt(training.getCreatedAt()); + TrainingDTO.Builder builder = TrainingDTO.builder().withId(training.getId()) + .withTrainingName(training.getTrainingName()).withDescription(training.getDescription()) + .withCompletionDate(training.getCompletionDate()).withExpiryDate(training.getExpiryDate()) + .withRequired(training.isRequired()).withCompleted(training.isCompleted()) + .withExpired(training.isExpired()).withCreatedAt(training.getCreatedAt()); if (training.getPerson() != null) { - builder - .withPersonId(training.getPerson().getId()) + builder.withPersonId(training.getPerson().getId()) .withPersonName(training.getPerson().getName()) .withPersonType(training.getPerson().getPersonType()); } diff --git a/frontend/src/api/businesses.ts b/frontend/src/api/businesses.ts index d0adf6a..0e55bd1 100644 --- a/frontend/src/api/businesses.ts +++ b/frontend/src/api/businesses.ts @@ -1,21 +1,21 @@ import api from "./axios"; -import type { - Company, - CreateBusinessRequest, - UpdateBusinessRequest +import type { + Company, + CreateBusinessRequest, + UpdateBusinessRequest, } from "../types/business"; -export const createBusiness = (data: CreateBusinessRequest) => +export const createBusiness = (data: CreateBusinessRequest) => api.post("/api/businesses", data); -export const getBusiness = (id: number) => +export const getBusiness = (id: number) => api.get(`/api/businesses/${id}`); -export const getAllBusinesses = () => - api.get("/api/businesses"); +export const getAllBusinesses = () => api.get("/api/businesses"); -export const updateBusiness = (id: number, data: UpdateBusinessRequest) => +export const updateBusiness = (id: number, data: UpdateBusinessRequest) => api.put(`/api/businesses/${id}`, data); -export const deleteBusiness = (id: number) => - api.delete(`/api/businesses/${id}`); \ No newline at end of file +export const deleteBusiness = (id: number) => + api.delete(`/api/businesses/${id}`); + diff --git a/frontend/src/api/employees.ts b/frontend/src/api/employees.ts index 397cb9d..baad73e 100644 --- a/frontend/src/api/employees.ts +++ b/frontend/src/api/employees.ts @@ -1,32 +1,31 @@ import api from "./axios"; -import type { - Employee, - CreateEmployeeRequest, - UpdateEmployeeRequest +import type { + Employee, + CreateEmployeeRequest, + UpdateEmployeeRequest, } from "../types/employee"; -export const createEmployee = (data: CreateEmployeeRequest) => +export const createEmployee = (data: CreateEmployeeRequest) => api.post("/api/employees", data); -export const getEmployee = (id: number) => +export const getEmployee = (id: number) => api.get(`/api/employees/${id}`); -export const getAllEmployees = () => - api.get("/api/employees"); +export const getAllEmployees = () => api.get("/api/employees"); -export const updateEmployee = (id: number, data: UpdateEmployeeRequest) => +export const updateEmployee = (id: number, data: UpdateEmployeeRequest) => api.put(`/api/employees/${id}`, data); -export const deleteEmployee = (id: number) => +export const deleteEmployee = (id: number) => api.delete(`/api/employees/${id}`); -export const getEmployeesByBusiness = (businessId: number) => +export const getEmployeesByBusiness = (businessId: number) => api.get(`/api/employees/business/${businessId}`); -export const getEmployeesByManager = (managerId: number) => +export const getEmployeesByManager = (managerId: number) => api.get(`/api/employees/manager/${managerId}`); -export const assignManager = (id: number, managerId: number) => +export const assignManager = (id: number, managerId: number) => api.put(`/api/employees/${id}/manager`, null, { - params: { managerId } - }); \ No newline at end of file + params: { managerId }, + }); diff --git a/frontend/src/hooks/useEmployeePayroll.ts b/frontend/src/hooks/useEmployeePayroll.ts index 2f5fc3f..16de699 100644 --- a/frontend/src/hooks/useEmployeePayroll.ts +++ b/frontend/src/hooks/useEmployeePayroll.ts @@ -1,6 +1,6 @@ -import { useState, useEffect, useMemo } from 'react'; -import type { Paycheck } from '../types/payroll'; -import { getPayrollHistory } from '../api/payroll'; +import { useState, useEffect, useMemo } from "react"; +import type { Paycheck } from "../types/payroll"; +import { getPayrollHistory } from "../api/payroll"; export const useEmployeePayroll = (employeeId: number | null) => { const [history, setHistory] = useState([]); @@ -17,10 +17,13 @@ export const useEmployeePayroll = (employeeId: number | null) => { try { const response = await getPayrollHistory(employeeId); // Filter out DRAFT paychecks for employee view - const filtered = response.data.filter((p: Paycheck) => p.status !== 'DRAFT'); + const filtered = response.data.filter( + (p: Paycheck) => p.status !== "DRAFT", + ); // Sort: Newest first - const sorted = filtered.sort((a: Paycheck, b: Paycheck) => - new Date(b.payDate).getTime() - new Date(a.payDate).getTime() + const sorted = filtered.sort( + (a: Paycheck, b: Paycheck) => + new Date(b.payDate).getTime() - new Date(a.payDate).getTime(), ); setHistory(sorted); } catch (error) { @@ -37,14 +40,19 @@ export const useEmployeePayroll = (employeeId: number | null) => { // Frontend YTD Calculation (MVP Shortcut) const stats = useMemo(() => { const currentYear = new Date().getFullYear(); - const thisYearChecks = history.filter(p => new Date(p.payDate).getFullYear() === currentYear); - + const thisYearChecks = history.filter( + (p) => new Date(p.payDate).getFullYear() === currentYear, + ); + return { totalGross: thisYearChecks.reduce((sum, p) => sum + p.grossPay, 0), totalNet: thisYearChecks.reduce((sum, p) => sum + p.netPay, 0), totalTax: thisYearChecks.reduce((sum, p) => sum + p.taxDeduction, 0), - totalInsurance: thisYearChecks.reduce((sum, p) => sum + p.insuranceDeduction, 0), - paycheckCount: thisYearChecks.length + totalInsurance: thisYearChecks.reduce( + (sum, p) => sum + p.insuranceDeduction, + 0, + ), + paycheckCount: thisYearChecks.length, }; }, [history]); @@ -52,4 +60,3 @@ export const useEmployeePayroll = (employeeId: number | null) => { return { history, latestPaycheck, stats, loading }; }; -