diff --git a/backend/pirocheck/src/main/java/backend/pirocheck/User/filter/SessionCheckFilter.java b/backend/pirocheck/src/main/java/backend/pirocheck/User/filter/SessionCheckFilter.java index 61a09c4..83dc991 100644 --- a/backend/pirocheck/src/main/java/backend/pirocheck/User/filter/SessionCheckFilter.java +++ b/backend/pirocheck/src/main/java/backend/pirocheck/User/filter/SessionCheckFilter.java @@ -18,9 +18,10 @@ protected void doFilterInternal(HttpServletRequest request, throws ServletException, IOException { String path = request.getRequestURI(); + String method = request.getMethod(); - // 로그인/로그아웃 요청은 세션 체크 제외 - if (path.startsWith("/api/login") || path.startsWith("/api/logout")) { + // CORS preflight 요청(OPTIONS) 또는 로그인/로그아웃 요청은 세션 체크 제외 + if ("OPTIONS".equals(method) || path.startsWith("/api/login") || path.startsWith("/api/logout")) { filterChain.doFilter(request, response); // 다음 필터나 컨트롤러로 넘기는 명령어 return; // 세션 검사 안함 } diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index e177e6b..10300fe 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -12,31 +12,16 @@ import ManageTask from "./pages/admin/ManageTask.jsx"; import AttendanceCode from "./pages/admin/AttendanceCode"; import Attendance from "./pages/generation/Attendance"; import AdminStudentAttendance from "./pages/admin/AdminStudentAttendance"; -<<<<<<< HEAD import AdminStudentAssignment from "./pages/admin/AdminStudentAssignment.jsx"; -======= import RequireAuth from "./components/RequireAuth"; import RequireAdmin from "./components/RequireAdmin"; ->>>>>>> 08242a5045ea08b68c40b107cc871f8b3c3446eb function App() { return ( } /> } /> -<<<<<<< HEAD - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> -======= } /> ->>>>>>> 08242a5045ea08b68c40b107cc871f8b3c3446eb + + + + } + /> ); diff --git a/frontend/src/Intro.module.css b/frontend/src/Intro.module.css index 491aef3..ba814f5 100644 --- a/frontend/src/Intro.module.css +++ b/frontend/src/Intro.module.css @@ -13,7 +13,7 @@ content: ""; position: absolute; inset: 0; - background-image: url("./assets/img/logo.svg"); + background-image: url("/assets/img/logo.svg"); background-repeat: no-repeat; background-size: contain; background-position: center; @@ -27,7 +27,7 @@ .intro_container { background-color: var(--background-black); color: var(--main-green); - font-family: 'Akira Expanded'; + font-family: "Akira Expanded"; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); display: flex; justify-content: center; diff --git a/frontend/src/api/assignment.js b/frontend/src/api/assignment.js index 323730a..0c31de0 100644 --- a/frontend/src/api/assignment.js +++ b/frontend/src/api/assignment.js @@ -7,10 +7,25 @@ export const fetchAssignmentsByUser = async (userId) => { */ export const fetchAssignmentsByUser = async (userId) => { try { - const res = await api.get(`/api/assignment/${userId}`); + const res = await api.get(`/assignment/${userId}`); return res.data; // 백엔드가 반환하는 JSON 그대로 } catch (err) { console.error("과제 데이터 불러오기 실패:", err); throw err; } -}; \ No newline at end of file +}; + + +export const submitAssignmentStatus = async (userId, assignmentId, status) => { + return api.post(`/admin/users/${userId}/assignments/${assignmentId}/submission`, { + assignmentId, + userId, + status, + }); +}; + +export const updateAssignmentStatus = async (userId, assignmentId, status) => { + return api.put(`/admin/users/${userId}/assignments/${assignmentId}/submission`, { + status, + }); +}; diff --git a/frontend/src/pages/admin/AdminStudentAssignment.jsx b/frontend/src/pages/admin/AdminStudentAssignment.jsx index 2114cb4..9424ca7 100644 --- a/frontend/src/pages/admin/AdminStudentAssignment.jsx +++ b/frontend/src/pages/admin/AdminStudentAssignment.jsx @@ -5,6 +5,7 @@ import WeeklyOpenBlock from "../../components/WeeklyOpenBlock"; import AssignmentInfoBlock from "../../components/AssignmentInfoBlock"; import api from "../../api/api"; import styles from "./AdminStudentAssignment.module.css"; +import { submitAssignmentStatus, updateAssignmentStatus } from "../../api/assignment"; const AdminStudentAssignment = () => { const { studentId, week } = useParams(); @@ -14,7 +15,7 @@ const AdminStudentAssignment = () => { const [selectedWeekLabel, setSelectedWeekLabel] = useState(null); useEffect(() => { - api.get(`/admin/users/${studentId}`).then((res) => { + api.get(`/admin/users/${userId}`).then((res) => { setStudentInfo(res.data.data); }); @@ -62,13 +63,33 @@ const AdminStudentAssignment = () => { task.modified = true; setWeeks(updated); }; - +/* const handleSave = async (taskId, status) => { await api.put("/admin/assignment/status", { assignmentId: taskId, status, }); }; +*/ +const handleSave = async (taskId, status) => { + const userId = parseInt(studentId); // 문자열일 수 있으니 숫자로 변환 + + try { + // PUT 요청 시도 (기존 과제 수정) + await updateAssignmentStatus(userId, taskId, status); + alert("과제 상태가 수정되었습니다."); + } catch (err) { + console.warn("PUT 실패, POST 시도"); + try { + // 없으면 POST 요청 (새 과제 등록) + await submitAssignmentStatus(userId, taskId, status); + alert("과제 상태가 등록되었습니다."); + } catch (err) { + alert("상태 저장 실패"); + console.error(err); + } + } +}; return (
@@ -122,4 +143,4 @@ const AdminStudentAssignment = () => { ); }; -export default AdminStudentAssignment; \ No newline at end of file +export default AdminStudentAssignment; diff --git a/frontend/src/pages/admin/AttendanceCode.jsx b/frontend/src/pages/admin/AttendanceCode.jsx index d93ea52..879f86f 100644 --- a/frontend/src/pages/admin/AttendanceCode.jsx +++ b/frontend/src/pages/admin/AttendanceCode.jsx @@ -19,9 +19,7 @@ const AttendanceCode = () => { console.log("기존 출석코드 자동 만료됨"); } catch (error) { if (error.response?.status !== 404) { - alert( - "초기화 중 오류: " + (error.response?.data?.message || "서버 오류") - ); + return; } } }; diff --git a/frontend/src/pages/admin/DetailManageStudent.jsx b/frontend/src/pages/admin/DetailManageStudent.jsx index 3b4907a..e6b20bb 100644 --- a/frontend/src/pages/admin/DetailManageStudent.jsx +++ b/frontend/src/pages/admin/DetailManageStudent.jsx @@ -1,13 +1,23 @@ import { useParams } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import { useEffect, useState } from "react"; import Header from "../../components/Header"; import style from "./DetailManageStudent.module.css"; import { getStudentDetail } from "../../api/students"; +const weekData = [ + { week: "1주차", title: "Git/HTML/CSS" }, + { week: "2주차", title: "JavaScript/웹 개론" }, + { week: "3주차", title: "Django CRUD/DB 개론" }, + { week: "4주차", title: "Django ORM/Ajax" }, + { week: "5주차", title: "배포/아이디어 기획" }, +]; + const DetailManageStudent = () => { const { studentId } = useParams(); const numericId = Number(studentId); const [student, setStudent] = useState(null); + const navigate = useNavigate(); useEffect(() => { const fetchStudent = async () => { @@ -34,30 +44,33 @@ const DetailManageStudent = () => {

{student.name}

-

- 잔여 보증금:

{student.deposit}원

-

+ 잔여 보증금: {student.deposit}원
-

- 보증금 방어권:

{student.defence}

-

+ 보증금 방어권: {student.defence}
- -
- {student.assignmentTitles.map((title, idx) => ( - - ))} -
+ {student && ( + + )} + {student && ( +
+ {weekData.map((week, index) => ( + + ))} +
+ )}
); diff --git a/frontend/src/pages/admin/DetailManageStudent.module.css b/frontend/src/pages/admin/DetailManageStudent.module.css index 0e081f2..d69fe20 100644 --- a/frontend/src/pages/admin/DetailManageStudent.module.css +++ b/frontend/src/pages/admin/DetailManageStudent.module.css @@ -10,14 +10,14 @@ align-items: center; } .student_card { + /* height: 150px; */ display: flex; background: #49ff24; flex-direction: column; border-radius: 9px; padding: 15px 20px; width: 300px; - height: 150px; - justify-content: space-around; + gap: 15px; } .student_name { font-size: 25px; @@ -38,8 +38,31 @@ display: flex; align-items: center; justify-content: space-between; - background-color: #333; color: #49ff24; - padding: 15px; - text-align: left; + padding: 24px 15px; + margin-block: 30px; + font-size: 18px; +} +.assignment_list { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.assignment_button { + width: 309px; + height: 47px; + border-radius: 14px; + background-color: var(--border-gray); + color: var(--text-white); + font-weight: 400; + font-size: 16px; + font-family: "Noto Sans KR", sans-serif; + border: 1px var(--background-black) solid; + padding: 10px; + margin-top: 11px; +} +.assignment_button:focus { + border: 1px var(--main-green) solid; } diff --git a/frontend/src/pages/generation/Attendance.jsx b/frontend/src/pages/generation/Attendance.jsx index dce08b1..a81d189 100644 --- a/frontend/src/pages/generation/Attendance.jsx +++ b/frontend/src/pages/generation/Attendance.jsx @@ -152,7 +152,7 @@ const Attendance = () => { // 유저가 입력한 출석 코드 서버에 전달(서버에서 출석코드 체크) - const res = await axios.post( + const res = await api.post( "/api/attendance/mark", {