diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..06b1517 --- /dev/null +++ b/.mcp.json @@ -0,0 +1,11 @@ +{ + "mcpServers": { + "figma": { + "command": "npx", + "args": ["-y", "figma-developer-mcp", "--stdio"], + "env": { + "FIGMA_ACCESS_TOKEN": "${FIGMA_ACCESS_TOKEN}" + } + } + } +} diff --git a/src/App.jsx b/src/App.jsx index f133bd5..75785ba 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -7,6 +7,7 @@ import RecruitPage from '@/pages/visitor/RecruitPage'; import SchedulePage from '@/pages/visitor/SchedulePage'; import AboutPage from '@/pages/visitor/AboutPage'; import AdminPage from '@/pages/admin/AdminPage'; +import RecruitManagePage from '@/pages/admin/RecruitManagePage'; import MemberPage from '@/pages/admin/MemberPage'; import MemberRegisterPage from '@/pages/admin/MemberRegisterPage'; import MemberEditPage from '@/pages/admin/MemberEditPage'; @@ -21,6 +22,7 @@ function App() { } /> } /> } /> + } /> } /> {/* admin 명부 관리: 방문자 Layout(Header/Footer) 없이 렌더 */} diff --git a/src/assets/images/Date_today_duotone_line1.svg b/src/assets/images/Date_today_duotone_line1.svg new file mode 100644 index 0000000..5916303 --- /dev/null +++ b/src/assets/images/Date_today_duotone_line1.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/images/Date_today_duotone_line2.svg b/src/assets/images/Date_today_duotone_line2.svg new file mode 100644 index 0000000..4206f9d --- /dev/null +++ b/src/assets/images/Date_today_duotone_line2.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/images/User1.svg b/src/assets/images/User1.svg new file mode 100644 index 0000000..93a38b8 --- /dev/null +++ b/src/assets/images/User1.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/User2.svg b/src/assets/images/User2.svg new file mode 100644 index 0000000..7af5623 --- /dev/null +++ b/src/assets/images/User2.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/search.svg b/src/assets/images/search.svg new file mode 100644 index 0000000..89f0091 --- /dev/null +++ b/src/assets/images/search.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/components/layout/Header.jsx b/src/components/layout/Header.jsx index 81e2918..1354831 100644 --- a/src/components/layout/Header.jsx +++ b/src/components/layout/Header.jsx @@ -1,17 +1,69 @@ -import { Link } from 'react-router-dom'; +import { NavLink } from 'react-router-dom'; + import { ROUTES } from '@/constants/routes'; +import { COLORS } from '@/constants/theme'; +import calendarBlackIcon from '@/assets/images/Date_today_duotone_line1.svg'; //검정 아이콘 +import calendarOrangeIcon from '@/assets/images/Date_today_duotone_line2.svg'; //주황 아이콘 + +import userBlackIcon from '@/assets/images/User1.svg'; //검정 아이콘 +import userOrangeIcon from '@/assets/images/User2.svg'; //주황 아이콘 function Header() { return ( - - - ONE - 동아리 소개 - 연간 계획 - 모집 신청 + + + + {({ isActive }) => ( + + + + + 연간 계획 + + + )} + + + + {({ isActive }) => ( + + + + + 신입 부원 모집 + + + )} + ); } -export default Header; +export default Header; \ No newline at end of file diff --git a/src/constants/routes.js b/src/constants/routes.js index eed8b07..51068ef 100644 --- a/src/constants/routes.js +++ b/src/constants/routes.js @@ -8,6 +8,7 @@ export const ROUTES = { SCHEDULE: '/schedule', ABOUT: '/about', ADMIN: '/admin', + ADMIN_RECRUIT: '/admin/Memberpage', // 명부 관리: 외부에 노출하지 않는 admin 히든 경로 하위에 둔다. 방문자 내비에 링크하지 않는다. ADMIN_MEMBER: '/admin/members', // 부원 등록: 명부 관리에서 '부원 등록' 클릭 시 이동하는 폼 화면. diff --git a/src/constants/theme.js b/src/constants/theme.js index 61137ee..a69957c 100644 --- a/src/constants/theme.js +++ b/src/constants/theme.js @@ -7,6 +7,7 @@ export const COLORS = { primary: '#3B82F6', primaryDark: '#1E40AF', secondary: '#F59E0B', + orange: '#FF6B00', // 상단바 및 주요 액션 색상 (Figma 추출) background: '#FFFFFF', surface: '#F3F4F6', textPrimary: '#1F2937', diff --git a/src/pages/admin/AdminPage.jsx b/src/pages/admin/AdminPage.jsx index 6a8b0c0..9a9173d 100644 --- a/src/pages/admin/AdminPage.jsx +++ b/src/pages/admin/AdminPage.jsx @@ -7,4 +7,4 @@ function AdminPage() { ); } -export default AdminPage; +export default AdminPage; \ No newline at end of file diff --git a/src/pages/admin/RecruitManagePage.jsx b/src/pages/admin/RecruitManagePage.jsx new file mode 100644 index 0000000..99070d3 --- /dev/null +++ b/src/pages/admin/RecruitManagePage.jsx @@ -0,0 +1,223 @@ +import { useState } from 'react'; +import memberGroupIcon from '@/assets/images/member-group.svg'; +import searchIcon from '@/assets/images/search.svg'; + +const APPLICANTS = [ + { + id: 1, + name: '최현우', + studentId: '20301234', + department: '웹응용소프트웨어학과', + birthDate: '2025.01.01', + grade: '2', + gender: '남', + phone: '010-1111-2222', + appliedAt: '2026.08.08', + motivation: '동아리 활동을 하며 실무경험을 길러 보고 싶어 지원하게 되었습니다.', + usedTool: 'React, Figma', + goal: '프로젝트 경험 쌓기', + lastWord: '잘 부탁드립니다.', + isNew: false, + }, + { + id: 2, + name: '최현우', + studentId: '20301234', + department: '웹응용소프트웨어학과', + birthDate: '2025.01.01', + grade: '2', + gender: '남', + phone: '010-1111-2222', + appliedAt: '2026.08.08', + motivation: '프로젝트를 함께 진행하며 성장하고 싶습니다.', + usedTool: 'JavaScript', + goal: '협업 능력 향상', + lastWord: '열심히 하겠습니다.', + isNew: false, + }, + { + id: 3, + name: '최현우', + studentId: '20301234', + department: '웹응용소프트웨어학과', + birthDate: '2025.01.01', + grade: '2', + gender: '남', + phone: '010-1111-2222', + appliedAt: '2026.08.08', + motivation: '프론트엔드 개발 경험을 쌓고 싶어 지원했습니다.', + usedTool: 'HTML, CSS', + goal: '웹 프로젝트 참여', + lastWord: '잘 부탁드립니다.', + isNew: false, + }, + { + id: 4, + name: '최현우', + studentId: '20301234', + department: '웹응용소프트웨어학과', + birthDate: '2025.01.01', + grade: '2', + gender: '남', + phone: '010-1111-2222', + appliedAt: '2026.08.08', + motivation: '팀 프로젝트에서 맡은 역할을 책임감 있게 수행하고 싶습니다.', + usedTool: 'React', + goal: '실무 경험 확보', + lastWord: '최선을 다하겠습니다.', + isNew: true, + }, + { + id: 5, + name: '최현우', + studentId: '20301234', + department: '웹응용소프트웨어학과', + birthDate: '2025.01.01', + grade: '2', + gender: '남', + phone: '010-1111-2222', + appliedAt: '2026.08.08', + motivation: '동아리 활동을 통해 협업과 개발 역량을 키우고 싶습니다.', + usedTool: 'Figma', + goal: '포트폴리오 제작', + lastWord: '잘 부탁드립니다.', + isNew: true, + }, +]; + +const TD_CLASS = + 'h-[89px] border-b border-line text-[20px] font-normal text-ink'; + +function RecruitManagePage() { + const [selectedApplicant, setSelectedApplicant] = useState(null); + + const handleOpenDetail = (applicant) => setSelectedApplicant(applicant); + const handleCloseDetail = () => setSelectedApplicant(null); + + return ( + + + + + {/* 아이콘 + 총 N명을 세로로 묶기 */} + + + + 총 {APPLICANTS.length}명 + + + 신청 부원 조회 + + + 최근 1년 동안 신청한 부원의 정보만 조회가능합니다 + + + + + + + + {['NO', '이름', '학번', '전화번호', '신청날짜', '정보조회'].map((col) => ( + + {col} + + ))} + + + + + {APPLICANTS.map((applicant) => ( + + + + {applicant.id} + {applicant.isNew && ( + + N + + )} + + + + {applicant.name} + {applicant.studentId} + {applicant.phone} + {applicant.appliedAt} + + handleOpenDetail(applicant)} + > + + + + + ))} + + + + + + + + + + + 1 + 2 + 3 + 4 + + + + + + + + + {selectedApplicant && ( + + e.stopPropagation()} + > + + × + + + + {[ + ['이름', selectedApplicant.name], + ['학번', selectedApplicant.studentId], + ['학과', selectedApplicant.department], + ['생년월일', selectedApplicant.birthDate], + ['전화번호', selectedApplicant.phone], + ['학년', selectedApplicant.grade], + ['성별', selectedApplicant.gender], + ['지원동기', selectedApplicant.motivation], + ['사용해봤거나 들어본 언어 및 라이브러리', selectedApplicant.usedTool], + ['동아리에서 해 보고 싶은 것', selectedApplicant.goal], + ['마지막으로 하고 싶은 말', selectedApplicant.lastWord], + ].map(([label, value]) => ( + + {label} + {value} + + ))} + + + + )} + + ); +} + +export default RecruitManagePage; \ No newline at end of file diff --git a/tailwind.config.js b/tailwind.config.js index 9ee0595..7a7473f 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -27,6 +27,10 @@ export default { // 신청 부원 목록 모달. modal: '30px', }, + boxShadow: { + // 명부 관리/신청 부원 카드 그림자 (시안 실측). + card: '0 4px 4px rgba(0,0,0,0.25)', + }, // 부원 상태 배지 너비(시안 실측 150px). minWidth: { badge: '150px',
+ 총 {APPLICANTS.length}명 +
+ 최근 1년 동안 신청한 부원의 정보만 조회가능합니다 +