Skip to content

Commit 7cb791c

Browse files
committed
feat: add HackernoonCard component and associated ArticleItem with icon
1 parent 7e908eb commit 7cb791c

File tree

6 files changed

+124
-0
lines changed

6 files changed

+124
-0
lines changed

src/assets/icon_hackernoon.jpeg

7.33 KB
Loading

src/config/supportedCards.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { CgIndieHackers } from 'react-icons/cg'
22
import { FaDev, FaFreeCodeCamp, FaMediumM, FaReddit } from 'react-icons/fa'
33
import { HiSparkles, HiTicket } from 'react-icons/hi'
44
import { SiGithub, SiProducthunt, SiYcombinator } from 'react-icons/si'
5+
import HackernoonIcon from 'src/assets/icon_hackernoon.jpeg'
56
import HashNodeIcon from 'src/assets/icon_hashnode.png'
67
import LobstersIcon from 'src/assets/icon_lobsters.png'
78
import { AICard } from 'src/features/cards/components/aiCard'
@@ -18,6 +19,7 @@ const { IndiehackersCard } = lazyImport(() => import('src/features/cards'), 'Ind
1819
const { LobstersCard } = lazyImport(() => import('src/features/cards'), 'LobstersCard')
1920
const { ProductHuntCard } = lazyImport(() => import('src/features/cards'), 'ProductHuntCard')
2021
const { RedditCard } = lazyImport(() => import('src/features/cards'), 'RedditCard')
22+
const { HackernoonCard } = lazyImport(() => import('src/features/cards'), 'HackernoonCard')
2123

2224
export const SUPPORTED_CARDS: SupportedCardType[] = [
2325
{
@@ -128,4 +130,13 @@ export const SUPPORTED_CARDS: SupportedCardType[] = [
128130
type: 'supported',
129131
link: 'https://hackertab.dev/',
130132
},
133+
{
134+
value: 'hackernoon',
135+
analyticsTag: 'hackernoon',
136+
label: 'Hackernoon',
137+
component: HackernoonCard,
138+
icon: <img alt="hackernoon" src={HackernoonIcon} />,
139+
link: 'https://hackernoon.com/',
140+
type: 'supported',
141+
},
131142
]
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { MdAccessTime } from 'react-icons/md'
2+
import { CardItemWithActions, CardLink, ColoredLanguagesBadge } from 'src/components/Elements'
3+
import { Attributes } from 'src/lib/analytics'
4+
import { useUserPreferences } from 'src/stores/preferences'
5+
import { Article, BaseItemPropsType } from 'src/types'
6+
import { format } from 'timeago.js'
7+
8+
const ArticleItem = (props: BaseItemPropsType<Article>) => {
9+
const { item, selectedTag, analyticsTag } = props
10+
const { listingMode } = useUserPreferences()
11+
return (
12+
<CardItemWithActions
13+
source={analyticsTag}
14+
item={item}
15+
cardItem={
16+
<>
17+
<CardLink
18+
link={item.url}
19+
analyticsAttributes={{
20+
[Attributes.TRIGERED_FROM]: 'card',
21+
[Attributes.TITLE]: item.title,
22+
[Attributes.LINK]: item.url,
23+
[Attributes.SOURCE]: analyticsTag,
24+
[Attributes.LANGUAGE]: selectedTag?.value,
25+
}}>
26+
<div className="subTitle">{item.title}</div>
27+
</CardLink>
28+
{listingMode === 'normal' && (
29+
<>
30+
<p className="rowDescription">
31+
<span className="rowItem">
32+
<MdAccessTime className={'rowTitleIcon'} />
33+
{format(new Date(item.published_at))}
34+
</span>
35+
</p>
36+
<p className="rowDetails">
37+
<ColoredLanguagesBadge languages={item.tags.slice(0, 4)} />
38+
</p>
39+
</>
40+
)}
41+
</>
42+
}
43+
/>
44+
)
45+
}
46+
47+
export default ArticleItem
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { useCallback } from 'react'
2+
import { Card } from 'src/components/Elements'
3+
import { ListPostComponent } from 'src/components/List/ListPostComponent'
4+
import { Article, CardPropsType } from 'src/types'
5+
import { useGetSourceArticles } from '../../api/getSourceArticles'
6+
import { useLazyListLoad } from '../../hooks/useLazyListLoad'
7+
import { useSelectedTags } from '../../hooks/useSelectedTags'
8+
import { MemoizedCardHeader } from '../CardHeader'
9+
import { MemoizedCardSettings } from '../CardSettings'
10+
import ArticleItem from './ArticleItem'
11+
12+
const GLOBAL_TAG = { label: 'Global', value: '' }
13+
14+
export function HackernoonCard(props: CardPropsType) {
15+
const { meta } = props
16+
const { ref, isVisible } = useLazyListLoad()
17+
const {
18+
queryTags,
19+
selectedTag,
20+
cardSettings: { sortBy, language } = {},
21+
} = useSelectedTags({
22+
source: meta.value,
23+
fallbackTag: GLOBAL_TAG,
24+
})
25+
26+
const { data, isLoading } = useGetSourceArticles({
27+
source: 'hackernoon',
28+
tags: queryTags,
29+
config: {
30+
enabled: isVisible,
31+
},
32+
})
33+
34+
const renderItem = useCallback(
35+
(item: Article) => <ArticleItem item={item} key={item.id} analyticsTag={meta.analyticsTag} />,
36+
[meta.analyticsTag]
37+
)
38+
39+
return (
40+
<Card
41+
ref={ref}
42+
titleComponent={
43+
<MemoizedCardHeader label={meta.label} fallbackTag={GLOBAL_TAG} selectedTag={selectedTag} />
44+
}
45+
settingsComponent={
46+
<MemoizedCardSettings
47+
url={meta.link}
48+
id={meta.value}
49+
globalTag={GLOBAL_TAG}
50+
sortBy={sortBy}
51+
language={language || GLOBAL_TAG.value}
52+
showDateRangeFilter={false}
53+
/>
54+
}
55+
{...props}>
56+
<ListPostComponent
57+
sortBy={sortBy as keyof Article}
58+
items={data}
59+
isLoading={isLoading}
60+
renderItem={renderItem}
61+
/>
62+
</Card>
63+
)
64+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './HackernoonCard'

src/features/cards/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export * from './components/devtoCard'
66
export * from './components/freecodecampCard'
77
export * from './components/githubCard'
88
export * from './components/hackernewsCard'
9+
export * from './components/hackernoonCard'
910
export * from './components/hashnodeCard'
1011
export * from './components/indiehackersCard'
1112
export * from './components/lobstersCard'

0 commit comments

Comments
 (0)