diff --git a/functions/graphql/nexus-typegen.ts b/functions/graphql/nexus-typegen.ts
index 69aeb90..8bfff43 100644
--- a/functions/graphql/nexus-typegen.ts
+++ b/functions/graphql/nexus-typegen.ts
@@ -443,7 +443,9 @@ export interface NexusGenArgTypes {
id: number; // Int!
}
getFeed: { // args
+ category: string | null; // String
skip?: number | null; // Int
+ sortBy: string | null; // String
take: number | null; // Int
}
getLnurlDetailsForProject: { // args
diff --git a/functions/graphql/schema.graphql b/functions/graphql/schema.graphql
index 35785cb..92330d5 100644
--- a/functions/graphql/schema.graphql
+++ b/functions/graphql/schema.graphql
@@ -102,7 +102,7 @@ type Query {
allCategories: [Category!]!
allProjects(skip: Int = 0, take: Int = 50): [Project!]!
getCategory(id: Int!): Category!
- getFeed(skip: Int = 0, take: Int = 10): [Post!]!
+ getFeed(category: String = "all", skip: Int = 0, sortBy: String = "all", take: Int = 10): [Post!]!
getLnurlDetailsForProject(project_id: Int!): LnurlDetails!
getPostById(id: Int!, type: POST_TYPE!): Post!
getProject(id: Int!): Project!
diff --git a/functions/graphql/types/post.js b/functions/graphql/types/post.js
index 6aae735..cc41d4b 100644
--- a/functions/graphql/types/post.js
+++ b/functions/graphql/types/post.js
@@ -125,7 +125,13 @@ const getFeed = extendType({
t.nonNull.list.nonNull.field('getFeed', {
type: "Post",
args: {
- ...paginationArgs({ take: 10 })
+ ...paginationArgs({ take: 10 }),
+ sortBy: stringArg({
+ default: "all"
+ }),
+ category: stringArg({
+ default: "all"
+ })
},
resolve(_, { take, skip }) {
const feed = []
diff --git a/package-lock.json b/package-lock.json
index 9108dd3..3330d1b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -51,6 +51,7 @@
"react-responsive-carousel": "^3.2.22",
"react-router-dom": "^6.2.2",
"react-scripts": "4.0.3",
+ "react-topbar-progress-indicator": "^4.1.1",
"typescript": "^4.4.4",
"web-vitals": "^1.1.2",
"webln": "^0.2.2"
@@ -53156,6 +53157,17 @@
"react": "^16.8.0 || ^17.0.0"
}
},
+ "node_modules/react-topbar-progress-indicator": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/react-topbar-progress-indicator/-/react-topbar-progress-indicator-4.1.1.tgz",
+ "integrity": "sha512-Oy3ENNKfymt16zoz5SYy/WOepMurB0oeZEyvuHm8JZ3jrTCe1oAUD7fG6HhYt5sg8Wcg5gdkzSWItaFF6c6VhA==",
+ "dependencies": {
+ "topbar": "^0.1.3"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
+ },
"node_modules/read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
@@ -57847,6 +57859,11 @@
"url": "https://github.com/sponsors/Borewit"
}
},
+ "node_modules/topbar": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/topbar/-/topbar-0.1.4.tgz",
+ "integrity": "sha512-P3n4WnN4GFd2mQXDo30rQmsAGe4V1bVkggtTreSbNyL50Fyc+eVkW5oatSLeGQmJoan2TLIgoXUZypN+6nw4MQ=="
+ },
"node_modules/tough-cookie": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
@@ -101774,6 +101791,14 @@
"use-latest": "^1.0.0"
}
},
+ "react-topbar-progress-indicator": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/react-topbar-progress-indicator/-/react-topbar-progress-indicator-4.1.1.tgz",
+ "integrity": "sha512-Oy3ENNKfymt16zoz5SYy/WOepMurB0oeZEyvuHm8JZ3jrTCe1oAUD7fG6HhYt5sg8Wcg5gdkzSWItaFF6c6VhA==",
+ "requires": {
+ "topbar": "^0.1.3"
+ }
+ },
"read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
@@ -105463,6 +105488,11 @@
"ieee754": "^1.2.1"
}
},
+ "topbar": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/topbar/-/topbar-0.1.4.tgz",
+ "integrity": "sha512-P3n4WnN4GFd2mQXDo30rQmsAGe4V1bVkggtTreSbNyL50Fyc+eVkW5oatSLeGQmJoan2TLIgoXUZypN+6nw4MQ=="
+ },
"tough-cookie": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
diff --git a/package.json b/package.json
index 03dc6de..6d66003 100644
--- a/package.json
+++ b/package.json
@@ -46,6 +46,7 @@
"react-responsive-carousel": "^3.2.22",
"react-router-dom": "^6.2.2",
"react-scripts": "4.0.3",
+ "react-topbar-progress-indicator": "^4.1.1",
"typescript": "^4.4.4",
"web-vitals": "^1.1.2",
"webln": "^0.2.2"
diff --git a/src/App.tsx b/src/App.tsx
index 7acbea1..4d1125f 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,15 +1,18 @@
-import { useEffect } from "react";
+import React, { Suspense, useEffect } from "react";
import Navbar from "src/Components/Navbar/Navbar";
-import ExplorePage from "src/features/Projects/pages/ExplorePage";
import ModalsContainer from "src/Components/Modals/ModalsContainer/ModalsContainer";
import { useAppSelector } from './utils/hooks';
import { Wallet_Service } from "./services";
import { Route, Routes } from "react-router-dom";
-import CategoryPage from "src/features/Projects/pages/CategoryPage/CategoryPage";
import { useWrapperSetup } from "./utils/Wrapper";
-import HottestPage from "src/features/Projects/pages/HottestPage/HottestPage";
-import FeedPage from "./features/Posts/pages/FeedPage/FeedPage";
-import PostDetailsPage from "./features/Posts/pages/PostDetailsPage/PostDetailsPage";
+import LoadingPage from "./Components/LoadingPage/LoadingPage";
+
+// Pages
+const FeedPage = React.lazy(() => import("./features/Posts/pages/FeedPage/FeedPage"))
+const HottestPage = React.lazy(() => import("src/features/Projects/pages/HottestPage/HottestPage"))
+const PostDetailsPage = React.lazy(() => import("./features/Posts/pages/PostDetailsPage/PostDetailsPage"))
+const CategoryPage = React.lazy(() => import("src/features/Projects/pages/CategoryPage/CategoryPage"))
+const ExplorePage = React.lazy(() => import("src/features/Projects/pages/ExplorePage"))
function App() {
const { isWalletConnected } = useAppSelector(state => ({
@@ -38,13 +41,15 @@ function App() {
return
-
- } />
- } />
- } />
- } />
- } />
-
+ }>
+
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
;
}
diff --git a/src/Components/LoadingPage/LoadingPage.jsx b/src/Components/LoadingPage/LoadingPage.jsx
new file mode 100644
index 0000000..0d39b37
--- /dev/null
+++ b/src/Components/LoadingPage/LoadingPage.jsx
@@ -0,0 +1,14 @@
+import TopBarProgress from "react-topbar-progress-indicator";
+import THEME from "src/utils/theme";
+
+TopBarProgress.config({
+ barColors: {
+ 0: THEME.colors.primary[400],
+ ".5": THEME.colors.primary[500],
+ "1.0": THEME.colors.primary[700],
+ },
+});
+
+export default function LoadingPage() {
+ return ;
+}
diff --git a/src/features/Posts/Components/TrendingCard/TrendingCard.tsx b/src/features/Posts/Components/TrendingCard/TrendingCard.tsx
index 913f578..be83a81 100644
--- a/src/features/Posts/Components/TrendingCard/TrendingCard.tsx
+++ b/src/features/Posts/Components/TrendingCard/TrendingCard.tsx
@@ -24,7 +24,7 @@ export default function TrendingCard() {
)
:
trendingPosts.data?.getTrendingPosts.map(post => {
- return
+ return
{post.title}
diff --git a/src/features/Posts/pages/FeedPage/FeedPage.tsx b/src/features/Posts/pages/FeedPage/FeedPage.tsx
index f35e79c..ffd33b3 100644
--- a/src/features/Posts/pages/FeedPage/FeedPage.tsx
+++ b/src/features/Posts/pages/FeedPage/FeedPage.tsx
@@ -1,4 +1,5 @@
+import { useReducer, useState } from 'react'
import { useFeedQuery } from 'src/graphql'
import { useAppSelector, useInfiniteQuery } from 'src/utils/hooks'
import PostsList from '../../Components/PostsList/PostsList'
@@ -10,10 +11,16 @@ import styles from './styles.module.css'
export default function FeedPage() {
+ const [sortByFilter, setSortByFilter] = useState('all')
+ const [categoryFilter, setCategoryFilter] = useState('all')
+
+
const feedQuery = useFeedQuery({
variables: {
take: 10,
- skip: 0
+ skip: 0,
+ sortBy: sortByFilter,
+ category: categoryFilter
},
})
const { fetchMore, isFetchingMore } = useInfiniteQuery(feedQuery, 'getFeed')
@@ -32,9 +39,13 @@ export default function FeedPage() {
maxHeight: `calc(100vh - ${navHeight}px - 16px)`,
overflowY: "scroll",
}}>
-
+
-
+
- // if (isQuestion(post))
- // return
+ if (isQuestion(post))
+ return
return null
diff --git a/src/features/Posts/pages/PostDetailsPage/Components/PageContent/QuestionPageContent.tsx b/src/features/Posts/pages/PostDetailsPage/Components/PageContent/QuestionPageContent.tsx
new file mode 100644
index 0000000..0ee7d7c
--- /dev/null
+++ b/src/features/Posts/pages/PostDetailsPage/Components/PageContent/QuestionPageContent.tsx
@@ -0,0 +1,39 @@
+import Header from "src/features/Posts/Components/PostCard/Header/Header"
+import { Question } from "src/features/Posts/types"
+import { marked } from 'marked';
+import styles from './styles.module.css'
+import Badge from "src/Components/Badge/Badge";
+import { BiComment } from "react-icons/bi";
+import { RiFlashlightLine } from "react-icons/ri";
+
+
+interface Props {
+ question: Question
+}
+
+export default function QuestionPageContent({ question }: Props) {
+ return (
+
+
+
+
{question.title}
+
+ {question.tags.map(tag =>
+ {tag.title}
+ )}
+
+
+
+ {question.votes_count} votes
+
+
+ 32 Comments
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.tsx b/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.tsx
index 1e2c90b..21d6529 100644
--- a/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.tsx
+++ b/src/features/Posts/pages/PostDetailsPage/PostDetailsPage.tsx
@@ -1,5 +1,6 @@
import { useParams } from 'react-router-dom'
+import LoadingPage from 'src/Components/LoadingPage/LoadingPage'
import { usePostDetailsQuery } from 'src/graphql'
import { useAppSelector, } from 'src/utils/hooks'
import TrendingCard from '../../Components/TrendingCard/TrendingCard'
@@ -17,7 +18,8 @@ export default function PostDetailsPage() {
id: Number(id!),
type: type as any
},
- skip: isNaN(Number(id))
+ skip: isNaN(Number(id)),
+
})
const { navHeight } = useAppSelector((state) => ({
@@ -25,7 +27,7 @@ export default function PostDetailsPage() {
}));
if (postDetailsQuery.loading)
- return Loading
+ return
const post = postDetailsQuery.data?.getPostById;
diff --git a/src/features/Projects/pages/ExplorePage/Header/Header.tsx b/src/features/Projects/pages/ExplorePage/Header/Header.tsx
index 5196565..7c37de7 100644
--- a/src/features/Projects/pages/ExplorePage/Header/Header.tsx
+++ b/src/features/Projects/pages/ExplorePage/Header/Header.tsx
@@ -2,7 +2,7 @@ import { useMediaQuery } from "@react-hookz/web";
import Carousel from "react-multi-carousel";
import Assets from "src/assets";
import Button from "src/Components/Button/Button";
-import { THEME } from "src/utils/theme";
+import THEME from "src/utils/theme";
import { MEDIA_QUERIES } from "src/utils/theme/media_queries";
import CustomDot from "./CustomDot/CustomDot";
import styles from './styles.module.css'
diff --git a/src/graphql/index.tsx b/src/graphql/index.tsx
index 0b91205..ccfeb7c 100644
--- a/src/graphql/index.tsx
+++ b/src/graphql/index.tsx
@@ -160,7 +160,9 @@ export type QueryGetCategoryArgs = {
export type QueryGetFeedArgs = {
+ category?: InputMaybe;
skip?: InputMaybe;
+ sortBy?: InputMaybe;
take?: InputMaybe;
};
@@ -278,8 +280,10 @@ export type TrendingPostsQueryVariables = Exact<{ [key: string]: never; }>;
export type TrendingPostsQuery = { __typename?: 'Query', getTrendingPosts: Array<{ __typename?: 'Bounty', id: number, title: string, author: { __typename?: 'User', id: number, image: string } } | { __typename?: 'Question', id: number, title: string, author: { __typename?: 'User', id: number, image: string } } | { __typename?: 'Story', id: number, title: string, author: { __typename?: 'User', id: number, image: string } }> };
export type FeedQueryVariables = Exact<{
- skip: InputMaybe;
take: InputMaybe;
+ skip: InputMaybe;
+ sortBy: InputMaybe;
+ category: InputMaybe;
}>;
@@ -475,8 +479,8 @@ export type TrendingPostsQueryHookResult = ReturnType;
export type TrendingPostsQueryResult = Apollo.QueryResult;
export const FeedDocument = gql`
- query Feed($skip: Int, $take: Int) {
- getFeed(skip: $skip, take: $take) {
+ query Feed($take: Int, $skip: Int, $sortBy: String, $category: String) {
+ getFeed(take: $take, skip: $skip, sortBy: $sortBy, category: $category) {
... on Story {
id
title
@@ -561,8 +565,10 @@ export const FeedDocument = gql`
* @example
* const { data, loading, error } = useFeedQuery({
* variables: {
- * skip: // value for 'skip'
* take: // value for 'take'
+ * skip: // value for 'skip'
+ * sortBy: // value for 'sortBy'
+ * category: // value for 'category'
* },
* });
*/
diff --git a/src/mocks/data/posts.ts b/src/mocks/data/posts.ts
index 512e5e7..801ecd1 100644
--- a/src/mocks/data/posts.ts
+++ b/src/mocks/data/posts.ts
@@ -153,5 +153,9 @@ const feedRandomer = new Chance('feed')
export const feed: Post[] = Array(30).fill(0).map((_, idx) => {
const post = feedRandomer.pickone([posts.bounties[0], posts.questions[0], posts.stories[0]])
- return { ...post, id: idx + 1, title: `${post.type} Title ${idx + 1}` }
+ return {
+ ...post, id: idx + 1, title: feedRandomer.sentence({
+ words: feedRandomer.integer({ min: 4, max: 7 })
+ })
+ }
})
diff --git a/src/utils/apollo.ts b/src/utils/apollo.ts
index 9cd5c6a..fd7e395 100644
--- a/src/utils/apollo.ts
+++ b/src/utils/apollo.ts
@@ -50,7 +50,7 @@ export const apolloClient = new ApolloClient({
typePolicies: {
Query: {
fields: {
- getFeed: offsetLimitPagination()
+ getFeed: offsetLimitPagination(['sortBy', 'category'])
},
},
},
diff --git a/src/utils/theme/colors.js b/src/utils/theme/colors.js
new file mode 100644
index 0000000..fbdbf12
--- /dev/null
+++ b/src/utils/theme/colors.js
@@ -0,0 +1,47 @@
+const colors = {
+ gray: {
+ 25: "#FCFCFD",
+ 50: "#F9FAFB",
+ 100: "#F2F4F7",
+ 200: "#E4E7EC",
+ 300: "#D0D5DD",
+ 400: "#98A2B3",
+ 500: "#667085",
+ 600: "#475467",
+ 700: "#344054",
+ 800: "#1D2939",
+ 900: "#101828",
+ },
+ primary: {
+ 25: "#FAF8FF",
+ 50: "#F5F2FF",
+ 100: "#E6DFFF",
+ 200: "#B3A0FF",
+ 300: "#B3A0FF",
+ 400: "#9E88FF",
+ 500: "#7B61FF",
+ 600: "#5C46DB",
+ 700: "#4230B7",
+ 800: "#2C1E93",
+ 900: "#1C127A",
+ },
+ sucess: {
+ 300: "#6CE9A6",
+ 400: "#32D583",
+ 500: "#12B76A",
+ 600: "#039855",
+ 700: "#027A48",
+ },
+ warning: {
+ 25: "#FFFCF5",
+ 50: "#FFFAEB",
+ 100: "#FEF0C7",
+ 200: "#FEDF89",
+ },
+
+ // Custom Colors
+ thunder: "#ffd400",
+ fire: "#ff6a00",
+}
+
+module.exports = { colors };
\ No newline at end of file
diff --git a/src/utils/theme/index.js b/src/utils/theme/index.js
new file mode 100644
index 0000000..45c08f9
--- /dev/null
+++ b/src/utils/theme/index.js
@@ -0,0 +1,11 @@
+
+const { colors } = require('./colors')
+const { MEDIA_QUERIES, screens } = require('./media_queries')
+
+const THEME = {
+ colors,
+ screens,
+ MEDIA_QUERIES
+}
+
+module.exports = THEME
diff --git a/src/utils/theme/index.ts b/src/utils/theme/index.ts
deleted file mode 100644
index 2bc2db3..0000000
--- a/src/utils/theme/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export * as THEME from './media_queries'
-
-const THEME = {}
-
-
-export default THEME;
\ No newline at end of file
diff --git a/src/utils/theme/media_queries.js b/src/utils/theme/media_queries.js
index e41f09d..ca2c678 100644
--- a/src/utils/theme/media_queries.js
+++ b/src/utils/theme/media_queries.js
@@ -1,4 +1,4 @@
-export const screens = {
+const screens = {
sm: 640,
md: 768,
lg: 1024,
@@ -6,9 +6,14 @@ export const screens = {
'2xl': 1536,
}
-export const MEDIA_QUERIES = {
+const MEDIA_QUERIES = {
isSmall: `only screen and (min-width : ${screens.sm}px)`,
isMedium: `only screen and (min-width : ${screens.md}px)`,
isLarge: `only screen and (min-width : ${screens.lg}px)`,
isXLarge: `only screen and (min-width : ${screens["2xl"]}px))`,
+}
+
+module.exports = {
+ screens,
+ MEDIA_QUERIES
}
\ No newline at end of file
diff --git a/tailwind.config.js b/tailwind.config.js
index 593fd99..731c3ce 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -1,3 +1,5 @@
+const THEME = require('./src/utils/theme')
+
module.exports = {
mode: "jit",
purge: [
@@ -10,51 +12,7 @@ module.exports = {
darkMode: false, // or 'media' or 'class'
theme: {
extend: {
- colors: {
- gray: {
- 25: "#FCFCFD",
- 50: "#F9FAFB",
- 100: "#F2F4F7",
- 200: "#E4E7EC",
- 300: "#D0D5DD",
- 400: "#98A2B3",
- 500: "#667085",
- 600: "#475467",
- 700: "#344054",
- 800: "#1D2939",
- 900: "#101828",
- },
- primary: {
- 25: "#FAF8FF",
- 50: "#F5F2FF",
- 100: "#E6DFFF",
- 200: "#B3A0FF",
- 300: "#B3A0FF",
- 400: "#9E88FF",
- 500: "#7B61FF",
- 600: "#5C46DB",
- 700: "#4230B7",
- 800: "#2C1E93",
- 900: "#1C127A",
- },
- sucess: {
- 300: "#6CE9A6",
- 400: "#32D583",
- 500: "#12B76A",
- 600: "#039855",
- 700: "#027A48",
- },
- warning: {
- 25: "#FFFCF5",
- 50: "#FFFAEB",
- 100: "#FEF0C7",
- 200: "#FEDF89",
- },
-
- // Custom Colors
- thunder: "#ffd400",
- fire: "#ff6a00",
- },
+ colors: THEME.colors,
boxShadow: {
xs: "0px 1px 2px rgba(16, 24, 40, 0.05)",
sm: