feat: projects filters

This commit is contained in:
MTG2000
2022-10-20 14:41:31 +03:00
parent 11f81dfd1f
commit fcc4d80996
14 changed files with 445 additions and 35 deletions

View File

@@ -30,7 +30,11 @@ export default function Modal({ onClose, children, ...props }: Props) {
className=' '
closeTimeoutMS={1000}
onAfterClose={onAfterClose}
contentElement={(_props, children) => <div {..._props} className={`${_props.className} w-screen min-h-screen relative flex flex-col justify-center items-center md:py-64 md:px-16 inset-0`}>
contentElement={(_props, children) => <div {..._props} className={`
${_props.className}
w-screen min-h-screen relative flex flex-col justify-center items-center inset-0
${!props.isPageModal && "md:py-64 md:px-16 "}
`}>
<div
onClick={onClose}
className={`absolute w-full h-full top-0 left-0 bg-gray-300 bg-opacity-50 ${props.isPageModal && "hidden md:block"}`}

View File

@@ -50,21 +50,11 @@ export default function ModalsContainer() {
}
useEffect(() => {
// let prevOverflow = document.body.style.overflow;
// if (isOpen) {
// const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
// prevOverflow = document.body.style.overflow;
// console.log(prevOverflow);
// document.body.style.overflow = 'hidden';
// if (scrollbarWidth) {
// document.documentElement.style.paddingRight = `${scrollbarWidth}px`;
// }
// }
// else {
// document.body.style.overflow = prevOverflow;
// document.documentElement.style.paddingRight = "";
// }
if (isOpen) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = 'unset';
}
}, [isOpen]);
return (

View File

@@ -35,7 +35,7 @@ export default function Categories(props: Props) {
if (loading || !data)
return <div className="flex gap-32 border-b border-gray-200">
return <div className="flex overflow-hidden gap-32 border-b border-gray-200">
{Array(15).fill(0).map((_, idx) =>
<div
key={idx}
@@ -50,14 +50,14 @@ export default function Categories(props: Props) {
return (
<div className="relative group">
<div className="overflow-hidden" ref={viewportRef}>
<div className="select-none w-full flex gap-32 border-b border-gray-200">
<div className="overflow-hidden border-b border-gray-200" ref={viewportRef}>
<div className="select-none w-full flex gap-8">
<button
onClick={() => {
props.onChange?.(null)
}}
className={`
flex flex-col font-medium py-16 min-w-max
flex flex-col font-medium hover:bg-gray-100 active:bg-gray-200 rounded-t-8 px-16 py-16 min-w-max
${props.value === null ? "text-primary-500 border-b-2 border-primary-500" : "text-gray-500"}
`}
>All projects</button>
@@ -69,7 +69,7 @@ export default function Categories(props: Props) {
props.onChange?.(isSame ? null : category)
}}
className={`
flex flex-col font-medium py-16 min-w-max
flex flex-col font-medium hover:bg-gray-100 active:bg-gray-200 rounded-t-8 px-8 py-16 min-w-max
${props.value?.id === category?.id ? "text-primary-500 border-b-2 border-primary-500" : "text-gray-500"}
`}
>{category!.name} ({category?.projectsCount!})</button>

View File

@@ -12,7 +12,7 @@ export default function ProjectCardMini({ project, onClick }: Props) {
return (
<div
className="py-16 select-none px-16 flex items-center gap-16 border-2 border-gray-100 rounded-16 bg-white hover:bg-gray-50"
className="py-16 select-none px-16 flex items-center gap-16 rounded-16 hover:bg-gray-100"
onKeyDown={e => {
e.key !== 'Enter' || onClick(project?.id!)
}}

View File

@@ -5,30 +5,102 @@ import HeaderImage from './Header/Header';
import ProjectsGrid from './ProjectsGrid/ProjectsGrid';
import { Helmet } from "react-helmet";
import Categories, { Category } from '../../Components/Categories/Categories';
import { useState } from 'react';
import { useCallback, 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 { GoSettings } from 'react-icons/go'
import { FiSliders } from 'react-icons/fi';
import { ProjectsFilters } from './Filters/FiltersModal';
const UPDATE_FILTERS_ACTION = createAction<{ categoriesIds?: string[], tagsIds?: string[], yearFounded?: string }>('PROJECTS_FILTERS_UPDATED')({})
export default function ExplorePage() {
const dispatch = useAppDispatch();
const [filters, setFilters] = useState<Partial<ProjectsFilters>>()
const [selectedCategory, setSelectedCategory] = useState<Category | null>(null)
const { data, loading, error } = useExplorePageQuery({
const queryFilters = useMemo(() => {
let filter: any = {}
if (!filters) return null;
if (filters.categoriesIds && filters.categoriesIds?.length > 0)
filter['categoryId'] = filters.categoriesIds
if (filters.tagsIds && filters.tagsIds?.length > 0)
filter['tags'] = filters.tagsIds
if (filters.yearFounded && filters.yearFounded !== "Any")
filter['yearFounded'] = Number(filters.yearFounded)
if (Object.keys(filter).length === 0) return null
return filter;
}, [filters])
const { data, networkStatus, error } = useExplorePageQuery({
variables: {
page: 1,
pageSize: 20,
filter: selectedCategory ? {
"categoryId": selectedCategory?.id
} : null
}
filter: queryFilters
},
notifyOnNetworkStatusChange: true,
});
const onFiltersUpdated = useCallback(({ payload }: typeof UPDATE_FILTERS_ACTION) => {
setSelectedCategory(null)
setFilters(payload);
}, [])
useReduxEffect(onFiltersUpdated, UPDATE_FILTERS_ACTION.type)
const openFilters = () => {
dispatch(openModal({
Modal: "FiltersModal",
isPageModal: true,
props: {
callbackAction: {
type: UPDATE_FILTERS_ACTION.type,
payload: {
}
},
initFilters: {
...filters
}
}
}))
}
const selectCategoryTab = (category?: Category | null) => {
if (!category?.id)
return;
setSelectedCategory(category);
setFilters({
categoriesIds: [category.id]
})
}
if (error) {
return <div className="p-32">
<ErrorMessage type='fetching' />
</div>
}
console.log(networkStatus, NetworkStatus.loading, NetworkStatus.refetch, NetworkStatus.setVariables);
const isLoading = networkStatus === NetworkStatus.loading || networkStatus === NetworkStatus.refetch || networkStatus === NetworkStatus.setVariables;
return (
@@ -41,10 +113,13 @@ export default function ExplorePage() {
<Header
category={selectedCategory}
/>
<Categories value={selectedCategory} onChange={v => setSelectedCategory(v)} />
<div className="grid grid-cols-[1fr_auto] items-center gap-32">
<div className="min-w-0"><Categories value={selectedCategory} onChange={v => selectCategoryTab(v)} /></div>
<Button className='self-center' variant='outline' color='white' onClick={openFilters}><FiSliders className="scale-150 mr-8 text-primary-500" /> <span className='align-middle'>Filters</span></Button>
</div>
<div className="mt-40">
<ProjectsGrid
isLoading={loading}
isLoading={isLoading}
projects={data?.projects?.filter((p) => p !== null) as any[] ?? []}
/>
</div>

View File

@@ -0,0 +1,17 @@
import { ComponentStory, ComponentMeta } from '@storybook/react';
import FiltersModal from './FiltersModal';
import { ModalsDecorator } from 'src/utils/storybook/decorators';
export default {
title: 'Projects/Filters Modal',
component: FiltersModal,
decorators: [ModalsDecorator]
} as ComponentMeta<typeof FiltersModal>;
const Template: ComponentStory<typeof FiltersModal> = (args) => <FiltersModal {...args} />;
export const Default = Template.bind({});

View File

@@ -0,0 +1,186 @@
import React, { FormEvent, useState } from 'react'
import { ModalCard, modalCardVariants } from 'src/Components/Modals/ModalsContainer/ModalsContainer'
import { motion } from 'framer-motion'
import { IoClose } from 'react-icons/io5'
import Button from 'src/Components/Button/Button'
import { useAppDispatch } from 'src/utils/hooks'
import { PayloadAction } from '@reduxjs/toolkit'
import * as yup from "yup";
import { SubmitHandler, useForm } from "react-hook-form"
import { yupResolver } from "@hookform/resolvers/yup";
import IconButton from 'src/Components/IconButton/IconButton'
import Badge from 'src/Components/Badge/Badge'
import { useGetFiltersQuery } from 'src/graphql'
import Skeleton from 'react-loading-skeleton';
import { random } from 'src/utils/helperFunctions';
interface Props extends ModalCard {
initFilters?: Partial<ProjectsFilters>
callbackAction: PayloadAction<Partial<ProjectsFilters>>
}
export interface IFormInputs {
text: string,
href: string,
}
export type ProjectsFilters = {
categoriesIds: string[]
tagsIds: string[]
yearFounded: string
}
const yearsFounded = ['Any', '2016', '2017', '2018', '2019', '2020', '2021', '2022']
export default function FiltersModal({ onClose, direction, initFilters, callbackAction, ...props }: Props) {
const dispatch = useAppDispatch()
const query = useGetFiltersQuery();
const [categoriesFilter, setCategoriesFilter] = useState<string[]>(initFilters?.categoriesIds ?? []);
const [tagsFilter, setTagsFilter] = useState<string[]>(initFilters?.tagsIds ?? []);
const [yearFoundedFilter, setYearFoundedFilter] = useState(initFilters?.yearFounded ?? yearsFounded[0]);
const clickCategory = (id: string) => {
if (categoriesFilter.includes(id))
setCategoriesFilter(categoriesFilter.filter(v => v !== id));
else
setCategoriesFilter([...categoriesFilter, id]);
}
const clickTag = (id: string) => {
if (tagsFilter.includes(id))
setTagsFilter(tagsFilter.filter(v => v !== id));
else
setTagsFilter([...tagsFilter, id]);
}
const clearFilters = () => {
setCategoriesFilter([]);
setTagsFilter([]);
setYearFoundedFilter(yearsFounded[0]);
}
const applyFilters = () => {
const action = Object.assign({}, callbackAction);
action.payload = { categoriesIds: categoriesFilter, tagsIds: tagsFilter, yearFounded: yearFoundedFilter }
dispatch(action)
onClose?.();
}
return (
<motion.div
custom={direction}
variants={modalCardVariants}
initial='initial'
animate="animate"
exit='exit'
className="modal-card p-24 min-h-screen !rounded-0 relative"
>
<div className="page-container relative">
<div className="flex justify-between items-center">
<h2 className='text-h2 font-bolder'>Filter Projects</h2>
<IconButton onClick={onClose} className='!bg-gray-100 hover:!bg-gray-200'>
<IoClose className='text-h3 text-gray-400' />
</IconButton>
</div>
<div className="flex flex-col gap-24 mt-24">
<hr className="bg-gray-100" />
<div>
<h3 className="text-body2 font-bolder">🌈 Category</h3>
<p className='text-gray-600 mt-8'>Select one or more tags to search from.</p>
<ul className="flex flex-wrap gap-16 mt-24">
{query.data?.categoryList
?.filter(c => !!(c && c.name))
.map(category => <li
key={category?.id}
>
<button
className={`
px-12 py-8 border rounded-10 text-body5 font-medium
active:scale-95 transition-transform
${!categoriesFilter.includes(category?.id!) ? "bg-gray-100 hover:bg-gray-200 border-gray-200" : "bg-primary-100 text-primary-600 border-primary-200"}
`}
onClick={() => clickCategory(category?.id!)}
>{category?.icon} {category?.name}
</button>
</li>)}
{query.loading &&
Array(10).fill(0).map((_, idx) => {
return <div
key={idx}
className={`px-12 py-8 border bg-gray-100 hover:bg-gray-200 border-gray-200 rounded-10 text-body5 font-medium`}
><Skeleton width={`${Math.round(random(8, 15))}ch`} />
</div>
})}
</ul>
</div>
<hr className="bg-gray-100" />
<div>
<h3 className="text-body2 font-bolder">🔖 Tags</h3>
<p className='text-gray-600 mt-8'>Select one or more tags to search from.</p>
<ul className="flex flex-wrap gap-16 mt-24">
{query.data?.tags
?.filter(t => !!(t && t.name))
.map(tag => <li
key={tag?.id}
>
<button
className={`
px-12 py-8 border rounded-10 text-body5 font-medium
active:scale-95 transition-transform
${!tagsFilter.includes(tag?.id!) ? "bg-gray-100 hover:bg-gray-200 border-gray-200" : "bg-primary-100 text-primary-600 border-primary-200"}
`}
onClick={() => clickTag(tag?.id!)}
>{tag?.icon} {tag?.name}
</button>
</li>)}
{query.loading &&
Array(8).fill(0).map((_, idx) => {
return <div
key={idx}
className={`px-12 py-8 border bg-gray-100 hover:bg-gray-200 border-gray-200 rounded-10 text-body5 font-medium`}
><Skeleton width={`${Math.round(random(8, 15))}ch`} />
</div>
})}
</ul>
</div>
<hr className="bg-gray-100" />
<div>
<h3 className="text-body2 font-bolder">📆 Founded</h3>
<p className='text-gray-600 mt-8'>Select the year you wish to see companies founded in.</p>
<div className="flex flex-wrap gap-48 mt-24">
{yearsFounded.map(year =>
<div key={year} className='flex gap-16 items-center'>
<input
name='yearFounded'
value={year}
checked={year === yearFoundedFilter}
className='input-radio self-center'
onChange={e => setYearFoundedFilter(e.target.value)}
type="radio" />
<label className="text-body4 text-gray-800" >
{year}
</label>
</div>)}
</div>
</div>
<div className="my-48"></div>
<div className='w-full bg-white content-container fixed bottom-0 left-0 py-24 border-t border-gray-200'>
<div className="flex justify-end gap-16">
<Button onClick={clearFilters}>Clear all</Button>
<Button color='primary' onClick={applyFilters}>Apply filters</Button>
</div>
</div>
</div>
</div>
</motion.div>
)
}

View File

@@ -0,0 +1,12 @@
query GetFilters {
categoryList {
id
name
icon
}
tags {
id
name
icon
}
}

View File

@@ -0,0 +1,4 @@
import { lazyModal } from 'src/utils/helperFunctions';
export const { LazyComponent: InsertLinkModal } = lazyModal(() => import('./FiltersModal'))

View File

@@ -18,7 +18,11 @@ query ProjectDetails($projectsId: String) {
website
yearFounded
telegram
subcategory
tags {
id
name
icon
}
stars
repository
openSource

View File

@@ -127,7 +127,7 @@ export default function ProjectDetailsCard({ direction, projectId, ...props }: P
{/* Title & Basic Info */}
<div className="flex flex-col mt-[-80px] md:flex-row md:mt-0 gap-24 md:items-center relative">
<div className="flex-shrink-0 w-[108px] h-[108px]">
<img className="w-full h-full border-2 border-white rounded-24" src={project?.logo?.[0]['thumbnails']['large'].url} alt="" />
<img className="w-full h-full border-2 border-white rounded-24 object-cover" src={project?.logo?.[0]['thumbnails']['large'].url} alt="" />
</div>
<div className='flex flex-col gap-8 items-start justify-between'>
<a href={project?.website!} target='_blank' rel="noreferrer"><h3 className="text-body1 font-bold">{project?.title}</h3></a>

View File

@@ -23,7 +23,9 @@ export type Query = {
backup: Maybe<Array<Maybe<Backup>>>;
categories: Maybe<Array<Maybe<Categories>>>;
categoryList: Maybe<Array<Maybe<CategoryList>>>;
companies: Maybe<Array<Maybe<Companies>>>;
projects: Maybe<Array<Maybe<Projects>>>;
stats: Maybe<Array<Maybe<Stats>>>;
tags: Maybe<Array<Maybe<Tags>>>;
};
@@ -137,6 +139,27 @@ export type QueryCategoryListArgs = {
};
export type QueryCompaniesArgs = {
_filter: InputMaybe<Scalars['JSON']>;
_order_by: InputMaybe<Scalars['JSON']>;
_page: InputMaybe<Scalars['JSON']>;
_page_size: InputMaybe<Scalars['JSON']>;
angelList: InputMaybe<Scalars['String']>;
assignee: InputMaybe<Scalars['String']>;
crunchbase: InputMaybe<Scalars['String']>;
description: InputMaybe<Scalars['String']>;
id: InputMaybe<Scalars['String']>;
industry: InputMaybe<Scalars['String']>;
location: InputMaybe<Scalars['String']>;
logo: InputMaybe<Array<InputMaybe<Scalars['JSON']>>>;
name: InputMaybe<Scalars['String']>;
projects: InputMaybe<Array<InputMaybe<Scalars['String']>>>;
status: InputMaybe<Scalars['String']>;
type: InputMaybe<Scalars['String']>;
website: InputMaybe<Scalars['String']>;
};
export type QueryProjectsArgs = {
_filter: InputMaybe<Scalars['JSON']>;
_order_by: InputMaybe<Scalars['JSON']>;
@@ -148,6 +171,7 @@ export type QueryProjectsArgs = {
categoryId: InputMaybe<Array<InputMaybe<Scalars['String']>>>;
categoryList: InputMaybe<Array<InputMaybe<Scalars['String']>>>;
comment: InputMaybe<Scalars['String']>;
company: InputMaybe<Array<InputMaybe<Scalars['String']>>>;
companyName: InputMaybe<Scalars['String']>;
createdAt: InputMaybe<Scalars['String']>;
dead: InputMaybe<Scalars['Boolean']>;
@@ -165,6 +189,7 @@ export type QueryProjectsArgs = {
stars: InputMaybe<Scalars['Float']>;
status: InputMaybe<Scalars['String']>;
subcategory: InputMaybe<Array<InputMaybe<Scalars['String']>>>;
tags: InputMaybe<Array<InputMaybe<Scalars['String']>>>;
telegram: InputMaybe<Scalars['String']>;
title: InputMaybe<Scalars['String']>;
twitter: InputMaybe<Scalars['String']>;
@@ -176,6 +201,17 @@ export type QueryProjectsArgs = {
};
export type QueryStatsArgs = {
_filter: InputMaybe<Scalars['JSON']>;
_order_by: InputMaybe<Scalars['JSON']>;
_page: InputMaybe<Scalars['JSON']>;
_page_size: InputMaybe<Scalars['JSON']>;
id: InputMaybe<Scalars['String']>;
stat: InputMaybe<Scalars['String']>;
totalProjects: InputMaybe<Scalars['String']>;
};
export type QueryTagsArgs = {
_filter: InputMaybe<Scalars['JSON']>;
_order_by: InputMaybe<Scalars['JSON']>;
@@ -190,6 +226,8 @@ export type QueryTagsArgs = {
importedTableCopy2: InputMaybe<Array<InputMaybe<Scalars['String']>>>;
name: InputMaybe<Scalars['String']>;
projectProductFromFeatured: InputMaybe<Array<InputMaybe<Scalars['String']>>>;
projects: InputMaybe<Array<InputMaybe<Scalars['String']>>>;
projectsCount: InputMaybe<Scalars['String']>;
};
export type ApiTesting = {
@@ -285,6 +323,23 @@ export type CategoryList = {
projectsCount: Maybe<Scalars['String']>;
};
export type Companies = {
__typename?: 'companies';
angelList: Maybe<Scalars['String']>;
assignee: Maybe<Scalars['String']>;
crunchbase: Maybe<Scalars['String']>;
description: Maybe<Scalars['String']>;
id: Maybe<Scalars['String']>;
industry: Maybe<Scalars['String']>;
location: Maybe<Scalars['String']>;
logo: Maybe<Array<Maybe<Scalars['JSON']>>>;
name: Maybe<Scalars['String']>;
projects: Maybe<Array<Maybe<Projects>>>;
status: Maybe<Scalars['String']>;
type: Maybe<Scalars['String']>;
website: Maybe<Scalars['String']>;
};
export type Projects = {
__typename?: 'projects';
categories: Maybe<Array<Maybe<Categories>>>;
@@ -293,6 +348,7 @@ export type Projects = {
categoryId: Maybe<Array<Maybe<Scalars['String']>>>;
categoryList: Maybe<Array<Maybe<CategoryList>>>;
comment: Maybe<Scalars['String']>;
company: Maybe<Array<Maybe<Companies>>>;
companyName: Maybe<Scalars['String']>;
createdAt: Maybe<Scalars['String']>;
dead: Maybe<Scalars['Boolean']>;
@@ -310,6 +366,7 @@ export type Projects = {
stars: Maybe<Scalars['Float']>;
status: Maybe<Scalars['String']>;
subcategory: Maybe<Array<Maybe<Scalars['String']>>>;
tags: Maybe<Array<Maybe<Tags>>>;
telegram: Maybe<Scalars['String']>;
title: Maybe<Scalars['String']>;
twitter: Maybe<Scalars['String']>;
@@ -320,6 +377,13 @@ export type Projects = {
yearFounded: Maybe<Scalars['Float']>;
};
export type Stats = {
__typename?: 'stats';
id: Maybe<Scalars['String']>;
stat: Maybe<Scalars['String']>;
totalProjects: Maybe<Scalars['String']>;
};
export type Tags = {
__typename?: 'tags';
description: Maybe<Scalars['String']>;
@@ -331,6 +395,8 @@ export type Tags = {
importedTableCopy2: Maybe<Array<Maybe<Backup>>>;
name: Maybe<Scalars['String']>;
projectProductFromFeatured: Maybe<Array<Maybe<Scalars['String']>>>;
projects: Maybe<Array<Maybe<Projects>>>;
projectsCount: Maybe<Scalars['String']>;
};
export type AllCategoriesQueryVariables = Exact<{
@@ -340,6 +406,11 @@ export type AllCategoriesQueryVariables = Exact<{
export type AllCategoriesQuery = { __typename?: 'Query', categoryList: Array<{ __typename?: 'categoryList', projectsCount: string | null, id: string | null, name: string | null, description: string | null, icon: string | null } | null> | null };
export type GetFiltersQueryVariables = Exact<{ [key: string]: never; }>;
export type GetFiltersQuery = { __typename?: 'Query', categoryList: Array<{ __typename?: 'categoryList', id: string | null, name: string | null, icon: string | null } | null> | null, tags: Array<{ __typename?: 'tags', id: string | null, name: string | null, icon: string | null } | null> | null };
export type ExplorePageQueryVariables = Exact<{
filter: InputMaybe<Scalars['JSON']>;
page: InputMaybe<Scalars['JSON']>;
@@ -354,7 +425,7 @@ export type ProjectDetailsQueryVariables = Exact<{
}>;
export type ProjectDetailsQuery = { __typename?: 'Query', projects: Array<{ __typename?: 'projects', id: string | null, title: string | null, dead: boolean | null, createdAt: string | null, companyName: string | null, category: string | null, description: string | null, discord: string | null, endDate: string | null, twitter: string | null, updatedAt: string | null, watchers: number | null, website: string | null, yearFounded: number | null, telegram: string | null, subcategory: Array<string | null> | null, stars: number | null, repository: string | null, openSource: string | null, logo: Array<any | null> | null, linkedIn: string | null, license: string | null, language: string | null, forks: number | null, categoryList: Array<{ __typename?: 'categoryList', name: string | null } | null> | null } | null> | null };
export type ProjectDetailsQuery = { __typename?: 'Query', projects: Array<{ __typename?: 'projects', id: string | null, title: string | null, dead: boolean | null, createdAt: string | null, companyName: string | null, category: string | null, description: string | null, discord: string | null, endDate: string | null, twitter: string | null, updatedAt: string | null, watchers: number | null, website: string | null, yearFounded: number | null, telegram: string | null, stars: number | null, repository: string | null, openSource: string | null, logo: Array<any | null> | null, linkedIn: string | null, license: string | null, language: string | null, forks: number | null, categoryList: Array<{ __typename?: 'categoryList', name: string | null } | null> | null, tags: Array<{ __typename?: 'tags', id: string | null, name: string | null, icon: string | null } | null> | null } | null> | null };
export const AllCategoriesDocument = gql`
@@ -396,6 +467,47 @@ export function useAllCategoriesLazyQuery(baseOptions?: Apollo.LazyQueryHookOpti
export type AllCategoriesQueryHookResult = ReturnType<typeof useAllCategoriesQuery>;
export type AllCategoriesLazyQueryHookResult = ReturnType<typeof useAllCategoriesLazyQuery>;
export type AllCategoriesQueryResult = Apollo.QueryResult<AllCategoriesQuery, AllCategoriesQueryVariables>;
export const GetFiltersDocument = gql`
query GetFilters {
categoryList {
id
name
icon
}
tags {
id
name
icon
}
}
`;
/**
* __useGetFiltersQuery__
*
* To run a query within a React component, call `useGetFiltersQuery` and pass it any options that fit your needs.
* When your component renders, `useGetFiltersQuery` returns an object from Apollo Client that contains loading, error, and data properties
* you can use to render your UI.
*
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useGetFiltersQuery({
* variables: {
* },
* });
*/
export function useGetFiltersQuery(baseOptions?: Apollo.QueryHookOptions<GetFiltersQuery, GetFiltersQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<GetFiltersQuery, GetFiltersQueryVariables>(GetFiltersDocument, options);
}
export function useGetFiltersLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetFiltersQuery, GetFiltersQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<GetFiltersQuery, GetFiltersQueryVariables>(GetFiltersDocument, options);
}
export type GetFiltersQueryHookResult = ReturnType<typeof useGetFiltersQuery>;
export type GetFiltersLazyQueryHookResult = ReturnType<typeof useGetFiltersLazyQuery>;
export type GetFiltersQueryResult = Apollo.QueryResult<GetFiltersQuery, GetFiltersQueryVariables>;
export const ExplorePageDocument = gql`
query ExplorePage($filter: JSON, $page: JSON, $pageSize: JSON) {
projects(_filter: $filter, _page: $page, _page_size: $pageSize) {
@@ -477,7 +589,11 @@ export const ProjectDetailsDocument = gql`
website
yearFounded
telegram
subcategory
tags {
id
name
icon
}
stars
repository
openSource

View File

@@ -15,6 +15,7 @@ import { ConfirmModal } from "src/Components/Modals/ConfirmModal";
import { ComponentProps } from "react";
import { generateId } from "src/utils/helperFunctions";
import { NoWeblnModal } from "src/Components/Modals/NoWeblnModal";
import FiltersModal from "src/features/Projects/pages/ExplorePage/Filters/FiltersModal";
// import { ConnectToMakerModal } from "src/features/Tournaments/pages/MakersPage/ConnectToMakerModal";
// import { RegistrationModals } from "src/features/Tournaments/pages/OverviewPage/RegisterationModals";
@@ -30,6 +31,7 @@ export enum Direction {
export const ALL_MODALS = {
//Projects
ProjectDetailsCard,
FiltersModal,
// Auth
Login_ScanningWalletCard,

View File

@@ -12,7 +12,7 @@ html {
body {
overflow-x: hidden;
background-color: #f9fafb;
background-color: #ffffff;
}
.content-container,