mirror of
https://github.com/jetkvm/website.git
synced 2025-09-16 08:38:16 +00:00
Add stars to Landingpage Navbar
This commit is contained in:
parent
3cd2e99fe9
commit
181f34be0b
@ -3,7 +3,8 @@ import clsx from "clsx";
|
|||||||
import ExtLink from "~/components/ExtLink";
|
import ExtLink from "~/components/ExtLink";
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { LinkButton } from "~/components/Button";
|
import { Button, LinkButton } from "~/components/Button";
|
||||||
|
import { GitHubIcon } from "../Icons";
|
||||||
|
|
||||||
type LinkProps = {
|
type LinkProps = {
|
||||||
to: string;
|
to: string;
|
||||||
@ -50,27 +51,40 @@ const NavLink = (props: NavLinkProps) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function LandingNavbar() {
|
export default function LandingNavbar({ githubStars }: { githubStars: number | null }) {
|
||||||
|
const formatNumber = (number: number) => {
|
||||||
|
return new Intl.NumberFormat("en", {
|
||||||
|
notation: "compact",
|
||||||
|
compactDisplay: "short",
|
||||||
|
maximumFractionDigits: 1, // Adjust for desired decimal places
|
||||||
|
}).format(number);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full flex-col items-center justify-between gap-x-6 space-y-4 pb-0 pt-6 xs:flex xs:flex-row xs:space-y-0 xs:border-b-0">
|
<div className="w-full flex-col items-center justify-between gap-x-6 space-y-4 pb-0 pt-6 xs:flex xs:flex-row xs:space-y-0 xs:border-b-0">
|
||||||
<div>
|
<div className="flex items-center gap-x-4">
|
||||||
<Link to="/">
|
<Link to="/">
|
||||||
<img src="/logo-blue.png" className="h-[24px] shrink-0" alt="" />
|
<img src="/logo-blue.png" className="h-[24px] shrink-0" alt="" />
|
||||||
</Link>
|
</Link>
|
||||||
|
<NavLink to="/docs">Documentation</NavLink>
|
||||||
|
<NavLink to="/contact">Contact us</NavLink>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<div className="flex items-center gap-x-4">
|
<div className="flex items-center gap-x-4">
|
||||||
<NavLink to="/docs">Documentation</NavLink>
|
<LinkButton
|
||||||
<NavLink to="/contact">Contact us</NavLink>
|
size="SM"
|
||||||
{/*<div className="hidden md:block">*/}
|
theme="blank"
|
||||||
{/* <NavLink to="/contact">GitHub</NavLink>*/}
|
to="https://github.com/jetkvm/kvm"
|
||||||
{/*</div>*/}
|
text={githubStars ? `Star ${formatNumber(githubStars)}` : "GitHub"}
|
||||||
{/*<LinkButton*/}
|
LeadingIcon={GitHubIcon}
|
||||||
{/* size="SM"*/}
|
/>
|
||||||
{/* theme="light"*/}
|
<div className="h-3/4 w-px bg-slate-800/20" />
|
||||||
{/* to="https://app.jetkvm.com"*/}
|
<LinkButton
|
||||||
{/* text="Cloud Dashboard"*/}
|
size="SM"
|
||||||
{/*/>*/}
|
theme="light"
|
||||||
|
to="https://app.jetkvm.com"
|
||||||
|
text="Cloud Dashboard"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import LandingNavbar from "~/components/landingpage/LandingNavbar";
|
import LandingNavbar from "~/components/landingpage/LandingNavbar";
|
||||||
import Container from "~/components/Container";
|
import Container from "~/components/Container";
|
||||||
|
|
||||||
import { HeadersFunction } from "@remix-run/node";
|
import { HeadersFunction, json } from "@remix-run/node";
|
||||||
import { Outlet } from "@remix-run/react";
|
import { Outlet, useLoaderData } from "@remix-run/react";
|
||||||
import Footer from "~/components/landingpage/Footer";
|
import Footer from "~/components/landingpage/Footer";
|
||||||
|
import { getGitHubStars } from "../services/github.server";
|
||||||
|
|
||||||
export const headers: HeadersFunction = () => {
|
export const headers: HeadersFunction = () => {
|
||||||
/*
|
/*
|
||||||
@ -39,11 +40,17 @@ export const headers: HeadersFunction = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const loader = async () => {
|
||||||
|
const githubStars = await getGitHubStars();
|
||||||
|
return json({ githubStars });
|
||||||
|
};
|
||||||
|
|
||||||
export default function LandingRootRoute() {
|
export default function LandingRootRoute() {
|
||||||
|
const { githubStars } = useLoaderData<typeof loader>();
|
||||||
return (
|
return (
|
||||||
<div className="grid h-full ">
|
<div className="grid h-full ">
|
||||||
<Container>
|
<Container>
|
||||||
<LandingNavbar />
|
<LandingNavbar githubStars={githubStars} />
|
||||||
</Container>
|
</Container>
|
||||||
<div className="h-full">
|
<div className="h-full">
|
||||||
<Outlet />
|
<Outlet />
|
||||||
|
|||||||
36
app/services/github.server.ts
Normal file
36
app/services/github.server.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
interface GitHubRepoResponse {
|
||||||
|
stargazers_count: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CACHE_DURATION = 1; // 1 hour in milliseconds
|
||||||
|
|
||||||
|
let cachedStars: number | null = null;
|
||||||
|
let lastFetchTime: number | null = null;
|
||||||
|
|
||||||
|
export async function getGitHubStars(): Promise<number | null> {
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
if (
|
||||||
|
cachedStars !== null &&
|
||||||
|
lastFetchTime !== null &&
|
||||||
|
now - lastFetchTime < CACHE_DURATION
|
||||||
|
) {
|
||||||
|
return cachedStars;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const resp = await fetch(`https://api.github.com/repos/jetkvm/kvm`);
|
||||||
|
|
||||||
|
if (!resp.ok) {
|
||||||
|
throw new Error(`GitHub API error: ${resp.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = (await resp.json()) as GitHubRepoResponse;
|
||||||
|
cachedStars = data.stargazers_count;
|
||||||
|
lastFetchTime = now;
|
||||||
|
return cachedStars;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to fetch GitHub stars:", error);
|
||||||
|
return cachedStars ?? null;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user