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": {}
+}