-
Notifications
You must be signed in to change notification settings - Fork 0
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
전체 모임 필터 작업 및 UI 수정 작업 (필터 모달 삭제) #997
Changes from 6 commits
8cf31f5
66ec434
b35c704
65b1ae5
1ecbb24
a46f145
159dd5a
dcf171e
5cab518
6fb0719
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -93,4 +93,4 @@ | |
"workspaces": [ | ||
"packages/*" | ||
] | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { ampli } from '@/ampli'; | ||
import { FilterType } from '@constants/option'; | ||
import { useQueryString } from '@hooks/queryString'; | ||
import { SelectV2 } from '@sopt-makers/ui'; | ||
import { useRouter } from 'next/router'; | ||
import React from 'react'; | ||
import { styled } from 'stitches.config'; | ||
|
||
interface DropDownFilterProps { | ||
filter: FilterType; | ||
} | ||
|
||
function DropDownFilter({ filter }: DropDownFilterProps) { | ||
const router = useRouter(); | ||
const selectedPartQuery = router.query.part as string; | ||
const defaultValue = selectedPartQuery ? { label: selectedPartQuery, value: selectedPartQuery } : undefined; | ||
|
||
const { subject, options } = filter; | ||
const { value: selectedValue, setValue, deleteKey } = useQueryString(subject); | ||
|
||
const setPartQuery = (value: string) => { | ||
ampli.clickFilterPart({ group_part: value }); | ||
|
||
if (selectedValue === value) return deleteKey(); | ||
return setValue(value); | ||
}; | ||
|
||
return ( | ||
<SDropDownContainer> | ||
<SelectV2.Root type="text" visibleOptions={6} defaultValue={defaultValue} onChange={setPartQuery}> | ||
<SelectV2.Trigger> | ||
<SelectV2.TriggerContent placeholder={'대상 파트'} /> | ||
</SelectV2.Trigger> | ||
<SelectV2.Menu> | ||
{options.map(option => ( | ||
<SelectV2.MenuItem key={option} option={{ label: option, value: option }} /> | ||
))} | ||
</SelectV2.Menu> | ||
</SelectV2.Root> | ||
</SDropDownContainer> | ||
); | ||
} | ||
|
||
export default DropDownFilter; | ||
|
||
const SDropDownContainer = styled('div', { | ||
ml: '$16', | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
import { ampli } from '@/ampli'; | ||
import { CATEGORY_FILTER, PART_FILTER, STATUS_FILTER } from '@constants/option'; | ||
import { useMediaQuery } from '@hooks/useMediaQuery'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 라이브러리 사용하고 있으니 직접 구현한 것을 사용할 필요가 없을 것 같다는 생각이 드는데 ..! 다른 의도가 있으신지 궁금합니다 :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 위에서 이유는 설명드렸으니 여기선 생략하겠습니당 |
||
import { Chip } from '@sopt-makers/ui'; | ||
import { styled } from 'stitches.config'; | ||
|
||
interface ChipItemProps { | ||
|
@@ -8,10 +10,17 @@ interface ChipItemProps { | |
isSelected: boolean; | ||
addValue: (val: string) => void; | ||
deleteValue: (val: string) => void; | ||
resetQuery: () => void; | ||
} | ||
|
||
function ChipItem({ label, value, isSelected, addValue, deleteValue }: ChipItemProps) { | ||
function ChipItem({ label, value, isSelected, addValue, deleteValue, resetQuery }: ChipItemProps) { | ||
const isTablet = useMediaQuery('(max-width: 768px)'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 우리 useDisplay 라는 커스텀 훅을 활용하고 있어!! :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 알려주셔서 감사합니다 !! 확인하고 반영하겠습니다 ~! |
||
const toggle = () => { | ||
if (value === '전체') { | ||
resetQuery(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 전체 클릭시 모든 파라미터를 reset 시키는 방식으로 한다면 다른 필터링 조건들도 함께 날아갈텐데 의도하신 부분이 맞을까요 ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 네 맞습니다 ! |
||
return; | ||
} | ||
|
||
switch (label) { | ||
case CATEGORY_FILTER.label: | ||
ampli.clickFilterCategory({ group_category: value }); | ||
|
@@ -28,9 +37,9 @@ function ChipItem({ label, value, isSelected, addValue, deleteValue }: ChipItemP | |
return addValue(value); | ||
}; | ||
return ( | ||
<SOption isSelected={isSelected} onClick={toggle}> | ||
<Chip size={isTablet ? 'sm' : 'md'} active={isSelected} onClick={toggle}> | ||
{value} | ||
</SOption> | ||
</Chip> | ||
); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,9 +2,10 @@ import { styled } from 'stitches.config'; | |
import { Flex } from '@components/util/layout/Flex'; | ||
import { useSearchParams } from '@hooks/queryString/custom'; | ||
import Search from './Search'; | ||
import Result from './Result'; | ||
import ArrowSmallRightIcon from '@assets/svg/arrow_small_right.svg'; | ||
import FilterModalOpenButton from './Modal/OpenButton'; | ||
import ArrowRightCircleIcon from '@assets/svg/arrow_right_circle.svg'; | ||
import Toggle from './Modal/Toggle'; | ||
import { PART_FILTER } from '@constants/option'; | ||
import DropDownFilter from './DropDown'; | ||
|
||
function Filter() { | ||
const { value: search } = useSearchParams(); | ||
|
@@ -13,8 +14,9 @@ function Filter() { | |
<> | ||
<Flex align="center" justify="between"> | ||
<Flex> | ||
<FilterModalOpenButton /> | ||
<Search /> | ||
<DropDownFilter filter={PART_FILTER} /> | ||
<Toggle /> | ||
</Flex> | ||
|
||
<SGuideButton | ||
|
@@ -23,13 +25,10 @@ function Filter() { | |
rel="noreferrer noopener" | ||
> | ||
모임 신청 가이드 | ||
<ArrowSmallRightIcon /> | ||
<ArrowRightCircleIcon /> | ||
</SGuideButton> | ||
</Flex> | ||
|
||
{/*필터 적용 결과 박스 (chip 모임)*/} | ||
<Result /> | ||
|
||
{!!search && <SearchResultMessage>"{search}"에 대한 검색결과입니다.</SearchResultMessage>} | ||
</> | ||
); | ||
|
@@ -38,13 +37,14 @@ function Filter() { | |
export default Filter; | ||
|
||
const SGuideButton = styled('a', { | ||
height: '$48', | ||
flexType: 'verticalCenter', | ||
gap: '$8', | ||
color: '$gray10', | ||
padding: '$18 $20', | ||
border: '1px solid $gray10', | ||
//border: '1px solid $gray10', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 주석 발견! 레거시가 되지 않도록 제거 부탁드립니당 |
||
borderRadius: '14px', | ||
fontAg: '18_medium_100', | ||
fontAg: '18_semibold_100', | ||
boxSizing: 'border-box', | ||
'@tablet': { | ||
padding: '$14 $12 $14 $16', | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,7 @@ export const APPROVAL_STATUS_KOREAN_TO_ENGLISH: StringKeyObject = { | |
거절: 'REJECT', | ||
}; | ||
export const APPLICATION_TYPE = ['신청', '초대']; | ||
export const CATEGORY_OPTIONS = ['번쩍', '스터디', '세미나', '행사']; | ||
export const CATEGORY_OPTIONS = ['전체', '스터디', '세미나', '행사', '번쩍']; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
번쩍 요소의 순서를 변경한 이유도 궁금합니당 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 좋은 의견 감사합니다! 확인해보니, 다른 부분들에서는 style 적용하는 용도로만 사용하고 있더라구요 ('스터디'일 경우 빨간 글씨가 나타나도록 함) 번쩍 요소의 순서는 기획 의도 상 번쩍 칩이 가장 오른쪽에 가길 원하셨고, 이미 구현되어 있는 로직에서는 CATEGORY_OPTIONS 을 순서대로 map 돌리면서 렌더링하고 있어서, 기존의 코드를 최대한 활용하기 위해 간단하게 '번쩍' 요소의 순서를 변경하는 방식으로 코드를 구현했습니다! |
||
export const PART_OPTIONS = ['기획', '디자인', 'Android', 'iOS', '웹', '서버']; | ||
export const PART_VALUES = ['PM', 'DESIGN', 'ANDROID', 'IOS', 'WEB', 'SERVER']; | ||
export const ACTION_STATUS = ['모집 전', '모집 중', '모집 마감', '활동 중', '활동 종료']; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저희가 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. react-responsive 라이브러리를 사용해서 만든 useDisplay라는 훅이 있는 걸 몰랐어요,, |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { useEffect, useState } from 'react'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. useDisplay 훅을 활용한다면 useMediaQuery 는 동일한 기능을 하는 훅인 것 같으니 삭제해줘도 괜찮겠다!! |
||
|
||
export function useMediaQuery(query: string) { | ||
const [matches, setMatches] = useState(false); | ||
|
||
useEffect(() => { | ||
const mediaQuery = window.matchMedia(query); | ||
setMatches(mediaQuery.matches); | ||
|
||
const handleChange = (event: MediaQueryListEvent) => { | ||
setMatches(event.matches); | ||
}; | ||
|
||
mediaQuery.addEventListener('change', handleChange); | ||
return () => mediaQuery.removeEventListener('change', handleChange); | ||
}, [query]); | ||
|
||
return matches; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mds chip 이 따로 있는데, mds chip 과 해당 chip 의 디자인이 동일한 게 맞을까요?? 보통의 경우엔 기존의 것이 legacy 이고 mds 컴포넌트로 교체해서요~!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아 저 Chips라는 부분이 내부적으로 만든 chip 컴포넌트를 사용하고 있었는데, 해당 chip 컴포넌트를 mds로 변경했어요!
그래서 칩들을 렌더링하는 컴포넌트인 Chips는 거의 그대로 재활용하는 방식으로 구현 진행했습니다 :)