Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

useOffers.js 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import { useEffect, useMemo, useState } from "react";
  2. import { useDispatch, useSelector } from "react-redux";
  3. import {
  4. KEY_CATEGORY,
  5. KEY_LOCATION,
  6. KEY_PAGE,
  7. KEY_SEARCH,
  8. KEY_SORTBY,
  9. KEY_SUBCATEGORY,
  10. } from "../../constants/queryStringConstants";
  11. import { fetchCategories } from "../../store/actions/categories/categoriesActions";
  12. import { fetchLocations } from "../../store/actions/locations/locationsActions";
  13. import {
  14. selectOffers,
  15. selectTotalOffers,
  16. } from "../../store/selectors/offersSelectors";
  17. import useFilters from "./useFilters";
  18. import useQueryString from "./useQueryString";
  19. import { setQueryString } from "../../store/actions/queryString/queryStringActions";
  20. import {
  21. convertQueryStringForBackend,
  22. makeHeaderStringHelper,
  23. makeQueryStringHelper,
  24. } from "../../util/helpers/queryHelpers";
  25. import useSorting from "./useSorting";
  26. import useSearch from "./useSearch";
  27. import {
  28. setHeaderString,
  29. setSearchString,
  30. } from "../../store/actions/filters/filtersActions";
  31. import usePaging from "./usePaging";
  32. import { useHistory } from "react-router-dom";
  33. const useOffers = () => {
  34. const dispatch = useDispatch();
  35. const filters = useFilters();
  36. const queryStringHook = useQueryString();
  37. const offers = useSelector(selectOffers);
  38. const totalOffers = useSelector(selectTotalOffers);
  39. const history = useHistory();
  40. const [filtersCleared, setFiltersCleared] = useState(false);
  41. // Always fetch categories and locations,
  42. // becouse count of total offers change over time
  43. useEffect(() => {
  44. dispatch(fetchCategories());
  45. dispatch(fetchLocations());
  46. return () => clear();
  47. }, []);
  48. useEffect(() => {
  49. if (history.location.state?.logo) {
  50. clear();
  51. }
  52. }, [history.location])
  53. // On every change of query string, new header string should be created
  54. // Header string is shown on Home page above offers
  55. useEffect(() => {
  56. const headerStringLocal = makeHeaderStringHelper(filters);
  57. dispatch(setHeaderString(headerStringLocal));
  58. }, [queryStringHook.queryString]);
  59. // Initially set category, location and subcategory based on query string
  60. useEffect(() => {
  61. if (queryStringHook.isInitiallyLoaded) {
  62. const queryObject = queryStringHook.queryObject;
  63. if (KEY_CATEGORY in queryObject) {
  64. const category = filters.category.findCategory(
  65. queryObject[KEY_CATEGORY]
  66. );
  67. filters.category.setSelectedCategory(category);
  68. if (KEY_SUBCATEGORY in queryObject) {
  69. const subcategory = filters.category
  70. .getSubcategories(category?.name)
  71. .find(
  72. (subcategory) => subcategory.name === queryObject[KEY_SUBCATEGORY]
  73. );
  74. filters.subcategory.setSelectedSubcategory(subcategory);
  75. }
  76. }
  77. if (KEY_LOCATION in queryObject) {
  78. filters.locations.setSelectedLocationsFromArray(
  79. queryObject[KEY_LOCATION]
  80. );
  81. }
  82. if (KEY_SORTBY in queryObject) {
  83. sorting.changeSortingFromName(queryObject[KEY_SORTBY]);
  84. }
  85. if (KEY_PAGE in queryObject) {
  86. if (queryObject[KEY_PAGE] !== 1)
  87. paging.changePage(queryObject[KEY_PAGE]);
  88. }
  89. dispatch(setSearchString(queryObject[KEY_SEARCH]));
  90. }
  91. }, [queryStringHook.isInitiallyLoaded]);
  92. const allOffersToShow = useMemo(() => {
  93. return offers;
  94. }, [offers]);
  95. useEffect(() => {
  96. if (filtersCleared) {
  97. setFiltersCleared(false);
  98. apply();
  99. }
  100. }, [filtersCleared])
  101. const apply = () => {
  102. filters.apply();
  103. const newQueryString = makeQueryStringHelper(
  104. filters,
  105. paging,
  106. search,
  107. sorting
  108. );
  109. dispatch(setQueryString(convertQueryStringForBackend(newQueryString)));
  110. };
  111. const clearFiltersAndApply = () => {
  112. clear();
  113. setFiltersCleared(true);
  114. }
  115. // Those hooks are below becouse function apply cannot be put on props before initialization
  116. const sorting = useSorting(apply);
  117. const paging = usePaging(apply);
  118. const search = useSearch(apply);
  119. // On every change of search string, offers should be immediately searched
  120. useEffect(() => {
  121. if (queryStringHook.isInitiallyLoaded) {
  122. search.searchOffers(search.searchString);
  123. }
  124. }, [search.searchString]);
  125. const clear = () => {
  126. filters.clear();
  127. sorting.clear();
  128. paging.changePage(1);
  129. };
  130. return {
  131. filters,
  132. sorting,
  133. paging,
  134. queryStringHook,
  135. allOffersToShow,
  136. totalOffers,
  137. clearFiltersAndApply,
  138. apply,
  139. clear,
  140. };
  141. };
  142. export default useOffers;