diff --git a/client/src/app/leader/retreat-attendance-for-same-age/RetreatAttendanceCard.tsx b/client/src/app/leader/retreat-attendance-for-same-age/RetreatAttendanceCard.tsx new file mode 100644 index 00000000..af1b311d --- /dev/null +++ b/client/src/app/leader/retreat-attendance-for-same-age/RetreatAttendanceCard.tsx @@ -0,0 +1,95 @@ +"use client" + +import { Chip, Stack, Typography, Box } from "@mui/material" +import { User } from "@server/entity/user" +import CheckCircleIcon from "@mui/icons-material/CheckCircle" +import CancelIcon from "@mui/icons-material/Cancel" +import SchoolIcon from "@mui/icons-material/School" +import WorkIcon from "@mui/icons-material/Work" +import AccessTimeIcon from "@mui/icons-material/AccessTime" +import EventAvailableIcon from "@mui/icons-material/EventAvailable" + +interface RetreatAttendanceCardProps { + soon: User +} + +export default function RetreatAttendanceCard({ + soon, +}: RetreatAttendanceCardProps) { + const isRegistered = !!soon.retreatAttend && !soon.retreatAttend.isCanceled + + return ( + + + + + {soon.name} + + + {soon.yearOfBirth} + + + + {isRegistered ? ( + + + ) : ( + + ) + } + sx={{ borderRadius: "6px" }} + /> + : + } + sx={{ borderRadius: "6px" }} + /> + + ) : ( + + 수련회 미신청 + + )} + + + + {isRegistered ? ( + + + + 신청완료 + + + ) : ( + + + + 미신청 + + + )} + + + ) +} diff --git a/client/src/app/leader/retreat-attendance-for-same-age/page.tsx b/client/src/app/leader/retreat-attendance-for-same-age/page.tsx new file mode 100644 index 00000000..813029ba --- /dev/null +++ b/client/src/app/leader/retreat-attendance-for-same-age/page.tsx @@ -0,0 +1,37 @@ +"use client" + +import axios from "@/config/axios" +import { Stack } from "@mui/material" +import { User } from "@server/entity/user" +import { useEffect, useState } from "react" +import RetreatAttendanceCard from "./RetreatAttendanceCard" + +export default function RetreatAttendancePage() { + const [soonList, setSoonList] = useState([]) + useEffect(() => { + fetchSoonList() + }, []) + + async function fetchSoonList() { + try { + const response = await axios.get( + "/retreat/retreat-attendance-records-for-same-age", + ) + setSoonList(response.data) + } catch (error) { + console.error("Failed to fetch soon list:", error) + } + } + + return ( + + + {soonList.map((soon) => ( + + + + ))} + + + ) +} diff --git a/client/src/app/leader/retreat-attendance/page.tsx b/client/src/app/leader/retreat-attendance/page.tsx index eceead44..482e6ea2 100644 --- a/client/src/app/leader/retreat-attendance/page.tsx +++ b/client/src/app/leader/retreat-attendance/page.tsx @@ -15,7 +15,7 @@ export default function RetreatAttendancePage() { async function fetchSoonList() { try { const response = await axios.get( - "/soon/retreat-attendance-records" + "/soon/retreat-attendance-records", ) setSoonList(response.data) } catch (error) { diff --git a/client/src/components/Header/index.tsx b/client/src/components/Header/index.tsx index 66fbeae4..bbbae74f 100644 --- a/client/src/components/Header/index.tsx +++ b/client/src/components/Header/index.tsx @@ -84,6 +84,13 @@ export default function Header() { type: "menu", }) + DrawerItems.push({ + title: "동기 수련회 접수 조회", + icon: , + path: "/leader/retreat-attendance-for-same-age", + type: "menu", + }) + if (authUserData?.role.VillageLeader) { DrawerItems.push({ title: "전체 출석 조회", diff --git a/server/src/routes/retreat/retreatRouter.ts b/server/src/routes/retreat/retreatRouter.ts index 87578b6b..8e5a9d35 100644 --- a/server/src/routes/retreat/retreatRouter.ts +++ b/server/src/routes/retreat/retreatRouter.ts @@ -4,7 +4,7 @@ import { retreatAttendDatabase, userDatabase, } from "../../model/dataSource" -import { getUserFromToken } from "../../util/util" +import { checkJwt, getUserFromToken } from "../../util/util" import adminRouter from "./adminRouter" import sharingRouter from "./sharingRouter" import { getKakaoIdFromAccessToken } from "../../util/auth" @@ -186,6 +186,43 @@ router.get("/isRegistered", async (req, res) => { res.send({ result: foundUser ? "success" : "fail" }) }) +router.get("/retreat-attendance-records-for-same-age", async (req, res) => { + const user = await checkJwt(req) + if (!user) { + res.status(401).send({ error: "Unauthorized" }) + return + } + if (!user.role.Leader) { + res.status(403).send({ error: "Forbidden" }) + return + } + + let attendDataList = await userDatabase.find({ + where: { + yearOfBirth: user.yearOfBirth, + }, + select: { + id: true, + name: true, + yearOfBirth: true, + gender: true, + phone: true, + retreatAttend: { + id: true, + isWorker: true, + isHalf: true, + createAt: true, + isCanceled: true, + }, + }, + relations: { + retreatAttend: true, + }, + }) + + res.status(200).send(attendDataList) +}) + router.use("/sharing", sharingRouter) router.use("/admin", adminRouter)