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 <153032991+gio-start...@users.noreply.github.com> 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: commits-unsubscr...@pinot.apache.org For additional commands, e-mail: commits-h...@pinot.apache.org