Skip to content

Commit dc97aef

Browse files
committed
Squashed commit of the following:
commit 7ab21880d8204d1547af3909a6042b6203a3194d Author: John Doe <elmehdi.sakout@gmail.com> Date: Sat Dec 23 23:24:31 2023 +0100 update readme commit 181a4b1469b69db5819d892f63dcea8f0679ded2 Merge: f30f6aa bf76f7e Author: John Doe <elmehdi.sakout@gmail.com> Date: Sat Dec 23 21:59:03 2023 +0100 Merge branch 'develop' into feat/card-by-ai commit f30f6aacd20f81e3fca7000645c2c45c524d999d Merge: 010f059 d235b4e Author: John Doe <elmehdi.sakout@gmail.com> Date: Sat Dec 23 20:55:55 2023 +0100 Merge branch 'develop' into feat/card-by-ai commit 010f059a6f6944e5b2e38591871c498f273ed4cf Author: John Doe <elmehdi.sakout@gmail.com> Date: Sat Dec 23 17:53:35 2023 +0100 check if analytics key exists commit fbdf1c059984b2c986a829484ce21f567b06c0e8 Author: John Doe <elmehdi.sakout@gmail.com> Date: Sat Dec 23 17:48:47 2023 +0100 fix close icon color commit 15432ed8e0ac8976fc15fb69a8f7cefee98cb72e Merge: 0b75404 b84849f Author: John Doe <elmehdi.sakout@gmail.com> Date: Sat Dec 23 17:41:12 2023 +0100 Merge branch 'develop' into feat/card-by-ai commit 0b75404c727e47aa27cbe00d2db2dc0a963b48b7 Author: John Doe <elmehdi.sakout@gmail.com> Date: Sat Dec 23 12:17:40 2023 +0100 add close button commit 8475a4a24416f03107766d8cc5d2c6b464d157ee Merge: 67a7f98 9036ec2 Author: John Doe <elmehdi.sakout@gmail.com> Date: Tue Dec 19 16:46:50 2023 +0100 Merge branch 'develop' into feat/card-by-ai commit 67a7f9864b8f106bebfca60c6087cb5c26573919 Author: John Doe <elmehdi.sakout@gmail.com> Date: Mon Dec 18 18:30:02 2023 +0100 add image bloc if available commit 64e81129ef93102ddf641f8bb2962b493fbda903 Author: John Doe <elmehdi.sakout@gmail.com> Date: Mon Dec 18 18:29:48 2023 +0100 remove redundant share bloc commit 4d6385aef457c7f2c2850361fdbb17d4e1fc1ad5 Merge: 62f773c 64a02ee Author: John Doe <elmehdi.sakout@gmail.com> Date: Sun Dec 17 21:22:06 2023 +0100 Merge branch 'develop' into feat/card-by-ai commit 62f773c1d290ea1cf6ff3d101d1119c173b62c34 Author: John Doe <elmehdi.sakout@gmail.com> Date: Sat Dec 16 13:47:55 2023 +0100 implement powered by AI Card commit 40045812d4e8c06804ef653edacae16e0bb8a171 Author: John Doe <elmehdi.sakout@gmail.com> Date: Sun Dec 10 23:09:26 2023 +0100 add panel element commit 4ced4bb6516bda883199cef775059699172ace1b Author: John Doe <elmehdi.sakout@gmail.com> Date: Sat Dec 9 23:48:04 2023 +0100 update react icons
1 parent bf76f7e commit dc97aef

File tree

21 files changed

+382
-36
lines changed

21 files changed

+382
-36
lines changed

