Skip to content

Commit

Permalink
[feat] filter 적용 추가 및 filter 다이얼로그의 input 앞에 통화 붙이는 작업 중
Browse files Browse the repository at this point in the history
  • Loading branch information
zestlee1106 committed Oct 19, 2023
1 parent ce85346 commit 99e1802
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 79 deletions.
52 changes: 48 additions & 4 deletions components/Filter/Filter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ export default function Filter({
const { register, handleSubmit, watch, reset } = useForm({ mode: 'onChange' });
const [selectedLocations, setSelectedLocations] = useState<GuDong[]>([]);
const [count, setCount] = useState(0);
const [searchParams, setSearchParams] = useState({});

const onSubmit: SubmitHandler<FieldValues> = (data) => {
getChildData(data);
const onSubmit: SubmitHandler<FieldValues> = () => {
getChildData(searchParams);
closeModal();
};

Expand Down Expand Up @@ -123,6 +124,24 @@ export default function Filter({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [dong]);

const [housingChecked, setHousingChecked] = useState<string[]>([]);
const handleHousingCheck = (value: string, isChecked: boolean) => {
if (isChecked) {
setHousingChecked((prev) => [...prev, value]);
} else {
setHousingChecked((prev) => prev.filter((item) => item !== value));
}
};

const [furnishingChecked, setFurnishingChecked] = useState<(string | number)[]>([]);
const handleFurnishingCheck = (value: string | number, isChecked: boolean) => {
if (isChecked) {
setFurnishingChecked((prev) => [...prev, value]);
} else {
setFurnishingChecked((prev) => prev.filter((item) => item !== value));
}
};

const minDeposit = watch('depositMin');
const maxDeposit = watch('depositMax');
const minMonthlyRent = watch('monthMin');
Expand All @@ -138,18 +157,32 @@ export default function Filter({
!maxDeposit &&
!minMonthlyRent &&
!maxMonthlyRent &&
!dateAvailable
!dateAvailable &&
!housingChecked.length &&
!furnishingChecked.length
) {
return;
}

const fetchData = async () => {
setSearchParams({
locationIds: formattedSelectedLocation.join(', '),
minDeposit,
maxDeposit,
minMonthlyRent,
maxMonthlyRent,
types: housingChecked.join(', '),
furnishingTypes: furnishingChecked.join(', '),
...(dateAvailable ? { availableDate: formatDateForAPI(dateAvailable) } : {}),
});
const data = await getRooms({
locationIds: formattedSelectedLocation.join(', '),
minDeposit,
maxDeposit,
minMonthlyRent,
maxMonthlyRent,
types: housingChecked.join(', '),
furnishingTypes: furnishingChecked.join(', '),
...(dateAvailable ? { availableDate: formatDateForAPI(dateAvailable) } : {}),
});
if (data) {
Expand All @@ -158,7 +191,16 @@ export default function Filter({
};

fetchData();
}, [selectedLocations, minDeposit, maxDeposit, minMonthlyRent, maxMonthlyRent, dateAvailable]);
}, [
selectedLocations,
minDeposit,
maxDeposit,
minMonthlyRent,
maxMonthlyRent,
dateAvailable,
housingChecked,
furnishingChecked,
]);

return (
<form onSubmit={handleSubmit(onSubmit)}>
Expand Down Expand Up @@ -269,6 +311,7 @@ export default function Filter({
label={item.label}
register={register(item.value)}
checked={watch(item.value)}
onChange={(e) => handleHousingCheck(item.value, e)}
key={item.value}
/>
);
Expand All @@ -289,6 +332,7 @@ export default function Filter({
type="outlined"
label={item.label}
register={register(`furnishing-${item.value}`)}
onChange={(e) => handleFurnishingCheck(item.value, e)}
key={item.value}
/>
);
Expand Down
8 changes: 8 additions & 0 deletions components/Input/Input.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
}
}

.input::before {
content: '$';
position: absolute;
left: 10px; /* 원하는 위치로 조절 */
top: 50%; /* 수직 가운데 정렬 */
transform: translateY(-50%);
}

.eye {
@apply w-[24px] h-[24px];
}
Expand Down
3 changes: 2 additions & 1 deletion components/Input/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ interface InputProps {
error?: FieldError;
maxLength?: number;
disabled?: boolean;
fixedWord?: string;
}

function Input({ placeholder, register, type, error, maxLength, disabled }: InputProps) {
function Input({ placeholder, register, type, error, maxLength, disabled, fixedWord }: InputProps) {
const hasError = error && error.message;
const [isPasswordShow, setIsPasswordShow] = useState(false);
const inputType = useMemo(() => {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"@storybook/testing-library": "^0.1.0",
"@svgr/webpack": "5.5.0",
"@types/date-fns": "^2.6.0",
"@types/lodash-es": "^4.17.10",
"@types/next-auth": "^3.15.0",
"@types/node": "20.2.5",
"@types/react": "18.2.7",
Expand Down
114 changes: 40 additions & 74 deletions pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,108 +11,64 @@ import { FilterType } from '@/public/types/filter';
import useModal from '@/hooks/useModal.ts';
import { FieldValues } from 'react-hook-form';
import Filter from '@/components/Filter/Filter.tsx';
import { useTranslation } from 'next-i18next';
import { getRooms } from '@/api/room';
import isEmpty from 'lodash-es/isEmpty';

type HomeProps = NextPage & {
getLayout: (page: React.ReactElement, ctx: NextPageContext) => React.ReactNode;
};

const FILTER_LABEL: Record<string, string> = {
locationIds: 'Location',
maxDeposit: 'Deposit',
maxMonthlyRent: 'Monthly rent',
availableDate: 'Date available',
types: 'Type of housing',
furnishingTypes: 'Furnishing',
};

function Home() {
const commonTranslation = useTranslation('common');
const [rooms, setRooms] = useState<RoomSearch[]>([]);
const [filters, setFilters] = useState<string[]>([]);
// const [selectedOptions, setSelectedOptions] = useState<string[]>([]);
const [clickedChip, setClickedChip] = useState('');
const router = useRouter();
const { openModal, closeModal } = useModal();
const [page, setPage] = useState(0);
const [totalElements, setTotalElements] = useState(0);
const [searchParams, setSearchParams] = useState<Record<string, string>>({});

// TODO: 전체 페이지보다 크면 페이징 처리 안되도록 수정

const selectRooms = async () => {
try {
const data = await getRooms({ page });
const data = await getRooms({
...searchParams,
page,
});
setRooms(data?.content || []);
setTotalElements(data?.totalElements || 0);
} catch (error) {
console.error(error);
}
};

const makeFilters = (filterParams: FilterType) => {
const makeFilters = (filterParams: Record<string, string>) => {
const resultFilter: string[] = [];
Object.keys(filterParams).forEach((key) => {
// eslint-disable-next-line no-unused-expressions
filterParams[`${key}`] && resultFilter.push(commonTranslation.t(`${key}`));
if (!isEmpty(filterParams[key])) {
resultFilter.push(FILTER_LABEL[key]);
}
});
setFilters(() => [...resultFilter]);
};

const target = useRef(null);

const makeSubmitParam = (data: FieldValues): FilterType => {
const typeOfHousings = ['studioChecked', 'bedFlatsChecked', 'shareHouseChecked'];
const furnishings = [
'bedChecked',
'inductionChecked',
'airconditionerChecked',
'stoveChecked',
'refregeratorChecked',
'wardrobeChecked',
'washingMachineChecked',
'doorLockChecked',
'tvChecked',
'kitchenetteChecked',
'heaterChecked',
];

let typeOfHousing = false;
let furnishing = false;
let monthRent = false;
let deposit = false;
let location = false;
let dateAvailable = false;

// typeOfHousing 중 하나라도 체크되면 true
typeOfHousings.forEach((key) => {
if (data[`${key}`]) {
typeOfHousing = true;
}
});

// furnishing 중 하나라도 체크되면 true
furnishings.forEach((key) => {
if (data[`${key}`]) {
furnishing = true;
}
});

// monthRent 비용 체크
if ((data[`${'monthMax'}`] || '') !== '' || (data[`${'monthMin'}`] || '') !== '') {
monthRent = true;
}

// deposit 비용 체크
if ((data[`${'depositMax'}`] || '') !== '' || (data[`${'depositMin'}`] || '') !== '') {
deposit = true;
}

if ((data.gu || '') !== '') {
location = true;
}

if ((data.dateAvailable || '') !== '') {
dateAvailable = true;
}
return { typeOfHousing, furnishing, monthRent, deposit, location, dateAvailable };
};

const getChildData = async (childData: any) => {
const filteredChips = makeSubmitParam(childData);
makeFilters(filteredChips);
await selectRooms();
const getChildData = async (childData: Record<string, string>) => {
makeFilters(childData);
setPage(0);
setSearchParams(childData);
setRooms([]);
};

const openFilterPopup = () => {
Expand All @@ -133,7 +89,6 @@ function Home() {

const callback = async (entries: IntersectionObserverEntry[]) => {
const [{ isIntersecting }] = entries;
// target?.current?.innerText += '관측되었습니다';
if (isIntersecting) {
setPage((prev) => prev + 1);
}
Expand All @@ -145,12 +100,13 @@ function Home() {
}

const fetchData = async () => {
const data = await getRooms({ page });
const data = await getRooms({ ...searchParams, page });
setRooms((prevRooms) => [...prevRooms, ...(data?.content || [])]);
setTotalElements(data?.totalElements || 0);
};

fetchData();
}, [page]);
}, [page, searchParams]);

// 최초 접근 시 Room 정보 조회
useEffect(() => {
Expand Down Expand Up @@ -188,8 +144,19 @@ function Home() {
const resultFilters = filters.filter((item) => item !== option);
setFilters(() => [...resultFilters]);

const selectedOption = Object.keys(FILTER_LABEL).find((key) => {
return FILTER_LABEL[key] === option;
});
setPage(0);
setRooms([]);
setSearchParams((prev) => {
return {
...prev,
[selectedOption as string]: '',
};
});

// 선택된 칩이 없거나 클릭된 칩이 삭제된 칩인 경우에 맨 처음 칩을 clickedChip으로 설정
// if ((clickedChip || '' ) === '' || selectedOptions.length !== filters.length) {
if ((clickedChip || '') === '') {
setClickedChip(filters?.[0]);
}
Expand All @@ -204,9 +171,8 @@ function Home() {
style={{ alignSelf: 'flex-start' }}
/>
{filters.map((label, index) => {
console.log('label >>', label);
return (
<div style={{ marginLeft: index === 0 ? '4px' : '0', marginRight: '-4px' }}>
<div style={{ marginLeft: index === 0 ? '4px' : '0', marginRight: '-4px' }} key={index}>
<Chip
key={`${label}-${index}`}
label={label}
Expand Down
2 changes: 2 additions & 0 deletions public/types/room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,6 @@ export interface RoomSearchParams {
minMonthlyRent?: string;
maxMonthlyRent?: string;
availableDate?: string;
types?: string;
furnishingTypes?: string;
}
7 changes: 7 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3274,6 +3274,13 @@
resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz"
integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==

"@types/lodash-es@^4.17.10":
version "4.17.10"
resolved "https://registry.yarnpkg.com/@types/lodash-es/-/lodash-es-4.17.10.tgz#1b36a76ca9eda20c0263e19bbe1a3adb1b317707"
integrity sha512-YJP+w/2khSBwbUSFdGsSqmDvmnN3cCKoPOL7Zjle6s30ZtemkkqhjVfFqGwPN7ASil5VyjE2GtyU/yqYY6mC0A==
dependencies:
"@types/lodash" "*"

"@types/lodash.memoize@^4.1.7":
version "4.1.7"
resolved "https://registry.npmjs.org/@types/lodash.memoize/-/lodash.memoize-4.1.7.tgz"
Expand Down

0 comments on commit 99e1802

Please sign in to comment.