From 39bfdd37de6b33827c58333904c8e12fe442a505 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 09:08:57 +0000 Subject: [PATCH 1/9] Create draft PR for #823 From 66b14e2005d7f8f070c708c5b6397ab282ab9235 Mon Sep 17 00:00:00 2001 From: Kim Da Eun Date: Wed, 16 Oct 2024 17:19:23 +0900 Subject: [PATCH 2/9] =?UTF-8?q?feat:=20ProcessQueryParams=20=EC=BB=A8?= =?UTF-8?q?=ED=85=8D=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/api/domain/process.ts | 6 +-- .../contexts/ProcessQueryParamsProvider.tsx | 51 +++++++++++++++++++ frontend/src/hooks/useProcess/index.ts | 6 +-- frontend/src/pages/Dashboard/index.tsx | 51 ++++++++++--------- frontend/src/types/process.ts | 18 +++++++ 5 files changed, 102 insertions(+), 30 deletions(-) create mode 100644 frontend/src/contexts/ProcessQueryParamsProvider.tsx diff --git a/frontend/src/api/domain/process.ts b/frontend/src/api/domain/process.ts index 079e7903e..a618d2dc6 100644 --- a/frontend/src/api/domain/process.ts +++ b/frontend/src/api/domain/process.ts @@ -1,4 +1,4 @@ -import { ProcessResponse } from '@customTypes/process'; +import { ProcessQueryParams, ProcessResponse } from '@customTypes/process'; import { PROCESSES } from '../endPoint'; import { createParams } from '../utils'; import APIClient from '../APIClient'; @@ -6,9 +6,9 @@ import APIClient from '../APIClient'; const apiClient = new APIClient(PROCESSES); const processApis = { - get: async ({ dashboardId }: { dashboardId: string }): Promise => + get: async ({ dashboardId, ...params }: ProcessQueryParams): Promise => apiClient.get({ - path: `?${createParams({ dashboardId })}`, + path: `?${createParams({ dashboardId, ...params })}`, }), create: async (params: { dashboardId: number; orderIndex: number; name: string; description?: string }) => diff --git a/frontend/src/contexts/ProcessQueryParamsProvider.tsx b/frontend/src/contexts/ProcessQueryParamsProvider.tsx new file mode 100644 index 000000000..53f39b236 --- /dev/null +++ b/frontend/src/contexts/ProcessQueryParamsProvider.tsx @@ -0,0 +1,51 @@ +import { ProcessFilterOptions, ProcessSortOptions } from '@customTypes/process'; +import { createContext, PropsWithChildren, useCallback, useContext, useMemo, useState } from 'react'; + +interface ProcessQueryParamsContextProps { + sortOption: ProcessSortOptions; + filterOption: ProcessFilterOptions; + updateSortOption: (sortOption: ProcessSortOptions) => void; + updateFilterOption: (filterOption: ProcessFilterOptions) => void; +} + +const ProcessQueryParamsContext = createContext(null); + +export function ProcessQueryParamsProvider({ children }: PropsWithChildren) { + const [sortOption, setSortOption] = useState({ + sortByCreatedAt: 'DESC', + sortByScore: 'DESC', + }); + const [filterOption, setFilterOption] = useState({ + evaluationStatus: 'ALL', + minScore: undefined, + maxScore: undefined, + }); + + const updateSortOption = useCallback((newSortOption: ProcessSortOptions) => { + setSortOption(newSortOption); + }, []); + + const updateFilterOption = useCallback((newFilterOption: ProcessFilterOptions) => { + setFilterOption(newFilterOption); + }, []); + + const obj = useMemo( + () => ({ + sortOption, + filterOption, + updateSortOption, + updateFilterOption, + }), + [sortOption, filterOption, updateSortOption, updateFilterOption], + ); + + return {children}; +} + +export const useProcessQueryParams = () => { + const context = useContext(ProcessQueryParamsContext); + if (!context) { + throw new Error('useProcessQueryParams은 ProcessQueryParamsProvider내부에서 관리되어야 합니다.'); + } + return context; +}; diff --git a/frontend/src/hooks/useProcess/index.ts b/frontend/src/hooks/useProcess/index.ts index c1d5484a2..7c4cceb02 100644 --- a/frontend/src/hooks/useProcess/index.ts +++ b/frontend/src/hooks/useProcess/index.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; -import type { Process, ProcessResponse } from '@customTypes/process'; +import type { Process, ProcessQueryParams, ProcessResponse } from '@customTypes/process'; import processApis from '@api/domain/process'; import QUERY_KEYS from '@hooks/queryKeys'; @@ -12,8 +12,7 @@ export interface SimpleProcess { processId: number; } -interface UseProcessProps { - dashboardId: string; +interface UseProcessProps extends ProcessQueryParams { applyFormId: string; } @@ -37,6 +36,7 @@ export default function useProcess({ dashboardId, applyFormId }: UseProcessProps const processes = data?.processes || []; const processList = processes.map((p) => ({ processName: p.name, processId: p.processId })); + return { title: data?.title ?? '', postUrl: `${DOMAIN_URL}${routes.post({ applyFormId: data?.applyFormId ?? '' })}`, diff --git a/frontend/src/pages/Dashboard/index.tsx b/frontend/src/pages/Dashboard/index.tsx index cb40d83a7..d9b356206 100644 --- a/frontend/src/pages/Dashboard/index.tsx +++ b/frontend/src/pages/Dashboard/index.tsx @@ -18,6 +18,7 @@ import { MultiApplicantContextProvider } from '@contexts/MultiApplicantContext'; import { SpecificProcessIdProvider } from '@contexts/SpecificProcessIdContext'; import { SpecificApplicantIdProvider } from '@contexts/SpecificApplicnatIdContext'; +import { ProcessQueryParamsProvider } from '@contexts/ProcessQueryParamsProvider'; import S from './style'; export type DashboardTabItems = '지원자 관리' | '모집 과정 관리' | '불합격자 관리' | '공고 관리' | '지원서 관리'; @@ -58,36 +59,38 @@ export default function Dashboard() { 파일 맨 첫줄 주석도 삭제해야합니다. */} - - {/* [10.15-lesser] sub tab이 구현되면 아래 코드를 사용합니다. */} - {/* + + {/* [10.15-lesser] sub tab이 구현되면 아래 코드를 사용합니다. */} + {/* updateName(e.target.value)} /> */} - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/frontend/src/types/process.ts b/frontend/src/types/process.ts index be64d78ae..9d91ce44e 100644 --- a/frontend/src/types/process.ts +++ b/frontend/src/types/process.ts @@ -22,3 +22,21 @@ export interface ProcessResponse { startDate: string; endDate: string; } + +export type EvaluationStatus = 'ALL' | 'NOT_EVALUATION' | 'EVALUATED'; +export type SortOption = 'ASC' | 'DESC'; + +export type ProcessFilterOptions = { + minScore?: string; + maxScore?: string; + evaluationStatus?: EvaluationStatus; +}; +export type ProcessSortOptions = { + sortByCreatedAt?: SortOption; + sortByScore?: SortOption; +}; + +export type ProcessQueryParams = { + dashboardId: string; +} & ProcessFilterOptions & + ProcessSortOptions; From 8348174ba90b0db70cf72ec5dcb7d8a08f91c024 Mon Sep 17 00:00:00 2001 From: Kim Da Eun Date: Thu, 17 Oct 2024 02:01:55 +0900 Subject: [PATCH 3/9] =?UTF-8?q?chore:=20small=20dropdown=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/_common/molecules/Dropdown/style.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/_common/molecules/Dropdown/style.ts b/frontend/src/components/_common/molecules/Dropdown/style.ts index 87b17b84e..b897efe37 100644 --- a/frontend/src/components/_common/molecules/Dropdown/style.ts +++ b/frontend/src/components/_common/molecules/Dropdown/style.ts @@ -31,7 +31,7 @@ const Header = styled.div<{ isOpen: boolean; size: 'sm' | 'md' }>` justify-content: space-between; align-items: center; - padding: ${({ size }) => (size === 'md' ? '16px 24px' : '12px 4px 12px 8px ')}; + padding: ${({ size }) => (size === 'md' ? '16px 24px' : '8px 4px 8px 8px ')}; border: 1px solid ${({ theme }) => theme.baseColors.grayscale[400]}; From 4bc48ff4f057b31eacf224418faa541098489b7a Mon Sep 17 00:00:00 2001 From: Kim Da Eun Date: Thu, 17 Oct 2024 02:02:41 +0900 Subject: [PATCH 4/9] =?UTF-8?q?feat:=20=EC=A0=95=EB=A0=AC=20=EB=93=9C?= =?UTF-8?q?=EB=A1=AD=EB=B0=95=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dashboard/ApplicantSortDropdown/index.tsx | 42 ++++++++++ .../components/dashboard/useSortApplicant.ts | 15 ++++ .../contexts/ProcessQueryParamsProvider.tsx | 51 ------------ frontend/src/hooks/useProcess/index.ts | 29 +++++-- frontend/src/pages/Dashboard/index.tsx | 80 ++++++++++--------- frontend/src/types/process.ts | 13 +-- frontend/src/types/utilTypes.ts | 4 + 7 files changed, 137 insertions(+), 97 deletions(-) create mode 100644 frontend/src/components/dashboard/ApplicantSortDropdown/index.tsx create mode 100644 frontend/src/components/dashboard/useSortApplicant.ts delete mode 100644 frontend/src/contexts/ProcessQueryParamsProvider.tsx diff --git a/frontend/src/components/dashboard/ApplicantSortDropdown/index.tsx b/frontend/src/components/dashboard/ApplicantSortDropdown/index.tsx new file mode 100644 index 000000000..ac563dd82 --- /dev/null +++ b/frontend/src/components/dashboard/ApplicantSortDropdown/index.tsx @@ -0,0 +1,42 @@ +import Dropdown from '@components/_common/molecules/Dropdown'; +import DropdownItemRenderer, { DropdownItemType } from '@components/_common/molecules/DropdownItemRenderer'; +import { ProcessSortOption } from '@customTypes/process'; +import { Entries } from '@customTypes/utilTypes'; + +interface ApplicantSortDropdownProps { + sortOption: ProcessSortOption | undefined; + updateSortOption: (option?: ProcessSortOption) => void; +} + +type DropdownSortOptions = { + sortByScore: string; + sortByCreatedAt: string; +}; + +const sortOptions: DropdownSortOptions = { + sortByScore: '평점 높은 순', + sortByCreatedAt: '지원 날짜 순', +}; + +export default function ApplicantSortDropdown({ sortOption, updateSortOption }: ApplicantSortDropdownProps) { + return ( + + updateSortOption() }, + ...((Object.entries(sortOptions) as Entries).map(([id, name]) => ({ + type: 'clickable', + id, + name, + onClick: () => updateSortOption(id), + })) as DropdownItemType[]), + ]} + /> + + ); +} diff --git a/frontend/src/components/dashboard/useSortApplicant.ts b/frontend/src/components/dashboard/useSortApplicant.ts new file mode 100644 index 000000000..8556aaf91 --- /dev/null +++ b/frontend/src/components/dashboard/useSortApplicant.ts @@ -0,0 +1,15 @@ +import { ProcessSortOption } from '@customTypes/process'; +import { useCallback, useState } from 'react'; + +export default function useSortApplicant() { + const [sortOption, setSortOption] = useState(); + + const updateSortOption = useCallback((option?: ProcessSortOption) => { + setSortOption(option); + }, []); + + return { + sortOption, + updateSortOption, + }; +} diff --git a/frontend/src/contexts/ProcessQueryParamsProvider.tsx b/frontend/src/contexts/ProcessQueryParamsProvider.tsx deleted file mode 100644 index 53f39b236..000000000 --- a/frontend/src/contexts/ProcessQueryParamsProvider.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { ProcessFilterOptions, ProcessSortOptions } from '@customTypes/process'; -import { createContext, PropsWithChildren, useCallback, useContext, useMemo, useState } from 'react'; - -interface ProcessQueryParamsContextProps { - sortOption: ProcessSortOptions; - filterOption: ProcessFilterOptions; - updateSortOption: (sortOption: ProcessSortOptions) => void; - updateFilterOption: (filterOption: ProcessFilterOptions) => void; -} - -const ProcessQueryParamsContext = createContext(null); - -export function ProcessQueryParamsProvider({ children }: PropsWithChildren) { - const [sortOption, setSortOption] = useState({ - sortByCreatedAt: 'DESC', - sortByScore: 'DESC', - }); - const [filterOption, setFilterOption] = useState({ - evaluationStatus: 'ALL', - minScore: undefined, - maxScore: undefined, - }); - - const updateSortOption = useCallback((newSortOption: ProcessSortOptions) => { - setSortOption(newSortOption); - }, []); - - const updateFilterOption = useCallback((newFilterOption: ProcessFilterOptions) => { - setFilterOption(newFilterOption); - }, []); - - const obj = useMemo( - () => ({ - sortOption, - filterOption, - updateSortOption, - updateFilterOption, - }), - [sortOption, filterOption, updateSortOption, updateFilterOption], - ); - - return {children}; -} - -export const useProcessQueryParams = () => { - const context = useContext(ProcessQueryParamsContext); - if (!context) { - throw new Error('useProcessQueryParams은 ProcessQueryParamsProvider내부에서 관리되어야 합니다.'); - } - return context; -}; diff --git a/frontend/src/hooks/useProcess/index.ts b/frontend/src/hooks/useProcess/index.ts index 7c4cceb02..ac8856df9 100644 --- a/frontend/src/hooks/useProcess/index.ts +++ b/frontend/src/hooks/useProcess/index.ts @@ -1,6 +1,6 @@ import { useQuery } from '@tanstack/react-query'; -import type { Process, ProcessQueryParams, ProcessResponse } from '@customTypes/process'; +import type { Process, ProcessFilterOptions, ProcessResponse, ProcessSortOption } from '@customTypes/process'; import processApis from '@api/domain/process'; import QUERY_KEYS from '@hooks/queryKeys'; @@ -12,8 +12,11 @@ export interface SimpleProcess { processId: number; } -interface UseProcessProps extends ProcessQueryParams { +interface UseProcessProps { applyFormId: string; + dashboardId: string; + sortOption?: ProcessSortOption; + filterOption?: ProcessFilterOptions; } interface UseProcessReturn { @@ -27,10 +30,26 @@ interface UseProcessReturn { endDate: string; } -export default function useProcess({ dashboardId, applyFormId }: UseProcessProps): UseProcessReturn { +export default function useProcess({ + dashboardId, + applyFormId, + sortOption, + filterOption, +}: UseProcessProps): UseProcessReturn { const { data, error, isLoading } = useQuery({ - queryKey: [QUERY_KEYS.DASHBOARD, dashboardId, applyFormId], - queryFn: () => processApis.get({ dashboardId }), + queryKey: [ + QUERY_KEYS.DASHBOARD, + dashboardId, + applyFormId, + sortOption ?? 'defaultSortOption', + filterOption ?? 'defaultFilterOption', + ], + queryFn: () => + processApis.get({ + dashboardId, + ...(sortOption && { [sortOption]: 'ASC' }), + ...(filterOption && { filterOption }), + }), }); const processes = data?.processes || []; diff --git a/frontend/src/pages/Dashboard/index.tsx b/frontend/src/pages/Dashboard/index.tsx index d9b356206..3468e7236 100644 --- a/frontend/src/pages/Dashboard/index.tsx +++ b/frontend/src/pages/Dashboard/index.tsx @@ -2,37 +2,43 @@ import { useParams } from 'react-router-dom'; import Tab from '@components/_common/molecules/Tab'; -import ProcessBoard from '@components/dashboard/ProcessBoard'; import ApplyManagement from '@components/applyManagement'; -import ProcessManageBoard from '@components/processManagement/ProcessManageBoard'; -import PostManageBoard from '@components/postManagement/PostManageBoard'; import DashboardHeader from '@components/dashboard/DashboardHeader'; +import ProcessBoard from '@components/dashboard/ProcessBoard'; +import PostManageBoard from '@components/postManagement/PostManageBoard'; +import ProcessManageBoard from '@components/processManagement/ProcessManageBoard'; -import useProcess from '@hooks/useProcess'; import useTab from '@components/_common/molecules/Tab/useTab'; import { useSearchApplicant } from '@components/dashboard/useSearchApplicant'; +import useProcess from '@hooks/useProcess'; import { DASHBOARD_TAB_MENUS } from '@constants/constants'; import { FloatingEmailFormProvider } from '@contexts/FloatingEmailFormContext'; import { MultiApplicantContextProvider } from '@contexts/MultiApplicantContext'; -import { SpecificProcessIdProvider } from '@contexts/SpecificProcessIdContext'; import { SpecificApplicantIdProvider } from '@contexts/SpecificApplicnatIdContext'; +import { SpecificProcessIdProvider } from '@contexts/SpecificProcessIdContext'; -import { ProcessQueryParamsProvider } from '@contexts/ProcessQueryParamsProvider'; +import ApplicantSortDropdown from '@components/dashboard/ApplicantSortDropdown'; +import useSortApplicant from '@components/dashboard/useSortApplicant'; import S from './style'; export type DashboardTabItems = '지원자 관리' | '모집 과정 관리' | '불합격자 관리' | '공고 관리' | '지원서 관리'; export default function Dashboard() { - const { dashboardId, applyFormId } = useParams() as { dashboardId: string; applyFormId: string }; - const { processes, title, postUrl, startDate, endDate } = useProcess({ dashboardId, applyFormId }); - const { currentMenu, moveTab } = useTab({ defaultValue: '지원자 관리' }); const { debouncedName } = useSearchApplicant(); // TODO: [10.15-lesser] sub tab이 구현되면 아래 코드를 사용합니다. // const { debouncedName, name, updateName } = useSearchApplicant(); + const { sortOption, updateSortOption } = useSortApplicant(); + const { dashboardId, applyFormId } = useParams() as { dashboardId: string; applyFormId: string }; + const { processes, title, postUrl, startDate, endDate } = useProcess({ + dashboardId, + applyFormId, + sortOption, + }); + return ( - - - {/* [10.15-lesser] sub tab이 구현되면 아래 코드를 사용합니다. */} - {/* + {/* [10.15-lesser] sub tab이 구현되면 아래 코드를 사용합니다. */} + {/* updateName(e.target.value)} /> */} - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/frontend/src/types/process.ts b/frontend/src/types/process.ts index 9d91ce44e..a537fcbd5 100644 --- a/frontend/src/types/process.ts +++ b/frontend/src/types/process.ts @@ -24,19 +24,22 @@ export interface ProcessResponse { } export type EvaluationStatus = 'ALL' | 'NOT_EVALUATION' | 'EVALUATED'; -export type SortOption = 'ASC' | 'DESC'; -export type ProcessFilterOptions = { +type FilterParams = { minScore?: string; maxScore?: string; evaluationStatus?: EvaluationStatus; }; -export type ProcessSortOptions = { +export type ProcessFilterOptions = FilterParams; + +type SortOption = 'ASC' | 'DESC'; +type SortParams = { sortByCreatedAt?: SortOption; sortByScore?: SortOption; }; +export type ProcessSortOption = keyof SortParams; export type ProcessQueryParams = { dashboardId: string; -} & ProcessFilterOptions & - ProcessSortOptions; +} & FilterParams & + SortParams; diff --git a/frontend/src/types/utilTypes.ts b/frontend/src/types/utilTypes.ts index c16db3996..27b1e032d 100644 --- a/frontend/src/types/utilTypes.ts +++ b/frontend/src/types/utilTypes.ts @@ -23,3 +23,7 @@ type Brand = { [__brand]: B }; export type Branded = T & Brand; export type KeyedStrings = Record; + +export type Entries = { + [K in keyof T]: [K, T[K]]; +}[keyof T][]; From 22200024758287ba5b1932f14d4f4e28bebf3885 Mon Sep 17 00:00:00 2001 From: Kim Da Eun Date: Thu, 17 Oct 2024 11:06:13 +0900 Subject: [PATCH 5/9] =?UTF-8?q?fix:=20=EC=A0=95=EB=A0=AC=20=EC=98=B5?= =?UTF-8?q?=EC=85=98=EC=9D=B4=20=EB=B0=94=EB=80=8C=EC=97=88=EC=9D=84=20?= =?UTF-8?q?=EB=95=8C=20=EC=9A=94=EC=B2=AD=EC=9D=B4=202=EB=B2=88=20?= =?UTF-8?q?=EA=B0=80=EB=8A=94=20=EB=B2=84=EA=B7=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dashboard/ApplicantSortDropdown/index.tsx | 2 +- frontend/src/hooks/useProcess/index.ts | 36 ++++++++++--------- frontend/src/pages/Dashboard/index.tsx | 5 +-- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/frontend/src/components/dashboard/ApplicantSortDropdown/index.tsx b/frontend/src/components/dashboard/ApplicantSortDropdown/index.tsx index ac563dd82..b25ea15f1 100644 --- a/frontend/src/components/dashboard/ApplicantSortDropdown/index.tsx +++ b/frontend/src/components/dashboard/ApplicantSortDropdown/index.tsx @@ -28,7 +28,7 @@ export default function ApplicantSortDropdown({ sortOption, updateSortOption }: > updateSortOption() }, + { type: 'clickable', id: '', name: '기본 순', onClick: () => updateSortOption() }, ...((Object.entries(sortOptions) as Entries).map(([id, name]) => ({ type: 'clickable', id, diff --git a/frontend/src/hooks/useProcess/index.ts b/frontend/src/hooks/useProcess/index.ts index ac8856df9..1ad6791a1 100644 --- a/frontend/src/hooks/useProcess/index.ts +++ b/frontend/src/hooks/useProcess/index.ts @@ -1,10 +1,12 @@ import { useQuery } from '@tanstack/react-query'; -import type { Process, ProcessFilterOptions, ProcessResponse, ProcessSortOption } from '@customTypes/process'; +import type { Process, ProcessResponse } from '@customTypes/process'; import processApis from '@api/domain/process'; +import useSortApplicant from '@components/dashboard/useSortApplicant'; import QUERY_KEYS from '@hooks/queryKeys'; import { routes } from '@router/path'; +import { useEffect } from 'react'; import { DOMAIN_URL } from '../../constants/constants'; export interface SimpleProcess { @@ -15,8 +17,6 @@ export interface SimpleProcess { interface UseProcessProps { applyFormId: string; dashboardId: string; - sortOption?: ProcessSortOption; - filterOption?: ProcessFilterOptions; } interface UseProcessReturn { @@ -33,25 +33,27 @@ interface UseProcessReturn { export default function useProcess({ dashboardId, applyFormId, - sortOption, - filterOption, -}: UseProcessProps): UseProcessReturn { - const { data, error, isLoading } = useQuery({ - queryKey: [ - QUERY_KEYS.DASHBOARD, - dashboardId, - applyFormId, - sortOption ?? 'defaultSortOption', - filterOption ?? 'defaultFilterOption', - ], +}: UseProcessProps): UseProcessReturn & ReturnType { + const { sortOption, updateSortOption } = useSortApplicant(); + + const { data, error, isLoading, refetch } = useQuery({ + // [10.17-lesser] + // sortOption을 queryKey에 추가하면 기존 요청까지 다시 보내게 되어 + // queryKey에 sortOption을 추가하지 않고, refetch로 재요청 보내도록 수정합니다. + // eslint-disable-next-line + queryKey: [QUERY_KEYS.DASHBOARD, dashboardId, applyFormId], queryFn: () => processApis.get({ dashboardId, - ...(sortOption && { [sortOption]: 'ASC' }), - ...(filterOption && { filterOption }), + ...(sortOption && { [sortOption as string]: 'ASC' }), + // ...(filterOption && { filterOption: filterOption as ProcessFilterOptions }), }), }); + useEffect(() => { + refetch(); + }, [sortOption]); + const processes = data?.processes || []; const processList = processes.map((p) => ({ processName: p.name, processId: p.processId })); @@ -65,5 +67,7 @@ export default function useProcess({ isLoading, startDate: data?.startDate ?? '0', endDate: data?.endDate ?? '0', + sortOption, + updateSortOption, }; } diff --git a/frontend/src/pages/Dashboard/index.tsx b/frontend/src/pages/Dashboard/index.tsx index 3468e7236..1776aca10 100644 --- a/frontend/src/pages/Dashboard/index.tsx +++ b/frontend/src/pages/Dashboard/index.tsx @@ -19,7 +19,6 @@ import { SpecificApplicantIdProvider } from '@contexts/SpecificApplicnatIdContex import { SpecificProcessIdProvider } from '@contexts/SpecificProcessIdContext'; import ApplicantSortDropdown from '@components/dashboard/ApplicantSortDropdown'; -import useSortApplicant from '@components/dashboard/useSortApplicant'; import S from './style'; export type DashboardTabItems = '지원자 관리' | '모집 과정 관리' | '불합격자 관리' | '공고 관리' | '지원서 관리'; @@ -31,12 +30,10 @@ export default function Dashboard() { // TODO: [10.15-lesser] sub tab이 구현되면 아래 코드를 사용합니다. // const { debouncedName, name, updateName } = useSearchApplicant(); - const { sortOption, updateSortOption } = useSortApplicant(); const { dashboardId, applyFormId } = useParams() as { dashboardId: string; applyFormId: string }; - const { processes, title, postUrl, startDate, endDate } = useProcess({ + const { processes, title, postUrl, startDate, endDate, sortOption, updateSortOption } = useProcess({ dashboardId, applyFormId, - sortOption, }); return ( From c8ebbbcf5081abf919100d3036daae07cc66a90a Mon Sep 17 00:00:00 2001 From: Kim Da Eun Date: Thu, 17 Oct 2024 11:38:22 +0900 Subject: [PATCH 6/9] =?UTF-8?q?refactor:=20useSortApplicant=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=EB=A5=BC=20useProcess=20=ED=95=98=EC=9C=84=EB=A1=9C?= =?UTF-8?q?=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useProcess/index.ts | 2 +- .../dashboard => hooks/useProcess}/useSortApplicant.ts | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename frontend/src/{components/dashboard => hooks/useProcess}/useSortApplicant.ts (100%) diff --git a/frontend/src/hooks/useProcess/index.ts b/frontend/src/hooks/useProcess/index.ts index 1ad6791a1..58c960261 100644 --- a/frontend/src/hooks/useProcess/index.ts +++ b/frontend/src/hooks/useProcess/index.ts @@ -3,8 +3,8 @@ import { useQuery } from '@tanstack/react-query'; import type { Process, ProcessResponse } from '@customTypes/process'; import processApis from '@api/domain/process'; -import useSortApplicant from '@components/dashboard/useSortApplicant'; import QUERY_KEYS from '@hooks/queryKeys'; +import useSortApplicant from '@hooks/useProcess/useSortApplicant'; import { routes } from '@router/path'; import { useEffect } from 'react'; import { DOMAIN_URL } from '../../constants/constants'; diff --git a/frontend/src/components/dashboard/useSortApplicant.ts b/frontend/src/hooks/useProcess/useSortApplicant.ts similarity index 100% rename from frontend/src/components/dashboard/useSortApplicant.ts rename to frontend/src/hooks/useProcess/useSortApplicant.ts From 5b1fd80c5fe4f8a87063d30c789579e5b550310a Mon Sep 17 00:00:00 2001 From: Kim Da Eun Date: Thu, 17 Oct 2024 14:33:02 +0900 Subject: [PATCH 7/9] =?UTF-8?q?feat:=20=EC=A0=95=EB=A0=AC=20=EA=B8=B0?= =?UTF-8?q?=EC=A4=80=20=EB=8B=A4=EC=96=91=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dashboard/ApplicantSortDropdown/index.tsx | 52 ++++++++++--------- frontend/src/hooks/useProcess/index.ts | 2 +- .../src/hooks/useProcess/useSortApplicant.ts | 8 +-- frontend/src/pages/Dashboard/index.tsx | 11 ++-- frontend/src/types/process.ts | 2 +- 5 files changed, 42 insertions(+), 33 deletions(-) diff --git a/frontend/src/components/dashboard/ApplicantSortDropdown/index.tsx b/frontend/src/components/dashboard/ApplicantSortDropdown/index.tsx index b25ea15f1..978dd5939 100644 --- a/frontend/src/components/dashboard/ApplicantSortDropdown/index.tsx +++ b/frontend/src/components/dashboard/ApplicantSortDropdown/index.tsx @@ -1,41 +1,45 @@ import Dropdown from '@components/_common/molecules/Dropdown'; -import DropdownItemRenderer, { DropdownItemType } from '@components/_common/molecules/DropdownItemRenderer'; -import { ProcessSortOption } from '@customTypes/process'; -import { Entries } from '@customTypes/utilTypes'; +import DropdownItemRenderer from '@components/_common/molecules/DropdownItemRenderer'; +import { ProcessSortOption, SortOption } from '@customTypes/process'; +import { SortOptionState } from '@hooks/useProcess/useSortApplicant'; interface ApplicantSortDropdownProps { - sortOption: ProcessSortOption | undefined; - updateSortOption: (option?: ProcessSortOption) => void; + sortOption: SortOptionState; + updateSortOption: (option?: SortOptionState) => void; } -type DropdownSortOptions = { - sortByScore: string; - sortByCreatedAt: string; -}; +interface SortOptionsType { + id: ProcessSortOption; + name: string; + value: SortOption; +} -const sortOptions: DropdownSortOptions = { - sortByScore: '평점 높은 순', - sortByCreatedAt: '지원 날짜 순', -}; +const sortOptions: SortOptionsType[] = [ + { id: 'sortByScore', name: '평점 높은 순', value: 'DESC' }, + { id: 'sortByScore', name: '평점 낮은 순', value: 'ASC' }, + { id: 'sortByCreatedAt', name: '지원일 최신 순', value: 'DESC' }, + { id: 'sortByCreatedAt', name: '지원일 오래된 순', value: 'ASC' }, +]; export default function ApplicantSortDropdown({ sortOption, updateSortOption }: ApplicantSortDropdownProps) { + const selectedOption = sortOptions.find( + (option) => sortOption && option.id in sortOption && option.value === sortOption[option.id], + ); + return ( updateSortOption() }, - ...((Object.entries(sortOptions) as Entries).map(([id, name]) => ({ - type: 'clickable', - id, - name, - onClick: () => updateSortOption(id), - })) as DropdownItemType[]), - ]} + items={sortOptions.map(({ id, name, value }) => ({ + type: 'clickable', + id, + name, + onClick: () => updateSortOption({ [id]: value } as SortOptionState), + }))} /> ); diff --git a/frontend/src/hooks/useProcess/index.ts b/frontend/src/hooks/useProcess/index.ts index 58c960261..912966b92 100644 --- a/frontend/src/hooks/useProcess/index.ts +++ b/frontend/src/hooks/useProcess/index.ts @@ -45,7 +45,7 @@ export default function useProcess({ queryFn: () => processApis.get({ dashboardId, - ...(sortOption && { [sortOption as string]: 'ASC' }), + ...sortOption, // ...(filterOption && { filterOption: filterOption as ProcessFilterOptions }), }), }); diff --git a/frontend/src/hooks/useProcess/useSortApplicant.ts b/frontend/src/hooks/useProcess/useSortApplicant.ts index 8556aaf91..deaa0ecf0 100644 --- a/frontend/src/hooks/useProcess/useSortApplicant.ts +++ b/frontend/src/hooks/useProcess/useSortApplicant.ts @@ -1,10 +1,12 @@ -import { ProcessSortOption } from '@customTypes/process'; +import { ProcessSortOption, SortOption } from '@customTypes/process'; import { useCallback, useState } from 'react'; +export type SortOptionState = Record | undefined; + export default function useSortApplicant() { - const [sortOption, setSortOption] = useState(); + const [sortOption, setSortOption] = useState(); - const updateSortOption = useCallback((option?: ProcessSortOption) => { + const updateSortOption = useCallback((option?: SortOptionState) => { setSortOption(option); }, []); diff --git a/frontend/src/pages/Dashboard/index.tsx b/frontend/src/pages/Dashboard/index.tsx index 1776aca10..627d16af5 100644 --- a/frontend/src/pages/Dashboard/index.tsx +++ b/frontend/src/pages/Dashboard/index.tsx @@ -18,7 +18,6 @@ import { MultiApplicantContextProvider } from '@contexts/MultiApplicantContext'; import { SpecificApplicantIdProvider } from '@contexts/SpecificApplicnatIdContext'; import { SpecificProcessIdProvider } from '@contexts/SpecificProcessIdContext'; -import ApplicantSortDropdown from '@components/dashboard/ApplicantSortDropdown'; import S from './style'; export type DashboardTabItems = '지원자 관리' | '모집 과정 관리' | '불합격자 관리' | '공고 관리' | '지원서 관리'; @@ -29,9 +28,13 @@ export default function Dashboard() { const { debouncedName } = useSearchApplicant(); // TODO: [10.15-lesser] sub tab이 구현되면 아래 코드를 사용합니다. // const { debouncedName, name, updateName } = useSearchApplicant(); + // const { processes, title, postUrl, startDate, endDate, sortOption, updateSortOption } = useProcess({ + // dashboardId, + // applyFormId, + // }); const { dashboardId, applyFormId } = useParams() as { dashboardId: string; applyFormId: string }; - const { processes, title, postUrl, startDate, endDate, sortOption, updateSortOption } = useProcess({ + const { processes, title, postUrl, startDate, endDate } = useProcess({ dashboardId, applyFormId, }); @@ -70,10 +73,10 @@ export default function Dashboard() { value={name} onChange={(e) => updateName(e.target.value)} /> */} - + /> */} diff --git a/frontend/src/types/process.ts b/frontend/src/types/process.ts index a537fcbd5..27a06d8f3 100644 --- a/frontend/src/types/process.ts +++ b/frontend/src/types/process.ts @@ -32,7 +32,7 @@ type FilterParams = { }; export type ProcessFilterOptions = FilterParams; -type SortOption = 'ASC' | 'DESC'; +export type SortOption = 'ASC' | 'DESC'; type SortParams = { sortByCreatedAt?: SortOption; sortByScore?: SortOption; From 2bdfcc849258d5691ad6dd569d28e93f7a237acb Mon Sep 17 00:00:00 2001 From: Kim Da Eun Date: Thu, 17 Oct 2024 15:41:12 +0900 Subject: [PATCH 8/9] =?UTF-8?q?refactor:=20SortOptionState=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=84=A0=EC=96=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useProcess/useSortApplicant.ts | 4 ++-- frontend/src/types/process.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/hooks/useProcess/useSortApplicant.ts b/frontend/src/hooks/useProcess/useSortApplicant.ts index deaa0ecf0..65848fb2f 100644 --- a/frontend/src/hooks/useProcess/useSortApplicant.ts +++ b/frontend/src/hooks/useProcess/useSortApplicant.ts @@ -1,7 +1,7 @@ -import { ProcessSortOption, SortOption } from '@customTypes/process'; +import { SortParams } from '@customTypes/process'; import { useCallback, useState } from 'react'; -export type SortOptionState = Record | undefined; +export type SortOptionState = Partial | undefined; export default function useSortApplicant() { const [sortOption, setSortOption] = useState(); diff --git a/frontend/src/types/process.ts b/frontend/src/types/process.ts index 27a06d8f3..2be36793b 100644 --- a/frontend/src/types/process.ts +++ b/frontend/src/types/process.ts @@ -33,7 +33,7 @@ type FilterParams = { export type ProcessFilterOptions = FilterParams; export type SortOption = 'ASC' | 'DESC'; -type SortParams = { +export type SortParams = { sortByCreatedAt?: SortOption; sortByScore?: SortOption; }; From 9dc11d48c6465ba0ec6db7117e01f243e348bc45 Mon Sep 17 00:00:00 2001 From: Kim Da Eun Date: Thu, 17 Oct 2024 15:52:26 +0900 Subject: [PATCH 9/9] =?UTF-8?q?chore:=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=ED=83=80=EC=9E=85=20=EC=B6=94=EB=A1=A0=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/dashboard/ApplicantSortDropdown/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/dashboard/ApplicantSortDropdown/index.tsx b/frontend/src/components/dashboard/ApplicantSortDropdown/index.tsx index 978dd5939..98cd58879 100644 --- a/frontend/src/components/dashboard/ApplicantSortDropdown/index.tsx +++ b/frontend/src/components/dashboard/ApplicantSortDropdown/index.tsx @@ -23,7 +23,7 @@ const sortOptions: SortOptionsType[] = [ export default function ApplicantSortDropdown({ sortOption, updateSortOption }: ApplicantSortDropdownProps) { const selectedOption = sortOptions.find( - (option) => sortOption && option.id in sortOption && option.value === sortOption[option.id], + (option) => sortOption && option.id && option.value === sortOption[option.id], ); return (