diff --git a/apps/what-today/src/pages/main/index.tsx b/apps/what-today/src/pages/main/index.tsx index 2f7c4b50..848dd94f 100644 --- a/apps/what-today/src/pages/main/index.tsx +++ b/apps/what-today/src/pages/main/index.tsx @@ -26,7 +26,7 @@ import { type Activity, getActivities } from '@/apis/activities'; const MemoizedMainCard = React.memo(MainCard.Root); -// ✅ 화면 너비에 따른 카드 개수 +// ✅ 화면 너비에 따른 카드 개수 (모든 체험용) const getCount = () => { const w = window.innerWidth; if (w < 768) return 6; // 모바일 @@ -34,18 +34,31 @@ const getCount = () => { return 8; // 데스크탑 }; +// ✅ 인기 체험용 반응형 카드 개수 +const MOBILE_BREAK = 768; +const TABLET_BREAK = 1280; + +const getPopularPerPage = () => { + const w = window.innerWidth; + if (w < MOBILE_BREAK) return 4; // 모바일 + if (w < TABLET_BREAK) return 2; // 태블릿 + return 4; // 데스크탑 +}; + export default function MainPage() { const [currentPage, setCurrentPage] = useState(1); const [itemsPerPage, setItemsPerPage] = useState(() => getCount()); + const [popularPerPage, setPopularPerPage] = useState(() => getPopularPerPage()); const [searchKeyword, setSearchKeyword] = useState(''); const [sortOrder, setSortOrder] = useState<'latest' | 'asc' | 'desc'>('latest'); const [selectedValue, setSelectedValue] = useState(null); const [selectedCategory, setSelectedCategory] = useState(''); const navigate = useNavigate(); - // 반응형 카드 수 + // 반응형 카드 수 const handleResize = useCallback(() => { setItemsPerPage(getCount()); + setPopularPerPage(getPopularPerPage()); }, []); useEffect(() => { @@ -157,7 +170,7 @@ export default function MainPage() { return ( <>
-
+
{/* 인기 체험 */} @@ -166,7 +179,11 @@ export default function MainPage() { {isLoading ? ( ) : ( - navigate(`/activities/${id}`)} /> + navigate(`/activities/${id}`)} + /> )}
diff --git a/packages/design-system/src/components/Carousel/Carousel.tsx b/packages/design-system/src/components/Carousel/Carousel.tsx index 6e929c09..4933735f 100644 --- a/packages/design-system/src/components/Carousel/Carousel.tsx +++ b/packages/design-system/src/components/Carousel/Carousel.tsx @@ -16,71 +16,79 @@ export default function Carousel({ items, itemsPerPage, onClick }: Props -
- {/* 왼쪽 버튼 */} - + {/* 왼쪽 버튼 (absolute 배치) */} + - {/* 데스크탑/태블릿 캐러셀 */} -
- - {items.map((item, idx) => ( -
- onClick?.(item.id)} - > - - - -
- ))} -
-
- - {/* 모바일 캐러셀 */} -
+ - - {items.map((item) => ( - ( +
onClick?.(item.id)} + className={`box-border shrink-0 ${idx % itemsPerPage !== itemsPerPage - 1 ? 'pr-10' : ''}`} + style={{ width: `${itemWidthPercent}%` }} > - - - + onClick?.(item.id)} + > + + + +
))} -
+ +
- {/* 오른쪽 버튼 */} - + {/* 모바일 캐러셀 */} +
+ + {items.map((item) => ( + onClick?.(item.id)} + > + + + + ))}
+ + {/* 오른쪽 버튼 (absolute 배치) */} +
); } diff --git a/packages/design-system/src/components/Carousel/NavigationButton.tsx b/packages/design-system/src/components/Carousel/NavigationButton.tsx index b0eda6b8..ef1e4dd1 100644 --- a/packages/design-system/src/components/Carousel/NavigationButton.tsx +++ b/packages/design-system/src/components/Carousel/NavigationButton.tsx @@ -17,6 +17,11 @@ interface Props { * 버튼 비활성화 여부 */ disabled: boolean; + + /** + * 추가 클래스명 + */ + className?: string; } /** @@ -24,12 +29,12 @@ interface Props { * - 화면 너비가 md 이상일 때만 표시됩니다. * - 방향에 따라 왼쪽 또는 오른쪽 버튼을 렌더링합니다. */ -export default function NavigationButton({ direction, onClick, disabled }: Props) { +export default function NavigationButton({ direction, onClick, disabled, className = '' }: Props) { const marginClass = direction === 'left' ? '-mr-20' : '-ml-20'; return (