This is an automated email from the ASF dual-hosted git repository.
xiangfu pushed a commit to branch new-site-dev
in repository https://gitbox.apache.org/repos/asf/pinot-site.git
The following commit(s) were added to refs/heads/new-site-dev by this push:
new a5916ba9 Fetch actual stars from GitHub repo (#125)
a5916ba9 is described below
commit a5916ba9dca35b747ee1909c2d93fedb2a677faa
Author: Gio <[email protected]>
AuthorDate: Sat Jul 13 18:50:44 2024 +0200
Fetch actual stars from GitHub repo (#125)
* WB-286 - Handle redirect both /who_uses and /who_uses/
* NO_TICKET-github-stars - Able to fetch correct stars from github
* NO_TICKET-github-stars - Simplify code. Remove fallback. Show nothing if
error from github
---
app/lib/stars.utils.ts | 37 +++++++++++++++++++++++++++++++++++++
components/Header.tsx | 42 +++++++++++++++++++++++++++++++++++-------
components/MobileNav.tsx | 10 +++++++---
3 files changed, 79 insertions(+), 10 deletions(-)
diff --git a/app/lib/stars.utils.ts b/app/lib/stars.utils.ts
new file mode 100644
index 00000000..99f3e8d4
--- /dev/null
+++ b/app/lib/stars.utils.ts
@@ -0,0 +1,37 @@
+export function formatNumber(num: number): string {
+ if (num >= 1000) {
+ return (num / 1000).toFixed(1) + 'k';
+ }
+ return num.toString();
+}
+
+export function isLessThanOneHourAgo(date: Date): boolean {
+ const oneHourInMillis = 60 * 60 * 1000; // Number of milliseconds in one
hour
+ const currentTime = new Date().getTime();
+ const inputTime = date.getTime();
+
+ return currentTime - inputTime < oneHourInMillis;
+}
+
+export async function getStars(owner: string, repo: string): Promise<number> {
+ const url = `https://api.github.com/repos/${owner}/${repo}`;
+
+ try {
+ const response = await fetch(url);
+ if (!response.ok) {
+ if (response.status === 403) {
+ // Rate limit exceeded
+ throw new Error('Rate limit exceeded');
+ }
+ throw new Error(`Error fetching repository data:
${response.statusText}`);
+ }
+ const json = await response.json();
+
+ const stars: number = json.stargazers_count;
+
+ return stars;
+ } catch (error) {
+ console.error(error);
+ throw error;
+ }
+}
diff --git a/components/Header.tsx b/components/Header.tsx
index a76d7707..4bffe0a1 100644
--- a/components/Header.tsx
+++ b/components/Header.tsx
@@ -1,21 +1,49 @@
'use client';
+import { useEffect, useState } from 'react';
import { useRouter, usePathname, useSearchParams } from 'next/navigation';
+import Link from './Link';
import siteMetadata from '@/data/siteMetadata';
import headerNavLinks from '@/data/headerNavLinks';
import Logo from '@/data/logo.svg';
import GitHub from '@/data/github.svg';
-import Link from './Link';
+import { formatNumber, getStars, isLessThanOneHourAgo } from
'@/app/lib/stars.utils';
+import { Button } from '@/components/ui/button';
import MobileNav from './MobileNav';
-import ThemeSwitch from './ThemeSwitch';
+// import ThemeSwitch from './ThemeSwitch';
import SearchButton from './SearchButton';
import AnnouncementBar from './AnnouncementBar';
-import { Button } from '@/components/ui/button';
const Header = () => {
- const router = useRouter();
+ const [stars, setStars] = useState<string | null>(null);
+ // const router = useRouter();
const pathname = usePathname();
+ useEffect(() => {
+ const fetchStars = async () => {
+ const cacheKey = 'githubStars';
+ const cachedStars = localStorage.getItem(cacheKey);
+ const storedDate = localStorage.getItem(`${cacheKey}_time`);
+ const lastRunDate = storedDate ? new Date(storedDate) : new
Date(0);
+
+ // Use cached data if it's less than an hour old
+ if (cachedStars && storedDate &&
isLessThanOneHourAgo(lastRunDate)) {
+ setStars(cachedStars);
+ } else {
+ try {
+ const starCount = await getStars('apache', 'pinot');
+ const formattedStars = formatNumber(starCount);
+ setStars(formattedStars);
+ localStorage.setItem(cacheKey, formattedStars);
+ localStorage.setItem(`${cacheKey}_time`, new
Date().toISOString());
+ } catch (error) {
+ setStars(null);
+ }
+ }
+ };
+ fetchStars();
+ }, []);
+
return (
<>
<AnnouncementBar
@@ -62,13 +90,13 @@ const Header = () => {
{/* <ThemeSwitch /> */}
</div>
</div>
- <MobileNav />
+ <MobileNav stars={stars} />
<div className="hidden gap-3 sm:flex">
<SearchButton />
<Button variant="outline" size="lg" asChild
className="px-3 py-2 text-base">
<Link href={siteMetadata.github} target="_blank">
- <GitHub className="mr-2" />
- 3.5k
+ <GitHub className={`${stars && 'mr-2'}`} />
+ {stars && stars}
</Link>
</Button>
<Button variant="default" size="lg" className="bg-vine-100
px-6 py-2 text-base">
diff --git a/components/MobileNav.tsx b/components/MobileNav.tsx
index 2e31dd86..54551320 100644
--- a/components/MobileNav.tsx
+++ b/components/MobileNav.tsx
@@ -9,7 +9,11 @@ import Menu from '@/data/assets/menu.svg';
import { Button } from './ui/button';
import Link from './Link';
-const MobileNav = () => {
+interface MobileNavProps {
+ stars: string | null;
+}
+
+const MobileNav = ({ stars }: MobileNavProps) => {
const [navShow, setNavShow] = useState(false);
const navRef = useRef<HTMLDivElement>(null);
@@ -108,8 +112,8 @@ const MobileNav = () => {
className="px-3 py-2 text-base"
>
<Link href={siteMetadata.github}
target="_blank">
- <GitHub className="mr-2" />
- 3.5k
+ <GitHub className={`${stars &&
'mr-2'}`} />
+ {stars && stars}
</Link>
</Button>
</div>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]