Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added frontend/public/assets/img/boom-fill-green.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/public/assets/img/boom-fill-red.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
101 changes: 73 additions & 28 deletions frontend/src/Attendance.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import axios from "axios";
const Attendance = () => {
const [attendanceCode, setAttendanceCode] = useState([""]);
const [attendanceData, setAttendanceData] = useState([]);
const [todayStatuses, setTodayStatuses] = useState([
"not_started",
"not_started",
"not_started",
]);

const getSubImage = (count) => {
switch (count) {
Expand All @@ -22,6 +27,18 @@ const Attendance = () => {
}
};

// 세션별 상단 이미지 handling
const getBoomImage = (status) => {
switch (status) {
case "success":
return "/assets/img/boom-fill-green.png";
case "fail":
return "/assets/img/boom-fill-red.png";
default:
return "/assets/img/tabler--boom.png";
}
};

// 날짜 기반 주차 계산
const getWeekFromDate = (dateStr) => {
const startDate = new Date("2025-06-24"); // 세션 시작일
Expand Down Expand Up @@ -64,26 +81,57 @@ const Attendance = () => {
});
};

useEffect(() => {
const fetchAttendance = async () => {
try {
const user = JSON.parse(localStorage.getItem("user"));
const userId = user?.id;

if (!userId) return;

const res = await axios.get(`/api/attendance/user`, {
params: { userId },
});

const rawData = res.data.data;
const weekly = processWeeklyAttendance(rawData);
setAttendanceData(weekly);
} catch (error) {
console.error("출석 정보 가져오기 실패:", error);
const fetchAttendance = async () => {
try {
const user = JSON.parse(localStorage.getItem("user"));
const userId = user?.id;
if (!userId) return;

// 유저 전체 출석 데이터 불러오기
const res = await axios.get(`/api/attendance/user`, {
params: { userId },
});
const rawData = res.data.data;
const weekly = processWeeklyAttendance(rawData);
setAttendanceData(weekly);
} catch (error) {
console.error("출석 정보 가져오기 실패:", error);
}
};

// 세션별 출석체크(총 3번) 진행 정보 불러오기
const fetchTodayAttendance = async () => {
try {
const user = JSON.parse(localStorage.getItem("user"));
const userId = user?.id;
if (!userId) return;

const today = new Date().toISOString().split("T")[0]; // YYYY-MM-DD
const res = await axios.get(`/api/attendance/user/date`, {
params: { userId, date: today },
});

const slots = res.data.data?.[0]?.slots || [];

const statuses = slots.map((slot) => {
if (slot.status === true) return "success";
else return "fail";
});

// 출석체크 진행안된 것 처리
while (statuses.length < 3) {
statuses.push("not_started");
}
};

setTodayStatuses(statuses);
} catch (error) {
console.error("오늘 출석 정보 가져오기 실패:", error);
}
};

useEffect(() => {
fetchAttendance();
fetchTodayAttendance();
}, []);

const handleChange = (index, value) => {
Expand All @@ -100,7 +148,7 @@ const Attendance = () => {
const userId = user?.id;
if (!userId) return;

// 출석체크 서버에 반영
// 유저가 입력한 출석 코드 서버에 전달(서버에서 출석코드 체크)
const res = await axios.post("/api/attendance/mark", {
userId,
code: attendanceCode[0],
Expand All @@ -109,6 +157,7 @@ const Attendance = () => {
if (res.data.success) {
alert("출석이 성공적으로 처리되었습니다!");
fetchAttendance(); // 서버 출석체크 전달 후 UI 반영
fetchTodayAttendance(); // 세션별 상단 이미지 UI 반영
} else {
alert(res.data.message);
}
Expand Down Expand Up @@ -137,15 +186,11 @@ const Attendance = () => {
</button>
)}
<div className={styles.attend_img_container}>
<div className={styles.boom_icon}>
<img src="/assets/img/tabler--boom.png" />
</div>
<div className={styles.boom_icon}>
<img src="/assets/img/tabler--boom.png" />
</div>
<div className={styles.boom_icon}>
<img src="/assets/img/tabler--boom.png" />
</div>
{todayStatuses.map((status, idx) => (
<div className={styles.boom_icon} key={idx}>
<img src={getBoomImage(status)} alt={`attendance-${idx}`} />
</div>
))}
</div>
<div className={styles.attend_week_container}>
{attendanceData.map(({ week, classes }) => (
Expand Down