README.md

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,38 @@
55
[![Chrome Web Store Rating](https://img.shields.io/chrome-web-store/stars/ocoipcahhaedjhnpoanfflhbdcpmalmp.svg?colorB=%234FC828&label=rating&style=flat)](https://chrome.google.com/webstore/detail/hackertabdev/ocoipcahhaedjhnpoanfflhbdcpmalmp/reviews)
66

77
# Hackertab.dev — All Developer news in one tab!
8+
89
**Hackertab makes it easy for you to stay up-to-date with the latest developer news, tools, jobs and events.**
910

1011
<img src="/demo/demo_hackertab.dev.jpeg" width="100%" alt="Hackertab.dev"/>
1112

1213
As a developer, it can be difficult to stay on top of everything happening in the field. Hackertab makes it easy by allowing you to customize your default tab page to include news, tools and events from top sources such as GitHub Trendings, Hacker News, DevTo, Medium, and Product Hunt. No matter what type of developer you are, you'll find valuable and relevant information with Hackertab. Don't miss out - give it a try today!
1314

1415
#### Demo
16+
1517
👉 [now.hackertab.dev](https://now.hackertab.dev)
1618

1719
## 👩‍💻 How to use it
20+
1821
- Install the extension from the [Chrome store](https://bit.ly/hackertab-ch), or [Mozilla add-ons](https://bit.ly/hackertab-ff)
1922
- Open a new tab
2023
- The extension should now be running and visible
2124
- Select your preferred programming languages and sources.
2225
- Enjoy
2326

2427
## 🔥 Features
25-
- 🆕 Hourly updated content
26-
- 💻 Customizable by language or topic
27-
- 👍 Curated content from the best sources
28-
- 🔖 Bookmark and read it later
29-
- 🌙 Dark mode for when it gets late
28+
29+
- 🆕 Daily updated content
30+
- 💻 Customizable by programming language, framework and topic.
31+
- 👍 Curated content from the best sources.
32+
- 🔖 Bookmark and read it later.
33+
- 🌙 Dark mode for when it gets late.
34+
- ✨ AI-powered recommendations exclusively tailored to your preferences.
35+
3036
Even more features are going to come in the future!
3137

3238
## Data sources
39+
3340
- Github Trendings
3441
- Hackernews
3542
- DevTo
@@ -44,10 +51,13 @@ Even more features are going to come in the future!
4451
- **or create an issue to ask for a new data source**
4552

4653
## Support
54+
4755
Please do not hesitate to ask a question, report a bug or add a suggestion. or send an email to hello@hackertab.dev
4856

4957
## Development
50-
Please use the develop branch
58+
59+
Please use the develop branch. Create an .env file with the necessary
60+
5161
```bash
5262
$ git clone --branch develop git@github.com:medyo/hackertab.dev.git
5363
$ cd hackertab.dev
@@ -57,9 +67,10 @@ $ # Then visit http://localhost:3000
5767
```
5868

5969
## Maintainers
70+
6071
- [medyo](https://github.com/medyo)
61-
- [chouikane](https://github.com/Chouikane)
6272

6373
## Licencing
64-
Hackertab is licensed under the Apache License, Version 2.0.
74+
75+
Hackertab is licensed under the Apache License, Version 2.0.
6576
See [LICENSE](/LICENSE) for the full license text.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"react-dom": "^17.0.1",
2424
"react-easy-sort": "^1.5.1",
2525
"react-error-boundary": "^3.1.4",
26-
"react-icons": "^4.4.0",
26+
"react-icons": "^4.12.0",
2727
"react-markdown": "^7.0.1",
2828
"react-modal": "^3.12.1",
2929
"react-router-dom": "^6.21.0",

src/assets/App.css

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,20 @@ a {
329329
height: 16px;
330330
width: 16px;
331331
}
332-
332+
.blockHeaderBadge {
333+
width: auto;
334+
font-size: 12px;
335+
height: 20px;
336+
background-color: var(--tooltip-accent-color);
337+
border-radius: 20px;
338+
justify-content: center;
339+
align-items: center;
340+
text-align: center;
341+
display: inline-flex;
342+
padding: 0 6px;
343+
text-transform: lowercase;
344+
color: white;
345+
}
333346
.blockHeaderIcon img {
334347
display: block;
335348
}
@@ -348,7 +361,7 @@ a {
348361
position: absolute;
349362
right: 0;
350363
top: 0;
351-
width: 26%;
364+
width: 30%;
352365
}
353366

354367
.blockActions.active {
@@ -408,14 +421,23 @@ a {
408421
.blockRow:not(:last-child) {
409422
border-bottom: 1px solid var(--card-content-divider);
410423
}
411-
424+
.rowCover {
425+
border-radius: 4px;
426+
display: block;
427+
width: 100%;
428+
min-height: auto;
429+
object-fit: cover;
430+
aspect-ratio: 16/9;
431+
background-color: var(--placeholder-background-color);
432+
margin-bottom: 12px;
433+
}
412434
.rowTitle {
413435
color: var(--primary-text-color);
414436
margin: 0;
415437
padding: 0;
416438
font-size: 16px;
417439
text-decoration: none;
418-
display: flex;
440+
display: block;
419441
flex-direction: row;
420442
}
421443

@@ -1279,3 +1301,6 @@ Producthunt item
12791301
color: var(--primary-text-color);
12801302
border-radius: 10px;
12811303
}
1304+
.capitalize {
1305+
text-transform: capitalize;
1306+
}

src/components/Elements/Card/Card.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ type CardProps = {
1616

1717
export const Card = ({ card, titleComponent, children, fullBlock = false }: CardProps) => {
1818
const { openLinksNewTab } = useUserPreferences()
19-
const { link, icon, label } = card
19+
const { link, icon, label, badge } = card
2020
const handleHeaderLinkClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
2121
e.preventDefault()
2222
let url = `${link}?${ref}`
@@ -39,6 +39,7 @@ export const Card = ({ card, titleComponent, children, fullBlock = false }: Card
3939
<BsBoxArrowInUpRight />
4040
</a>
4141
)}
42+
{badge && <span className="blockHeaderBadge">{badge}</span>}
4243
</div>
4344

4445
<div className="blockContent scrollable">{children}</div>

src/components/Elements/CardWithActions/CardItemWithActions.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import React, { useEffect, useState } from 'react'
22
import { BiBookmarkMinus, BiBookmarkPlus, BiShareAlt } from 'react-icons/bi'
3+
import { MdBugReport } from 'react-icons/md'
4+
import { reportLink } from 'src/config'
35
import { ShareModal } from 'src/features/shareModal'
46
import { ShareModalData } from 'src/features/shareModal/types'
57
import { Attributes, trackLinkBookmark, trackLinkUnBookmark } from 'src/lib/analytics'
68
import { useBookmarks } from 'src/stores/bookmarks'
9+
import { useUserPreferences } from 'src/stores/preferences'
710
import { BaseEntry } from 'src/types'
811

912
type CardItemWithActionsProps = {
@@ -62,16 +65,30 @@ export const CardItemWithActions = ({
6265
setShareModalData({ title: item.title, link: item.url, source: source })
6366
}
6467

68+
const onReportClicked = () => {
69+
const tags = useUserPreferences
70+
.getState()
71+
.userSelectedTags.map((tag) => tag.label.toLocaleLowerCase())
72+
window.open(`${reportLink}?tags=${tags.join(',')}&url=${item.url}`, '_blank')
73+
}
74+
6575
return (
6676
<div key={`${source}-${index}`} className="blockRow">
6777
<ShareModal
6878
showModal={setShareModalData !== undefined}
6979
closeModal={() => setShareModalData(undefined)}
7080
shareData={shareModalData}
7181
/>
72-
7382
{cardItem}
7483
<div className={`blockActions ${isBookmarked ? 'active' : ''} `}>
84+
{source === 'ai' && (
85+
<button
86+
className={`blockActionButton `}
87+
onClick={onReportClicked}
88+
aria-label="Report item">
89+
<MdBugReport />
90+
</button>
91+
)}
7592
<button
7693
className={`blockActionButton `}
7794
onClick={onShareModalClicked}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import './panel.css'
2+
3+
const variants = {
4+
information: 'information',
5+
warning: 'bg-yellow-100 border-yellow-500 text-yellow-700',
6+
}
7+
type PanelProps = {
8+
title: string | React.ReactNode
9+
body: string | React.ReactNode
10+
variant: keyof typeof variants
11+
}
12+
13+
export const Panel = ({ title, body, variant = 'information' }: PanelProps) => {
14+
return (
15+
<div className={`panel ${variants[variant]}`}>
16+
<h3 className="title">{title}</h3>
17+
<p className="body">{body}</p>
18+
</div>
19+
)
20+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './Panel'
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
.panel {
2+
height: 200px;
3+
display: flex;
4+
flex-direction: column;
5+
gap: 12px;
6+
scroll-snap-align: start;
7+
padding: 16px 18px;
8+
}
9+
.panel .title {
10+
font-size: 16px;
11+
font-weight: 600;
12+
margin: 0;
13+
padding: 0;
14+
display: inline-flex;
15+
gap: 6px;
16+
}
17+
.panel .body {
18+
font-size: 14px;
19+
line-height: 20px;
20+
margin: 0;
21+
padding: 0;
22+
}
23+
24+
.dark .panel.information {
25+
background-color: #3b424b;
26+
color: white;
27+
}
28+
.light .panel.information {
29+
background-color: #cce6ff;
30+
color: black;
31+
}
32+
.panel .closeBtn {
33+
background: none;
34+
margin-left: auto;
35+
border: 0;
36+
cursor: pointer;
37+
color: var(--primary-text-color);
38+
}
39+
.panel .closeBtn :hover {
40+
opacity: 0.7;
41+
}

src/components/Elements/index.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
export * from "./BottomNavigation"
2-
export * from "./Card"
3-
export * from "./CardLink"
4-
export * from "./CardWithActions"
5-
export * from "./ChipsSet"
6-
export * from "./ClickableItem"
7-
export * from "./ColoredLanguagesBadges"
8-
export * from "./FloatingFilter"
9-
export * from "./InlineTextFilter"
10-
export * from "./SearchBar"
11-
export * from "./SearchBarWithLogo"
12-
export * from "./Steps"
13-
export * from "./UserTags"
14-
1+
export * from './BottomNavigation'
2+
export * from './Card'
3+
export * from './CardLink'
4+
export * from './CardWithActions'
5+
export * from './ChipsSet'
6+
export * from './ClickableItem'
7+
export * from './ColoredLanguagesBadges'
8+
export * from './FloatingFilter'
9+
export * from './InlineTextFilter'
10+
export * from './Panel'
11+
export * from './SearchBar'
12+
export * from './SearchBarWithLogo'
13+
export * from './Steps'
14+
export * from './UserTags'

src/components/List/ListComponent.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export type ListComponentPropsType<T extends BaseEntry> = {
2525
renderItem: (item: T, index: number) => React.ReactNode
2626
withAds: boolean
2727
placeholder?: React.ReactNode
28+
header?: React.ReactNode
2829
refresh?: boolean
2930
error?: any
3031
limit?: number
@@ -37,6 +38,7 @@ export function ListComponent<T extends BaseEntry>(props: ListComponentPropsType
3738
error,
3839
renderItem,
3940
withAds,
41+
header,
4042
placeholder = <Placeholder />,
4143
limit = MAX_ITEMS_PER_CARD,
4244
} = props
@@ -75,9 +77,14 @@ export function ListComponent<T extends BaseEntry>(props: ListComponentPropsType
7577

7678
return items.slice(0, limit).map((item, index) => {
7779
let content: ReactNode[] = [renderItem(item, index)]
80+
if (header && index === 0) {
81+
content.unshift(header)
82+
}
83+
7884
if (canAdsLoad && adsConfig.enabled && withAds && index === adsConfig.rowPosition) {
7985
content.unshift(<BannerAd key={'banner-ad'} />)
8086
}
87+
8188
return content
8289
})
8390
}

0 commit comments

Comments
 (0)