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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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. selectPinnedOffers,
  16. selectTotalOffers,
  17. } from "../../store/selectors/offersSelectors";
  18. import useFilters from "./useFilters";
  19. import useQueryString from "./useQueryString";
  20. import { setQueryString } from "../../store/actions/queryString/queryStringActions";
  21. import {
  22. convertQueryStringForBackend,
  23. makeHeaderStringFromQueryObjectHelper,
  24. makeHeaderStringHelper,
  25. makeQueryStringHelper,
  26. } from "../../util/helpers/queryHelpers";
  27. import useSorting from "./useSorting";
  28. import useSearch from "./useSearch";
  29. import {
  30. setHeaderString,
  31. setSearchString,
  32. } from "../../store/actions/filters/filtersActions";
  33. import usePaging from "./usePaging";
  34. import { useHistory } from "react-router-dom";
  35. const useOffers = () => {
  36. const dispatch = useDispatch();
  37. const filters = useFilters();
  38. const queryStringHook = useQueryString();
  39. const pinnedOffers = useSelector(selectPinnedOffers);
  40. const offers = useSelector(selectOffers);
  41. const totalOffers = useSelector(selectTotalOffers);
  42. const history = useHistory();
  43. const [filtersCleared, setFiltersCleared] = useState(false);
  44. // Always fetch categories and locations,
  45. // becouse count of total offers change over time
  46. useEffect(() => {
  47. dispatch(fetchCategories());
  48. dispatch(fetchLocations());
  49. return () => clear();
  50. }, []);
  51. useEffect(() => {
  52. if (!queryStringHook.historyStateCleared && history.location.state) {
  53. clearFiltersAndApply();
  54. dispatch(setHeaderString(makeHeaderStringHelper({})));
  55. history.location.state = {};
  56. }
  57. }, [history.location]);
  58. // On every change of query string, new header string should be created
  59. // Header string is shown on Home page above offers
  60. useEffect(() => {
  61. const headerStringLocal = makeHeaderStringHelper(filters);
  62. dispatch(setHeaderString(headerStringLocal));
  63. }, [queryStringHook.queryString, filtersCleared]);
  64. // Initially set category, location and subcategory based on query string
  65. useEffect(() => {
  66. if (queryStringHook.isInitiallyLoaded) {
  67. const queryObject = queryStringHook.queryObject;
  68. if (KEY_CATEGORY in queryObject) {
  69. const category = filters.category.findCategory(
  70. queryObject[KEY_CATEGORY]
  71. );
  72. filters.category.setSelectedCategory(category);
  73. if (KEY_SUBCATEGORY in queryObject) {
  74. const subcategory = filters.category
  75. .getSubcategories(category?.name)
  76. .find(
  77. (subcategory) => subcategory.name === queryObject[KEY_SUBCATEGORY]
  78. );
  79. filters.subcategory.setSelectedSubcategory(subcategory);
  80. }
  81. }
  82. if (KEY_LOCATION in queryObject) {
  83. filters.locations.setSelectedLocationsFromArray(
  84. queryObject[KEY_LOCATION]
  85. );
  86. }
  87. if (KEY_SORTBY in queryObject) {
  88. sorting.changeSortingFromName(queryObject[KEY_SORTBY]);
  89. }
  90. if (KEY_PAGE in queryObject) {
  91. if (queryObject[KEY_PAGE] !== 1)
  92. paging.changePage(queryObject[KEY_PAGE]);
  93. }
  94. if (KEY_SEARCH in queryObject) {
  95. search.searchOffers(queryObject[KEY_SEARCH]);
  96. } else {
  97. search.clear();
  98. }
  99. dispatch(setSearchString(queryObject[KEY_SEARCH]));
  100. dispatch(
  101. setHeaderString(makeHeaderStringFromQueryObjectHelper(queryObject))
  102. );
  103. }
  104. }, [queryStringHook.isInitiallyLoaded]);
  105. const allOffersToShow = useMemo(() => {
  106. return [...pinnedOffers, ...offers];
  107. }, [offers, pinnedOffers]);
  108. useEffect(() => {
  109. console.log("useeff", filtersCleared);
  110. if (filtersCleared) {
  111. console.log("useeff unutra");
  112. setFiltersCleared(false);
  113. apply();
  114. console.log("posle useeff");
  115. }
  116. }, [filtersCleared]);
  117. const apply = () => {
  118. filters.apply();
  119. console.log("ovde");
  120. const newQueryString = makeQueryStringHelper(
  121. filters,
  122. paging,
  123. search,
  124. sorting
  125. );
  126. dispatch(setQueryString(convertQueryStringForBackend(newQueryString)));
  127. };
  128. const applyFilters = () => {
  129. console.log("applyfilters");
  130. setFiltersCleared(true);
  131. };
  132. const clearFiltersAndApply = () => {
  133. clear();
  134. console.log("clearfiltersandapply filterscleared");
  135. setFiltersCleared(true);
  136. };
  137. const applySorting = () => {
  138. paging.changePage(1);
  139. setFiltersCleared(true);
  140. }
  141. const applySearch = () => {
  142. paging.changePage(1);
  143. setFiltersCleared(true);
  144. }
  145. // Those hooks are below becouse function apply cannot be put on props before initialization
  146. const sorting = useSorting(applySorting);
  147. const paging = usePaging(apply);
  148. const search = useSearch(applySearch);
  149. // On every change of search string, offers should be immediately searched
  150. useEffect(() => {
  151. if (queryStringHook.isInitiallyLoaded) {
  152. search.searchOffers(search.searchString);
  153. }
  154. }, [search.searchString]);
  155. // Clears only filters(does not clear sorting and search)
  156. const clearOnlyFiltersAndApply = () => {
  157. filters.clear();
  158. paging.changePage(1);
  159. console.log("clearonlyfiltersandapply filterscleared");
  160. setFiltersCleared(true);
  161. };
  162. const clear = () => {
  163. filters.clear();
  164. sorting.clear();
  165. paging.changePage(1);
  166. search.clear();
  167. };
  168. return {
  169. filters,
  170. sorting,
  171. paging,
  172. search,
  173. queryStringHook,
  174. allOffersToShow,
  175. totalOffers,
  176. applyFilters,
  177. clearFiltersAndApply,
  178. clearOnlyFiltersAndApply,
  179. apply,
  180. clear,
  181. };
  182. };
  183. export default useOffers;