Skip to content

Commit

Permalink
refactor: selectableProblemList 컴포넌트로 분리:
Browse files Browse the repository at this point in the history
  • Loading branch information
dev2820 committed Nov 23, 2023
1 parent 01df1d2 commit da285b0
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 37 deletions.
48 changes: 48 additions & 0 deletions frontend/src/components/Problem/SelectableProblemList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { MouseEvent } from 'react';

import type { ProblemId, ProblemInfo } from '@/apis/problems';

interface ProblemListProps {
problemList: ProblemInfo[];
pickedProblemIds: ProblemId[];
onSelectProblem: (problemId: ProblemId) => void;
}

const SelectableProblemList = ({
problemList,
pickedProblemIds,
onSelectProblem,
}: ProblemListProps) => {
function handleSelectProblem(e: MouseEvent<HTMLUListElement>) {
const $target = e.target as HTMLElement;
if ($target.tagName !== 'BUTTON') return;

const $li = $target.closest('li');
if (!$li) return;

const problemId = Number($li.dataset['problemId']);
onSelectProblem(problemId);
}

const getSelectButton = ({ isPicked }: { isPicked: boolean }) => {
if (isPicked) {
return <button>취소</button>;
}
return <button>선택</button>;
};

return (
<ul onClick={handleSelectProblem}>
{problemList.map(({ id, title }) => (
<li key={id} data-problem-id={id}>
<span>
{id}: {title}
</span>
{getSelectButton({ isPicked: pickedProblemIds.includes(id) })}
</li>
))}
</ul>
);
};

export default SelectableProblemList;
43 changes: 6 additions & 37 deletions frontend/src/pages/CreateCompetitionPage.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { css } from '@style/css';

import type { ChangeEvent, MouseEvent } from 'react';
import type { ChangeEvent } from 'react';
import { useNavigate } from 'react-router-dom';

import type { ProblemId, ProblemInfo } from '@/apis/problems';
import type { ProblemId } from '@/apis/problems';
import { Input } from '@/components/Common';
import SelectableProblemList from '@/components/Problem/SelectableProblemList';
import { useCompetitionForm } from '@/hooks/competition/useCompetitionForm';
import { useProblemList } from '@/hooks/problem/useProblemList';
import { isNil } from '@/utils/type';
Expand Down Expand Up @@ -112,50 +113,18 @@ export default function CompetitionCreatePage() {
required
></Input.DateTimeField>
</Input>
<ProblemList
allProblems={problemList}
<SelectableProblemList
problemList={problemList}
pickedProblemIds={form.problems}
onSelectProblem={handleSelectProblem}
></ProblemList>
></SelectableProblemList>
<div>선택된 문제: {[...form.problems].join(',')}</div>
</fieldset>
<button onClick={handleSumbitCompetition}>대회 생성</button>
</main>
);
}

interface ProblemListProps {
allProblems: ProblemInfo[];
pickedProblemIds: ProblemId[];
onSelectProblem: (problemId: ProblemId) => void;
}

const ProblemList = ({ allProblems, pickedProblemIds, onSelectProblem }: ProblemListProps) => {
function handleSelectProblem(e: MouseEvent<HTMLUListElement>) {
const $target = e.target as HTMLElement;
if ($target.tagName !== 'BUTTON') return;

const $li = $target.closest('li');
if (!$li) return;

const problemId = Number($li.dataset['problemId']);
onSelectProblem(problemId);
}

return (
<ul onClick={handleSelectProblem}>
{allProblems.map(({ id, title }) => (
<li key={id} data-problem-id={id}>
<span>
{id}: {title}
</span>
<button>{pickedProblemIds.includes(id) ? '취소' : '선택'}</button>
</li>
))}
</ul>
);
};

const fieldSetStyle = css({
display: 'flex',
flexDirection: 'column',
Expand Down

0 comments on commit da285b0

Please sign in to comment.