diff --git a/osanReactStudy/src/App.jsx b/osanReactStudy/src/App.jsx index 1486a32..76fbbd3 100644 --- a/osanReactStudy/src/App.jsx +++ b/osanReactStudy/src/App.jsx @@ -1,5 +1,6 @@ import React, { useState } from 'react'; import TeamMemberCard from './components/TeamMemberCard'; // 팀원 카드 컴포넌트 import +import AttendanceButton from './components/AttendanceButton'; // 출근/퇴근 버튼 컴포넌트 import // 팀원 정보 배열 const teamMembers = [ @@ -54,6 +55,11 @@ function App() { + {/* 출근/퇴근 버튼 컴포넌트 추가 */} +
+ +
+ {/* 필터된 팀원 목록 출력 */}
{filtered.map((member, i) => ( diff --git a/osanReactStudy/src/components/AttendanceButton.jsx b/osanReactStudy/src/components/AttendanceButton.jsx new file mode 100644 index 0000000..c6f5384 --- /dev/null +++ b/osanReactStudy/src/components/AttendanceButton.jsx @@ -0,0 +1,167 @@ +import React, { useState, useEffect } from 'react'; + +const AttendanceButton = () => { + // 상태 관리 + const [isWorking, setIsWorking] = useState(false); // 출근 상태 + const [isLate, setIsLate] = useState(false); // 지각 여부 + const [checkInTime, setCheckInTime] = useState(null); // 출근 시간 + const [checkOutTime, setCheckOutTime] = useState(null); // 퇴근 시간 + const [workingHours, setWorkingHours] = useState(0); // 근무 시간 (시간 단위) + + // 컴포넌트 마운트 시 localStorage에서 상태 복원 + useEffect(() => { + const savedCheckInTime = localStorage.getItem('checkInTime'); + const savedIsWorking = localStorage.getItem('isWorking'); + + if (savedCheckInTime && savedIsWorking === 'true') { + const parsedTime = new Date(savedCheckInTime); + setCheckInTime(parsedTime); + setIsWorking(true); + + // 9시 이후 출근인지 확인 + checkIfLate(parsedTime); + + // 근무 시간 계산 및 표시 + calculateWorkingHours(parsedTime); + } + }, []); + + // 매 분마다 근무 시간 업데이트 + useEffect(() => { + let timer; + if (isWorking && checkInTime) { + timer = setInterval(() => { + calculateWorkingHours(checkInTime); + + // 8시간 이상 근무했으면 자동 퇴근 처리 + if (workingHours >= 8) { + handleCheckOut(); + } + }, 60000); // 1분마다 업데이트 + } + + return () => clearInterval(timer); + }, [isWorking, checkInTime, workingHours]); + + // 9시 이후 출근인지 확인하는 함수 + const checkIfLate = (time) => { + const checkInHour = time.getHours(); + const checkInMinute = time.getMinutes(); + + // 9시 이후면 지각 + if (checkInHour > 9 || (checkInHour === 9 && checkInMinute > 0)) { + setIsLate(true); + } else { + setIsLate(false); + } + }; + + // 근무 시간 계산 함수 + const calculateWorkingHours = (startTime) => { + if (!startTime) return; + + const now = new Date(); + const diff = now - startTime; // 밀리초 단위 차이 + const hours = diff / (1000 * 60 * 60); // 시간 단위로 변환 + + setWorkingHours(parseFloat(hours.toFixed(2))); + }; + + // 출근 버튼 클릭 이벤트 핸들러 + const handleCheckIn = () => { + const now = new Date(); + setCheckInTime(now); + setIsWorking(true); + setCheckOutTime(null); + + // 지각 여부 확인 + checkIfLate(now); + + // localStorage에 출근 정보 저장 + localStorage.setItem('checkInTime', now.toString()); + localStorage.setItem('isWorking', 'true'); + }; + + // 퇴근 버튼 클릭 이벤트 핸들러 + const handleCheckOut = () => { + const now = new Date(); + setCheckOutTime(now); + setIsWorking(false); + + // localStorage 정보 초기화 + localStorage.removeItem('checkInTime'); + localStorage.removeItem('isWorking'); + + // 최종 근무 시간 계산 + if (checkInTime) { + calculateWorkingHours(checkInTime); + } + }; + + // 시간 형식을 포맷팅하는 함수 + const formatTime = (date) => { + if (!date) return '--:--'; + + const hours = date.getHours().toString().padStart(2, '0'); + const minutes = date.getMinutes().toString().padStart(2, '0'); + + return `${hours}:${minutes}`; + }; + + return ( +
+

근태 관리

+ + {/* 출근/퇴근 시간 표시 */} +
+
+

출근 시간

+

{formatTime(checkInTime)}

+
+
+

퇴근 시간

+

{formatTime(checkOutTime)}

+
+
+ + {/* 근무 상태 표시 */} +
+
+
+

+ {isWorking ? '근무 중' : '퇴근 완료'} +

+
+ + {/* 지각 표시 */} + {isLate && isWorking && ( +

+ 지각입니다! (9시 이후 출근) +

+ )} + + {/* 근무 시간 표시 */} + {isWorking && ( +

+ 근무 시간: {workingHours.toFixed(2)}시간 + {workingHours >= 8 && " (일일 목표 달성!)"} +

+ )} +
+ + {/* 출근/퇴근 버튼 */} + +
+ ); +}; + +export default AttendanceButton; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..fc4faea --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "react-study-osan", + "lockfileVersion": 3, + "requires": true, + "packages": {} +}