diff --git a/frontend/src/containers/AdminPage/AdminPage.tsx b/frontend/src/containers/AdminPage/AdminPage.tsx index b3cc0f8..d390d3c 100644 --- a/frontend/src/containers/AdminPage/AdminPage.tsx +++ b/frontend/src/containers/AdminPage/AdminPage.tsx @@ -1,7 +1,7 @@ import styled from "styled-components"; import React, { useState, useEffect } from "react"; import { UseFormReturn, useForm } from "react-hook-form"; -import { useNavigate } from "react-router-dom"; // useNavigate 훅 임포트 +import { useNavigate } from "react-router-dom"; interface AdminData { checkbox: boolean; @@ -17,6 +17,7 @@ const AdminPage = () => { const [filteredData, setFilteredData] = useState([]); const [showLogoutModal, setShowLogoutModal] = useState(false); const [showRegistrationModal, setShowRegistrationModal] = useState(false); + const [showDeleteModal, setShowDeleteModal] = useState(false); const navigate = useNavigate(); const TestData: AdminData[] = [ @@ -88,26 +89,21 @@ const AdminPage = () => { }; const handleDelete = () => { + setShowDeleteModal(true); + }; + + const handleConfirmDelete = () => { const newData = adminData.filter((item) => !item.checkbox); setAdminData(newData); setFilteredData(newData); + setShowDeleteModal(false); + }; + + const handleCancelDelete = () => { + setShowDeleteModal(false); }; - const { register, handleSubmit, reset } = useForm(); - // const newStudent: AdminData = { - // checkbox: false, - // name: data.name, - // studentid: parseInt(data.studentid), - // studentclass: data.studentclass, - // chapel: parseInt(data.chapel), - // chapelseat: data.chapelseat, - // }; - // const newData = [...adminData, newStudent]; - // setAdminData(newData); - // setFilteredData(newData); - // reset(); // 입력 폼 초기화 - // setShowRegistrationModal(false); // 등록 모달 닫기 - // // + const { register, handleSubmit } = useForm(); const onSubmit = (data: any) => { const searchQuery = data.search.toLowerCase(); @@ -124,6 +120,38 @@ const AdminPage = () => { }); setFilteredData(filtered); }; + const handleRegistration = (data: any) => { + const existingStudent = adminData.some( + (student) => + student.name === data.name || + student.studentid === parseInt(data.studentid) + ); + + if (existingStudent) { + alert("이미 등록된 데이터입니다."); + } else { + const newAdminData = [ + ...adminData, + { + checkbox: false, + name: data.name, + studentid: parseInt(data.studentid), + studentclass: data.studentclass, + chapel: parseInt(data.chapel), + chapelseat: data.chapelseat, + }, + ]; + setAdminData(newAdminData); + setFilteredData(newAdminData); + setShowRegistrationModal(false); + } + }; + + const handleCheckboxChange = (index: number) => { + const newData = [...adminData]; + newData[index].checkbox = !newData[index].checkbox; + setAdminData(newData); + }; return (
@@ -172,11 +200,7 @@ const AdminPage = () => { { - const newData = [...adminData]; - newData[index].checkbox = !newData[index].checkbox; - setAdminData(newData); - }} + onChange={() => handleCheckboxChange(index)} /> {data.name} {data.studentid} @@ -188,6 +212,57 @@ const AdminPage = () => { + + {showRegistrationModal && ( + + + 학생 등록 + + 이름: + + + + 학번: + + + + 학과: + + + + 채플: + + + + 좌석: + + + + + 등록 + + setShowRegistrationModal(false)} + > + 취소 + + + + + )} + + {showDeleteModal && ( + + + 정말로 삭제할까요? + + Yes + No + + + + )} + {showLogoutModal && ( @@ -199,46 +274,27 @@ const AdminPage = () => { )} - {showRegistrationModal && ( - - - 학생 등록 -
- - 이름: - - - - 학번: - - - - 학과: - - - - 채플: - - - - 좌석: - - - - 등록 - setShowRegistrationModal(false)}> - 취소 - - -
-
-
- )}
); }; export default AdminPage; + +const DeleteModal = styled.div` + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 30%; + padding: 20px; + background-color: white; + border: 1px solid #375cde; + border-radius: 10px; + display: flex; + flex-direction: column; + align-items: center; +`; + const RegistrationModal = styled.div` position: fixed; top: 50%; @@ -324,6 +380,15 @@ const ModalButton = styled.button` color: white; cursor: pointer; `; +const ModalButtonCancel = styled.button` + padding: 10px 20px; + margin: 0 10px; + border-radius: 5px; + border: none; + background-color: #375cde; + color: white; + cursor: pointer; +`; const AdminManagementBox = styled.div` display: flex; diff --git a/frontend/src/containers/LoginPage/LoginPage.tsx b/frontend/src/containers/LoginPage/LoginPage.tsx index 4489a82..ab03841 100644 --- a/frontend/src/containers/LoginPage/LoginPage.tsx +++ b/frontend/src/containers/LoginPage/LoginPage.tsx @@ -6,7 +6,7 @@ import { useState } from "react"; import axios from "axios"; const LoginPage = () => { - const [error, setError] = useState(""); + // const [error, setError] = useState(""); const signup = useNavigate(); // useNavigate 훅 사용 const { register, @@ -24,17 +24,41 @@ const LoginPage = () => { if (data.studentId === "admin" && data.password === "admin") { signup("/admin"); - } else { - try { - const response = await axios.post( - "http://isaacnas.duckdns.org:8083/user/login", - loginData - ); - if (response.status === 200) { - signup("/main"); + // if (data.studentId === "admin") { + // signup("/admin"); + } + try { + const response = await axios.post( + "http://isaacnas.duckdns.org:8083/user/login", + loginData, + { + headers: { + "Content-Type": "application/json", + }, } - } catch (error) { - setError("로그인에 실패했습니다. 다시 시도해주세요."); + ); + + console.log("서버 응답:", response); // 디버깅을 위해 콘솔에 출력 + + if (response.status === 200 || response.data.success) { + alert("로그인 되었습니다!"); + signup("/main"); + } else { + alert("로그인에 실패했습니다. 다시 시도해주세요."); + } + } catch (error: any) { + if (error.response) { + // 요청이 이루어졌고 서버가 2xx 범위 외의 상태 코드로 응답함 + console.error("Error response:", error.response.data); + alert(`로그인에 실패했습니다: ${error.response.data.message}`); + } else if (error.request) { + // 요청이 이루어졌지만 응답을 받지 못함 + console.error("Error request:", error.request); + alert("로그인 서버로부터 응답이 없습니다. 나중에 다시 시도해주세요."); + } else { + // 요청 설정 중 오류가 발생함 + console.error("Error message:", error.message); + alert("로그인 중 오류가 발생했습니다. 다시 시도해주세요."); } } }; @@ -78,7 +102,8 @@ const LoginPage = () => { value === "admin" || value === watch("studentId") || /^(?=.*[a-zA-Z])(?=.*[0-9]).{8,}$/.test(value) || - "영문+숫자 조합 8자 이상 입력해주세요.", + "비밀번호를 제대로 입력해주세요.", + // "영문+숫자 조합 8자 이상 입력해주세요.", })} /> {errors.password && ( @@ -153,6 +178,11 @@ const LoginBtn = styled.div` width: 100vw; min-width: 200px; max-width: 580px; + position: fixed; + bottom: 3%; + left: 50%; + transform: translateX(-50%); + z-index: 1; `; const SubmitButton = styled.button` diff --git a/frontend/src/containers/Mainpage/Mainpage.tsx b/frontend/src/containers/Mainpage/Mainpage.tsx index 31d2c32..1fa9dc9 100644 --- a/frontend/src/containers/Mainpage/Mainpage.tsx +++ b/frontend/src/containers/Mainpage/Mainpage.tsx @@ -1,3 +1,4 @@ +<<<<<<< HEAD //복사생성자 deep copy경우 2가지가 필요 (깊은 복사를 할수있게해야한다.) //{}연산자 ()연산자 꼭 알아야한다. //상속하는거와 다형성 부모타입으로 하는것을 추상화 객체타입을 부모타입으로 자식객체를 부모타입으로 (참조 and 포인터) @@ -10,6 +11,12 @@ import React, { useState, useEffect } from 'react'; import styled from 'styled-components'; import Nav from '../../components/NavBar'; import axios from 'axios'; +======= +import React, { useState, useEffect } from "react"; +import styled from "styled-components"; +import Nav from "../../components/NavBar"; +import axios from "axios"; +>>>>>>> 33c2d9c62bebf15d054d7dbbdc6d483124b20b2e const images = [ "https://pimg.hackers.com/land/main/land_default.jpg", @@ -32,6 +39,7 @@ const Mainpage = () => { return () => clearInterval(interval); // Cleanup function }, []); +<<<<<<< HEAD // const onSubmit = async (data: any) => { // if (NFC) { // return; @@ -71,6 +79,35 @@ const Mainpage = () => { const attendanceStatuses = ['present', 'absent', 'late']; // Updated to 3 statuses +======= + const onSubmit = async (data: any) => { + if (NFC) { + return; + } + + try { + const response = await axios.post( + "http://isaacnas.duckdns.org:8083/attendance/nfc", + { + mac_address: data.address, + nfc_position: data.position, + attendanceTime: new Date().toISOString(), // or any appropriate time format + }, + { + headers: { + Authorization: "Bearer your-auth-token", // Include your token here + }, + } + ); + console.log("Response:", response.data); //응답처리 + //응답 실패 + } catch (error) { + console.error(error); + } + }; + + const attendanceStatuses = ["present", "absent", "late"]; // Updated to 3 statuses +>>>>>>> 33c2d9c62bebf15d054d7dbbdc6d483124b20b2e const getColor = (status: string): string => { switch (status) { @@ -87,10 +124,17 @@ const Mainpage = () => { // Example data for buttons from the backend const buttonsData = [ +<<<<<<< HEAD { label: 'Menu 1' }, { label: 'Menu 2' }, { label: 'Menu 3' }, { label: 'Menu 4' }, +======= + { label: "Menu 1" }, + { label: "Menu 2" }, + { label: "Menu 3" }, + { label: "Menu 4" }, +>>>>>>> 33c2d9c62bebf15d054d7dbbdc6d483124b20b2e ]; const handleMenu1Click = () => { @@ -161,9 +205,9 @@ const Mainpage = () => { - - 채플현황 - + + 채플현황 + @@ -173,6 +217,7 @@ const Mainpage = () => { +<<<<<<< HEAD {buttonsData.map((button, index) => ( { ))} +======= + + {buttonsData.map((button, index) => ( + + onSubmit({ + address: "exampleAddress", + position: "examplePosition", + }) + : undefined + } + > + {button.label} + + ))} + + +>>>>>>> 33c2d9c62bebf15d054d7dbbdc6d483124b20b2e