From 33214002f28080a7ad8234a96eb2d5e78ef8d687 Mon Sep 17 00:00:00 2001 From: Jelaletdin12 Date: Tue, 31 Mar 2026 22:04:17 +0500 Subject: [PATCH] updated category carousel ui --- .../CategoryCarousel/CategoryCarousel.jsx | 123 +++++++----------- .../Categorycarousel.module.scss | 66 +++++----- 2 files changed, 80 insertions(+), 109 deletions(-) diff --git a/src/components/CategoryCarousel/CategoryCarousel.jsx b/src/components/CategoryCarousel/CategoryCarousel.jsx index ea06cbd..82e4ce8 100644 --- a/src/components/CategoryCarousel/CategoryCarousel.jsx +++ b/src/components/CategoryCarousel/CategoryCarousel.jsx @@ -1,75 +1,40 @@ -import React, { useRef } from "react"; +import React from "react"; import { useNavigate } from "react-router-dom"; +import { Swiper, SwiperSlide } from "swiper/react"; +import { Navigation, FreeMode } from "swiper/modules"; import { useGetCategoriesQuery } from "../../app/api/categories.js"; import styles from "./CategoryCarousel.module.scss"; +import "swiper/css"; +import "swiper/css/navigation"; +import "swiper/css/free-mode"; + const CategoryCarousel = () => { const { data, isLoading } = useGetCategoriesQuery("tree"); - const scrollRef = useRef(null); const navigate = useNavigate(); - const isDragging = useRef(false); - const startX = useRef(0); - const scrollLeft = useRef(0); - const hasDragged = useRef(false); - const mainCategories = data?.data?.filter((cat) => cat.parent_id === null) ?? []; - const scroll = (dir) => { - if (!scrollRef.current) return; - scrollRef.current.scrollBy({ left: dir * 320, behavior: "smooth" }); - }; - - const onMouseDown = (e) => { - isDragging.current = true; - hasDragged.current = false; - startX.current = e.pageX - scrollRef.current.offsetLeft; - scrollLeft.current = scrollRef.current.scrollLeft; - scrollRef.current.style.cursor = "grabbing"; - }; - - const onMouseMove = (e) => { - if (!isDragging.current) return; - e.preventDefault(); - const x = e.pageX - scrollRef.current.offsetLeft; - const walk = x - startX.current; - if (Math.abs(walk) > 4) hasDragged.current = true; - scrollRef.current.scrollLeft = scrollLeft.current - walk; - }; - - const onMouseUp = () => { - isDragging.current = false; - if (scrollRef.current) scrollRef.current.style.cursor = "grab"; - }; - - const handleCardClick = (e, slug) => { - if (hasDragged.current) { - e.preventDefault(); - return; - } - navigate(`/category/${slug}`); + const handleCardClick = (id) => { + navigate(`/category/${id}`); }; if (isLoading || mainCategories.length === 0) return null; return (
- - -
{mainCategories.map((cat) => { const thumb = @@ -78,34 +43,34 @@ const CategoryCarousel = () => { null; return ( -
handleCardClick(e, cat.slug)} - > -
- {thumb ? ( - {cat.name} - ) : ( -
- )} + +
handleCardClick(cat.id)} + > +
+ {thumb ? ( + {cat.name} + ) : ( +
+ )} +
+ {cat.name}
- {cat.name} -
+
); })} -
+ - +
diff --git a/src/components/CategoryCarousel/Categorycarousel.module.scss b/src/components/CategoryCarousel/Categorycarousel.module.scss index 8e4b02f..70865a9 100644 --- a/src/components/CategoryCarousel/Categorycarousel.module.scss +++ b/src/components/CategoryCarousel/Categorycarousel.module.scss @@ -6,33 +6,27 @@ margin: 20px 0 24px 0; } -/* ── Scrollable track ── */ -.track { - display: flex; - gap: 12px; - overflow-x: auto; - scroll-snap-type: x mandatory; - -webkit-overflow-scrolling: touch; - scrollbar-width: none; - padding: 4px 2px 8px 2px; +/* ── Swiper overrides ── */ +.swiper { flex: 1; - cursor: grab; - user-select: none; + overflow: hidden; + padding: 4px 2px 8px 2px !important; - &::-webkit-scrollbar { - display: none; + :global(.swiper-button-disabled) { + opacity: 0.3; + pointer-events: none; } +} - &:active { - cursor: grabbing; - } +.slide { + width: 200px !important; + height: auto; } /* ── Card ── */ .card { - flex: 0 0 auto; - scroll-snap-align: start; - width: 180px; + width: 100%; + height: 100%; border-radius: 12px; background: #f5f5f5; overflow: hidden; @@ -44,6 +38,7 @@ &:hover { box-shadow: 0 6px 20px rgba(0, 0, 0, 0.1); transform: translateY(-2px); + border: 1px solid #d24141; .imgWrap img { transform: scale(1.04); @@ -54,9 +49,10 @@ /* ── Image area ── */ .imgWrap { width: 100%; - aspect-ratio: 1 / 1; + // aspect-ratio: 4 / 3; overflow: hidden; background: #ebebeb; + flex-shrink: 0; img { width: 100%; @@ -73,19 +69,25 @@ background: linear-gradient(135deg, #e0e0e0 0%, #d0d0d0 100%); } -/* ── Name label ── */ +/* ── Name label — sabit yükseklik ── */ .name { padding: 10px 12px 12px 12px; - font-size: 13px; - font-weight: 500; + font-size: 16px; + font-weight: 600; color: #222; text-align: center; line-height: 1.4; background: #fff; + /* 2 satır = 2 × 13px × 1.4 + padding = ~60px — tüm kartlar eşit */ + min-height: 60px; + display: flex; + align-items: center; + justify-content: center; } /* ── Arrow buttons ── */ .arrow { + position: absolute; flex: 0 0 auto; width: 32px; height: 32px; @@ -100,8 +102,7 @@ cursor: pointer; color: #444; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08); - transition: background 0.15s, border-color 0.15s, color 0.15s, - box-shadow 0.15s; + transition: background 0.15s, border-color 0.15s, color 0.15s, box-shadow 0.15s; padding: 0; z-index: 1; @@ -112,12 +113,13 @@ box-shadow: 0 2px 8px rgba(210, 65, 65, 0.35); } - &.left { + &.prev { margin-right: 4px; } - &.right { + &.next { margin-left: 4px; + right: 0; } } @@ -127,19 +129,23 @@ display: none; } - .card { - width: 140px; + .slide { + width: 140px !important; } } @media (max-width: 480px) { + .slide { + width: 120px !important; + } + .card { - width: 120px; border-radius: 10px; } .name { font-size: 12px; padding: 8px 8px 10px 8px; + min-height: 52px; } } \ No newline at end of file