From 1e083dd6fc85c2ed789fcdace8925aabe643741c Mon Sep 17 00:00:00 2001 From: hyuna Date: Thu, 4 Apr 2024 23:16:10 +0900 Subject: [PATCH] =?UTF-8?q?add=20:=20=EA=B5=90=EC=8B=A4=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/changeClass/index.ts | 49 +++- src/app/classChange/ok/page.tsx | 152 ++++++++++ src/app/classChange/page.tsx | 264 ++++++++++++------ .../common/list/changeClass/page.tsx | 56 +++- src/app/main/page.tsx | 4 +- 5 files changed, 416 insertions(+), 109 deletions(-) create mode 100644 src/app/classChange/ok/page.tsx diff --git a/src/apis/changeClass/index.ts b/src/apis/changeClass/index.ts index d378cab..8742468 100644 --- a/src/apis/changeClass/index.ts +++ b/src/apis/changeClass/index.ts @@ -1,6 +1,5 @@ import { instance } from ".."; import { useMutation } from "@tanstack/react-query"; -import { getToken } from "@/utils/auth"; interface changeClass { class_num: number; @@ -13,13 +12,24 @@ interface changeClass { username: string; } +interface FloorClass { + id: string; + class_num: number; + classroom_name: string; + end_period: number; + grade: number; + move: string; + num: number; + start_period: number; + username: string; +} + export const GetFloor = () => { return useMutation({ mutationFn: async (param) => { try { const response = await instance.get( - `/class-room/floor?floor=${param.floor}`, - + `/class-room/floor?floor=${param.floor}&status=OK` ); return response.data; } catch (error) { @@ -30,12 +40,26 @@ export const GetFloor = () => { }; export const ChangeClassList = () => { - return useMutation({ mutationFn: async (param) => { try { const response = await instance.get( - `/class-room/grade?grade=${param.grade}&classNum=${param.class}`, + `/class-room/grade?grade=${param.grade}&classNum=${param.class}` + ); + return response.data; + } catch (error) { + console.log(error); + } + }, + }); +}; + +export const AcceptClassChange = () => { + return useMutation({ + mutationFn: async (param) => { + try { + const response = await instance.get( + `/class-room/floor?floor=${param.floor}&status=QUIET` ); return response.data; } catch (error) { @@ -44,3 +68,18 @@ export const ChangeClassList = () => { }, }); }; + +export const AcceptClass = () => { + return useMutation({ + mutationFn: async (param) => { + try { + await instance.patch(`/class-room/status`, { + status: param.status, + ids: param.id, + }); + } catch (error) { + console.log(error); + } + }, + }); +}; diff --git a/src/app/classChange/ok/page.tsx b/src/app/classChange/ok/page.tsx new file mode 100644 index 0000000..8190628 --- /dev/null +++ b/src/app/classChange/ok/page.tsx @@ -0,0 +1,152 @@ +"use client"; +import React, { useEffect } from "react"; +import DoubleTab from "../../components/common/tab/page"; +import { getFullToday } from "@/utils/date"; +import { useState } from "react"; +import Dropdown from "../../components/common/dropdown"; +import ChangeClass from "../../components/common/list/changeClass/page"; +import { ChangeClassList, GetFloor } from "@/apis/changeClass"; +import { getStudentString } from "@/utils/until"; +import { BackGround } from "../../components/common/background"; +import Link from "next/link"; + +interface changeClass { + class_num: number; + classroom_name: string; + floor: number; + grade: number; + id: string; + num: number; + user_id: string; + username: string; +} + +const ClassChangeOk = () => { + const [selectedTab, setSelectedTab] = useState(true); + const [selectedGrade, setSelectedGrade] = useState(1); + const [selectedClass, setSelectedClass] = useState(1); + const { mutate: changelistMutate } = ChangeClassList(); + const [floorData, setFloorData] = useState([]); + const { mutate: changelistFloorMutate } = GetFloor(); + const [changelist, setChangelist] = useState([]); + const [selectedFloor, setSelectedFloor] = useState(2); + + const onClickTab = (tab: boolean) => { + setSelectedTab(tab); + }; + + const handleGradeChange = (selectedOption: number) => { + setSelectedGrade(selectedOption); + }; + + const handleClassChange = (selectedOption: number) => { + setSelectedClass(selectedOption); + }; + + const handleFloorChange = (selectedOption: number) => { + setSelectedFloor(selectedOption); + }; + + useEffect(() => { + changeClassData(); + }, [selectedGrade, selectedClass]); + + useEffect(() => { + ChangeClassDataFloor(); + }, [selectedFloor]); + + useEffect(() => { + changeClassData(); + }, []); + + const ChangeClassDataFloor = async () => { + try { + if (selectedFloor) { + await changelistFloorMutate( + { floor: selectedFloor }, + { + onSuccess: (data) => { + setFloorData(data); + }, + onError: (error) => { + console.log(error); + }, + } + ); + } + } catch (error) { + console.log(error); + } + }; + + const changeClassData = async () => { + try { + if (selectedClass && selectedGrade) { + await changelistMutate( + { grade: selectedGrade, class: selectedClass }, + { + onSuccess: (data) => { + console.log(data); + setChangelist(data); + }, + } + ); + } + } catch (error) { + console.log(error); + } + }; + + return ( + + 교실 이동 수락 > 교실 이동 현황 + + } + DropChildren={ + <> + +
+ {selectedTab ? ( + <> + + + + ) : ( + + )} +
+ + } + > +
+ {selectedTab + ? changelist?.map((item, index) => ( + + )) + : floorData?.map((item, index) => ( + + ))} +
+
+ ); +}; + +export default ClassChangeOk; diff --git a/src/app/classChange/page.tsx b/src/app/classChange/page.tsx index 60d3284..734ddd3 100644 --- a/src/app/classChange/page.tsx +++ b/src/app/classChange/page.tsx @@ -1,96 +1,132 @@ "use client"; -import React, { useEffect } from "react"; -import DoubleTab from "../components/common/tab/page"; import { getFullToday } from "@/utils/date"; -import { useState } from "react"; +import { BackGround } from "../components/common/background"; +import { AcceptClass, AcceptClassChange } from "@/apis/changeClass"; import Dropdown from "../components/common/dropdown"; +import { useEffect, useState } from "react"; +import Button from "../components/common/Button"; +import { useRouter } from "next/navigation"; import ChangeClass from "../components/common/list/changeClass/page"; -import { ChangeClassList, GetFloor } from "@/apis/changeClass"; import { getStudentString } from "@/utils/until"; -import { BackGround } from "../components/common/background"; +import Modal from "../components/common/modal/page"; -interface changeClass { +interface FloorClass { + id: string; class_num: number; classroom_name: string; - floor: number; + end_period: number; grade: number; - id: string; + move: string; num: number; - user_id: string; + start_period: number; username: string; } -const OutList = () => { - const [selectedTab, setSelectedTab] = useState(true); - const [selectedGrade, setSelectedGrade] = useState(1); - const [selectedClass, setSelectedClass] = useState(1); - const { mutate: changelistMutate } = ChangeClassList(); - const [floorData, setFloorData] = useState([]); - const { mutate: changelistFloorMutate } = GetFloor(); - const [changelist, setChangelist] = useState([]); +const ClassChange = () => { const [selectedFloor, setSelectedFloor] = useState(2); + const [data, setData] = useState([]); + const [accept, setAccept] = useState(false); + const [refuse, setRefuse] = useState(false); + const [selectedStudents, setSelectedStudents] = useState([]); + const [selectedStudentName, setSelectedStudentName] = useState([]); + + const { mutate: AccpetMutate } = AcceptClassChange(); + const { mutate: AccpetList } = AcceptClass(); - const onClickTab = (tab: boolean) => { - setSelectedTab(tab); + const Accept = async () => { + setAccept(true); }; - const handleGradeChange = (selectedOption: number) => { - setSelectedGrade(selectedOption); + const Refuse = () => { + setRefuse(true); }; - const handleClassChange = (selectedOption: number) => { - setSelectedClass(selectedOption); + const handleAcceptListClick = (id: string, name: string) => { + const isStudentSelected = selectedStudents.includes(id); + if (isStudentSelected) { + setSelectedStudents((prevSelectedStudents) => + prevSelectedStudents.filter((selectedStudent) => selectedStudent !== id) + ); + setSelectedStudentName((prevSelectedStudentName) => + prevSelectedStudentName.filter( + (selectedStudentName) => selectedStudentName !== name + ) + ); + } else { + setSelectedStudents((prevSelectedStudents) => [ + ...prevSelectedStudents, + id, + ]); + setSelectedStudentName((prevSelectedStudentName) => [ + ...prevSelectedStudentName, + name, + ]); + } }; - const handleFloorChange = (selectedOption: number) => { - setSelectedFloor(selectedOption); + const Accpet = async () => { + try { + await AccpetMutate( + { floor: selectedFloor }, + { + onSuccess: (data) => { + setData(data); + }, + onError: (error) => { + alert(error.name); + }, + } + ); + } catch (error) { + console.log(error); + } }; - useEffect(() => { - changeClassData(); - }, [selectedGrade, selectedClass]); + const nav = useRouter(); useEffect(() => { - ChangeClassDataFloor(); + Accpet(); }, [selectedFloor]); - useEffect(() => { - changeClassData(); - }, []); + const handleFloorChange = (selectedOption: number) => { + setSelectedFloor(selectedOption); + }; - const ChangeClassDataFloor = async () => { + const closeModal = () => { + setRefuse(false); + }; + + const AcceptrCancel = () => { + setAccept(false); + }; + + const confirmReturn = async () => { try { - if (selectedFloor) { - await changelistFloorMutate( - { floor: selectedFloor }, - { - onSuccess: (data) => { - setFloorData(data); - }, - onError: (error) => { - console.log(error); - }, - } - ); - } + await AccpetList( + { status: "NO", id: selectedStudents }, + { + onSuccess: () => { + location.reload(); + alert("교실이동이 거절되었습니다."); + }, + } + ); } catch (error) { console.log(error); } }; - const changeClassData = async () => { + const Acceptconfirm = async () => { try { - if (selectedClass && selectedGrade) { - await changelistMutate( - { grade: selectedGrade, class: selectedClass }, - { - onSuccess: (data) => { - console.log(data); - setChangelist(data); - }, - } - ); - } + await AccpetList( + { status: "OK", id: selectedStudents }, + { + onSuccess: () => { + location.reload(); + alert("교실이동이 수락되었습니다"); + }, + } + ); } catch (error) { console.log(error); } @@ -98,50 +134,94 @@ const OutList = () => { return ( - -
- {selectedTab ? ( - <> - - - - ) : ( - - )} +
+ +
} > -
- {selectedTab - ? changelist?.map((item, index) => ( - - )) - : floorData?.map((item, index) => ( - - ))} + {data?.map((item, index) => ( + handleAcceptListClick(item.id, item.username)} + prevClass={`${item.grade}-${item.class_num}`} + nextClass={`${item.classroom_name}`} + student={getStudentString(item)} + /> + ))} +
+ +
+ {refuse && ( + 1 + ? `${selectedStudentName[0]} 학생 외 ${ + selectedStudentName.length - 1 + }명` + : selectedStudentName.length === 1 + ? `${selectedStudentName[0]} 학생` + : "" + }`} + heading2={`교실이동을 거절하시겠습니까?`} + type="error" + buttonMessage="거절" + onCancel={closeModal} + onConfirm={confirmReturn} + /> + )} + {accept && ( + 1 + ? `${selectedStudentName[0]} 학생 외 ${ + selectedStudentName.length - 1 + }명` + : selectedStudentName.length === 1 + ? `${selectedStudentName[0]} 학생` + : "" + }`} + heading2={`교실이동을 수락하시겠습니까?`} + type="button" + buttonMessage="수락" + onCancel={AcceptrCancel} + onConfirm={Acceptconfirm} + /> + )} ); }; -export default OutList; +export default ClassChange; diff --git a/src/app/components/common/list/changeClass/page.tsx b/src/app/components/common/list/changeClass/page.tsx index 1982719..e82758e 100644 --- a/src/app/components/common/list/changeClass/page.tsx +++ b/src/app/components/common/list/changeClass/page.tsx @@ -1,26 +1,60 @@ +"use client"; import Image from "next/image"; -import React from "react"; +import React, { useState } from "react"; import nextArrow from "@/assets/img/Icon/arrow-narrow-right.svg"; -interface changeClassProp { +interface ChangeClassProps { student: string; prevClass: string; nextClass: string; + type?: "accept"; + onClick?: () => void; } -const ChangeClass: React.FC = ({ + +const ChangeClass: React.FC = ({ student, prevClass, nextClass, + type, + onClick, }) => { + const [isActive, setIsActive] = useState(false); + + const handleClick = () => { + console.log(isActive); + setIsActive(!isActive); + onClick?.(); + }; + return ( -
-
{student}
-
- {prevClass} - - {nextClass} -
-
+ <> + {type === "accept" ? ( +
+
{student}
+
+ {prevClass} + + {nextClass} +
+
+ ) : ( +
+
{student}
+
+ {prevClass} + + {nextClass} +
+
+ )} + ); }; diff --git a/src/app/main/page.tsx b/src/app/main/page.tsx index fb2573f..f420336 100644 --- a/src/app/main/page.tsx +++ b/src/app/main/page.tsx @@ -9,7 +9,6 @@ import WeekendMeals from "../../assets/img/Icon/주말급식.svg"; import classManage from "../../assets/img/Icon/학급관리.svg"; import afterManage from "../../assets/img/Icon/방과후관리.svg"; import notice from "../../assets/img/Icon/공지사항.svg"; -import studentInquiry from "../../assets/img/Icon/학생조회.svg"; import changeTeacher from "../../assets/img/Icon/자습감독선생님변경.svg"; import schedule from "../../assets/img/Icon/일정변경.svg"; import outStudent from "../../assets/img/외출 일러스트.png"; @@ -122,6 +121,9 @@ const Main = () => { 학급 관리 + + 출결 + 방과후 관리