|
| 1 | +import { useState } from "react"; |
| 2 | + |
| 3 | +import { FilterBottomSheet } from "@/app/_shared/FilterBottomSheet"; |
| 4 | +import ChevronDownIcon from "@/assets/chevron-down.svg"; |
| 5 | +import { Chip } from "@/components/ui/Chip"; |
| 6 | +import { HStack } from "@/components/ui/Stack"; |
| 7 | + |
| 8 | +import * as styles from "./ChipFilter.css"; |
| 9 | +import { type FilterTabType } from "./chipFilter.types"; |
| 10 | +import { getChipDisplayText } from "./chipFilterUtils"; |
| 11 | +import { useChipFilter } from "./useChipFilter"; |
| 12 | + |
| 13 | +/** |
| 14 | + * ChipFilter 컴포넌트 |
| 15 | + * |
| 16 | + * @description |
| 17 | + * 지역, 분위기, 실용도 필터를 선택할 수 있는 Chip 버튼들을 제공합니다. |
| 18 | + * 각 Chip을 클릭하면 FilterBottomSheet가 열리고, 선택된 필터에 따라 Chip의 텍스트가 동적으로 변경됩니다. |
| 19 | + * |
| 20 | + * @features |
| 21 | + * - 3개의 필터 타입: 지역(location), 분위기(mood), 실용도(utility) |
| 22 | + * - 선택된 필터가 있으면 Chip이 활성화 상태로 표시 |
| 23 | + * - 선택된 필터 개수에 따라 "외 N개" 형태로 표시 |
| 24 | + * - FilterBottomSheet와 연동하여 필터 선택 UI 제공 |
| 25 | + * |
| 26 | + */ |
| 27 | +export const ChipFilter = () => { |
| 28 | + const { selectedFilters, handleFilterApply } = useChipFilter(); |
| 29 | + const [isFilterOpen, setIsFilterOpen] = useState(false); |
| 30 | + const [activeTab, setActiveTab] = useState<FilterTabType>("location"); |
| 31 | + |
| 32 | + const handleChipClick = (tab: FilterTabType) => { |
| 33 | + setActiveTab(tab); |
| 34 | + setIsFilterOpen(true); |
| 35 | + }; |
| 36 | + |
| 37 | + const filterConfigs = [ |
| 38 | + { |
| 39 | + type: "location" as const, |
| 40 | + getActiveState: () => selectedFilters.locations.length > 0, |
| 41 | + }, |
| 42 | + { |
| 43 | + type: "mood" as const, |
| 44 | + getActiveState: () => selectedFilters.atmosphereTags.length > 0, |
| 45 | + }, |
| 46 | + { |
| 47 | + type: "utility" as const, |
| 48 | + getActiveState: () => selectedFilters.utilityTags.length > 0, |
| 49 | + }, |
| 50 | + ]; |
| 51 | + |
| 52 | + return ( |
| 53 | + <> |
| 54 | + <HStack gap={8} className={styles.container}> |
| 55 | + {filterConfigs.map(({ type, getActiveState }) => ( |
| 56 | + <Chip |
| 57 | + key={type} |
| 58 | + active={getActiveState()} |
| 59 | + onClick={() => handleChipClick(type)} |
| 60 | + > |
| 61 | + {getChipDisplayText(type, selectedFilters)} |
| 62 | + <ChevronDownIcon width={16} height={16} /> |
| 63 | + </Chip> |
| 64 | + ))} |
| 65 | + </HStack> |
| 66 | + |
| 67 | + <FilterBottomSheet |
| 68 | + open={isFilterOpen} |
| 69 | + onOpenChange={setIsFilterOpen} |
| 70 | + onApply={handleFilterApply} |
| 71 | + defaultTab={activeTab} |
| 72 | + defaultValues={selectedFilters} |
| 73 | + /> |
| 74 | + </> |
| 75 | + ); |
| 76 | +}; |
0 commit comments