+
diff --git a/src/pages/CartPage/CartItem/CartItem.scss b/src/pages/CartPage/CartItem/CartItem.scss
index 6aee6db..723ade8 100644
--- a/src/pages/CartPage/CartItem/CartItem.scss
+++ b/src/pages/CartPage/CartItem/CartItem.scss
@@ -52,44 +52,32 @@
&__product-link {
display: flex;
- // flex-basis: 25%;
text-decoration: none;
-
- &--name {
- // flex-basis: 60%;
-
- @include on-mobile {
- // flex-basis: 45%
- }
- }
}
&__name {
@include body-text;
+
font-weight: 600;
transition: all $effect-duration;
&:hover {
text-decoration: underline;
}
- @include on-mobile {
- // flex-basis: 100%;
- }
}
&__count-buttons {
- // margin-right: 40px;
width: 96px;
height: 32px;
display: grid;
justify-content: space-between;
align-items: center;
- // gap: 14px;
flex-direction: column;
grid-template-columns: 1fr 32px 1fr;
justify-items: center;
+
@include body-text;
- }
+ }
&__button {
min-width: 32px;
@@ -113,10 +101,9 @@
justify-content: space-between;
align-items: center;
gap: 16px;
+
@include on-mobile {
width: 100%;
- // gap: 16px;
- // justify-content: space-between;
}
}
.gadget {
@@ -127,8 +114,8 @@
justify-content: flex-start;
align-items: center;
gap: 24px;
+
@include on-mobile {
- // width: 100%;
gap: 16px;
}
}
diff --git a/src/pages/EmptyCart/EmptyCart.scss b/src/pages/EmptyCart/EmptyCart.scss
index 302149c..e3276b2 100644
--- a/src/pages/EmptyCart/EmptyCart.scss
+++ b/src/pages/EmptyCart/EmptyCart.scss
@@ -23,7 +23,7 @@
&__image-wrapper {
display: flex;
justify-content: center;
- height: 300px;
+ height: 250px;
margin-block: 32px;
}
diff --git a/src/pages/EmptyFav/EmptyFav.scss b/src/pages/EmptyFav/EmptyFav.scss
index 06e3af9..71438d1 100644
--- a/src/pages/EmptyFav/EmptyFav.scss
+++ b/src/pages/EmptyFav/EmptyFav.scss
@@ -23,7 +23,7 @@
&__image-wrapper {
display: flex;
justify-content: center;
- height: 300px;
+ height: 250px;
margin-block: 32px;
}
diff --git a/src/pages/ProductsPage/DropDown/DropDown.scss b/src/pages/ProductsPage/DropDown/DropDown.scss
index 915a0f9..31a890e 100644
--- a/src/pages/ProductsPage/DropDown/DropDown.scss
+++ b/src/pages/ProductsPage/DropDown/DropDown.scss
@@ -21,28 +21,33 @@
align-items: center;
justify-content: space-between;
height: 40px;
- border: 1px solid #b4bdc3;
+ background-color: var(--dropdown-mainbutton-bg-color);
+ border: 1px solid var(--dropdown-mainbutton-border-color);
@include buttons-text;
&:hover {
- border: 1px solid #89939a;
+ border-color: var(--dropdown-mainbutton-border-hover);
}
&--active {
- border: 1px solid #313237;
+ border-color: var(--dropdown-mainbutton-border-focused);
+
+ &:hover {
+ border-color: var(--dropdown-mainbutton-border-focused);
+ }
}
}
&__bottom {
min-width: 100%;
- background-color: #fff;
+ background-color: var(--page-bg-color);
position: absolute;
top: 44px;
padding-block: 8px;
display: flex;
flex-direction: column;
- border: 1px solid #e2e6e9;
+ border: 1px solid var(--dropdown-options-border-color);
box-shadow: 0px 2px 15px 0px #0000000d;
opacity: 0;
transform: translateY(-5);
@@ -53,6 +58,7 @@
transform $effect-duration;
&--active {
+ z-index: 1;
opacity: 1;
transform: translateY(0);
pointer-events: all;
@@ -67,8 +73,8 @@
color: var(--color-secondary);
&:hover {
- background: #fafbfc;
- color: var(--dropdown-hover-color);
+ background: var(--dropdown-option-hover-color);
+ color: var(--color-primary);
}
}
}
diff --git a/src/pages/ProductsPage/Pagination/Pagination.scss b/src/pages/ProductsPage/Pagination/Pagination.scss
index dd7bebb..da7de6e 100644
--- a/src/pages/ProductsPage/Pagination/Pagination.scss
+++ b/src/pages/ProductsPage/Pagination/Pagination.scss
@@ -18,8 +18,9 @@ $pageItem-size: 32px;
padding-left: 8px;
}
- &--hidden {
- visibility: hidden;
+ &--disabled {
+ pointer-events: none;
+ filter: opacity(0.5);
}
&--plug {
@@ -36,8 +37,8 @@ $pageItem-size: 32px;
justify-content: center;
padding: 0;
border: none;
- background: none;
- border: 1px solid var(--color-elements);
+ background-color: var( --pagin-number-bg-color);
+ border: 1px solid var(--pagin-number-border);
box-sizing: border-box;
height: $pageItem-size;
width: $pageItem-size;
@@ -49,13 +50,14 @@ $pageItem-size: 32px;
@include hover(border-color, var(--color-secondary));
&--active {
- background: var(--color-primary);
- border-color: var(--color-primary);
- color: #fff;
+ background: var(--pagin-number-bg-active);
+ border-color: var(--pagin-number-border-active);
+ color: var(--pagin-number-text-color-active);
}
&--arrow {
- border: 1px solid #b4bdc3;
+ background-color: var(--pagin-button-bg);
+ border: 1px solid var(--pagin-button-border);
}
}
diff --git a/src/pages/ProductsPage/Pagination/Pagination.tsx b/src/pages/ProductsPage/Pagination/Pagination.tsx
index 4676193..ef78f76 100644
--- a/src/pages/ProductsPage/Pagination/Pagination.tsx
+++ b/src/pages/ProductsPage/Pagination/Pagination.tsx
@@ -9,92 +9,42 @@ interface Props {
onPageChange: (value: number) => void;
}
-const getPaginationNumbers = (currentPage: number, lastPage: number) => {
- const maxLength = 7;
- const res: Array
= [];
+function paginate(currentPage: number, lastPage: number) {
+ let startPage, endPage;
+ const MAX_LENGTH = 5;
- if (lastPage <= maxLength) {
- for (let i = 1; i <= lastPage; i++) {
- res.push(i);
- }
+ if (lastPage <= MAX_LENGTH) {
+ startPage = 1;
+ endPage = lastPage;
} else {
- const firstPage = 1;
- const confirmedPagesCount = 3;
- const deductedMaxLength = maxLength - confirmedPagesCount;
- const sideLength = deductedMaxLength / 2;
-
- if (
- currentPage - firstPage < sideLength ||
- lastPage - currentPage < sideLength
- ) {
- for (let j = 1; j <= sideLength + firstPage; j++) {
- res.push(j);
- }
-
- res.push(NaN);
-
- for (let k = lastPage - sideLength; k <= lastPage; k++) {
- res.push(k);
- }
- } else if (
- currentPage - firstPage >= deductedMaxLength &&
- lastPage - currentPage >= deductedMaxLength
- ) {
- const deductedSideLength = sideLength - 1;
-
- res.push(1);
- res.push(NaN);
-
- for (
- let l = currentPage - deductedSideLength;
- l <= currentPage + deductedSideLength;
- l++
- ) {
- res.push(l);
- }
-
- res.push(NaN);
- res.push(lastPage);
-
+ if (currentPage <= 3) {
+ startPage = 1;
+ endPage = 5;
+ } else if (currentPage + 2 >= lastPage) {
+ startPage = lastPage - 4;
+ endPage = lastPage;
} else {
- const isNearFirstPage = currentPage - firstPage < lastPage - currentPage;
- let remainingLength = maxLength;
-
- if (isNearFirstPage) {
- for (let m = 1; m <= currentPage + 1; m++) {
- res.push(m);
- remainingLength -= 1;
- }
-
- res.push(NaN);
- remainingLength -= 1;
- } else {
- for (let o = lastPage; o >= currentPage - 1; o--) {
- res.unshift(o);
- remainingLength -= 1;
- }
-
- res.unshift(NaN);
- remainingLength -= 1;
-
- for (let p = remainingLength; p >= 1; p--) {
- res.unshift(p);
- }
- }
+ startPage = currentPage - 2;
+ endPage = currentPage + 2;
}
}
- return res;
-};
+ const pages = [];
+ for (let i = startPage; i <= endPage; i++) {
+ pages.push(i);
+ }
+
+ return pages;
+}
export const Pagination: FC = ({
totalPages,
currentPage,
onPageChange,
}) => {
- const pagesNumbers = getPaginationNumbers(currentPage, totalPages);
- const prevPageButtonHidden = currentPage === 1;
- const nextPageButtonHidden =
+ const pagesNumbers = paginate(currentPage, totalPages);
+ const prevPageButtonDisabled = currentPage === 1;
+ const nextPageButtonDisabled =
currentPage === pagesNumbers[pagesNumbers.length - 1];
const isPageActive = (page: number) => page === currentPage;
@@ -107,12 +57,13 @@ export const Pagination: FC = ({
-
@@ -121,10 +72,13 @@ export const Pagination: FC = ({
{pagesNumbers.map((pageNumber, id) => {
if (isNaN(pageNumber)) {
return (
-
-
-
...
+ -
+
...
- )
+ );
}
return (
@@ -139,17 +93,18 @@ export const Pagination: FC = ({
{pageNumber}
- )
+ );
})}
-
diff --git a/src/pages/ProductsPage/ProductsPage.scss b/src/pages/ProductsPage/ProductsPage.scss
index 156ad8e..503fbaa 100644
--- a/src/pages/ProductsPage/ProductsPage.scss
+++ b/src/pages/ProductsPage/ProductsPage.scss
@@ -35,6 +35,17 @@
&__filters {
display: flex;
gap: 16px;
+ flex-wrap: wrap;
+
+ &-wrapper-r {
+ display: flex;
+ gap: 10px;
+ }
+
+ &-wrapper-l {
+ display: flex;
+ gap: 10px;
+ }
}
&__filter {
@@ -47,6 +58,25 @@
@include on-mobile {
width: 136px;
}
+
+ &--search {
+ display: flex;
+ align-items: end;
+ }
+
+ &-search-input {
+ height: 40px;
+
+ @include body-text;
+ padding-inline: 5px;
+ background-color: var(--page-bg-color);
+ color: var(--color-primary);
+ border: 1px solid #b4bdc3;
+
+ &:placeholder-shown {
+ @include small-text;
+ }
+ }
}
&__filter-label {
@@ -98,6 +128,25 @@
height: 50vh;
}
+ &__not-found {
+ padding-top: 20px;
+ height: 50vh;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ }
+
+ &__not-found-text {
+ @include h3;
+ margin-bottom: 30px;
+ }
+
+ &__not-found-img {
+ object-fit: contain;
+ overflow: hidden;
+ }
+
&__view-wrp {
display: flex;
align-items: end;
@@ -108,10 +157,19 @@
@include hover(border, 1px solid #89939a);
@include active(scale, 0.95);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 40px;
+ width: 40px;
+
height: 40px;
- color: var(--color-primary);
background-color: var(--page-bg-color);
border: 1px solid #b4bdc3;
cursor: pointer;
}
+ &__view-icon {
+ height: 32px;
+ width: 32px;
+ }
}
diff --git a/src/pages/ProductsPage/ProductsPage.tsx b/src/pages/ProductsPage/ProductsPage.tsx
index ea2dd6b..acd417b 100644
--- a/src/pages/ProductsPage/ProductsPage.tsx
+++ b/src/pages/ProductsPage/ProductsPage.tsx
@@ -1,5 +1,6 @@
import { FC, useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
+import cn from 'classnames';
import { service } from '../../services/getAllProducts';
@@ -55,6 +56,7 @@ export const ProductsPage: FC = ({ category }) => {
const sortBy = searchParams.get('sort') || 'newest';
const itemsPerPage = searchParams.get('perPage') || '16';
const currentPage = +(searchParams.get('page') || 1);
+ const searchQuery = searchParams.get('search') || '';
useEffect(() => {
setIsLoading(true);
@@ -68,7 +70,7 @@ export const ProductsPage: FC = ({ category }) => {
throw new Error('Something went wrong');
})
.finally(() => setIsLoading(false));
- }, [category, itemsPerPage, sortBy]);
+ }, [category]);
const handlePageChange = (value: number) => {
const params = new URLSearchParams(searchParams);
@@ -90,15 +92,29 @@ export const ProductsPage: FC = ({ category }) => {
setSearchParams(params);
};
+ const handleSearchChange = (event: React.ChangeEvent) => {
+ const params = new URLSearchParams(searchParams);
+ params.set('search', event.target.value.trimStart());
+ params.set('page', String(1));
+ setSearchParams(params);
+ };
+
+ const filteredProducts = products.filter(product =>
+ product.name
+ .toLowerCase()
+ .trim()
+ .includes(searchQuery.toLowerCase().trim()),
+ );
+ const sortedProducts = sortProducts(filteredProducts, sortBy);
+
const pagesExist = itemsPerPage === 'all';
const totalPages = pagesExist
? 0
- : Math.ceil(products.length / +itemsPerPage);
+ : Math.ceil(filteredProducts.length / +itemsPerPage);
const startIndex = currentPage === 1 ? 0 : +itemsPerPage * (currentPage - 1);
const endIndex = startIndex + +itemsPerPage;
- const sortedProducts = sortProducts(products, sortBy);
const visibleProducts = pagesExist
? sortedProducts
: sortedProducts.slice(startIndex, endIndex);
@@ -110,34 +126,52 @@ export const ProductsPage: FC = ({ category }) => {
{category}
-
{products.length} models
+
{filteredProducts.length} models
-
-
-
-
Items on page
-
+
-
-
+
+
+
+
+
+
+
@@ -148,7 +182,7 @@ export const ProductsPage: FC
= ({ category }) => {
)}
- {!isLoading && (
+ {!isLoading && !!visibleProducts.length && (
<>
>
)}
+
+ {!isLoading && !visibleProducts.length && (
+