Skip to content

Commit e54baeb

Browse files
authored
feat: github stats, astro icons and octokit (#260)
* refactor: website Signed-off-by: Adam Setch <[email protected]> * refactor: website Signed-off-by: Adam Setch <[email protected]> * refactor: website Signed-off-by: Adam Setch <[email protected]> * refactor: website Signed-off-by: Adam Setch <[email protected]> * refactor: website Signed-off-by: Adam Setch <[email protected]> * refactor: website Signed-off-by: Adam Setch <[email protected]> --------- Signed-off-by: Adam Setch <[email protected]>
1 parent 042d5bc commit e54baeb

25 files changed

+1126
-220
lines changed

astro.config.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
import solidJs from '@astrojs/solid-js';
12
import tailwind from '@astrojs/tailwind';
3+
import icon from 'astro-icon';
24
import { defineConfig } from 'astro/config';
35

4-
import solidJs from '@astrojs/solid-js';
5-
66
// https://astro.build/config
77
export default defineConfig({
8-
integrations: [tailwind({ applyBaseStyles: false }), solidJs()],
8+
integrations: [tailwind({ applyBaseStyles: false }), solidJs(), icon()],
99
});

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,17 @@
5050
"dependencies": {
5151
"@astrojs/solid-js": "4.4.2",
5252
"@astrojs/tailwind": "5.1.2",
53+
"@iconify-json/mdi": "1.2.1",
5354
"@kobalte/core": "0.13.7",
55+
"@octokit/openapi-types": "22.2.0",
5456
"@tailwindcss/typography": "0.5.15",
5557
"astro": "4.16.8",
58+
"astro-icon": "1.1.2",
5659
"class-variance-authority": "0.7.0",
5760
"clsx": "2.1.1",
5861
"date-fns": "4.1.0",
5962
"marked": "14.1.3",
63+
"octokit": "4.0.2",
6064
"sharp": "0.33.5",
6165
"solid-js": "1.9.3",
6266
"solid-markdown": "2.0.13",

pnpm-lock.yaml

Lines changed: 917 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/images/404.png

165 KB
Loading

public/images/404.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/components/Footer.astro

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
2-
import { siteMetadata } from '~/constants';
3-
import GitHubIcon from '../icons/GitHub.astro';
2+
import { Icon } from 'astro-icon/components';
3+
4+
import { URLs, siteMetadata } from '~/constants';
45
56
const { currentPathname } = Astro.props;
67
const isHomepage = currentPathname === '/';
@@ -15,11 +16,11 @@ const isHomepage = currentPathname === '/';
1516
<a
1617
target="_blank"
1718
rel="noopener noreferrer"
18-
href=`https://github.com/${siteMetadata.repo}`
19+
href=`${URLs.GITHUB.REPO}`
1920
aria-label="GitHub Repository"
2021
class="mt-1 mb-4 mx-2 p-1 text-white hover:text-gray-400"
2122
>
22-
<GitHubIcon className="w-6" />
23+
<Icon name="mdi:github" size={32} />
2324
</a>
2425

2526
<div class="my-3">

src/components/GitHubRepo.astro

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
---
2+
import { Icon } from 'astro-icon/components';
3+
import { Octokit } from 'octokit';
4+
5+
import { URLs, siteMetadata } from '~/constants';
6+
import type { RepoStats } from '~/types';
7+
8+
const octokit = new Octokit();
9+
10+
const formatCount = (count: number) => {
11+
return new Intl.NumberFormat('en', {
12+
notation: 'compact',
13+
maximumFractionDigits: 1,
14+
}).format(count);
15+
};
16+
17+
const loadRepoStats = async (): Promise<RepoStats> => {
18+
try {
19+
const repository = await octokit.rest.repos.get({
20+
owner: siteMetadata.repo.owner,
21+
repo: siteMetadata.repo.name,
22+
});
23+
24+
const latestRelease = await octokit.rest.repos.getLatestRelease({
25+
owner: siteMetadata.repo.owner,
26+
repo: siteMetadata.repo.name,
27+
});
28+
29+
return {
30+
forks: formatCount(repository.data.forks_count),
31+
stars: formatCount(repository.data.stargazers_count),
32+
latestReleaseName: latestRelease.data.name?.replace('v', '') ?? '',
33+
};
34+
} catch (error) {
35+
console.error('Failed to load repo stats', error);
36+
return {
37+
forks: '',
38+
stars: '',
39+
latestReleaseName: '',
40+
};
41+
}
42+
};
43+
44+
const { forks, stars, latestReleaseName } = await loadRepoStats();
45+
---
46+
47+
<a href={URLs.GITHUB.REPO}
48+
target="_blank"
49+
rel="noopener noreferrer"
50+
aria-label="GitHub Repository"
51+
class="text-white hover:text-gray-300 hover:no-underline"
52+
>
53+
<section class="flex flex-row gap-2 items-center">
54+
<Icon name="mdi:github" size={32} class="w-6 sm:w-10" />
55+
<div class="font-light">
56+
<div class="text-sm">{siteMetadata.repo.fullName}</div>
57+
<div class="flex flex-row gap-2 text-xs">
58+
<div class="flex flex-row gap-0.5 items-center">
59+
<Icon name="mdi:tag-outline" /> {latestReleaseName}
60+
</div>
61+
<div class="flex flex-1 gap-0.5 items-center">
62+
<Icon name="mdi:star-outline" /> {stars}
63+
</div>
64+
<div class="flex flex-1 gap-0.5 items-center">
65+
<Icon name="mdi:source-branch" /> {forks}
66+
</div>
67+
</div>
68+
</div>
69+
</section>
70+
</a>
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
---
2+
import { siteMetadata } from '~/constants';
3+
---
4+
15
<!-- Google tag (gtag.js) -->
2-
<script async src="https://www.googletagmanager.com/gtag/js?id=G-QXML81DEDV"
3-
></script>
6+
<script async src=`https://www.googletagmanager.com/gtag/js?id=${siteMetadata.google.analytics}`></script>
47
<script>
58
window.dataLayer = window.dataLayer || [];
69
function gtag() {
710
dataLayer.push(arguments);
811
}
912
gtag('js', new Date());
1013

11-
gtag('config', 'G-QXML81DEDV');
14+
gtag('config', siteMetadata.google.analytics);
1215
</script>

src/components/Hero.astro

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { Image } from 'astro:assets';
33
import Logo from './Logo.astro';
44
5+
import { siteMetadata } from '~/constants';
56
import notifications from '../assets/notifications.png';
67
import LatestRelease from './LatestRelease.astro';
78
---
@@ -13,11 +14,9 @@ import LatestRelease from './LatestRelease.astro';
1314
<div class="flex flex-col justify-center flex-grow">
1415
<Logo className="w-16 lg:w-24 mb-4" isDark />
1516

16-
<h1 class="text-2xl lg:text-4xl font-semibold">Gitify</h1>
17+
<h1 class="text-2xl lg:text-4xl font-semibold">{siteMetadata.title}</h1>
1718

18-
<h2 class="mt-2 text-xl lg:text-2xl font-light">
19-
Your GitHub notifications <br /> on your menu bar.
20-
</h2>
19+
<h2 class="mt-2 text-xl lg:text-2xl font-light">{siteMetadata.description}.</h2>
2120

2221
<LatestRelease />
2322
</div>

src/components/LatestRelease.astro

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
---
2+
import { Icon } from 'astro-icon/components';
23
import { format, parseISO } from 'date-fns';
3-
import { siteMetadata } from '~/constants';
4-
import DownloadIcon from '../icons/Download.astro';
5-
import type { Assets, DownloadLink, DownloadLinks, HeroData } from '../types';
4+
import { Octokit } from 'octokit';
65
7-
const REPO_API_URL = `https://api.github.com/repos/${siteMetadata.repo}/releases/latest`;
8-
const REPO_RELEASES_URL = `https://github.com/${siteMetadata.repo}/releases/latest`;
9-
const releaseDetailsClassName = 'text-sm mt-4';
6+
import { URLs, siteMetadata } from '~/constants';
7+
import type {
8+
DownloadLink,
9+
DownloadLinks,
10+
HeroData,
11+
ReleaseAsset,
12+
} from '../types';
1013
11-
const getDownloadLinks = (assets: Assets[]): DownloadLinks => {
14+
const octokit = new Octokit();
15+
16+
const getDownloadLinks = (assets: ReleaseAsset[]): DownloadLinks => {
1217
const getAssetLink = (filenameRegex: RegExp): string => {
1318
const asset = assets.find((item) => item.name.match(filenameRegex));
14-
return asset ? asset.browser_download_url : REPO_RELEASES_URL;
19+
return asset ? asset.browser_download_url : URLs.GITHUB.LATEST_RELEASE;
1520
};
1621
1722
const supportedOSs: DownloadLink[] = [
@@ -63,15 +68,19 @@ const getDownloadLinks = (assets: Assets[]): DownloadLinks => {
6368
6469
const loadInitialData = async (): Promise<HeroData> => {
6570
try {
66-
const response = await fetch(REPO_API_URL);
67-
const data = await response.json();
68-
const parsedDate = parseISO(data.published_at.slice(0, -1));
69-
const downloadLinks = getDownloadLinks(data.assets);
71+
const latestRelease = await octokit.rest.repos.getLatestRelease({
72+
owner: siteMetadata.repo.owner,
73+
repo: siteMetadata.repo.name,
74+
});
75+
76+
const downloadLinks = getDownloadLinks(latestRelease.data.assets);
7077
7178
return {
7279
downloadLinks,
73-
version: data.tag_name,
74-
releaseDate: format(parsedDate, 'dd/MM/yyyy'),
80+
version: latestRelease.data.name,
81+
releaseDate: latestRelease.data.published_at
82+
? format(latestRelease.data.published_at, 'dd/MM/yyyy')
83+
: '',
7584
};
7685
} catch (error) {
7786
return {
@@ -88,30 +97,33 @@ const loadInitialData = async (): Promise<HeroData> => {
8897
const { downloadLinks, version, releaseDate } = await loadInitialData();
8998
---
9099

91-
<div class={releaseDetailsClassName}>
100+
<div class="text-sm mt-4">
92101
{
93102
version ? (
94103
<>
95104
<div class="sm:flex md:grid md:grid-cols-2">
96-
{downloadLinks.primary.map((item, index) => (
105+
{downloadLinks.primary.map((item) => (
97106
<a
98107
href={item.url}
99108
class={`flex items-center mb-3 px-4 py-3 font-semibold text-white rounded-md bg-green-700 hover:bg-green-800 hover:text-white mr-4`}
100109
>
101-
<DownloadIcon className="w-4 h-4 mr-2" /> <span>{item.name}</span>
110+
<div class="flex flex-row gap-2 items-center">
111+
<Icon name="mdi:cloud-download" size={24} />
112+
<span>{item.name}</span>
113+
</div>
102114
</a>
103115
))}
104116
</div>
105117
<div class="w-80">
106-
<p>Latest version: <a href={REPO_RELEASES_URL}>{version}</a></p>
118+
<p>Latest version: <a href={URLs.GITHUB.LATEST_RELEASE}>{version}</a></p>
107119
<p class="mt-1">Released on: {releaseDate}</p>
108120
{downloadLinks.alt.length > 0 && (
109121
<p class="mt-1">
110122
Also available on:
111123
<ul class="list-disc list-inside ml-4">
112-
{downloadLinks.alt.map((platform, index) => (
124+
{downloadLinks.alt.map((platform) => (
113125
<li>
114-
<a href={platform.url || REPO_RELEASES_URL}>
126+
<a href={platform.url || URLs.GITHUB.LATEST_RELEASE}>
115127
{platform.name}
116128
</a>
117129
</li>
@@ -126,10 +138,12 @@ const { downloadLinks, version, releaseDate } = await loadInitialData();
126138
<div class="flex">
127139
<a
128140
class="flex items-center mb-3 px-4 py-3 font-semibold text-white rounded-md bg-green-700 hover:bg-green-800"
129-
href={REPO_RELEASES_URL}
141+
href={URLs.GITHUB.LATEST_RELEASE}
130142
>
131-
<DownloadIcon className="w-4 h-4 mr-2" />{' '}
132-
<span>View GitHub Releases</span>
143+
<div class="flex flex-row gap-2 items-center">
144+
<Icon name="mdi:cloud-download" size={24} />
145+
<span>View GitHub Releases</span>
146+
</div>
133147
</a>
134148
</div>
135149
<div>

0 commit comments

Comments
 (0)