diff --git a/src/features/Projects/pages/ExplorePage/ExplorePage.tsx b/src/features/Projects/pages/ExplorePage/ExplorePage.tsx
index 85b93f3..284beff 100644
--- a/src/features/Projects/pages/ExplorePage/ExplorePage.tsx
+++ b/src/features/Projects/pages/ExplorePage/ExplorePage.tsx
@@ -1,208 +1,250 @@
-
-import ErrorMessage from 'src/Components/Errors/ErrorMessage/ErrorMessage';
-import { useExplorePageQuery, useGetFiltersQuery } from 'src/graphql';
-import ProjectsGrid from './ProjectsGrid/ProjectsGrid';
-import Categories, { Category } from '../../Components/Categories/Categories';
-import { useCallback, useEffect, useMemo, useState } from 'react';
-import Header from './Header/Header';
-import Button from 'src/Components/Button/Button';
-import { useAppDispatch } from 'src/utils/hooks';
-import { openModal } from 'src/redux/features/modals.slice';
-import { createAction } from '@reduxjs/toolkit';
-import { useReduxEffect } from 'src/utils/hooks/useReduxEffect';
-import { NetworkStatus } from '@apollo/client';
-import { FiSliders } from 'react-icons/fi';
-import { HiOutlineChevronDoubleDown } from 'react-icons/hi'
-import { ProjectsFilters } from './Filters/FiltersModal';
-import { useUpdateUrlWithFilters } from './helpers';
-import { withBasicProvider } from 'src/utils/helperFunctions';
-import { ProjectsFiltersProvider, useProjectsFilters } from './filters-context';
-import { setTheme } from 'src/redux/features/ui.slice';
-import OgTags from 'src/Components/OgTags/OgTags';
-
+import ErrorMessage from "src/Components/Errors/ErrorMessage/ErrorMessage";
+import { useExplorePageQuery, useGetFiltersQuery } from "src/graphql";
+import ProjectsGrid from "./ProjectsGrid/ProjectsGrid";
+import Categories, { Category } from "../../Components/Categories/Categories";
+import { useCallback, useEffect, useMemo, useState } from "react";
+import Header from "./Header/Header";
+import Button from "src/Components/Button/Button";
+import { useAppDispatch } from "src/utils/hooks";
+import { openModal } from "src/redux/features/modals.slice";
+import { createAction } from "@reduxjs/toolkit";
+import { useReduxEffect } from "src/utils/hooks/useReduxEffect";
+import { NetworkStatus } from "@apollo/client";
+import { FiSliders } from "react-icons/fi";
+import { HiOutlineChevronDoubleDown } from "react-icons/hi";
+import { ProjectsFilters } from "./Filters/FiltersModal";
+import { useUpdateUrlWithFilters } from "./helpers";
+import { withBasicProvider } from "src/utils/helperFunctions";
+import { ProjectsFiltersProvider, useProjectsFilters } from "./filters-context";
+import { setTheme } from "src/redux/features/ui.slice";
+import OgTags from "src/Components/OgTags/OgTags";
function ExplorePage() {
+ const dispatch = useAppDispatch();
- const dispatch = useAppDispatch();
+ const [canFetchMore, setCanFetchMore] = useState(true);
- const [canFetchMore, setCanFetchMore] = useState(true);
-
- const { filters, updateFilters } = useProjectsFilters();
-
- useUpdateUrlWithFilters(filters)
- const filtersQuery = useGetFiltersQuery();
-
- const hiddenCategoriesIds = useMemo(() => {
- if (filtersQuery.loading) return [];
- return filtersQuery.data?.categoryList?.filter(c => c?.isHidden).map(c => c!.id!) ?? [];
- }, [filtersQuery.data?.categoryList, filtersQuery.loading])
-
- const { queryFilters, hasSearchFilters } = useMemo(() => createQueryFilters(filters, {
- hiddenCategoriesIds
- }), [filters, hiddenCategoriesIds])
-
-
- const { data, networkStatus, error, fetchMore } = useExplorePageQuery({
- variables: {
- page: 1,
- pageSize: PAGE_SIZE,
- filter: queryFilters
- },
- notifyOnNetworkStatusChange: true,
- onCompleted: data => {
- if ((data.projects?.length ?? 0) < PAGE_SIZE) setCanFetchMore(false);
- },
- skip: filtersQuery.loading
- });
-
-
- const onFiltersUpdated = useCallback(({ payload }: typeof UPDATE_FILTERS_ACTION) => {
- updateFilters(payload)
- }, [updateFilters])
-
- useReduxEffect(onFiltersUpdated, UPDATE_FILTERS_ACTION.type);
-
- useEffect(() => {
- dispatch(setTheme('light'))
- }, [dispatch])
-
-
- useEffect(() => {
- setCanFetchMore(true);
- }, [filters])
-
-
- const openFilters = () => {
- dispatch(openModal({
- Modal: "FiltersModal",
- isPageModal: true,
- props: {
- callbackAction: {
- type: UPDATE_FILTERS_ACTION.type,
- payload: {
-
- }
- },
- initFilters: {
- ...filters
- }
- }
- }))
- }
-
- const selectCategoryTab = (category: Category | null) => {
- updateFilters({ ...(filters ?? {}), categories: category ? [category] : undefined })
- }
-
- const clickFetchMore = () => {
- fetchMore({ variables: { page: Math.floor((data?.projects?.length ?? 0) / PAGE_SIZE) + 1 } })
- .then(res => {
- if (!res.data.projects || res.data.projects.length < PAGE_SIZE) setCanFetchMore(false);
- })
- }
-
- if (error) {
- return
-
-
- }
-
- const isLoading = networkStatus === NetworkStatus.loading || networkStatus === NetworkStatus.refetch || networkStatus === NetworkStatus.setVariables || filtersQuery.loading;
- const isLoadingMore = networkStatus === NetworkStatus.fetchMore;
- const canLoadMore = !isLoading && !isLoadingMore && data?.projects && data.projects.length > 0 && canFetchMore;
+ const { filters, updateFilters } = useProjectsFilters();
+ useUpdateUrlWithFilters(filters);
+ const filtersQuery = useGetFiltersQuery();
+ const hiddenCategoriesIds = useMemo(() => {
+ if (filtersQuery.loading) return [];
return (
- <>
- c?.isHidden)
+ .map((c) => c!.id!) ?? []
+ );
+ }, [filtersQuery.data?.categoryList, filtersQuery.loading]);
+
+ const { queryFilters, hasSearchFilters } = useMemo(
+ () =>
+ createQueryFilters(filters, {
+ hiddenCategoriesIds,
+ }),
+ [filters, hiddenCategoriesIds]
+ );
+
+ const { data, networkStatus, error, fetchMore } = useExplorePageQuery({
+ variables: {
+ page: 1,
+ pageSize: PAGE_SIZE,
+ filter: queryFilters,
+ },
+ notifyOnNetworkStatusChange: true,
+ onCompleted: (data) => {
+ if ((data.projects?.length ?? 0) < PAGE_SIZE) setCanFetchMore(false);
+ },
+ skip: filtersQuery.loading,
+ });
+
+ const onFiltersUpdated = useCallback(
+ ({ payload }: typeof UPDATE_FILTERS_ACTION) => {
+ updateFilters(payload);
+ },
+ [updateFilters]
+ );
+
+ useReduxEffect(onFiltersUpdated, UPDATE_FILTERS_ACTION.type);
+
+ useEffect(() => {
+ dispatch(setTheme("light"));
+ }, [dispatch]);
+
+ useEffect(() => {
+ setCanFetchMore(true);
+ }, [filters]);
+
+ const openFilters = () => {
+ dispatch(
+ openModal({
+ Modal: "FiltersModal",
+ isPageModal: true,
+ props: {
+ callbackAction: {
+ type: UPDATE_FILTERS_ACTION.type,
+ payload: {},
+ },
+ initFilters: {
+ ...filters,
+ },
+ },
+ })
+ );
+ };
+
+ const selectCategoryTab = (category: Category | null) => {
+ updateFilters({
+ ...(filters ?? {}),
+ categories: category ? [category] : undefined,
+ });
+ };
+
+ const clickFetchMore = () => {
+ fetchMore({
+ variables: {
+ page: Math.floor((data?.projects?.length ?? 0) / PAGE_SIZE) + 1,
+ },
+ }).then((res) => {
+ if (!res.data.projects || res.data.projects.length < PAGE_SIZE)
+ setCanFetchMore(false);
+ });
+ };
+
+ if (error) {
+ return (
+
+
+
+ );
+ }
+
+ const isLoading =
+ networkStatus === NetworkStatus.loading ||
+ networkStatus === NetworkStatus.refetch ||
+ networkStatus === NetworkStatus.setVariables ||
+ filtersQuery.loading;
+ const isLoadingMore = networkStatus === NetworkStatus.fetchMore;
+ const canLoadMore =
+ !isLoading &&
+ !isLoadingMore &&
+ data?.projects &&
+ data.projects.length > 0 &&
+ canFetchMore;
+
+ return (
+ <>
+
+
+
+
+
+
selectCategoryTab(v)}
/>
-
-
-
-
selectCategoryTab(v)} />
-
-
-
p !== null) as any[] ?? []}
- />
- {canLoadMore &&
-
-
}
-
- >
- )
+
+
+
+
p !== null) as any[]) ?? []}
+ />
+ {canLoadMore && (
+
+
+
+ )}
+
+ >
+ );
}
export default withBasicProvider(ProjectsFiltersProvider, ExplorePage);
-
-const UPDATE_FILTERS_ACTION = createAction>('PROJECTS_FILTERS_UPDATED')({})
+const UPDATE_FILTERS_ACTION = createAction>(
+ "PROJECTS_FILTERS_UPDATED"
+)({});
const PAGE_SIZE = 28;
type QueryFilter = Partial<{
- categoryId: object | null
- tagId: object | null
- yearFounded: number | null
- dead: boolean | null
- license: string | null
-}>
+ categoryId: object | null;
+ tagId: object | null;
+ yearFounded: number | null;
+ dead: boolean | null;
+ license: string | null;
+}>;
+const createQueryFilters = (
+ filters: Partial | null,
+ extraFilters: { hiddenCategoriesIds: string[] }
+) => {
+ let filter: QueryFilter = {};
+ let hasSearchFilters = false;
-const createQueryFilters = (filters: Partial | null, extraFilters: { hiddenCategoriesIds: string[] }) => {
- let filter: QueryFilter = {}
- let hasSearchFilters = false;
+ const defaultFilters = {
+ status: "Published",
+ };
+ if (filters?.categories) {
+ filter.categoryId = filters?.categories.map((c) => c.id!);
+ hasSearchFilters = true;
+ } else {
+ filter.categoryId = {
+ _nin: extraFilters.hiddenCategoriesIds,
+ };
+ }
- if (filters?.categories) {
- filter.categoryId = filters?.categories.map(c => c.id!)
- hasSearchFilters = true;
- } else {
- filter.categoryId = {
- _nin: extraFilters.hiddenCategoriesIds
- };
- }
+ if (filters?.tags) {
+ filter.tagId = {
+ _in: filters?.tags.map((t) => t.id),
+ };
+ hasSearchFilters = true;
+ }
+ if (filters?.yearFounded) {
+ filter.yearFounded = Number(filters?.yearFounded);
+ hasSearchFilters = true;
+ }
- if (filters?.tags) {
- filter.tagId = {
- _in: filters?.tags.map(t => t.id)
- }
- hasSearchFilters = true;
- }
+ if (filters?.projectStatus) {
+ filter.dead = filters?.projectStatus === "alive" ? false : true;
+ hasSearchFilters = true;
+ }
- if (filters?.yearFounded) {
- filter.yearFounded = Number(filters?.yearFounded)
- hasSearchFilters = true;
- }
+ if (filters?.projectLicense) {
+ filter.license = filters?.projectLicense;
+ hasSearchFilters = true;
+ }
- if (filters?.projectStatus) {
- filter.dead = filters?.projectStatus === 'alive' ? false : true;
- hasSearchFilters = true;
- }
+ if (Object.keys(filter).length === 0)
+ return { queryFilters: null, hasSearchFilters };
-
- if (filters?.projectLicense) {
- filter.license = filters?.projectLicense
- hasSearchFilters = true;
- }
-
- if (Object.keys(filter).length === 0)
- return { queryFilters: null, hasSearchFilters }
-
- return { queryFilters: filter, hasSearchFilters };
-}
\ No newline at end of file
+ return { queryFilters: { ...defaultFilters, ...filter }, hasSearchFilters };
+};