You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Offers.js 2.7KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import React, { useEffect, useRef, useState } from "react";
  2. import PropTypes from "prop-types";
  3. import { OffersContainer } from "./Offers.styled";
  4. import OfferCard from "../../Cards/OfferCard/OfferCard";
  5. import {
  6. fetchMoreOffers,
  7. fetchOffers,
  8. } from "../../../store/actions/offers/offersActions";
  9. import { useDispatch, useSelector } from "react-redux";
  10. import {
  11. selectNoMoreOffers,
  12. selectOffers,
  13. selectPinnedOffers,
  14. } from "../../../store/selectors/offersSelectors";
  15. import useFilters from "../../../hooks/useFilters";
  16. const Offers = (props) => {
  17. const filters = useFilters();
  18. const [page, setPage] = useState(2);
  19. const [initialLoad, setInitialLoad] = useState(true);
  20. const pinnedOffers = useSelector(selectPinnedOffers);
  21. const offers = useSelector(selectOffers);
  22. const dispatch = useDispatch();
  23. const offersRef = useRef(null);
  24. const noMoreOffersStatus = useSelector(selectNoMoreOffers);
  25. let timeout = null;
  26. let listener;
  27. useEffect(() => {
  28. listener = () => {
  29. if (
  30. !noMoreOffersStatus &&
  31. offers?.length > 0 &&
  32. window.scrollY + window.innerHeight >
  33. window.document.body.offsetHeight * 0.8
  34. ) {
  35. if (!timeout) {
  36. timeout = setTimeout(() => {
  37. timeout = null;
  38. }, 5000);
  39. dispatch(
  40. fetchMoreOffers({ page: page, queryString: filters.queryString })
  41. );
  42. }
  43. }
  44. };
  45. window.addEventListener("scroll", listener);
  46. return () => window.removeEventListener("scroll", listener);
  47. }, [page, noMoreOffersStatus, filters.queryString, timeout, offers]);
  48. useEffect(() => {
  49. setPage(Math.floor((offers.length + pinnedOffers.length ) / 10) + 1);
  50. }, [offers, pinnedOffers]);
  51. useEffect(() => {
  52. dispatch(fetchOffers({ page: 1 }));
  53. }, []);
  54. useEffect(() => {
  55. if (filters.queryString) {
  56. if (filters.queryString.length > 1) {
  57. if (initialLoad) {
  58. dispatch(fetchOffers({ page: 1, queryString: filters.queryString }));
  59. setInitialLoad(false);
  60. }
  61. } else {
  62. setInitialLoad(false);
  63. }
  64. }
  65. }, [filters.queryString, initialLoad]);
  66. return (
  67. <OffersContainer ref={offersRef}>
  68. <>
  69. {pinnedOffers != undefined &&
  70. pinnedOffers.map((item) => {
  71. return (
  72. <OfferCard key={item._id} offer={item} halfwidth={props.isGrid} />
  73. );
  74. })}
  75. </>
  76. {offers != undefined &&
  77. offers.map((item) => {
  78. return (
  79. <OfferCard key={item._id} offer={item} halfwidth={props.isGrid} />
  80. );
  81. })}
  82. </OffersContainer>
  83. );
  84. };
  85. Offers.propTypes = {
  86. children: PropTypes.node,
  87. isGrid: PropTypes.bool,
  88. };
  89. export default Offers;