From 72f9d462d85609278e4880fcc3b4b1d806f337ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B7=9C=ED=9A=8C?= <48755156+KimKyuHoi@users.noreply.github.com> Date: Sun, 29 Dec 2024 05:08:25 +0900 Subject: [PATCH] Release v1.5.0 (#186) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 메인 화면 리드미 페이지 독스 기능 업데이트 (#164) * feat: GDSC => GDGoC 업데이트 * Docs: 메인 리드미 Docs 업데이트 * 로고 컨테스트 별 날짜 별로 로고 게시 (#169) * feat: code refactoring * Refac: MainNavigation refac * design: 로고 컨테스트 이미지 추가 * feat: navigation Logo 설정 * Design: Admin 로고 수정 * 뷰포인트 기반 lazy loading 로직 수정, GA 커스텀 이벤트 등록 및 채용공고 업데이트 (#171) * feat: 뷰포인트 기반 레이지로딩 구현 * Design: 세부 CSS 수정 * fix: 뷰포인트별 레이지로딩 구현 * Design: 날짜 원 수정 * Fix: 지원일자 조정 및 데이터 값 수정 * Design: CSS 수정 * Docs: 일정 등록 * Design: Apply Page CSS 수정 * Feat: GA Event 등록 * Fix: 페이지별 권한 설정 및 알람 설정 * feat: 커스텀 이벤트 추가 * Chore: 코드 주석처리 * Fix: 모듈화 수정 * Fix: build 수정 및 메타데이터 수정 * fix: 지원날짜 null로 올 경우 오늘 날짜로 들어가도록 처리 (#172) * observer-lazy-loading-package적용하기 (#175) * Chore: react-lazy-observer 패키지 설치 * feat: react-lazy-observer 패키지 대체 * 프론트엔드, 안드로이드 직렬 추가 (#181) * feat: 프엔, 안드 직렬 게시글 추가 * docs: 안드, 프엔 게시글 추가 * Feat/apply frontend (#183) * feat: 프엔, 안드 직렬 게시글 추가 * docs: 안드, 프엔 게시글 추가 * 어드민페이지 모달창 닫을 때 마크 정보 넘기기 구현 (#178) * fix: 모달창 닫을 때 리스트 업데이트되도록 수정 * style: 모달창 스타일 수정 * fix: 메모 줄바꿈 안됨 오류 수정 * fix: 메모 동시 수정 시 마지막만 반영되는 오류 수정 * style: 기수별 지원서 조회 퍼블리싱 * feat: 지원서 기수별 필터링 기능 추가 * fix: skeleton에 memo version 추가 * feat: 드롭다운리스트 기수 선택 시 사라지기 추가 * fix: 기수정보 초기화 데이터 수정 및 기수별 조회 버튼 이름 수정 --------- Co-authored-by: CHAE_WON_SHIN <96687276+chae-won-shin@users.noreply.github.com> --- src/apis/hooks/admin/docs/useGetApplyDocs.ts | 14 +++-- src/apis/hooks/admin/docs/useGetDocsDetail.ts | 2 + src/apis/hooks/admin/docs/usePatchDocsMemo.ts | 12 +++- src/pages/admin/AdminDocConfirmPage.style.ts | 5 ++ src/pages/admin/AdminDocConfirmPage.tsx | 33 +++++++++- .../components/docs/ApplyDetailModal.style.ts | 6 +- .../components/docs/ApplyDetailModal.tsx | 18 ++++-- .../docs/ApplyDetailModalSkeleton.tsx | 2 +- .../components/docs/ClassYearIdDropDown.tsx | 60 +++++++++++++++++++ src/pages/admin/components/docs/DocsTable.tsx | 9 ++- src/pages/admin/components/docs/Memo.tsx | 26 ++++++-- 11 files changed, 161 insertions(+), 26 deletions(-) create mode 100644 src/pages/admin/components/docs/ClassYearIdDropDown.tsx diff --git a/src/apis/hooks/admin/docs/useGetApplyDocs.ts b/src/apis/hooks/admin/docs/useGetApplyDocs.ts index 0bf09316..06ac948f 100644 --- a/src/apis/hooks/admin/docs/useGetApplyDocs.ts +++ b/src/apis/hooks/admin/docs/useGetApplyDocs.ts @@ -18,7 +18,8 @@ export const getApplyDocs = async ( track: string, isMarked: boolean, page: number, - size: number + size: number, + classYearId: number ): Promise => { const response = await fetchInstance.get( getApplyDocsPath(), @@ -28,6 +29,7 @@ export const getApplyDocs = async ( isMarked, page, size, + classYearId, }, } ); @@ -38,17 +40,19 @@ export const useGetApplyDocs = ( track: string, isMarked: boolean, page: number, - size: number + size: number, + classYearId: number ) => { const accessToken = sessionStorage.getItem('accessToken'); return useQuery({ - queryKey: [applyDocsQueryKey, track, isMarked, page, size], - queryFn: () => getApplyDocs(track, isMarked, page, size), + queryKey: [applyDocsQueryKey, track, isMarked, page, size, classYearId], + queryFn: () => getApplyDocs(track, isMarked, page, size, classYearId), enabled: !!accessToken && track !== undefined && isMarked !== undefined && - page !== undefined, + page !== undefined && + classYearId !== undefined, }); }; diff --git a/src/apis/hooks/admin/docs/useGetDocsDetail.ts b/src/apis/hooks/admin/docs/useGetDocsDetail.ts index 5bca0984..5ef72edb 100644 --- a/src/apis/hooks/admin/docs/useGetDocsDetail.ts +++ b/src/apis/hooks/admin/docs/useGetDocsDetail.ts @@ -9,6 +9,7 @@ export type AnswerData = { export interface DocsDetailInterface { id: number; + version: number; name: string; studentNumber: string; major: string; @@ -38,6 +39,7 @@ export const getDocsDetail = async ( }, } ); + return response.data; }; diff --git a/src/apis/hooks/admin/docs/usePatchDocsMemo.ts b/src/apis/hooks/admin/docs/usePatchDocsMemo.ts index b17e02aa..5525d449 100644 --- a/src/apis/hooks/admin/docs/usePatchDocsMemo.ts +++ b/src/apis/hooks/admin/docs/usePatchDocsMemo.ts @@ -4,15 +4,21 @@ import { fetchInstance } from '@gdg/apis/instance/Api_JWT'; const patchMemoPath = () => '/api/admin/application/note'; -const patchDocsMemo = async (id: number, memo: string): Promise => { - // console.log(memo); +const patchDocsMemo = async ( + id: number, + memo: { note: string; version: number } +): Promise => { await fetchInstance.patch(patchMemoPath(), memo, { params: { id } }); }; export const usePatchDocsMemo = () => { const accessToken = sessionStorage.getItem('accessToken'); - const mutation = useMutation({ + const mutation = useMutation< + void, + Error, + { id: number; memo: { note: string; version: number } } + >({ mutationFn: ({ id, memo }) => { if (!accessToken) { return Promise.reject(new Error('액세스 토큰이 없습니다.')); diff --git a/src/pages/admin/AdminDocConfirmPage.style.ts b/src/pages/admin/AdminDocConfirmPage.style.ts index 42bf97ad..5a6900d5 100644 --- a/src/pages/admin/AdminDocConfirmPage.style.ts +++ b/src/pages/admin/AdminDocConfirmPage.style.ts @@ -16,6 +16,11 @@ export const PassBtn = styled.button<{ isSelected: boolean }>` transition: background-color 0.3s ease; `; +export const ButtonContainer = styled.div` + width: auto; + height: 40px; +`; + export const ButtonBox = styled.div` display: flex; flex-direction: row; diff --git a/src/pages/admin/AdminDocConfirmPage.tsx b/src/pages/admin/AdminDocConfirmPage.tsx index 83b83469..64c91bef 100644 --- a/src/pages/admin/AdminDocConfirmPage.tsx +++ b/src/pages/admin/AdminDocConfirmPage.tsx @@ -4,8 +4,13 @@ import { useGetStatistic } from '@gdg/apis/hooks/admin/docs/useGetStatistic'; import { useGetTrack } from '@gdg/apis/hooks/admin/docs/useGetTrack'; import { DisplayLayout } from '@gdg/styles/LayoutStyle'; -import { PassBtn, ButtonBox, InfoBox } from './AdminDocConfirmPage.style'; - +import ClassYearIdDropDown from './components/docs/ClassYearIdDropDown'; +import { + PassBtn, + ButtonContainer, + ButtonBox, + InfoBox, +} from './AdminDocConfirmPage.style'; const TrackSelectBar = lazy(() => import('./components/docs/TrackSelectBar')); const DocsTable = lazy( @@ -21,11 +26,22 @@ const AdminDocConfirmPage = () => { const [isMarked, setIsMarked] = useState(false); const [searchName, setSearchName] = useState(''); const [trackIdx, setTrackIdx] = useState(0); + const [isDropdownOpen, setIsDropdownOpen] = useState(false); + const [classYearId, setClassYearId] = useState(4); const handlePassCheck = () => { setIsMarked((prev) => !prev); }; + const handleClassYearIdCheck = () => { + setIsDropdownOpen((prev) => !prev); + }; + + const handleYearIdClick = (id: number) => { + setClassYearId(id); + setIsDropdownOpen(false); + }; + const { data: applyData } = useGetStatistic(); const { data: trackData } = useGetTrack(); @@ -45,6 +61,17 @@ const AdminDocConfirmPage = () => { 서류합격자 조회 + + + {`${classYearId}기 ${'\u00A0'} ▾`} + + {isDropdownOpen && ( + + )} + @@ -52,10 +79,12 @@ const AdminDocConfirmPage = () => { {trackData && ( )} + ); diff --git a/src/pages/admin/components/docs/ApplyDetailModal.style.ts b/src/pages/admin/components/docs/ApplyDetailModal.style.ts index 5a5d7021..9903ad84 100644 --- a/src/pages/admin/components/docs/ApplyDetailModal.style.ts +++ b/src/pages/admin/components/docs/ApplyDetailModal.style.ts @@ -14,7 +14,7 @@ export const ModalBackdrop = styled.div` export const ModalWrapper = styled.div` width: 90%; height: 85vh; - min-width: 900px; + max-width: 1100px; min-height: 500px; ${displayCenter} @@ -120,10 +120,10 @@ export const SelfIntroduce = styled.div` overflow-y: scroll; color: black; - font-size: var(--font-size-xs); + font-size: var(--font-size-sm); font-weight: 200; - margin-top: 5px; + margin-top: 10px; `; export const ButtonContainer = styled.div` diff --git a/src/pages/admin/components/docs/ApplyDetailModal.tsx b/src/pages/admin/components/docs/ApplyDetailModal.tsx index 4ba2bf08..48cc1dbe 100644 --- a/src/pages/admin/components/docs/ApplyDetailModal.tsx +++ b/src/pages/admin/components/docs/ApplyDetailModal.tsx @@ -55,6 +55,7 @@ interface Answer { interface DetailInfo { id: number; + version: number; name: string; studentNumber: string; major: string; @@ -142,6 +143,9 @@ const ApplyDetailModal = ({ }; const trackData = detail ? getQuestionsByTrack(detail.track) : null; + const emptyAnswer = '해당 질문에 대한 답변이 작성되지 않았습니다.'; + + console.log(detail); return ( @@ -177,7 +181,7 @@ const ApplyDetailModal = ({ {detail.answers.length > 0 ? `${detail.answers[0].answer}` - : `${trackData.Question1.main}란이 비어있습니다.`} + : emptyAnswer} @@ -187,7 +191,7 @@ const ApplyDetailModal = ({ {detail.answers.length > 1 ? `${detail.answers[1].answer}` - : `${trackData.Question2.main}란이 비어있습니다.`} + : emptyAnswer} @@ -197,7 +201,7 @@ const ApplyDetailModal = ({ {detail.answers.length > 2 ? `${detail.answers[2].answer}` - : `${trackData.Question3.main}란이 비어있습니다.`} + : emptyAnswer} @@ -207,7 +211,7 @@ const ApplyDetailModal = ({ {detail.answers.length > 3 ? `${detail.answers[3].answer}` - : `${trackData.Question4.main}란이 비어있습니다.`} + : emptyAnswer} @@ -234,7 +238,11 @@ const ApplyDetailModal = ({ - + { - + void; +}) => { + const yearIdList = [1, 2, 3, 4]; + + return ( + + {yearIdList.map((id) => ( +
+ onYearIdClick(id)} + >{`${id}기`} + {id < yearIdList.length && } +
+ ))} +
+ ); +}; + +export default ClassYearIdDropDown; diff --git a/src/pages/admin/components/docs/DocsTable.tsx b/src/pages/admin/components/docs/DocsTable.tsx index 0641524a..dbe82f37 100644 --- a/src/pages/admin/components/docs/DocsTable.tsx +++ b/src/pages/admin/components/docs/DocsTable.tsx @@ -46,21 +46,24 @@ const DocsTable = ({ searchName, trackIdx, isMarked, + classYearId, }: { searchName?: string | undefined; trackIdx: number; isMarked: boolean; + classYearId: number; }) => { const [currentPage, setCurrentPage] = useState(0); const [currentGroup, setCurrentGroup] = useState(0); const [docsList, setDocsList] = useState(null); const [openDetail, setOpenDetail] = useState(null); - const { data: docsData } = useGetApplyDocs( + const { data: docsData, refetch: refetchDocs } = useGetApplyDocs( getTrack(trackIdx), isMarked, currentPage, - 7 + 7, + classYearId ); const { data: searchData } = useGetSearch(searchName, currentPage, 7); @@ -70,7 +73,7 @@ const DocsTable = ({ const handleCloseModal = () => { setOpenDetail(null); - // window.location.reload(); + refetchDocs(); }; useEffect(() => { diff --git a/src/pages/admin/components/docs/Memo.tsx b/src/pages/admin/components/docs/Memo.tsx index 5572ca05..83a3ba15 100644 --- a/src/pages/admin/components/docs/Memo.tsx +++ b/src/pages/admin/components/docs/Memo.tsx @@ -38,12 +38,30 @@ const MemoBox = styled.textarea` outline: none; `; -const Memo = ({ id, note }: { id: number | null; note: string | null }) => { - const [memo, setMemo] = useState(note || null); +interface IMemo { + note: string; + version: number; +} + +const Memo = ({ + id, + version, + note, +}: { + id: number | null; + version: number; + note: string | null; +}) => { + const [memo, setMemo] = useState( + note !== null ? { note: note, version: version } : null + ); const { mutate } = usePatchDocsMemo(); const handleMemoBoxChange = (e: React.ChangeEvent) => { - setMemo(e.target.value); + setMemo({ + note: e.target.value, + version: version, + }); }; const handleSaveClick = () => { @@ -87,7 +105,7 @@ const Memo = ({ id, note }: { id: number | null; note: string | null }) => {