Skip to content

Commit

Permalink
✨feat: 검색 지역 선택 시 최대 3개까지 가능하도록 구현하기 #15
Browse files Browse the repository at this point in the history
  • Loading branch information
naarang committed Oct 22, 2024
1 parent 04e93d5 commit ac82216
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 132 deletions.
118 changes: 76 additions & 42 deletions src/components/PostSearchFilter/PostSearchFilterArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,19 @@ const REGION_DATA: RegionDataType = {

type PostSearchFilterAreaType = {
setIsOpenAreaFilter: React.Dispatch<React.SetStateAction<boolean>>;
filterList: PostSearchFilterItemType[];
setFilterList: React.Dispatch<
React.SetStateAction<PostSearchFilterItemType[]>
>;
filterList: PostSearchFilterItemType;
setFilterList: React.Dispatch<React.SetStateAction<PostSearchFilterItemType>>;
};

const PostSearchFilterArea = ({
setIsOpenAreaFilter,
filterList,
setFilterList,
}: PostSearchFilterAreaType) => {
const [currentRegion, setCurrentRegion] = useState<(string | null)[]>([
null,
null,
null,
]);
// TODO: 전체 옵션인 경우 region3 선택 안해도 가능하도록 조건 추가하기
const [currentRegion1, setCurrentRegion1] = useState<string[]>([]);
const [currentRegion2, setCurrentRegion2] = useState<string[]>([]);
const [currentRegion3, setCurrentRegion3] = useState<string[]>([]);

const [region1Depth, setRegion1Depth] = useState<string | null>(null);
const [region2Depth, setRegion2Depth] = useState<string | null>(null);
Expand All @@ -54,22 +51,13 @@ const PostSearchFilterArea = ({
const [region3DepthData, setRegion3DepthData] = useState<string[]>([]);

useEffect(() => {
const region1Depth = filterList.find(
(value) => value.category === FILTER_CATEGORY.REGION_1DEPTH,
);

const region2Depth = filterList.find(
(value) => value.category === FILTER_CATEGORY.REGION_2DEPTH,
);
const region3Depth = filterList.find(
(value) => value.category === FILTER_CATEGORY.REGION_3DEPTH,
);
const region1Depth = filterList[FILTER_CATEGORY.REGION_1DEPTH];
const region2Depth = filterList[FILTER_CATEGORY.REGION_2DEPTH];
const region3Depth = filterList[FILTER_CATEGORY.REGION_3DEPTH];

setCurrentRegion([
region1Depth?.value ?? null,
region2Depth?.value ?? null,
region3Depth?.value ?? null,
]);
setCurrentRegion1(region1Depth ?? []);
setCurrentRegion2(region2Depth ?? []);
setCurrentRegion3(region3Depth ?? []);
}, [filterList]);

const onClickBackButton = () => {
Expand Down Expand Up @@ -106,29 +94,72 @@ const PostSearchFilterArea = ({
const onSelectRegion3Depth = (region: string) => {
if (!region1Depth || !region2Depth) return;
setRegion3Depth(region);
setCurrentRegion([region1Depth, region2Depth, region]);

if (currentRegion1.length === 3) {
alert('지역은 3개까지만 선택할 수 있습니다');
return;
}

if (isExistedFilter(region1Depth, region2Depth, region)) {
alert('이미 선택된 지역입니다.');
return;
}

setCurrentRegion1([...currentRegion1, region1Depth]);
setCurrentRegion2([...currentRegion2, region2Depth]);
setCurrentRegion3([...currentRegion3, region]);
};

const onClickSubmit = () => {
const resetRegionFilterList = filterList.filter(
(value) => !value.category.includes('Region'),
// 중복 선택 검사하기
const isExistedFilter = (
region1Depth: string,
region2Depth: string,
region: string,
) => {
const isSameRegion1 = currentRegion1.find(
(value) => value === region1Depth,
);
const region1 = {
category: FILTER_CATEGORY.REGION_1DEPTH,
value: currentRegion[0],
};
const region2 = {
category: FILTER_CATEGORY.REGION_2DEPTH,
value: currentRegion[1],
};
const region3 = {
category: FILTER_CATEGORY.REGION_3DEPTH,
value: currentRegion[2],
const isSameRegion2 = currentRegion2.find(
(value) => value === region2Depth,
);
const isSameRegion3 = currentRegion3.find((value) => value === region);

if (isSameRegion1 && isSameRegion2 && isSameRegion3) return true;
return false;
};

const onClickSubmit = () => {
const updatedFilterList = {
...filterList,
[FILTER_CATEGORY.REGION_1DEPTH]: [...currentRegion1],
[FILTER_CATEGORY.REGION_2DEPTH]: [...currentRegion2],
[FILTER_CATEGORY.REGION_3DEPTH]: [...currentRegion3],
};
setFilterList([...resetRegionFilterList, region1, region2, region3]);
setFilterList(updatedFilterList);
setIsOpenAreaFilter(false);
};

const onClickDelete = (regionIndex: number) => {
const newCurrentRegion1 = currentRegion1.filter(
(_value, index) => index !== regionIndex,
);
setCurrentRegion1(newCurrentRegion1);
const newCurrentRegion2 = currentRegion2.filter(
(_value, index) => index !== regionIndex,
);
setCurrentRegion2(newCurrentRegion2);
const newCurrentRegion3 = currentRegion3.filter(
(_value, index) => index !== regionIndex,
);
setCurrentRegion3(newCurrentRegion3);
};

const onClickReset = () => {
setCurrentRegion1([]);
setCurrentRegion2([]);
setCurrentRegion3([]);
};

return (
<>
<div className="min-h-screen flex flex-col">
Expand Down Expand Up @@ -157,8 +188,11 @@ const PostSearchFilterArea = ({
</section>
</div>
<PostSearchFilterBottomSheet
currentRegion={currentRegion}
setCurrentRegion={setCurrentRegion}
currentRegion1={currentRegion1}
currentRegion2={currentRegion2}
currentRegion3={currentRegion3}
onClickDelete={onClickDelete}
onClickReset={onClickReset}
onClickSubmit={onClickSubmit}
/>
</>
Expand Down
68 changes: 32 additions & 36 deletions src/components/PostSearchFilter/PostSearchFilterAreaInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,47 @@ import { FILTER_CATEGORY } from '@/constants/postSearch';

type PostSearchFilterAreaInputProps = {
setIsOpenAreaFilter: React.Dispatch<React.SetStateAction<boolean>>;
filterList: PostSearchFilterItemType[];
setFilterList: React.Dispatch<
React.SetStateAction<PostSearchFilterItemType[]>
>;
filterList: PostSearchFilterItemType;
setFilterList: React.Dispatch<React.SetStateAction<PostSearchFilterItemType>>;
};

const PostSearchFilterAreaInput = ({
setIsOpenAreaFilter,
filterList,
setFilterList,
}: PostSearchFilterAreaInputProps) => {
const [currentRegion, setCurrentRegion] = useState<(string | null)[]>([
null,
null,
null,
]);
const [region1Depth, setRegion1Depth] = useState<string[]>([]);
const [region2Depth, setRegion2Depth] = useState<string[]>([]);
const [region3Depth, setRegion3Depth] = useState<string[]>([]);

useEffect(() => {
const region1Depth = filterList.find(
(value) => value.category === FILTER_CATEGORY.REGION_1DEPTH,
);
const region1Depth = filterList[FILTER_CATEGORY.REGION_1DEPTH];
const region2Depth = filterList[FILTER_CATEGORY.REGION_2DEPTH];
const region3Depth = filterList[FILTER_CATEGORY.REGION_3DEPTH];

const region2Depth = filterList.find(
(value) => value.category === FILTER_CATEGORY.REGION_2DEPTH,
);
const region3Depth = filterList.find(
(value) => value.category === FILTER_CATEGORY.REGION_3DEPTH,
);

setCurrentRegion([
region1Depth?.value ?? null,
region2Depth?.value ?? null,
region3Depth?.value ?? null,
]);
setRegion1Depth(region1Depth ?? []);
setRegion2Depth(region2Depth ?? []);
setRegion3Depth(region3Depth ?? []);
}, [filterList]);

const formatRegionArrayToString = (region: (string | null)[]) => {
return `${region[0] ?? ''} ${region[1] ?? ''} ${region[2] ?? ''}`;
const formatRegionArrayToString = (index: number) => {
return `${region1Depth[index]} ${region2Depth[index]} ${region3Depth[index]}`;
};

const onClickDelete = () => {
setCurrentRegion([null, null, null]);
const resetRegionFilterList = filterList.filter(
(value) => !value.category.includes('Region'),
);
setFilterList([...resetRegionFilterList]);
const onClickDelete = (regionIndex: number) => {
const updatedFilterList = {
...filterList,
[FILTER_CATEGORY.REGION_1DEPTH]: region1Depth.filter(
(_value, index) => index !== regionIndex,
),
[FILTER_CATEGORY.REGION_2DEPTH]: region2Depth.filter(
(_value, index) => index !== regionIndex,
),
[FILTER_CATEGORY.REGION_3DEPTH]: region3Depth.filter(
(_value, index) => index !== regionIndex,
),
};
setFilterList(updatedFilterList);
};

return (
Expand All @@ -71,18 +66,19 @@ const PostSearchFilterAreaInput = ({
/>
</div>
<div className="flex flex-wrap gap-[0.5rem] px-[0.5rem] w-full">
{currentRegion[0] && (
{region1Depth.map((region, index) => (
<Tag
value={formatRegionArrayToString(currentRegion)}
key={`${region}_${index}`}
value={formatRegionArrayToString(index)}
padding="0.313rem 0.625rem 0.313rem 0.75rem"
isRounded={true}
hasCheckIcon={false}
backgroundColor={'#FEF387'}
color="#1E1926"
fontStyle="body-3"
onDelete={onClickDelete}
onDelete={() => onClickDelete(index)}
/>
)}
))}
</div>
</PostSearchFilterToggle>
);
Expand Down
35 changes: 19 additions & 16 deletions src/components/PostSearchFilter/PostSearchFilterBottomSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,24 @@ import Tag from '@/components/Common/Tag';
import { buttonTypeKeys } from '@/constants/components';

type PostSearchFilterBottomSheetType = {
currentRegion: (string | null)[];
setCurrentRegion: React.Dispatch<React.SetStateAction<(string | null)[]>>;
currentRegion1: string[];
currentRegion2: string[];
currentRegion3: string[];
onClickDelete: (index: number) => void;
onClickReset: () => void;
onClickSubmit: () => void;
};

const PostSearchFilterBottomSheet = ({
currentRegion,
setCurrentRegion,
currentRegion1,
currentRegion2,
currentRegion3,
onClickDelete,
onClickReset,
onClickSubmit,
}: PostSearchFilterBottomSheetType) => {
const onClickDelete = () => {
setCurrentRegion([null, null, null]);
};

const formatRegionArrayToString = (region: (string | null)[]) => {
return `${region[0] ?? ''} ${region[1] ?? ''} ${region[2] ?? ''}`;
const formatRegionArrayToString = (index: number) => {
return `${currentRegion1[index]} ${currentRegion2[index]} ${currentRegion3[index]}`;
};

return (
Expand All @@ -28,23 +30,24 @@ const PostSearchFilterBottomSheet = ({
isAvailableHidden={false}
isShowBottomsheet={true}
>
<div className="w-full flex flex-col gap-[1.5rem]">
<div className="w-full flex flex-col gap-[1.5rem] pb-[2rem]">
<h3 className="w-full px-[0.75rem] head-3 text-black">
Selected Areas
</h3>
<div className="w-full px-[0.5rem] flex flex-wrap gap-[0.5rem]">
{currentRegion[0] && (
{currentRegion1.map((region, index) => (
<Tag
value={formatRegionArrayToString(currentRegion)}
key={`${region}_${index}`}
value={formatRegionArrayToString(index)}
padding="0.313rem 0.625rem 0.313rem 0.75rem"
isRounded={true}
hasCheckIcon={false}
backgroundColor={'#FEF387'}
color="#1E1926"
fontStyle="body-3"
onDelete={onClickDelete}
onDelete={() => onClickDelete(index)}
/>
)}
))}
</div>
<div className="w-full flex justify-center items-center gap-[0.5rem]">
<Button
Expand All @@ -53,7 +56,7 @@ const PostSearchFilterBottomSheet = ({
fontColor="text-[#BDBDBD] button-1"
title="Reset"
isBorder={false}
onClick={onClickDelete}
onClick={onClickReset}
/>
<Button
type={buttonTypeKeys.CONTINUE}
Expand Down
19 changes: 15 additions & 4 deletions src/components/PostSearchFilter/PostSearchFilterButtons.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
import { buttonTypeKeys } from '@/constants/components';
import Button from '@/components/Common/Button';
import { PostSearchFilterItemType } from '@/types/PostSearchFilter/PostSearchFilterItem';
import { FILTER_CATEGORY } from '@/constants/postSearch';

type PostSearchFilterButtonsType = {
setFilterList: React.Dispatch<
React.SetStateAction<PostSearchFilterItemType[]>
>;
setFilterList: React.Dispatch<React.SetStateAction<PostSearchFilterItemType>>;
};

const PostSearchFilterButtons = ({
setFilterList,
}: PostSearchFilterButtonsType) => {
const onClickReset = () => {
setFilterList([]);
setFilterList({
[FILTER_CATEGORY.REGION_1DEPTH]: [],
[FILTER_CATEGORY.REGION_2DEPTH]: [],
[FILTER_CATEGORY.REGION_3DEPTH]: [],
[FILTER_CATEGORY.INDUSTRY]: [],
[FILTER_CATEGORY.WORK_PERIOD]: [],
[FILTER_CATEGORY.WORK_DAYS_PER_WEEK]: [],
[FILTER_CATEGORY.WORKING_DAY]: [],
[FILTER_CATEGORY.WORKING_HOURS]: [],
[FILTER_CATEGORY.RECRUITMENT_PERIOD]: [],
[FILTER_CATEGORY.EMPLOYMENT_TYPE]: [],
[FILTER_CATEGORY.VISA]: [],
});
};

return (
Expand Down
Loading

0 comments on commit ac82216

Please sign in to comment.