mirror of
https://github.com/aljazceru/landscape-template.git
synced 2026-01-06 07:54:21 +01:00
feat: connect feed filters apis with ui, change filters list style
This commit is contained in:
@@ -39,7 +39,7 @@ function App() {
|
||||
|
||||
|
||||
|
||||
return <div id="app" className='w-full overflow-hidden'>
|
||||
return <div id="app" className='w-full'>
|
||||
<Navbar />
|
||||
<Suspense fallback={<LoadingPage />}>
|
||||
<Routes>
|
||||
|
||||
@@ -199,20 +199,36 @@ export default function VoteButton({
|
||||
key={increment.id}
|
||||
className={styles.vote_counter}
|
||||
>+{increment.value}</span>)}
|
||||
{sparks.map(spark =>
|
||||
<div
|
||||
key={spark.id}
|
||||
className={styles.spark}
|
||||
|
||||
<div className="relative z-50">
|
||||
<MdLocalFireDepartment className={styles.spark}
|
||||
style={{
|
||||
"--offsetX": spark.offsetX,
|
||||
"--offsetY": spark.offsetY,
|
||||
"--animationSpeed": spark.animationSpeed,
|
||||
"--scale": spark.scale,
|
||||
"animationName": spark.animation,
|
||||
"color": spark.color
|
||||
} as any}
|
||||
><MdLocalFireDepartment className='' /></div>)
|
||||
}
|
||||
opacity: 1,
|
||||
scale: 1,
|
||||
top: 0,
|
||||
left: 0,
|
||||
color: 'green'
|
||||
}}
|
||||
/>
|
||||
{sparks.map(spark =>
|
||||
<div
|
||||
key={spark.id}
|
||||
className={styles.spark}
|
||||
style={{
|
||||
"--offsetX": spark.offsetX,
|
||||
"--offsetY": spark.offsetY,
|
||||
"--animationSpeed": spark.animationSpeed,
|
||||
"--scale": spark.scale,
|
||||
"animationName": spark.animation,
|
||||
"color": spark.color
|
||||
} as any}
|
||||
><MdLocalFireDepartment className='' /></div>)
|
||||
}
|
||||
</div>
|
||||
<div
|
||||
className={styles.spark}
|
||||
|
||||
><MdLocalFireDepartment className='' /></div>
|
||||
</button>
|
||||
|
||||
)
|
||||
|
||||
@@ -136,6 +136,7 @@
|
||||
transform: scale(var(--scale));
|
||||
opacity: 0;
|
||||
will-change: transform;
|
||||
z-index: 3000;
|
||||
|
||||
animation-name: fly-spark-1;
|
||||
animation-duration: calc(var(--animationSpeed) * 1s);
|
||||
|
||||
@@ -18,7 +18,7 @@ export default function HackathonsPage() {
|
||||
take: 10,
|
||||
skip: 0,
|
||||
sortBy: sortByFilter,
|
||||
category: topicsFilter
|
||||
topic: Number(topicsFilter)
|
||||
},
|
||||
})
|
||||
const { fetchMore, isFetchingMore } = useInfiniteQuery(feedQuery, 'getFeed')
|
||||
|
||||
@@ -12,7 +12,7 @@ interface Props {
|
||||
export default function CommentCard({ comment, onReply }: Props) {
|
||||
return (
|
||||
<div className="border rounded-12 p-24">
|
||||
<Header author={comment.author} date={comment.created_at} />
|
||||
<Header author={comment.author} date={comment.createdAt} />
|
||||
<p className="text-body4 mt-16">
|
||||
{comment.body}
|
||||
</p>
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Author } from "src/features/Posts/types";
|
||||
export interface Comment {
|
||||
id: number
|
||||
author: Author
|
||||
created_at: string
|
||||
createdAt: string
|
||||
body: string
|
||||
votes_count: number
|
||||
parentId: number | null
|
||||
|
||||
@@ -12,7 +12,7 @@ export type BountyCardType = Pick<Bounty,
|
||||
| 'type'
|
||||
| 'title'
|
||||
| 'cover_image'
|
||||
| 'date'
|
||||
| 'createdAt'
|
||||
| 'author'
|
||||
| 'excerpt'
|
||||
| 'votes_count'
|
||||
@@ -33,7 +33,7 @@ export default function BountyCard({ bounty }: Props) {
|
||||
<div className="bg-white rounded-12 overflow-hidden border">
|
||||
<img src={bounty.cover_image} className='h-[200px] w-full object-cover bg-gray-100' alt="" />
|
||||
<div className="p-24">
|
||||
<Header author={bounty.author} date={bounty.date} />
|
||||
<Header author={bounty.author} date={bounty.createdAt} />
|
||||
<div className="flex flex-col gap-8 md:gap-0 md:flex-row justify-between">
|
||||
<div>
|
||||
<Link to={`/blog/post/Bounty/${bounty.id}`}>
|
||||
|
||||
@@ -6,7 +6,7 @@ interface Props {
|
||||
author: {
|
||||
id: number,
|
||||
name: string,
|
||||
image: string
|
||||
avatar: string
|
||||
}
|
||||
date: string;
|
||||
size?: 'sm' | 'md' | 'lg';
|
||||
@@ -27,21 +27,25 @@ const nameSize: UnionToObjectKeys<Props, 'size'> = {
|
||||
|
||||
export default function Header({
|
||||
size = 'md',
|
||||
showTimeAgo = true,
|
||||
showTimeAgo = false,
|
||||
...props }: Props) {
|
||||
|
||||
const passedTime = dayjs().diff(props.date, 'hour');
|
||||
const dateToShow = passedTime < 24 ?
|
||||
`${dayjs().diff(props.date, 'hour')}h ago`
|
||||
:
|
||||
dayjs(props.date).format('MMMM DD');
|
||||
|
||||
const dateToShow = () => {
|
||||
const passedTime = dayjs().diff(props.date, 'hour');
|
||||
if (passedTime === 0) return 'now';
|
||||
if (passedTime < 24) return `${dayjs().diff(props.date, 'hour')}h ago`
|
||||
return dayjs(props.date).format('MMMM DD');
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className='flex gap-8'>
|
||||
<Avatar width={avatarSize[size]} src={props.author.image} />
|
||||
<Avatar width={avatarSize[size]} src={props.author.avatar} />
|
||||
<div>
|
||||
<p className={`${nameSize[size]} text-black font-medium`}>{props.author.name}</p>
|
||||
<p className={`text-body6 text-gray-600`}>{dateToShow}</p>
|
||||
<p className={`text-body6 text-gray-600`}>{dateToShow()}</p>
|
||||
</div>
|
||||
{/* {showTimeAgo && <p className={`${nameSize[size]} text-gray-500 ml-auto `}>
|
||||
{dayjs().diff(props.date, 'hour') < 24 ? `${dayjs().diff(props.date, 'hour')}h ago` : undefined}
|
||||
|
||||
@@ -11,7 +11,7 @@ export type QuestionCardType = Pick<Question,
|
||||
| 'id'
|
||||
| 'type'
|
||||
| 'title'
|
||||
| 'date'
|
||||
| 'createdAt'
|
||||
| 'author'
|
||||
| 'excerpt'
|
||||
| 'votes_count'
|
||||
@@ -22,7 +22,7 @@ export type QuestionCardType = Pick<Question,
|
||||
| 'id'
|
||||
| 'author'
|
||||
| 'body'
|
||||
| 'created_at'
|
||||
| 'createdAt'
|
||||
>>
|
||||
};
|
||||
interface Props {
|
||||
@@ -33,7 +33,7 @@ export default function QuestionCard({ question }: Props) {
|
||||
<div className="bg-white rounded-12 overflow-hidden border">
|
||||
{/* <img src={question.cover_image} className='h-[200px] w-full object-cover' alt="" /> */}
|
||||
<div className="p-24">
|
||||
<Header author={question.author} date={question.date} />
|
||||
<Header author={question.author} date={question.createdAt} />
|
||||
<div className="flex justify-between">
|
||||
<Link to={`/blog/post/Question/${question.id}`}>
|
||||
<h2 className="text-h5 font-bolder mt-16">{question.title}</h2>
|
||||
@@ -61,7 +61,7 @@ export default function QuestionCard({ question }: Props) {
|
||||
<div className="flex p-16 mt-16 flex-col gap-10 bg-gray-50">
|
||||
<div className="flex flex-col gap-10">
|
||||
{question.comments.slice(0, 2).map(comment => <div key={comment.id} className="border-b last-of-type:border-b-0 pb-8 " >
|
||||
<Header author={comment.author} size='sm' date={comment.created_at} />
|
||||
<Header author={comment.author} size='sm' date={comment.createdAt} />
|
||||
<p className="text-body5 text-gray-600 mt-8">{trimText(comment.body, 80)}</p>
|
||||
</div>)}
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,7 @@ export type StoryCardType = Pick<Story,
|
||||
| 'type'
|
||||
| 'title'
|
||||
| 'cover_image'
|
||||
| 'date'
|
||||
| 'createdAt'
|
||||
| 'author'
|
||||
| 'excerpt'
|
||||
| 'votes_count'
|
||||
@@ -25,7 +25,7 @@ export default function StoryCard({ story }: Props) {
|
||||
<div className="bg-white rounded-12 overflow-hidden border">
|
||||
<img src={story.cover_image} className='h-[200px] w-full object-cover' alt="" />
|
||||
<div className="p-24">
|
||||
<Header author={story.author} date={story.date} />
|
||||
<Header author={story.author} date={story.createdAt} />
|
||||
<Link to={`/blog/post/Story/${story.id}`}>
|
||||
<h2 className="text-h5 font-bolder mt-16">{story.title}</h2>
|
||||
</Link>
|
||||
|
||||
@@ -26,7 +26,7 @@ export default function TrendingCard() {
|
||||
trendingPosts.data?.getTrendingPosts.map(post => {
|
||||
return <Link key={post.id} to={`/blog/post/${post.__typename}/${post.id}`} className="border-b pb-4 last-of-type:border-b-0">
|
||||
<li className="flex items-start gap-8">
|
||||
<Avatar width={24} src={post.author.image} />
|
||||
<Avatar width={24} src={post.author.avatar} />
|
||||
<p className="text-body5 font-medium">{post.title}</p>
|
||||
</li>
|
||||
</Link>
|
||||
|
||||
@@ -5,7 +5,7 @@ query TrendingPosts {
|
||||
title
|
||||
author {
|
||||
id
|
||||
image
|
||||
avatar
|
||||
}
|
||||
}
|
||||
... on Bounty {
|
||||
@@ -13,7 +13,7 @@ query TrendingPosts {
|
||||
title
|
||||
author {
|
||||
id
|
||||
image
|
||||
avatar
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ query TrendingPosts {
|
||||
title
|
||||
author {
|
||||
id
|
||||
image
|
||||
avatar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useFeedQuery } from 'src/graphql'
|
||||
import { useAppSelector, useInfiniteQuery } from 'src/utils/hooks'
|
||||
import PostsList from '../../Components/PostsList/PostsList'
|
||||
import TrendingCard from '../../Components/TrendingCard/TrendingCard'
|
||||
import PopularCategories from './PopularCategories/PopularCategories'
|
||||
import PopularTopicsFilter from './PopularTopicsFilter/PopularTopicsFilter'
|
||||
import SortBy from './SortBy/SortBy'
|
||||
import styles from './styles.module.scss'
|
||||
|
||||
@@ -12,15 +12,15 @@ import styles from './styles.module.scss'
|
||||
export default function FeedPage() {
|
||||
|
||||
const [sortByFilter, setSortByFilter] = useState('all')
|
||||
const [categoryFilter, setCategoryFilter] = useState('all')
|
||||
const [topicFilter, setTopicFilter] = useState<number | null>(null)
|
||||
|
||||
|
||||
const feedQuery = useFeedQuery({
|
||||
variables: {
|
||||
take: 10,
|
||||
take: 3,
|
||||
skip: 0,
|
||||
sortBy: sortByFilter,
|
||||
category: categoryFilter
|
||||
topic: topicFilter
|
||||
},
|
||||
})
|
||||
const { fetchMore, isFetchingMore } = useInfiniteQuery(feedQuery, 'getFeed')
|
||||
@@ -42,9 +42,9 @@ export default function FeedPage() {
|
||||
<SortBy
|
||||
filterChanged={setSortByFilter}
|
||||
/>
|
||||
<hr className="my-24 bg-gray-100" />
|
||||
<PopularCategories
|
||||
filterChanged={setCategoryFilter}
|
||||
<div className="my-24"></div>
|
||||
<PopularTopicsFilter
|
||||
filterChanged={setTopicFilter}
|
||||
/>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||
|
||||
import PopularCategories from './PopularCategories';
|
||||
|
||||
export default {
|
||||
title: 'Posts/Feed Page/Components/PopularCategories',
|
||||
component: PopularCategories,
|
||||
argTypes: {
|
||||
backgroundColor: { control: 'color' },
|
||||
},
|
||||
} as ComponentMeta<typeof PopularCategories>;
|
||||
|
||||
|
||||
const Template: ComponentStory<typeof PopularCategories> = (args) => <div className="max-w-[326px]"><PopularCategories {...args as any} ></PopularCategories></div>
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
}
|
||||
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
import React, { useState } from 'react'
|
||||
|
||||
const filters = [
|
||||
{
|
||||
text: "🔥 All",
|
||||
value: 'all'
|
||||
}, {
|
||||
text: "Lightning Network",
|
||||
value: 'lightning-network'
|
||||
}, {
|
||||
text: "Bitcoin",
|
||||
value: 'bitcoin'
|
||||
}, {
|
||||
text: "Cybersecurity",
|
||||
value: 'cybersecurity'
|
||||
}, {
|
||||
text: "Bounties",
|
||||
value: 'bounties'
|
||||
}, {
|
||||
text: "Grants",
|
||||
value: 'Grants'
|
||||
},
|
||||
]
|
||||
|
||||
interface Props {
|
||||
filterChanged?: (newFilter: string) => void
|
||||
}
|
||||
|
||||
export default function PopularCategories({ filterChanged }: Props) {
|
||||
|
||||
const [selected, setSelected] = useState(filters[0].value);
|
||||
|
||||
const filterClicked = (newValue: string) => {
|
||||
if (selected === newValue)
|
||||
return
|
||||
setSelected(newValue);
|
||||
filterChanged?.(newValue);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className=''>
|
||||
<p className="text-body2 font-bolder text-black mb-16">Popular Categories</p>
|
||||
<ul>
|
||||
{filters.map((f, idx) => <li
|
||||
key={f.value}
|
||||
className={`p-12 rounded-8 cursor-pointer font-bold ${f.value === selected && 'bg-gray-100'}`}
|
||||
onClick={() => filterClicked(f.value)}
|
||||
>
|
||||
{f.text}
|
||||
</li>)}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||
|
||||
import PopularTopicsFilter from './PopularTopicsFilter';
|
||||
|
||||
export default {
|
||||
title: 'Posts/Feed Page/Components/Popular Topics Filter',
|
||||
component: PopularTopicsFilter,
|
||||
argTypes: {
|
||||
backgroundColor: { control: 'color' },
|
||||
},
|
||||
} as ComponentMeta<typeof PopularTopicsFilter>;
|
||||
|
||||
|
||||
const Template: ComponentStory<typeof PopularTopicsFilter> = (args) => <div className="max-w-[326px]"><PopularTopicsFilter {...args as any} ></PopularTopicsFilter></div>
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
import React, { useState } from 'react'
|
||||
import Skeleton from 'react-loading-skeleton';
|
||||
import { usePopularTopicsQuery } from 'src/graphql';
|
||||
|
||||
const filters = [
|
||||
{
|
||||
text: "🔥 All",
|
||||
value: 0
|
||||
}, {
|
||||
text: "Lightning Network",
|
||||
value: 1
|
||||
}, {
|
||||
text: "Bitcoin",
|
||||
value: 2
|
||||
}, {
|
||||
text: "Cybersecurity",
|
||||
value: 3
|
||||
}, {
|
||||
text: "Bounties",
|
||||
value: 4
|
||||
}, {
|
||||
text: "Grants",
|
||||
value: 5
|
||||
},
|
||||
]
|
||||
|
||||
interface Props {
|
||||
filterChanged?: (newFilter: number) => void
|
||||
}
|
||||
|
||||
export default function PopularTopicsFilter({ filterChanged }: Props) {
|
||||
|
||||
const [selected, setSelected] = useState(filters[0].value);
|
||||
|
||||
const topicsQuery = usePopularTopicsQuery();
|
||||
|
||||
|
||||
const filterClicked = (newValue: number) => {
|
||||
if (selected === newValue)
|
||||
return
|
||||
setSelected(newValue);
|
||||
filterChanged?.(newValue);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='bg-white border rounded-12 p-16'>
|
||||
<p className="text-body2 font-bolder text-black mb-16">Topics</p>
|
||||
<ul className=' flex flex-col gap-16'>
|
||||
{topicsQuery.loading ?
|
||||
Array(4).fill(0).map((_, idx) => <li
|
||||
key={idx}
|
||||
className={`flex items-start rounded-8 font-bold`}
|
||||
|
||||
>
|
||||
<span className='bg-gray-50 rounded-8 w-40 h-40 text-center py-8'> </span>
|
||||
<span className="self-center px-16"><Skeleton width={'10ch'} />
|
||||
</span>
|
||||
</li>
|
||||
)
|
||||
:
|
||||
topicsQuery.data?.popularTopics.map((f, idx) => <li
|
||||
key={f.id}
|
||||
className={`flex items-start rounded-8 cursor-pointer font-bold ${f.id === selected && 'bg-gray-50'}`}
|
||||
onClick={() => filterClicked(f.id)}
|
||||
>
|
||||
<span className='bg-gray-50 rounded-8 w-40 h-40 text-center py-8'>{f.icon}</span>
|
||||
<span className="self-center px-16">
|
||||
{f.title}
|
||||
</span>
|
||||
</li>)}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
query PopularTopics {
|
||||
popularTopics {
|
||||
id
|
||||
title
|
||||
icon
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ export default function SortBy({ filterChanged }: Props) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className=''>
|
||||
<div className='bg-white border rounded-12 p-16'>
|
||||
<p className="text-body2 font-bolder text-black mb-16">Sort By</p>
|
||||
<ul>
|
||||
{filters.map((f, idx) => <li
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
query Feed($take: Int, $skip: Int, $sortBy: String, $category: String) {
|
||||
getFeed(take: $take, skip: $skip, sortBy: $sortBy, category: $category) {
|
||||
query Feed($take: Int, $skip: Int, $sortBy: String, $topic: Int) {
|
||||
getFeed(take: $take, skip: $skip, sortBy: $sortBy, topic: $topic) {
|
||||
... on Story {
|
||||
id
|
||||
title
|
||||
date
|
||||
createdAt
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
excerpt
|
||||
tags {
|
||||
@@ -22,11 +22,11 @@ query Feed($take: Int, $skip: Int, $sortBy: String, $category: String) {
|
||||
... on Bounty {
|
||||
id
|
||||
title
|
||||
date
|
||||
createdAt
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
excerpt
|
||||
tags {
|
||||
@@ -43,11 +43,11 @@ query Feed($take: Int, $skip: Int, $sortBy: String, $category: String) {
|
||||
... on Question {
|
||||
id
|
||||
title
|
||||
date
|
||||
createdAt
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
excerpt
|
||||
tags {
|
||||
@@ -59,12 +59,12 @@ query Feed($take: Int, $skip: Int, $sortBy: String, $category: String) {
|
||||
answers_count
|
||||
comments {
|
||||
id
|
||||
created_at
|
||||
createdAt
|
||||
body
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ export default function AuthorCard({ author }: Props) {
|
||||
return (
|
||||
<div className="bg-white p-16 border rounded-8">
|
||||
<div className='flex gap-8'>
|
||||
<Avatar width={48} src={author.image} />
|
||||
<Avatar width={48} src={author.avatar} />
|
||||
<div>
|
||||
<p className={`'text-body4' text-black font-medium`}>{author.name}</p>
|
||||
<p className={`text-body6 text-gray-600`}>Joined on {dayjs(author.join_date).format('MMMM DD, YYYY')}</p>
|
||||
|
||||
@@ -9,6 +9,8 @@ import Button from "src/Components/Button/Button";
|
||||
import { FiGithub, FiShare2 } from "react-icons/fi";
|
||||
import BountyApplicants from "./BountyApplicants";
|
||||
import VoteButton from "src/Components/VoteButton/VoteButton";
|
||||
import { RiFlashlightLine } from "react-icons/ri";
|
||||
import { numberFormatter } from "src/utils/helperFunctions";
|
||||
|
||||
|
||||
interface Props {
|
||||
@@ -21,14 +23,16 @@ export default function BountyPageContent({ bounty }: Props) {
|
||||
|
||||
{/* Header */}
|
||||
<div className="flex flex-col gap-24">
|
||||
<Header size="lg" showTimeAgo={false} author={bounty.author} date={bounty.date} />
|
||||
<Header size="lg" showTimeAgo={false} author={bounty.author} date={bounty.createdAt} />
|
||||
<h1 className="text-h2 font-bolder">{bounty.title} <Badge color="none" size="sm" className="bg-warning-500 text-black">Bounty</Badge></h1>
|
||||
<div className="">
|
||||
<span className="text-body4 text-gray-600 font-bolder">Reward: </span>
|
||||
<span className="text-body4 text-purple-500 font-medium">{bounty.reward_amount} sats</span>
|
||||
</div>
|
||||
<div className="flex gap-24 items-center">
|
||||
<VoteButton initVotes={bounty.votes_count} />
|
||||
<div className="text-black font-medium">
|
||||
<RiFlashlightLine /> <span className="align-middle text-body5">{numberFormatter(bounty.votes_count)} votes</span>
|
||||
</div>
|
||||
<div className="text-black font-medium">
|
||||
<BiComment /> <span className="align-middle text-body5">32 Comments</span>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { BsBookmark } from "react-icons/bs"
|
||||
import { MdIosShare, MdLocalFireDepartment } from "react-icons/md"
|
||||
import { MdIosShare } from "react-icons/md"
|
||||
import VoteButton from "src/Components/VoteButton/VoteButton"
|
||||
|
||||
interface Props {
|
||||
votes_count: number
|
||||
}
|
||||
|
||||
|
||||
export default function PostActions() {
|
||||
export default function PostActions(props: Props) {
|
||||
|
||||
const actions = [
|
||||
{
|
||||
@@ -19,7 +21,7 @@ export default function PostActions() {
|
||||
|
||||
return (
|
||||
<ul className="bg-white rounded-12 p-16 border flex justify-around md:flex-col gap-32">
|
||||
<VoteButton initVotes={123} direction='vertical' fillType="upDown" />
|
||||
<VoteButton initVotes={props.votes_count} direction='vertical' fillType="upDown" />
|
||||
{actions.map((action, idx) => <li
|
||||
className={`py-8 px-20 text-body5 flex flex-col justify-center items-center cursor-pointer rounded-8
|
||||
${'text-gray-500 hover:bg-gray-50 active:bg-gray-100'}`}>
|
||||
|
||||
@@ -6,6 +6,7 @@ import Badge from "src/Components/Badge/Badge";
|
||||
import { BiComment } from "react-icons/bi";
|
||||
import { RiFlashlightLine } from "react-icons/ri";
|
||||
import { CommentsSection } from "src/features/Posts/Components/Comments";
|
||||
import { numberFormatter } from "src/utils/helperFunctions";
|
||||
|
||||
|
||||
interface Props {
|
||||
@@ -17,7 +18,7 @@ export default function QuestionPageContent({ question }: Props) {
|
||||
<>
|
||||
<div id="content" className="bg-white p-32 border rounded-16">
|
||||
<div className="flex flex-col gap-24">
|
||||
<Header size="lg" showTimeAgo={false} author={question.author} date={question.date} />
|
||||
<Header size="lg" showTimeAgo={false} author={question.author} date={question.createdAt} />
|
||||
<h1 className="text-h2 font-bolder">{question.title}</h1>
|
||||
<div className="flex gap-8">
|
||||
{question.tags.map(tag => <Badge key={tag.id} size='sm'>
|
||||
@@ -26,7 +27,7 @@ export default function QuestionPageContent({ question }: Props) {
|
||||
</div>
|
||||
<div className="flex gap-24">
|
||||
<div className="text-black font-medium">
|
||||
<RiFlashlightLine /> <span className="align-middle text-body5">{question.votes_count} votes</span>
|
||||
<RiFlashlightLine /> <span className="align-middle text-body5">{numberFormatter(question.votes_count)} votes</span>
|
||||
</div>
|
||||
<div className="text-black font-medium">
|
||||
<BiComment /> <span className="align-middle text-body5">32 Comments</span>
|
||||
@@ -38,9 +39,9 @@ export default function QuestionPageContent({ question }: Props) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="comments" className="mt-10">
|
||||
{/* <div id="comments" className="mt-10">
|
||||
<CommentsSection comments={question.comments} />
|
||||
</div>
|
||||
</div> */}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import Badge from "src/Components/Badge/Badge";
|
||||
import { BiComment } from "react-icons/bi";
|
||||
import { RiFlashlightLine } from "react-icons/ri";
|
||||
import { CommentsSection } from "src/features/Posts/Components/Comments";
|
||||
import { numberFormatter } from "src/utils/helperFunctions";
|
||||
|
||||
|
||||
interface Props {
|
||||
@@ -17,16 +18,16 @@ export default function StoryPageContent({ story }: Props) {
|
||||
<>
|
||||
<div id="content" className="bg-white p-32 border rounded-16">
|
||||
<div className="flex flex-col gap-24">
|
||||
<Header size="lg" showTimeAgo={false} author={story.author} date={story.date} />
|
||||
<Header size="lg" showTimeAgo={false} author={story.author} date={story.createdAt} />
|
||||
<h1 className="text-h2 font-bolder">{story.title}</h1>
|
||||
<div className="flex gap-8">
|
||||
{story.tags.length > 0 && <div className="flex gap-8">
|
||||
{story.tags.map(tag => <Badge key={tag.id} size='sm'>
|
||||
{tag.title}
|
||||
</Badge>)}
|
||||
</div>
|
||||
</div>}
|
||||
<div className="flex gap-24">
|
||||
<div className="text-black font-medium">
|
||||
<RiFlashlightLine /> <span className="align-middle text-body5">{story.votes_count} votes</span>
|
||||
<RiFlashlightLine /> <span className="align-middle text-body5">{numberFormatter(story.votes_count)} votes</span>
|
||||
</div>
|
||||
<div className="text-black font-medium">
|
||||
<BiComment /> <span className="align-middle text-body5">{story.comments_count} Comments</span>
|
||||
@@ -37,9 +38,9 @@ export default function StoryPageContent({ story }: Props) {
|
||||
<div className={`mt-42 ${styles.body}`} dangerouslySetInnerHTML={{ __html: marked.parse(story.body) }}>
|
||||
</div>
|
||||
</div>
|
||||
<div id="comments" className="mt-10 comments_col">
|
||||
{/* <div id="comments" className="mt-10 comments_col">
|
||||
<CommentsSection comments={story.comments} />
|
||||
</div>
|
||||
</div> */}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ export default function PostDetailsPage() {
|
||||
top: `${navHeight + 16}px`,
|
||||
maxHeight: `calc(100vh - ${navHeight}px - 16px)`,
|
||||
}}>
|
||||
<PostActions />
|
||||
<PostActions votes_count={post.votes_count} />
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@ query PostDetails($id: Int!, $type: POST_TYPE!) {
|
||||
... on Story {
|
||||
id
|
||||
title
|
||||
date
|
||||
createdAt
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
body
|
||||
tags {
|
||||
@@ -20,25 +20,25 @@ query PostDetails($id: Int!, $type: POST_TYPE!) {
|
||||
comments_count
|
||||
comments {
|
||||
id
|
||||
created_at
|
||||
createdAt
|
||||
body
|
||||
votes_count
|
||||
parentId
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
}
|
||||
}
|
||||
... on Bounty {
|
||||
id
|
||||
title
|
||||
date
|
||||
createdAt
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
body
|
||||
tags {
|
||||
@@ -58,18 +58,18 @@ query PostDetails($id: Int!, $type: POST_TYPE!) {
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
}
|
||||
}
|
||||
... on Question {
|
||||
id
|
||||
title
|
||||
date
|
||||
createdAt
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
body
|
||||
tags {
|
||||
@@ -81,14 +81,14 @@ query PostDetails($id: Int!, $type: POST_TYPE!) {
|
||||
answers_count
|
||||
comments {
|
||||
id
|
||||
created_at
|
||||
createdAt
|
||||
body
|
||||
votes_count
|
||||
parentId
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Tag } from "src/utils/interfaces"
|
||||
export type User = {
|
||||
id: number
|
||||
name: string
|
||||
image: string
|
||||
avatar: string
|
||||
}
|
||||
|
||||
export type Author = User & {
|
||||
@@ -14,7 +14,7 @@ export type Author = User & {
|
||||
export type PostBase1 = {
|
||||
id: number
|
||||
title: string
|
||||
date: string
|
||||
createdAt: string
|
||||
author: Author
|
||||
excerpt: string
|
||||
tags: Tag[]
|
||||
|
||||
@@ -4,14 +4,16 @@ import ProjectsSection from "./ProjectsSection/ProjectsSection";
|
||||
|
||||
export default function ExplorePage() {
|
||||
return (
|
||||
<>
|
||||
<div className="px-32">
|
||||
<Header />
|
||||
</div>
|
||||
<div className="page-container">
|
||||
|
||||
<Header />
|
||||
|
||||
{/* <div className="my-40 px-32">
|
||||
<Categories />
|
||||
</div> */}
|
||||
<ProjectsSection />
|
||||
</>
|
||||
<div className="w-full overflow-hidden">
|
||||
<ProjectsSection />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@ export default function ProjectsRowSkeleton() {
|
||||
|
||||
return (
|
||||
<div className='mb-48'>
|
||||
<h3 className="font-bolder text-body3 mb-24 px-32">
|
||||
<h3 className="font-bolder text-body3 mb-24">
|
||||
<Skeleton width='10ch' />
|
||||
</h3>
|
||||
<div className="p-32 flex gap-20">
|
||||
<div className=" flex gap-20">
|
||||
{Array(5).fill(0).map((_, idx) => (
|
||||
<ProjectCardMiniSkeleton key={idx} />
|
||||
))}
|
||||
|
||||
@@ -83,13 +83,13 @@ export default function ProjectsRow({ title, categoryId, projects }: Props) {
|
||||
|
||||
return (
|
||||
<div className='mb-48'>
|
||||
<h3 className="font-bolder text-body3 mb-24 px-32">
|
||||
<h3 className="font-bolder text-body3 mb-24">
|
||||
<span className="align-middle">{title}</span>
|
||||
{categoryId > 0 && <Link to={`/category/${categoryId}`}>
|
||||
<MdDoubleArrow className='text-gray-200 ml-8 hover:cursor-pointer transform scale-y-110 scale-x-125 origin-left' />
|
||||
</Link>}
|
||||
</h3>
|
||||
<div className="px-32">
|
||||
<div className="">
|
||||
<Carousel
|
||||
showDots={false}
|
||||
autoPlay={false}
|
||||
|
||||
@@ -13,6 +13,8 @@ export type Scalars = {
|
||||
Boolean: boolean;
|
||||
Int: number;
|
||||
Float: number;
|
||||
/** Date custom scalar type */
|
||||
Date: any;
|
||||
};
|
||||
|
||||
export type Award = {
|
||||
@@ -31,7 +33,7 @@ export type Bounty = PostBase & {
|
||||
author: User;
|
||||
body: Scalars['String'];
|
||||
cover_image: Scalars['String'];
|
||||
date: Scalars['String'];
|
||||
createdAt: Scalars['Date'];
|
||||
deadline: Scalars['String'];
|
||||
excerpt: Scalars['String'];
|
||||
id: Scalars['Int'];
|
||||
@@ -73,6 +75,7 @@ export type Mutation = {
|
||||
__typename?: 'Mutation';
|
||||
confirmVote: Vote;
|
||||
vote: Vote;
|
||||
vote2: Vote2;
|
||||
};
|
||||
|
||||
|
||||
@@ -87,6 +90,13 @@ export type MutationVoteArgs = {
|
||||
project_id: Scalars['Int'];
|
||||
};
|
||||
|
||||
|
||||
export type MutationVote2Args = {
|
||||
amount_in_sat: Scalars['Int'];
|
||||
item_id: Scalars['Int'];
|
||||
item_type: Vote_Item_Type;
|
||||
};
|
||||
|
||||
export enum Post_Type {
|
||||
Bounty = 'Bounty',
|
||||
Question = 'Question',
|
||||
@@ -96,12 +106,10 @@ export enum Post_Type {
|
||||
export type Post = Bounty | Question | Story;
|
||||
|
||||
export type PostBase = {
|
||||
author: User;
|
||||
body: Scalars['String'];
|
||||
date: Scalars['String'];
|
||||
createdAt: Scalars['Date'];
|
||||
excerpt: Scalars['String'];
|
||||
id: Scalars['Int'];
|
||||
tags: Array<Tag>;
|
||||
title: Scalars['String'];
|
||||
votes_count: Scalars['Int'];
|
||||
};
|
||||
@@ -110,7 +118,7 @@ export type PostComment = {
|
||||
__typename?: 'PostComment';
|
||||
author: User;
|
||||
body: Scalars['String'];
|
||||
created_at: Scalars['String'];
|
||||
createdAt: Scalars['Date'];
|
||||
id: Scalars['Int'];
|
||||
parentId: Maybe<Scalars['Int']>;
|
||||
votes_count: Scalars['Int'];
|
||||
@@ -137,6 +145,7 @@ export type Query = {
|
||||
__typename?: 'Query';
|
||||
allCategories: Array<Category>;
|
||||
allProjects: Array<Project>;
|
||||
allTopics: Array<Topic>;
|
||||
getCategory: Category;
|
||||
getFeed: Array<Post>;
|
||||
getLnurlDetailsForProject: LnurlDetails;
|
||||
@@ -145,6 +154,7 @@ export type Query = {
|
||||
getTrendingPosts: Array<Post>;
|
||||
hottestProjects: Array<Project>;
|
||||
newProjects: Array<Project>;
|
||||
popularTopics: Array<Topic>;
|
||||
projectsByCategory: Array<Project>;
|
||||
searchProjects: Array<Project>;
|
||||
};
|
||||
@@ -162,10 +172,10 @@ export type QueryGetCategoryArgs = {
|
||||
|
||||
|
||||
export type QueryGetFeedArgs = {
|
||||
category?: InputMaybe<Scalars['String']>;
|
||||
skip?: InputMaybe<Scalars['Int']>;
|
||||
sortBy?: InputMaybe<Scalars['String']>;
|
||||
take?: InputMaybe<Scalars['Int']>;
|
||||
topic?: InputMaybe<Scalars['Int']>;
|
||||
};
|
||||
|
||||
|
||||
@@ -216,7 +226,7 @@ export type Question = PostBase & {
|
||||
author: User;
|
||||
body: Scalars['String'];
|
||||
comments: Array<PostComment>;
|
||||
date: Scalars['String'];
|
||||
createdAt: Scalars['Date'];
|
||||
excerpt: Scalars['String'];
|
||||
id: Scalars['Int'];
|
||||
tags: Array<Tag>;
|
||||
@@ -232,11 +242,12 @@ export type Story = PostBase & {
|
||||
comments: Array<PostComment>;
|
||||
comments_count: Scalars['Int'];
|
||||
cover_image: Scalars['String'];
|
||||
date: Scalars['String'];
|
||||
createdAt: Scalars['Date'];
|
||||
excerpt: Scalars['String'];
|
||||
id: Scalars['Int'];
|
||||
tags: Array<Tag>;
|
||||
title: Scalars['String'];
|
||||
topic: Topic;
|
||||
type: Scalars['String'];
|
||||
votes_count: Scalars['Int'];
|
||||
};
|
||||
@@ -247,13 +258,29 @@ export type Tag = {
|
||||
title: Scalars['String'];
|
||||
};
|
||||
|
||||
export type Topic = {
|
||||
__typename?: 'Topic';
|
||||
icon: Scalars['String'];
|
||||
id: Scalars['Int'];
|
||||
title: Scalars['String'];
|
||||
};
|
||||
|
||||
export type User = {
|
||||
__typename?: 'User';
|
||||
avatar: Scalars['String'];
|
||||
id: Scalars['Int'];
|
||||
image: Scalars['String'];
|
||||
name: Scalars['String'];
|
||||
};
|
||||
|
||||
export enum Vote_Item_Type {
|
||||
Bounty = 'Bounty',
|
||||
Comment = 'Comment',
|
||||
Project = 'Project',
|
||||
Question = 'Question',
|
||||
Story = 'Story',
|
||||
User = 'User'
|
||||
}
|
||||
|
||||
export type Vote = {
|
||||
__typename?: 'Vote';
|
||||
amount_in_sat: Scalars['Int'];
|
||||
@@ -264,6 +291,17 @@ export type Vote = {
|
||||
project: Project;
|
||||
};
|
||||
|
||||
export type Vote2 = {
|
||||
__typename?: 'Vote2';
|
||||
amount_in_sat: Scalars['Int'];
|
||||
id: Scalars['Int'];
|
||||
item_id: Scalars['Int'];
|
||||
item_type: Vote_Item_Type;
|
||||
paid: Scalars['Boolean'];
|
||||
payment_hash: Scalars['String'];
|
||||
payment_request: Scalars['String'];
|
||||
};
|
||||
|
||||
export type NavCategoriesQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
@@ -279,17 +317,22 @@ export type SearchProjectsQuery = { __typename?: 'Query', searchProjects: Array<
|
||||
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 TrendingPostsQuery = { __typename?: 'Query', getTrendingPosts: Array<{ __typename?: 'Bounty', id: number, title: string, author: { __typename?: 'User', id: number, avatar: string } } | { __typename?: 'Question', id: number, title: string, author: { __typename?: 'User', id: number, avatar: string } } | { __typename?: 'Story', id: number, title: string, author: { __typename?: 'User', id: number, avatar: string } }> };
|
||||
|
||||
export type PopularTopicsQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type PopularTopicsQuery = { __typename?: 'Query', popularTopics: Array<{ __typename?: 'Topic', id: number, title: string, icon: string }> };
|
||||
|
||||
export type FeedQueryVariables = Exact<{
|
||||
take: InputMaybe<Scalars['Int']>;
|
||||
skip: InputMaybe<Scalars['Int']>;
|
||||
sortBy: InputMaybe<Scalars['String']>;
|
||||
category: InputMaybe<Scalars['String']>;
|
||||
topic: InputMaybe<Scalars['Int']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type FeedQuery = { __typename?: 'Query', getFeed: Array<{ __typename?: 'Bounty', id: number, title: string, date: string, excerpt: string, votes_count: number, type: string, cover_image: string, deadline: string, reward_amount: number, applicants_count: number, author: { __typename?: 'User', id: number, name: string, image: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }> } | { __typename?: 'Question', id: number, title: string, date: string, excerpt: string, votes_count: number, type: string, answers_count: number, author: { __typename?: 'User', id: number, name: string, image: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, comments: Array<{ __typename?: 'PostComment', id: number, created_at: string, body: string, author: { __typename?: 'User', id: number, name: string, image: string } }> } | { __typename?: 'Story', id: number, title: string, date: string, excerpt: string, votes_count: number, type: string, cover_image: string, comments_count: number, author: { __typename?: 'User', id: number, name: string, image: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }> }> };
|
||||
export type FeedQuery = { __typename?: 'Query', getFeed: Array<{ __typename?: 'Bounty', id: number, title: string, createdAt: any, excerpt: string, votes_count: number, type: string, cover_image: string, deadline: string, reward_amount: number, applicants_count: number, author: { __typename?: 'User', id: number, name: string, avatar: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }> } | { __typename?: 'Question', id: number, title: string, createdAt: any, excerpt: string, votes_count: number, type: string, answers_count: number, author: { __typename?: 'User', id: number, name: string, avatar: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, comments: Array<{ __typename?: 'PostComment', id: number, createdAt: any, body: string, author: { __typename?: 'User', id: number, name: string, avatar: string } }> } | { __typename?: 'Story', id: number, title: string, createdAt: any, excerpt: string, votes_count: number, type: string, cover_image: string, comments_count: number, author: { __typename?: 'User', id: number, name: string, avatar: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }> }> };
|
||||
|
||||
export type PostDetailsQueryVariables = Exact<{
|
||||
id: Scalars['Int'];
|
||||
@@ -297,7 +340,7 @@ export type PostDetailsQueryVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type PostDetailsQuery = { __typename?: 'Query', getPostById: { __typename?: 'Bounty', id: number, title: string, date: string, body: string, votes_count: number, type: string, cover_image: string, deadline: string, reward_amount: number, applicants_count: number, author: { __typename?: 'User', id: number, name: string, image: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, applications: Array<{ __typename?: 'BountyApplication', id: number, date: string, workplan: string, author: { __typename?: 'User', id: number, name: string, image: string } }> } | { __typename?: 'Question', id: number, title: string, date: string, body: string, votes_count: number, type: string, answers_count: number, author: { __typename?: 'User', id: number, name: string, image: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, comments: Array<{ __typename?: 'PostComment', id: number, created_at: string, body: string, votes_count: number, parentId: number | null, author: { __typename?: 'User', id: number, name: string, image: string } }> } | { __typename?: 'Story', id: number, title: string, date: string, body: string, votes_count: number, type: string, cover_image: string, comments_count: number, author: { __typename?: 'User', id: number, name: string, image: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, comments: Array<{ __typename?: 'PostComment', id: number, created_at: string, body: string, votes_count: number, parentId: number | null, author: { __typename?: 'User', id: number, name: string, image: string } }> } };
|
||||
export type PostDetailsQuery = { __typename?: 'Query', getPostById: { __typename?: 'Bounty', id: number, title: string, createdAt: any, body: string, votes_count: number, type: string, cover_image: string, deadline: string, reward_amount: number, applicants_count: number, author: { __typename?: 'User', id: number, name: string, avatar: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, applications: Array<{ __typename?: 'BountyApplication', id: number, date: string, workplan: string, author: { __typename?: 'User', id: number, name: string, avatar: string } }> } | { __typename?: 'Question', id: number, title: string, createdAt: any, body: string, votes_count: number, type: string, answers_count: number, author: { __typename?: 'User', id: number, name: string, avatar: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, comments: Array<{ __typename?: 'PostComment', id: number, createdAt: any, body: string, votes_count: number, parentId: number | null, author: { __typename?: 'User', id: number, name: string, avatar: string } }> } | { __typename?: 'Story', id: number, title: string, createdAt: any, body: string, votes_count: number, type: string, cover_image: string, comments_count: number, author: { __typename?: 'User', id: number, name: string, avatar: string }, tags: Array<{ __typename?: 'Tag', id: number, title: string }>, comments: Array<{ __typename?: 'PostComment', id: number, createdAt: any, body: string, votes_count: number, parentId: number | null, author: { __typename?: 'User', id: number, name: string, avatar: string } }> } };
|
||||
|
||||
export type CategoryPageQueryVariables = Exact<{
|
||||
categoryId: Scalars['Int'];
|
||||
@@ -431,7 +474,7 @@ export const TrendingPostsDocument = gql`
|
||||
title
|
||||
author {
|
||||
id
|
||||
image
|
||||
avatar
|
||||
}
|
||||
}
|
||||
... on Bounty {
|
||||
@@ -439,7 +482,7 @@ export const TrendingPostsDocument = gql`
|
||||
title
|
||||
author {
|
||||
id
|
||||
image
|
||||
avatar
|
||||
}
|
||||
}
|
||||
... on Question {
|
||||
@@ -447,7 +490,7 @@ export const TrendingPostsDocument = gql`
|
||||
title
|
||||
author {
|
||||
id
|
||||
image
|
||||
avatar
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -480,17 +523,53 @@ export function useTrendingPostsLazyQuery(baseOptions?: Apollo.LazyQueryHookOpti
|
||||
export type TrendingPostsQueryHookResult = ReturnType<typeof useTrendingPostsQuery>;
|
||||
export type TrendingPostsLazyQueryHookResult = ReturnType<typeof useTrendingPostsLazyQuery>;
|
||||
export type TrendingPostsQueryResult = Apollo.QueryResult<TrendingPostsQuery, TrendingPostsQueryVariables>;
|
||||
export const PopularTopicsDocument = gql`
|
||||
query PopularTopics {
|
||||
popularTopics {
|
||||
id
|
||||
title
|
||||
icon
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __usePopularTopicsQuery__
|
||||
*
|
||||
* To run a query within a React component, call `usePopularTopicsQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `usePopularTopicsQuery` 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 } = usePopularTopicsQuery({
|
||||
* variables: {
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function usePopularTopicsQuery(baseOptions?: Apollo.QueryHookOptions<PopularTopicsQuery, PopularTopicsQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<PopularTopicsQuery, PopularTopicsQueryVariables>(PopularTopicsDocument, options);
|
||||
}
|
||||
export function usePopularTopicsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<PopularTopicsQuery, PopularTopicsQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<PopularTopicsQuery, PopularTopicsQueryVariables>(PopularTopicsDocument, options);
|
||||
}
|
||||
export type PopularTopicsQueryHookResult = ReturnType<typeof usePopularTopicsQuery>;
|
||||
export type PopularTopicsLazyQueryHookResult = ReturnType<typeof usePopularTopicsLazyQuery>;
|
||||
export type PopularTopicsQueryResult = Apollo.QueryResult<PopularTopicsQuery, PopularTopicsQueryVariables>;
|
||||
export const FeedDocument = gql`
|
||||
query Feed($take: Int, $skip: Int, $sortBy: String, $category: String) {
|
||||
getFeed(take: $take, skip: $skip, sortBy: $sortBy, category: $category) {
|
||||
query Feed($take: Int, $skip: Int, $sortBy: String, $topic: Int) {
|
||||
getFeed(take: $take, skip: $skip, sortBy: $sortBy, topic: $topic) {
|
||||
... on Story {
|
||||
id
|
||||
title
|
||||
date
|
||||
createdAt
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
excerpt
|
||||
tags {
|
||||
@@ -505,11 +584,11 @@ export const FeedDocument = gql`
|
||||
... on Bounty {
|
||||
id
|
||||
title
|
||||
date
|
||||
createdAt
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
excerpt
|
||||
tags {
|
||||
@@ -526,11 +605,11 @@ export const FeedDocument = gql`
|
||||
... on Question {
|
||||
id
|
||||
title
|
||||
date
|
||||
createdAt
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
excerpt
|
||||
tags {
|
||||
@@ -542,12 +621,12 @@ export const FeedDocument = gql`
|
||||
answers_count
|
||||
comments {
|
||||
id
|
||||
created_at
|
||||
createdAt
|
||||
body
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -570,7 +649,7 @@ export const FeedDocument = gql`
|
||||
* take: // value for 'take'
|
||||
* skip: // value for 'skip'
|
||||
* sortBy: // value for 'sortBy'
|
||||
* category: // value for 'category'
|
||||
* topic: // value for 'topic'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
@@ -591,11 +670,11 @@ export const PostDetailsDocument = gql`
|
||||
... on Story {
|
||||
id
|
||||
title
|
||||
date
|
||||
createdAt
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
body
|
||||
tags {
|
||||
@@ -608,25 +687,25 @@ export const PostDetailsDocument = gql`
|
||||
comments_count
|
||||
comments {
|
||||
id
|
||||
created_at
|
||||
createdAt
|
||||
body
|
||||
votes_count
|
||||
parentId
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
}
|
||||
}
|
||||
... on Bounty {
|
||||
id
|
||||
title
|
||||
date
|
||||
createdAt
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
body
|
||||
tags {
|
||||
@@ -646,18 +725,18 @@ export const PostDetailsDocument = gql`
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
}
|
||||
}
|
||||
... on Question {
|
||||
id
|
||||
title
|
||||
date
|
||||
createdAt
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
body
|
||||
tags {
|
||||
@@ -669,14 +748,14 @@ export const PostDetailsDocument = gql`
|
||||
answers_count
|
||||
comments {
|
||||
id
|
||||
created_at
|
||||
createdAt
|
||||
body
|
||||
votes_count
|
||||
parentId
|
||||
author {
|
||||
id
|
||||
name
|
||||
image
|
||||
avatar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { random, randomItem, randomItems } from "src/utils/helperFunctions"
|
||||
import { getCoverImage } from "./utils"
|
||||
|
||||
const topics = [
|
||||
export const topics = [
|
||||
{
|
||||
id: 1,
|
||||
title: '🎨 Design'
|
||||
|
||||
@@ -4,13 +4,14 @@ import { Bounty, Post, Question, Story } from "src/features/Posts/types";
|
||||
import { random, randomItem } from "src/utils/helperFunctions";
|
||||
import { getAvatarImage, getCoverImage } from "./utils";
|
||||
import { Chance } from 'chance'
|
||||
import { topics } from "./hackathon";
|
||||
|
||||
const getDate = () => dayjs().subtract(random(5, 48), 'hour').toString();
|
||||
|
||||
const getAuthor = () => ({
|
||||
id: 12,
|
||||
name: "John Doe",
|
||||
image: getAvatarImage(),
|
||||
avatar: getAvatarImage(),
|
||||
join_date: getDate()
|
||||
})
|
||||
|
||||
@@ -23,7 +24,7 @@ export const generatePostComments = (cnt: number = 1): Story['comments'] => {
|
||||
const comment = {
|
||||
id: i + 1,
|
||||
body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nisi, at ut sit id. Vulputate aliquet aliquam penatibus ac, et dictum est etiam. Sagittis odio dui sed viverra donec rutrum iaculis vitae morbi.",
|
||||
created_at: getDate(),
|
||||
createdAt: getDate(),
|
||||
author: getAuthor(),
|
||||
votes_count: 123,
|
||||
parentId
|
||||
@@ -85,7 +86,7 @@ export let posts = {
|
||||
body: postBody,
|
||||
cover_image: getCoverImage(),
|
||||
comments_count: 3,
|
||||
date: getDate(),
|
||||
createdAt: getDate(),
|
||||
votes_count: 120,
|
||||
excerpt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. In odio libero accumsan...',
|
||||
type: "Story",
|
||||
@@ -96,6 +97,7 @@ export let posts = {
|
||||
],
|
||||
author: getAuthor(),
|
||||
comments: generatePostComments(3),
|
||||
topic: randomItem(...topics)
|
||||
|
||||
},
|
||||
] as Story[],
|
||||
@@ -107,7 +109,7 @@ export let posts = {
|
||||
body: postBody,
|
||||
cover_image: getCoverImage(),
|
||||
applicants_count: 31,
|
||||
date: getDate(),
|
||||
createdAt: getDate(),
|
||||
votes_count: 120,
|
||||
excerpt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. In odio libero accumsan...',
|
||||
tags: [
|
||||
@@ -129,7 +131,7 @@ export let posts = {
|
||||
title: 'Digital Editor, Mars Review of Books',
|
||||
body: postBody,
|
||||
answers_count: 3,
|
||||
date: getDate(),
|
||||
createdAt: getDate(),
|
||||
votes_count: 70,
|
||||
excerpt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. In odio libero accumsan...',
|
||||
tags: [
|
||||
|
||||
@@ -106,7 +106,7 @@ export const handlers = [
|
||||
const { take, skip } = req.variables;
|
||||
return res(
|
||||
ctx.data({
|
||||
getFeed: getFeed({ take, skip })
|
||||
getFeed: getFeed({ take, skip, })
|
||||
})
|
||||
)
|
||||
}),
|
||||
|
||||
@@ -11,9 +11,8 @@ body {
|
||||
}
|
||||
|
||||
.page-container {
|
||||
width: 98%;
|
||||
width: calc(min(100% - 64px, 1440px));
|
||||
margin: 0 auto;
|
||||
max-width: 1440px;
|
||||
}
|
||||
|
||||
svg {
|
||||
|
||||
@@ -50,7 +50,7 @@ export const apolloClient = new ApolloClient({
|
||||
typePolicies: {
|
||||
Query: {
|
||||
fields: {
|
||||
getFeed: offsetLimitPagination(['sortBy', 'category'])
|
||||
getFeed: offsetLimitPagination(['sortBy', 'topic'])
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user