From a6898304826050680cb9cb5771e8d3159a6e72f3 Mon Sep 17 00:00:00 2001 From: mina-gwak Date: Mon, 14 Apr 2025 23:57:05 +0900 Subject: [PATCH 1/3] =?UTF-8?q?Feat:=20PD-254=20=EC=A7=80=EC=9B=90?= =?UTF-8?q?=EC=9E=90=20=EB=AA=A9=EB=A1=9D=20API=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/get-job-post-resume.ts | 20 ++- .../job-post-resume-relation/api/query.ts | 10 +- .../job-post-resume-relation/index.ts | 2 +- .../model/application.ts | 1 + .../api/use-job-post-relations.ts | 28 ++++ .../ui/applicant-management-list-page.tsx | 132 +++++++++++------- src/shared/api/pagination.ts | 2 + .../locales/en/applicant-management.json | 3 +- .../locales/ko/applicant-management.json | 3 +- src/shared/ui/pagination/index.tsx | 6 +- 10 files changed, 145 insertions(+), 62 deletions(-) create mode 100644 src/pages/applicant-management/api/use-job-post-relations.ts diff --git a/src/entities/job-post-resume-relation/api/get-job-post-resume.ts b/src/entities/job-post-resume-relation/api/get-job-post-resume.ts index d24d30ba..35dcc170 100644 --- a/src/entities/job-post-resume-relation/api/get-job-post-resume.ts +++ b/src/entities/job-post-resume-relation/api/get-job-post-resume.ts @@ -1,6 +1,6 @@ 'use server' -import { getTeacherSession } from 'entities/auth' +import { getBusinessSession, getTeacherSession } from 'entities/auth' import { apiClient, Pagination, PaginationParams } from 'shared/api' import { JobPostRelation } from '../model/application' @@ -12,7 +12,7 @@ export type GetJobPostResumeRequest = PaginationParams<{ type GetJobPostResumeResponse = Pagination -export const getJobPostResumeRelations = async ( +export const getTeacherJobPostResumeRelations = async ( queryParams: GetJobPostResumeRequest, ) => { const { accessToken } = await getTeacherSession() @@ -27,3 +27,19 @@ export const getJobPostResumeRelations = async ( return response } + +export const getBusinessJobPostResumeRelations = async ( + queryParams: GetJobPostResumeRequest, +) => { + const { accessToken } = await getBusinessSession() + + const response = await apiClient.get({ + endpoint: '/job-post-resume-relations', + queryParams, + option: { + authorization: `Bearer ${accessToken}`, + }, + }) + + return response +} diff --git a/src/entities/job-post-resume-relation/api/query.ts b/src/entities/job-post-resume-relation/api/query.ts index 6431fd8a..c3eac487 100644 --- a/src/entities/job-post-resume-relation/api/query.ts +++ b/src/entities/job-post-resume-relation/api/query.ts @@ -1,7 +1,8 @@ import { queryOptions } from '@tanstack/react-query' import { - getJobPostResumeRelations, + getBusinessJobPostResumeRelations, + getTeacherJobPostResumeRelations, GetJobPostResumeRequest, } from './get-job-post-resume' @@ -11,6 +12,11 @@ export const jobPostResumeRelationQueries = { list: (params: GetJobPostResumeRequest) => queryOptions({ queryKey: [...jobPostResumeRelationQueries.lists(), params], - queryFn: () => getJobPostResumeRelations(params), + queryFn: () => getTeacherJobPostResumeRelations(params), + }), + businessList: (params: GetJobPostResumeRequest) => + queryOptions({ + queryKey: [...jobPostResumeRelationQueries.lists(), params], + queryFn: () => getBusinessJobPostResumeRelations(params), }), } diff --git a/src/entities/job-post-resume-relation/index.ts b/src/entities/job-post-resume-relation/index.ts index c1606599..679843aa 100644 --- a/src/entities/job-post-resume-relation/index.ts +++ b/src/entities/job-post-resume-relation/index.ts @@ -1,7 +1,7 @@ export { getJobPostResumeSummary } from './api/get-job-post-resume-summary' export { getJobPostResumeByCode } from './api/get-job-post-resume-by-code' export { jobPostResumeRelationQueries } from './api/query' -export type { ApplicationStatus, StatusSummary } from './model/status' +export { ApplicationStatus, type StatusSummary } from './model/status' export type { JobPostRelationDetail } from './model/application' export { HistoryPanel } from './ui/history-panel' export { StatusPanel } from './ui/status-panel' diff --git a/src/entities/job-post-resume-relation/model/application.ts b/src/entities/job-post-resume-relation/model/application.ts index 7b9e427e..cddcee22 100644 --- a/src/entities/job-post-resume-relation/model/application.ts +++ b/src/entities/job-post-resume-relation/model/application.ts @@ -13,6 +13,7 @@ export type JobPostRelation = { jobPostTitle: string academyId: number academyName: string + academyMemo: string | null } export type JobPostRelationDetail = { diff --git a/src/pages/applicant-management/api/use-job-post-relations.ts b/src/pages/applicant-management/api/use-job-post-relations.ts new file mode 100644 index 00000000..49cbb63b --- /dev/null +++ b/src/pages/applicant-management/api/use-job-post-relations.ts @@ -0,0 +1,28 @@ +import { keepPreviousData, useQuery } from '@tanstack/react-query' + +import { + ApplicationStatus, + jobPostResumeRelationQueries, +} from 'entities/job-post-resume-relation' + +export const useJobPostRelations = ({ + status, + pageNumber, +}: { + status: ApplicationStatus + pageNumber: number +}) => { + const { data } = useQuery({ + ...jobPostResumeRelationQueries.businessList({ + pageNumber, + rowCount: 10, + status, + }), + placeholderData: keepPreviousData, + }) + + return { + applications: data?.content ?? [], + totalPages: data?.totalPages === 0 ? 1 : data?.totalPages, + } +} diff --git a/src/pages/applicant-management/ui/applicant-management-list-page.tsx b/src/pages/applicant-management/ui/applicant-management-list-page.tsx index 2efcf280..2e3ecbc7 100644 --- a/src/pages/applicant-management/ui/applicant-management-list-page.tsx +++ b/src/pages/applicant-management/ui/applicant-management-list-page.tsx @@ -3,81 +3,109 @@ import { useTranslations } from 'next-intl' import { useState } from 'react' +import { ApplicationStatus } from 'entities/job-post-resume-relation' +import { cn } from 'shared/lib' import { Layout, Tabs, Table, Pagination } from 'shared/ui' -const relations = [ - { - id: 1, - firstName: '길동', - lastName: '홍', - jobPostTitle: '웹 프론트엔드 개발자', - memo: '메모', - submittedDate: '2024-01-01', - }, - { - id: 2, - firstName: '길동', - lastName: '홍', - jobPostTitle: '웹 프론트엔드 개발자', - memo: '메모', - submittedDate: '2024-01-01', - }, -] +import { useJobPostRelations } from '../api/use-job-post-relations' export const ApplicantManagementListPage = () => { const t = useTranslations('applicant-management-list') + const [currentPage, setCurrentPage] = useState(0) + const [status, setStatus] = useState( + ApplicationStatus.SUBMITTED, + ) + + const { applications, totalPages } = useJobPostRelations({ + status, + pageNumber: currentPage, + }) const handlePageChange = ({ selected }: { selected: number }) => { setCurrentPage(selected) - // API 호출 등 페이지 변경 로직 } + const handleStatusChange = (value: string) => { + setStatus(value as ApplicationStatus) + } + + const hasNoApplications = applications.length === 0 + return (

{t('title')}

- - + + {t('tabs.submitted')} {t('tabs.reviewed')} {t('tabs.accepted')} {t('tabs.rejected')} + +
+ + + + + {t('table.applicant')} + + + {t('table.job-title')} + + + {t('table.memo')} + + + {t('table.application-date')} + + + + {(() => { + if (hasNoApplications) { + return null + } + + return ( + + {applications.map(application => ( + + + {application.resumeFirstName}{' '} + {application.resumeLastName} + + {application.jobPostTitle} + + {application?.academyMemo ?? ''} + + {application.submittedDate} + + ))} + + ) + })()} + + {hasNoApplications && ( +

+ {t('table.no-data')} +

+ )} +
+
-
- - - - - {t('table.applicant')} - - - {t('table.job-title')} - - {t('table.memo')} - - {t('table.application-date')} - - - - - {relations.map(relation => ( - - - {relation.firstName} {relation.lastName} - - {relation.jobPostTitle} - {relation.memo} - {relation.submittedDate} - - ))} - - -
diff --git a/src/shared/api/pagination.ts b/src/shared/api/pagination.ts index 726eea76..968dad5a 100644 --- a/src/shared/api/pagination.ts +++ b/src/shared/api/pagination.ts @@ -16,6 +16,8 @@ type Pageable = { } export type Pagination = { + totalPages: number + totalElements: number size: number content: Content[] number: number diff --git a/src/shared/config/internationalization/locales/en/applicant-management.json b/src/shared/config/internationalization/locales/en/applicant-management.json index df208e7e..f3fcd0a8 100644 --- a/src/shared/config/internationalization/locales/en/applicant-management.json +++ b/src/shared/config/internationalization/locales/en/applicant-management.json @@ -11,7 +11,8 @@ "applicant": "Applicant", "job-title": "Job Title", "memo": "Memo", - "application-date": "Application Date" + "application-date": "Application Date", + "no-data": "No applications have been received yet" } } } diff --git a/src/shared/config/internationalization/locales/ko/applicant-management.json b/src/shared/config/internationalization/locales/ko/applicant-management.json index 20caf3d6..88b72184 100644 --- a/src/shared/config/internationalization/locales/ko/applicant-management.json +++ b/src/shared/config/internationalization/locales/ko/applicant-management.json @@ -11,7 +11,8 @@ "applicant": "지원자", "job-title": "공고 제목", "memo": "메모", - "application-date": "지원 일자" + "application-date": "지원 일자", + "no-data": "아직 접수된 지원자가 없습니다" } } } diff --git a/src/shared/ui/pagination/index.tsx b/src/shared/ui/pagination/index.tsx index 09a440cd..adf214a7 100644 --- a/src/shared/ui/pagination/index.tsx +++ b/src/shared/ui/pagination/index.tsx @@ -8,14 +8,14 @@ import { cn } from 'shared/lib' import { Icon } from '../icon' interface PaginationProps { - pageCount: number + pageCount?: number currentPage: number onPageChange: (selectedItem: { selected: number }) => void className?: string } export const Pagination = ({ - pageCount, + pageCount = 1, currentPage, onPageChange, className, @@ -32,7 +32,7 @@ export const Pagination = ({ 'body-large flex h-8 w-8 items-center justify-center rounded-md font-bold text-gray-900 transition-colors', 'hover:bg-gray-100', )} - activeLinkClassName={cn('bg-blue-800 text-white', 'hover:bg-blue-700')} + activeLinkClassName={cn('bg-blue-800 text-white', 'hover:!bg-blue-700')} previousLinkClassName={cn( 'flex h-8 w-8 items-center justify-center rounded-md text-gray-700', 'hover:bg-gray-100', From 2017a8f71fe2639bd366705d4c55e34d7560262d Mon Sep 17 00:00:00 2001 From: mina-gwak Date: Tue, 15 Apr 2025 00:01:29 +0900 Subject: [PATCH 2/3] =?UTF-8?q?Feat:=20PD-254=20=EC=95=84=EC=9D=B4?= =?UTF-8?q?=ED=85=9C=20=ED=81=B4=EB=A6=AD=20=EC=8B=9C=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=20=ED=8E=98=EC=9D=B4=EC=A7=80=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/applicant-management-list-page.tsx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/pages/applicant-management/ui/applicant-management-list-page.tsx b/src/pages/applicant-management/ui/applicant-management-list-page.tsx index 2e3ecbc7..c7c920ec 100644 --- a/src/pages/applicant-management/ui/applicant-management-list-page.tsx +++ b/src/pages/applicant-management/ui/applicant-management-list-page.tsx @@ -1,5 +1,6 @@ 'use client' +import { useRouter } from 'next/navigation' import { useTranslations } from 'next-intl' import { useState } from 'react' @@ -12,6 +13,8 @@ import { useJobPostRelations } from '../api/use-job-post-relations' export const ApplicantManagementListPage = () => { const t = useTranslations('applicant-management-list') + const router = useRouter() + const [currentPage, setCurrentPage] = useState(0) const [status, setStatus] = useState( ApplicationStatus.SUBMITTED, @@ -22,6 +25,8 @@ export const ApplicantManagementListPage = () => { pageNumber: currentPage, }) + const hasNoApplications = applications.length === 0 + const handlePageChange = ({ selected }: { selected: number }) => { setCurrentPage(selected) } @@ -30,7 +35,9 @@ export const ApplicantManagementListPage = () => { setStatus(value as ApplicationStatus) } - const hasNoApplications = applications.length === 0 + const handleItemClick = (id: number) => () => { + router.push(`/business/applicant-management/${id}`) + } return ( @@ -80,7 +87,10 @@ export const ApplicantManagementListPage = () => { return ( {applications.map(application => ( - + {application.resumeFirstName}{' '} {application.resumeLastName} From 18d754de9a6bd91ef899ff84f25391735d46054e Mon Sep 17 00:00:00 2001 From: mina-gwak Date: Tue, 15 Apr 2025 00:04:40 +0900 Subject: [PATCH 3/3] =?UTF-8?q?Feat:=20PD-254=20=EC=BB=A4=EC=84=9C=20?= =?UTF-8?q?=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../applicant-management/ui/applicant-management-list-page.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/applicant-management/ui/applicant-management-list-page.tsx b/src/pages/applicant-management/ui/applicant-management-list-page.tsx index c7c920ec..93fbe782 100644 --- a/src/pages/applicant-management/ui/applicant-management-list-page.tsx +++ b/src/pages/applicant-management/ui/applicant-management-list-page.tsx @@ -90,6 +90,7 @@ export const ApplicantManagementListPage = () => { {application.resumeFirstName}{' '}