From 4a164879929c491c3fc402f94d772b8fbaf208b5 Mon Sep 17 00:00:00 2001
From: llddang <77055208+llddang@users.noreply.github.com>
Date: Fri, 29 Nov 2024 18:34:25 +0900
Subject: [PATCH] =?UTF-8?q?Feature/#227=20=ED=94=84=EB=A1=A0=ED=8A=B8=20?=
=?UTF-8?q?=ED=8F=B4=EB=8D=94=20=EA=B5=AC=EC=A1=B0=20=EC=88=98=EC=A0=95=20?=
=?UTF-8?q?(#228)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* refactor: formik 컴포넌트 위치 이동
* feat: Footer styled components 대신 tailwind로 작성 및 위치 이동
* feat: IconButton tailwind 로 변경 및 컴포넌트 위치 이동
* refactor: footer 폴더 위치 이동
* design: items-content:center 에서 justify-content: center 로 수정
* feat: Header 컴포넌트 styled component가 아닌 tailwind css사용하도록 수정 및 폴더 위치 이동
* feat: 홈페이지에서 사용되는 GoPageIcon 폴더 위치 이동 및 tailwind css 적용
* refactor: MarkdownViewer 폴더 위치 이동
* refactor: PageTitle 컴포넌트 위치 이동
* feat: 팀 빌딩 카드 컴포넌트 위치 이동 및 css 라이브러리 교체
* feat: SignPageTabButton 컴포넌트 폴더위치 이동
* feat: PageSubTitle 컴포넌트 폴더 위치 이동
* feat: SearchBox 폴더 위치 이동
* feat: MilestoneOverviewTable 파일 이동 및 css 라이브러리 교체
* feat: PeriodSearchBox 폴더 위치 이동 및 css 라이브러리 교체
* feat: MilestoneGroupLabel 폴더 위치 이동
* feat: MilestoneCircleChart 폴더 이동 및 css 라이브러리 교체
* refactor: components 폴더명 수정
* refactor: 중복되는 컴포넌트 삭제
* refactor: Pagination 폴더 위치 이동
* feat: 홈화면의 공지사항 폴더 위치 이동 및 css 라이브러리 교체
* feat: 홈의 외부 링크 폴더 위치 이동 및 css 라이브러리 교체
* feat: 홈화면의 팀빌딩 세션 폴더 위치 이동 및 css 라이브러리 교체
#227
* feat: 홈화면의 로그인 세션 폴더 위치 이동 및 css 라이브러리 변경
#227
* feat: 사이드바 폴더 위치 이동 및 css 라이브러리 수정
#227
* refactor: 함수 선언 방식 변경 (Arrow -> Named Function)
#227
* feat: 홈 화면의 pnuLink 세션 폴더 위치 이동 및 css 라이브러리 변경
#227
* feat: 홈 화면의 마일스톤 폴더 위치 이동 및 css 라이브러리 변경
#227
* feat: 홈 화면의 css 라이브러리 변경
#227
* feat: milestone 폴더 구조 변경 및 css 라이브러리 변정
#227
* fix: map 관련하여 key 오류가 나지 않도록 수정
#227
* design: 사이드바가 있는 layout 수정
#227
* refactor: milestone status label 컴포넌트 경로 이동 및 리펙토링
#227
* design: 마이페이지의 마일스톤 실적 컴포넌트 경로 이동 및 디자인 수정
#227
* refactor: 마일스톤 상태 라벨 컴포넌트 추가
#227
* refactor: 마일스톤 상세 테이블 및 마이페이지의 마일스톤 세션 폴더 이동
#227
* refactor: 마이페이지의 학생 정보 세션 폴더 이동
#227
* refactor: 함수 선언 방식 변경 및 마일스톤 overview 컴포넌트 위치 이동
#227
* refactor: 함수 선언 방식 및 내 정보 수정 페이지 이동
#227
* refactor: 함수 선언 방식 변경 및 마이페이지의 마일스톤 상세 내역 폴더 위치 이동
#227
* refactor: 마일스톤 내역 테이블 컴포넌트
#227
* fix: 더이상 사용되지 않는 환경 설정 변경 (images.domains -> images.remotePatterns)
#227
* refactor: 마일스톤 내역 테이블의 명 변경 (MilestoneHistoryTable -> MilestoneAcceptedTable)
#227
* refactor: 마일스톤 실적 등록 내역
#227
* refactor: 마일스톤 내역 삭제 버튼
#227
* refactor: 마일스톤 카테고리 드롭다운 컴포넌트
#227
* refactor: 마이페이지의 모든 페이지들 폴더 변경 및 함수 선언 방식 등 변경
#227
* feat: textInput에 툴팁 기능 추가
#227
* feat: dataPicker에 key 값 추가
#227
* refactor: 팀빌딩 페이지
#227
* refactor: 해커톤 페이지
#227
* refactor: 아이디/비밀번호 찾는 페이지의 tabButton 렌더 방식 및 컴포넌트 명 변경
#227
* refactor: 아이디,비밀번호 찾는 페이지의 footer 컴포넌트
#227
* feat: 비밀번호를 찾는 페이지의 form
#227
* refactor: 로그인 form 컴포넌트
#227
* refactor: 로그인 페이지
#227
* refactor: 아이디 비밀번호 찾는 페이지
#227
* refactor: 로그인 폼 css 라이브러리 변경
#227
* refactor: 로그아웃 페이지
#227
* refactor: 회원가입 페이지
#227
* refactor: 필요없는 style 파일 제거
#227
* refactor: 어드민 헤더
#227
* refactor: 관리자 페이지의 사이드바
#227
* refactor: 관리자 페이지의 레이아웃
#227
* refactor: 관리자 페이지의 페이지네이션 컴포넌트
#227
* refactor: 관리자페이지의 검색 박스 컴포넌트
#227
* refactor: 관리자 페이지에서 교직원 목록 페이지 및 관련 컴포넌트
#227
* refactor: 클라이언트의 레이아웃
#227
* design: 홈화면의 로그인 세션의 input의 placehold 스타일 통일
#227
* design: textInput에서 value가 남아 있는 오류 해결
#227
* refactor: 교직원 등록 페이지
#227
* refactor: 관리자페이지의 학생 목록 페이지 및 관련 컴포넌트
#227
* refactor: 관리자의 팀빌딩 페이지
#227
* refactor: 관리자의 마일스톤 등록 및 랭킹 페이지
#227
* refactor: 마일스톤 목록와 상세 페이지 및 관련 컴포넌트
#227
* chore: eslint에서 airbnb 문법 없앰
#227
* feat: 빌드 에러 및 워닝 해결
#227
---
frontend/.babelrc | 4 -
frontend/.eslintrc.json | 56 +-
frontend/babel.config.json | 9 -
frontend/next.config.mjs | 16 +-
frontend/package-lock.json | 478 ++++++++----------
frontend/package.json | 10 +-
frontend/src/adminComponents/Footer/index.tsx | 16 -
.../Header/components/Navigator/index.tsx | 31 --
.../Header/components/Navigator/styled.ts | 32 --
.../Header/components/UserName/index.tsx | 16 -
frontend/src/adminComponents/Header/index.tsx | 32 --
frontend/src/adminComponents/Header/styled.ts | 33 --
.../src/adminComponents/Sidebar/index.tsx | 53 --
.../src/adminComponents/Sidebar/styled.ts | 51 --
frontend/src/adminConstants.ts | 61 ---
.../(auth)/components/FindFooter/index.tsx | 18 -
.../src/app/(client)/(auth)/find-id/page.tsx | 70 ++-
.../(client)/(auth)/find-password/page.tsx | 43 +-
.../components/InputUserInfo/index.tsx | 81 ---
.../src/app/(client)/(auth)/sign-in/page.tsx | 46 +-
.../src/app/(client)/(auth)/sign-in/styled.ts | 59 ---
.../src/app/(client)/(auth)/sign-out/page.tsx | 22 +-
.../components/EmailTextInput/index.tsx | 50 --
.../components/SignUpSecondPage/index.tsx | 133 -----
.../src/app/(client)/(auth)/sign-up/page.tsx | 24 +-
frontend/src/app/(client)/(auth)/styled.ts | 69 ---
.../vote/components/ReadmeViewer/index.tsx | 15 -
.../src/app/(client)/(withSidebar)/layout.tsx | 15 -
.../(client)/(withSidebar)/milestone/page.tsx | 55 --
.../(withSidebar)/milestone/styled.ts | 63 ---
.../components/MilestoneRowBarTable/index.tsx | 30 --
.../StudentInfoLabel/index.tsx | 14 -
.../components/MilestoneDetail/styled.ts | 62 ---
.../MilestoneHistoryTable/styled.ts | 31 --
.../components/MilestoneOverview/styled.ts | 10 -
.../my-page/milestone/register/page.tsx | 22 -
.../(withSidebar)/my-page/milestone/styled.ts | 18 -
.../(client)/(withSidebar)/my-page/page.tsx | 18 -
.../src/app/(client)/(withSidebar)/styled.ts | 33 --
.../components/Announcement/index.tsx | 33 --
.../components/Announcement/styled.ts | 35 --
.../components/ExternalLink/index.tsx | 23 -
.../components/ExternalLink/styled.ts | 44 --
.../(client)/components/GoPageIcon/index.tsx | 28 -
.../(client)/components/Milestone/styled.ts | 11 -
.../(client)/components/PageTitle/index.tsx | 27 -
.../app/(client)/components/PnuLink/styled.ts | 34 --
.../app/(client)/components/Sidebar/index.tsx | 82 ---
.../app/(client)/components/Sidebar/styled.ts | 120 -----
.../SignIn/components/InputUserInfo/index.tsx | 73 ---
.../SignIn/components/InputUserInfo/styled.ts | 46 --
.../app/(client)/components/SignIn/index.tsx | 21 -
.../app/(client)/components/SignIn/styled.ts | 47 --
.../components/TeamBuildings/index.tsx | 42 --
.../components/TeamBuildings/styled.ts | 56 --
.../src/app/(client)/components/styled.ts | 25 -
.../HackathonInformationTypeButtons/index.tsx | 0
.../hackathon/[slug]/layout.tsx | 4 +-
.../hackathon/[slug]/page.tsx | 2 +-
.../hackathon/[slug]/prize/page.tsx | 0
.../HackathonTeamCreateModal/index.tsx | 8 +-
.../HackathonTeamReadModal/index.tsx | 4 +-
.../vote/components/ReadmeViewer/index.tsx | 25 +
.../TeamCreateInputSection/index.tsx | 0
.../vote/components/TeamMemberInput/index.tsx | 4 +-
.../hackathon/[slug]/vote/page.tsx | 2 +-
.../src/app/(client)/hackathon/layout.tsx | 5 +
.../{(withSidebar) => }/hackathon/page.tsx | 6 +-
.../hackathon/sw-contest/page.tsx | 4 +-
frontend/src/app/(client)/layout-styled.ts | 19 -
frontend/src/app/(client)/layout.tsx | 25 +-
.../src/app/(client)/milestone/layout.tsx | 5 +
frontend/src/app/(client)/milestone/page.tsx | 58 +++
.../edit => my-page/info-edit}/page.tsx | 10 +-
frontend/src/app/(client)/my-page/layout.tsx | 5 +
.../(client)/my-page/milestone-list/page.tsx | 23 +
.../milestone-register}/page.tsx | 32 +-
.../my-page/milestone/page.tsx | 40 +-
frontend/src/app/(client)/my-page/page.tsx | 19 +
frontend/src/app/(client)/page.tsx | 51 +-
frontend/src/app/(client)/styled.ts | 50 --
.../src/app/(client)/team-building/layout.tsx | 5 +
.../team-building/page.tsx | 10 +-
.../src/app/admin/contest/create/page.tsx | 6 +-
.../src/app/admin/contest/{list => }/page.tsx | 6 +-
.../src/app/admin/faculty/{list => }/page.tsx | 26 +-
.../src/app/admin/faculty/register/page.tsx | 30 +-
frontend/src/app/admin/layout.tsx | 34 +-
.../list/components/MemberTable/index.tsx | 41 --
frontend/src/app/admin/member/page.tsx | 8 -
.../[slug]/components/FilePreview/index.tsx | 0
.../index.tsx | 6 +-
.../milestone/{list => }/[slug]/not-found.tsx | 2 +-
.../milestone/{list => }/[slug]/page.tsx | 18 +-
.../MilestoneHistoryTable/index.tsx | 142 ------
.../app/admin/milestone/{list => }/page.tsx | 23 +-
.../src/app/admin/milestone/rank/page.tsx | 87 ++--
.../src/app/admin/milestone/register/page.tsx | 26 +-
.../admin/{member/list => student}/page.tsx | 23 +-
frontend/src/app/admin/styled.ts | 64 ---
frontend/src/app/admin/team-building/page.tsx | 6 +-
frontend/src/app/layout.tsx | 3 +-
frontend/src/components/Footer/index.tsx | 18 -
frontend/src/components/Footer/styled.ts | 54 --
frontend/src/components/GoPageIcon/index.tsx | 28 -
.../Header/HeaderAccordion/index.tsx | 18 -
.../Header/HeaderAccordion/styled.ts | 51 --
.../src/components/Header/Sidebar/index.tsx | 64 ---
.../src/components/Header/Sidebar/styled.ts | 63 ---
frontend/src/components/Header/index.tsx | 108 ----
frontend/src/components/Header/styled.ts | 52 --
frontend/src/components/IconButton/index.tsx | 42 --
frontend/src/components/IconButton/styled.ts | 19 -
.../src/components/MilestoneChart/index.tsx | 39 --
.../src/components/MilestoneChart/styled.ts | 93 ----
.../MilestonePeriodSearchForm/index.tsx | 40 --
.../MilestonePeriodSearchForm/styled.ts | 28 -
.../src/components/MilestoneTable/index.tsx | 37 --
.../src/components/MilestoneTable/styled.ts | 50 --
frontend/src/components/SubTitle/index.tsx | 20 -
frontend/src/components/TabButton/index.tsx | 29 --
.../src/components/TeamBuilding/index.tsx | 51 --
.../src/components/TeamBuilding/styled.ts | 87 ----
frontend/src/components/Title/index.tsx | 13 -
frontend/src/components/common/IconButton.tsx | 30 ++
.../src/components/common/PageSubTitle.tsx | 20 +
frontend/src/components/common/PageTitle.tsx | 13 +
.../common/Pagination.tsx} | 11 +-
.../src/components/common/PeriodSearchBox.tsx | 39 ++
.../common/admin/AdminPagination.tsx} | 22 +-
.../admin/AdminSearchBox.tsx} | 20 +-
.../formik/DatePicker.tsx} | 6 +-
.../index.tsx => common/formik/Dropdown.tsx} | 3 -
.../common/formik/DropdownDdang.tsx} | 2 -
.../formik/EmailTextInput.tsx} | 2 +-
.../formik/FileUploader.tsx} | 0
.../formik/ImageUploader.tsx} | 0
.../index.tsx => common/formik/TextInput.tsx} | 20 +-
.../common/formik/TextInputDdang.tsx} | 0
.../src/components/layout/AdminFooter.tsx | 7 +
.../src/components/layout/AdminHeader.tsx | 77 +++
.../src/components/layout/AdminSidebar.tsx | 60 +++
frontend/src/components/layout/Footer.tsx | 29 ++
frontend/src/components/layout/Header.tsx | 214 ++++++++
frontend/src/components/layout/Sidebar.tsx | 57 +++
.../src/components/layout/SidebarLayout.tsx | 12 +
.../ui/admin/faculty/FacultyMemberTable.tsx} | 19 +-
.../AdminMilestoneDownloadButton.tsx} | 8 +-
.../milestone/AdminMilestoneFilePreview.tsx | 55 ++
.../AdminMilestoneStatusChangeButton.tsx | 105 ++++
.../admin/milestone/AdminMilestoneTable.tsx | 111 ++++
.../ui/admin/student/StudentMemberTable.tsx | 40 ++
.../components/ui/auth/AuthFindPageFooter.tsx | 18 +
.../ui/auth/AuthFindPageTabButton.tsx | 28 +
.../ui/auth/AuthFindPasswordForm.tsx} | 14 +-
.../src/components/ui/auth/AuthSignInForm.tsx | 93 ++++
.../ui/auth/AuthSignUpFirst.tsx} | 18 +-
.../ui/auth/AuthSignUpMajorDropdown.tsx} | 13 +-
.../components/ui/auth/AuthSignUpSecond.tsx | 133 +++++
.../hackathon/MarkdownViewer.css} | 0
.../hackathon/MarkdownViewer.tsx} | 8 +-
.../src/components/ui/home/GoPageIcon.tsx | 16 +
.../components/ui/home/HomeAnnouncement.tsx | 40 ++
.../components/ui/home/HomeExternalLink.tsx | 28 +
.../ui/home/HomeMilestone.tsx} | 70 ++-
.../ui/home/HomePnuLink.tsx} | 39 +-
.../src/components/ui/home/HomeSignIn.tsx | 104 ++++
.../components/ui/home/HomeTeamBuilding.tsx | 46 ++
.../ui/milestone/MilestoneAcceptedTable.tsx} | 21 +-
.../milestone/MilestoneCategoryDropdown.tsx} | 12 +-
.../ui/milestone/MilestoneCircleChart.tsx | 53 ++
.../ui/milestone/MilestoneDeleteButton.tsx} | 10 +-
.../ui/milestone/MilestoneDetailTable.tsx | 34 ++
.../milestone/MilestoneGroupLabel.tsx} | 9 +-
.../ui/milestone/MilestoneHistoryTable.tsx} | 62 +--
.../ui/milestone/MilestoneOverviewTable.tsx | 43 ++
.../ui/milestone/MilestoneStatusLabel.tsx} | 9 +-
.../ui/my-page/MyPageMilestone.tsx} | 30 +-
.../ui/my-page/MyPageMilestoneDetail.tsx} | 25 +-
.../ui/my-page/MyPageMilestoneHistory.tsx} | 25 +-
.../ui/my-page/MyPageMilestoneOverview.tsx} | 26 +-
.../ui/my-page/MyPageStudentInfo.tsx} | 38 +-
.../ui/team-building/TeamBuildingCard.tsx | 75 +++
frontend/src/constants.ts | 82 ---
frontend/src/data/adminCategory.ts | 11 +-
frontend/src/data/clientCategory.ts | 7 +-
frontend/src/lib/hooks/useAdminApi.ts | 1 -
frontend/src/lib/hooks/useApi.ts | 6 +-
frontend/src/lib/hooks/useAxios.ts | 2 -
frontend/src/lib/utils/utils.tsx | 3 -
frontend/src/middleware.ts | 2 +-
frontend/src/store/auth.slice.ts | 1 -
frontend/src/store/index.ts | 1 -
frontend/src/store/store.tsx | 2 -
.../theme/StyledComponentsRegistry/index.tsx | 3 -
frontend/src/types/error.ts | 2 -
frontend/tailwind.config.js | 19 +
197 files changed, 2550 insertions(+), 4331 deletions(-)
delete mode 100644 frontend/.babelrc
delete mode 100644 frontend/babel.config.json
delete mode 100644 frontend/src/adminComponents/Footer/index.tsx
delete mode 100644 frontend/src/adminComponents/Header/components/Navigator/index.tsx
delete mode 100644 frontend/src/adminComponents/Header/components/Navigator/styled.ts
delete mode 100644 frontend/src/adminComponents/Header/components/UserName/index.tsx
delete mode 100644 frontend/src/adminComponents/Header/index.tsx
delete mode 100644 frontend/src/adminComponents/Header/styled.ts
delete mode 100644 frontend/src/adminComponents/Sidebar/index.tsx
delete mode 100644 frontend/src/adminComponents/Sidebar/styled.ts
delete mode 100644 frontend/src/adminConstants.ts
delete mode 100644 frontend/src/app/(client)/(auth)/components/FindFooter/index.tsx
delete mode 100644 frontend/src/app/(client)/(auth)/sign-in/components/InputUserInfo/index.tsx
delete mode 100644 frontend/src/app/(client)/(auth)/sign-in/styled.ts
delete mode 100644 frontend/src/app/(client)/(auth)/sign-up/components/SignUpFirstPage/components/EmailTextInput/index.tsx
delete mode 100644 frontend/src/app/(client)/(auth)/sign-up/components/SignUpSecondPage/index.tsx
delete mode 100644 frontend/src/app/(client)/(auth)/styled.ts
delete mode 100644 frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/vote/components/ReadmeViewer/index.tsx
delete mode 100644 frontend/src/app/(client)/(withSidebar)/layout.tsx
delete mode 100644 frontend/src/app/(client)/(withSidebar)/milestone/page.tsx
delete mode 100644 frontend/src/app/(client)/(withSidebar)/milestone/styled.ts
delete mode 100644 frontend/src/app/(client)/(withSidebar)/my-page/components/MilestoneRowBarTable/index.tsx
delete mode 100644 frontend/src/app/(client)/(withSidebar)/my-page/components/StudentInfoSection/StudentInfoLabel/index.tsx
delete mode 100644 frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneDetail/styled.ts
delete mode 100644 frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneHistoryTable/styled.ts
delete mode 100644 frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneOverview/styled.ts
delete mode 100644 frontend/src/app/(client)/(withSidebar)/my-page/milestone/register/page.tsx
delete mode 100644 frontend/src/app/(client)/(withSidebar)/my-page/milestone/styled.ts
delete mode 100644 frontend/src/app/(client)/(withSidebar)/my-page/page.tsx
delete mode 100644 frontend/src/app/(client)/(withSidebar)/styled.ts
delete mode 100644 frontend/src/app/(client)/components/Announcement/index.tsx
delete mode 100644 frontend/src/app/(client)/components/Announcement/styled.ts
delete mode 100644 frontend/src/app/(client)/components/ExternalLink/index.tsx
delete mode 100644 frontend/src/app/(client)/components/ExternalLink/styled.ts
delete mode 100644 frontend/src/app/(client)/components/GoPageIcon/index.tsx
delete mode 100644 frontend/src/app/(client)/components/Milestone/styled.ts
delete mode 100644 frontend/src/app/(client)/components/PageTitle/index.tsx
delete mode 100644 frontend/src/app/(client)/components/PnuLink/styled.ts
delete mode 100644 frontend/src/app/(client)/components/Sidebar/index.tsx
delete mode 100644 frontend/src/app/(client)/components/Sidebar/styled.ts
delete mode 100644 frontend/src/app/(client)/components/SignIn/components/InputUserInfo/index.tsx
delete mode 100644 frontend/src/app/(client)/components/SignIn/components/InputUserInfo/styled.ts
delete mode 100644 frontend/src/app/(client)/components/SignIn/index.tsx
delete mode 100644 frontend/src/app/(client)/components/SignIn/styled.ts
delete mode 100644 frontend/src/app/(client)/components/TeamBuildings/index.tsx
delete mode 100644 frontend/src/app/(client)/components/TeamBuildings/styled.ts
delete mode 100644 frontend/src/app/(client)/components/styled.ts
rename frontend/src/app/(client)/{(withSidebar) => }/hackathon/[slug]/components/HackathonInformationTypeButtons/index.tsx (100%)
rename frontend/src/app/(client)/{(withSidebar) => }/hackathon/[slug]/layout.tsx (85%)
rename frontend/src/app/(client)/{(withSidebar) => }/hackathon/[slug]/page.tsx (93%)
rename frontend/src/app/(client)/{(withSidebar) => }/hackathon/[slug]/prize/page.tsx (100%)
rename frontend/src/app/(client)/{(withSidebar) => }/hackathon/[slug]/vote/components/HackathonTeamCreateModal/index.tsx (98%)
rename frontend/src/app/(client)/{(withSidebar) => }/hackathon/[slug]/vote/components/HackathonTeamReadModal/index.tsx (97%)
create mode 100644 frontend/src/app/(client)/hackathon/[slug]/vote/components/ReadmeViewer/index.tsx
rename frontend/src/app/(client)/{(withSidebar) => }/hackathon/[slug]/vote/components/TeamCreateInputSection/index.tsx (100%)
rename frontend/src/app/(client)/{(withSidebar) => }/hackathon/[slug]/vote/components/TeamMemberInput/index.tsx (94%)
rename frontend/src/app/(client)/{(withSidebar) => }/hackathon/[slug]/vote/page.tsx (97%)
create mode 100644 frontend/src/app/(client)/hackathon/layout.tsx
rename frontend/src/app/(client)/{(withSidebar) => }/hackathon/page.tsx (97%)
rename frontend/src/app/(client)/{(withSidebar) => }/hackathon/sw-contest/page.tsx (61%)
delete mode 100644 frontend/src/app/(client)/layout-styled.ts
create mode 100644 frontend/src/app/(client)/milestone/layout.tsx
create mode 100644 frontend/src/app/(client)/milestone/page.tsx
rename frontend/src/app/(client)/{(withSidebar)/my-page/edit => my-page/info-edit}/page.tsx (60%)
create mode 100644 frontend/src/app/(client)/my-page/layout.tsx
create mode 100644 frontend/src/app/(client)/my-page/milestone-list/page.tsx
rename frontend/src/app/(client)/{(withSidebar)/my-page/milestone/register/write => my-page/milestone-register}/page.tsx (90%)
rename frontend/src/app/(client)/{(withSidebar) => }/my-page/milestone/page.tsx (50%)
create mode 100644 frontend/src/app/(client)/my-page/page.tsx
delete mode 100644 frontend/src/app/(client)/styled.ts
create mode 100644 frontend/src/app/(client)/team-building/layout.tsx
rename frontend/src/app/(client)/{(withSidebar) => }/team-building/page.tsx (60%)
rename frontend/src/app/admin/contest/{list => }/page.tsx (79%)
rename frontend/src/app/admin/faculty/{list => }/page.tsx (73%)
delete mode 100644 frontend/src/app/admin/member/list/components/MemberTable/index.tsx
delete mode 100644 frontend/src/app/admin/member/page.tsx
rename frontend/src/app/admin/milestone/{list => }/[slug]/components/FilePreview/index.tsx (100%)
rename frontend/src/app/admin/milestone/{list => }/[slug]/components/MilestoneHistoryStatusChangeButton/index.tsx (94%)
rename frontend/src/app/admin/milestone/{list => }/[slug]/not-found.tsx (93%)
rename frontend/src/app/admin/milestone/{list => }/[slug]/page.tsx (90%)
delete mode 100644 frontend/src/app/admin/milestone/list/components/MilestoneHistoryTable/index.tsx
rename frontend/src/app/admin/milestone/{list => }/page.tsx (74%)
rename frontend/src/app/admin/{member/list => student}/page.tsx (66%)
delete mode 100644 frontend/src/app/admin/styled.ts
delete mode 100644 frontend/src/components/Footer/index.tsx
delete mode 100644 frontend/src/components/Footer/styled.ts
delete mode 100644 frontend/src/components/GoPageIcon/index.tsx
delete mode 100644 frontend/src/components/Header/HeaderAccordion/index.tsx
delete mode 100644 frontend/src/components/Header/HeaderAccordion/styled.ts
delete mode 100644 frontend/src/components/Header/Sidebar/index.tsx
delete mode 100644 frontend/src/components/Header/Sidebar/styled.ts
delete mode 100644 frontend/src/components/Header/index.tsx
delete mode 100644 frontend/src/components/Header/styled.ts
delete mode 100644 frontend/src/components/IconButton/index.tsx
delete mode 100644 frontend/src/components/IconButton/styled.ts
delete mode 100644 frontend/src/components/MilestoneChart/index.tsx
delete mode 100644 frontend/src/components/MilestoneChart/styled.ts
delete mode 100644 frontend/src/components/MilestonePeriodSearchForm/index.tsx
delete mode 100644 frontend/src/components/MilestonePeriodSearchForm/styled.ts
delete mode 100644 frontend/src/components/MilestoneTable/index.tsx
delete mode 100644 frontend/src/components/MilestoneTable/styled.ts
delete mode 100644 frontend/src/components/SubTitle/index.tsx
delete mode 100644 frontend/src/components/TabButton/index.tsx
delete mode 100644 frontend/src/components/TeamBuilding/index.tsx
delete mode 100644 frontend/src/components/TeamBuilding/styled.ts
delete mode 100644 frontend/src/components/Title/index.tsx
create mode 100644 frontend/src/components/common/IconButton.tsx
create mode 100644 frontend/src/components/common/PageSubTitle.tsx
create mode 100644 frontend/src/components/common/PageTitle.tsx
rename frontend/src/{app/(client)/components/Pagination/index.tsx => components/common/Pagination.tsx} (83%)
create mode 100644 frontend/src/components/common/PeriodSearchBox.tsx
rename frontend/src/{adminComponents/Pagination/index.tsx => components/common/admin/AdminPagination.tsx} (85%)
rename frontend/src/components/{SearchBox/index.tsx => common/admin/AdminSearchBox.tsx} (78%)
rename frontend/src/components/{Formik/DatePicker/index.tsx => common/formik/DatePicker.tsx} (92%)
rename frontend/src/components/{Formik/Dropdown/index.tsx => common/formik/Dropdown.tsx} (95%)
rename frontend/src/{app/(client)/components/Formik/Dropdown/index.tsx => components/common/formik/DropdownDdang.tsx} (97%)
rename frontend/src/components/{Formik/EmailTextInput/index.tsx => common/formik/EmailTextInput.tsx} (97%)
rename frontend/src/components/{Formik/FileUploader/index.tsx => common/formik/FileUploader.tsx} (100%)
rename frontend/src/components/{Formik/ImageUploader/index.tsx => common/formik/ImageUploader.tsx} (100%)
rename frontend/src/components/{Formik/TextInput/index.tsx => common/formik/TextInput.tsx} (61%)
rename frontend/src/{app/(client)/components/Formik/TextInput/index.tsx => components/common/formik/TextInputDdang.tsx} (100%)
create mode 100644 frontend/src/components/layout/AdminFooter.tsx
create mode 100644 frontend/src/components/layout/AdminHeader.tsx
create mode 100644 frontend/src/components/layout/AdminSidebar.tsx
create mode 100644 frontend/src/components/layout/Footer.tsx
create mode 100644 frontend/src/components/layout/Header.tsx
create mode 100644 frontend/src/components/layout/Sidebar.tsx
create mode 100644 frontend/src/components/layout/SidebarLayout.tsx
rename frontend/src/{app/admin/faculty/list/components/MemberTable/index.tsx => components/ui/admin/faculty/FacultyMemberTable.tsx} (90%)
rename frontend/src/{app/admin/milestone/list/components/MilestoneHistoryTable/MilestoneHistoryExcelFileDownloadButton.tsx/index.tsx => components/ui/admin/milestone/AdminMilestoneDownloadButton.tsx} (80%)
create mode 100644 frontend/src/components/ui/admin/milestone/AdminMilestoneFilePreview.tsx
create mode 100644 frontend/src/components/ui/admin/milestone/AdminMilestoneStatusChangeButton.tsx
create mode 100644 frontend/src/components/ui/admin/milestone/AdminMilestoneTable.tsx
create mode 100644 frontend/src/components/ui/admin/student/StudentMemberTable.tsx
create mode 100644 frontend/src/components/ui/auth/AuthFindPageFooter.tsx
create mode 100644 frontend/src/components/ui/auth/AuthFindPageTabButton.tsx
rename frontend/src/{app/(client)/(auth)/find-password/components/FindForm/index.tsx => components/ui/auth/AuthFindPasswordForm.tsx} (92%)
create mode 100644 frontend/src/components/ui/auth/AuthSignInForm.tsx
rename frontend/src/{app/(client)/(auth)/sign-up/components/SignUpFirstPage/index.tsx => components/ui/auth/AuthSignUpFirst.tsx} (94%)
rename frontend/src/{app/(client)/(auth)/sign-up/components/SignUpSecondPage/components/MajorDropdown/index.tsx => components/ui/auth/AuthSignUpMajorDropdown.tsx} (80%)
create mode 100644 frontend/src/components/ui/auth/AuthSignUpSecond.tsx
rename frontend/src/components/{MarkdownViewer/markdown.css => ui/hackathon/MarkdownViewer.css} (100%)
rename frontend/src/components/{MarkdownViewer/index.tsx => ui/hackathon/MarkdownViewer.tsx} (94%)
create mode 100644 frontend/src/components/ui/home/GoPageIcon.tsx
create mode 100644 frontend/src/components/ui/home/HomeAnnouncement.tsx
create mode 100644 frontend/src/components/ui/home/HomeExternalLink.tsx
rename frontend/src/{app/(client)/components/Milestone/index.tsx => components/ui/home/HomeMilestone.tsx} (55%)
rename frontend/src/{app/(client)/components/PnuLink/index.tsx => components/ui/home/HomePnuLink.tsx} (61%)
create mode 100644 frontend/src/components/ui/home/HomeSignIn.tsx
create mode 100644 frontend/src/components/ui/home/HomeTeamBuilding.tsx
rename frontend/src/{app/(client)/(withSidebar)/my-page/milestone/components/MilestoneHistoryTable/index.tsx => components/ui/milestone/MilestoneAcceptedTable.tsx} (86%)
rename frontend/src/{app/(client)/(withSidebar)/my-page/milestone/register/write/components/MilestoneDropdown/index.tsx => components/ui/milestone/MilestoneCategoryDropdown.tsx} (88%)
create mode 100644 frontend/src/components/ui/milestone/MilestoneCircleChart.tsx
rename frontend/src/{app/(client)/(withSidebar)/my-page/milestone/register/components/MilestoneHistoryDeleteButton/index.tsx => components/ui/milestone/MilestoneDeleteButton.tsx} (76%)
create mode 100644 frontend/src/components/ui/milestone/MilestoneDetailTable.tsx
rename frontend/src/components/{MilestoneGroupLabel/index.tsx => ui/milestone/MilestoneGroupLabel.tsx} (86%)
rename frontend/src/{app/(client)/(withSidebar)/my-page/milestone/register/components/MilestoneHistoryTable/index.tsx => components/ui/milestone/MilestoneHistoryTable.tsx} (53%)
create mode 100644 frontend/src/components/ui/milestone/MilestoneOverviewTable.tsx
rename frontend/src/{app/(client)/(withSidebar)/my-page/components/MilestoneHistoryStatusLabel/index.tsx => components/ui/milestone/MilestoneStatusLabel.tsx} (82%)
rename frontend/src/{app/(client)/(withSidebar)/my-page/components/MilestoneSection/index.tsx => components/ui/my-page/MyPageMilestone.tsx} (75%)
rename frontend/src/{app/(client)/(withSidebar)/my-page/milestone/components/MilestoneDetail/index.tsx => components/ui/my-page/MyPageMilestoneDetail.tsx} (58%)
rename frontend/src/{app/(client)/(withSidebar)/my-page/components/MilestoneHistorySection/index.tsx => components/ui/my-page/MyPageMilestoneHistory.tsx} (65%)
rename frontend/src/{app/(client)/(withSidebar)/my-page/milestone/components/MilestoneOverview/index.tsx => components/ui/my-page/MyPageMilestoneOverview.tsx} (60%)
rename frontend/src/{app/(client)/(withSidebar)/my-page/components/StudentInfoSection/index.tsx => components/ui/my-page/MyPageStudentInfo.tsx} (76%)
create mode 100644 frontend/src/components/ui/team-building/TeamBuildingCard.tsx
diff --git a/frontend/.babelrc b/frontend/.babelrc
deleted file mode 100644
index 4543c7d8..00000000
--- a/frontend/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["next/babel","@babel/preset-env" ],
- "plugins": [["styled-components", { "ssr": true }]]
-}
diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json
index f3b119b0..325be0ca 100644
--- a/frontend/.eslintrc.json
+++ b/frontend/.eslintrc.json
@@ -1,56 +1,4 @@
{
- "parser": "@typescript-eslint/parser",
- "plugins": ["@typescript-eslint", "react", "tailwindcss"],
- "extends": [
- "next/core-web-vitals",
- "plugin:@typescript-eslint/recommended",
- "plugin:prettier/recommended",
- "airbnb",
- "airbnb/hooks",
- "airbnb-typescript",
- "plugin:import/typescript",
- "plugin:import/recommended"
- ],
- "parserOptions": {
- "project": "./tsconfig.json"
- },
- "rules": {
- "prettier/prettier": ["error", { "endOfLine": "auto" }],
- "max-len": ["warn", { "code": 120 }],
- "react/react-in-jsx-scope": "off",
- "import/extensions": "off",
- "react/function-component-definition": [
- "error",
- {
- "namedComponents": ["arrow-function"]
- }
- ],
- "import/order": [
- "error",
- {
- "groups": ["builtin", "external", "internal", ["sibling", "parent", "index"], "type"],
- "pathGroupsExcludedImportTypes": [],
- "newlines-between": "always",
- "alphabetize": {
- "order": "asc",
- "caseInsensitive": true
- }
- }
- ],
- "object-curly-newline": "off",
- "react/jsx-one-expression-per-line": "off",
- "no-param-reassign": "off",
- "import/prefer-default-export": "off",
- "react/jsx-props-no-spreading": "off",
- "react/require-default-props": "off"
- },
- "settings": {
- "import/resolver": {
- "node": {},
- "typescript": {
- "directory": "./src"
- }
- },
- "import/parsers": { "@typescript-eslint/parser": [".ts", ".tsx"] }
- }
+ "extends": ["next/core-web-vitals"],
+ "rules": { "react-hooks/exhaustive-deps": "off", "@next/next/no-img-element": "off" }
}
diff --git a/frontend/babel.config.json b/frontend/babel.config.json
deleted file mode 100644
index bc15f0b6..00000000
--- a/frontend/babel.config.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "plugins": ["@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-private-methods"],
- "overrides": [
- {
- "include": "./node_modules/linkifyjs",
- "presets": ["@babel/preset-env"]
- }
- ]
-}
diff --git a/frontend/next.config.mjs b/frontend/next.config.mjs
index e2b7bfd6..e6bbfe75 100644
--- a/frontend/next.config.mjs
+++ b/frontend/next.config.mjs
@@ -1,11 +1,19 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
- compiler: {
- styledComponents: true,
- },
images: {
- domains: ['localhost', 'swcss.pusan.ac.kr'],
+ remotePatterns: [
+ {
+ protocol: 'http',
+ hostname: 'localhost',
+ pathname: '**',
+ },
+ {
+ protocol: 'https',
+ hostname: 'swcss.pusan.ac.kr',
+ pathname: '**',
+ },
+ ],
},
};
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 546fc20c..5bd4e384 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -65,18 +65,12 @@
"@types/react-cookies": "^0.1.3",
"@types/react-dom": "^18",
"@types/react-syntax-highlighter": "^15.5.13",
+ "@typescript-eslint/parser": "^8.16.0",
"autoprefixer": "^10.4.19",
- "eslint": "^8.57.0",
- "eslint-config-airbnb": "^19.0.4",
- "eslint-config-airbnb-typescript": "^17.1.0",
+ "eslint": "^8.57.1",
"eslint-config-next": "14.2.3",
"eslint-config-prettier": "^9.1.0",
- "eslint-import-resolver-typescript": "^3.6.1",
- "eslint-plugin-import": "^2.29.1",
- "eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-prettier": "^5.1.3",
- "eslint-plugin-react": "^7.33.2",
- "eslint-plugin-react-hooks": "^4.6.0",
"postcss": "^8.4.39",
"prettier": "^3.3.2",
"prettier-plugin-tailwindcss": "^0.6.5",
@@ -1911,22 +1905,22 @@
}
},
"node_modules/@eslint/js": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
- "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
+ "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/@humanwhocodes/config-array": {
- "version": "0.11.14",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
- "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
+ "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
"deprecated": "Use @eslint/config-array instead",
"dev": true,
"dependencies": {
- "@humanwhocodes/object-schema": "^2.0.2",
+ "@humanwhocodes/object-schema": "^2.0.3",
"debug": "^4.3.1",
"minimatch": "^3.0.5"
},
@@ -2314,6 +2308,12 @@
"resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-2.0.2.tgz",
"integrity": "sha512-dyHY+sMF0ihPus3O27ODd4+agdHMEmuRdyiZJ2CCWjPV5UFmn17ZbElvk6WOGVE4rdCJKZQCrPV2BcikOMLUGQ=="
},
+ "node_modules/@rtsao/scc": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
+ "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
+ "dev": true
+ },
"node_modules/@rushstack/eslint-patch": {
"version": "1.10.4",
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz",
@@ -2982,13 +2982,6 @@
"integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
"dev": true
},
- "node_modules/@types/json-schema": {
- "version": "7.0.15",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
- "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
- "dev": true,
- "peer": true
- },
"node_modules/@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@@ -3095,13 +3088,6 @@
"@types/react": "*"
}
},
- "node_modules/@types/semver": {
- "version": "7.5.8",
- "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
- "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
- "dev": true,
- "peer": true
- },
"node_modules/@types/send": {
"version": "0.17.4",
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
@@ -3138,76 +3124,27 @@
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
"integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg=="
},
- "node_modules/@typescript-eslint/eslint-plugin": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
- "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==",
- "dev": true,
- "peer": true,
- "dependencies": {
- "@eslint-community/regexpp": "^4.5.1",
- "@typescript-eslint/scope-manager": "6.21.0",
- "@typescript-eslint/type-utils": "6.21.0",
- "@typescript-eslint/utils": "6.21.0",
- "@typescript-eslint/visitor-keys": "6.21.0",
- "debug": "^4.3.4",
- "graphemer": "^1.4.0",
- "ignore": "^5.2.4",
- "natural-compare": "^1.4.0",
- "semver": "^7.5.4",
- "ts-api-utils": "^1.0.1"
- },
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
- "eslint": "^7.0.0 || ^8.0.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": {
- "version": "7.6.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
- "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
- "dev": true,
- "peer": true,
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/@typescript-eslint/parser": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
- "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
+ "version": "8.16.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.16.0.tgz",
+ "integrity": "sha512-D7DbgGFtsqIPIFMPJwCad9Gfi/hC0PWErRRHFnaCWoEDYi5tQUDiJCTmGUbBiLzjqAck4KcXt9Ayj0CNlIrF+w==",
"dev": true,
"dependencies": {
- "@typescript-eslint/scope-manager": "6.21.0",
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/typescript-estree": "6.21.0",
- "@typescript-eslint/visitor-keys": "6.21.0",
+ "@typescript-eslint/scope-manager": "8.16.0",
+ "@typescript-eslint/types": "8.16.0",
+ "@typescript-eslint/typescript-estree": "8.16.0",
+ "@typescript-eslint/visitor-keys": "8.16.0",
"debug": "^4.3.4"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^7.0.0 || ^8.0.0"
+ "eslint": "^8.57.0 || ^9.0.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -3216,57 +3153,29 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
- "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
+ "version": "8.16.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.16.0.tgz",
+ "integrity": "sha512-mwsZWubQvBki2t5565uxF0EYvG+FwdFb8bMtDuGQLdCCnGPrDEDvm1gtfynuKlnpzeBRqdFCkMf9jg1fnAK8sg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/visitor-keys": "6.21.0"
+ "@typescript-eslint/types": "8.16.0",
+ "@typescript-eslint/visitor-keys": "8.16.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
- "node_modules/@typescript-eslint/type-utils": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz",
- "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==",
- "dev": true,
- "peer": true,
- "dependencies": {
- "@typescript-eslint/typescript-estree": "6.21.0",
- "@typescript-eslint/utils": "6.21.0",
- "debug": "^4.3.4",
- "ts-api-utils": "^1.0.1"
- },
- "engines": {
- "node": "^16.0.0 || >=18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^7.0.0 || ^8.0.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
"node_modules/@typescript-eslint/types": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
- "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
+ "version": "8.16.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.16.0.tgz",
+ "integrity": "sha512-NzrHj6thBAOSE4d9bsuRNMvk+BvaQvmY4dDglgkgGC0EW/tB3Kelnp3tAKH87GEwzoxgeQn9fNGRyFJM/xd+GQ==",
"dev": true,
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
@@ -3274,22 +3183,22 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
- "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
+ "version": "8.16.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.16.0.tgz",
+ "integrity": "sha512-E2+9IzzXMc1iaBy9zmo+UYvluE3TW7bCGWSF41hVWUE01o8nzr1rvOQYSxelxr6StUvRcTMe633eY8mXASMaNw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/visitor-keys": "6.21.0",
+ "@typescript-eslint/types": "8.16.0",
+ "@typescript-eslint/visitor-keys": "8.16.0",
"debug": "^4.3.4",
- "globby": "^11.1.0",
+ "fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
- "minimatch": "9.0.3",
- "semver": "^7.5.4",
- "ts-api-utils": "^1.0.1"
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^1.3.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
@@ -3313,60 +3222,33 @@
"node": ">=10"
}
},
- "node_modules/@typescript-eslint/utils": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
- "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==",
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.16.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.16.0.tgz",
+ "integrity": "sha512-pq19gbaMOmFE3CbL0ZB8J8BFCo2ckfHBfaIsaOZgBIF4EoISJIdLX5xRhd0FGB0LlHReNRuzoJoMGpTjq8F2CQ==",
"dev": true,
- "peer": true,
"dependencies": {
- "@eslint-community/eslint-utils": "^4.4.0",
- "@types/json-schema": "^7.0.12",
- "@types/semver": "^7.5.0",
- "@typescript-eslint/scope-manager": "6.21.0",
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/typescript-estree": "6.21.0",
- "semver": "^7.5.4"
+ "@typescript-eslint/types": "8.16.0",
+ "eslint-visitor-keys": "^4.2.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^7.0.0 || ^8.0.0"
- }
- },
- "node_modules/@typescript-eslint/utils/node_modules/semver": {
- "version": "7.6.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
- "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
- "dev": true,
- "peer": true,
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
}
},
- "node_modules/@typescript-eslint/visitor-keys": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
- "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
+ "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
+ "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
"dev": true,
- "dependencies": {
- "@typescript-eslint/types": "6.21.0",
- "eslint-visitor-keys": "^3.4.1"
- },
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
+ "url": "https://opencollective.com/eslint"
}
},
"node_modules/@ungap/structured-clone": {
@@ -4034,12 +3916,6 @@
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true
},
- "node_modules/confusing-browser-globals": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz",
- "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==",
- "dev": true
- },
"node_modules/convert-source-map": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
@@ -4574,16 +4450,17 @@
}
},
"node_modules/eslint": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
- "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
+ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
+ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
"@eslint/eslintrc": "^2.1.4",
- "@eslint/js": "8.57.0",
- "@humanwhocodes/config-array": "^0.11.14",
+ "@eslint/js": "8.57.1",
+ "@humanwhocodes/config-array": "^0.13.0",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
"@ungap/structured-clone": "^1.2.0",
@@ -4628,80 +4505,111 @@
"url": "https://opencollective.com/eslint"
}
},
- "node_modules/eslint-config-airbnb": {
- "version": "19.0.4",
- "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz",
- "integrity": "sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==",
+ "node_modules/eslint-config-next": {
+ "version": "14.2.3",
+ "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.2.3.tgz",
+ "integrity": "sha512-ZkNztm3Q7hjqvB1rRlOX8P9E/cXRL9ajRcs8jufEtwMfTVYRqnmtnaSu57QqHyBlovMuiB8LEzfLBkh5RYV6Fg==",
"dev": true,
"dependencies": {
- "eslint-config-airbnb-base": "^15.0.0",
- "object.assign": "^4.1.2",
- "object.entries": "^1.1.5"
- },
- "engines": {
- "node": "^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0"
+ "@next/eslint-plugin-next": "14.2.3",
+ "@rushstack/eslint-patch": "^1.3.3",
+ "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0",
+ "eslint-import-resolver-node": "^0.3.6",
+ "eslint-import-resolver-typescript": "^3.5.2",
+ "eslint-plugin-import": "^2.28.1",
+ "eslint-plugin-jsx-a11y": "^6.7.1",
+ "eslint-plugin-react": "^7.33.2",
+ "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705"
},
"peerDependencies": {
- "eslint": "^7.32.0 || ^8.2.0",
- "eslint-plugin-import": "^2.25.3",
- "eslint-plugin-jsx-a11y": "^6.5.1",
- "eslint-plugin-react": "^7.28.0",
- "eslint-plugin-react-hooks": "^4.3.0"
+ "eslint": "^7.23.0 || ^8.0.0",
+ "typescript": ">=3.3.1"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
}
},
- "node_modules/eslint-config-airbnb-base": {
- "version": "15.0.0",
- "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz",
- "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==",
+ "node_modules/eslint-config-next/node_modules/@typescript-eslint/parser": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz",
+ "integrity": "sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==",
"dev": true,
"dependencies": {
- "confusing-browser-globals": "^1.0.10",
- "object.assign": "^4.1.2",
- "object.entries": "^1.1.5",
- "semver": "^6.3.0"
+ "@typescript-eslint/scope-manager": "7.2.0",
+ "@typescript-eslint/types": "7.2.0",
+ "@typescript-eslint/typescript-estree": "7.2.0",
+ "@typescript-eslint/visitor-keys": "7.2.0",
+ "debug": "^4.3.4"
},
"engines": {
- "node": "^10.12.0 || >=12.0.0"
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^7.32.0 || ^8.2.0",
- "eslint-plugin-import": "^2.25.2"
+ "eslint": "^8.56.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
}
},
- "node_modules/eslint-config-airbnb-typescript": {
- "version": "17.1.0",
- "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-17.1.0.tgz",
- "integrity": "sha512-GPxI5URre6dDpJ0CtcthSZVBAfI+Uw7un5OYNVxP2EYi3H81Jw701yFP7AU+/vCE7xBtFmjge7kfhhk4+RAiig==",
+ "node_modules/eslint-config-next/node_modules/@typescript-eslint/scope-manager": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz",
+ "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==",
"dev": true,
"dependencies": {
- "eslint-config-airbnb-base": "^15.0.0"
+ "@typescript-eslint/types": "7.2.0",
+ "@typescript-eslint/visitor-keys": "7.2.0"
},
- "peerDependencies": {
- "@typescript-eslint/eslint-plugin": "^5.13.0 || ^6.0.0",
- "@typescript-eslint/parser": "^5.0.0 || ^6.0.0",
- "eslint": "^7.32.0 || ^8.2.0",
- "eslint-plugin-import": "^2.25.3"
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
}
},
- "node_modules/eslint-config-next": {
- "version": "14.2.3",
- "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.2.3.tgz",
- "integrity": "sha512-ZkNztm3Q7hjqvB1rRlOX8P9E/cXRL9ajRcs8jufEtwMfTVYRqnmtnaSu57QqHyBlovMuiB8LEzfLBkh5RYV6Fg==",
+ "node_modules/eslint-config-next/node_modules/@typescript-eslint/types": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz",
+ "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==",
+ "dev": true,
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/eslint-config-next/node_modules/@typescript-eslint/typescript-estree": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz",
+ "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==",
"dev": true,
"dependencies": {
- "@next/eslint-plugin-next": "14.2.3",
- "@rushstack/eslint-patch": "^1.3.3",
- "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0",
- "eslint-import-resolver-node": "^0.3.6",
- "eslint-import-resolver-typescript": "^3.5.2",
- "eslint-plugin-import": "^2.28.1",
- "eslint-plugin-jsx-a11y": "^6.7.1",
- "eslint-plugin-react": "^7.33.2",
- "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705"
+ "@typescript-eslint/types": "7.2.0",
+ "@typescript-eslint/visitor-keys": "7.2.0",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
+ "is-glob": "^4.0.3",
+ "minimatch": "9.0.3",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
},
- "peerDependencies": {
- "eslint": "^7.23.0 || ^8.0.0",
- "typescript": ">=3.3.1"
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
},
"peerDependenciesMeta": {
"typescript": {
@@ -4709,6 +4617,50 @@
}
}
},
+ "node_modules/eslint-config-next/node_modules/@typescript-eslint/visitor-keys": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz",
+ "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "7.2.0",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/eslint-config-next/node_modules/minimatch": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+ "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/eslint-config-next/node_modules/semver": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/eslint-config-prettier": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
@@ -4767,9 +4719,9 @@
}
},
"node_modules/eslint-module-utils": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz",
- "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==",
+ "version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz",
+ "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==",
"dev": true,
"dependencies": {
"debug": "^3.2.7"
@@ -4793,34 +4745,36 @@
}
},
"node_modules/eslint-plugin-import": {
- "version": "2.29.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz",
- "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==",
+ "version": "2.31.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz",
+ "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==",
"dev": true,
"dependencies": {
- "array-includes": "^3.1.7",
- "array.prototype.findlastindex": "^1.2.3",
+ "@rtsao/scc": "^1.1.0",
+ "array-includes": "^3.1.8",
+ "array.prototype.findlastindex": "^1.2.5",
"array.prototype.flat": "^1.3.2",
"array.prototype.flatmap": "^1.3.2",
"debug": "^3.2.7",
"doctrine": "^2.1.0",
"eslint-import-resolver-node": "^0.3.9",
- "eslint-module-utils": "^2.8.0",
- "hasown": "^2.0.0",
- "is-core-module": "^2.13.1",
+ "eslint-module-utils": "^2.12.0",
+ "hasown": "^2.0.2",
+ "is-core-module": "^2.15.1",
"is-glob": "^4.0.3",
"minimatch": "^3.1.2",
- "object.fromentries": "^2.0.7",
- "object.groupby": "^1.0.1",
- "object.values": "^1.1.7",
+ "object.fromentries": "^2.0.8",
+ "object.groupby": "^1.0.3",
+ "object.values": "^1.2.0",
"semver": "^6.3.1",
+ "string.prototype.trimend": "^1.0.8",
"tsconfig-paths": "^3.15.0"
},
"engines": {
"node": ">=4"
},
"peerDependencies": {
- "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8"
+ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9"
}
},
"node_modules/eslint-plugin-import/node_modules/brace-expansion": {
@@ -5972,9 +5926,9 @@
}
},
"node_modules/is-core-module": {
- "version": "2.15.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz",
- "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==",
+ "version": "2.15.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
+ "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
"dev": true,
"dependencies": {
"hasown": "^2.0.2"
@@ -6628,9 +6582,9 @@
}
},
"node_modules/minimatch": {
- "version": "9.0.3",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
- "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
@@ -8739,9 +8693,9 @@
"integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg=="
},
"node_modules/ts-api-utils": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
- "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
+ "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==",
"dev": true,
"engines": {
"node": ">=16"
diff --git a/frontend/package.json b/frontend/package.json
index ded78e62..9368489a 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -66,18 +66,12 @@
"@types/react-cookies": "^0.1.3",
"@types/react-dom": "^18",
"@types/react-syntax-highlighter": "^15.5.13",
+ "@typescript-eslint/parser": "^8.16.0",
"autoprefixer": "^10.4.19",
- "eslint": "^8.57.0",
- "eslint-config-airbnb": "^19.0.4",
- "eslint-config-airbnb-typescript": "^17.1.0",
+ "eslint": "^8.57.1",
"eslint-config-next": "14.2.3",
"eslint-config-prettier": "^9.1.0",
- "eslint-import-resolver-typescript": "^3.6.1",
- "eslint-plugin-import": "^2.29.1",
- "eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-prettier": "^5.1.3",
- "eslint-plugin-react": "^7.33.2",
- "eslint-plugin-react-hooks": "^4.6.0",
"postcss": "^8.4.39",
"prettier": "^3.3.2",
"prettier-plugin-tailwindcss": "^0.6.5",
diff --git a/frontend/src/adminComponents/Footer/index.tsx b/frontend/src/adminComponents/Footer/index.tsx
deleted file mode 100644
index ed5c44f6..00000000
--- a/frontend/src/adminComponents/Footer/index.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import { COLOR, FONT_STYLE } from '@/adminConstants';
-
-const Footer = () => (
-
- copyright ⓒ KOREA LEARNING CONSULTING CENTER. All Right Reserved
-
-);
-
-export default Footer;
diff --git a/frontend/src/adminComponents/Header/components/Navigator/index.tsx b/frontend/src/adminComponents/Header/components/Navigator/index.tsx
deleted file mode 100644
index 20fb99af..00000000
--- a/frontend/src/adminComponents/Header/components/Navigator/index.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-'use client';
-
-import { usePathname } from 'next/navigation';
-
-import { adminCategories } from '@/data/adminCategory';
-
-import { HeaderLinker, HeaderLinkerPoint } from './styled';
-
-const Navigator = () => {
- const pathname = usePathname();
- return (
- <>
- {adminCategories.map((item) => {
- if (pathname.includes(item.url)) {
- return (
-
- {item.title}
-
- );
- }
- return (
-
- {item.title}
-
- );
- })}
- >
- );
-};
-
-export default Navigator;
diff --git a/frontend/src/adminComponents/Header/components/Navigator/styled.ts b/frontend/src/adminComponents/Header/components/Navigator/styled.ts
deleted file mode 100644
index a6b10756..00000000
--- a/frontend/src/adminComponents/Header/components/Navigator/styled.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import Link from 'next/link';
-import styled from 'styled-components';
-
-import { ADMIN_HEADER_HEIGHT, COLOR, FONT_STYLE } from '@/adminConstants';
-
-export const HeaderLinker = styled(Link)`
- position: relative;
- display: flex;
- align-items: center;
- height: ${ADMIN_HEADER_HEIGHT};
- padding: 0 20px;
- color: ${COLOR.comment};
- font: ${FONT_STYLE.base.normal};
- &:after {
- content: '';
- background: ${COLOR.border};
- position: absolute;
- top: 15%;
- left: 0;
- height: 70%;
- width: 1px;
- }
-`;
-
-export const HeaderLinkerPoint = styled(HeaderLinker)`
- background-color: ${COLOR.primary.main};
- color: ${COLOR.white};
- &:after {
- height: 0;
- width: 0;
- }
-`;
diff --git a/frontend/src/adminComponents/Header/components/UserName/index.tsx b/frontend/src/adminComponents/Header/components/UserName/index.tsx
deleted file mode 100644
index 0897c0a1..00000000
--- a/frontend/src/adminComponents/Header/components/UserName/index.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-'use client';
-
-import { COLOR, FONT_STYLE } from '@/constants';
-import { useAppSelector } from '@/lib/hooks/redux';
-
-const UserName = () => {
- const auth = useAppSelector((state) => state.auth).value;
-
- return (
-
- 반갑습니다! {auth.name} 님
-
- );
-};
-
-export default UserName;
diff --git a/frontend/src/adminComponents/Header/index.tsx b/frontend/src/adminComponents/Header/index.tsx
deleted file mode 100644
index a693aa0d..00000000
--- a/frontend/src/adminComponents/Header/index.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import Image from 'next/image';
-
-import { AdminBlackLink, AdminGrayLink } from '@/app/admin/styled';
-import { BORDER_RADIUS, FONT_STYLE } from '@/constants';
-
-import Navigator from './components/Navigator';
-import UserName from './components/UserName';
-import { HeaderLayout, HeaderWrapper, LogoLink } from './styled';
-
-const Header = () => (
-
-
-
-
-
-
-
-
-
-
-
- 사이트 메인으로
-
-
- 로그아웃
-
-
-
-
-);
-
-export default Header;
diff --git a/frontend/src/adminComponents/Header/styled.ts b/frontend/src/adminComponents/Header/styled.ts
deleted file mode 100644
index 85b2046f..00000000
--- a/frontend/src/adminComponents/Header/styled.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-'use client';
-
-import Link from 'next/link';
-import styled from 'styled-components';
-
-import { ADMIN_SIDEBAR_WIDTH, COLOR } from '@/adminConstants';
-
-export const HeaderWrapper = styled.div`
- position: fixed;
- width: 100vw;
- min-width: 1200px;
- background: ${COLOR.white};
- border-bottom: 2px solid ${COLOR.primary.main};
- z-index: 1;
-`;
-
-export const HeaderLayout = styled.div`
- width: 100%;
- height: 100%;
- padding-right: 8px;
- display: flex;
- justify-content: space-between;
- align-items: center;
-`;
-
-export const LogoLink = styled(Link)`
- width: ${ADMIN_SIDEBAR_WIDTH};
- margin: auto;
- padding-left: 10px;
- display: flex;
- align-items: center;
- justify-content: center;
-`;
diff --git a/frontend/src/adminComponents/Sidebar/index.tsx b/frontend/src/adminComponents/Sidebar/index.tsx
deleted file mode 100644
index e0d0d739..00000000
--- a/frontend/src/adminComponents/Sidebar/index.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-'use client';
-
-import { usePathname } from 'next/navigation';
-import { useEffect, useState } from 'react';
-
-import { adminCategories } from '@/data/adminCategory';
-
-import * as S from './styled';
-
-const Sidebar = () => {
- const [currTab, setCurrTab] = useState('');
- const pathname = usePathname();
-
- const handleTabClick = (tab: string) => {
- setCurrTab(tab);
- };
-
- useEffect(() => {
- setCurrTab(pathname);
- }, [pathname]);
-
- return (
-
-
- {adminCategories.map((item) => (
-
- {currTab.includes(item.url) ? (
- handleTabClick(item.url)}>
- {item.title}
-
- ) : (
- handleTabClick(item.url)}>{item.title}
- )}
- {item.sub.map((subItem) => (
-
- {subItem.title}
-
- ))}
-
- ))}
-
-
- );
-};
-
-export default Sidebar;
diff --git a/frontend/src/adminComponents/Sidebar/styled.ts b/frontend/src/adminComponents/Sidebar/styled.ts
deleted file mode 100644
index c40d4435..00000000
--- a/frontend/src/adminComponents/Sidebar/styled.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-'use client';
-
-import Link from 'next/link';
-import styled from 'styled-components';
-
-import { ADMIN_HEADER_HEIGHT, ADMIN_SIDEBAR_WIDTH, COLOR } from '@/adminConstants';
-
-export const SidebarWrapper = styled.div`
- position: fixed;
- width: ${ADMIN_SIDEBAR_WIDTH};
- height: calc(100vh - ${ADMIN_HEADER_HEIGHT});
- margin-top: calc(${ADMIN_HEADER_HEIGHT} + 2px);
- box-shadow: 0px 0px 7px 0px rgba(0, 0, 0, 0.3);
- background-color: ${COLOR.white};
- z-index: 1;
-`;
-
-export const SidebarLayout = styled.div`
- display: flex;
- width: 100%;
- height: 100%;
- flex-direction: column;
-`;
-
-export const SidebarContentLayout = styled.div`
- overflow: hidden;
- transition: max-height 0.6s ease-in-out;
-`;
-
-export const SidebarContentTitle = styled.div`
- display: block;
- max-height: 42px;
- padding: 10px 20px;
- border-bottom: 1px solid ${COLOR.border};
- cursor: default;
- overflow: hidden;
-`;
-
-export const SidebarContentPointTitle = styled(SidebarContentTitle)`
- background-color: ${COLOR.secondary.main};
- color: ${COLOR.white};
-`;
-
-export const SidebarContentSubTitle = styled(Link)`
- display: block;
- padding: 10px 30px;
- border-bottom: 1px solid ${COLOR.border};
- background-color: ${COLOR.background.light};
- cursor: default;
- color: ${COLOR.comment};
-`;
diff --git a/frontend/src/adminConstants.ts b/frontend/src/adminConstants.ts
deleted file mode 100644
index 2192f56e..00000000
--- a/frontend/src/adminConstants.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-export const COLOR = {
- white: '#FFFFFF',
- black_text: '#333333',
- comment: '#4E5963',
- border: '#DEE2E6',
- background: {
- light: '#F0F0F0',
- base: '#B0B0B0',
- },
- primary: {
- light: '#3B80C7',
- main: '#095DB3',
- dark: '#053566',
- },
- secondary: {
- light: '#F0F0F0',
- main: '#7F7F7F',
- dark: '#3F3F3F',
- },
- semantic: {
- error: 'B30818',
- },
-};
-
-export const FONT_STYLE = {
- xs: {
- normal: '400 12px "Noto Sans KR", sans-serif',
- semibold: '600 12px "Noto Sans KR", sans-serif',
- bold: '700 12px "Noto Sans KR", sans-serif',
- },
- sm: {
- normal: '400 14px "Noto Sans KR", sans-serif',
- semibold: '600 14px "Noto Sans KR", sans-serif',
- bold: '700 14px "Noto Sans KR", sans-serif',
- },
- base: {
- normal: '400 16px "Noto Sans KR", sans-serif',
- semibold: '600 16px "Noto Sans KR", sans-serif',
- bold: '700 16px "Noto Sans KR", sans-serif',
- },
- lg: {
- normal: '400 20px "Noto Sans KR", sans-serif',
- semibold: '600 20px "Noto Sans KR", sans-serif',
- bold: '700 20px "Noto Sans KR", sans-serif',
- },
- xl: {
- normal: '400 32px "Noto Sans KR", sans-serif',
- semibold: '600 32px "Noto Sans KR", sans-serif',
- bold: '700 32px "Noto Sans KR", sans-serif',
- },
-};
-
-export const BORDER_RADIUS = {
- sm: '10px',
- md: '20px',
- lg: '30px',
- full: '100%',
-};
-
-export const ADMIN_HEADER_HEIGHT = '55px';
-export const ADMIN_SIDEBAR_WIDTH = '220px';
diff --git a/frontend/src/app/(client)/(auth)/components/FindFooter/index.tsx b/frontend/src/app/(client)/(auth)/components/FindFooter/index.tsx
deleted file mode 100644
index d8c76693..00000000
--- a/frontend/src/app/(client)/(auth)/components/FindFooter/index.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-const FindFooter = () => (
-
-);
-
-export default FindFooter;
diff --git a/frontend/src/app/(client)/(auth)/find-id/page.tsx b/frontend/src/app/(client)/(auth)/find-id/page.tsx
index 9a430e64..25d8280b 100644
--- a/frontend/src/app/(client)/(auth)/find-id/page.tsx
+++ b/frontend/src/app/(client)/(auth)/find-id/page.tsx
@@ -1,41 +1,35 @@
-import PageTitle from '@/app/(client)/components/PageTitle';
-import TabButton from '@/components/TabButton';
+import PageTitle from '@/components/common/PageTitle';
+import AuthFindPageTabButton from '@/components/ui/auth/AuthFindPageTabButton';
+import AuthFindPageFooter from '@/components/ui/auth/AuthFindPageFooter';
-import FindFooter from '../components/FindFooter';
-
-const findTabs = [
- { name: '아이디 찾기', url: '/find-id' },
- { name: '비밀번호 찾기', url: '/find-password' },
-];
-
-const Page = () => (
-
-
-
-
-
-
-);
-
-export default Page;
+
+ );
+}
diff --git a/frontend/src/app/(client)/(auth)/find-password/page.tsx b/frontend/src/app/(client)/(auth)/find-password/page.tsx
index ad3ca869..df26c628 100644
--- a/frontend/src/app/(client)/(auth)/find-password/page.tsx
+++ b/frontend/src/app/(client)/(auth)/find-password/page.tsx
@@ -1,28 +1,17 @@
-import PageTitle from '@/app/(client)/components/PageTitle';
-import TabButton from '@/components/TabButton';
+import PageTitle from '@/components/common/PageTitle';
+import AuthFindPageTabButton from '@/components/ui/auth/AuthFindPageTabButton';
+import AuthFindPageFooter from '@/components/ui/auth/AuthFindPageFooter';
+import AuthFindPasswordForm from '@/components/ui/auth/AuthFindPasswordForm';
-import FindForm from './components/FindForm';
-import FindFooter from '../components/FindFooter';
-
-const findTabs = [
- { name: '아이디 찾기', url: '/find-id' },
- { name: '비밀번호 찾기', url: '/find-password' },
-];
-
-const Page = () => (
-
-
-
-);
-
-export default Page;
+export default function FindPasswordPage() {
+ return (
+
+
+
+ );
+}
diff --git a/frontend/src/app/(client)/(auth)/sign-in/components/InputUserInfo/index.tsx b/frontend/src/app/(client)/(auth)/sign-in/components/InputUserInfo/index.tsx
deleted file mode 100644
index 15ab95c2..00000000
--- a/frontend/src/app/(client)/(auth)/sign-in/components/InputUserInfo/index.tsx
+++ /dev/null
@@ -1,81 +0,0 @@
-'use client';
-
-import { useRouter } from 'next/navigation';
-
-import { InputFixedText, Input, InputLabel, InputWrapper, SignButton } from '@/app/(client)/(auth)/styled';
-import { useAppDispatch, useAppSelector } from '@/lib/hooks/redux';
-import { signIn } from '@/store/auth.slice';
-import { useSignInMutation } from '@/lib/hooks/useApi';
-import { useState } from 'react';
-import { toast } from 'react-toastify';
-
-const InputUserInfo = () => {
- const [userInfo, setUserInfo] = useState({
- email: '',
- password: '',
- });
-
- const router = useRouter();
-
- const { mutate: signInMutation } = useSignInMutation();
-
- const dispatch = useAppDispatch();
- const auth = useAppSelector((state) => state.auth).value;
-
- if (auth.isAuth) router.push('/');
-
- const handleInputChange = (e: React.ChangeEvent
) => {
- setUserInfo((prev) => {
- return {
- ...prev,
- [e.target.id]: e.target.value,
- };
- });
- };
-
- const handleSubmit = (e: React.FormEvent) => {
- e.preventDefault();
- signInMutation(userInfo, {
- onSuccess(data, variables, context) {
- dispatch(
- signIn({
- id: data.member_id,
- token: `Bearer ${data.token}`,
- name: data.name,
- email: data.email,
- isModerator: data.is_moderator,
- }),
- );
- router.push('/');
- },
- onError(error, variables, context) {
- toast.error(error.message);
- },
- });
- };
-
- return (
- <>
-
- >
- );
-};
-
-export default InputUserInfo;
diff --git a/frontend/src/app/(client)/(auth)/sign-in/page.tsx b/frontend/src/app/(client)/(auth)/sign-in/page.tsx
index d9715153..ff0c249e 100644
--- a/frontend/src/app/(client)/(auth)/sign-in/page.tsx
+++ b/frontend/src/app/(client)/(auth)/sign-in/page.tsx
@@ -1,27 +1,25 @@
-import { FONT_STYLE } from '@/constants';
+import Link from 'next/link';
-import InputUserInfo from './components/InputUserInfo';
-import { Divisor, FindLink, SignInContentWrapper, SignInPageWrapper, SignUpLink, SuggestionComment } from './styled';
-import { Description, Title, TitleContent } from '../styled';
+import PageTitle from '@/components/common/PageTitle';
+import AuthSignInForm from '@/components/ui/auth/AuthSignInForm';
-const Page = () => (
-
-
-
- 로그인
- PNU SW역량시스템 첫 사용시 회원가입이 필요합니다.
-
-
-
-
- 아이디 / 비밀번호 찾기
-
-
- 처음오셨나요?
회원가입
+export default function SignInPage() {
+ return (
+
+
+
-
-
-
-);
-
-export default Page;
+
+
+
+ 아이디 / 비밀번호 찾기
+
+
+ 처음오셨나요? 회원가입
+
+
+
+
+ );
+}
diff --git a/frontend/src/app/(client)/(auth)/sign-in/styled.ts b/frontend/src/app/(client)/(auth)/sign-in/styled.ts
deleted file mode 100644
index f612909a..00000000
--- a/frontend/src/app/(client)/(auth)/sign-in/styled.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-'use client';
-
-import Link from 'next/link';
-import styled from 'styled-components';
-
-import { SIGN_WIDTH, RESPONSIVE_WIDTH, FONT_STYLE, COLOR } from '@/constants';
-
-export const SignInPageWrapper = styled.div`
- max-width: ${SIGN_WIDTH};
- margin: auto;
- padding: 80px 0 40px;
-
- @media screen and (max-width: ${RESPONSIVE_WIDTH.desktop}) {
- padding-top: 50px;
- }
-`;
-
-export const SignInContentWrapper = styled.div`
- padding: 70px 20px 20px;
- display: flex;
- flex-direction: column;
- gap: 20px;
-
- @media screen and (max-width: ${RESPONSIVE_WIDTH.mobile}) {
- padding: 20px;
- }
-`;
-
-export const SuggestionComment = styled.div`
- display: grid;
- grid-template-columns: 1fr 1fr;
- text-align: center;
- color: ${COLOR.comment};
-`;
-
-export const Divisor = styled.div`
- position: relative;
- font: ${FONT_STYLE.xs.normal};
- z-index: 0;
-
- &::after {
- content: '';
- position: absolute;
- bottom: 25%;
- right: 0;
- height: 50%;
- border-right: 1px solid ${COLOR.comment};
-`;
-
-export const FindLink = styled(Link)`
- font: ${FONT_STYLE.xs.normal};
- color: ${COLOR.comment};
-`;
-
-export const SignUpLink = styled(Link)`
- font: ${FONT_STYLE.xs.normal};
- color: ${COLOR.comment};
- text-decoration: underline;
-`;
diff --git a/frontend/src/app/(client)/(auth)/sign-out/page.tsx b/frontend/src/app/(client)/(auth)/sign-out/page.tsx
index 1f3bb99d..3146d0c2 100644
--- a/frontend/src/app/(client)/(auth)/sign-out/page.tsx
+++ b/frontend/src/app/(client)/(auth)/sign-out/page.tsx
@@ -1,26 +1,22 @@
-/* eslint-disable react-hooks/exhaustive-deps */
-
'use client';
import { useRouter } from 'next/navigation';
import { useAppDispatch, useAppSelector } from '@/lib/hooks/redux';
import { signOut } from '@/store/auth.slice';
+import { useEffect } from 'react';
-const Page = () => {
+export default function SignOutPage() {
const router = useRouter();
const dispatch = useAppDispatch();
- const auth = useAppSelector((state) => state.auth).value;
+ const auth = useAppSelector((state) => state.auth.value);
- if (!auth.isAuth) router.push('/');
+ useEffect(() => {
+ if (!auth.isAuth) router.push('/', { scroll: false });
- // TODO: api 연결
- dispatch(signOut());
- setTimeout(() => {
- router.refresh();
- }, 0);
+ dispatch(signOut());
+ router.push('/sign-in', { scroll: false });
+ }, [auth, router, dispatch]);
return null;
-};
-
-export default Page;
+}
diff --git a/frontend/src/app/(client)/(auth)/sign-up/components/SignUpFirstPage/components/EmailTextInput/index.tsx b/frontend/src/app/(client)/(auth)/sign-up/components/SignUpFirstPage/components/EmailTextInput/index.tsx
deleted file mode 100644
index e4ca465e..00000000
--- a/frontend/src/app/(client)/(auth)/sign-up/components/SignUpFirstPage/components/EmailTextInput/index.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-type BuiltInTextInputProps = React.DetailedHTMLProps
, HTMLInputElement>;
-
-interface CustomTextInputProps {
- name: string;
- label: string;
- errorText?: string;
- onKeyDownEnter?(): void;
- onChangeText?(text: string): void;
-}
-
-export type TextInputProps = BuiltInTextInputProps & CustomTextInputProps;
-
-export const EmailTextInput = ({ ...props }: TextInputProps) => {
- const { label, errorText, onKeyDownEnter, onChangeText, ...inputProps } = props;
- const hasError = errorText !== undefined;
-
- return (
-
-
- {label} * {' '}
-
- 부산대 메일이 없나요?{' '}
-
- 신청바로가기
-
-
-
-
-
{
- if (e.key === 'Enter') {
- onKeyDownEnter?.();
- }
- inputProps.onKeyDown?.(e);
- }}
- onChange={(e) => {
- inputProps.onChange?.(e);
- onChangeText?.(e.target.value);
- }}
- className={`m-0 w-full rounded-sm border-[1px] border-border p-3 text-base ${hasError && 'border-red-400'}`}
- />
-
@pusan.ac.kr
-
- {errorText &&
{errorText} }
-
- );
-};
-
-export default EmailTextInput;
diff --git a/frontend/src/app/(client)/(auth)/sign-up/components/SignUpSecondPage/index.tsx b/frontend/src/app/(client)/(auth)/sign-up/components/SignUpSecondPage/index.tsx
deleted file mode 100644
index 18b73e63..00000000
--- a/frontend/src/app/(client)/(auth)/sign-up/components/SignUpSecondPage/index.tsx
+++ /dev/null
@@ -1,133 +0,0 @@
-/* eslint-disable react/button-has-type */
-/* eslint-disable import/no-extraneous-dependencies */
-
-'use client';
-
-import { Formik, Form } from 'formik';
-import * as Yup from 'yup';
-
-import { Dropdown } from '@/app/(client)/components/Formik/Dropdown';
-import { TextInput } from '@/app/(client)/components/Formik/TextInput';
-import { careerCategory } from '@/data/signUp';
-
-import MajorDropdown from './components/MajorDropdown';
-
-export interface SecondInfo {
- majorCollegeId: number;
- majorId: number;
- minorCollegeId: number;
- minorId: number;
- doubleMajorCollegeId: number;
- doubleMajorId: number;
- career: number;
- careerDetail: string;
-}
-
-const validationSchema = Yup.object().shape({
- majorId: Yup.number().min(1, '필수 입력란입니다. 전공을 선택해주세요.'),
- minorId: Yup.number().min(0, '필수 입력란입니다. 부전공 선택해주세요.'),
- doubleMajorId: Yup.number().min(0, '필수 입력란입니다. 복수전공을 선택해주세요.'),
- career: Yup.number().min(1, '필수 입력란입니다. 진로 분류를 선택해주세요.'),
- careerDetail: Yup.string().required('필수 입력란입니다. 진로 상세 계획을 입력해주세요.'),
-});
-
-export interface SignUpSecondPageProps {
- initialValues: SecondInfo;
- handlePrevButtonClick: (value: SecondInfo) => void;
- handleSubmitButtonClick: (value: SecondInfo) => void;
-}
-
-const SignUpSecondPage = ({ initialValues, handlePrevButtonClick, handleSubmitButtonClick }: SignUpSecondPageProps) => (
- {
- handleSubmitButtonClick(values);
- setSubmitting(false);
- }}
- >
- {({ isSubmitting, values, touched, handleChange, handleBlur, setFieldValue, errors }) => (
-
- )}
-
-);
-
-export default SignUpSecondPage;
diff --git a/frontend/src/app/(client)/(auth)/sign-up/page.tsx b/frontend/src/app/(client)/(auth)/sign-up/page.tsx
index 7b8aacfc..5ca4f0c7 100644
--- a/frontend/src/app/(client)/(auth)/sign-up/page.tsx
+++ b/frontend/src/app/(client)/(auth)/sign-up/page.tsx
@@ -1,19 +1,19 @@
'use client';
-import { useEffect, useState } from 'react';
+import { useState } from 'react';
+import { useRouter } from 'next/navigation';
+import { toast } from 'react-toastify';
-import PageTitle from '@/app/(client)/components/PageTitle';
+import PageTitle from '@/components/common/PageTitle';
import { SignUpPhase } from '@/data/signUp';
-import SignUpFirstPage, { FirstInfo } from './components/SignUpFirstPage';
-import SignUpSecondPage, { SecondInfo } from './components/SignUpSecondPage';
import { useSignUpMutation } from '@/lib/hooks/useApi';
-import { toast } from 'react-toastify';
-import { useRouter } from 'next/navigation';
+import AuthSignUpFirst, { FirstInfo } from '@/components/ui/auth/AuthSignUpFirst';
+import AuthSignUpSecond, { SecondInfo } from '@/components/ui/auth/AuthSignUpSecond';
type UserInformation = FirstInfo & SecondInfo;
-const Page = () => {
+export default function SignUpPage() {
const [userInfo, setUserInfo] = useState({
email: '',
authCode: '',
@@ -63,12 +63,12 @@ const Page = () => {
return (
-
+
{phase === SignUpPhase.one && (
-
+
)}
{phase === SignUpPhase.two && (
-
{
);
-};
-
-export default Page;
+}
diff --git a/frontend/src/app/(client)/(auth)/styled.ts b/frontend/src/app/(client)/(auth)/styled.ts
deleted file mode 100644
index 01098781..00000000
--- a/frontend/src/app/(client)/(auth)/styled.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-'use client';
-
-import styled from 'styled-components';
-
-import { BORDER_RADIUS, COLOR, FONT_STYLE } from '@/constants';
-
-export const TitleWrapper = styled.div`
- display: flex;
-`;
-
-export const TitleContent = styled.div`
- display: flex;
- flex-direction: column;
-`;
-
-export const Title = styled.p`
- font: ${FONT_STYLE.xl.semibold};
- cursor: default;
-`;
-
-export const Description = styled.p`
- font: ${FONT_STYLE.sm.normal};
- color: ${COLOR.comment};
- cursor: default;
-`;
-
-export const InputWrapper = styled.div`
- position: relative;
- display: flex;
- flex-direction: column;
-`;
-
-export const InputLabel = styled.label`
- font: ${FONT_STYLE.sm.semibold};
- color: ${COLOR.black_text};
-`;
-
-export const Input = styled.input`
- border: 1px solid ${COLOR.border};
- border-radius: ${BORDER_RADIUS.sm};
- padding: 8px;
- font: ${FONT_STYLE.base.normal};
- color: ${COLOR.black_text};
- outline: none;
- &::placeholder {
- color: ${COLOR.border};
- font-style: italic;
- }
-`;
-
-export const InputFixedText = styled.div`
- position: absolute;
- color: ${COLOR.comment};
- right: 10px;
- bottom: calc(50% - 10px);
- transform: translate(0, 50%);
- font: ${FONT_STYLE.sm.normal};
-`;
-
-export const SignButton = styled.button`
- width: 100%;
- border: none;
- border-radius: ${BORDER_RADIUS.sm};
- padding: 8px;
- margin-top: 16px;
- background-color: ${COLOR.primary.main};
- color: ${COLOR.white};
- font: ${FONT_STYLE.base.normal};
-`;
diff --git a/frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/vote/components/ReadmeViewer/index.tsx b/frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/vote/components/ReadmeViewer/index.tsx
deleted file mode 100644
index b6022309..00000000
--- a/frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/vote/components/ReadmeViewer/index.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import { useGithubReadme } from '@/lib/hooks/useGithubReadme';
-import MarkdownViewer from '@/components/MarkdownViewer';
-
-interface ReadmeViewerProps {
- repoUrl: string;
-}
-
-const ReadmeViewer = ({ repoUrl }: ReadmeViewerProps) => {
- const { data: readme, isPending, isError } = useGithubReadme(repoUrl);
- if (isPending) return README 문서를 불러오는 중입니다.
;
- if(isError||!readme) return README 문서를 불러오는 데 실패했습니다.
;
- return ;
-};
-
-export default ReadmeViewer;
diff --git a/frontend/src/app/(client)/(withSidebar)/layout.tsx b/frontend/src/app/(client)/(withSidebar)/layout.tsx
deleted file mode 100644
index bf9d55d8..00000000
--- a/frontend/src/app/(client)/(withSidebar)/layout.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-/* eslint-disable @next/next/no-page-custom-font */
-
-import Sidebar from '@/app/(client)/components/Sidebar';
-
-import { Content, ContentWrapper, PageWithSidebarWrapper } from './styled';
-
-const Layout = ({ children }: Readonly<{ children: React.ReactNode }>) => (
-
-
-
- {children}
-
-
-);
-export default Layout;
diff --git a/frontend/src/app/(client)/(withSidebar)/milestone/page.tsx b/frontend/src/app/(client)/(withSidebar)/milestone/page.tsx
deleted file mode 100644
index 9bf6d0b0..00000000
--- a/frontend/src/app/(client)/(withSidebar)/milestone/page.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import Image from 'next/image';
-
-import * as S from './styled';
-import Link from 'next/link';
-
-const Page = () => (
-
-
-
-
-
- 마일스톤이란
- 마일스톤은 전공자들의 SW역량을 종합적으로 평가하기 위한 역량평가지수입니다.
-
- 학생들은 교내외 여러 활동들을 통하여 실전적 SW역량, 글로벌 역량, 커뮤니케이션 역량을 균형있게 함양하고
- SW중심대학사업단에서는 학생들의 적립된 마일스톤 점수에 따라 매년 장학생을 선발하고 있습니다.
-
-
-
- 마일스톤 등록하러 가기
-
-
-
-
-
-
-
- 마일스톤 획득 방법
- 각 영역별 활동 수행 시, 책정 기준에 따라 마일스톤을 획득할 수 있습니다.
-
- 상세 내용은 아래 표를 참고해주세요.
-
-
- 마일스톤 평가기간
- 전년도 9월부터 당해년도 8월까지의 실적
- ※ SW 창업, 오픈소스 SW 컨트리뷰션의 경우 당해년도 1월부터 9월까지의 실적만을 반영함.
-
-
- 마일스톤 확인 방법
- SW역량지원시스템에서는 나의 마일스톤 현황을 한 눈에 볼 수 있도록 제공하고 있습니다.
-
- 로그인 후, 메인 페이지와 마이페이지에서 확인하실 수 있습니다.
-
-
-
-
-
-
-);
-
-export default Page;
diff --git a/frontend/src/app/(client)/(withSidebar)/milestone/styled.ts b/frontend/src/app/(client)/(withSidebar)/milestone/styled.ts
deleted file mode 100644
index f074a49b..00000000
--- a/frontend/src/app/(client)/(withSidebar)/milestone/styled.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-'use client';
-
-import styled from 'styled-components';
-
-import { BORDER_RADIUS, COLOR, FONT_STYLE, RESPONSIVE_WIDTH } from '@/constants';
-
-interface ResponsiveImageProps {
- maxHeight: string;
- maxWidth: string;
- backgroundImage?: string;
-}
-
-export const Content = styled.div`
- width: 100%;
- background-color: white;
- padding: 60px 20px 20px 20px;
- border-radius: ${BORDER_RADIUS.sm};
-`;
-
-export const Title = styled.div`
- color: ${COLOR.primary.main};
- font: ${FONT_STYLE.xl.bold};
- margin: 20px auto;
-`;
-
-export const Description = styled.div`
- text-align: center;
-`;
-
-export const InformationList = styled.ul`
- margin-top: 70px;
-`;
-
-export const Information = styled.li`
- display: flex;
- margin-bottom: 40px;
- @media screen and (max-width: ${RESPONSIVE_WIDTH.mobile}) {
- display: block;
- }
-`;
-
-export const InformationTitle = styled.div`
- color: ${COLOR.primary.main};
- font: ${FONT_STYLE.lg.semibold};
- width: 220px;
- @media screen and (max-width: ${RESPONSIVE_WIDTH.mobile}) {
- margin-bottom: 10px;
- }
-`;
-export const ImageWrapper = styled.div`
- display: flex;
- justify-content: center;
- ${({ backgroundImage }) => backgroundImage && `background-image: url(${backgroundImage});`}
- background-position: center;
- img {
- position: relative !important;
- height: 100%;
- width: 100%;
- max-height: ${(props) => props.maxHeight};
- max-width: ${(props) => props.maxWidth};
- object-fit: cover;
- }
-`;
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/components/MilestoneRowBarTable/index.tsx b/frontend/src/app/(client)/(withSidebar)/my-page/components/MilestoneRowBarTable/index.tsx
deleted file mode 100644
index fc961996..00000000
--- a/frontend/src/app/(client)/(withSidebar)/my-page/components/MilestoneRowBarTable/index.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-/* eslint-disable implicit-arrow-linebreak */
-
-import { MilestoneScoreDto } from '@/types/common.dto';
-
-interface MilestoneRowBarTableProps {
- milestoneScores: MilestoneScoreDto[] | undefined;
-}
-
-const MilestoneRowBarTable = ({ milestoneScores }: MilestoneRowBarTableProps) =>
- milestoneScores?.map((milestoneScore) => (
-
-
{milestoneScore.name}
-
-
-
- {milestoneScore.score}/{milestoneScore.limitScore}
-
-
-
- ));
-
-export default MilestoneRowBarTable;
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/components/StudentInfoSection/StudentInfoLabel/index.tsx b/frontend/src/app/(client)/(withSidebar)/my-page/components/StudentInfoSection/StudentInfoLabel/index.tsx
deleted file mode 100644
index ac0b261e..00000000
--- a/frontend/src/app/(client)/(withSidebar)/my-page/components/StudentInfoSection/StudentInfoLabel/index.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import { ReactNode } from 'react';
-
-interface StudentInfoLabelProps {
- label: string;
- value: ReactNode | string;
-}
-
-const StudentInfoLabel = ({ label, value }: StudentInfoLabelProps) => (
-
- {label}
- {value}
-
-);
-export default StudentInfoLabel;
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneDetail/styled.ts b/frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneDetail/styled.ts
deleted file mode 100644
index 4925a363..00000000
--- a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneDetail/styled.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-'use client';
-
-import styled from 'styled-components';
-
-import { BORDER_RADIUS } from '@/adminConstants';
-import { COLOR, FONT_STYLE } from '@/constants';
-
-interface GroupButtonProps {
- isSelected: boolean;
-}
-
-export const GroupButton = styled.button`
- color: ${({ isSelected }) => (isSelected ? COLOR.black_text : COLOR.comment)};
- border: none;
- background-color: white;
- flex-grow: 1;
- height: 30px;
- font: ${FONT_STYLE.base.normal};
- border-bottom: ${({ isSelected }) => (isSelected ? '2px solid black' : '0px solid black')};
-
- &:hover {
- color: ${COLOR.black_text};
- border-bottom: 2px solid black;
- }
-`;
-
-export const TableRow = styled.div`
- padding: 7px 0px;
- border-bottom: 1px solid ${COLOR.border};
- font: ${FONT_STYLE.sm.normal};
- display: flex;
- align-items: center;
- gap: 8px;
- justify-content: space-between;
-`;
-
-export const TableRowTitle = styled.div`
- flex-shrink: 1;
-`;
-
-export const TableRowBar = styled.div`
- background-color: ${COLOR.background.light};
- width: 75px;
- height: 10px;
- border-radius: ${BORDER_RADIUS.lg};
- overflow: hidden;
-`;
-
-interface TableRowBarFillProps {
- ratio: number;
-}
-
-export const TableRowBarFill = styled.div`
- width: ${({ ratio }) => 100 * ratio}%;
- background-color: ${COLOR.primary.main};
- height: 100%;
-`;
-
-export const TableRowScore = styled.div`
- font: ${FONT_STYLE.xs.normal};
- min-width: 45px;
-`;
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneHistoryTable/styled.ts b/frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneHistoryTable/styled.ts
deleted file mode 100644
index 2ca24d68..00000000
--- a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneHistoryTable/styled.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-'use client';
-
-import styled from 'styled-components';
-
-import { COLOR, FONT_STYLE } from '@/constants';
-
-export const TableBody = styled.tbody`
- border-top: 2px solid ${COLOR.black_text};
- border-bottom: 2px solid ${COLOR.black_text};
- font: ${FONT_STYLE.sm.normal};
- > :last-child {
- border-bottom: 0px solid;
- }
-`;
-
-export const TableRow = styled.tr`
- border-bottom: 1px solid ${COLOR.border};
- text-align: center;
- > td,
- > th {
- padding: 10px;
- }
-
- > td:first-child {
- text-align: left;
- }
-`;
-
-export const HistoryDescription = styled.td`
- width: 540px;
-`;
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneOverview/styled.ts b/frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneOverview/styled.ts
deleted file mode 100644
index adb5c13d..00000000
--- a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneOverview/styled.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-'use client';
-
-import styled from 'styled-components';
-
-export const MilestoneWrapper = styled.div`
- min-width: 330px;
- display: flex;
- flex-direction: column;
- gap: 16px;
-`;
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/register/page.tsx b/frontend/src/app/(client)/(withSidebar)/my-page/milestone/register/page.tsx
deleted file mode 100644
index c6fc020e..00000000
--- a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/register/page.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import Link from 'next/link';
-
-import PageTitle from '@/app/(client)/components/PageTitle';
-
-import MilestoneHistoryTable from './components/MilestoneHistoryTable';
-
-const Page = async ({ searchParams }: { searchParams?: { [key: string]: string | undefined } }) => {
- const pageNumber = searchParams?.page ? parseInt(searchParams.page, 10) : 1;
- return (
-
- );
-};
-
-export default Page;
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/styled.ts b/frontend/src/app/(client)/(withSidebar)/my-page/milestone/styled.ts
deleted file mode 100644
index d8e5dcb4..00000000
--- a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/styled.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-'use client';
-
-import styled from 'styled-components';
-
-import { BORDER_RADIUS, COLOR, FONT_STYLE } from '@/constants';
-
-export const Content = styled.div`
- width: 100%;
- background-color: white;
- padding: 20px;
- border-radius: ${BORDER_RADIUS.sm};
-`;
-
-export const SubTitle = styled.div`
- color: ${COLOR.black_text};
- font: ${FONT_STYLE.lg.bold};
- margin-bottom: 25px;
-`;
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/page.tsx b/frontend/src/app/(client)/(withSidebar)/my-page/page.tsx
deleted file mode 100644
index 1fa6adb5..00000000
--- a/frontend/src/app/(client)/(withSidebar)/my-page/page.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import SubTitle from '@/components/SubTitle';
-
-import MilestoneHistorySection from './components/MilestoneHistorySection';
-import MilestoneSection from './components/MilestoneSection';
-import StudentInfoSection from './components/StudentInfoSection';
-
-const Page = () => (
-
-);
-export default Page;
diff --git a/frontend/src/app/(client)/(withSidebar)/styled.ts b/frontend/src/app/(client)/(withSidebar)/styled.ts
deleted file mode 100644
index 98e06192..00000000
--- a/frontend/src/app/(client)/(withSidebar)/styled.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-'use client';
-
-import styled from 'styled-components';
-
-import { COLOR, CONTENT_WIDTH, RESPONSIVE_WIDTH } from '@/constants';
-
-export const PageWithSidebarWrapper = styled.div`
- width: 100%;
- min-height: calc(100vh - 200px);
- display: flex;
- background-color: ${COLOR.background.light};
-
- @media screen and (max-width: ${RESPONSIVE_WIDTH.desktop}) {
- display: block;
- background-color: ${COLOR.white};
- }
-`;
-
-export const ContentWrapper = styled.div`
- flex-grow: 1;
-`;
-
-export const Content = styled.div`
- width: ${CONTENT_WIDTH};
- height: 100%;
- padding: 100px 20px 20px;
- overflow: hidden;
-
- @media screen and (max-width: ${RESPONSIVE_WIDTH.desktop}) {
- padding: 20px;
- width: 100%;
- }
-`;
diff --git a/frontend/src/app/(client)/components/Announcement/index.tsx b/frontend/src/app/(client)/components/Announcement/index.tsx
deleted file mode 100644
index c79a47cc..00000000
--- a/frontend/src/app/(client)/components/Announcement/index.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import RSSParser from 'rss-parser';
-
-import GoPageIcon from '@/components/GoPageIcon';
-
-import { AnnouncementDate, AnnouncementItem, AnnouncementTitle } from './styled';
-import { Description, Title, TitleContent, TitleWrapper } from '../styled';
-
-const Announcement = async () => {
- const ANNOUNCEMENT_URL = 'https://swedu.pusan.ac.kr/swedu/31630/subview.do';
- const parser = new RSSParser();
- const announcements = await parser.parseURL('https://swedu.pusan.ac.kr/bbs/swedu/6906/rssList.do?row=50');
- return (
-
-
-
- 공지사항
- 소프트웨어융합교육원의 공지사항을 알려드려요.
-
-
-
-
- {announcements.items.slice(0, 4).map((item) => (
-
- {item.title}
- {item.pubDate?.slice(0, 10).replaceAll('-', '.')}
-
- ))}
-
-
- );
-};
-
-export default Announcement;
diff --git a/frontend/src/app/(client)/components/Announcement/styled.ts b/frontend/src/app/(client)/components/Announcement/styled.ts
deleted file mode 100644
index 5e79b3a8..00000000
--- a/frontend/src/app/(client)/components/Announcement/styled.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-'use client';
-
-import Link from 'next/link';
-import styled from 'styled-components';
-
-import { BORDER_RADIUS, COLOR, FONT_STYLE } from '@/constants';
-
-export const AnnouncementItem = styled(Link)`
- border: 1px solid ${COLOR.border};
- border-radius: ${BORDER_RADIUS.sm};
- padding: 10px;
- display: flex;
- justify-content: space-between;
- gap: 20px;
- &:hover > * {
- color: ${COLOR.primary.main};
- }
-`;
-
-export const AnnouncementTitle = styled.span`
- min-width: 0;
- text-overflow: ellipsis;
- overflow: hidden;
- white-space: nowrap;
- font: ${FONT_STYLE.base.semibold};
- color: ${COLOR.black_text};
-`;
-
-export const AnnouncementDate = styled.span`
- width: 90px;
- flex-shirk: 1;
- text-align: right;
- font: ${FONT_STYLE.sm.normal};
- color: ${COLOR.comment};
-`;
diff --git a/frontend/src/app/(client)/components/ExternalLink/index.tsx b/frontend/src/app/(client)/components/ExternalLink/index.tsx
deleted file mode 100644
index 196b7d35..00000000
--- a/frontend/src/app/(client)/components/ExternalLink/index.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import Image from 'next/image';
-
-import { externalLinkInfos } from '@/data/externalLink';
-
-import { ImageTitle, ImageWrapper, ItemWrapper, LinkWrapper } from './styled';
-
-const ExternalLink = () => (
-
- {externalLinkInfos.map((link) => {
- const markup = { __html: link.title };
- return (
-
-
-
-
-
-
- );
- })}
-
-);
-
-export default ExternalLink;
diff --git a/frontend/src/app/(client)/components/ExternalLink/styled.ts b/frontend/src/app/(client)/components/ExternalLink/styled.ts
deleted file mode 100644
index 1aaa7ca6..00000000
--- a/frontend/src/app/(client)/components/ExternalLink/styled.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-'use client';
-
-import Link from 'next/link';
-import styled from 'styled-components';
-
-import { BORDER_RADIUS, COLOR, FONT_STYLE, RESPONSIVE_WIDTH } from '@/constants';
-
-export const LinkWrapper = styled.div`
- border-radius: ${BORDER_RADIUS.sm};
- padding: 10px;
- display: grid;
- grid-template-columns: repeat(6, 1fr);
- row-gap: 20px;
- background-color: ${COLOR.primary.light};
-
- @media screen and (max-width: ${RESPONSIVE_WIDTH.tablet}) {
- grid-template-columns: repeat(3, 1fr);
- }
-`;
-
-export const ItemWrapper = styled(Link)`
- display: flex;
- flex-direction: column;
- gap: 12px;
- justify-content: center;
- align-items: center;
-`;
-
-export const ImageWrapper = styled.div`
- width: 80px;
- height: 80px;
- display: flex;
- justify-content: center;
- align-items: center;
- background-color: ${COLOR.white};
- border-radius: ${BORDER_RADIUS.full};
-`;
-
-export const ImageTitle = styled.div`
- height: 40px;
- color: ${COLOR.black_text};
- font: ${FONT_STYLE.xs.semibold};
- text-align: center;
-`;
diff --git a/frontend/src/app/(client)/components/GoPageIcon/index.tsx b/frontend/src/app/(client)/components/GoPageIcon/index.tsx
deleted file mode 100644
index 15237611..00000000
--- a/frontend/src/app/(client)/components/GoPageIcon/index.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-/* eslint-disable import/no-extraneous-dependencies */
-import { VscAdd } from '@react-icons/all-files/vsc/VscAdd';
-import Link from 'next/link';
-
-import { COLOR, FONT_STYLE } from '@/constants';
-
-interface GoPageIconProps {
- name: string;
- url: string;
-}
-
-const GoPageIcon = ({ name, url }: GoPageIconProps) => (
-
-
- {name}
-
-);
-
-export default GoPageIcon;
diff --git a/frontend/src/app/(client)/components/Milestone/styled.ts b/frontend/src/app/(client)/components/Milestone/styled.ts
deleted file mode 100644
index a4f6c49d..00000000
--- a/frontend/src/app/(client)/components/Milestone/styled.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-'use client';
-
-import styled from 'styled-components';
-
-export const MilestoneChartWrapper = styled.div`
- margin: 12px;
- display: flex;
- gap: 20px;
- align-items: center;
- justify-content: space-around;
-`;
diff --git a/frontend/src/app/(client)/components/PageTitle/index.tsx b/frontend/src/app/(client)/components/PageTitle/index.tsx
deleted file mode 100644
index 7db1c284..00000000
--- a/frontend/src/app/(client)/components/PageTitle/index.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-/* eslint-disable import/no-extraneous-dependencies */
-import { VscAdd } from '@react-icons/all-files/vsc/VscAdd';
-import Link from 'next/link';
-
-export interface PageTitleProps {
- title: string;
- description: string;
- urlText: string;
- url: string;
-}
-
-const PageTitle = ({ title, description, urlText, url }: PageTitleProps) => (
-
-
-
{title}
-
{description}
-
- {urlText !== '' && (
-
-
- {urlText}
-
- )}
-
-);
-
-export default PageTitle;
diff --git a/frontend/src/app/(client)/components/PnuLink/styled.ts b/frontend/src/app/(client)/components/PnuLink/styled.ts
deleted file mode 100644
index 5af102d9..00000000
--- a/frontend/src/app/(client)/components/PnuLink/styled.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-/* eslint-disable import/no-extraneous-dependencies */
-import { VscChevronLeft } from '@react-icons/all-files/vsc/VscChevronLeft';
-import { VscChevronRight } from '@react-icons/all-files/vsc/VscChevronRight';
-import Link from 'next/link';
-import styled from 'styled-components';
-
-import { BORDER_RADIUS, COLOR, FONT_STYLE } from '@/constants';
-
-export const ButtonWrapper = styled.div`
- display: flex;
- gap: 10px;
- align-items: center;
-`;
-
-export const PrevButton = styled(VscChevronLeft)`
- font: ${FONT_STYLE.xl.semibold};
- color: ${COLOR.black_text};
- border: 1px solid ${COLOR.comment};
- border-radius: ${BORDER_RADIUS.full};
-`;
-
-export const NextButton = styled(VscChevronRight)`
- font: ${FONT_STYLE.xl.semibold};
- color: ${COLOR.black_text};
- border: 1px solid ${COLOR.comment};
- border-radius: ${BORDER_RADIUS.full};
-`;
-
-export const PnuLinker = styled(Link)`
- width: 162px;
- height: 52px;
- display: block;
- border: 1px solid ${COLOR.border};
-`;
diff --git a/frontend/src/app/(client)/components/Sidebar/index.tsx b/frontend/src/app/(client)/components/Sidebar/index.tsx
deleted file mode 100644
index d1700094..00000000
--- a/frontend/src/app/(client)/components/Sidebar/index.tsx
+++ /dev/null
@@ -1,82 +0,0 @@
-/* eslint-disable import/no-extraneous-dependencies */
-
-'use client';
-
-import { VscChevronDown } from '@react-icons/all-files/vsc/VscChevronDown';
-import { VscChevronUp } from '@react-icons/all-files/vsc/VscChevronUp';
-import { usePathname } from 'next/navigation';
-import { useCallback, useEffect, useState } from 'react';
-
-import { headerInfos } from '@/data/clientCategory';
-import { CategoryDto, SubCategoryDto } from '@/types/common.dto';
-
-import * as S from './styled';
-
-const Sidebar = () => {
- const pathname = usePathname();
- const [currentCategory, setCurrentCategory] = useState();
- const [currentSubCategory, setCurrentSubCategory] = useState();
- const [isOpenNavigationBar, setIsOpenNavigationBar] = useState(false);
-
- const findMatchPath = useCallback(() => {
- let maxOverlap = 0;
- let bestMatch: SubCategoryDto | null = null;
- currentCategory?.sub.forEach((category) => {
- const { url } = category;
- if (pathname.startsWith(url) && url.length > maxOverlap) {
- maxOverlap = url.length;
- bestMatch = category;
- }
- });
- return bestMatch;
- }, [pathname, currentCategory]);
-
- useEffect(() => {
- setCurrentCategory(headerInfos.filter((headerInfo) => pathname.startsWith(headerInfo.url))[0]);
- setIsOpenNavigationBar(false);
- }, [pathname]);
-
- useEffect(() => {
- setCurrentSubCategory(findMatchPath());
- }, [findMatchPath]);
-
- return (
- <>
-
- {currentCategory?.title}
- {currentCategory?.description}
-
- {currentCategory?.sub.map((sub) => (
-
- {sub.title}
-
- ))}
-
-
-
- setIsOpenNavigationBar((prev) => !prev)}>
- {currentSubCategory?.title}
- {isOpenNavigationBar ? : }
-
-
-
- {currentCategory?.sub.map((sub) => (
-
- {sub.title}
-
- ))}
-
-
- >
- );
-};
-
-export default Sidebar;
diff --git a/frontend/src/app/(client)/components/Sidebar/styled.ts b/frontend/src/app/(client)/components/Sidebar/styled.ts
deleted file mode 100644
index 01d77a24..00000000
--- a/frontend/src/app/(client)/components/Sidebar/styled.ts
+++ /dev/null
@@ -1,120 +0,0 @@
-/* eslint-disable implicit-arrow-linebreak */
-/* eslint-disable @typescript-eslint/indent */
-/* eslint-disable operator-linebreak */
-
-'use client';
-
-import Link from 'next/link';
-import styled from 'styled-components';
-
-import { COLOR, FONT_STYLE, RESPONSIVE_WIDTH } from '@/constants';
-
-interface SidebarCategoryProps {
- isCurrentCategory: boolean;
-}
-
-interface SidebarCategoryListProps {
- isOpen: boolean;
-}
-
-export const SidebarWrapper = styled.div`
- width: 290px;
- min-height: calc(100vh - 200px);
- padding: 120px 20px 0px 20px;
- border-right: 1px solid ${COLOR.border};
- background-color: ${COLOR.white};
- @media screen and (max-width: ${RESPONSIVE_WIDTH.desktop}) {
- display: none;
- }
-`;
-
-export const SidebarCategoryTitle = styled.p`
- font: ${FONT_STYLE.xl.semibold};
-`;
-
-export const SidebarCategoryDescription = styled.p`
- font: ${FONT_STYLE.sm.normal};
- color: ${COLOR.comment};
- margin-top: 30px;
- word-break: keep-all;
-`;
-
-export const SidebarCategoryList = styled.div`
- width: 100%;
- height: 100%;
- display: flex;
- margin-top: 30px;
- flex-direction: column;
- z-index: 49;
-
- @media screen and (max-width: ${RESPONSIVE_WIDTH.desktop}) {
- transition: all 0.6s ease-in-out;
- position: absolute;
- top: 45px;
- left: 0;
- height: fit-content;
- max-height: 0;
- overflow: hidden;
- margin-top: 0px;
- background-color: ${COLOR.background.light};
- ${({ isOpen }) => isOpen && 'max-height: 100vh;'}
- }
-`;
-
-export const SidebarCategory = styled(Link)`
- font: ${FONT_STYLE.lg.semibold};
- margin-bottom: 20px;
- color: ${COLOR.comment};
- line-height: 40px;
-
- ${({ isCurrentCategory }) =>
- isCurrentCategory &&
- `color: ${COLOR.black_text};
- text-decoration: underline;
- text-underline-offset: 12px;
- `}
-
- @media screen and (max-width: ${RESPONSIVE_WIDTH.desktop}) {
- margin-bottom: 0px;
- padding: 10px 15px;
- border-bottom: 1px solid ${COLOR.border};
- color: ${COLOR.comment};
- font: ${FONT_STYLE.sm.normal};
- ${({ isCurrentCategory }) =>
- isCurrentCategory &&
- `color: ${COLOR.primary.main};
- text-decoration: none;`};
- }
-`;
-
-export const SidebarMobileWrapper = styled.div`
- width: 100%;
- margin-top: 50px;
- height: inherit;
- position: relative;
-
- @media screen and (min-width: ${RESPONSIVE_WIDTH.desktop}) {
- display: none;
- }
-`;
-
-export const SidebarMobileButton = styled.button`
- display: none;
- width: 100%;
- height: 45px;
- background-color: ${COLOR.secondary.main};
- color: ${COLOR.white};
- padding: 0px 15px;
- z-index: 49;
-
- @media screen and (max-width: ${RESPONSIVE_WIDTH.desktop}) {
- display: flex;
- justify-content: space-between;
- align-items: center;
- &:active,
- &:focus {
- outline: none;
- border: none;
- }
- }
-`;
diff --git a/frontend/src/app/(client)/components/SignIn/components/InputUserInfo/index.tsx b/frontend/src/app/(client)/components/SignIn/components/InputUserInfo/index.tsx
deleted file mode 100644
index dc94e70b..00000000
--- a/frontend/src/app/(client)/components/SignIn/components/InputUserInfo/index.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-'use client';
-
-import { useRouter } from 'next/navigation';
-import { useState } from 'react';
-
-import { useAppDispatch } from '@/lib/hooks/redux';
-import { signIn } from '@/store/auth.slice';
-
-import { FixedEmail, InputID, InputPW, SignInButton } from './styled';
-import { useSignInMutation } from '@/lib/hooks/useApi';
-import { toast } from 'react-toastify';
-
-const InputUserInfo = () => {
- const [userInfo, setUserInfo] = useState({
- email: '',
- password: '',
- });
-
- const { mutate: signInMutation } = useSignInMutation();
-
- const router = useRouter();
- const dispatch = useAppDispatch();
-
- const handleInputChange = (e: React.ChangeEvent) => {
- setUserInfo((prev) => {
- return {
- ...prev,
- [e.target.id]: e.target.value,
- };
- });
- };
-
- const handleSubmit = (e: React.FormEvent) => {
- e.preventDefault();
-
- signInMutation(userInfo, {
- onSuccess(data, variables, context) {
- dispatch(
- signIn({
- id: data.member_id,
- token: `Bearer ${data.token}`,
- name: data.name,
- email: data.email,
- isModerator: data.is_moderator,
- }),
- );
- router.refresh();
- },
- onError(error, variables, context) {
- toast.error(error.message);
- },
- });
- };
-
- return (
-
- );
-};
-
-export default InputUserInfo;
diff --git a/frontend/src/app/(client)/components/SignIn/components/InputUserInfo/styled.ts b/frontend/src/app/(client)/components/SignIn/components/InputUserInfo/styled.ts
deleted file mode 100644
index ce5cd987..00000000
--- a/frontend/src/app/(client)/components/SignIn/components/InputUserInfo/styled.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import styled from 'styled-components';
-
-import { BORDER_RADIUS, COLOR, FONT_STYLE } from '@/constants';
-
-export const Input = styled.input`
- min-width: 232px;
- border: 1px solid ${COLOR.border};
- border-radius: ${BORDER_RADIUS.sm};
- padding: 8px;
- font: ${FONT_STYLE.base.normal};
- outline: none;
- &::placeholder {
- color: ${COLOR.border};
- font-style: italic;
- }
-`;
-
-export const InputID = styled(Input)`
- border-bottom-left-radius: 0;
- border-bottom-right-radius: 0;
-`;
-
-export const InputPW = styled(Input)`
- border-top-left-radius: 0;
- border-top-right-radius: 0;
-`;
-
-export const FixedEmail = styled.div`
- position: absolute;
- color: ${COLOR.comment};
- right: 10px;
- top: 25%;
- transform: translate(0, -50%);
- font: ${FONT_STYLE.xs.normal};
-`;
-
-export const SignInButton = styled.button`
- min-width: 70px;
- max-width: 110px;
- border: none;
- border-radius: ${BORDER_RADIUS.sm};
- flex-grow: 1;
- background-color: ${COLOR.primary.main};
- color: ${COLOR.white};
- font: ${FONT_STYLE.base.normal};
-`;
diff --git a/frontend/src/app/(client)/components/SignIn/index.tsx b/frontend/src/app/(client)/components/SignIn/index.tsx
deleted file mode 100644
index fdf336aa..00000000
--- a/frontend/src/app/(client)/components/SignIn/index.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { FONT_STYLE } from '@/adminConstants';
-
-import InputUserInfo from './components/InputUserInfo';
-import { AlertComment, Divisor, FindLink, SignUpLink, SuggestionComment } from './styled';
-
-const SignIn = () => (
-
-
로그인이 필요한 서비스입니다.
-
-
-
- 아이디 / 비밀번호 찾기
-
-
- 처음오셨나요? 회원가입
-
-
-
-);
-
-export default SignIn;
diff --git a/frontend/src/app/(client)/components/SignIn/styled.ts b/frontend/src/app/(client)/components/SignIn/styled.ts
deleted file mode 100644
index 261a61fb..00000000
--- a/frontend/src/app/(client)/components/SignIn/styled.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-'use client';
-
-import Link from 'next/link';
-import styled from 'styled-components';
-
-import { BORDER_RADIUS, COLOR, FONT_STYLE } from '@/constants';
-
-export const AlertComment = styled.div`
- padding: 8px;
- border-radius: ${BORDER_RADIUS.sm};
- background-color: ${COLOR.background.light};
- font: ${FONT_STYLE.base.normal};
- text-align: center;
- color: ${COLOR.comment};
-`;
-
-export const FindLink = styled(Link)`
- font: ${FONT_STYLE.xs.normal};
- color: ${COLOR.comment};
-`;
-
-export const SignUpLink = styled(Link)`
- font: ${FONT_STYLE.xs.normal};
- color: ${COLOR.comment};
- text-decoration: underline;
-`;
-
-export const SuggestionComment = styled.div`
- display: grid;
- grid-template-columns: 1fr 1fr;
- text-align: center;
- color: ${COLOR.comment};
-`;
-
-export const Divisor = styled.div`
- position: relative;
- font: ${FONT_STYLE.xs.normal};
- z-index: 0;
-
- &::after {
- content: '';
- position: absolute;
- bottom: 25%;
- right: 0;
- height: 50%;
- border-right: 1px solid ${COLOR.comment};
-`;
diff --git a/frontend/src/app/(client)/components/TeamBuildings/index.tsx b/frontend/src/app/(client)/components/TeamBuildings/index.tsx
deleted file mode 100644
index d0d232ab..00000000
--- a/frontend/src/app/(client)/components/TeamBuildings/index.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import TeamBuilding from '@/components/TeamBuilding';
-import { teamBuildingInfos } from '@/mocks/teamBuilding';
-
-import { AlertComment, AlertDescription, AlertLink, AlertTitle, TeamBuildingWrapper } from './styled';
-import GoPageIcon from '../GoPageIcon';
-import { Description, Title, TitleContent, TitleWrapper } from '../styled';
-
-const TeamBuildings = () => (
-
-
-
- 팀 빌딩
- 프로젝트 팀원을 모집하고 있나요? 함께할 팀을 찾고 있나요?
-
-
-
-
- {teamBuildingInfos.length === 0 && (
-
- 아직 팀이 생성되지 않았습니다.
- 지금 바로 새로운 팀을 생성해 보세요!
- [팀 생성하기]
-
- )}
- {teamBuildingInfos.map((team) => (
-
- ))}
-
-
-);
-
-export default TeamBuildings;
diff --git a/frontend/src/app/(client)/components/TeamBuildings/styled.ts b/frontend/src/app/(client)/components/TeamBuildings/styled.ts
deleted file mode 100644
index 521a862a..00000000
--- a/frontend/src/app/(client)/components/TeamBuildings/styled.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-'use client';
-
-import Link from 'next/link';
-import styled from 'styled-components';
-
-import { BORDER_RADIUS, COLOR, FONT_STYLE, RESPONSIVE_WIDTH } from '@/constants';
-
-export const TeamBuildingWrapper = styled.div`
- margin-top: 20px;
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- row-gap: 16px;
- justify-items: center;
-
- @media screen and (max-width: ${RESPONSIVE_WIDTH.desktop}) {
- grid-template-columns: repeat(2, 1fr);
- > :nth-child(3) {
- display: none;
- }
- }
- @media screen and (max-width: ${RESPONSIVE_WIDTH.tablet}) {
- grid-template-columns: repeat(1, 1fr);
- > :nth-child(2) {
- display: none;
- }
- }
-`;
-
-export const AlertComment = styled.div`
- grid-column: 1 / 4;
- width: 100%;
- margin: 8px;
- border-radius: ${BORDER_RADIUS.sm};
- background-color: ${COLOR.background.light};
- padding: 10px;
- text-align: center;
-`;
-
-export const AlertTitle = styled.p`
- margin: 10px;
- color: ${COLOR.black_text};
- font: ${FONT_STYLE.base.semibold};
-`;
-
-export const AlertDescription = styled.p`
- margin: 10px;
- color: ${COLOR.comment};
- font: ${FONT_STYLE.sm.normal};
-`;
-
-export const AlertLink = styled(Link)`
- display: block;
- margin: 10px;
- color: ${COLOR.comment};
- font: ${FONT_STYLE.base.normal};
-`;
diff --git a/frontend/src/app/(client)/components/styled.ts b/frontend/src/app/(client)/components/styled.ts
deleted file mode 100644
index d50b1135..00000000
--- a/frontend/src/app/(client)/components/styled.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-'use client';
-
-import styled from 'styled-components';
-
-import { COLOR, FONT_STYLE } from '@/constants';
-
-export const TitleWrapper = styled.div`
- display: flex;
-`;
-
-export const TitleContent = styled.div`
- display: flex;
- flex-direction: column;
-`;
-
-export const Title = styled.p`
- font: ${FONT_STYLE.lg.semibold};
- cursor: default;
-`;
-
-export const Description = styled.p`
- font: ${FONT_STYLE.sm.normal};
- color: ${COLOR.comment};
- cursor: default;
-`;
diff --git a/frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/components/HackathonInformationTypeButtons/index.tsx b/frontend/src/app/(client)/hackathon/[slug]/components/HackathonInformationTypeButtons/index.tsx
similarity index 100%
rename from frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/components/HackathonInformationTypeButtons/index.tsx
rename to frontend/src/app/(client)/hackathon/[slug]/components/HackathonInformationTypeButtons/index.tsx
diff --git a/frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/layout.tsx b/frontend/src/app/(client)/hackathon/[slug]/layout.tsx
similarity index 85%
rename from frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/layout.tsx
rename to frontend/src/app/(client)/hackathon/[slug]/layout.tsx
index 7acbcada..b8029834 100644
--- a/frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/layout.tsx
+++ b/frontend/src/app/(client)/hackathon/[slug]/layout.tsx
@@ -1,4 +1,4 @@
-import Title from '@/components/Title';
+import PageTitle from '@/components/common/PageTitle';
import { getHackathonInformation } from '@/lib/api/server.api';
import HackathonInformationTypeButtons from './components/HackathonInformationTypeButtons';
@@ -9,7 +9,7 @@ const Layout = async ({
const hackathonInformation = await getHackathonInformation(slug);
return (
-
+
{children}
diff --git a/frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/page.tsx b/frontend/src/app/(client)/hackathon/[slug]/page.tsx
similarity index 93%
rename from frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/page.tsx
rename to frontend/src/app/(client)/hackathon/[slug]/page.tsx
index 508aa16c..c5cc9740 100644
--- a/frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/page.tsx
+++ b/frontend/src/app/(client)/hackathon/[slug]/page.tsx
@@ -1,4 +1,4 @@
-import MarkdownViewer from '@/components/MarkdownViewer';
+import MarkdownViewer from '@/components/ui/hackathon/MarkdownViewer';
import { getHackathonInformation } from '@/lib/api/server.api';
import Image from 'next/image';
diff --git a/frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/prize/page.tsx b/frontend/src/app/(client)/hackathon/[slug]/prize/page.tsx
similarity index 100%
rename from frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/prize/page.tsx
rename to frontend/src/app/(client)/hackathon/[slug]/prize/page.tsx
diff --git a/frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/vote/components/HackathonTeamCreateModal/index.tsx b/frontend/src/app/(client)/hackathon/[slug]/vote/components/HackathonTeamCreateModal/index.tsx
similarity index 98%
rename from frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/vote/components/HackathonTeamCreateModal/index.tsx
rename to frontend/src/app/(client)/hackathon/[slug]/vote/components/HackathonTeamCreateModal/index.tsx
index 8ed60093..ba78e6db 100644
--- a/frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/vote/components/HackathonTeamCreateModal/index.tsx
+++ b/frontend/src/app/(client)/hackathon/[slug]/vote/components/HackathonTeamCreateModal/index.tsx
@@ -1,6 +1,6 @@
-import ImageUploader from '@/components/Formik/ImageUploader';
-import TextInput from '@/components/Formik/TextInput';
-import Title from '@/components/Title';
+import ImageUploader from '@/components/common/formik/ImageUploader';
+import TextInput from '@/components/common/formik/TextInput';
+import PageTitle from '@/components/common/PageTitle';
import { TeamMemberRole } from '@/data/hackathon';
import { useRegisterTeamMutation } from '@/lib/hooks/useApi';
import useBodyScrollLock from '@/lib/hooks/useBodyScrollLock';
@@ -103,7 +103,7 @@ const HackathonTeamCreateModal = ({ hackathonId, open, onClose }: HackathonTeamC
-
+
diff --git a/frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/vote/components/HackathonTeamReadModal/index.tsx b/frontend/src/app/(client)/hackathon/[slug]/vote/components/HackathonTeamReadModal/index.tsx
similarity index 97%
rename from frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/vote/components/HackathonTeamReadModal/index.tsx
rename to frontend/src/app/(client)/hackathon/[slug]/vote/components/HackathonTeamReadModal/index.tsx
index 76af2ee1..7089508a 100644
--- a/frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/vote/components/HackathonTeamReadModal/index.tsx
+++ b/frontend/src/app/(client)/hackathon/[slug]/vote/components/HackathonTeamReadModal/index.tsx
@@ -1,4 +1,4 @@
-import Title from '@/components/Title';
+import PageTitle from '@/components/common/PageTitle';
import { TeamMemberRole, teamMemberRoleInfo } from '@/data/hackathon';
import useBodyScrollLock from '@/lib/hooks/useBodyScrollLock';
import useOnClickOutside from '@/lib/hooks/useOnClickOutside';
@@ -40,7 +40,7 @@ const HackathonTeamReadModal = ({ selectedTeam, onClose }: HackathonTeamReadModa
className="flex h-[600px] w-full max-w-[900px] flex-col items-center gap-2 rounded bg-white p-5 sm:h-[700px]"
>
-
+
diff --git a/frontend/src/app/(client)/hackathon/[slug]/vote/components/ReadmeViewer/index.tsx b/frontend/src/app/(client)/hackathon/[slug]/vote/components/ReadmeViewer/index.tsx
new file mode 100644
index 00000000..17178d6c
--- /dev/null
+++ b/frontend/src/app/(client)/hackathon/[slug]/vote/components/ReadmeViewer/index.tsx
@@ -0,0 +1,25 @@
+import { useGithubReadme } from '@/lib/hooks/useGithubReadme';
+import MarkdownViewer from '@/components/ui/hackathon/MarkdownViewer';
+
+interface ReadmeViewerProps {
+ repoUrl: string;
+}
+
+const ReadmeViewer = ({ repoUrl }: ReadmeViewerProps) => {
+ const { data: readme, isPending, isError } = useGithubReadme(repoUrl);
+ if (isPending)
+ return (
+
+ README 문서를 불러오는 중입니다.
+
+ );
+ if (isError || !readme)
+ return (
+
+ README 문서를 불러오는 데 실패했습니다.
+
+ );
+ return ;
+};
+
+export default ReadmeViewer;
diff --git a/frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/vote/components/TeamCreateInputSection/index.tsx b/frontend/src/app/(client)/hackathon/[slug]/vote/components/TeamCreateInputSection/index.tsx
similarity index 100%
rename from frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/vote/components/TeamCreateInputSection/index.tsx
rename to frontend/src/app/(client)/hackathon/[slug]/vote/components/TeamCreateInputSection/index.tsx
diff --git a/frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/vote/components/TeamMemberInput/index.tsx b/frontend/src/app/(client)/hackathon/[slug]/vote/components/TeamMemberInput/index.tsx
similarity index 94%
rename from frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/vote/components/TeamMemberInput/index.tsx
rename to frontend/src/app/(client)/hackathon/[slug]/vote/components/TeamMemberInput/index.tsx
index 6e8aaf48..b0270dfc 100644
--- a/frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/vote/components/TeamMemberInput/index.tsx
+++ b/frontend/src/app/(client)/hackathon/[slug]/vote/components/TeamMemberInput/index.tsx
@@ -1,5 +1,5 @@
-import Dropdown from '@/components/Formik/Dropdown';
-import TextInput from '@/components/Formik/TextInput';
+import Dropdown from '@/components/common/formik/Dropdown';
+import TextInput from '@/components/common/formik/TextInput';
import { memberRoleOptions, teamMemberRoleInfo } from '@/data/hackathon';
import { useStudentMemberMutation } from '@/lib/hooks/useApi';
import useDebounce from '@/lib/hooks/useDebounce';
diff --git a/frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/vote/page.tsx b/frontend/src/app/(client)/hackathon/[slug]/vote/page.tsx
similarity index 97%
rename from frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/vote/page.tsx
rename to frontend/src/app/(client)/hackathon/[slug]/vote/page.tsx
index 506c0553..d1385433 100644
--- a/frontend/src/app/(client)/(withSidebar)/hackathon/[slug]/vote/page.tsx
+++ b/frontend/src/app/(client)/hackathon/[slug]/vote/page.tsx
@@ -1,6 +1,6 @@
'use client';
-import Pagination from '@/app/(client)/components/Pagination';
+import Pagination from '@/components/common/Pagination';
import { useHackathonTeamsQuery } from '@/lib/hooks/useApi';
import { HackathonTeamDto } from '@/types/common.dto';
import Image from 'next/image';
diff --git a/frontend/src/app/(client)/hackathon/layout.tsx b/frontend/src/app/(client)/hackathon/layout.tsx
new file mode 100644
index 00000000..34b7f7e5
--- /dev/null
+++ b/frontend/src/app/(client)/hackathon/layout.tsx
@@ -0,0 +1,5 @@
+import SidebarLayout from '@/components/layout/SidebarLayout';
+
+export default function Layout({ children }: Readonly<{ children: React.ReactNode }>) {
+ return {children} ;
+}
diff --git a/frontend/src/app/(client)/(withSidebar)/hackathon/page.tsx b/frontend/src/app/(client)/hackathon/page.tsx
similarity index 97%
rename from frontend/src/app/(client)/(withSidebar)/hackathon/page.tsx
rename to frontend/src/app/(client)/hackathon/page.tsx
index ff85af86..30052f69 100644
--- a/frontend/src/app/(client)/(withSidebar)/hackathon/page.tsx
+++ b/frontend/src/app/(client)/hackathon/page.tsx
@@ -1,5 +1,5 @@
-import Pagination from '@/app/(client)/components/Pagination';
-import Title from '@/components/Title';
+import Pagination from '@/components/common/Pagination';
+import PageTitle from '@/components/common/PageTitle';
import { HackathonState } from '@/data/hackathon';
import { getHackathons } from '@/lib/api/server.api';
import classname from 'classnames';
@@ -44,7 +44,7 @@ const Page = async ({ searchParams }: { searchParams?: { [key: string]: string |
return (
-
diff --git a/frontend/src/app/(client)/(withSidebar)/hackathon/sw-contest/page.tsx b/frontend/src/app/(client)/hackathon/sw-contest/page.tsx
similarity index 61%
rename from frontend/src/app/(client)/(withSidebar)/hackathon/sw-contest/page.tsx
rename to frontend/src/app/(client)/hackathon/sw-contest/page.tsx
index 3db07350..dd5bdb0b 100644
--- a/frontend/src/app/(client)/(withSidebar)/hackathon/sw-contest/page.tsx
+++ b/frontend/src/app/(client)/hackathon/sw-contest/page.tsx
@@ -1,9 +1,9 @@
-import Title from '@/components/Title';
+import PageTitle from '@/components/common/PageTitle';
const Page = () => {
return (
-
+
개발 중인 기능입니다.
diff --git a/frontend/src/app/(client)/layout-styled.ts b/frontend/src/app/(client)/layout-styled.ts
deleted file mode 100644
index 65881ee9..00000000
--- a/frontend/src/app/(client)/layout-styled.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-'use client';
-
-import styled from 'styled-components';
-
-import { ADMIN_HEADER_HEIGHT, ADMIN_SIDEBAR_WIDTH, COLOR } from '@/adminConstants';
-
-export const PageWrapper = styled.div`
- width: 100vw;
- min-height: calc(100vh - 200px);
- background-color: ${COLOR.white};
-`;
-
-export const AdminPageWrapper = styled.div`
- width: 100vw;
- min-height: 100vh;
- background-color: ${COLOR.secondary.light};
- padding-top: calc(${ADMIN_HEADER_HEIGHT} + 2px);
- padding-left: ${ADMIN_SIDEBAR_WIDTH};
-`;
diff --git a/frontend/src/app/(client)/layout.tsx b/frontend/src/app/(client)/layout.tsx
index bd79c84e..6c832882 100644
--- a/frontend/src/app/(client)/layout.tsx
+++ b/frontend/src/app/(client)/layout.tsx
@@ -1,15 +1,12 @@
-/* eslint-disable @next/next/no-page-custom-font */
+import Footer from '@/components/layout/Footer';
+import Header from '@/components/layout/Header';
-import Footer from '@/components/Footer';
-import Header from '@/components/Header';
-
-import { PageWrapper } from './layout-styled';
-
-const RootLayout = ({ children }: Readonly<{ children: React.ReactNode }>) => (
- <>
-
-
{children}
-
- >
-);
-export default RootLayout;
+export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
+ return (
+ <>
+
+
{children}
+
+ >
+ );
+}
diff --git a/frontend/src/app/(client)/milestone/layout.tsx b/frontend/src/app/(client)/milestone/layout.tsx
new file mode 100644
index 00000000..34b7f7e5
--- /dev/null
+++ b/frontend/src/app/(client)/milestone/layout.tsx
@@ -0,0 +1,5 @@
+import SidebarLayout from '@/components/layout/SidebarLayout';
+
+export default function Layout({ children }: Readonly<{ children: React.ReactNode }>) {
+ return
{children} ;
+}
diff --git a/frontend/src/app/(client)/milestone/page.tsx b/frontend/src/app/(client)/milestone/page.tsx
new file mode 100644
index 00000000..ddf39bef
--- /dev/null
+++ b/frontend/src/app/(client)/milestone/page.tsx
@@ -0,0 +1,58 @@
+import Link from 'next/link';
+
+export default function MilestonePage() {
+ return (
+
+
+
+
마일스톤이란
+ 마일스톤은 전공자들의 SW역량을 종합적으로 평가하기 위한 역량평가지수입니다.
+
+ 학생들은 교내외 여러 활동들을 통하여 실전적 SW역량, 글로벌 역량, 커뮤니케이션 역량을 균형있게 함양하고
+ SW중심대학사업단에서는 학생들의 적립된 마일스톤 점수에 따라 매년 장학생을 선발하고 있습니다.
+
+
+
+ 마일스톤 등록하러 가기
+
+
+
+
+
+
+
+ 마일스톤 획득 방법
+ 각 영역별 활동 수행 시, 책정 기준에 따라 마일스톤을 획득할 수 있습니다.
+
+ 상세 내용은 아래 표를 참고해주세요.
+
+
+ 마일스톤 평가기간
+ 전년도 9월부터 당해년도 8월까지의 실적
+ ※ SW 창업, 오픈소스 SW 컨트리뷰션의 경우 당해년도 1월부터 9월까지의 실적만을 반영함.
+
+
+ 마일스톤 확인 방법
+ SW역량지원시스템에서는 나의 마일스톤 현황을 한 눈에 볼 수 있도록 제공하고 있습니다.
+
+ 로그인 후, 메인 페이지와 마이페이지에서 확인하실 수 있습니다.
+
+
+
+
+
+
+ );
+}
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/edit/page.tsx b/frontend/src/app/(client)/my-page/info-edit/page.tsx
similarity index 60%
rename from frontend/src/app/(client)/(withSidebar)/my-page/edit/page.tsx
rename to frontend/src/app/(client)/my-page/info-edit/page.tsx
index 429d9ef8..68f5ef31 100644
--- a/frontend/src/app/(client)/(withSidebar)/my-page/edit/page.tsx
+++ b/frontend/src/app/(client)/my-page/info-edit/page.tsx
@@ -1,13 +1,11 @@
-import Title from '@/components/Title';
+import PageTitle from '@/components/common/PageTitle';
-const Page = () => {
+export default function EditMyInfoPage() {
return (
);
-};
-
-export default Page;
+}
diff --git a/frontend/src/app/(client)/my-page/layout.tsx b/frontend/src/app/(client)/my-page/layout.tsx
new file mode 100644
index 00000000..34b7f7e5
--- /dev/null
+++ b/frontend/src/app/(client)/my-page/layout.tsx
@@ -0,0 +1,5 @@
+import SidebarLayout from '@/components/layout/SidebarLayout';
+
+export default function Layout({ children }: Readonly<{ children: React.ReactNode }>) {
+ return
{children} ;
+}
diff --git a/frontend/src/app/(client)/my-page/milestone-list/page.tsx b/frontend/src/app/(client)/my-page/milestone-list/page.tsx
new file mode 100644
index 00000000..d2919704
--- /dev/null
+++ b/frontend/src/app/(client)/my-page/milestone-list/page.tsx
@@ -0,0 +1,23 @@
+import Link from 'next/link';
+
+import PageTitle from '@/components/common/PageTitle';
+import MilestoneHistoryTable from '@/components/ui/milestone/MilestoneHistoryTable';
+
+export interface MilestoneRegisterPageProps {
+ searchParams?: { [key: string]: string | undefined };
+}
+
+export default async function MilestoneHistoryListPage({ searchParams }: MilestoneRegisterPageProps) {
+ const pageNumber = searchParams?.page ? parseInt(searchParams.page, 10) : 1;
+ return (
+
+ );
+}
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/register/write/page.tsx b/frontend/src/app/(client)/my-page/milestone-register/page.tsx
similarity index 90%
rename from frontend/src/app/(client)/(withSidebar)/my-page/milestone/register/write/page.tsx
rename to frontend/src/app/(client)/my-page/milestone-register/page.tsx
index 6584ae34..6ac54d60 100644
--- a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/register/write/page.tsx
+++ b/frontend/src/app/(client)/my-page/milestone-register/page.tsx
@@ -1,23 +1,20 @@
-/* eslint-disable implicit-arrow-linebreak */
-
'use client';
import { Form, Formik } from 'formik';
-import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { useState } from 'react';
import * as Yup from 'yup';
import { toast } from 'react-toastify';
-import { DatePicker } from '@/components/Formik/DatePicker';
-import { FileUploader } from '@/components/Formik/FileUploader';
-import { TextInput } from '@/app/(client)/components/Formik/TextInput';
-import PageTitle from '@/app/(client)/components/PageTitle';
+import { DatePicker } from '@/components/common/formik/DatePicker';
+import { FileUploader } from '@/components/common/formik/FileUploader';
+import TextInput from '@/components/common/formik/TextInput';
+import PageTitle from '@/components/common/PageTitle';
import { useMilestoneHistoryCreateMutation } from '@/lib/hooks/useApi';
import { MilestoneHistoryCreateDto } from '@/types/common.dto';
import { Milestone, MilestoneCategory } from '@/types/milestone';
-import MilestoneDropdown from './components/MilestoneDropdown';
+import MilestoneCategoryDropdown from '@/components/ui/milestone/MilestoneCategoryDropdown';
const validationSchema = Yup.object().shape({
milestoneId: Yup.number().min(1, '활동 구분을 선택해주세요.'),
@@ -52,7 +49,7 @@ const initialValues: MilestoneHistoryInfo = {
activatedAt: '',
};
-const Page = () => {
+export default function MilestoneRegisterPage() {
const router = useRouter();
const { mutate: createMilestoneHistory } = useMilestoneHistoryCreateMutation();
const [selectedCategory, setSelectedCategory] = useState
();
@@ -60,9 +57,10 @@ const Page = () => {
const handleSubmitButtonClick = (values: MilestoneHistoryCreateDto) => {
createMilestoneHistory(values, {
- onSuccess: () => {
+ onSuccess: (res) => {
+ console.log(res);
toast.info('실적 등록에 성공하였습니다.');
- router.push('/my-page/milestone/register');
+ // router.push('/my-page/milestone-list');
},
onError: () => {
toast.error('실적 등록에 실패하였습니다.');
@@ -72,7 +70,7 @@ const Page = () => {
return (
-
+
실적 등록하기
@@ -86,7 +84,7 @@ const Page = () => {
>
{({ isSubmitting, values, touched, handleChange, handleBlur, setFieldValue, errors }) => (
@@ -200,6 +196,4 @@ const Page = () => {
);
-};
-
-export default Page;
+}
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/page.tsx b/frontend/src/app/(client)/my-page/milestone/page.tsx
similarity index 50%
rename from frontend/src/app/(client)/(withSidebar)/my-page/milestone/page.tsx
rename to frontend/src/app/(client)/my-page/milestone/page.tsx
index 02206d48..864fa3b0 100644
--- a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/page.tsx
+++ b/frontend/src/app/(client)/my-page/milestone/page.tsx
@@ -1,18 +1,16 @@
'use client';
-import { DateTime } from 'luxon';
import { useEffect, useState } from 'react';
+import { DateTime } from 'luxon';
+import { useSearchParams } from 'next/navigation';
-import { COLOR } from '@/constants';
-import { Period } from '@/types/common';
+import PeriodSearchBox from '@/components/common/PeriodSearchBox';
+import MyPageMilestoneOverview from '@/components/ui/my-page/MyPageMilestoneOverview';
+import MilestoneAcceptedTable from '@/components/ui/milestone/MilestoneAcceptedTable';
-import MilestoneHistoryTable from './components/MilestoneHistoryTable';
-import MilestoneOverview from './components/MilestoneOverview';
-import { Content, SubTitle } from './styled';
-import MilestonePeriodSearchForm from '@/components/MilestonePeriodSearchForm';
-import { useSearchParams } from 'next/navigation';
+import { Period } from '@/types/common';
-const Page = () => {
+export default function MyPageMilestonePage() {
const searchParams = useSearchParams();
const [pageNumber, setPageNumber] = useState
(1);
const [filterPeriod, setFilterPeriod] = useState({
@@ -29,22 +27,16 @@ const Page = () => {
}, [searchParams]);
return (
-
+
-
전체 현황
-
-
-
획득 내역
-
-
+
전체 현황
+
+
+
획득 내역
+
+
);
-};
-
-export default Page;
+}
diff --git a/frontend/src/app/(client)/my-page/page.tsx b/frontend/src/app/(client)/my-page/page.tsx
new file mode 100644
index 00000000..5afe2c5d
--- /dev/null
+++ b/frontend/src/app/(client)/my-page/page.tsx
@@ -0,0 +1,19 @@
+import PageSubTitle from '@/components/common/PageSubTitle';
+
+import MyPageMilestoneHistory from '@/components/ui/my-page/MyPageMilestoneHistory';
+import MyPageMilestone from '@/components/ui/my-page/MyPageMilestone';
+import MyPageStudentInfo from '@/components/ui/my-page/MyPageStudentInfo';
+
+export default function MyPage() {
+ return (
+
+ );
+}
diff --git a/frontend/src/app/(client)/page.tsx b/frontend/src/app/(client)/page.tsx
index f4d3cee3..c438140d 100644
--- a/frontend/src/app/(client)/page.tsx
+++ b/frontend/src/app/(client)/page.tsx
@@ -1,31 +1,30 @@
-import Announcement from './components/Announcement';
-import ExternalLink from './components/ExternalLink';
-import Milestone from './components/Milestone';
-import PnuLink from './components/PnuLink';
-import TeamBuildings from './components/TeamBuildings';
-import { AnnouncementContent, ContentWrapper, MilestoneWrapper, FlexWrapper, MainPageWrapper } from './styled';
+import HomeAnnouncement from '@/components/ui/home/HomeAnnouncement';
+import HomeExternalLink from '@/components/ui/home/HomeExternalLink';
+import HomeMilestone from '@/components/ui/home/HomeMilestone';
+import HomePnuLink from '@/components/ui/home/HomePnuLink';
+import HomeTeamBuilding from '@/components/ui/home/HomeTeamBuilding';
const Page = () => (
-
-
-
-
-
-
-
-
-
-
-
-
- {/* TODO: 팀빌딩 구현 완료 되면 주석 풀기
-
-
- */}
-
-
-
-
+
+
+
+
+
+ {/* TODO: 팀빌딩 구현 완료 되면 주석 풀기 */}
+ {/*
+
+
*/}
+
+
+
+
);
export default Page;
diff --git a/frontend/src/app/(client)/styled.ts b/frontend/src/app/(client)/styled.ts
deleted file mode 100644
index a7c3a7d8..00000000
--- a/frontend/src/app/(client)/styled.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-'use client';
-
-import styled from 'styled-components';
-
-import { MAX_WIDTH, RESPONSIVE_WIDTH } from '@/constants';
-
-export const MainPageWrapper = styled.div`
- max-width: ${MAX_WIDTH};
- min-height: calc(100vh - 200px);
- margin: auto;
- padding: 77px 0 40px;
- display: flex;
- flex-direction: column;
-
- @media screen and (max-width: ${RESPONSIVE_WIDTH.desktop}) {
- padding-top: 50px;
- }
-`;
-
-export const ContentWrapper = styled.div`
- width: 100%;
- margin-top: 40px;
- padding: 10px;
-`;
-
-export const FlexWrapper = styled.div`
- display: flex;
- gap: 10px;
- @media screen and (max-width: ${RESPONSIVE_WIDTH.tablet}) {
- flex-direction: column;
- gap: 0;
- }
-`;
-
-export const MilestoneWrapper = styled(ContentWrapper)`
- width: 500px;
- flex-shrink: 0;
- @media screen and (max-width: ${RESPONSIVE_WIDTH.desktop}) {
- width: 380px;
- }
-
- @media screen and (max-width: ${RESPONSIVE_WIDTH.tablet}) {
- width: 100%;
- }
-`;
-
-export const AnnouncementContent = styled(ContentWrapper)`
- flex-grow: 1;
- min-width: 0;
-`;
diff --git a/frontend/src/app/(client)/team-building/layout.tsx b/frontend/src/app/(client)/team-building/layout.tsx
new file mode 100644
index 00000000..34b7f7e5
--- /dev/null
+++ b/frontend/src/app/(client)/team-building/layout.tsx
@@ -0,0 +1,5 @@
+import SidebarLayout from '@/components/layout/SidebarLayout';
+
+export default function Layout({ children }: Readonly<{ children: React.ReactNode }>) {
+ return {children} ;
+}
diff --git a/frontend/src/app/(client)/(withSidebar)/team-building/page.tsx b/frontend/src/app/(client)/team-building/page.tsx
similarity index 60%
rename from frontend/src/app/(client)/(withSidebar)/team-building/page.tsx
rename to frontend/src/app/(client)/team-building/page.tsx
index ba587ac6..8b7aecbd 100644
--- a/frontend/src/app/(client)/(withSidebar)/team-building/page.tsx
+++ b/frontend/src/app/(client)/team-building/page.tsx
@@ -1,13 +1,11 @@
-import Title from '@/components/Title';
+import PageTitle from '@/components/common/PageTitle';
-const Page = () => {
+export default function TeamBuildingPage() {
return (
);
-};
-
-export default Page;
+}
diff --git a/frontend/src/app/admin/contest/create/page.tsx b/frontend/src/app/admin/contest/create/page.tsx
index bf4f4cdf..5435e9ab 100644
--- a/frontend/src/app/admin/contest/create/page.tsx
+++ b/frontend/src/app/admin/contest/create/page.tsx
@@ -1,9 +1,7 @@
-const Page = () => {
+export default function ContestCreatePage() {
return (
);
-};
-
-export default Page;
+}
diff --git a/frontend/src/app/admin/contest/list/page.tsx b/frontend/src/app/admin/contest/page.tsx
similarity index 79%
rename from frontend/src/app/admin/contest/list/page.tsx
rename to frontend/src/app/admin/contest/page.tsx
index bf4f4cdf..a42d4efe 100644
--- a/frontend/src/app/admin/contest/list/page.tsx
+++ b/frontend/src/app/admin/contest/page.tsx
@@ -1,9 +1,7 @@
-const Page = () => {
+export default function ContestListPage() {
return (
);
-};
-
-export default Page;
+}
diff --git a/frontend/src/app/admin/faculty/list/page.tsx b/frontend/src/app/admin/faculty/page.tsx
similarity index 73%
rename from frontend/src/app/admin/faculty/list/page.tsx
rename to frontend/src/app/admin/faculty/page.tsx
index d9d52c7e..6b9ee726 100644
--- a/frontend/src/app/admin/faculty/list/page.tsx
+++ b/frontend/src/app/admin/faculty/page.tsx
@@ -1,17 +1,19 @@
-/* eslint-disable max-len */
-
import { headers } from 'next/headers';
-import Pagination from '@/adminComponents/Pagination';
-import SearchBox from '@/components/SearchBox';
+import AdminSearchBox from '@/components/common/admin/AdminSearchBox';
+import AdminPagination from '@/components/common/admin/AdminPagination';
+import FacultyMemberTable from '@/components/ui/admin/faculty/FacultyMemberTable';
import { facultyFieldCategories, members } from '@/mocks/adminMember';
-import MemberTable from './components/MemberTable';
import { getFacultyMembers } from '@/lib/api/server.api';
import { AuthSliceState } from '@/store/auth.slice';
import { getAuthFromCookie } from '@/lib/utils/auth';
-const Page = async ({ searchParams }: { searchParams?: { [key: string]: string | undefined } }) => {
+export interface FacultyListPageProps {
+ searchParams?: { [key: string]: string | undefined };
+}
+
+export default async function FacultyListPage({ searchParams }: FacultyListPageProps) {
const headersList = headers();
const pathname = headersList.get('x-pathname') || '';
@@ -29,18 +31,18 @@ const Page = async ({ searchParams }: { searchParams?: { [key: string]: string |
총 {members.length} 명의 회원이 있습니다.
-
{facultyMembers.content.length === 0 ? (
조건에 부합하는 교직원이 없습니다.
) : (
<>
-
-
+
);
-};
-
-export default Page;
+}
diff --git a/frontend/src/app/admin/faculty/register/page.tsx b/frontend/src/app/admin/faculty/register/page.tsx
index e8bf2bda..6cac65f5 100644
--- a/frontend/src/app/admin/faculty/register/page.tsx
+++ b/frontend/src/app/admin/faculty/register/page.tsx
@@ -1,23 +1,15 @@
-/* eslint-disable import/no-unresolved */
-/* eslint-disable import/no-extraneous-dependencies */
-/* eslint-disable jsx-a11y/label-has-associated-control */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
-/* eslint-disable max-len */
-
'use client';
-import { Form, Formik } from 'formik';
+import { useState } from 'react';
import Image from 'next/image';
import Link from 'next/link';
import { toast } from 'react-toastify';
+import { Form, Formik } from 'formik';
import * as Yup from 'yup';
-import 'react-toastify/dist/ReactToastify.css';
-import EmailTextInput from '@/components/Formik/EmailTextInput';
-import TextInput from '@/components/Formik/TextInput';
+import EmailTextInput from '@/components/common/formik/EmailTextInput';
+import TextInput from '@/components/common/formik/TextInput';
import { useRegisterFacultiesByFileMutation, useRegisterFacultyMutation } from '@/lib/hooks/useAdminApi';
-import { useState } from 'react';
interface FormType {
email: string;
@@ -37,7 +29,7 @@ const validationSchema = Yup.object().shape({
name: Yup.string().required('필수 입력란입니다. 이름을 입력해주세요.'),
});
-const Page = () => {
+export default function FacultyRegisterPage() {
const { mutate: registerFaculty } = useRegisterFacultyMutation();
const { mutate: registerFacultiesByFile } = useRegisterFacultiesByFileMutation();
const [errorMessage, setErrorMessage] = useState();
@@ -91,7 +83,13 @@ const Page = () => {
교직원 일괄 등록 방법
>
);
-};
-
-export default Page;
+}
diff --git a/frontend/src/app/admin/layout.tsx b/frontend/src/app/admin/layout.tsx
index 9efb636e..162447d7 100644
--- a/frontend/src/app/admin/layout.tsx
+++ b/frontend/src/app/admin/layout.tsx
@@ -1,18 +1,18 @@
-/* eslint-disable @next/next/no-page-custom-font */
+import AdminFooter from '@/components/layout/AdminFooter';
+import AdminHeader from '@/components/layout/AdminHeader';
+import AdminSidebar from '@/components/layout/AdminSidebar';
-import AdminFooter from '@/adminComponents/Footer';
-import AdminHeader from '@/adminComponents/Header';
-import AdminSidebar from '@/adminComponents/Sidebar';
-import { ADMIN_HEADER_HEIGHT, ADMIN_SIDEBAR_WIDTH, COLOR } from '@/adminConstants';
-
-const Layout = ({ children }: Readonly<{ children: React.ReactNode }>) => (
- <>
-
-
-
- >
-);
-export default Layout;
+export default function AdminLayout({ children }: Readonly<{ children: React.ReactNode }>) {
+ return (
+ <>
+
+
+
+ >
+ );
+}
diff --git a/frontend/src/app/admin/member/list/components/MemberTable/index.tsx b/frontend/src/app/admin/member/list/components/MemberTable/index.tsx
deleted file mode 100644
index b6854d52..00000000
--- a/frontend/src/app/admin/member/list/components/MemberTable/index.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-/* eslint-disable prettier/prettier */
-import { StudentMemberDto } from '@/types/common.dto';
-
-const MemberTable = ({ members }: { members: StudentMemberDto[] }) => (
-
-
- 이메일
- 이름
- 학번
- 주전공
- 부전공
- 복수전공
- 전화번호
- 진로
-
-
- {members.map((member) => {
- const emailWords = member.email.split('@');
- return (
-
-
- {emailWords[0]}
- @pusan.ac.kr
-
- {member.name}
- {member.id}
- {member.major}
- {member.minor}
- {member.doubleMajor}
- {member.phoneNumber}
-
- {member.careerDetail}
-
-
- );
- })}
-
-
-);
-
-export default MemberTable;
diff --git a/frontend/src/app/admin/member/page.tsx b/frontend/src/app/admin/member/page.tsx
deleted file mode 100644
index c703c9c7..00000000
--- a/frontend/src/app/admin/member/page.tsx
+++ /dev/null
@@ -1,8 +0,0 @@
-import { redirect } from 'next/navigation';
-
-const Page = () => {
- redirect('/admin/member/list');
- return null;
-};
-
-export default Page;
diff --git a/frontend/src/app/admin/milestone/list/[slug]/components/FilePreview/index.tsx b/frontend/src/app/admin/milestone/[slug]/components/FilePreview/index.tsx
similarity index 100%
rename from frontend/src/app/admin/milestone/list/[slug]/components/FilePreview/index.tsx
rename to frontend/src/app/admin/milestone/[slug]/components/FilePreview/index.tsx
diff --git a/frontend/src/app/admin/milestone/list/[slug]/components/MilestoneHistoryStatusChangeButton/index.tsx b/frontend/src/app/admin/milestone/[slug]/components/MilestoneHistoryStatusChangeButton/index.tsx
similarity index 94%
rename from frontend/src/app/admin/milestone/list/[slug]/components/MilestoneHistoryStatusChangeButton/index.tsx
rename to frontend/src/app/admin/milestone/[slug]/components/MilestoneHistoryStatusChangeButton/index.tsx
index 2a71a13b..5ebc1b88 100644
--- a/frontend/src/app/admin/milestone/list/[slug]/components/MilestoneHistoryStatusChangeButton/index.tsx
+++ b/frontend/src/app/admin/milestone/[slug]/components/MilestoneHistoryStatusChangeButton/index.tsx
@@ -1,12 +1,10 @@
-/* eslint-disable implicit-arrow-linebreak */
-
'use client';
import { useRouter } from 'next/navigation';
import { useState } from 'react';
import { toast } from 'react-toastify';
-import TextInput from '@/components/Formik/TextInput';
+import TextInput from '@/components/common/formik/TextInput';
import { MilestoneHistoryStatus } from '@/data/milestone';
import {
useMilestoneHistoryStatusApproveMutation,
@@ -83,7 +81,7 @@ const MilestoneHistoryStatusChangeButton = ({ historyId, status }: MilestoneHist
반려
diff --git a/frontend/src/app/admin/milestone/list/[slug]/not-found.tsx b/frontend/src/app/admin/milestone/[slug]/not-found.tsx
similarity index 93%
rename from frontend/src/app/admin/milestone/list/[slug]/not-found.tsx
rename to frontend/src/app/admin/milestone/[slug]/not-found.tsx
index 713737a5..2d1684f4 100644
--- a/frontend/src/app/admin/milestone/list/[slug]/not-found.tsx
+++ b/frontend/src/app/admin/milestone/[slug]/not-found.tsx
@@ -7,7 +7,7 @@ export default function NotFound() {
404 Not Found
요청하신 리소스를 찾을 수 없습니다.
목록으로
diff --git a/frontend/src/app/admin/milestone/list/[slug]/page.tsx b/frontend/src/app/admin/milestone/[slug]/page.tsx
similarity index 90%
rename from frontend/src/app/admin/milestone/list/[slug]/page.tsx
rename to frontend/src/app/admin/milestone/[slug]/page.tsx
index 92ea9b8e..ed7990cd 100644
--- a/frontend/src/app/admin/milestone/list/[slug]/page.tsx
+++ b/frontend/src/app/admin/milestone/[slug]/page.tsx
@@ -1,15 +1,15 @@
-/* eslint-disable max-len */
import Link from 'next/link';
+import { notFound } from 'next/navigation';
+
+import MilestoneGroupLabel from '@/components/ui/milestone/MilestoneGroupLabel';
+import AdminMilestoneFilePreview from '@/components/ui/admin/milestone/AdminMilestoneFilePreview';
+import AdminMilestoneStatusChangeButton from '@/components/ui/admin/milestone/AdminMilestoneStatusChangeButton';
-import MilestoneGroupLabel from '@/components/MilestoneGroupLabel';
import { getMilestoneHistory } from '@/lib/api/server.api';
import { convertMilestoneHistoryStatus } from '@/lib/utils/utils';
+import { getAuthFromCookie } from '@/lib/utils/auth';
-import FilePreview from './components/FilePreview';
-import MilestoneHistoryStatusChangeButton from './components/MilestoneHistoryStatusChangeButton';
-import { notFound } from 'next/navigation';
import { AuthSliceState } from '@/store/auth.slice';
-import { getAuthFromCookie } from '@/lib/utils/auth';
interface MilestoneHistoryDetailPageProps {
params: {
@@ -103,20 +103,20 @@ const Page = async ({ params: { slug } }: MilestoneHistoryDetailPageProps) => {
{history.rejectReason}
)}
-
+
목록으로
diff --git a/frontend/src/app/admin/milestone/list/components/MilestoneHistoryTable/index.tsx b/frontend/src/app/admin/milestone/list/components/MilestoneHistoryTable/index.tsx
deleted file mode 100644
index 728f0f2b..00000000
--- a/frontend/src/app/admin/milestone/list/components/MilestoneHistoryTable/index.tsx
+++ /dev/null
@@ -1,142 +0,0 @@
-/* eslint-disable max-len */
-/* eslint-disable jsx-a11y/control-has-associated-label */
-import Link from 'next/link';
-
-import { MilestoneHistoryStatus } from '@/data/milestone';
-import { convertMilestoneHistoryStatus } from '@/lib/utils/utils';
-import { MilestoneHistoryDto } from '@/types/common.dto';
-
-interface MilestoneHistoryTableProps {
- histories: MilestoneHistoryDto[];
-}
-
-const MilestoneHistoryTable = ({ histories }: MilestoneHistoryTableProps) => {
- const getHistoryStatus = (status: string) => {
- switch (status) {
- case MilestoneHistoryStatus.PENDING:
- return
{convertMilestoneHistoryStatus(status)} ;
- case MilestoneHistoryStatus.APPROVED:
- return (
-
{convertMilestoneHistoryStatus(status)}
- );
- case MilestoneHistoryStatus.REJECTED:
- return (
-
- {convertMilestoneHistoryStatus(status)}
-
- );
- default:
- return convertMilestoneHistoryStatus(status);
- }
- };
-
- return (
-
-
-
- No.
- 이름
- 학번
- 활동 코드
- 활동명
- 건당 점수
- 활동 횟수(건)
- 활동일
- 등록일
- 승인 여부
-
-
-
- {histories?.map((history) => (
-
-
-
- {history.id}
-
-
-
-
- {history.student.name}
-
-
-
-
- {history.student.id}
-
-
-
-
- {history.milestone.id}
-
-
-
-
- {history.description}
-
-
-
-
- {history.milestone.score}
-
-
-
-
- {history.count}
-
-
-
-
- {history.activatedAt}
-
-
-
-
- {history.createdAt.slice(0, 10)}
-
-
-
-
- {getHistoryStatus(history.status)}
-
-
-
- ))}
-
-
- );
-};
-
-export default MilestoneHistoryTable;
diff --git a/frontend/src/app/admin/milestone/list/page.tsx b/frontend/src/app/admin/milestone/page.tsx
similarity index 74%
rename from frontend/src/app/admin/milestone/list/page.tsx
rename to frontend/src/app/admin/milestone/page.tsx
index 7120f81f..19dd6d24 100644
--- a/frontend/src/app/admin/milestone/list/page.tsx
+++ b/frontend/src/app/admin/milestone/page.tsx
@@ -1,15 +1,14 @@
-/* eslint-disable max-len */
import { headers } from 'next/headers';
-import Pagination from '@/adminComponents/Pagination';
-import SearchBox from '@/components/SearchBox';
+import AdminPagination from '@/components/common/admin/AdminPagination';
+import AdminSearchBox from '@/components/common/admin/AdminSearchBox';
+import AdminMilestoneTable from '@/components/ui/admin/milestone/AdminMilestoneTable';
+import AdminMilestoneDownloadButton from '@/components/ui/admin/milestone/AdminMilestoneDownloadButton';
+
import { milestoneHistorySearchField } from '@/data/milestone';
import { getMilestoneHistories } from '@/lib/api/server.api';
-
-import MilestoneHistoryTable from './components/MilestoneHistoryTable';
-import MilestoneHistoryExcelFileDownloadButton from './components/MilestoneHistoryTable/MilestoneHistoryExcelFileDownloadButton.tsx';
-import { AuthSliceState } from '@/store/auth.slice';
import { getAuthFromCookie } from '@/lib/utils/auth';
+import { AuthSliceState } from '@/store/auth.slice';
const Page = async ({ searchParams }: { searchParams?: { [key: string]: string | undefined } }) => {
const headersList = headers();
@@ -35,17 +34,17 @@ const Page = async ({ searchParams }: { searchParams?: { [key: string]: string |
총
{milestoneHistories?.totalElements ?? 0} 건의 내역이
있습니다.
-
-
+
-
{
+export default function MilestoneRankPage() {
const [filterPeriod, setFilterPeriod] = useState({
startDate: DateTime.now().minus({ years: 1 }).toFormat('yyyy-MM-dd'),
endDate: DateTime.now().toFormat('yyyy-MM-dd'),
@@ -28,7 +23,6 @@ const Page = () => {
const searchParams = useSearchParams();
const pathname = usePathname();
const page = parseInt(searchParams.get('page') || '1', 10);
- console.log(page);
const { data: excelFile } = useMilestoneHistoryScoreExcelFileQuery(
searchFilterPeriod.startDate,
@@ -62,11 +56,7 @@ const Page = () => {
return (
@@ -77,9 +67,9 @@ const Page = () => {
학번
총점
{Object.values(MilestoneGroup).map((group) => (
- <>
+
{milestones &&
- milestones[group]?.map((milestone) => (
+ milestones[group].map((milestone) => (
{milestone.name}
@@ -87,37 +77,38 @@ const Page = () => {
{convertMilestoneGroup(group)} SW역량 소계
- >
+
))}
- {milestoneScores?.content?.map((milestoneScore, index) => (
-
- {milestoneScores!.size * milestoneScores!.number + index + 1}
- {milestoneScore.student.name}
- {milestoneScore.student.id}
-
- {Object.values(milestoneScore.milestoneScores).reduce(
- (accumulator, currentValue) =>
- accumulator + currentValue.reduce((acc, curr) => acc + curr.score, 0),
- 0,
- )}
-
- {Object.values(MilestoneGroup).map((group) => (
- <>
- {milestoneScore.milestoneScores[group].map((score) => (
-
- {score.score}
+ {milestoneScores &&
+ milestoneScores.content.map((milestoneScore, index) => (
+
+ {milestoneScores!.size * milestoneScores!.number + index + 1}
+ {milestoneScore.student.name}
+ {milestoneScore.student.id}
+
+ {Object.values(milestoneScore.milestoneScores).reduce(
+ (accumulator, currentValue) =>
+ accumulator + currentValue.reduce((acc, curr) => acc + curr.score, 0),
+ 0,
+ )}
+
+ {Object.values(MilestoneGroup).map((group) => (
+
+ {milestoneScore.milestoneScores[group].map((score) => (
+
+ {score.score}
+
+ ))}
+
+ {milestoneScore.milestoneScores[group].reduce((acc, curr) => acc + curr.score, 0)}
- ))}
-
- {milestoneScore.milestoneScores[group].reduce((acc, curr) => acc + curr.score, 0)}
-
- >
- ))}
-
- ))}
+
+ ))}
+
+ ))}
@@ -130,9 +121,7 @@ const Page = () => {
Excel로 다운로드
-
+
);
-};
-
-export default Page;
+}
diff --git a/frontend/src/app/admin/milestone/register/page.tsx b/frontend/src/app/admin/milestone/register/page.tsx
index b933ea03..d7578463 100644
--- a/frontend/src/app/admin/milestone/register/page.tsx
+++ b/frontend/src/app/admin/milestone/register/page.tsx
@@ -1,16 +1,12 @@
-/* eslint-disable max-len */
-/* eslint-disable operator-linebreak */
-/* eslint-disable implicit-arrow-linebreak */
-
'use client';
-import { Form, Formik } from 'formik';
import Image from 'next/image';
import { useRouter } from 'next/navigation';
+import { Form, Formik } from 'formik';
import { toast } from 'react-toastify';
import * as Yup from 'yup';
-import { FileUploader } from '@/components/Formik/FileUploader';
+import { FileUploader } from '@/components/common/formik/FileUploader';
import { useRegisterHistoryInBatchMutation } from '@/lib/hooks/useAdminApi';
const validationSchema = Yup.object().shape({
@@ -35,7 +31,7 @@ const initialValues: HistoryRegisterFormProps = {
file: undefined,
};
-const Page = () => {
+export default function MilestoneRegisterPage() {
const router = useRouter();
const { mutate: registerHistories } = useRegisterHistoryInBatchMutation();
@@ -43,7 +39,8 @@ const Page = () => {
<>
-
-
+
*/}
);
-};
-
-export default Page;
+}
diff --git a/frontend/src/app/admin/styled.ts b/frontend/src/app/admin/styled.ts
deleted file mode 100644
index 9ef43657..00000000
--- a/frontend/src/app/admin/styled.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-'use client';
-
-import styled from 'styled-components';
-
-import { COLOR, FONT_STYLE } from '@/adminConstants';
-import { BORDER_RADIUS } from '@/constants';
-
-export const AdminButton = styled.button`
- padding: 4px 8px;
- border-radius: ${BORDER_RADIUS.sm};
- border: none;
- font: ${FONT_STYLE.base.normal};
- cursor: pointer;
-`;
-
-export const AdminBlueButton = styled(AdminButton)`
- background-color: ${COLOR.primary.main};
- color: ${COLOR.white};
-`;
-
-export const AdminRedButton = styled(AdminButton)`
- background-color: ${COLOR.semantic.error};
- color: ${COLOR.white};
-`;
-
-export const AdminBlackButton = styled(AdminButton)`
- background-color: black;
- color: ${COLOR.white};
-`;
-
-export const AdminGrayButton = styled(AdminButton)`
- background-color: ${COLOR.secondary.light};
- border: 1px solid ${COLOR.secondary.main};
- color: ${COLOR.comment};
-`;
-
-export const AdminLink = styled.a`
- padding: 4px 8px;
- border-radius: ${BORDER_RADIUS.sm};
- border: none;
- font: ${FONT_STYLE.base.normal};
- cursor: pointer;
-`;
-
-export const AdminBlueLink = styled(AdminLink)`
- background-color: ${COLOR.primary.main};
- color: ${COLOR.white};
-`;
-
-export const AdminRedLink = styled(AdminLink)`
- background-color: ${COLOR.semantic.error};
- color: ${COLOR.white};
-`;
-
-export const AdminBlackLink = styled(AdminLink)`
- background-color: black;
- color: ${COLOR.white};
-`;
-
-export const AdminGrayLink = styled(AdminLink)`
- background-color: ${COLOR.secondary.light};
- border: 1px solid ${COLOR.secondary.main};
- color: ${COLOR.comment};
-`;
diff --git a/frontend/src/app/admin/team-building/page.tsx b/frontend/src/app/admin/team-building/page.tsx
index bf4f4cdf..3ee4a72d 100644
--- a/frontend/src/app/admin/team-building/page.tsx
+++ b/frontend/src/app/admin/team-building/page.tsx
@@ -1,9 +1,7 @@
-const Page = () => {
+export default function TeamBuildingPage() {
return (
);
-};
-
-export default Page;
+}
diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx
index 063cc8b6..83655f57 100644
--- a/frontend/src/app/layout.tsx
+++ b/frontend/src/app/layout.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable @next/next/no-page-custom-font */
import { Metadata } from 'next';
import { ToastContainer } from 'react-toastify';
@@ -7,6 +6,7 @@ import ReduxProvider from '@/lib/utils/reduxProvider';
import StyledComponentsRegistry from '@/theme/StyledComponentsRegistry';
import './globals.css';
+import 'react-toastify/ReactToastify.min.css';
export const metadata: Metadata = {
title: '부산대학교 SW역량지원시스템',
@@ -19,7 +19,6 @@ const RootLayout = ({ children }: Readonly<{ children: React.ReactNode }>) => (
-
diff --git a/frontend/src/components/Footer/index.tsx b/frontend/src/components/Footer/index.tsx
deleted file mode 100644
index 58dd5967..00000000
--- a/frontend/src/components/Footer/index.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import { FooterWrapper, FooterLayout, FooterLogo, FooterDiv, FooterText, FooterLink } from './styled';
-
-const Footer = () => (
-
-
-
-
- (46241) 부산광역시 금정구 부산대학로 63번길 2 (장전동)
- 부산대학교 소프트웨어융합교육원
-
- 개인정보처리방침
- ⓒ 2021 PNUswedu. All Right Reserved.
- TEL : 051-510-3737, 3738, 3624
-
-
-);
-
-export default Footer;
diff --git a/frontend/src/components/Footer/styled.ts b/frontend/src/components/Footer/styled.ts
deleted file mode 100644
index 64342039..00000000
--- a/frontend/src/components/Footer/styled.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-'use client';
-
-import Image from 'next/image';
-import Link from 'next/link';
-import styled from 'styled-components';
-
-import { COLOR, FONT_STYLE, RESPONSIVE_WIDTH } from '@/constants';
-
-export const FooterWrapper = styled.div`
- width: 100vw;
- min-height: 200px;
- display: flex;
- align-items: center;
- justify-content: center;
- background-color: ${COLOR.background.base};
-`;
-
-export const FooterLayout = styled.div`
- width: 1200px;
- display: grid;
- grid-template-columns: 1fr 3fr 105px;
- gap: 20px;
-
- @media screen and (max-width: ${RESPONSIVE_WIDTH.desktop}) {
- grid-template-columns: 1fr;
- justify-items: center;
- }
-`;
-
-export const FooterLogo = styled(Image)`
- @media screen and (max-width: ${RESPONSIVE_WIDTH.desktop}) {
- display: none;
- }
-`;
-
-export const FooterDiv = styled.div`
- @media screen and (max-width: ${RESPONSIVE_WIDTH.desktop}) {
- text-align: center;
- }
-`;
-
-export const FooterText = styled.p`
- font: ${FONT_STYLE.sm.normal};
- color: ${COLOR.comment};
-`;
-
-export const FooterLink = styled(Link)`
- width: fit-content;
- height: fit-content;
- font: ${FONT_STYLE.sm.normal};
- color: ${COLOR.comment};
- padding-bottom: 2px;
- border-bottom: 1px solid ${COLOR.comment};
-`;
diff --git a/frontend/src/components/GoPageIcon/index.tsx b/frontend/src/components/GoPageIcon/index.tsx
deleted file mode 100644
index 15237611..00000000
--- a/frontend/src/components/GoPageIcon/index.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-/* eslint-disable import/no-extraneous-dependencies */
-import { VscAdd } from '@react-icons/all-files/vsc/VscAdd';
-import Link from 'next/link';
-
-import { COLOR, FONT_STYLE } from '@/constants';
-
-interface GoPageIconProps {
- name: string;
- url: string;
-}
-
-const GoPageIcon = ({ name, url }: GoPageIconProps) => (
-
-
- {name}
-
-);
-
-export default GoPageIcon;
diff --git a/frontend/src/components/Header/HeaderAccordion/index.tsx b/frontend/src/components/Header/HeaderAccordion/index.tsx
deleted file mode 100644
index a9bd6ed6..00000000
--- a/frontend/src/components/Header/HeaderAccordion/index.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import { CategoryDto } from '@/types/common.dto';
-
-import { HeaderAccordionWrapper, Linker, Accordion, AccordionLink } from './styled';
-
-const HeaderAccordion = ({ title, url, sub }: CategoryDto) => (
-
- {title}
-
- {sub.map((item) => (
-
- {item.title}
-
- ))}
-
-
-);
-
-export default HeaderAccordion;
diff --git a/frontend/src/components/Header/HeaderAccordion/styled.ts b/frontend/src/components/Header/HeaderAccordion/styled.ts
deleted file mode 100644
index 36b98bdc..00000000
--- a/frontend/src/components/Header/HeaderAccordion/styled.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import Link from 'next/link';
-import styled from 'styled-components';
-
-import { BORDER_RADIUS, COLOR, FONT_STYLE } from '@/constants';
-
-export const HeaderAccordionWrapper = styled.div`
- position: relative;
- height: 76px;
- line-height: 76px;
- align-items: center;
- &:hover {
- > div {
- max-height: 200px;
- }
- }
-`;
-
-export const Linker = styled(Link)`
- padding: 0 40px;
- font: ${FONT_STYLE.lg.semibold};
- &:hover {
- color: ${COLOR.primary.dark};
- }
-`;
-
-export const AccordionLink = styled(Link)`
- display: block;
- padding: 10px;
- border-bottom: 1px solid ${COLOR.border};
- &:hover {
- color: ${COLOR.primary.dark};
- }
-`;
-
-export const Accordion = styled.div`
- position: absolute;
- width: 180px;
- max-height: 0;
- text-align: center;
- font: ${FONT_STYLE.sm.normal};
- color: ${COLOR.comment};
- background-color: ${COLOR.white};
- border-bottom-left-radius: ${BORDER_RADIUS.sm};
- border-bottom-right-radius: ${BORDER_RADIUS.sm};
- box-shadow: 0px 2px 5px rgb(0, 0, 0, 0.25);
- left: 50%;
- top: 100%;
- transform: translate(-50%, 0);
- transition: max-height 0.4s ease-in-out;
- overflow: hidden;
-`;
diff --git a/frontend/src/components/Header/Sidebar/index.tsx b/frontend/src/components/Header/Sidebar/index.tsx
deleted file mode 100644
index 71900382..00000000
--- a/frontend/src/components/Header/Sidebar/index.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import { useState } from 'react';
-
-import { COLOR } from '@/constants';
-import { CategoryDto } from '@/types/common.dto';
-
-import * as S from './styled';
-
-export interface SidebarProps {
- open: boolean;
- handleOpen: React.Dispatch>;
- headerInfos: CategoryDto[];
-}
-
-const Sidebar = ({ open, handleOpen, headerInfos }: SidebarProps) => {
- const [currTab, setCurrTab] = useState('');
-
- const handleClose = () => {
- handleOpen((e) => !e);
- setCurrTab('');
- };
-
- return (
-
-
-
-
-
-
-
- {headerInfos.map((item) => (
-
- setCurrTab(item.title)}
- >
- {item.title}
-
- {item.sub.map((subItem) => (
-
- {subItem.title}
-
- ))}
-
- ))}
-
-
- );
-};
-
-export default Sidebar;
diff --git a/frontend/src/components/Header/Sidebar/styled.ts b/frontend/src/components/Header/Sidebar/styled.ts
deleted file mode 100644
index 8719809e..00000000
--- a/frontend/src/components/Header/Sidebar/styled.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import Link from 'next/link';
-import styled from 'styled-components';
-
-import { BORDER_RADIUS, COLOR, FONT_STYLE } from '@/constants';
-
-export const SidebarWrapper = styled.div`
- width: 50px;
- height: 50px;
- position: relative;
-`;
-
-export const HamburgerLogo = styled.div`
- background-color: ${COLOR.primary.main};
- width: 100%;
- height: 100%;
- position: absolute;
- transition: left 0.4s ease-in-out;
-`;
-
-export const HamburgerLine = styled.div`
- width: 70%;
- border-radius: ${BORDER_RADIUS.md};
- border: 2px solid ${COLOR.white};
- position: absolute;
- left: 50%;
- top: 50%;
- transition: transform 0.4s ease-in-out;
-`;
-
-export const SidebarContent = styled.div`
- width: 200px;
- height: 100vh;
- font: ${FONT_STYLE.sm.normal};
- background-color: ${COLOR.white};
- position: absolute;
- transition: left 0.4s ease-in-out;
-`;
-
-export const SidebarContentLayout = styled.div`
- overflow: hidden;
- transition: max-height 0.4s ease-in-out;
-`;
-
-export const SidebarContentTitle = styled.div`
- padding: 10px 20px;
- border-bottom: 1px solid ${COLOR.border};
- cursor: default;
- &:hover {
- color: ${COLOR.primary.main};
- }
-`;
-
-export const SidebarContentSubTitle = styled(Link)`
- display: block;
- padding: 10px 30px;
- border-bottom: 1px solid ${COLOR.border};
- background-color: ${COLOR.background.light};
- cursor: default;
- color: ${COLOR.comment};
- &:hover {
- color: ${COLOR.primary.main};
- }
-`;
diff --git a/frontend/src/components/Header/index.tsx b/frontend/src/components/Header/index.tsx
deleted file mode 100644
index 61fbdbcd..00000000
--- a/frontend/src/components/Header/index.tsx
+++ /dev/null
@@ -1,108 +0,0 @@
-/* eslint-disable import/no-extraneous-dependencies */
-/* eslint-disable implicit-arrow-linebreak */
-
-'use client';
-
-import { VscSettingsGear } from '@react-icons/all-files/vsc/VscSettingsGear';
-import { VscAccount } from '@react-icons/all-files/vsc/VscAccount';
-import { VscSignIn } from '@react-icons/all-files/vsc/VscSignIn';
-import { VscSignOut } from '@react-icons/all-files/vsc/VscSignOut';
-import Image from 'next/image';
-import Link from 'next/link';
-import { useState } from 'react';
-
-import { headerInfos } from '@/data/clientCategory';
-import { useAppSelector } from '@/lib/hooks/redux';
-
-import HeaderAccordion from './HeaderAccordion';
-import Sidebar from './Sidebar';
-import * as S from './styled';
-import IconButton from '../IconButton';
-
-const Header = () => {
- const [isSidebarOpen, setIsSideBarOpen] = useState(false);
-
- const auth = useAppSelector((state) => state.auth.value);
-
- return (
-
-
-
-
-
-
- {headerInfos.map(
- (item) =>
- item.inHeader && (
-
- ),
- )}
-
- {auth.isAuth && auth.isModerator && (
- <>
- } title="관리" size="sm" link="/admin" />
- } title="로그아웃" size="sm" link="/sign-out" />
- >
- )}
- {auth.isAuth && !auth.isModerator && (
- <>
- } title="마이페이지" size="sm" link="/my-page" />
- } title="로그아웃" size="sm" link="/sign-out" />
- >
- )}
- {!auth.isAuth && (
-
-
- 로그인 / 회원가입
-
-
- )}
-
- setIsSideBarOpen(false)}
- />
-
-
-
-
-
-
- {auth.isAuth && auth.isModerator && (
- <>
- } title="관리" size="sm" link="/admin" />
- } title="로그아웃" size="sm" link="/sign-out" />
- >
- )}
- {auth.isAuth && !auth.isModerator && (
- <>
- } title="마이페이지" size="sm" link="/my-page" />
- } title="로그아웃" size="sm" link="/sign-out" />
- >
- )}
- {!auth.isAuth && } title="로그인" size="sm" link="/sign-in" />}
-
-
-
-
- );
-};
-export default Header;
diff --git a/frontend/src/components/Header/styled.ts b/frontend/src/components/Header/styled.ts
deleted file mode 100644
index 69df510a..00000000
--- a/frontend/src/components/Header/styled.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-'use client';
-
-import styled from 'styled-components';
-
-import { MAX_WIDTH, RESPONSIVE_WIDTH, FONT_STYLE, COLOR, BORDER_RADIUS } from '@/constants';
-
-export const HeaderWrapper = styled.div`
- position: fixed;
- background-color: ${COLOR.white};
- width: 100vw;
- border-bottom: 1px solid ${COLOR.border};
- z-index: 50;
-`;
-
-export const HeaderDesktopLayout = styled.div`
- max-width: ${MAX_WIDTH};
- margin: auto;
- display: flex;
- align-items: center;
- @media screen and (max-width: ${RESPONSIVE_WIDTH.desktop}) {
- display: none;
- }
-`;
-
-export const HeaderTabletLayout = styled.div`
- display: flex;
- justify-content: space-between;
- align-items: center;
- @media screen and (min-width: ${RESPONSIVE_WIDTH.desktop}) {
- display: none;
- }
-`;
-
-export const SignButton = styled.div`
- background-color: ${COLOR.primary.main};
- padding: 10px 20px;
- border-radius: ${BORDER_RADIUS.md};
-`;
-
-export const SignText = styled.span`
- font: ${FONT_STYLE.sm.normal};
- color: ${COLOR.white};
-`;
-
-export const SidebarBackground = styled.div`
- position: absolute;
- width: 100vw;
- height: 100vh;
- left: 0;
- top: 0;
- background-color: rgba(0, 0, 0, 0.7);
-`;
diff --git a/frontend/src/components/IconButton/index.tsx b/frontend/src/components/IconButton/index.tsx
deleted file mode 100644
index 511b6c99..00000000
--- a/frontend/src/components/IconButton/index.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-/* eslint-disable no-nested-ternary */
-import React from 'react';
-
-import { FONT_STYLE } from '@/constants';
-
-import { IconButtonWrapper } from './styled';
-
-export interface IconButtonProps {
- icon: React.ReactElement;
- title: string;
- size: 'sm' | 'md' | 'lg';
- link: string;
-}
-
-const IconButton = ({ icon, title, size, link }: IconButtonProps) => {
- const width = size === 'sm' ? '24px' : size === 'md' ? '32px' : '80px';
- const height = size === 'sm' ? '24px' : size === 'md' ? '32px' : '80px';
-
- const Icon = React.createElement(icon.type, {
- ...{
- ...icon.props,
- style: { width, height },
- },
- });
-
- return (
-
- {Icon}
-
- {title}
-
-
- );
-};
-
-export default IconButton;
diff --git a/frontend/src/components/IconButton/styled.ts b/frontend/src/components/IconButton/styled.ts
deleted file mode 100644
index 8d06240b..00000000
--- a/frontend/src/components/IconButton/styled.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-/* eslint-disable import/prefer-default-export */
-import Link from 'next/link';
-import styled from 'styled-components';
-
-export const IconButtonWrapper = styled(Link)`
- width: 60px;
- height: 50px;
- margin-right: 10px;
- display: flex;
- align-items: center;
- justify-content: center;
- flex-direction: column;
- background-color: transparent;
- border: none;
- cursor: pointer;
- &:hover {
- background-color: transparent;
- }
-`;
diff --git a/frontend/src/components/MilestoneChart/index.tsx b/frontend/src/components/MilestoneChart/index.tsx
deleted file mode 100644
index 65797d50..00000000
--- a/frontend/src/components/MilestoneChart/index.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import { COLOR } from '@/constants';
-import { MilestoneOverviewScore } from '@/types/milestone';
-
-import * as S from './styled';
-
-export interface MilestoneChartProps {
- chartSize: number;
- fontSize: 'sm' | 'lg';
- milestoneOverviewScore: MilestoneOverviewScore;
-}
-
-const MilestoneChart = ({ chartSize, fontSize, milestoneOverviewScore }: MilestoneChartProps) => {
- const { activityScore, globalScore, communityScore, totalScore } = milestoneOverviewScore;
- const scores = [
- { start: 0, score: activityScore, color: COLOR.milestone.blue.main, title: '실전적 SW역량' },
- { start: activityScore, score: globalScore, color: COLOR.milestone.green.main, title: '글로벌 SW역량' },
- {
- start: activityScore + globalScore,
- score: communityScore,
- color: COLOR.milestone.purple.main,
- title: '커뮤니티 SW역량',
- },
- ];
-
- return (
-
- {scores.map((bar) => (
-
- ))}
-
-
- {totalScore}
- / 1000
-
-
- );
-};
-
-export default MilestoneChart;
diff --git a/frontend/src/components/MilestoneChart/styled.ts b/frontend/src/components/MilestoneChart/styled.ts
deleted file mode 100644
index 19f63bb4..00000000
--- a/frontend/src/components/MilestoneChart/styled.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-'use client';
-
-import styled from 'styled-components';
-
-import { COLOR, FONT_STYLE } from '@/constants';
-
-interface ChartProps {
- size: number;
-}
-
-interface ChartBarProps {
- start: number;
- score: number;
- color: string;
-}
-
-export const Chart = styled.div`
- margin: 0 auto;
- position: relative;
- width: ${(props) => props.size}px;
- height: ${(props) => props.size}px;
- border-radius: 100%;
- background: ${COLOR.milestone.gray.light};
-`;
-
-export const ChartBar = styled.div`
- position: absolute;
- width: inherit;
- height: inherit;
- border-radius: 50%;
- background: conic-gradient(
- transparent ${(props) => (props.start / 1000.0) * 360}deg,
- ${(props) => props.color} ${(props) => (props.start / 1000.0) * 360}deg,
- ${(props) => props.color} ${(props) => ((props.start + props.score) / 1000.0) * 360}deg,
- transparent ${(props) => ((props.start + props.score) / 1000.0) * 360}deg
- );
-`;
-
-export const ChartHole = styled.div`
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- width: ${(props) => props.size / 1.7}px;
- height: ${(props) => props.size / 1.7}px;
- border-radius: 100%;
- background: ${COLOR.white};
-`;
-
-export const ChartTextWrapper = styled.div`
- position: absolute;
- top: 45%;
- left: 50%;
- transform: translate(-50%, -50%);
- width: 50%;
- height: 50px;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
-`;
-
-interface ChartTextProps {
- fontSize: 'sm' | 'lg';
-}
-
-export const ChartText = styled.p`
- color: ${COLOR.comment};
- font: ${({ fontSize }) => {
- switch (fontSize) {
- case 'sm':
- return FONT_STYLE.xs.normal;
- case 'lg':
- return FONT_STYLE.base.normal;
- default:
- return FONT_STYLE.sm.normal;
- }
- }};
-`;
-
-export const ChartScoreText = styled(ChartText)`
- color: ${COLOR.black_text};
- font: ${({ fontSize }) => {
- switch (fontSize) {
- case 'sm':
- return FONT_STYLE.base.bold;
- case 'lg':
- return FONT_STYLE.xl.bold;
- default:
- return FONT_STYLE.lg.bold;
- }
- }};
-`;
diff --git a/frontend/src/components/MilestonePeriodSearchForm/index.tsx b/frontend/src/components/MilestonePeriodSearchForm/index.tsx
deleted file mode 100644
index 581b6bcc..00000000
--- a/frontend/src/components/MilestonePeriodSearchForm/index.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import { ChangeEvent, Dispatch, SetStateAction } from 'react';
-
-import { Period } from '@/types/common';
-
-import { PeriodInput, SearchButton } from './styled';
-
-interface MilestonePeriodSearchFormProps {
- filterPeriod: Period;
- setFilterPeriod: Dispatch>;
- setSearchFilterPeriod: Dispatch>;
-}
-
-const MilestonePeriodSearchForm = ({
- filterPeriod,
- setFilterPeriod,
- setSearchFilterPeriod,
-}: MilestonePeriodSearchFormProps) => {
- const handleSearchButtonClick = () => {
- setSearchFilterPeriod(filterPeriod);
- };
-
- return (
-
-
) => setFilterPeriod({ ...filterPeriod, startDate: e.target.value })}
- />
- ~
- ) => setFilterPeriod({ ...filterPeriod, endDate: e.target.value })}
- />
- 검색
-
- );
-};
-
-export default MilestonePeriodSearchForm;
diff --git a/frontend/src/components/MilestonePeriodSearchForm/styled.ts b/frontend/src/components/MilestonePeriodSearchForm/styled.ts
deleted file mode 100644
index 01950316..00000000
--- a/frontend/src/components/MilestonePeriodSearchForm/styled.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-'use client';
-
-import styled from 'styled-components';
-
-import { BORDER_RADIUS, COLOR, RESPONSIVE_WIDTH } from '@/constants';
-
-export const PeriodInput = styled.input`
- text-align: center;
- padding: 8px;
- border-radius: ${BORDER_RADIUS.md};
- border: none;
- background-color: ${COLOR.border};
-
- &:focus {
- outline-color: ${COLOR.black_text};
- }
-`;
-
-export const SearchButton = styled.button`
- background-color: ${COLOR.black_text};
- color: white;
- padding: 4px 16px;
- border-radius: ${BORDER_RADIUS.sm};
-
- @media screen and (max-width: ${RESPONSIVE_WIDTH.mobile}) {
- margin-top: 16px;
- }
-`;
diff --git a/frontend/src/components/MilestoneTable/index.tsx b/frontend/src/components/MilestoneTable/index.tsx
deleted file mode 100644
index cb0d9c36..00000000
--- a/frontend/src/components/MilestoneTable/index.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import { COLOR } from '@/constants';
-import { MilestoneOverviewScore } from '@/types/milestone';
-
-import * as S from './styled';
-
-interface MilestoneTableProps {
- milestoneOverviewScore: MilestoneOverviewScore;
-}
-
-const MilestoneTable = ({ milestoneOverviewScore }: MilestoneTableProps) => {
- const { activityScore, globalScore, communityScore, totalScore } = milestoneOverviewScore;
- const squareSize = 12;
- const scores = [
- { score: activityScore, color: COLOR.milestone.blue.main, title: '실전적 SW역량' },
- { score: globalScore, color: COLOR.milestone.green.main, title: '글로벌 SW역량' },
- { score: communityScore, color: COLOR.milestone.purple.main, title: '커뮤니티 SW역량' },
- ];
-
- return (
-
- 역량 구분 획득
- {scores.map((bar) => (
- <>
-
-
- {bar.title}
-
- {bar.score}
- >
- ))}
- 합계
- {totalScore}
-
- );
-};
-
-export default MilestoneTable;
diff --git a/frontend/src/components/MilestoneTable/styled.ts b/frontend/src/components/MilestoneTable/styled.ts
deleted file mode 100644
index 9d27b0da..00000000
--- a/frontend/src/components/MilestoneTable/styled.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-'use client';
-
-import styled from 'styled-components';
-
-import { COLOR, FONT_STYLE } from '@/constants';
-
-interface SquareProps {
- size: number;
- color: string;
-}
-
-export const TableWrapper = styled.div`
- flex-grow: 1;
- max-width: 300px;
- display: grid;
- grid-template-columns: 70% 30%;
- color: ${COLOR.comment};
- text-align: center;
- align-content: center;
-`;
-
-export const TableTopBorderContent = styled.div`
- padding: 8px 4px;
- border-top: 1px solid ${COLOR.black_text};
- font: ${FONT_STYLE.sm.normal};
-`;
-
-export const TableBottomBorderContent = styled.div`
- padding: 8px 4px;
- border-bottom: 1px solid ${COLOR.border};
- font: ${FONT_STYLE.sm.normal};
-`;
-
-export const TableTitle = styled(TableBottomBorderContent)`
- color: ${COLOR.black_text};
- font: ${FONT_STYLE.xs.semibold};
-`;
-
-export const ScoreContent = styled(TableBottomBorderContent)`
- display: flex;
- padding-left: 14px;
- align-items: center;
- gap: 4px;
-`;
-
-export const Square = styled.div`
- width: ${(props) => props.size}px;
- height: ${(props) => props.size}px;
- background: ${(props) => props.color};
-`;
diff --git a/frontend/src/components/SubTitle/index.tsx b/frontend/src/components/SubTitle/index.tsx
deleted file mode 100644
index 9c588072..00000000
--- a/frontend/src/components/SubTitle/index.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import Link from 'next/link';
-
-export interface SubTitleProps {
- title: string;
- urlText?: string;
- url?: string;
-}
-
-const SubTitle = ({ title, urlText, url }: SubTitleProps) => (
-
-
{title}
- {urlText && url && (
-
- {urlText}
-
- )}
-
-);
-
-export default SubTitle;
diff --git a/frontend/src/components/TabButton/index.tsx b/frontend/src/components/TabButton/index.tsx
deleted file mode 100644
index 2069511f..00000000
--- a/frontend/src/components/TabButton/index.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-/* eslint-disable max-len */
-
-'use client';
-
-import { usePathname } from 'next/navigation';
-
-export interface PageTabProps {
- tabs: { name: string; url: string }[];
-}
-
-const PageTab = ({ tabs }: PageTabProps) => {
- const pathname = usePathname();
-
- return (
-
- );
-};
-
-export default PageTab;
diff --git a/frontend/src/components/TeamBuilding/index.tsx b/frontend/src/components/TeamBuilding/index.tsx
deleted file mode 100644
index d6054e63..00000000
--- a/frontend/src/components/TeamBuilding/index.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-/* eslint-disable import/no-extraneous-dependencies */
-import { CgEye } from '@react-icons/all-files/cg/CgEye';
-import Image from 'next/image';
-
-import { COLOR, TEAM_STATUS } from '@/constants';
-import { TeamBuildingDto } from '@/types/common.dto';
-
-import * as S from './styled';
-
-const TeamBuilding = ({ id, category, status, title, developer, designer, artist, other, views }: TeamBuildingDto) => {
- const recruitment = [
- { img: '/images/teamBuilding/team_type_img_1.svg', text: '개발', count: developer },
- { img: '/images/teamBuilding/team_type_img_2.svg', text: '디자인', count: artist },
- { img: '/images/teamBuilding/team_type_img_3.svg', text: '기획', count: designer },
- { img: '/images/teamBuilding/team_type_img_4.svg', text: '기타', count: other },
- ];
- return (
-
-
- {category}
- {TEAM_STATUS[status].text}
-
-
- {title}
-
- {recruitment.map((item) => {
- if (item.count !== 0) {
- return (
-
-
-
- {item.text}
-
- {item.count}명
-
-
- );
- }
- return null;
- })}
-
-
-
- {views}
-
-
-
- );
-};
-
-export default TeamBuilding;
diff --git a/frontend/src/components/TeamBuilding/styled.ts b/frontend/src/components/TeamBuilding/styled.ts
deleted file mode 100644
index 23d62b36..00000000
--- a/frontend/src/components/TeamBuilding/styled.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-'use client';
-
-import Link from 'next/link';
-import styled from 'styled-components';
-
-import { BORDER_RADIUS, FONT_STYLE, COLOR } from '@/constants';
-
-interface StatusTextProps {
- color: string;
-}
-
-export const TeamBuildingWrapper = styled(Link)`
- width: 360px;
- border: 2px solid ${COLOR.border};
- border-radius: ${BORDER_RADIUS.sm};
- overflow: hidden;
-`;
-
-export const TeamHeaderWrapper = styled.div`
- display: flex;
- gap: 10px;
- align-items: center;
-`;
-
-export const CategoryText = styled.p`
- border-bottom-right-radius: ${BORDER_RADIUS.sm};
- padding: 6px 12px;
- background-color: ${COLOR.border};
- color: ${COLOR.black_text};
- font: ${FONT_STYLE.base.semibold};
-`;
-
-export const StatusText = styled.p`
- border: 1px solid ${(props) => props.color};
- border-radius: ${BORDER_RADIUS.sm};
- padding: 2px 8px;
- color: ${(props) => props.color};
- font: ${FONT_STYLE.sm.normal};
-`;
-
-export const TeamBodyWrapper = styled.div`
- margin: 8px 16px 16px;
- display: flex;
- flex-direction: column;
- gap: 12px;
- overflow: hidden;
-`;
-
-export const TeamTitle = styled.p`
- color: ${COLOR.black_text};
- font: ${FONT_STYLE.base.bold};
-
- white-space: nowrap;
- text-overflow: ellipsis;
- overflow: hidden;
-
- &:hover {
- white-space: wrap;
- word-break: keep-all;
- }
-`;
-
-export const RecruitmentWrapper = styled.div`
- display: flex;
- justify-content: center;
- gap: 16px;
-`;
-
-export const RecruitmentItem = styled.div`
- display: flex;
- gap: 4px;
- align-items: center;
-`;
-
-export const RecruitmentItemText = styled.div`
- font: ${FONT_STYLE.sm.semibold};
- color: ${COLOR.comment};
- text-align: center;
-`;
-
-export const ViewDiv = styled.div`
- display: flex;
- align-items: center;
- justify-content: end;
- gap: 8px;
- color: ${COLOR.comment};
-`;
diff --git a/frontend/src/components/Title/index.tsx b/frontend/src/components/Title/index.tsx
deleted file mode 100644
index 1c77647f..00000000
--- a/frontend/src/components/Title/index.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-export interface TitleProps {
- title: string;
- description?: string;
-}
-
-const Title = ({ title, description }: TitleProps) => (
-
-
{title}
- {description &&
{description}
}
-
-);
-
-export default Title;
diff --git a/frontend/src/components/common/IconButton.tsx b/frontend/src/components/common/IconButton.tsx
new file mode 100644
index 00000000..0c27fcd9
--- /dev/null
+++ b/frontend/src/components/common/IconButton.tsx
@@ -0,0 +1,30 @@
+import React from 'react';
+import Link from 'next/link';
+
+export interface IconButtonProps {
+ icon: React.ReactElement;
+ title: string;
+ link: string;
+}
+
+export default function IconButton({ icon, title, link }: IconButtonProps) {
+ const width = '24px';
+ const height = '24px';
+
+ const Icon = React.createElement(icon.type, {
+ ...{
+ ...icon.props,
+ style: { width, height },
+ },
+ });
+
+ return (
+
+ {Icon}
+ {title}
+
+ );
+}
diff --git a/frontend/src/components/common/PageSubTitle.tsx b/frontend/src/components/common/PageSubTitle.tsx
new file mode 100644
index 00000000..8442c3f6
--- /dev/null
+++ b/frontend/src/components/common/PageSubTitle.tsx
@@ -0,0 +1,20 @@
+import Link from 'next/link';
+
+export interface PageSubTitleProps {
+ title: string;
+ urlText?: string;
+ url?: string;
+}
+
+export default function PageSubTitle({ title, urlText, url }: PageSubTitleProps) {
+ return (
+
+
{title}
+ {urlText && url && (
+
+ {urlText}
+
+ )}
+
+ );
+}
diff --git a/frontend/src/components/common/PageTitle.tsx b/frontend/src/components/common/PageTitle.tsx
new file mode 100644
index 00000000..223cef84
--- /dev/null
+++ b/frontend/src/components/common/PageTitle.tsx
@@ -0,0 +1,13 @@
+export interface PageTitleProps {
+ title: string;
+ description?: string;
+}
+
+export default function PageTitle({ title, description }: PageTitleProps) {
+ return (
+
+
{title}
+ {description &&
{description}
}
+
+ );
+}
diff --git a/frontend/src/app/(client)/components/Pagination/index.tsx b/frontend/src/components/common/Pagination.tsx
similarity index 83%
rename from frontend/src/app/(client)/components/Pagination/index.tsx
rename to frontend/src/components/common/Pagination.tsx
index 1d3d63a7..6a8818a8 100644
--- a/frontend/src/app/(client)/components/Pagination/index.tsx
+++ b/frontend/src/components/common/Pagination.tsx
@@ -1,6 +1,3 @@
-/* eslint-disable prettier/prettier */
-/* eslint-disable import/no-extraneous-dependencies */
-/* eslint-disable max-len */
import { VscChevronLeft } from '@react-icons/all-files/vsc/VscChevronLeft';
import { VscChevronRight } from '@react-icons/all-files/vsc/VscChevronRight';
import Link from 'next/link';
@@ -13,7 +10,7 @@ export interface PaginationProps {
query?: string;
}
-const Pagination = ({ currentPage, pageSize, totalItems, pathname, query }: PaginationProps) => {
+export default function Pagination({ currentPage, pageSize, totalItems, pathname, query }: PaginationProps) {
const buttonPerPage = 10;
const totalPageCount = Math.ceil(totalItems / pageSize);
@@ -25,7 +22,7 @@ const Pagination = ({ currentPage, pageSize, totalItems, pathname, query }: Pagi
const queries = query ? JSON.parse(query) : null;
const nextPageCalc = (showIdx + 1) * buttonPerPage + 1;
- const prevPage = showIdx === 0 ? 1 : showIdx * buttonPerPage;
+ const prevPage = showIdx <= 1 ? 1 : showIdx * buttonPerPage;
const nextPage = totalPageCount >= nextPageCalc ? nextPageCalc : totalPageCount;
return (
@@ -47,6 +44,4 @@ const Pagination = ({ currentPage, pageSize, totalItems, pathname, query }: Pagi
);
-};
-
-export default Pagination;
+}
diff --git a/frontend/src/components/common/PeriodSearchBox.tsx b/frontend/src/components/common/PeriodSearchBox.tsx
new file mode 100644
index 00000000..75d05e60
--- /dev/null
+++ b/frontend/src/components/common/PeriodSearchBox.tsx
@@ -0,0 +1,39 @@
+import { ChangeEvent, Dispatch, SetStateAction } from 'react';
+
+export interface Period {
+ startDate: string;
+ endDate: string;
+}
+
+export interface PeriodSearchBoxProps {
+ period: Period;
+ setPeriod: Dispatch>;
+ setSearchPeriod: Dispatch>;
+}
+
+export default function PeriodSearchBox({ period, setPeriod, setSearchPeriod }: PeriodSearchBoxProps) {
+ const handleSearchButtonClick = () => {
+ setSearchPeriod(period);
+ };
+
+ return (
+
+ ) => setPeriod({ ...period, startDate: e.target.value })}
+ />
+ ~
+ ) => setPeriod({ ...period, endDate: e.target.value })}
+ />
+
+ 검색
+
+
+ );
+}
diff --git a/frontend/src/adminComponents/Pagination/index.tsx b/frontend/src/components/common/admin/AdminPagination.tsx
similarity index 85%
rename from frontend/src/adminComponents/Pagination/index.tsx
rename to frontend/src/components/common/admin/AdminPagination.tsx
index 8470dbd5..161b77c4 100644
--- a/frontend/src/adminComponents/Pagination/index.tsx
+++ b/frontend/src/components/common/admin/AdminPagination.tsx
@@ -1,19 +1,23 @@
-/* eslint-disable prettier/prettier */
-/* eslint-disable import/no-extraneous-dependencies */
-/* eslint-disable max-len */
+import Link from 'next/link';
+
import { VscChevronLeft } from '@react-icons/all-files/vsc/VscChevronLeft';
import { VscChevronRight } from '@react-icons/all-files/vsc/VscChevronRight';
-import Link from 'next/link';
-export interface PaginationProps {
+export interface AdminPaginationProps {
currentPage: number;
totalItems: number;
- itemPerPage?: number;
pathname: string;
+ itemPerPage?: number;
query?: string;
}
-const Pagination = ({ currentPage, totalItems, itemPerPage = 10, pathname, query }: PaginationProps) => {
+export default function AdminPagination({
+ currentPage,
+ pathname,
+ totalItems,
+ itemPerPage = 10,
+ query,
+}: AdminPaginationProps) {
const buttonPerPage = 10;
const totalPageCount = Math.ceil(totalItems / itemPerPage);
@@ -47,6 +51,4 @@ const Pagination = ({ currentPage, totalItems, itemPerPage = 10, pathname, query
);
-};
-
-export default Pagination;
+}
diff --git a/frontend/src/components/SearchBox/index.tsx b/frontend/src/components/common/admin/AdminSearchBox.tsx
similarity index 78%
rename from frontend/src/components/SearchBox/index.tsx
rename to frontend/src/components/common/admin/AdminSearchBox.tsx
index 0ce535f0..e5c51661 100644
--- a/frontend/src/components/SearchBox/index.tsx
+++ b/frontend/src/components/common/admin/AdminSearchBox.tsx
@@ -1,29 +1,27 @@
-/* eslint-disable prettier/prettier */
-
'use client';
import { Form, Formik } from 'formik';
import { useRouter } from 'next/navigation';
-import Dropdown from '@/components/Formik/Dropdown';
-import TextInput from '@/components/Formik/TextInput';
+import Dropdown from '@/components/common/formik/Dropdown';
+import TextInput from '@/components/common/formik/TextInput';
import { FORM_SIZE } from '@/constants';
-interface SearchFormProps {
+interface AdminSearchFormProps {
field: number;
keyword: string;
}
-export interface SearchBoxProps {
- initialValues: SearchFormProps;
+export interface AdminSearchBoxProps {
+ initialValues: AdminSearchFormProps;
fieldCategories: { id: number; name: string }[];
path: string;
}
-const SearchBox = ({ initialValues, fieldCategories, path }: SearchBoxProps) => {
+export default function AdminSearchBox({ initialValues, fieldCategories, path }: AdminSearchBoxProps) {
const router = useRouter();
- const handleSearchButtonClick = (values: SearchFormProps) => {
+ const handleSearchButtonClick = (values: AdminSearchFormProps) => {
router.push(`${path}?field=${values.field}&keyword=${values.keyword}`);
};
@@ -67,6 +65,4 @@ const SearchBox = ({ initialValues, fieldCategories, path }: SearchBoxProps) =>
)}
);
-};
-
-export default SearchBox;
+}
diff --git a/frontend/src/components/Formik/DatePicker/index.tsx b/frontend/src/components/common/formik/DatePicker.tsx
similarity index 92%
rename from frontend/src/components/Formik/DatePicker/index.tsx
rename to frontend/src/components/common/formik/DatePicker.tsx
index 02ac998a..0c258e23 100644
--- a/frontend/src/components/Formik/DatePicker/index.tsx
+++ b/frontend/src/components/common/formik/DatePicker.tsx
@@ -1,3 +1,5 @@
+'use client';
+
import { VscInfo } from '@react-icons/all-files/vsc/VscInfo';
type BuiltInInputProps = React.DetailedHTMLProps, HTMLInputElement>;
@@ -24,8 +26,8 @@ export const DatePicker = ({ isRequired = false, ...props }: DatePickerProps) =>
- {tooltip.split('\\n').map((data) => (
-
{data}
+ {tooltip.split('\\n').map((data, index) => (
+
{data}
))}
diff --git a/frontend/src/components/Formik/Dropdown/index.tsx b/frontend/src/components/common/formik/Dropdown.tsx
similarity index 95%
rename from frontend/src/components/Formik/Dropdown/index.tsx
rename to frontend/src/components/common/formik/Dropdown.tsx
index 15eff666..f793b18d 100644
--- a/frontend/src/components/Formik/Dropdown/index.tsx
+++ b/frontend/src/components/common/formik/Dropdown.tsx
@@ -1,6 +1,3 @@
-/* eslint-disable import/no-extraneous-dependencies */
-/* eslint-disable max-len */
-/* eslint-disable @typescript-eslint/no-explicit-any */
import { VscChevronDown } from '@react-icons/all-files/vsc/VscChevronDown';
import { VscChevronUp } from '@react-icons/all-files/vsc/VscChevronUp';
import { useState } from 'react';
diff --git a/frontend/src/app/(client)/components/Formik/Dropdown/index.tsx b/frontend/src/components/common/formik/DropdownDdang.tsx
similarity index 97%
rename from frontend/src/app/(client)/components/Formik/Dropdown/index.tsx
rename to frontend/src/components/common/formik/DropdownDdang.tsx
index 6a5b3632..fb31023d 100644
--- a/frontend/src/app/(client)/components/Formik/Dropdown/index.tsx
+++ b/frontend/src/components/common/formik/DropdownDdang.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable max-len */
-/* eslint-disable @typescript-eslint/no-explicit-any */
import { VscChevronDown } from '@react-icons/all-files/vsc/VscChevronDown';
import { VscChevronUp } from '@react-icons/all-files/vsc/VscChevronUp';
import React, { useState } from 'react';
diff --git a/frontend/src/components/Formik/EmailTextInput/index.tsx b/frontend/src/components/common/formik/EmailTextInput.tsx
similarity index 97%
rename from frontend/src/components/Formik/EmailTextInput/index.tsx
rename to frontend/src/components/common/formik/EmailTextInput.tsx
index fab027a6..805db493 100644
--- a/frontend/src/components/Formik/EmailTextInput/index.tsx
+++ b/frontend/src/components/common/formik/EmailTextInput.tsx
@@ -15,7 +15,7 @@ const EmailTextInput = ({ ...props }: TextInputProps) => {
const hasError = errorText !== undefined;
return (
-
+
{label} * {' '}
diff --git a/frontend/src/components/Formik/FileUploader/index.tsx b/frontend/src/components/common/formik/FileUploader.tsx
similarity index 100%
rename from frontend/src/components/Formik/FileUploader/index.tsx
rename to frontend/src/components/common/formik/FileUploader.tsx
diff --git a/frontend/src/components/Formik/ImageUploader/index.tsx b/frontend/src/components/common/formik/ImageUploader.tsx
similarity index 100%
rename from frontend/src/components/Formik/ImageUploader/index.tsx
rename to frontend/src/components/common/formik/ImageUploader.tsx
diff --git a/frontend/src/components/Formik/TextInput/index.tsx b/frontend/src/components/common/formik/TextInput.tsx
similarity index 61%
rename from frontend/src/components/Formik/TextInput/index.tsx
rename to frontend/src/components/common/formik/TextInput.tsx
index 9b37377b..ed4a20d1 100644
--- a/frontend/src/components/Formik/TextInput/index.tsx
+++ b/frontend/src/components/common/formik/TextInput.tsx
@@ -1,6 +1,7 @@
-/* eslint-disable @typescript-eslint/indent */
-/* eslint-disable max-len */
+'use client';
+
import { FORM_SIZE } from '@/constants';
+import { VscInfo } from '@react-icons/all-files/vsc/VscInfo';
type BuiltInTextInputProps = React.DetailedHTMLProps, HTMLInputElement>;
@@ -11,6 +12,7 @@ interface CustomTextInputProps {
errorText?: string;
size?: 'sm' | 'md' | 'lg';
isAdmin?: boolean;
+ tooltip?: string;
onKeyDownEnter?(): void;
onChangeText?(text: string): void;
}
@@ -18,13 +20,21 @@ interface CustomTextInputProps {
export type TextInputProps = Omit & CustomTextInputProps;
const TextInput = ({ isRequired = false, size = 'md', ...props }: TextInputProps) => {
- const { label, errorText, onKeyDownEnter, onChangeText, isAdmin, ...inputProps } = props;
+ const { label, errorText, isAdmin, tooltip, onKeyDownEnter, onChangeText, ...inputProps } = props;
const hasError = errorText !== undefined;
return (
{label && (
-
+
+ {tooltip && (
+
+ )}
{label} {isRequired && * }
)}
@@ -40,7 +50,7 @@ const TextInput = ({ isRequired = false, size = 'md', ...props }: TextInputProps
inputProps.onChange?.(e);
onChangeText?.(e.target.value);
}}
- className={`rounded-sm border-[1px] outline-none ${isAdmin ? 'border-admin-border' : 'border-border'} ${FORM_SIZE[size].padding} ${FORM_SIZE[size].textSize} ${hasError && 'border-red-400'}`}
+ className={`rounded-sm border-[1px] ${isAdmin ? 'border-admin-border' : 'border-border'} outline-none ${FORM_SIZE[size].padding} ${FORM_SIZE[size].textSize} ${hasError && 'border-red-400'}`}
/>
{errorText && {errorText} }
diff --git a/frontend/src/app/(client)/components/Formik/TextInput/index.tsx b/frontend/src/components/common/formik/TextInputDdang.tsx
similarity index 100%
rename from frontend/src/app/(client)/components/Formik/TextInput/index.tsx
rename to frontend/src/components/common/formik/TextInputDdang.tsx
diff --git a/frontend/src/components/layout/AdminFooter.tsx b/frontend/src/components/layout/AdminFooter.tsx
new file mode 100644
index 00000000..29a2cdfb
--- /dev/null
+++ b/frontend/src/components/layout/AdminFooter.tsx
@@ -0,0 +1,7 @@
+export default function AdminFooter() {
+ return (
+
+ copyright ⓒ KOREA LEARNING CONSULTING CENTER. All Right Reserved
+
+ );
+}
diff --git a/frontend/src/components/layout/AdminHeader.tsx b/frontend/src/components/layout/AdminHeader.tsx
new file mode 100644
index 00000000..44fc25ae
--- /dev/null
+++ b/frontend/src/components/layout/AdminHeader.tsx
@@ -0,0 +1,77 @@
+'use client';
+
+import Link from 'next/link';
+import Image from 'next/image';
+import { usePathname } from 'next/navigation';
+
+import { adminCategories } from '@/data/adminCategory';
+import { useAppSelector } from '@/lib/hooks/redux';
+
+export default function AdminHeader() {
+ return (
+
+
+
+
+
+
+ 사이트 메인으로
+
+
+ 로그아웃
+
+
+
+
+ );
+}
+
+export function AdminNavigator() {
+ const pathname = usePathname();
+ const linkStyle =
+ "h-admin-header text-admin-comment after:absolute relative flex items-center px-5 after:left-0 after:top-[15%] after:h-[70%] after:w-[1px] after:bg-border after:content-['']";
+ return (
+ <>
+ {adminCategories.map((item) => {
+ if (pathname.includes(item.url)) {
+ return (
+
+ {item.title}
+
+ );
+ }
+ return (
+
+ {item.title}
+
+ );
+ })}
+ >
+ );
+}
+
+export function AdminGreetingUser() {
+ const auth = useAppSelector((state) => state.auth).value;
+
+ return (
+
+ 반갑습니다! {auth.name} 님
+
+ );
+}
diff --git a/frontend/src/components/layout/AdminSidebar.tsx b/frontend/src/components/layout/AdminSidebar.tsx
new file mode 100644
index 00000000..559a7a8c
--- /dev/null
+++ b/frontend/src/components/layout/AdminSidebar.tsx
@@ -0,0 +1,60 @@
+'use client';
+
+import { useEffect, useState } from 'react';
+
+import Link from 'next/link';
+import { usePathname } from 'next/navigation';
+
+import { adminCategories } from '@/data/adminCategory';
+
+export default function AdminSidebar() {
+ const [currTab, setCurrTab] = useState('');
+ const pathname = usePathname();
+
+ const titleStyle = 'block max-h-[42px] cursor-default overflow-hidden border-b border-admin-border px-5 py-2.5';
+
+ const handleTabClick = (tab: string) => {
+ setCurrTab(tab);
+ };
+
+ useEffect(() => {
+ setCurrTab(pathname);
+ }, [pathname]);
+
+ return (
+
+
+ {adminCategories.map((item) => (
+
+ {currTab.includes(item.url) ? (
+
handleTabClick(item.url)}
+ >
+ {item.title}
+
+ ) : (
+
handleTabClick(item.url)}>
+ {item.title}
+
+ )}
+ {item.sub.map((subItem) => (
+
+ {subItem.title}
+
+ ))}
+
+ ))}
+
+
+ );
+}
diff --git a/frontend/src/components/layout/Footer.tsx b/frontend/src/components/layout/Footer.tsx
new file mode 100644
index 00000000..2db78978
--- /dev/null
+++ b/frontend/src/components/layout/Footer.tsx
@@ -0,0 +1,29 @@
+import Image from 'next/image';
+import Link from 'next/link';
+
+export default function Footer() {
+ return (
+
+
+
+ {/* 400 14px "Noto Sans KR", sans-serif */}
+
+
(46241) 부산광역시 금정구 부산대학로 63번길 2 (장전동)
+
부산대학교 소프트웨어융합교육원
+
+
+ 개인정보처리방침
+
+
ⓒ 2021 PNUswedu. All Right Reserved.
+
TEL : 051-510-3737, 3738, 3624
+
+
+ );
+}
diff --git a/frontend/src/components/layout/Header.tsx b/frontend/src/components/layout/Header.tsx
new file mode 100644
index 00000000..88e67f77
--- /dev/null
+++ b/frontend/src/components/layout/Header.tsx
@@ -0,0 +1,214 @@
+'use client';
+
+import { VscSettingsGear } from '@react-icons/all-files/vsc/VscSettingsGear';
+import { VscAccount } from '@react-icons/all-files/vsc/VscAccount';
+import { VscSignIn } from '@react-icons/all-files/vsc/VscSignIn';
+import { VscSignOut } from '@react-icons/all-files/vsc/VscSignOut';
+
+import Image from 'next/image';
+import Link from 'next/link';
+import { useState } from 'react';
+
+import { headerInfos } from '@/data/clientCategory';
+import { useAppSelector } from '@/lib/hooks/redux';
+import { CategoryDto } from '@/types/common.dto';
+import { AuthSliceState } from '@/store/auth.slice';
+import IconButton from '@/components/common/IconButton';
+
+interface HeaderUIProps {
+ auth: AuthSliceState;
+}
+
+interface SidebarProps {
+ open: boolean;
+ handleOpen: React.Dispatch>;
+}
+
+export default function Header() {
+ const auth = useAppSelector((state) => state.auth.value);
+
+ return (
+
+ );
+}
+
+export function TabletLayoutHeader({ auth }: HeaderUIProps) {
+ const [isSidebarOpen, setIsSideBarOpen] = useState(false);
+
+ return (
+ <>
+ setIsSideBarOpen(false)}
+ />
+
+
+
+
+
+ {auth.isAuth && auth.isModerator && (
+ <>
+ } title="관리" link="/admin" />
+ } title="로그아웃" link="/sign-out" />
+ >
+ )}
+ {auth.isAuth && !auth.isModerator && (
+ <>
+ } title="마이페이지" link="/my-page" />
+ } title="로그아웃" link="/sign-out" />
+ >
+ )}
+ {!auth.isAuth && } title="로그인" link="/sign-in" />}
+
+
+
+ >
+ );
+}
+
+export function DesktopLayoutHeader({ auth }: HeaderUIProps) {
+ return (
+
+
+
+
+
+ {headerInfos.map(
+ (item) =>
+ item.inHeader && (
+
+ ),
+ )}
+
+ {auth.isAuth && auth.isModerator && (
+ <>
+
} title="관리" link="/admin" />
+
} title="로그아웃" link="/sign-out" />
+ >
+ )}
+ {auth.isAuth && !auth.isModerator && (
+ <>
+
} title="마이페이지" link="/my-page" />
+
} title="로그아웃" link="/sign-out" />
+ >
+ )}
+ {!auth.isAuth && (
+
+
+ 로그인 / 회원가입
+
+
+ )}
+
+ );
+}
+
+export function HeaderAccordion({ title, url, sub }: CategoryDto) {
+ return (
+
+
+ {title}
+
+
+ {sub.map((item) => (
+
+ {item.title}
+
+ ))}
+
+
+ );
+}
+
+export function Sidebar({ open, handleOpen }: SidebarProps) {
+ const [currTab, setCurrTab] = useState
('');
+
+ const handleClose = () => {
+ handleOpen((e) => !e);
+ setCurrTab('');
+ };
+
+ return (
+
+
+
+ {headerInfos.map((item) => (
+
+
setCurrTab(item.title)}
+ >
+ {item.title}
+
+ {item.sub.map((subItem) => (
+
+ {subItem.title}
+
+ ))}
+
+ ))}
+
+
+ );
+}
diff --git a/frontend/src/components/layout/Sidebar.tsx b/frontend/src/components/layout/Sidebar.tsx
new file mode 100644
index 00000000..ba387967
--- /dev/null
+++ b/frontend/src/components/layout/Sidebar.tsx
@@ -0,0 +1,57 @@
+'use client';
+
+import { usePathname } from 'next/navigation';
+import { useCallback, useEffect, useState } from 'react';
+
+import { headerInfos } from '@/data/clientCategory';
+import { CategoryDto, SubCategoryDto } from '@/types/common.dto';
+
+import Link from 'next/link';
+
+export default function Sidebar() {
+ const pathname = usePathname();
+ const [currentCategory, setCurrentCategory] = useState();
+ const [currentSubCategory, setCurrentSubCategory] = useState();
+
+ const findMatchPath = useCallback(() => {
+ let maxOverlap = 0;
+ let bestMatch: SubCategoryDto | null = null;
+ currentCategory?.sub.forEach((category) => {
+ const { url } = category;
+ if (pathname.startsWith(url) && url.length > maxOverlap) {
+ maxOverlap = url.length;
+ bestMatch = category;
+ }
+ });
+ return bestMatch;
+ }, [pathname, currentCategory]);
+
+ useEffect(() => {
+ setCurrentCategory(headerInfos.filter((headerInfo) => pathname.startsWith(headerInfo.url))[0]);
+ }, [pathname]);
+
+ useEffect(() => {
+ setCurrentSubCategory(findMatchPath());
+ }, [findMatchPath]);
+
+ return (
+
+
{currentCategory?.title}
+
{currentCategory?.description}
+
+ {currentCategory?.sub.map((sub) => (
+
+ {sub.title}
+
+ ))}
+
+
+ );
+}
diff --git a/frontend/src/components/layout/SidebarLayout.tsx b/frontend/src/components/layout/SidebarLayout.tsx
new file mode 100644
index 00000000..414c7385
--- /dev/null
+++ b/frontend/src/components/layout/SidebarLayout.tsx
@@ -0,0 +1,12 @@
+import Sidebar from '@/components/layout/Sidebar';
+
+export default function SidebarLayout({ children }: Readonly<{ children: React.ReactNode }>) {
+ return (
+
+ );
+}
diff --git a/frontend/src/app/admin/faculty/list/components/MemberTable/index.tsx b/frontend/src/components/ui/admin/faculty/FacultyMemberTable.tsx
similarity index 90%
rename from frontend/src/app/admin/faculty/list/components/MemberTable/index.tsx
rename to frontend/src/components/ui/admin/faculty/FacultyMemberTable.tsx
index b8603a09..54baea39 100644
--- a/frontend/src/app/admin/faculty/list/components/MemberTable/index.tsx
+++ b/frontend/src/components/ui/admin/faculty/FacultyMemberTable.tsx
@@ -1,14 +1,13 @@
-/* eslint-disable max-len */
-
'use client';
+import { useRouter } from 'next/navigation';
+import { toast } from 'react-toastify';
+
import { useAppSelector } from '@/lib/hooks/redux';
import { useDeleteFacultyMutation } from '@/lib/hooks/useAdminApi';
import { FacultyMemberDto } from '@/types/common.dto';
-import { useRouter } from 'next/navigation';
-import { toast } from 'react-toastify';
-const MemberTable = ({ members }: { members: FacultyMemberDto[] }) => {
+export default function FacultyMemberTable({ members }: { members: FacultyMemberDto[] }) {
const { mutate: deleteFaculty } = useDeleteFacultyMutation();
const auth = useAppSelector((state) => state.auth).value;
const router = useRouter();
@@ -16,18 +15,16 @@ const MemberTable = ({ members }: { members: FacultyMemberDto[] }) => {
const handleDeleteButtonClick = (member: FacultyMemberDto) => {
window.confirm(`${member.name}을(를) 삭제하시겠습니까?`);
deleteFaculty(member.facultyId, {
- onSuccess(data, variables, context) {
+ onSuccess() {
toast.info('교직원 삭제에 성공했습니다.');
router.refresh();
},
- onError(error, variables, context) {
+ onError(error) {
toast.error(error.message);
},
});
};
- console.log(auth);
-
return (
@@ -64,6 +61,4 @@ const MemberTable = ({ members }: { members: FacultyMemberDto[] }) => {
);
-};
-
-export default MemberTable;
+}
diff --git a/frontend/src/app/admin/milestone/list/components/MilestoneHistoryTable/MilestoneHistoryExcelFileDownloadButton.tsx/index.tsx b/frontend/src/components/ui/admin/milestone/AdminMilestoneDownloadButton.tsx
similarity index 80%
rename from frontend/src/app/admin/milestone/list/components/MilestoneHistoryTable/MilestoneHistoryExcelFileDownloadButton.tsx/index.tsx
rename to frontend/src/components/ui/admin/milestone/AdminMilestoneDownloadButton.tsx
index a216f697..6273d66f 100644
--- a/frontend/src/app/admin/milestone/list/components/MilestoneHistoryTable/MilestoneHistoryExcelFileDownloadButton.tsx/index.tsx
+++ b/frontend/src/components/ui/admin/milestone/AdminMilestoneDownloadButton.tsx
@@ -4,12 +4,12 @@ import { useMilestoneHistoryExcelFileQuery } from '@/lib/hooks/useAdminApi';
import { useMemo } from 'react';
import { toast } from 'react-toastify';
-interface MilestoneHistoryExcelFileDownloadButtonProps {
+interface AdminMilestoneDownloadButtonProps {
field: number | null;
keyword: string | null;
}
-const MilestoneHistoryExcelFileDownloadButton = ({ field, keyword }: MilestoneHistoryExcelFileDownloadButtonProps) => {
+export default function AdminMilestoneDownloadButton({ field, keyword }: AdminMilestoneDownloadButtonProps) {
const { data: excelFile } = useMilestoneHistoryExcelFileQuery(field, keyword);
const excelFileUrl = useMemo(() => {
if (excelFile) {
@@ -38,6 +38,4 @@ const MilestoneHistoryExcelFileDownloadButton = ({ field, keyword }: MilestoneHi
Excel로 다운로드
);
-};
-
-export default MilestoneHistoryExcelFileDownloadButton;
+}
diff --git a/frontend/src/components/ui/admin/milestone/AdminMilestoneFilePreview.tsx b/frontend/src/components/ui/admin/milestone/AdminMilestoneFilePreview.tsx
new file mode 100644
index 00000000..68251016
--- /dev/null
+++ b/frontend/src/components/ui/admin/milestone/AdminMilestoneFilePreview.tsx
@@ -0,0 +1,55 @@
+import Image from 'next/image';
+
+import { HistoryFileType } from '@/data/milestone';
+import { getFileType } from '@/lib/utils/utils';
+
+interface AdminMilestoneFilePreviewProps {
+ fileName: string | null;
+}
+
+export default function AdminMilestoneFilePreview({ fileName }: AdminMilestoneFilePreviewProps) {
+ switch (getFileType(fileName)) {
+ case HistoryFileType.PDF:
+ return (
+ <>
+
+ 다운로드
+
+
+ >
+ );
+ case HistoryFileType.IMAGE:
+ return (
+ <>
+
+ 다운로드
+
+
+ >
+ );
+ case HistoryFileType.EMPTY:
+ return 첨부된 파일이 없습니다.
;
+ default:
+ return 잘못된 유형의 파일이 첨부되어 있습니다.
;
+ }
+}
diff --git a/frontend/src/components/ui/admin/milestone/AdminMilestoneStatusChangeButton.tsx b/frontend/src/components/ui/admin/milestone/AdminMilestoneStatusChangeButton.tsx
new file mode 100644
index 00000000..624e55e8
--- /dev/null
+++ b/frontend/src/components/ui/admin/milestone/AdminMilestoneStatusChangeButton.tsx
@@ -0,0 +1,105 @@
+'use client';
+
+import { useRouter } from 'next/navigation';
+import { useState } from 'react';
+import { toast } from 'react-toastify';
+
+import TextInput from '@/components/common/formik/TextInput';
+import { MilestoneHistoryStatus } from '@/data/milestone';
+import {
+ useMilestoneHistoryStatusApproveMutation,
+ useMilestoneHistoryStatusCancelMutation,
+ useMilestoneHistoryStatusRejectMutation,
+} from '@/lib/hooks/useAdminApi';
+import { convertMilestoneHistoryStatus } from '@/lib/utils/utils';
+
+interface AdminMilestoneStatusChangeButtonProps {
+ historyId: number;
+ status: string;
+}
+export default function AdminMilestoneStatusChangeButton({ historyId, status }: AdminMilestoneStatusChangeButtonProps) {
+ const { mutate: approveMilestoneHistory } = useMilestoneHistoryStatusApproveMutation();
+ const { mutate: rejectMilestoneHistory } = useMilestoneHistoryStatusRejectMutation();
+ const { mutate: cancelMilestoneHistory } = useMilestoneHistoryStatusCancelMutation();
+ const [rejectReason, setRejectReason] = useState('');
+ const router = useRouter();
+
+ const handleApproveButtonClick = () =>
+ approveMilestoneHistory(historyId, {
+ onSuccess: () => {
+ toast.info('실적 내역을 승인하였습니다.');
+ router.refresh();
+ },
+ onError: () => {
+ toast.error('실적 내역을 승인하는 데 실패했습니다.');
+ },
+ });
+ const handleRejectButtonClick = () =>
+ rejectMilestoneHistory(
+ { historyId, rejectReason },
+ {
+ onSuccess: () => {
+ toast.info('실적 내역을 반려하였습니다.');
+ router.refresh();
+ },
+ onError: () => {
+ toast.error('실적 내역을 반려하는 데 실패했습니다.');
+ },
+ },
+ );
+
+ const handleCancelButtonClick = () =>
+ cancelMilestoneHistory(historyId, {
+ onSuccess: () => {
+ toast.info(`${convertMilestoneHistoryStatus(status)}을(를) 취소했습니다.`);
+ router.refresh();
+ },
+ onError: () => {
+ toast.error(`${convertMilestoneHistoryStatus(status)} 취소에 실패하였습니다.`);
+ },
+ });
+ switch (status) {
+ case MilestoneHistoryStatus.PENDING:
+ return (
+
+
+ 승인
+
+
+
+ setRejectReason(e.target.value)}
+ name="rejectReason"
+ className="w-full"
+ />
+
+ 반려
+
+
+
+ );
+ case MilestoneHistoryStatus.APPROVED:
+ case MilestoneHistoryStatus.REJECTED:
+ return (
+
+ {convertMilestoneHistoryStatus(status)}취소
+
+ );
+ default:
+ return 마일스톤 내역의 상태 값에 문제가 있습니다.
;
+ }
+}
diff --git a/frontend/src/components/ui/admin/milestone/AdminMilestoneTable.tsx b/frontend/src/components/ui/admin/milestone/AdminMilestoneTable.tsx
new file mode 100644
index 00000000..982293f4
--- /dev/null
+++ b/frontend/src/components/ui/admin/milestone/AdminMilestoneTable.tsx
@@ -0,0 +1,111 @@
+import Link from 'next/link';
+
+import { MilestoneHistoryStatus } from '@/data/milestone';
+import { convertMilestoneHistoryStatus } from '@/lib/utils/utils';
+import { MilestoneHistoryDto } from '@/types/common.dto';
+
+interface AdminMilestoneTableProps {
+ histories: MilestoneHistoryDto[];
+}
+
+export default function AdminMilestoneTable({ histories }: AdminMilestoneTableProps) {
+ const getHistoryStatus = (status: string) => {
+ switch (status) {
+ case MilestoneHistoryStatus.PENDING:
+ return {convertMilestoneHistoryStatus(status)} ;
+ case MilestoneHistoryStatus.APPROVED:
+ return (
+ {convertMilestoneHistoryStatus(status)}
+ );
+ case MilestoneHistoryStatus.REJECTED:
+ return (
+
+ {convertMilestoneHistoryStatus(status)}
+
+ );
+ default:
+ return convertMilestoneHistoryStatus(status);
+ }
+ };
+
+ return (
+
+
+
+ No.
+ 이름
+ 학번
+ 활동 코드
+ 활동명
+ 건당 점수
+ 활동 횟수(건)
+ 활동일
+ 등록일
+ 승인 여부
+
+
+
+ {histories?.map((history) => {
+ const linkHref = `/admin/milestone/${history.id}`;
+ return (
+
+
+
+ {history.id}
+
+
+
+
+ {history.student.name}
+
+
+
+
+ {history.student.id}
+
+
+
+
+ {history.milestone.id}
+
+
+
+
+ {history.description}
+
+
+
+
+ {history.milestone.score}
+
+
+
+
+ {history.count}
+
+
+
+
+ {history.activatedAt}
+
+
+
+
+ {history.createdAt.slice(0, 10)}
+
+
+
+
+ {getHistoryStatus(history.status)}
+
+
+
+ );
+ })}
+
+
+ );
+}
diff --git a/frontend/src/components/ui/admin/student/StudentMemberTable.tsx b/frontend/src/components/ui/admin/student/StudentMemberTable.tsx
new file mode 100644
index 00000000..632a6a32
--- /dev/null
+++ b/frontend/src/components/ui/admin/student/StudentMemberTable.tsx
@@ -0,0 +1,40 @@
+import { StudentMemberDto } from '@/types/common.dto';
+
+export default function StudentMemberTable({ members }: { members: StudentMemberDto[] }) {
+ return (
+
+
+ 이메일
+ 이름
+ 학번
+ 주전공
+ 부전공
+ 복수전공
+ 전화번호
+ 진로
+
+
+ {members.map((member) => {
+ const emailWords = member.email.split('@');
+ return (
+
+
+ {emailWords[0]}
+ @pusan.ac.kr
+
+ {member.name}
+ {member.id}
+ {member.major}
+ {member.minor}
+ {member.doubleMajor}
+ {member.phoneNumber}
+
+ {member.careerDetail}
+
+
+ );
+ })}
+
+
+ );
+}
diff --git a/frontend/src/components/ui/auth/AuthFindPageFooter.tsx b/frontend/src/components/ui/auth/AuthFindPageFooter.tsx
new file mode 100644
index 00000000..bf1e7023
--- /dev/null
+++ b/frontend/src/components/ui/auth/AuthFindPageFooter.tsx
@@ -0,0 +1,18 @@
+export default function AuthFindPageFooter() {
+ return (
+
+ );
+}
diff --git a/frontend/src/components/ui/auth/AuthFindPageTabButton.tsx b/frontend/src/components/ui/auth/AuthFindPageTabButton.tsx
new file mode 100644
index 00000000..c560561f
--- /dev/null
+++ b/frontend/src/components/ui/auth/AuthFindPageTabButton.tsx
@@ -0,0 +1,28 @@
+import { headers } from 'next/headers';
+
+const findTabs = [
+ { name: '아이디 찾기', url: '/find-id' },
+ { name: '비밀번호 찾기', url: '/find-password' },
+];
+
+export default function AuthFindPageTabButton() {
+ const headersList = headers();
+ const pathname = headersList.get('x-pathname') || '';
+
+ const matchedPathStyle = 'border-b-4 border-primary-main text-primary-main';
+ const unmatchedPathStyle = 'border-b-[1px] border-comment text-comment';
+
+ return (
+
+ );
+}
diff --git a/frontend/src/app/(client)/(auth)/find-password/components/FindForm/index.tsx b/frontend/src/components/ui/auth/AuthFindPasswordForm.tsx
similarity index 92%
rename from frontend/src/app/(client)/(auth)/find-password/components/FindForm/index.tsx
rename to frontend/src/components/ui/auth/AuthFindPasswordForm.tsx
index c909dfb0..e6284a61 100644
--- a/frontend/src/app/(client)/(auth)/find-password/components/FindForm/index.tsx
+++ b/frontend/src/components/ui/auth/AuthFindPasswordForm.tsx
@@ -1,12 +1,12 @@
'use client';
+import { useRouter } from 'next/navigation';
import { Form, Formik } from 'formik';
+import { toast } from 'react-toastify';
-import EmailTextInput from '@/components/Formik/EmailTextInput';
-import TextInput from '@/components/Formik/TextInput';
+import EmailTextInput from '@/components/common/formik/EmailTextInput';
+import TextInput from '@/components/common/formik/TextInput';
import { useResetPasswordMutation } from '@/lib/hooks/useApi';
-import { toast } from 'react-toastify';
-import { useRouter } from 'next/navigation';
interface FormType {
email: string;
@@ -18,7 +18,7 @@ const initialValues: FormType = {
name: '',
};
-const FindForm = () => {
+export default function AuthFindPasswordForm() {
const { mutate: resetPasswordMutation } = useResetPasswordMutation();
const router = useRouter();
@@ -82,6 +82,4 @@ const FindForm = () => {
)}
);
-};
-
-export default FindForm;
+}
diff --git a/frontend/src/components/ui/auth/AuthSignInForm.tsx b/frontend/src/components/ui/auth/AuthSignInForm.tsx
new file mode 100644
index 00000000..714a244c
--- /dev/null
+++ b/frontend/src/components/ui/auth/AuthSignInForm.tsx
@@ -0,0 +1,93 @@
+'use client';
+
+import { useEffect, useState } from 'react';
+import { useRouter } from 'next/navigation';
+import { toast } from 'react-toastify';
+
+import { useAppDispatch, useAppSelector } from '@/lib/hooks/redux';
+import { useSignInMutation } from '@/lib/hooks/useApi';
+import { signIn } from '@/store/auth.slice';
+
+export default function AuthSignInForm() {
+ const [userInfo, setUserInfo] = useState({
+ email: '',
+ password: '',
+ });
+
+ const router = useRouter();
+
+ const { mutate: signInMutation } = useSignInMutation();
+
+ const dispatch = useAppDispatch();
+ const auth = useAppSelector((state) => state.auth).value;
+
+ const handleInputChange = (e: React.ChangeEvent) => {
+ setUserInfo((prev) => {
+ return {
+ ...prev,
+ [e.target.id]: e.target.value,
+ };
+ });
+ };
+
+ const handleSubmit = (e: React.FormEvent) => {
+ e.preventDefault();
+ signInMutation(userInfo, {
+ onSuccess(data, variables, context) {
+ dispatch(
+ signIn({
+ id: data.member_id,
+ token: `Bearer ${data.token}`,
+ name: data.name,
+ email: data.email,
+ isModerator: data.is_moderator,
+ }),
+ );
+ router.push('/');
+ },
+ onError(error, variables, context) {
+ toast.error(error.message);
+ },
+ });
+ };
+
+ useEffect(() => {
+ if (auth.isAuth) router.push('/');
+ }, [auth, router]);
+
+ return (
+
+ );
+}
diff --git a/frontend/src/app/(client)/(auth)/sign-up/components/SignUpFirstPage/index.tsx b/frontend/src/components/ui/auth/AuthSignUpFirst.tsx
similarity index 94%
rename from frontend/src/app/(client)/(auth)/sign-up/components/SignUpFirstPage/index.tsx
rename to frontend/src/components/ui/auth/AuthSignUpFirst.tsx
index 639db8b3..b837827f 100644
--- a/frontend/src/app/(client)/(auth)/sign-up/components/SignUpFirstPage/index.tsx
+++ b/frontend/src/components/ui/auth/AuthSignUpFirst.tsx
@@ -1,17 +1,15 @@
-/* eslint-disable import/no-extraneous-dependencies */
-
'use client';
import { Formik, Form } from 'formik';
import * as Yup from 'yup';
-import { TextInput } from '@/app/(client)/components/Formik/TextInput';
+import { TextInput } from '@/components/common/formik/TextInputDdang';
-import EmailTextInput from './components/EmailTextInput';
import { useState } from 'react';
import { useSendAuthCodeMutation } from '@/lib/hooks/useApi';
import { toast } from 'react-toastify';
import { getValidationStudentId } from '@/lib/api/server.api';
+import EmailTextInput from '@/components/common/formik/EmailTextInput';
export interface FirstInfo {
email: string;
@@ -62,12 +60,12 @@ const validationSchema = Yup.object().shape({
.matches(/^([0-9]{10,11})$/, '띄어쓰기나 특수기호 없이 숫자로만 입력해주세요.'),
});
-interface SignUpFirstPageProps {
+interface AuthSignUpFirstProps {
initialValues: FirstInfo;
handleNextButtonClick: (value: FirstInfo) => void;
}
-const SignUpSecondPage = ({ initialValues, handleNextButtonClick }: SignUpFirstPageProps) => {
+export default function AuthSignUpFirst({ initialValues, handleNextButtonClick }: AuthSignUpFirstProps) {
const [isSendedMail, setIsSendedMail] = useState(false);
const { mutate: sendAuthCodeMutation } = useSendAuthCodeMutation();
@@ -75,10 +73,10 @@ const SignUpSecondPage = ({ initialValues, handleNextButtonClick }: SignUpFirstP
setIsSendedMail(true);
sendAuthCodeMutation(email + '@pusan.ac.kr', {
- onSuccess(data, variables, context) {
+ onSuccess() {
toast.info('메일이 정상 발송되었습니다.');
},
- onError(error, variables, context) {
+ onError(error) {
toast.error(error.message);
},
});
@@ -205,6 +203,4 @@ const SignUpSecondPage = ({ initialValues, handleNextButtonClick }: SignUpFirstP
)}
);
-};
-
-export default SignUpSecondPage;
+}
diff --git a/frontend/src/app/(client)/(auth)/sign-up/components/SignUpSecondPage/components/MajorDropdown/index.tsx b/frontend/src/components/ui/auth/AuthSignUpMajorDropdown.tsx
similarity index 80%
rename from frontend/src/app/(client)/(auth)/sign-up/components/SignUpSecondPage/components/MajorDropdown/index.tsx
rename to frontend/src/components/ui/auth/AuthSignUpMajorDropdown.tsx
index 542cfeb9..d340d4e9 100644
--- a/frontend/src/app/(client)/(auth)/sign-up/components/SignUpSecondPage/components/MajorDropdown/index.tsx
+++ b/frontend/src/components/ui/auth/AuthSignUpMajorDropdown.tsx
@@ -1,20 +1,17 @@
-/* eslint-disable react-hooks/exhaustive-deps */
-/* eslint-disable @typescript-eslint/no-unused-vars */
import { useEffect, useState } from 'react';
-import Dropdown, { DropdownProps } from '@/components/Formik/Dropdown';
-import { useCollegeQuery } from '@/lib/hooks/useApi';
+import Dropdown, { DropdownProps } from '@/components/common/formik/Dropdown';
import { getColleges } from '@/mocks/college';
import { CollegeDto, MajorDto } from '@/types/common.dto';
-export interface MajorDropdownProps extends Omit {
+export interface AuthSignUpMajorDropdownProps extends Omit {
collegeId: number;
majorId: number;
collegeName: string;
majorName: string;
}
-const MajorDropdown = ({ ...props }: MajorDropdownProps) => {
+export default function AuthSignUpMajorDropdown({ ...props }: AuthSignUpMajorDropdownProps) {
const collegesData = getColleges;
/* TODO: mocks 삭제 및 api 호출
const { data: collegesData } = useCollegeQuery();
@@ -65,6 +62,4 @@ const MajorDropdown = ({ ...props }: MajorDropdownProps) => {
/>
);
-};
-
-export default MajorDropdown;
+}
diff --git a/frontend/src/components/ui/auth/AuthSignUpSecond.tsx b/frontend/src/components/ui/auth/AuthSignUpSecond.tsx
new file mode 100644
index 00000000..b8458ebd
--- /dev/null
+++ b/frontend/src/components/ui/auth/AuthSignUpSecond.tsx
@@ -0,0 +1,133 @@
+'use client';
+
+import { Formik, Form } from 'formik';
+import * as Yup from 'yup';
+
+import { Dropdown } from '@/components/common/formik/DropdownDdang';
+import { TextInput } from '@/components/common/formik/TextInputDdang';
+import { careerCategory } from '@/data/signUp';
+import AuthSignUpMajorDropdown from '@/components/ui/auth/AuthSignUpMajorDropdown';
+
+export interface SecondInfo {
+ majorCollegeId: number;
+ majorId: number;
+ minorCollegeId: number;
+ minorId: number;
+ doubleMajorCollegeId: number;
+ doubleMajorId: number;
+ career: number;
+ careerDetail: string;
+}
+
+const validationSchema = Yup.object().shape({
+ majorId: Yup.number().min(1, '필수 입력란입니다. 전공을 선택해주세요.'),
+ minorId: Yup.number().min(0, '필수 입력란입니다. 부전공 선택해주세요.'),
+ doubleMajorId: Yup.number().min(0, '필수 입력란입니다. 복수전공을 선택해주세요.'),
+ career: Yup.number().min(1, '필수 입력란입니다. 진로 분류를 선택해주세요.'),
+ careerDetail: Yup.string().required('필수 입력란입니다. 진로 상세 계획을 입력해주세요.'),
+});
+
+export interface SignUpSecondPageProps {
+ initialValues: SecondInfo;
+ handlePrevButtonClick: (value: SecondInfo) => void;
+ handleSubmitButtonClick: (value: SecondInfo) => void;
+}
+
+export default function AuthSignUpSecond({
+ initialValues,
+ handlePrevButtonClick,
+ handleSubmitButtonClick,
+}: SignUpSecondPageProps) {
+ return (
+ {
+ handleSubmitButtonClick(values);
+ setSubmitting(false);
+ }}
+ >
+ {({ isSubmitting, values, touched, handleChange, handleBlur, setFieldValue, errors }) => (
+
+ )}
+
+ );
+}
diff --git a/frontend/src/components/MarkdownViewer/markdown.css b/frontend/src/components/ui/hackathon/MarkdownViewer.css
similarity index 100%
rename from frontend/src/components/MarkdownViewer/markdown.css
rename to frontend/src/components/ui/hackathon/MarkdownViewer.css
diff --git a/frontend/src/components/MarkdownViewer/index.tsx b/frontend/src/components/ui/hackathon/MarkdownViewer.tsx
similarity index 94%
rename from frontend/src/components/MarkdownViewer/index.tsx
rename to frontend/src/components/ui/hackathon/MarkdownViewer.tsx
index 22bc5710..0ca0c7e3 100644
--- a/frontend/src/components/MarkdownViewer/index.tsx
+++ b/frontend/src/components/ui/hackathon/MarkdownViewer.tsx
@@ -17,13 +17,13 @@ import { EditorContent, useEditor } from '@tiptap/react';
import { StarterKit } from '@tiptap/starter-kit';
import { common, createLowlight } from 'lowlight';
import { Markdown } from 'tiptap-markdown';
-import './markdown.css';
+import './MarkdownViewer.css';
interface MarkdownViewerProps {
content: string;
}
-const MarkdownViewer = ({ content }: MarkdownViewerProps) => {
+export default function MarkdownViewer({ content }: MarkdownViewerProps) {
const editor = useEditor({
extensions: [
StarterKit.configure({
@@ -69,6 +69,4 @@ const MarkdownViewer = ({ content }: MarkdownViewerProps) => {
);
-};
-
-export default MarkdownViewer;
+}
diff --git a/frontend/src/components/ui/home/GoPageIcon.tsx b/frontend/src/components/ui/home/GoPageIcon.tsx
new file mode 100644
index 00000000..7e6b5151
--- /dev/null
+++ b/frontend/src/components/ui/home/GoPageIcon.tsx
@@ -0,0 +1,16 @@
+import { VscAdd } from '@react-icons/all-files/vsc/VscAdd';
+import Link from 'next/link';
+
+interface GoPageIconProps {
+ name: string;
+ url: string;
+}
+
+export default function GoPageIcon({ name, url }: GoPageIconProps) {
+ return (
+
+
+ {name}
+
+ );
+}
diff --git a/frontend/src/components/ui/home/HomeAnnouncement.tsx b/frontend/src/components/ui/home/HomeAnnouncement.tsx
new file mode 100644
index 00000000..c9a2a057
--- /dev/null
+++ b/frontend/src/components/ui/home/HomeAnnouncement.tsx
@@ -0,0 +1,40 @@
+import RSSParser from 'rss-parser';
+
+import GoPageIcon from '@/components/ui/home/GoPageIcon';
+
+import Link from 'next/link';
+
+export default async function HomeAnnouncement() {
+ const ANNOUNCEMENT_URL = 'https://swedu.pusan.ac.kr/swedu/31630/subview.do';
+ const parser = new RSSParser();
+ const announcements = await parser.parseURL('https://swedu.pusan.ac.kr/bbs/swedu/6906/rssList.do?row=50');
+
+ return (
+
+
+
+
공지사항
+
소프트웨어융합교육원의 공지사항을 알려드려요.
+
+
+
+
+ {announcements.items.slice(0, 4).map((item) => (
+
+
+ {item.title}
+
+
+ {item.pubDate?.slice(0, 10).replaceAll('-', '.')}
+
+
+ ))}
+
+
+ );
+}
diff --git a/frontend/src/components/ui/home/HomeExternalLink.tsx b/frontend/src/components/ui/home/HomeExternalLink.tsx
new file mode 100644
index 00000000..463d3057
--- /dev/null
+++ b/frontend/src/components/ui/home/HomeExternalLink.tsx
@@ -0,0 +1,28 @@
+import Image from 'next/image';
+
+import { externalLinkInfos } from '@/data/externalLink';
+
+import Link from 'next/link';
+
+export default function HomeExternalLink() {
+ return (
+
+ {externalLinkInfos.map((link) => {
+ const markup = { __html: link.title };
+ return (
+
+
+
+
+
+
+ );
+ })}
+
+ );
+}
diff --git a/frontend/src/app/(client)/components/Milestone/index.tsx b/frontend/src/components/ui/home/HomeMilestone.tsx
similarity index 55%
rename from frontend/src/app/(client)/components/Milestone/index.tsx
rename to frontend/src/components/ui/home/HomeMilestone.tsx
index 85345ff5..0dfb1e22 100644
--- a/frontend/src/app/(client)/components/Milestone/index.tsx
+++ b/frontend/src/components/ui/home/HomeMilestone.tsx
@@ -1,18 +1,41 @@
-import MilestoneChart from '@/components/MilestoneChart';
-import MilestoneTable from '@/components/MilestoneTable';
+import MilestoneCircleChart from '@/components/ui/milestone/MilestoneCircleChart';
+import MilestoneOverviewTable from '@/components/ui/milestone/MilestoneOverviewTable';
+import GoPageIcon from '@/components/ui/home/GoPageIcon';
+import HomeSignIn from '@/components/ui/home/HomeSignIn';
import { getAuthFromCookie } from '@/lib/utils/auth';
import { AuthSliceState } from '@/store/auth.slice';
-import { MilestoneChartWrapper } from './styled';
-import GoPageIcon from '../GoPageIcon';
-import SignIn from '../SignIn';
-import { Description, Title, TitleContent, TitleWrapper } from '../styled';
import { getMyMilestoneHistory } from '@/lib/api/server.api';
import { DateTime } from 'luxon';
import { MilestoneOverviewScore } from '@/types/milestone';
import { initialMilestoneOverview } from '@/data/milestone';
-const getMilestoneScores = async (studentId: number) => {
+export default async function HomeMilestone() {
+ const auth: AuthSliceState = getAuthFromCookie();
+
+ const milestoneOverviewScore = await getMilestoneOverviewScore(auth.id);
+
+ return (
+
+
+
+
나의 마일스톤
+
나의 마일스톤 내역을 확인할 수 있어요.
+
+ {auth.isAuth &&
}
+
+ {auth.isAuth && (
+
+
+
+
+ )}
+ {!auth.isAuth &&
}
+
+ );
+}
+
+async function getMilestoneScores(studentId: number) {
const auth = getAuthFromCookie();
const startDate = DateTime.now().minus({ years: 1 }).toFormat('yyyy-MM-dd');
const endDate = DateTime.now().toFormat('yyyy-MM-dd');
@@ -23,9 +46,9 @@ const getMilestoneScores = async (studentId: number) => {
// TODO: server api error handling
}
return null;
-};
+}
-const getMilestoneOverviewScore = async (studentId: number) => {
+async function getMilestoneOverviewScore(studentId: number) {
const milestoneScores = await getMilestoneScores(studentId);
const milestoneOverviewScore = milestoneScores?.reduce
(
(acc, cur) => {
@@ -37,31 +60,4 @@ const getMilestoneOverviewScore = async (studentId: number) => {
{ ...initialMilestoneOverview },
);
return milestoneOverviewScore || initialMilestoneOverview;
-};
-
-const Milestone = async () => {
- const auth: AuthSliceState = getAuthFromCookie();
-
- const milestoneOverviewScore = await getMilestoneOverviewScore(auth.id);
-
- return (
-
-
-
- 나의 마일스톤
- 나의 마일스톤 내역을 확인할 수 있어요.
-
- {auth.isAuth && }
-
- {auth.isAuth && (
-
-
-
-
- )}
- {!auth.isAuth && }
-
- );
-};
-
-export default Milestone;
+}
diff --git a/frontend/src/app/(client)/components/PnuLink/index.tsx b/frontend/src/components/ui/home/HomePnuLink.tsx
similarity index 61%
rename from frontend/src/app/(client)/components/PnuLink/index.tsx
rename to frontend/src/components/ui/home/HomePnuLink.tsx
index 8d2ee2e1..90b72603 100644
--- a/frontend/src/app/(client)/components/PnuLink/index.tsx
+++ b/frontend/src/components/ui/home/HomePnuLink.tsx
@@ -5,14 +5,15 @@ import { useEffect, useState } from 'react';
import { Autoplay, Scrollbar } from 'swiper/modules';
import { Swiper, SwiperClass, SwiperSlide } from 'swiper/react';
+import { VscChevronLeft } from '@react-icons/all-files/vsc/VscChevronLeft';
+import { VscChevronRight } from '@react-icons/all-files/vsc/VscChevronRight';
import { RESPONSIVE_WIDTH } from '@/constants';
import { pnuLinkInfos } from '@/data/externalLink';
-import { ButtonWrapper, NextButton, PnuLinker, PrevButton } from './styled';
-
import 'swiper/css';
+import Link from 'next/link';
-const PnuLink = () => {
+export default function HomePnuLink() {
const [displayCount, setDisplayCount] = useState(2);
const [swiper, setSwiper] = useState();
const [innerWidth, setInnerWidth] = useState(window.innerWidth);
@@ -35,16 +36,21 @@ const PnuLink = () => {
useEffect(() => {
if (innerWidth > parseInt(RESPONSIVE_WIDTH.desktop, 10)) setDisplayCount(6);
else if (innerWidth > parseInt(RESPONSIVE_WIDTH.tablet, 10)) setDisplayCount(4);
- else if (innerWidth > parseInt(RESPONSIVE_WIDTH.mobile, 10)) setDisplayCount(3);
else setDisplayCount(2);
}, [innerWidth]);
return (
-
-
-
-
+
+
+
+
{
>
{pnuLinkInfos.map((link) => (
-
-
-
+
+
+
))}
);
-};
-
-export default PnuLink;
+}
diff --git a/frontend/src/components/ui/home/HomeSignIn.tsx b/frontend/src/components/ui/home/HomeSignIn.tsx
new file mode 100644
index 00000000..ccb50c18
--- /dev/null
+++ b/frontend/src/components/ui/home/HomeSignIn.tsx
@@ -0,0 +1,104 @@
+'use client';
+
+import { useRouter } from 'next/navigation';
+import { useState } from 'react';
+
+import { useAppDispatch } from '@/lib/hooks/redux';
+import { signIn } from '@/store/auth.slice';
+
+import { useSignInMutation } from '@/lib/hooks/useApi';
+import { toast } from 'react-toastify';
+import Link from 'next/link';
+
+export default function HomeSignIn() {
+ const [userInfo, setUserInfo] = useState({
+ email: '',
+ password: '',
+ });
+
+ const { mutate: signInMutation } = useSignInMutation();
+
+ const router = useRouter();
+ const dispatch = useAppDispatch();
+
+ const handleInputChange = (e: React.ChangeEvent) => {
+ setUserInfo((prev) => {
+ return {
+ ...prev,
+ [e.target.id]: e.target.value,
+ };
+ });
+ };
+
+ const handleSubmit = (e: React.FormEvent) => {
+ e.preventDefault();
+
+ signInMutation(userInfo, {
+ onSuccess(data, variables, context) {
+ dispatch(
+ signIn({
+ id: data.member_id,
+ token: `Bearer ${data.token}`,
+ name: data.name,
+ email: data.email,
+ isModerator: data.is_moderator,
+ }),
+ );
+ router.refresh();
+ },
+ onError(error, variables, context) {
+ toast.error(error.message);
+ },
+ });
+ };
+
+ return (
+
+
로그인이 필요한 서비스입니다.
+
+
+
+
+ 아이디
+
+ /
+
+ 비밀번호
+
+ 찾기
+
+
+ 처음오셨나요?{' '}
+
+ 회원가입
+
+
+
+
+ );
+}
diff --git a/frontend/src/components/ui/home/HomeTeamBuilding.tsx b/frontend/src/components/ui/home/HomeTeamBuilding.tsx
new file mode 100644
index 00000000..1c328bdb
--- /dev/null
+++ b/frontend/src/components/ui/home/HomeTeamBuilding.tsx
@@ -0,0 +1,46 @@
+import TeamBuildingCard from '@/components/ui/team-building/TeamBuildingCard';
+import GoPageIcon from '@/components/ui/home/GoPageIcon';
+import { teamBuildingInfos } from '@/mocks/teamBuilding';
+
+import Link from 'next/link';
+
+export default function HomeTeamBuilding() {
+ return (
+
+
+
+
팀 빌딩
+
+ 프로젝트 팀원을 모집하고 있나요? 함께할 팀을 찾고 있나요?
+
+
+
+
+
+ {teamBuildingInfos.length === 0 && (
+
+
아직 팀이 생성되지 않았습니다.
+
지금 바로 새로운 팀을 생성해 보세요!
+
+ [팀 생성하기]
+
+
+ )}
+ {teamBuildingInfos.map((team) => (
+
+ ))}
+
+
+ );
+}
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneHistoryTable/index.tsx b/frontend/src/components/ui/milestone/MilestoneAcceptedTable.tsx
similarity index 86%
rename from frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneHistoryTable/index.tsx
rename to frontend/src/components/ui/milestone/MilestoneAcceptedTable.tsx
index 438e09b5..f4e5381c 100644
--- a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneHistoryTable/index.tsx
+++ b/frontend/src/components/ui/milestone/MilestoneAcceptedTable.tsx
@@ -1,21 +1,24 @@
-/* eslint-disable jsx-a11y/control-has-associated-label */
-/* eslint-disable max-len */
-import Pagination from '@/app/(client)/components/Pagination';
-import MilestoneGroupLabel from '@/components/MilestoneGroupLabel';
+import { usePathname } from 'next/navigation';
+
+import Pagination from '@/components/common/Pagination';
+import MilestoneGroupLabel from '@/components/ui/milestone/MilestoneGroupLabel';
import { MilestoneHistoryStatus } from '@/data/milestone';
import { useAppSelector } from '@/lib/hooks/redux';
import { useMilestoneHistoriesOfStudentQuery } from '@/lib/hooks/useApi';
import { Period } from '@/types/common';
import { MilestoneHistorySortCriteria, SortDirection } from '@/types/milestone';
-import { usePathname } from 'next/navigation';
-interface MilestoneHistoryTableProps {
+export interface MilestoneAcceptedTableProps {
searchFilterPeriod: Period;
pageNumber: number;
pageSize: number;
}
-const MilestoneHistoryTable = ({ searchFilterPeriod, pageNumber, pageSize }: MilestoneHistoryTableProps) => {
+export default function MilestoneAcceptedTable({
+ searchFilterPeriod,
+ pageNumber,
+ pageSize,
+}: MilestoneAcceptedTableProps) {
const pathname = usePathname();
const auth = useAppSelector((state) => state.auth).value;
const { data: milestoneHistoriesOfStudent } = useMilestoneHistoriesOfStudentQuery(
@@ -64,6 +67,4 @@ const MilestoneHistoryTable = ({ searchFilterPeriod, pageNumber, pageSize }: Mil
/>
);
-};
-
-export default MilestoneHistoryTable;
+}
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/register/write/components/MilestoneDropdown/index.tsx b/frontend/src/components/ui/milestone/MilestoneCategoryDropdown.tsx
similarity index 88%
rename from frontend/src/app/(client)/(withSidebar)/my-page/milestone/register/write/components/MilestoneDropdown/index.tsx
rename to frontend/src/components/ui/milestone/MilestoneCategoryDropdown.tsx
index f7298846..febf882e 100644
--- a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/register/write/components/MilestoneDropdown/index.tsx
+++ b/frontend/src/components/ui/milestone/MilestoneCategoryDropdown.tsx
@@ -1,13 +1,11 @@
-/* eslint-disable operator-linebreak */
-/* eslint-disable implicit-arrow-linebreak */
import { Dispatch, SetStateAction, useEffect, useMemo, useState } from 'react';
-import { Dropdown, DropdownOption, DropdownProps } from '@/app/(client)/components/Formik/Dropdown';
+import { Dropdown, DropdownOption, DropdownProps } from '@/components/common/formik/DropdownDdang';
import { MilestoneGroup } from '@/data/milestone';
import { useMilestoneQuery } from '@/lib/hooks/useApi';
import { Milestone, MilestoneCategory } from '@/types/milestone';
-export interface MilestoneDropdownProps extends Omit {
+export interface MilestoneCategoryDropdownProps extends Omit {
categoryId: number;
milestoneId: number;
categoryName: string;
@@ -17,7 +15,7 @@ export interface MilestoneDropdownProps extends Omit>;
}
-const MilestoneDropdown = ({ ...props }: MilestoneDropdownProps) => {
+export default function MilestoneCategoryDropdown({ ...props }: MilestoneCategoryDropdownProps) {
const { data: milestoneOverviews } = useMilestoneQuery();
const {
categoryId,
@@ -93,6 +91,4 @@ const MilestoneDropdown = ({ ...props }: MilestoneDropdownProps) => {
);
-};
-
-export default MilestoneDropdown;
+}
diff --git a/frontend/src/components/ui/milestone/MilestoneCircleChart.tsx b/frontend/src/components/ui/milestone/MilestoneCircleChart.tsx
new file mode 100644
index 00000000..643b94d8
--- /dev/null
+++ b/frontend/src/components/ui/milestone/MilestoneCircleChart.tsx
@@ -0,0 +1,53 @@
+import { MilestoneOverviewScore } from '@/types/milestone';
+
+export interface MilestoneCircleChartProps {
+ chartSize: number;
+ fontSize: 'sm' | 'lg';
+ milestoneOverviewScore: MilestoneOverviewScore;
+}
+
+export default function MilestoneCircleChart({
+ chartSize,
+ fontSize,
+ milestoneOverviewScore,
+}: MilestoneCircleChartProps) {
+ const { activityScore, globalScore, communityScore, totalScore } = milestoneOverviewScore;
+ const scores = [
+ { start: 0, score: activityScore, color: '#8FA3F8', title: '실전적 SW역량' },
+ { start: activityScore, score: globalScore, color: '#9DE6BC', title: '글로벌 SW역량' },
+ {
+ start: activityScore + globalScore,
+ score: communityScore,
+ color: '#AA8CF8',
+ title: '커뮤니티 SW역량',
+ },
+ ];
+
+ return (
+
+ {scores.map((bar) => (
+
+ ))}
+
+
+
{totalScore}
+
/ 1000
+
+
+ );
+}
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/register/components/MilestoneHistoryDeleteButton/index.tsx b/frontend/src/components/ui/milestone/MilestoneDeleteButton.tsx
similarity index 76%
rename from frontend/src/app/(client)/(withSidebar)/my-page/milestone/register/components/MilestoneHistoryDeleteButton/index.tsx
rename to frontend/src/components/ui/milestone/MilestoneDeleteButton.tsx
index e536e30a..b7a262f0 100644
--- a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/register/components/MilestoneHistoryDeleteButton/index.tsx
+++ b/frontend/src/components/ui/milestone/MilestoneDeleteButton.tsx
@@ -5,11 +5,11 @@ import { useRouter } from 'next/navigation';
import { toast } from 'react-toastify';
import { useMilestoneHistoryDeleteMutation } from '@/lib/hooks/useApi';
-interface MilestoneHistoryDeleteButtonProps {
+export interface MilestoneDeleteButtonProps {
historyId: number;
}
-const MilestoneHistoryDeleteButton = ({ historyId }: MilestoneHistoryDeleteButtonProps) => {
+export default function MilestoneDeleteButton({ historyId }: MilestoneDeleteButtonProps) {
const router = useRouter();
const { mutate: deleteMilestoneHistory } = useMilestoneHistoryDeleteMutation();
@@ -30,11 +30,9 @@ const MilestoneHistoryDeleteButton = ({ historyId }: MilestoneHistoryDeleteButto
삭제
);
-};
-
-export default MilestoneHistoryDeleteButton;
+}
diff --git a/frontend/src/components/ui/milestone/MilestoneDetailTable.tsx b/frontend/src/components/ui/milestone/MilestoneDetailTable.tsx
new file mode 100644
index 00000000..10d97b8a
--- /dev/null
+++ b/frontend/src/components/ui/milestone/MilestoneDetailTable.tsx
@@ -0,0 +1,34 @@
+import { MilestoneScoreDto } from '@/types/common.dto';
+
+interface MilestoneDetailTableProps {
+ milestoneScores: MilestoneScoreDto[];
+}
+
+export default function MilestoneDetailTable({ milestoneScores }: MilestoneDetailTableProps) {
+ return (
+
+
+ {milestoneScores.map((milestoneScore) => (
+
+
+
+ {milestoneScore.name}
+
+
+
+
+
+
+ {milestoneScore.score}/{milestoneScore.limitScore}
+
+
+ ))}
+
+
+ );
+}
diff --git a/frontend/src/components/MilestoneGroupLabel/index.tsx b/frontend/src/components/ui/milestone/MilestoneGroupLabel.tsx
similarity index 86%
rename from frontend/src/components/MilestoneGroupLabel/index.tsx
rename to frontend/src/components/ui/milestone/MilestoneGroupLabel.tsx
index bd7ecec1..a7f1f6d8 100644
--- a/frontend/src/components/MilestoneGroupLabel/index.tsx
+++ b/frontend/src/components/ui/milestone/MilestoneGroupLabel.tsx
@@ -1,12 +1,13 @@
import { MilestoneGroup } from '@/data/milestone';
import { convertMilestoneGroup } from '@/lib/utils/utils';
-interface MilestoneGroupLabelProps {
+export interface MilestoneGroupLabelProps {
group: string;
}
-const MilestoneGroupLabel = ({ group }: MilestoneGroupLabelProps) => {
+export default function MilestoneGroupLabel({ group }: MilestoneGroupLabelProps) {
const labelText = convertMilestoneGroup(group);
+
switch (group) {
case MilestoneGroup.ACTIVITY:
return (
@@ -29,6 +30,4 @@ const MilestoneGroupLabel = ({ group }: MilestoneGroupLabelProps) => {
default:
return {labelText} ;
}
-};
-
-export default MilestoneGroupLabel;
+}
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/register/components/MilestoneHistoryTable/index.tsx b/frontend/src/components/ui/milestone/MilestoneHistoryTable.tsx
similarity index 53%
rename from frontend/src/app/(client)/(withSidebar)/my-page/milestone/register/components/MilestoneHistoryTable/index.tsx
rename to frontend/src/components/ui/milestone/MilestoneHistoryTable.tsx
index 5273acbe..dea789bf 100644
--- a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/register/components/MilestoneHistoryTable/index.tsx
+++ b/frontend/src/components/ui/milestone/MilestoneHistoryTable.tsx
@@ -1,20 +1,18 @@
-/* eslint-disable jsx-a11y/control-has-associated-label */
-/* eslint-disable max-len */
+import { headers } from 'next/headers';
-import MilestoneHistoryStatusLabel from '@/app/(client)/(withSidebar)/my-page/components/MilestoneHistoryStatusLabel';
import { getMilestoneHistoriesOfStudent } from '@/lib/api/server.api';
import { getAuthFromCookie } from '@/lib/utils/auth';
import { MilestoneHistorySortCriteria, SortDirection } from '@/types/milestone';
-import MilestoneHistoryDeleteButton from '../MilestoneHistoryDeleteButton';
-import Pagination from '@/app/(client)/components/Pagination';
-import { headers } from 'next/headers';
+import Pagination from '@/components/common/Pagination';
+import MilestoneStatusLabel from '@/components/ui/milestone/MilestoneStatusLabel';
+import MilestoneDeleteButton from '@/components/ui/milestone/MilestoneDeleteButton';
-interface MilestoneHistoryTableProp {
+export interface MilestoneHistoryTableProps {
pageNumber: number;
}
-const MilestoneHistoryTable = async ({ pageNumber }: MilestoneHistoryTableProp) => {
+export default async function MilestoneHistoryTable({ pageNumber }: MilestoneHistoryTableProps) {
const headersList = headers();
const pathname = headersList.get('x-pathname') || '';
@@ -37,51 +35,45 @@ const MilestoneHistoryTable = async ({ pageNumber }: MilestoneHistoryTableProp)
return (
-
+
No
- 제목
+ 제목
점수
- 활동일
- 등록일
- 진행 상황
- 처리
- 실적 내역
+ 활동일
+ 등록일
+ 진행 상황
+ 처리
+ 실적 내역
{milestoneHistories?.content.map((milestoneHistory, index) => (
-
+
{index + 1}
- {milestoneHistory.description}
+ {milestoneHistory.description}
{milestoneHistory.milestone.score * milestoneHistory.count}
- {milestoneHistory.activatedAt.replaceAll('-', '.')}
-
+ {milestoneHistory.activatedAt.replaceAll('-', '.')}
+
{milestoneHistory.createdAt.slice(0, 10).replaceAll('-', '.')}
-
-
+
+
-
-
+
+
-
+
-
+
{milestoneHistory.description}
-
+
활동: {milestoneHistory.activatedAt.replaceAll('-', '.')}
등록: {milestoneHistory.createdAt.slice(0, 10).replaceAll('-', '.')}
-
+
))}
@@ -95,6 +87,4 @@ const MilestoneHistoryTable = async ({ pageNumber }: MilestoneHistoryTableProp)
/>
);
-};
-
-export default MilestoneHistoryTable;
+}
diff --git a/frontend/src/components/ui/milestone/MilestoneOverviewTable.tsx b/frontend/src/components/ui/milestone/MilestoneOverviewTable.tsx
new file mode 100644
index 00000000..dfc3e072
--- /dev/null
+++ b/frontend/src/components/ui/milestone/MilestoneOverviewTable.tsx
@@ -0,0 +1,43 @@
+import { MilestoneOverviewScore } from '@/types/milestone';
+
+export interface MilestoneOverviewTableProps {
+ milestoneOverviewScore: MilestoneOverviewScore;
+}
+
+export default function MilestoneOverviewTable({ milestoneOverviewScore }: MilestoneOverviewTableProps) {
+ const { activityScore, globalScore, communityScore, totalScore } = milestoneOverviewScore;
+
+ const scores = [
+ { score: activityScore, color: '#8FA3F8', title: '실전적 SW역량' },
+ { score: globalScore, color: '#9DE6BC', title: '글로벌 SW역량' },
+ { score: communityScore, color: '#AA8CF8', title: '커뮤니티 SW역량' },
+ ];
+
+ return (
+
+
+
+ 역량 구분
+ 획득
+
+
+
+ {scores.map((score) => (
+
+
+
+ {score.title}
+
+ {score.score}
+
+ ))}
+
+
+
+ 합계
+ {totalScore}
+
+
+
+ );
+}
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/components/MilestoneHistoryStatusLabel/index.tsx b/frontend/src/components/ui/milestone/MilestoneStatusLabel.tsx
similarity index 82%
rename from frontend/src/app/(client)/(withSidebar)/my-page/components/MilestoneHistoryStatusLabel/index.tsx
rename to frontend/src/components/ui/milestone/MilestoneStatusLabel.tsx
index 764ec6e3..a2004003 100644
--- a/frontend/src/app/(client)/(withSidebar)/my-page/components/MilestoneHistoryStatusLabel/index.tsx
+++ b/frontend/src/components/ui/milestone/MilestoneStatusLabel.tsx
@@ -1,14 +1,13 @@
-/* eslint-disable max-len */
import { VscInfo } from '@react-icons/all-files/vsc/VscInfo';
import { MilestoneHistoryStatus } from '@/data/milestone';
-interface MilestoneHistoryStatusLabelProps {
+export interface MilestoneStatusLabelProps {
status: string;
rejectReason: string | null;
}
-const MilestoneHistoryStatusLabel = ({ status, rejectReason }: MilestoneHistoryStatusLabelProps) => {
+export default function MilestoneStatusLabel({ status, rejectReason }: MilestoneStatusLabelProps) {
switch (status) {
case MilestoneHistoryStatus.APPROVED:
return 승인 ;
@@ -27,6 +26,4 @@ const MilestoneHistoryStatusLabel = ({ status, rejectReason }: MilestoneHistoryS
default:
return '잘못된 상태';
}
-};
-
-export default MilestoneHistoryStatusLabel;
+}
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/components/MilestoneSection/index.tsx b/frontend/src/components/ui/my-page/MyPageMilestone.tsx
similarity index 75%
rename from frontend/src/app/(client)/(withSidebar)/my-page/components/MilestoneSection/index.tsx
rename to frontend/src/components/ui/my-page/MyPageMilestone.tsx
index 5af631a8..4d8eb1b5 100644
--- a/frontend/src/app/(client)/(withSidebar)/my-page/components/MilestoneSection/index.tsx
+++ b/frontend/src/components/ui/my-page/MyPageMilestone.tsx
@@ -1,16 +1,11 @@
-/* eslint-disable implicit-arrow-linebreak */
-/* eslint-disable max-len */
-/* eslint-disable operator-linebreak */
-/* eslint-disable react/jsx-wrap-multilines */
-
'use client';
import { DateTime } from 'luxon';
import { useMemo, useState } from 'react';
-import MilestoneChart from '@/components/MilestoneChart';
-import MilestoneTable from '@/components/MilestoneTable';
-import SubTitle from '@/components/SubTitle';
+import MilestoneCircleChart from '@/components/ui/milestone/MilestoneCircleChart';
+import MilestoneOverviewTable from '@/components/ui/milestone/MilestoneOverviewTable';
+import PageSubTitle from '@/components/common/PageSubTitle';
import { MilestoneInfoType, initialMilestoneOverview, milestoneInfoTypes } from '@/data/milestone';
import { useAppSelector } from '@/lib/hooks/redux';
import { useMilestoneScoresOfStudentQuery } from '@/lib/hooks/useApi';
@@ -18,10 +13,10 @@ import { compareByIdAsc } from '@/lib/utils/utils';
import { Period } from '@/types/common';
import { MilestoneOverviewScore } from '@/types/milestone';
-import MilestoneHistoryTable from '../../milestone/components/MilestoneHistoryTable';
-import MilestoneRowBarTable from '../MilestoneRowBarTable';
+import MilestoneDetailTable from '@/components/ui/milestone/MilestoneDetailTable';
+import MilestoneAcceptedTable from '@/components/ui/milestone/MilestoneAcceptedTable';
-const MilestoneSection = () => {
+export default function MyPageMilestone() {
const auth = useAppSelector((state) => state.auth).value;
const searchFilterPeriod: Period = {
startDate: DateTime.now().minus({ years: 1 }).toFormat('yyyy-MM-dd'),
@@ -49,7 +44,7 @@ const MilestoneSection = () => {
return (
-
+
{searchFilterPeriod.startDate} ~
{searchFilterPeriod.endDate}
@@ -69,14 +64,14 @@ const MilestoneSection = () => {
{selectedInfoType === MilestoneInfoType.TOTAL && (
-
-
+
+
)}
{(selectedInfoType === MilestoneInfoType.ACTIVITY ||
selectedInfoType === MilestoneInfoType.GLOBAL ||
selectedInfoType === MilestoneInfoType.COMMUNITY) && (
-
milestoneScore.group === selectedInfoType)
@@ -85,10 +80,9 @@ const MilestoneSection = () => {
/>
)}
{selectedInfoType === MilestoneInfoType.HISTORY && (
-
+
)}
);
-};
-export default MilestoneSection;
+}
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneDetail/index.tsx b/frontend/src/components/ui/my-page/MyPageMilestoneDetail.tsx
similarity index 58%
rename from frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneDetail/index.tsx
rename to frontend/src/components/ui/my-page/MyPageMilestoneDetail.tsx
index 4699d258..9503456a 100644
--- a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneDetail/index.tsx
+++ b/frontend/src/components/ui/my-page/MyPageMilestoneDetail.tsx
@@ -8,34 +8,31 @@ import { useMilestoneScoresOfStudentQuery } from '@/lib/hooks/useApi';
import { compareByIdAsc } from '@/lib/utils/utils';
import { Period } from '@/types/common';
-import { GroupButton } from './styled';
-import MilestoneRowBarTable from '../../../components/MilestoneRowBarTable';
+import MilestoneDetailTable from '@/components/ui/milestone/MilestoneDetailTable';
-const MilestoneDetail = ({ startDate, endDate }: Period) => {
+export default function MyPageMilestoneDetail({ startDate, endDate }: Period) {
const auth = useAppSelector((state) => state.auth).value;
const [selectedGroup, setSelectedGroup] = useState
(MilestoneGroup.ACTIVITY);
const { data: milestoneScores } = useMilestoneScoresOfStudentQuery(auth.id, startDate, endDate);
return (
-
+
{milestoneGroups.map((group) => (
- setSelectedGroup(group.id)}
>
{group.text}
-
+
))}
-
milestoneScore.group === selectedGroup)
- .sort(compareByIdAsc)}
+ milestoneScore.group === selectedGroup).sort(compareByIdAsc) || []
+ }
/>
);
-};
-
-export default MilestoneDetail;
+}
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/components/MilestoneHistorySection/index.tsx b/frontend/src/components/ui/my-page/MyPageMilestoneHistory.tsx
similarity index 65%
rename from frontend/src/app/(client)/(withSidebar)/my-page/components/MilestoneHistorySection/index.tsx
rename to frontend/src/components/ui/my-page/MyPageMilestoneHistory.tsx
index b2931673..395af0d5 100644
--- a/frontend/src/app/(client)/(withSidebar)/my-page/components/MilestoneHistorySection/index.tsx
+++ b/frontend/src/components/ui/my-page/MyPageMilestoneHistory.tsx
@@ -1,16 +1,11 @@
-/* eslint-disable implicit-arrow-linebreak */
-/* eslint-disable max-len */
-/* eslint-disable operator-linebreak */
-/* eslint-disable react/jsx-wrap-multilines */
-
-import SubTitle from '@/components/SubTitle';
+import PageSubTitle from '@/components/common/PageSubTitle';
import { getMilestoneHistoriesOfStudent } from '@/lib/api/server.api';
import { getAuthFromCookie } from '@/lib/utils/auth';
import { MilestoneHistorySortCriteria, SortDirection } from '@/types/milestone';
-import MilestoneHistoryStatusLabel from '../MilestoneHistoryStatusLabel';
+import MilestoneStatusLabel from '@/components/ui/milestone/MilestoneStatusLabel';
-const MilestoneHistorySection = async () => {
+export default async function MyPageMilestoneHistory() {
const auth = getAuthFromCookie();
let milestoneHistoriesOfStudent;
@@ -24,7 +19,7 @@ const MilestoneHistorySection = async () => {
MilestoneHistorySortCriteria.ACTIVATED_AT,
SortDirection.DESC,
0,
- 5,
+ 6,
);
} catch (err) {
// TODO: server api error handling...
@@ -32,18 +27,15 @@ const MilestoneHistorySection = async () => {
return (
-
+
{milestoneHistoriesOfStudent ? (
milestoneHistoriesOfStudent.content.map((milestoneHistory) => (
-
{milestoneHistory.description}
+
{milestoneHistory.description}
활동일: {milestoneHistory.activatedAt}
-
+
))
@@ -53,5 +45,4 @@ const MilestoneHistorySection = async () => {
);
-};
-export default MilestoneHistorySection;
+}
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneOverview/index.tsx b/frontend/src/components/ui/my-page/MyPageMilestoneOverview.tsx
similarity index 60%
rename from frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneOverview/index.tsx
rename to frontend/src/components/ui/my-page/MyPageMilestoneOverview.tsx
index 992366a1..063ebf9d 100644
--- a/frontend/src/app/(client)/(withSidebar)/my-page/milestone/components/MilestoneOverview/index.tsx
+++ b/frontend/src/components/ui/my-page/MyPageMilestoneOverview.tsx
@@ -1,22 +1,20 @@
-/* eslint-disable implicit-arrow-linebreak */
import { useMemo } from 'react';
-import MilestoneChart from '@/components/MilestoneChart';
-import MilestoneTable from '@/components/MilestoneTable';
+import MilestoneCircleChart from '@/components/ui/milestone/MilestoneCircleChart';
+import MilestoneOverviewTable from '@/components/ui/milestone/MilestoneOverviewTable';
import { initialMilestoneOverview } from '@/data/milestone';
import { useAppSelector } from '@/lib/hooks/redux';
import { useMilestoneScoresOfStudentQuery } from '@/lib/hooks/useApi';
import { Period } from '@/types/common';
import { MilestoneOverviewScore } from '@/types/milestone';
-import { MilestoneWrapper } from './styled';
-import MilestoneDetail from '../MilestoneDetail';
+import MyPageMilestoneDetail from './MyPageMilestoneDetail';
-interface MilestoneOverviewProps {
+export interface MyPageMilestoneOverviewProps {
searchFilterPeriod: Period;
}
-const MilestoneOverview = ({ searchFilterPeriod }: MilestoneOverviewProps) => {
+export default function MyPageMilestoneOverview({ searchFilterPeriod }: MyPageMilestoneOverviewProps) {
const auth = useAppSelector((state) => state.auth).value;
const { data: milestoneScoresOfStudent } = useMilestoneScoresOfStudentQuery(
auth.id,
@@ -38,13 +36,11 @@ const MilestoneOverview = ({ searchFilterPeriod }: MilestoneOverviewProps) => {
);
return (
);
-};
-
-export default MilestoneOverview;
+}
diff --git a/frontend/src/app/(client)/(withSidebar)/my-page/components/StudentInfoSection/index.tsx b/frontend/src/components/ui/my-page/MyPageStudentInfo.tsx
similarity index 76%
rename from frontend/src/app/(client)/(withSidebar)/my-page/components/StudentInfoSection/index.tsx
rename to frontend/src/components/ui/my-page/MyPageStudentInfo.tsx
index 5ba8760d..4d79dfee 100644
--- a/frontend/src/app/(client)/(withSidebar)/my-page/components/StudentInfoSection/index.tsx
+++ b/frontend/src/components/ui/my-page/MyPageStudentInfo.tsx
@@ -1,27 +1,20 @@
-/* eslint-disable react/jsx-wrap-multilines */
-
'use client';
-import SubTitle from '@/components/SubTitle';
+import { ReactNode } from 'react';
+
+import PageSubTitle from '@/components/common/PageSubTitle';
import { useAppSelector } from '@/lib/hooks/redux';
import { useStudentMemberQuery } from '@/lib/hooks/useApi';
import { appendDashPhoneNumber, convertCareerToStr } from '@/lib/utils/utils';
import { VscWarning } from '@react-icons/all-files/vsc/VscWarning';
-import StudentInfoLabel from './StudentInfoLabel';
-
-const StudentInfoSection = () => {
- // TODO - 관리자가 로그인한 경우에 대한 처린
+export default function MyPageStudentInfo() {
const auth = useAppSelector((state) => state.auth).value;
- let member;
- try {
- member = useStudentMemberQuery(auth.id).data;
- } catch (err) {
- // TODO: server api error handling
- }
+ const member = useStudentMemberQuery(auth.id).data;
+
return (
-
+
{member ? (
@@ -59,5 +52,18 @@ const StudentInfoSection = () => {
)}
);
-};
-export default StudentInfoSection;
+}
+
+export interface StudentInfoLabelProps {
+ label: string;
+ value: ReactNode | string;
+}
+
+export function StudentInfoLabel({ label, value }: StudentInfoLabelProps) {
+ return (
+
+ {label}
+ {value}
+
+ );
+}
diff --git a/frontend/src/components/ui/team-building/TeamBuildingCard.tsx b/frontend/src/components/ui/team-building/TeamBuildingCard.tsx
new file mode 100644
index 00000000..3acd8870
--- /dev/null
+++ b/frontend/src/components/ui/team-building/TeamBuildingCard.tsx
@@ -0,0 +1,75 @@
+import { CgEye } from '@react-icons/all-files/cg/CgEye';
+import Image from 'next/image';
+
+import { TeamBuildingDto } from '@/types/common.dto';
+
+import Link from 'next/link';
+
+export const TEAM_STATUS = {
+ RECRUITING: {
+ color: '#FAD3CA',
+ text: '모집 중',
+ },
+ RECRUITMENT_END: {
+ color: '#DEE3EB',
+ text: '모집마감',
+ },
+};
+
+export default function TeamBuildingCard({
+ id,
+ category,
+ status,
+ title,
+ developer,
+ designer,
+ artist,
+ other,
+ views,
+}: TeamBuildingDto) {
+ const recruitment = [
+ { img: '/images/teamBuilding/team_type_img_1.svg', text: '개발', count: developer },
+ { img: '/images/teamBuilding/team_type_img_2.svg', text: '디자인', count: artist },
+ { img: '/images/teamBuilding/team_type_img_3.svg', text: '기획', count: designer },
+ { img: '/images/teamBuilding/team_type_img_4.svg', text: '기타', count: other },
+ ];
+ return (
+
+
+
{category}
+
+ {TEAM_STATUS[status].text}
+
+
+
+
+ {title}
+
+
+ {recruitment.map((item) => {
+ if (item.count !== 0) {
+ return (
+
+
+
+ {item.text}
+
+ {item.count}명
+
+
+ );
+ }
+ return null;
+ })}
+
+
+
+ {views}
+
+
+
+ );
+}
diff --git a/frontend/src/constants.ts b/frontend/src/constants.ts
index 512aae4e..0fa95e66 100644
--- a/frontend/src/constants.ts
+++ b/frontend/src/constants.ts
@@ -1,91 +1,9 @@
-export const MAX_WIDTH = '1200px';
-
-export const CONTENT_WIDTH = '970px';
-
-export const SIGN_WIDTH = '500px';
-
export const RESPONSIVE_WIDTH = {
mobile: '480px',
tablet: '768px',
desktop: '1200px',
};
-export const COLOR = {
- white: '#FFFFFF',
- black_text: '#333333',
- comment: '#898C96',
- border: '#EEEEF0',
- background: {
- light: '#F0F1F7',
- base: '#D2D4DC',
- },
- primary: {
- light: '#E6EBFD',
- main: '#5773F1',
- dark: '#1A40EB',
- },
- secondary: {
- light: '#64709B',
- main: '#26325C',
- dark: '#050A1C',
- },
- milestone: {
- blue: {
- light: '#CCD7FF',
- dark: '#5379FF',
- main: '#8FA3F8',
- },
- green: {
- light: '#CEFFD9',
- dark: '#11BA69',
- main: '#9DE6BC',
- },
- purple: {
- light: '#D7C5FF',
- dark: '#7b61ff',
- main: '#AA8CF8',
- },
- gray: {
- light: '#F2F2F2',
- },
- },
-};
-
-export const FONT_STYLE = {
- xs: {
- normal: '400 12px "Noto Sans KR", sans-serif',
- semibold: '600 12px "Noto Sans KR", sans-serif',
- bold: '700 12px "Noto Sans KR", sans-serif',
- },
- sm: {
- normal: '400 14px "Noto Sans KR", sans-serif',
- semibold: '600 14px "Noto Sans KR", sans-serif',
- bold: '700 14px "Noto Sans KR", sans-serif',
- },
- base: {
- normal: '400 16px "Noto Sans KR", sans-serif',
- semibold: '600 16px "Noto Sans KR", sans-serif',
- bold: '700 16px "Noto Sans KR", sans-serif',
- },
- lg: {
- normal: '400 20px "Noto Sans KR", sans-serif',
- semibold: '600 20px "Noto Sans KR", sans-serif',
- bold: '700 20px "Noto Sans KR", sans-serif',
- },
- xl: {
- normal: '400 32px "Noto Sans KR", sans-serif',
- semibold: '600 32px "Noto Sans KR", sans-serif',
- bold: '700 32px "Noto Sans KR", sans-serif',
- },
-};
-
-export const BORDER_RADIUS = {
- sm: '10px',
- md: '20px',
- lg: '30px',
- full: '100%',
-};
-
export const TEAM_STATUS = {
RECRUITING: {
color: '#FAD3CA',
diff --git a/frontend/src/data/adminCategory.ts b/frontend/src/data/adminCategory.ts
index 001e53bf..20f128cd 100644
--- a/frontend/src/data/adminCategory.ts
+++ b/frontend/src/data/adminCategory.ts
@@ -1,4 +1,3 @@
-/* eslint-disable import/prefer-default-export */
import { CategoryDto } from '@/types/common.dto';
export const adminCategories: CategoryDto[] = [
@@ -6,7 +5,7 @@ export const adminCategories: CategoryDto[] = [
title: '마일스톤 관리',
url: '/admin/milestone',
sub: [
- { title: '마일스톤 목록', url: '/admin/milestone/list', key: 'milestone-list' },
+ { title: '마일스톤 목록', url: '/admin/milestone', key: 'milestone-list' },
{ title: '마일스톤 일괄 등록', url: '/admin/milestone/register', key: 'milestone-register' },
{ title: '마일스톤 점수 현황', url: '/admin/milestone/rank', key: 'milestone-rank' },
],
@@ -15,14 +14,14 @@ export const adminCategories: CategoryDto[] = [
title: '교직원 관리',
url: '/admin/faculty',
sub: [
- { title: '교직원 목록', url: '/admin/faculty/list', key: 'faculty-list' },
+ { title: '교직원 목록', url: '/admin/faculty', key: 'faculty-list' },
{ title: '교직원 등록', url: '/admin/faculty/register', key: 'faculty-register' },
],
},
{
title: '학생 관리',
- url: '/admin/member',
- sub: [{ title: '학생 목록', url: '/admin/member/list', key: 'member-list' }],
+ url: '/admin/student',
+ sub: [{ title: '학생 목록', url: '/admin/student', key: 'student-list' }],
},
{
title: '팀빌딩 관리',
@@ -33,7 +32,7 @@ export const adminCategories: CategoryDto[] = [
title: '대회 관리',
url: '/admin/contest',
sub: [
- { title: '대회 목록', url: '/admin/contest/list', key: 'contest-list' },
+ { title: '대회 목록', url: '/admin/contest', key: 'contest-list' },
{ title: '대회 생성', url: '/admin/contest/create', key: 'contest-create' },
],
},
diff --git a/frontend/src/data/clientCategory.ts b/frontend/src/data/clientCategory.ts
index 5482b8c9..8bfebb47 100644
--- a/frontend/src/data/clientCategory.ts
+++ b/frontend/src/data/clientCategory.ts
@@ -6,14 +6,14 @@ export const headerInfos: CategoryDto[] = [
url: '/milestone',
description: '마일스톤이란?',
inHeader: true,
- sub: [{ title: '마일스톤이란?', url: '/milestone', key: '1_milestone' }],
+ sub: [{ title: '마일스톤이란?', url: '/milestone', key: 'milestone' }],
},
{
title: '팀빌딩',
url: '/team-building',
description: '팀원을 모집하는 공간입니다.',
inHeader: true,
- sub: [{ title: '팀빌딩', url: '/', key: '2_teamBuilding' }],
+ sub: [{ title: '팀빌딩', url: '/team-building', key: 'teamBuilding' }],
},
{
title: 'PNU 해커톤',
@@ -32,8 +32,9 @@ export const headerInfos: CategoryDto[] = [
inHeader: false,
sub: [
{ title: '전체보기', url: '/my-page', key: 'dashboard' },
+ { title: '마일스톤 등록', url: '/my-page/milestone-register', key: 'register' },
{ title: '마일스톤 획득 내역', url: '/my-page/milestone', key: 'milestone' },
- { title: '실적 등록', url: '/my-page/milestone/register', key: 'result' },
+ { title: '마일스톤 등록 내역', url: '/my-page/milestone-list', key: 'result' },
],
},
];
diff --git a/frontend/src/lib/hooks/useAdminApi.ts b/frontend/src/lib/hooks/useAdminApi.ts
index a3e4068c..e800ca95 100644
--- a/frontend/src/lib/hooks/useAdminApi.ts
+++ b/frontend/src/lib/hooks/useAdminApi.ts
@@ -1,4 +1,3 @@
-/* eslint-disable implicit-arrow-linebreak */
import { QueryKeys } from '@/data/queryKey';
import { client } from '@/lib/api/client.axios';
import { useAxiosMutation, useAxiosQuery } from '@/lib/hooks/useAxios';
diff --git a/frontend/src/lib/hooks/useApi.ts b/frontend/src/lib/hooks/useApi.ts
index a70931ec..b74c07aa 100644
--- a/frontend/src/lib/hooks/useApi.ts
+++ b/frontend/src/lib/hooks/useApi.ts
@@ -1,6 +1,6 @@
-/* eslint-disable implicit-arrow-linebreak */
-import { FirstInfo } from '@/app/(client)/(auth)/sign-up/components/SignUpFirstPage';
-import { SecondInfo } from '@/app/(client)/(auth)/sign-up/components/SignUpSecondPage';
+import { FirstInfo } from '@/components/ui/auth/AuthSignUpFirst';
+import { SecondInfo } from '@/components/ui/auth/AuthSignUpSecond';
+
import { MilestoneHistoryStatus } from '@/data/milestone';
import { QueryKeys } from '@/data/queryKey';
import { client } from '@/lib/api/client.axios';
diff --git a/frontend/src/lib/hooks/useAxios.ts b/frontend/src/lib/hooks/useAxios.ts
index e84a066d..9eb74785 100644
--- a/frontend/src/lib/hooks/useAxios.ts
+++ b/frontend/src/lib/hooks/useAxios.ts
@@ -4,8 +4,6 @@ import { redirect, RedirectType, usePathname } from 'next/navigation';
import { useEffect } from 'react';
import { toast } from 'react-toastify';
-import 'react-toastify/dist/ReactToastify.css';
-
import { AccessDeniedError, BusinessError, UnauthorizedError } from '@/types/error';
const handleError = (error: Error, pathname: string) => {
diff --git a/frontend/src/lib/utils/utils.tsx b/frontend/src/lib/utils/utils.tsx
index 760c2efa..32c98b9a 100644
--- a/frontend/src/lib/utils/utils.tsx
+++ b/frontend/src/lib/utils/utils.tsx
@@ -1,6 +1,3 @@
-/* eslint-disable max-len */
-/* eslint-disable implicit-arrow-linebreak */
-
import { HistoryFileType, MilestoneGroup, MilestoneHistoryStatus } from '@/data/milestone';
// 빈 파라미터를 제거하는 유틸함수
diff --git a/frontend/src/middleware.ts b/frontend/src/middleware.ts
index 176e03cc..7736a44e 100644
--- a/frontend/src/middleware.ts
+++ b/frontend/src/middleware.ts
@@ -15,7 +15,7 @@ export const middleware = (request: NextRequest) => {
return Response.redirect(new URL('/', request.url));
}
if (request.nextUrl.pathname === '/admin') {
- return Response.redirect(new URL('/admin/milestone/list', request.url));
+ return Response.redirect(new URL('/admin/milestone', request.url));
}
const requestHeaders = new Headers(request.headers);
diff --git a/frontend/src/store/auth.slice.ts b/frontend/src/store/auth.slice.ts
index 235d4f6a..0f0fdbec 100644
--- a/frontend/src/store/auth.slice.ts
+++ b/frontend/src/store/auth.slice.ts
@@ -1,4 +1,3 @@
-/* eslint-disable import/no-extraneous-dependencies */
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import cookie from 'react-cookies';
diff --git a/frontend/src/store/index.ts b/frontend/src/store/index.ts
index 034fe9c2..8e52c2be 100644
--- a/frontend/src/store/index.ts
+++ b/frontend/src/store/index.ts
@@ -1,4 +1,3 @@
-/* eslint-disable implicit-arrow-linebreak */
import { combineReducers, configureStore } from '@reduxjs/toolkit';
import { persistReducer, persistStore } from 'redux-persist';
diff --git a/frontend/src/store/store.tsx b/frontend/src/store/store.tsx
index 0d18f582..56f02fd1 100644
--- a/frontend/src/store/store.tsx
+++ b/frontend/src/store/store.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable @typescript-eslint/no-unused-vars */
-/* eslint-disable @typescript-eslint/no-explicit-any */
import createWebStorage from 'redux-persist/lib/storage/createWebStorage';
const createNoopStorage = () => ({
diff --git a/frontend/src/theme/StyledComponentsRegistry/index.tsx b/frontend/src/theme/StyledComponentsRegistry/index.tsx
index 889ea616..5d1cfd4f 100644
--- a/frontend/src/theme/StyledComponentsRegistry/index.tsx
+++ b/frontend/src/theme/StyledComponentsRegistry/index.tsx
@@ -1,6 +1,3 @@
-/* eslint-disable react/jsx-no-useless-fragment */
-/* eslint-disable max-len */
-
'use client';
import { useServerInsertedHTML } from 'next/navigation';
diff --git a/frontend/src/types/error.ts b/frontend/src/types/error.ts
index 20798dae..66081681 100644
--- a/frontend/src/types/error.ts
+++ b/frontend/src/types/error.ts
@@ -1,5 +1,3 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable max-classes-per-file */
import { AxiosError } from 'axios';
export class ApplicationError extends Error {
diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js
index 8b7063aa..1e1af4ae 100644
--- a/frontend/tailwind.config.js
+++ b/frontend/tailwind.config.js
@@ -101,9 +101,28 @@ module.exports = {
},
width: {
sign: '500px',
+ 'client-max': '1200px',
+ 'client-content': '970px',
+ 'client-sidebar': '50px',
+ 'client-sidebar-open': '200px',
+ 'admin-max': '1200px',
+ 'admin-sidebar': '220px',
+ },
+ maxWidth: {
+ 'client-max': '1200px',
+ 'sign-max': '500px',
},
minWidth: {
admin: '1150px',
+ 'admin-max': '1200px',
+ },
+ height: {
+ 'client-header': '50px',
+ 'client-lg-header': '76px',
+ 'admin-header': '55px',
+ },
+ lineHeight: {
+ 'client-lg-header': '76px',
},
},
},