Skip to content

Commit

Permalink
refactor: name을 context가 아닌 prop으로 전달
Browse files Browse the repository at this point in the history
  • Loading branch information
llqqssttyy committed Oct 15, 2024
1 parent 166101b commit b890da2
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 215 deletions.
10 changes: 6 additions & 4 deletions frontend/src/components/dashboard/ProcessBoard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import ApplicantModal from '@components/ApplicantModal';
import { Process } from '@customTypes/process';

import { useSearchApplicant } from '@contexts/SearchApplicantContext';
import ProcessColumn from '../ProcessColumn';
import SideFloatingMessageForm from '../SideFloatingMessageForm';
import S from './style';
Expand All @@ -11,11 +10,14 @@ interface KanbanBoardProps {
// eslint-disable-next-line react/no-unused-prop-types
isSubTab?: boolean;
showRejectedApplicant?: boolean;
searchedName?: string;
}

export default function ProcessBoard({ processes, showRejectedApplicant = false }: KanbanBoardProps) {
const { debouncedName: searchedName } = useSearchApplicant();

export default function ProcessBoard({
processes,
showRejectedApplicant = false,
searchedName = '',
}: KanbanBoardProps) {
return (
<S.Container>
{/* TODO: isSubTab을 가져와서 SubTab을 렌더링 합니다. */}
Expand Down
198 changes: 96 additions & 102 deletions frontend/src/components/dashboard/ProcessColumn/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import React, { useMemo } from 'react';
import { useParams } from 'react-router-dom';

import { useModal } from '@contexts/ModalContext';
import { DropdownProvider } from '@contexts/DropdownContext';
import { useFloatingEmailForm } from '@contexts/FloatingEmailFormContext';
import { useSpecificProcessId } from '@contexts/SpecificProcessIdContext';
import { useSpecificApplicantId } from '@contexts/SpecificApplicnatIdContext';

import useProcess from '@hooks/useProcess';
import { useSpecificProcessId } from '@contexts/SpecificProcessIdContext';
import { Process } from '@customTypes/process';
import useApplicant from '@hooks/useApplicant';
import specificApplicant from '@hooks/useSpecificApplicant';
import useProcess from '@hooks/useProcess';

import { DropdownProvider } from '@contexts/DropdownContext';

import { DropdownItemType } from '@components/_common/molecules/DropdownItemRenderer';
import { Process } from '@customTypes/process';
import { useFloatingEmailForm } from '@contexts/FloatingEmailFormContext';
import specificApplicant from '@hooks/useSpecificApplicant';
import { useMemo } from 'react';
import ApplicantCard from '../ApplicantCard';
import ProcessDescription from './ProcessDescription';
import S from './style';
Expand All @@ -24,107 +24,101 @@ interface ProcessColumnProps {
searchedName?: string;
}

const shouldRerender = (prevProps: ProcessColumnProps, nextProps: ProcessColumnProps) => {
if (prevProps.process !== nextProps.process) return false;
if (prevProps.searchedName !== nextProps.searchedName) return false;
return true;
};

const ProcessColumn = React.memo(
({ process, showRejectedApplicant, isPassedColumn = false, searchedName = '' }: ProcessColumnProps) => {
const { dashboardId, applyFormId } = useParams() as { dashboardId: string; applyFormId: string };
const { processList } = useProcess({ dashboardId, applyFormId });
const { mutate: moveApplicantProcess } = useApplicant({});
const { mutate: rejectMutate } = specificApplicant.useRejectApplicant({ dashboardId, applyFormId });
export default function ProcessColumn({
process,
showRejectedApplicant,
isPassedColumn = false,
searchedName = '',
}: ProcessColumnProps) {
const { dashboardId, applyFormId } = useParams() as { dashboardId: string; applyFormId: string };
const { processList } = useProcess({ dashboardId, applyFormId });
const { mutate: moveApplicantProcess } = useApplicant({});
const { mutate: rejectMutate } = specificApplicant.useRejectApplicant({ dashboardId, applyFormId });

const { setApplicantId } = useSpecificApplicantId();
const { setProcessId } = useSpecificProcessId();
const { open } = useModal();
const { open: sideEmailFormOpen } = useFloatingEmailForm();
const { setApplicantId } = useSpecificApplicantId();
const { setProcessId } = useSpecificProcessId();
const { open } = useModal();
const { open: sideEmailFormOpen } = useFloatingEmailForm();

const menuItemsList = ({ applicantId }: { applicantId: number }) => {
const menuItems: DropdownItemType[] = [
{
type: 'subTrigger',
id: 'moveProcess',
name: '단계 이동',
items: processList.map(({ processName, processId }) => ({
type: 'clickable',
id: processId,
name: processName,
onClick: ({ targetProcessId }) => {
moveApplicantProcess({ processId: targetProcessId, applicants: [applicantId] });
},
})),
},
{
const menuItemsList = ({ applicantId }: { applicantId: number }) => {
const menuItems: DropdownItemType[] = [
{
type: 'subTrigger',
id: 'moveProcess',
name: '단계 이동',
items: processList.map(({ processName, processId }) => ({
type: 'clickable',
id: 'emailButton',
name: '이메일 보내기',
hasSeparate: true,
onClick: () => {
setApplicantId(applicantId);
sideEmailFormOpen();
id: processId,
name: processName,
onClick: ({ targetProcessId }) => {
moveApplicantProcess({ processId: targetProcessId, applicants: [applicantId] });
},
})),
},
{
type: 'clickable',
id: 'emailButton',
name: '이메일 보내기',
hasSeparate: true,
onClick: () => {
setApplicantId(applicantId);
sideEmailFormOpen();
},
{
type: 'clickable',
id: 'rejectButton',
name: '불합격 처리',
isHighlight: true,
hasSeparate: true,
onClick: () => {
rejectMutate({ applicantId });
},
},
{
type: 'clickable',
id: 'rejectButton',
name: '불합격 처리',
isHighlight: true,
hasSeparate: true,
onClick: () => {
rejectMutate({ applicantId });
},
];
},
];

return menuItems;
};
return menuItems;
};

const cardClickHandler = (id: number) => {
setApplicantId(id);
setProcessId(process.processId);
open();
};
const cardClickHandler = (id: number) => {
setApplicantId(id);
setProcessId(process.processId);
open();
};

const filteredApplicants = useMemo(
() =>
process.applicants.filter(({ applicantName, isRejected }) => {
const matchesName = applicantName.includes(searchedName);
const matchesRejection = showRejectedApplicant ? isRejected : !isRejected;
return matchesName && matchesRejection;
}),
[searchedName, showRejectedApplicant],
);
const filteredApplicants = useMemo(
() =>
process.applicants.filter(({ applicantName, isRejected }) => {
const matchesName = searchedName ? applicantName.includes(searchedName) : true;
const matchesRejection = showRejectedApplicant ? isRejected : !isRejected;
return matchesName && matchesRejection;
}),
[searchedName, showRejectedApplicant, process.applicants],
);

return (
<S.ProcessWrapper isPassedColumn={isPassedColumn}>
<S.Header>
<S.Title>{process.name}</S.Title>
<ProcessDescription description={process.description} />
</S.Header>
<S.ApplicantList>
{filteredApplicants.map(
({ applicantId, applicantName, createdAt, evaluationCount, averageScore, isRejected }) => (
<DropdownProvider key={applicantId}>
<ApplicantCard
name={applicantName}
isRejected={isRejected}
createdAt={createdAt}
evaluationCount={evaluationCount}
averageScore={averageScore}
popOverMenuItems={menuItemsList({ applicantId })}
onCardClick={() => cardClickHandler(applicantId)}
/>
</DropdownProvider>
),
)}
</S.ApplicantList>
</S.ProcessWrapper>
);
},
shouldRerender,
);

export default ProcessColumn;
return (
<S.ProcessWrapper isPassedColumn={isPassedColumn}>
<S.Header>
<S.Title>{process.name}</S.Title>
<ProcessDescription description={process.description} />
</S.Header>
<S.ApplicantList>
{filteredApplicants.map(
({ applicantId, applicantName, createdAt, evaluationCount, averageScore, isRejected }) => (
<DropdownProvider key={applicantId}>
<ApplicantCard
name={applicantName}
isRejected={isRejected}
createdAt={createdAt}
evaluationCount={evaluationCount}
averageScore={averageScore}
popOverMenuItems={menuItemsList({ applicantId })}
onCardClick={() => cardClickHandler(applicantId)}
/>
</DropdownProvider>
),
)}
</S.ApplicantList>
</S.ProcessWrapper>
);
}

This file was deleted.

15 changes: 0 additions & 15 deletions frontend/src/components/dashboard/SearchApplicantInput/index.tsx

This file was deleted.

18 changes: 18 additions & 0 deletions frontend/src/components/dashboard/useSearchApplicant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import useDebounce from '@hooks/utils/useDebounce';
import { useCallback, useState } from 'react';

export const useSearchApplicant = () => {
const [name, setName] = useState('');

const handleName = useCallback((newName: string) => {
setName(newName);
}, []);

const debouncedName = useDebounce(name, 300);

return {
name,
debouncedName,
handleName,
};
};
39 changes: 0 additions & 39 deletions frontend/src/contexts/SearchApplicantContext.tsx

This file was deleted.

Loading

0 comments on commit b890da2

Please sign in to comment.