diff --git a/src/screens/worker/WorkerMonthlyCalendarScreen.tsx b/src/screens/worker/WorkerMonthlyCalendarScreen.tsx index 38d6034..4c7d14b 100644 --- a/src/screens/worker/WorkerMonthlyCalendarScreen.tsx +++ b/src/screens/worker/WorkerMonthlyCalendarScreen.tsx @@ -20,6 +20,7 @@ import useCorrectionRequest from "../../hooks/worker/useCorrectionRequest"; import { useLogoutHandler } from "../../hooks/common/useLogoutHandler"; import { WorkerStackParamList } from "../../navigation/WorkerStack"; import { colors } from "../../constants/colors"; +import { calculateWorkSummary } from "../../utils/workSummary"; const WorkerMonthlyCalendarScreen: React.FC = ({ navigation }: any) => { const [isDrawerVisible, setIsDrawerVisible] = useState(false); @@ -114,9 +115,10 @@ const WorkerMonthlyCalendarScreen: React.FC = ({ navigation }: any) => { // 월간 요약 계산 (근무 총 시간/급여) const monthLabel = `${month + 1}월`; - const totalMinutes = works.reduce((sum, w) => sum + w.totalWorkMinutes, 0); - const totalHours = Math.round((totalMinutes / 60) * 10) / 10; - const estimatedPay = works.reduce((sum, w) => sum + (w.totalSalary ?? 0), 0); + const { totalHours, estimatedPay } = useMemo( + () => calculateWorkSummary(works), + [works] + ); return ( diff --git a/src/screens/worker/WorkerWeeklyCalendarScreen.tsx b/src/screens/worker/WorkerWeeklyCalendarScreen.tsx index 85d1581..3e982da 100644 --- a/src/screens/worker/WorkerWeeklyCalendarScreen.tsx +++ b/src/screens/worker/WorkerWeeklyCalendarScreen.tsx @@ -31,6 +31,7 @@ import { getWeekLabel, getWeekRange, } from "../../utils/date"; +import { calculateWorkSummary } from "../../utils/workSummary"; type Props = NativeStackScreenProps; @@ -128,14 +129,9 @@ const WorkerWeeklyCalendarScreen: React.FC = ({ navigation }) => { } = useCorrectionRequest(); // 주간 요약 계산 - const totalMinutes = works.reduce( - (sum, w) => sum + w.totalWorkMinutes, - 0 - ); - const totalHours = Math.round((totalMinutes / 60) * 10) / 10; - const estimatedPay = works.reduce( - (sum, w) => sum + (w.totalSalary ?? 0), - 0 + const { totalHours, estimatedPay } = useMemo( + () => calculateWorkSummary(works), + [works] ); return ( diff --git a/src/utils/workSummary.ts b/src/utils/workSummary.ts new file mode 100644 index 0000000..af2314c --- /dev/null +++ b/src/utils/workSummary.ts @@ -0,0 +1,30 @@ +import type { WorkItem } from "../types/worker.types"; + +export interface WorkSummary { + totalHours: number; + estimatedPay: number; +} + +/** + * 근무 목록에서 요약(총 근무시간, 예상 근무비) 계산. DELETED 근무는 두 값 모두 제외. + * - 총 근무시간: COMPLETED 근무의 totalWorkMinutes 합산 + * - 예상 근무비: COMPLETED + SCHEDULED의 totalSalary 합산 + * (백엔드가 SCHEDULED도 totalSalary를 계산해 반환 — PayCheck-backend#177) + */ +export const calculateWorkSummary = (works: WorkItem[]): WorkSummary => { + let completedMinutes = 0; + let estimatedPay = 0; + + for (const work of works) { + if (work.status === "DELETED") continue; + + if (work.status === "COMPLETED") { + completedMinutes += work.totalWorkMinutes; + } + estimatedPay += work.totalSalary ?? 0; + } + + const totalHours = Math.round((completedMinutes / 60) * 10) / 10; + + return { totalHours, estimatedPay }; +};