+
{idx + 1}차 출석
diff --git a/frontend/src/pages/admin/AdminStudentAssignment.jsx b/frontend/src/pages/admin/AdminStudentAssignment.jsx
index b5ddb99..180c8d5 100644
--- a/frontend/src/pages/admin/AdminStudentAssignment.jsx
+++ b/frontend/src/pages/admin/AdminStudentAssignment.jsx
@@ -27,7 +27,7 @@ const AdminStudentAssignment = () => {
}
fetchStudentInfo(id).then((res) => {
- setStudentInfo(res.data);
+ setStudentInfo(res);
});
@@ -38,28 +38,28 @@ const AdminStudentAssignment = () => {
label: `${weekItem.week}주차 ${weekItem.subject}`,
days: weekItem.days.map((dayItem) => ({
day: dayItem.day,
- subject: weekItem.subject,
tasks: dayItem.details.map((task) => ({
id: task.id,
label: task.assignmentName,
status: task.status,
- modified: false,
+ //modified: false,
})),
})),
}));
setWeeks(formatted);
- const matched = formatted.find((w) => String(w.week) === String(week));
+ const matched = formatted.find((w) => Number(w.week) === Number(week));
if (matched) {
setSelectedWeekLabel(matched.label);
+ /*
if (matched.days.length > 0) {
setHighlightCard({
weekLabel: matched.label,
day: matched.days[0].day,
tasks: matched.days[0].tasks,
});
- }
+ }*/
}
});
}, [studentId, week]);
@@ -79,9 +79,11 @@ const AdminStudentAssignment = () => {
});
};
*/
+
+
const handleSave = async (taskId, status) => {
const userId = parseInt(studentId); // 문자열일 수 있으니 숫자로 변환
-
+
try {
// PUT 요청 시도 (기존 과제 수정)
await updateAssignmentStatus(userId, taskId, status);
diff --git a/frontend/src/pages/admin/AdminStudentAttendance.jsx b/frontend/src/pages/admin/AdminStudentAttendance.jsx
index b7039ae..9a70692 100644
--- a/frontend/src/pages/admin/AdminStudentAttendance.jsx
+++ b/frontend/src/pages/admin/AdminStudentAttendance.jsx
@@ -1,7 +1,7 @@
import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import AdminStudentHeader from "../../components/AdminStudentHeader";
-import DailyAttendanceCard from "../../components/AdminDailyAttendanceCard";
+import AdminDailyAttendanceCard from "../../components/AdminDailyAttendanceCard";
import api from "../../api/api";
import styles from "./AdminStudentAttendance.module.css";
import AdminWeeklyAttendanceList from "../../components/AdminWeeklyAttendanceList";
@@ -12,7 +12,26 @@ const AdminStudentAttendance = () => {
const [studentInfo, setStudentInfo] = useState(null);
const [attendanceData, setAttendanceData] = useState([]);
const [selectedDate, setSelectedDate] = useState(null);
-
+ const fetchData = async () => {
+ try {
+ const studentRes = await getStudentBasicInfo(studentId);
+ setStudentInfo(studentRes);
+
+ const attendanceRes = await getStudentAttendance(studentId);
+ /*
+ "attendanceId": 1,
+ "userId": 1,
+ "username": "홍길동",
+ "date": "2023-10-20",
+ "order": 1,
+ "status": true
+ */
+ const processed = processWeeklyAttendance(attendanceRes);
+ setAttendanceData(processed);
+ } catch (err) {
+ console.error("데이터 불러오기 실패:", err);
+ }
+ };
useEffect(() => {
const id = Number(studentId);
@@ -21,19 +40,6 @@ const AdminStudentAttendance = () => {
return;
}
- const fetchData = async () => {
- try {
- const studentRes = await getStudentBasicInfo(studentId);
- setStudentInfo(studentRes);
-
- const attendanceRes = await getStudentAttendance(studentId);
- const processed = processWeeklyAttendance(attendanceRes);
- setAttendanceData(processed);
- } catch (err) {
- console.error("데이터 불러오기 실패:", err);
- }
- };
-
fetchData();
}, [studentId]);
@@ -56,64 +62,72 @@ const AdminStudentAttendance = () => {
}, []);
*/
// 날짜 기반 주차-회차 구조로 변환
- const processWeeklyAttendance = (rawData) => {
- const startDate = new Date("2025-06-24");
- const getWeekFromDate = (dateStr) => {
- const d = new Date(dateStr);
- const diffDays = Math.floor((d - startDate) / (1000 * 60 * 60 * 24));
- return Math.floor(diffDays / 7) + 1;
- };
-
- const weekSlotMap = new Map();
- const dateMap = new Map(); // 추가: 날짜 저장
-
- rawData.forEach(({ date, slots }) => {
- const week = getWeekFromDate(date);
- const statuses = slots.map((s) =>
- s.status ? "SUCCESS" : "FAILURE"
- );
- const existing = weekSlotMap.get(week) || [];
- const existingDates = dateMap.get(week) || [];
-
- weekSlotMap.set(week, [...existing, ...statuses]);
- dateMap.set(week, [...existingDates, date]);
- });
+const processWeeklyAttendance = (rawData) => {
+ const startDate = new Date("2025-06-24");
+ const offsetDays = [0, 2, 4];
- return Array.from({ length: 5 }, (_, i) => {
- const week = i + 1;
- const all = weekSlotMap.get(week) || [];
- const dates = dateMap.get(week) || [];
-
- const classes = [0, 1, 2].map((classIdx) => {
- const slice = all.slice(classIdx * 3, classIdx * 3 + 3);
- const trueCount = slice.filter((s) => s === "SUCCESS").length;
-
- let status;
- switch (trueCount) {
- case 3:
- status = "SUCCESS";
- break;
- case 2:
- status = "INSUFFICIENT";
- break;
- case 1:
- status = "FAILURE";
- break;
- default:
- status = "EMPTY";
- }
-
- return {
- status,
- date: dates[classIdx] || null,
- };
- });
-
-
- return { week, classes };
- });
+
+ const getWeekFromDate = (dateStr) => {
+ const d = new Date(dateStr);
+ const diffDays = Math.floor((d - startDate) / (1000 * 60 * 60 * 24));
+ return Math.floor(diffDays / 7) + 1;
+ };
+ const getDateForClass = (week, classIdx) => {
+ const base = new Date(startDate);
+ base.setDate(base.getDate() + (week - 1) * 7 + offsetDays[classIdx]);
+ return base.toISOString().split("T")[0]; // 'YYYY-MM-DD' 형식
};
+ // 주차별 출석 정보 묶기
+ const weekMap = new Map();
+
+ rawData.forEach(({ date, order, status }) => {
+ const week = getWeekFromDate(date);
+ const entry = { date, order, status: status ? "SUCCESS" : "FAILURE" };
+
+ if (!weekMap.has(week)) weekMap.set(week, []);
+ weekMap.get(week).push(entry);
+ });
+
+ return Array.from({ length: 5 }, (_, i) => {
+ const week = i + 1;
+ const entries = (weekMap.get(week) || []).sort((a, b) => a.order - b.order);
+
+ const classes = [0, 1, 2].map((classIdx) => {
+ const order = classIdx + 1;
+ const slice = entries.slice(classIdx * 3, classIdx * 3 + 3);
+ const entry = entries.find((e) => e.order === order);
+ const fallbackDate = getDateForClass(week, classIdx);
+
+
+ const trueCount = slice.filter((e) => e.status === "SUCCESS").length;
+
+ let status;
+ switch (trueCount) {
+ case 3:
+ status = "SUCCESS";
+ break;
+ case 2:
+ status = "INSUFFICIENT";
+ break;
+ case 1:
+ status = "FAILURE";
+ break;
+ default:
+ status = "EMPTY";
+ }
+
+ return {
+ order,
+ status: entry?.status ?? "EMPTY",
+ date: entry?.date ?? fallbackDate,
+ };
+ });
+
+ return { week, classes };
+ });
+};
+
return (
{/*헤더 */}
@@ -126,16 +140,26 @@ const AdminStudentAttendance = () => {
{/* 주차별 출석 */}
setSelectedDate(date)}
+ onSelectDate={(selected) => setSelectedDate(selected)}
+ //onSelectDate={(date) => setSelectedDate(date)}
/>
- {/* 선택된 날짜의 상세 수정 카드 */}
+ {/* 선택된 날짜의 상세 수정 카드
{selectedDate && (
- setSelectedDate(null)}
/>
+ )}*/}
+ {selectedDate && (
+ setSelectedDate(null)}
+ onRefresh={fetchData}
+ />
)}
);
diff --git a/frontend/src/pages/admin/DetailManageStudent.jsx b/frontend/src/pages/admin/DetailManageStudent.jsx
index 36cfbb1..9fbefcb 100644
--- a/frontend/src/pages/admin/DetailManageStudent.jsx
+++ b/frontend/src/pages/admin/DetailManageStudent.jsx
@@ -73,7 +73,7 @@ const DetailManageStudent = () => {
diff --git a/frontend/src/pages/generation/Assignment.jsx b/frontend/src/pages/generation/Assignment.jsx
index 095d5fc..3f5edc2 100644
--- a/frontend/src/pages/generation/Assignment.jsx
+++ b/frontend/src/pages/generation/Assignment.jsx
@@ -19,10 +19,12 @@ const Assignment = () => {
fetchAssignmentsByUser(userId)
.then((weekData) => {
const formatted = weekData.map((weekItem) => ({
- label: `${weekItem.week}주차 ${weekItem.subject}`,
+ label: `${weekItem.week}주차 ${weekItem.subtitle}`,
+ //label: `${weekItem.week}주차 ${weekItem.subject}`,
details: weekItem.days.map((dayItem) => ({
day: dayItem.day,
- subject: weekItem.subject,
+ subject: dayItem.subject,
+ //subject: weekItem.subject,
tasks: dayItem.details.map((task) => ({
label: task.assignmentName,
status: mapStatus(task.status),