From 8f3079801b309344a6904a4e8791ab71482bee9f Mon Sep 17 00:00:00 2001 From: "@jcarymuhammedow" Date: Sat, 2 May 2026 14:28:50 +0500 Subject: [PATCH] fixed some bugs --- src/app/api/brandsApi.js | 6 +- src/app/api/categories.js | 10 +- src/app/api/channelsApi.js | 6 +- src/app/api/collectionsApi.js | 6 +- src/components/Checkout/index.jsx | 4 +- src/components/Footer/index.jsx | 1 - .../HomeBrands/HomeBrands.module.scss | 49 ++------- src/components/HomeBrands/index.jsx | 102 ++++++++---------- .../ProductCard/ProductCard.module.scss | 18 +++- src/components/ProductCard/index.jsx | 2 +- src/pages/Category/CategoryPage.module.scss | 42 ++++++++ src/pages/Category/hooks/useCategoryData.js | 21 +++- .../Category/hooks/useCategoryProducts.js | 2 +- src/pages/Category/index.jsx | 40 +++++-- .../ProductDetail/ProductPage.module.scss | 7 +- src/pages/ProductDetail/index.jsx | 77 ++++++++++++- src/pages/Stores/index.jsx | 8 +- 17 files changed, 254 insertions(+), 147 deletions(-) diff --git a/src/app/api/brandsApi.js b/src/app/api/brandsApi.js index 1ab6866..3e7ebd2 100644 --- a/src/app/api/brandsApi.js +++ b/src/app/api/brandsApi.js @@ -7,7 +7,7 @@ export const brandsApi = baseApi.injectEndpoints({ const queryParams = new URLSearchParams(); if (params.type) queryParams.append("type", params.type); if (params.page) queryParams.append("page", params.page); - if (params.limit) queryParams.append("limit", params.limit); + if (params.perPage) queryParams.append("perPage", params.perPage); const queryString = queryParams.toString(); return `/brands${queryString ? `?${queryString}` : ""}`; }, @@ -25,10 +25,10 @@ export const brandsApi = baseApi.injectEndpoints({ return `/brands/${params}/products`; } - const { id, page = 1, limit = 24, sorting, min_price, max_price } = params; + const { id, page = 1, perPage = 12, sorting, min_price, max_price } = params; const urlParams = new URLSearchParams(); urlParams.append("page", page); - urlParams.append("limit", limit); + urlParams.append("perPage", perPage); if (sorting) urlParams.append("sorting", sorting); if (min_price) urlParams.append("min_price", min_price); if (max_price) urlParams.append("max_price", max_price); diff --git a/src/app/api/categories.js b/src/app/api/categories.js index 4cc07ba..74c4c51 100644 --- a/src/app/api/categories.js +++ b/src/app/api/categories.js @@ -7,10 +7,10 @@ export const categoriesApi = baseApi.injectEndpoints({ }), getCategoryProducts: builder.query({ - query: ({ categoryId, page = 1, limit = 24, brands, min_price, max_price, sorting }) => { + query: ({ categoryId, page = 1, perPage = 12, brands, min_price, max_price, sorting }) => { const params = new URLSearchParams(); params.append("page", page); - params.append("limit", limit); + params.append("perPage", perPage); if (brands) params.append("brands", brands); if (min_price) params.append("min_price", min_price); if (max_price) params.append("max_price", max_price); @@ -41,7 +41,7 @@ export const categoriesApi = baseApi.injectEndpoints({ getAllCategoryProductsPaginated: builder.query({ async queryFn( - { category, page = 1, limit = 24, brands, min_price, max_price, sorting }, + { category, page = 1, perPage = 12, brands, min_price, max_price, sorting }, _queryApi, _extraOptions, baseQuery @@ -58,7 +58,7 @@ export const categoriesApi = baseApi.injectEndpoints({ if (categoryIds.length === 1) { const params = new URLSearchParams(); params.append("page", page); - params.append("limit", limit); + params.append("perPage", perPage); if (brands) params.append("brands", brands); if (min_price) params.append("min_price", min_price); if (max_price) params.append("max_price", max_price); @@ -86,7 +86,7 @@ export const categoriesApi = baseApi.injectEndpoints({ const requests = categoryIds.map((categoryId) => { const params = new URLSearchParams(); params.append("page", page); - params.append("limit", limit); + params.append("perPage", perPage); if (brands) params.append("brands", brands); if (min_price) params.append("min_price", min_price); if (max_price) params.append("max_price", max_price); diff --git a/src/app/api/channelsApi.js b/src/app/api/channelsApi.js index b05ff41..2d9e519 100644 --- a/src/app/api/channelsApi.js +++ b/src/app/api/channelsApi.js @@ -8,14 +8,14 @@ export const channelsApi = baseApi.injectEndpoints({ const { channelId, page = 1, - limit = 24, + perPage = 24, min_price, max_price, sorting, } = params; const urlParams = new URLSearchParams(); urlParams.append("page", page); - urlParams.append("limit", limit); + urlParams.append("perPage", perPage); if (min_price) urlParams.append("min_price", min_price); if (max_price) urlParams.append("max_price", max_price); if (sorting) urlParams.append("sorting", sorting); @@ -31,7 +31,7 @@ export const channelsApi = baseApi.injectEndpoints({ query: (params = {}) => { const queryParams = new URLSearchParams(); if (params.page) queryParams.append("page", params.page); - if (params.limit) queryParams.append("limit", params.limit); + if (params.perPage) queryParams.append("perPage", params.perPage); if (params.search) queryParams.append("search", params.search); const queryString = queryParams.toString(); return `/channels${queryString ? `?${queryString}` : ""}`; diff --git a/src/app/api/collectionsApi.js b/src/app/api/collectionsApi.js index 9019aab..8f0f1e3 100644 --- a/src/app/api/collectionsApi.js +++ b/src/app/api/collectionsApi.js @@ -19,17 +19,17 @@ export const collectionsApi = baseApi.injectEndpoints({ }), checkCollectionHasProducts: builder.query({ - query: (collectionId) => `/collections/${collectionId}/products?limit=1`, + query: (collectionId) => `/collections/${collectionId}/products`, transformResponse: (response) => ({ hasProducts: response.data && response.data.length > 0, }), }), getCollectionProductsPaginated: builder.query({ - query: ({ collectionId, page = 1, limit = 24, brands, min_price, max_price, sorting }) => { + query: ({ collectionId, page = 1, perPage = 24, brands, min_price, max_price, sorting }) => { const params = new URLSearchParams(); params.append("page", page); - params.append("limit", limit); + params.append("perPage", perPage); if (brands) params.append("brands", brands); if (min_price) params.append("min_price", min_price); if (max_price) params.append("max_price", max_price); diff --git a/src/components/Checkout/index.jsx b/src/components/Checkout/index.jsx index bff0206..dcd733f 100644 --- a/src/components/Checkout/index.jsx +++ b/src/components/Checkout/index.jsx @@ -174,11 +174,11 @@ const Checkout = ({ } > {payment.name} - + {/* {payment.name === "Nagt" ? t("checkout.payment_in_cash_upon_delivery_of_the_order") : t("checkout.payment_by_card")} - + */} ))} diff --git a/src/components/Footer/index.jsx b/src/components/Footer/index.jsx index fe2c143..2e5fd2b 100644 --- a/src/components/Footer/index.jsx +++ b/src/components/Footer/index.jsx @@ -94,7 +94,6 @@ const Footer = () => { /> - Download APK diff --git a/src/components/HomeBrands/HomeBrands.module.scss b/src/components/HomeBrands/HomeBrands.module.scss index 71c05e9..146a8aa 100644 --- a/src/components/HomeBrands/HomeBrands.module.scss +++ b/src/components/HomeBrands/HomeBrands.module.scss @@ -7,23 +7,15 @@ } } -.brandsScroll { - display: flex; - gap: 12px; - overflow-x: auto; +.brandsSwiper { padding-bottom: 8px; - - /* Hide scrollbar for Webkit */ - &::-webkit-scrollbar { - display: none; - } - /* Hide scrollbar for Firefox, IE, Edge */ - -ms-overflow-style: none; - scrollbar-width: none; +} + +.brandSlide { + width: auto; } .brandCard { - flex: 0 0 auto; width: 122px; height: 50px; background: #ffffff; @@ -56,37 +48,8 @@ height: 100%; } -.allButton { - flex: 0 0 auto; - width: 122px; - height: 67.6px; - background: #ffffff; - border: 1px solid #e5e7eb; - border-radius: 8px; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - transition: all 0.2s ease; - gap: 4px; - color: #111827; - font-weight: 600; - font-size: 14px; - - &:hover { - box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); - transform: translateY(-1px); - color: #aaaaaa; - } - - svg { - font-size: 16px; - } -} - @media screen and (max-width: 768px) { - .brandCard, .allButton { + .brandCard { width: 100px; - // height: 79.2px; } } diff --git a/src/components/HomeBrands/index.jsx b/src/components/HomeBrands/index.jsx index b7ff7d2..427a9d5 100644 --- a/src/components/HomeBrands/index.jsx +++ b/src/components/HomeBrands/index.jsx @@ -1,77 +1,67 @@ -import React, { useMemo } from 'react'; +import React from 'react'; import { useNavigate } from 'react-router-dom'; -import { useTranslation } from 'react-i18next'; import { useGetBrandsQuery } from '../../app/api/brandsApi'; +import { Swiper, SwiperSlide } from 'swiper/react'; +import { Autoplay } from 'swiper/modules'; +import 'swiper/css'; import styles from './HomeBrands.module.scss'; import { Logo } from '../Icons'; -import { IoIosArrowForward } from 'react-icons/io'; const HomeBrands = () => { - const { t, i18n } = useTranslation(); const navigate = useNavigate(); - // We fetch a larger amount so we have enough to shuffle. - const { data: brandsData, isLoading } = useGetBrandsQuery({ limit: 50 }); - - const randomBrands = useMemo(() => { - if (!brandsData) return []; - // Create a shallow copy and shuffle it - const shuffled = [...brandsData].sort(() => 0.5 - Math.random()); - // Pick the first 9 brands - return shuffled.slice(0, 8); - }, [brandsData]); + // Fetch brands. + const { data: brandsData, isLoading } = useGetBrandsQuery({ limit: 100 }); if (isLoading || !brandsData || brandsData.length === 0) return null; - // "Еще" in ru, "Hemmesi" in tm, "More" in en - const getMoreText = () => { - const lang = i18n.language; - if (lang === 'ru') return 'Еще'; - if (lang === 'en') return 'More'; - return 'Hemmesi'; - }; - return (
-
- {randomBrands.map((brand) => ( -
navigate(`/brands/${brand.id}`)} - > - {brand.media?.[0]?.thumbnail || brand.media?.[0]?.images_800x800 || brand.logo ? ( - {brand.name} { - e.target.style.display = "none"; - e.target.nextSibling.style.display = "flex"; - }} - /> - ) : ( -
+ + {brandsData.map((brand) => ( + +
navigate(`/brands/${brand.id}`)} + > + {brand.media?.[0]?.thumbnail || brand.media?.[0]?.images_800x800 || brand.logo ? ( + {brand.name} { + e.target.style.display = "none"; + e.target.nextSibling.style.display = "flex"; + }} + /> + ) : ( +
+ +
+ )} +
- )} -
-
-
+
))} -
navigate('/brands')} - > - {getMoreText()} - -
-
+
); }; export default HomeBrands; + diff --git a/src/components/ProductCard/ProductCard.module.scss b/src/components/ProductCard/ProductCard.module.scss index 9a756b7..21bd7c3 100644 --- a/src/components/ProductCard/ProductCard.module.scss +++ b/src/components/ProductCard/ProductCard.module.scss @@ -72,8 +72,16 @@ font-weight: 600; color: #333; margin: 0; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; + height: 2.4em; + line-height: 1.2; + @media screen and (max-width: 426px) { font-size: 14px; + height: 2.8em; } } @@ -82,9 +90,15 @@ color: #666; line-height: 1.4; margin: 0; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; + height: 2.8em; @media screen and (max-width: 1023px) { font-size: 12px; + height: 2.8em; } } @@ -92,8 +106,8 @@ display: flex; align-items: center; gap: 0.5rem; - margin-top: 0.5rem; - margin: 0; + margin-top: auto; + margin-bottom: 0; justify-content: space-between; } diff --git a/src/components/ProductCard/index.jsx b/src/components/ProductCard/index.jsx index 2e8a2d1..e0ba4eb 100644 --- a/src/components/ProductCard/index.jsx +++ b/src/components/ProductCard/index.jsx @@ -37,7 +37,7 @@ const ProductCard = ({ onAddToCart, onToggleFavorite, isFavorite = false, - descriptionMaxLength = 85, + descriptionMaxLength = 120, }) => { const { t } = useTranslation(); const navigate = useNavigate(); diff --git a/src/pages/Category/CategoryPage.module.scss b/src/pages/Category/CategoryPage.module.scss index 84dfeba..d3a8eda 100644 --- a/src/pages/Category/CategoryPage.module.scss +++ b/src/pages/Category/CategoryPage.module.scss @@ -499,3 +499,45 @@ width: 85%; } } } + +.channelHeader { + display: flex; + align-items: center; + gap: 20px; + background: #fff; + padding: 20px; + border-radius: 12px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); + margin-bottom: 20px; + + .channelLogo { + width: 80px; + height: 80px; + border-radius: 50%; + object-fit: cover; + border: 1px solid #eee; + } + + .channelInfo { + h1 { + margin: 0; + font-size: 24px; + font-weight: 700; + color: #333; + } + } + + @media screen and (max-width: 768px) { + padding: 15px; + gap: 15px; + + .channelLogo { + width: 60px; + height: 60px; + } + + .channelInfo h1 { + font-size: 20px; + } + } +} diff --git a/src/pages/Category/hooks/useCategoryData.js b/src/pages/Category/hooks/useCategoryData.js index 58a759d..e58ac23 100644 --- a/src/pages/Category/hooks/useCategoryData.js +++ b/src/pages/Category/hooks/useCategoryData.js @@ -5,12 +5,13 @@ import { useGetFiltersQuery, useLazyGetFiltersQuery, } from "../../../app/api/filtersApi"; +import { useGetChannelsQuery } from "../../../app/api/channelsApi"; const useCategoryData = ({ categoryId, collectionId, brandId, - channelId, // EKLE + channelId, selectedFilterCategory, searchQuery, }) => { @@ -46,6 +47,19 @@ const useCategoryData = ({ skip: !collectionId, }); + const { + data: channelsListData, + isLoading: channelsLoading, + error: channelsError, + } = useGetChannelsQuery({ perPage: 100 }, { + skip: !channelId, + }); + + const channelData = useMemo(() => { + if (!channelId || !channelsListData?.data) return null; + return channelsListData.data.find(c => String(c.id) === String(channelId)); + }, [channelId, channelsListData]); + const isSubCategory = useMemo(() => { if (!categoriesData?.data || !categoryId) return false; @@ -94,8 +108,8 @@ const useCategoryData = ({ setSelectedCategory(category); }, [categoryId, categoriesData]); - const isLoading = filtersLoading || collectionLoading; - const hasError = filtersError || collectionError; + const isLoading = filtersLoading || collectionLoading || channelsLoading; + const hasError = filtersError || collectionError || channelsError; return { categoriesData, @@ -103,6 +117,7 @@ const useCategoryData = ({ isSubCategory, filtersData: activeFilters, collectionData, + channelData, isLoading, hasError, fetchFilters, diff --git a/src/pages/Category/hooks/useCategoryProducts.js b/src/pages/Category/hooks/useCategoryProducts.js index 8f5020c..50ce4a8 100644 --- a/src/pages/Category/hooks/useCategoryProducts.js +++ b/src/pages/Category/hooks/useCategoryProducts.js @@ -124,7 +124,7 @@ const useCategoryProducts = ({ const params = { page: snapshot.currentPage, - limit: 24, + perPage: 12, brands: snapshot.selectedFilterBrand || undefined, min_price: snapshot.minPrice || undefined, max_price: snapshot.maxPrice || undefined, diff --git a/src/pages/Category/index.jsx b/src/pages/Category/index.jsx index 55e2b69..30c529f 100644 --- a/src/pages/Category/index.jsx +++ b/src/pages/Category/index.jsx @@ -88,6 +88,7 @@ const CategoryPage = () => { isSubCategory, filtersData, collectionData, + channelData, isLoading: dataLoading, hasError: dataError, fetchFilters, @@ -373,18 +374,35 @@ const CategoryPage = () => { return (
- {(categoryId || filterState.selectedFilterCategory) && ( - - )} + {channelId && channelData ? ( +
+ {channelData.media?.[0]?.thumbnail && ( + {channelData.name} + )} +
+

{channelData.name}

+
+
+ ) : ( + <> + {(categoryId || filterState.selectedFilterCategory) && ( + + )} -

{pageTitle}

-

- {t("category.total")}: {totalItems} {t("category.items")} -

+

{pageTitle}

+

+ {t("category.total")}: {totalItems} {t("category.items")} +

+ + )}