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)