Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

도시 검색 기능 특수문자 작성시 버그 수정 + 검색어와 매칭되는 제안도시가 하나일 시 엔터로 적용가능 #159

Merged
merged 9 commits into from
Jul 28, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const CitySearchBar = ({ initialCities, updateCityInfo, required = false }: City
const { cityTags, addCityTag, deleteCityTag } = useCityTags(initialCities ?? []);
const { isOpen: isSuggestionOpen, open: openSuggestion, close: closeSuggestion } = useOverlay();
const inputRef = useRef<HTMLInputElement>(null);
const debouncedQueryWord = useDebounce(queryWord, 300);
const debouncedQueryWord = useDebounce(queryWord, 150);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 300에서 150으로 바꾼 이유가 있나요??

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

쪼금 더 자연스러운 느낌이 들더라구요?! 개인마다 다르겠지만 검색결과 없다는 텍스트도 잘 안보이는 편이라 150~~


useEffect(() => {
updateCityInfo(cityTags);
Expand All @@ -44,6 +44,11 @@ const CitySearchBar = ({ initialCities, updateCityInfo, required = false }: City
};

const handleSuggestionClick = (selectedCity: CityData) => {
if (!selectedCity) {
closeSuggestion();
Dahyeeee marked this conversation as resolved.
Show resolved Hide resolved
return;
}

addCityTag(selectedCity);
resetAll();
};
Expand All @@ -64,7 +69,7 @@ const CitySearchBar = ({ initialCities, updateCityInfo, required = false }: City
};

const handleInputFocus = () => {
if (queryWord) {
if (debouncedQueryWord) {
openSuggestion();
}
};
Expand Down
44 changes: 25 additions & 19 deletions frontend/src/components/common/CitySuggestion/CitySuggestion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,34 +29,40 @@ const CitySuggestion = ({ queryWord, onItemSelect }: SuggestionProps) => {
const { scrollToFocusedItem } = useAutoScroll(listRef, itemRef);

useEffect(() => {
if (!queryWord) return;

setNewSuggestions(queryWord);
}, [queryWord]);

const handleItemClick = (city: CityData) => () => {
onItemSelect(city);
};

useEffect(() => {
scrollToFocusedItem();
}, [focusedSuggestionIndex]);

const handleItemClick = (city: CityData) => () => {
onItemSelect(city);
};

return (
<SuggestionList css={containerStyling} ref={listRef}>
{suggestions.length ? (
suggestions.map((city, index) => (
<SuggestionsItem
key={city.id}
onClick={handleItemClick(city)}
css={getItemStyling(isFocused(index))}
ref={isFocused(index) ? itemRef : null}
>
{city.name}
</SuggestionsItem>
))
) : (
<Text css={emptyTextStyling}>검색어에 해당하는 도시가 없습니다.</Text>
<>
{queryWord && (
Dahyeeee marked this conversation as resolved.
Show resolved Hide resolved
<SuggestionList css={containerStyling} ref={listRef}>
{suggestions.length ? (
suggestions.map((city, index) => (
<SuggestionsItem
key={city.id}
onClick={handleItemClick(city)}
css={getItemStyling(isFocused(index))}
ref={isFocused(index) ? itemRef : null}
>
{city.name}
</SuggestionsItem>
))
) : (
<Text css={emptyTextStyling}>검색어에 해당하는 도시가 없습니다.</Text>
)}
</SuggestionList>
)}
</SuggestionList>
</>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ export const formStyling = css({
},
});

export const dateInputSupportingText = css({
wordBreak: 'keep-all',
});

export const titleStyling = css({
flexDirection: 'column',
width: '400px',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { useTripEditForm } from '@hooks/trip/useTripEditForm';
import CitySearchBar from '@components/common/CitySearchBar/CitySearchBar';
import DateInput from '@components/common/DateInput/DateInput';
import {
dateInputSupportingText,
formStyling,
textareaStyling,
titleStyling,
Expand Down Expand Up @@ -59,7 +60,7 @@ const TripInfoEditModal = ({ isOpen, onClose, ...information }: TripInfoEditModa
/>
<Flex styles={{ width: '400px', align: 'center', gap: '10px' }}>
<WarningIcon />
<SupportingText>
<SupportingText css={dateInputSupportingText}>
방문 기간을 단축하면 마지막 날짜부터 작성한 기록들이 삭제됩니다.
</SupportingText>
</Flex>
Expand Down
20 changes: 19 additions & 1 deletion frontend/src/hooks/common/useCitySuggestion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,22 @@ import type { CityData } from '@type/city';
import { useEffect, useState } from 'react';

import { makeRegexByCho } from '@utils/cityFilter';
import { stringToOnlyLetter } from '@utils/formatter';

export const useCitySuggestion = ({ onItemSelect }: { onItemSelect: (item: CityData) => void }) => {
const queryClient = useQueryClient();
const cityData = queryClient.getQueryData<CityData[]>(['city']);
const [suggestions, setSuggestions] = useState<CityData[]>([]);
const [focusedSuggestionIndex, setFocusedSuggestionIndex] = useState(-1);

useEffect(() => {
setFocusedSuggestionIndex(-1);
focusOnlySuggestion();
}, [suggestions]);

const setNewSuggestions = (word: string) => {
const regex = makeRegexByCho(word);
const query = stringToOnlyLetter(word);
const regex = makeRegexByCho(query);

if (cityData) {
const filteredSuggestions = cityData.filter(({ name }) => regex.test(name));
Expand All @@ -31,6 +38,12 @@ export const useCitySuggestion = ({ onItemSelect }: { onItemSelect: (item: CityD
);
};

const focusOnlySuggestion = () => {
if (suggestions.length === 1) {
setFocusedSuggestionIndex(0);
}
};

const isFocused = (index: number) => {
return index === focusedSuggestionIndex;
};
Expand All @@ -49,6 +62,11 @@ export const useCitySuggestion = ({ onItemSelect }: { onItemSelect: (item: CityD
onItemSelect(suggestions[focusedSuggestionIndex]);
}
}

if (e.key === 'Escape') {
//이거 onClose 프롭스로 받기 싫어서 꼼수로 일단 구현함....
onItemSelect(suggestions[-1]);
Copy link
Collaborator

@ashleysyheo ashleysyheo Jul 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요정도 deps면 그냥 props 받아도 되지 않을까요.....?? props로 넘겨주는게 더 명확할 것 같아요

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ㅋㅋㅋㅋ그럴게요! 뭔가 저 함수 프롭스로 넘겨주는 거 안좋아해여 이유는 없음 ㅋㅋㅋ

}
};

useEffect(() => {
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/utils/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,15 @@ export const dateRangeToString = (dateRange: DateRangeData) => {

return `${formatDate(start)} - ${formatDate(end)}`;
};

export const stringToOnlyLetter = (string: string) => {
const koreanCharacterRegex = /^[A-Za-z가-힣ㄱ-ㅎ]+$/g;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아예 상수로 빼도 될지도?!


const matches = string.match(koreanCharacterRegex);

if (matches) {
return matches[0];
}

return '';
};