Skip to content

Commit

Permalink
Merge pull request #103 from MargoMarm/feature/addInfScrollToExercise
Browse files Browse the repository at this point in the history
Feature/add inf scroll to exercise
  • Loading branch information
MargoMarm authored Sep 28, 2023
2 parents f9f5a44 + bffef71 commit e542821
Show file tree
Hide file tree
Showing 11 changed files with 161 additions and 111 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
"lodash.debounce": "^4.0.8",
"modern-normalize": "^2.0.0",
"notiflix": "^3.2.6",
"overlayscrollbars": "^2.3.1",
"overlayscrollbars-react": "^0.5.2",
"prop-types": "^15.8.1",
"react": "^18.2.0",
Expand Down
3 changes: 2 additions & 1 deletion src/components/ExercisesItemList/ExercisesItemList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ import 'swiper/css/navigation';
import 'swiper/css/pagination';
import 'swiper/css/scrollbar';
import { nanoid } from '@reduxjs/toolkit';
import { addSearchExerciseParams } from '../../redux/exercises/slice';

const ExercisesList = () => {
const dispatch = useDispatch();

const handleGetExercises = (params, name) => {
dispatch(getExercises(params));

dispatch(addSearchExerciseParams(params));
dispatch(setCurrentTitle(name));
};

Expand Down
18 changes: 3 additions & 15 deletions src/components/Scrollbar/Scrollbar.jsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,11 @@
import PropTypes from 'prop-types';
import { useMatchMedia } from '../../hooks/useMatchMedia';
import { useScrollbar } from '../../hooks/useScrollBar';
import { useRef } from 'react';

import { ScrollContainer } from './Scrollbar.syled';

export default function Scrollbar({ children, width }) {
const { isMobile } = useMatchMedia();
const ContainerWrapper = useRef(null);
const hasScroll = !isMobile;
useScrollbar(ContainerWrapper, hasScroll);

return (
<ScrollContainer width={width} ref={ContainerWrapper}>
{children}
</ScrollContainer>
);
export default function ScrollBar({ width, children }) {
return <ScrollContainer width={width}>{children}</ScrollContainer>;
}

Scrollbar.propTypes = {
ScrollBar.propTypes = {
width: PropTypes.object,
};
27 changes: 22 additions & 5 deletions src/components/Scrollbar/Scrollbar.syled.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@
import styled from '@emotion/styled';
import { mq } from '../../utils';
import { mq, colors } from '../../utils';

export const ScrollContainer = styled.div`
overflow: auto;
height: calc(100vh - 48px);
scrollbar-width: 0px;
width: ${({ width }) => width?.mob + 'px' || '100%'};
${mq.tablet} {
width: ${({ width }) => width?.nab + 'px' || '100%'};
width: ${({ width }) => width?.tab + 'px' || '100%'};
scrollbar-color: ${colors.orange} ${colors.textWhite01};
scrollbar-width: thin;
::-webkit-scrollbar {
width: 8px;
background-color: ${colors.textWhite01};
border-radius: 12px;
}
::-webkit-scrollbar-thumb {
background-color: ${colors.orange};
border-radius: 12px;
}
::-webkit-scrollbar-thumb:hover {
background-color: ${colors.orange};
}
}
${mq.desktop} {
width: ${({ width }) => width?.dt + 'px' || '100%'};
height: calc(100vh - 220px);
height: calc(100vh - 230px);
}
`;
27 changes: 0 additions & 27 deletions src/hooks/useScrollBar.js

This file was deleted.

80 changes: 56 additions & 24 deletions src/pages/Exercises/Exercises.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import InfiniteScroll from 'react-infinite-scroller';

import ExercisesItemList from '../../components/ExercisesItemList/ExercisesItemList';
import ExercisesCategories from '../../components/ExercisesCategories/ExercisesCategories';
import Title from '../../components/Title/Title';
Expand All @@ -10,27 +14,54 @@ import {

import ProductsOrExercisesContainer from '../../components/ProductOrExerciseContainer/ProductOrExerciseContainer';
import ProductsOrExercisesItem from '../../components/ProductsOrExercisesItem/ProductsOrExercisesItem';
import ScrollBar from '../../components/Scrollbar';
import ExercisesBtnBack from '../../components/ExercisesBtnBack/ExercisesBtnBack';
import Loader from '../../components/Lodaer/Loader';

import { useSelector } from 'react-redux';
import { selectGetFilters } from '../../redux/exercises/selectors';
import {
selectGetFilters,
selectHasMore,
selectSearchParams,
selectItems,
selectIsLoadingExercises,
} from '../../redux/exercises/selectors';

import {
selectCurrentTitle,
selectIsLoading,
} from '../../redux/exerciseFilters/selectors';
import { selectIsLoadingExercises } from '../../redux/exercises/selectors';
import { selectItems } from '../../redux/exercises/selectors';

import ExercisesBtnBack from '../../components/ExercisesBtnBack/ExercisesBtnBack';
import Scrollbar from '../../components/Scrollbar';
import Loader from '../../components/Lodaer/Loader';
import { getMoreExercises } from '../../redux/exercises/operations';

const Exercises = () => {
const [page, setPage] = useState(1);

let shouldGetFilters = useSelector(selectGetFilters);
let items = useSelector(selectItems);
let currentTitle = useSelector(selectCurrentTitle);
const isLoadingFilters = useSelector(selectIsLoading);
const isLoadingExercises = useSelector(selectIsLoadingExercises);
const dispatch = useDispatch();
const searchParams = useSelector(selectSearchParams);
const hasMore = useSelector(selectHasMore);

useEffect(() => {
setPage(1);
}, [searchParams]);

const onLoadMore = () => {
if (page === 1) {
setPage(prevPage => prevPage + 1);
return;
}
const paginationParams = new URLSearchParams({
page,
limit: 20,
}).toString();

dispatch(getMoreExercises(`${searchParams}&${paginationParams}`));
setPage(prevPage => prevPage + 1);
};

return (
<>
Expand Down Expand Up @@ -81,26 +112,27 @@ const Exercises = () => {
) : (
<ExercisesListContainer>
<BGImg />
{isLoadingExercises ? (
<Loader size={'60'} />
) : (
<Scrollbar width={{ dt: '868' }}>
<ScrollBar width={{ dt: '878' }}>
<InfiniteScroll
pageStart={0}
loadMore={onLoadMore}
hasMore={hasMore && !isLoadingExercises}
loader={<Loader key={'qwe258'} />}
useWindow={false}
>
<ProductsOrExercisesContainer>
{items.map((item, i) => {
if (i < 20) {
return (
<ProductsOrExercisesItem
key={item._id}
page="exercise"
data={item}
/>
);
}
return null;
{items.map(item => {
return (
<ProductsOrExercisesItem
key={item._id}
page="exercise"
data={item}
/>
);
})}
</ProductsOrExercisesContainer>
</Scrollbar>
)}
</InfiniteScroll>
</ScrollBar>
</ExercisesListContainer>
)}
</>
Expand Down
60 changes: 27 additions & 33 deletions src/pages/Products/Products.jsx
Original file line number Diff line number Diff line change
@@ -1,72 +1,66 @@
import { useDispatch, useSelector } from 'react-redux';
import { useEffect, useState } from 'react';
import InfiniteScroll from 'react-infinite-scroller';

import { FlexWrapper, ProductPageContainer } from './Products.styled';
import ProductsOrExercisesContainer from '../../components/ProductOrExerciseContainer/ProductOrExerciseContainer';
import Title from '../../components/Title/Title';
import ProductsFilter from '../../components/ProductsFilter/ProductsFilter';
import { FlexWrapper, ProductPageContainer } from './Products.styled';
import Scrollbar from '../../components/Scrollbar';
import ScrollBar from '../../components/Scrollbar';
import ProductsOrExercisesItem from '../../components/ProductsOrExercisesItem/ProductsOrExercisesItem';
import { useDispatch, useSelector } from 'react-redux';

import { getAddProductIsLoading } from '../../redux/products/selectors';
import { useEffect, useState } from 'react';
import { fetchProducts } from '../../redux/productsFilter/operations';
import EmptyProductList from '../../components/EmptyProductList/EmptyProductList';
import Loader from '../../components/Lodaer/Loader';

import { fetchMoreProducts } from '../../redux/productsFilter/operations';
import {
getIsLoading,
getSearchParams,
getProducts,
getHasMore,
} from '../../redux/productsFilter/selectors';
import InfiniteScroll from 'react-infinite-scroller';

const Products = () => {
const [page, setPage] = useState(1);

const hasMore = useSelector(getHasMore);

const isLoadingMoreProducts = useSelector(getIsLoading);
const products = useSelector(getProducts);

const dispatch = useDispatch();
const products = useSelector(getProducts);

const searchParams = useSelector(getSearchParams);

useEffect(() => {
setPage(1);
}, [searchParams]);

const onLoadMore = () => {
if (page === 1) {
setPage(prevPage => prevPage + 1);
return;
}

const paginationParams = new URLSearchParams({
page,
limit: 20,
}).toString();
dispatch(fetchMoreProducts(`${searchParams}&${paginationParams}`));
setPage(prevPage => prevPage + 1);
};

return (
<ProductPageContainer>
<FlexWrapper>
<Title text="Products" />
<ProductsFilter />
</FlexWrapper>
{products.length !== 0 ? (
<Scrollbar width={{ dt: '868' }}>
<ScrollBar width={{ dt: '878' }}>
<InfiniteScroll
pageStart={1}
loadMore={() => {
if (page === 1) {
setPage(prevPage => prevPage + 1);
return;
}

const urlParams = { page, limit: 20 };
const paginationParams = new URLSearchParams(
urlParams,
).toString();
dispatch(
fetchMoreProducts(`${searchParams}&${paginationParams}`),
);
setPage(prevPage => prevPage + 1);
}}
pageStart={0}
loadMore={onLoadMore}
hasMore={hasMore && !isLoadingMoreProducts}
loader={
<div className="loader" key={0}>
Loading ...
</div>
}
loader={<Loader key={'qwe789'} size={'60'} />}
useWindow={false}
>
<ProductsOrExercisesContainer>
Expand All @@ -81,7 +75,7 @@ const Products = () => {
})}
</ProductsOrExercisesContainer>
</InfiniteScroll>
</Scrollbar>
</ScrollBar>
) : (
<EmptyProductList />
)}
Expand Down
17 changes: 16 additions & 1 deletion src/redux/exercises/operations.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,25 @@ export const addExercise = createAsyncThunk(
'addExercise',
async (exerciseDetails, thunkAPI) => {
try {
const { data } = await axios.post('/api/diary/add-exercise', exerciseDetails);
const { data } = await axios.post(
'/api/diary/add-exercise',
exerciseDetails,
);
return data;
} catch (error) {
return thunkAPI.rejectWithValue(error.message);
}
},
);

export const getMoreExercises = createAsyncThunk(
'exercises/getMoreExercises',
async (params, thunkAPI) => {
try {
const response = await axios.get(`api/exercises?${params}`);
return response.data;
} catch (error) {
return thunkAPI.rejectWithValue(error.message);
}
},
);
4 changes: 4 additions & 0 deletions src/redux/exercises/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@ export const selectGetFilters = state => state.exercises.getFilters;

export const selectIsLoadingExercises = state => state.exercises.isLoading;

export const selectHasMore = state => state.exercises.hasMore;

export const selectSearchParams = state => state.exercises.searchParams;

export const isTimerOn = state => state.exercises.isTimerOn;
Loading

0 comments on commit e542821

Please sign in to comment.