This commit is contained in:
Lee 2024-10-16 08:03:36 +01:00
parent 6d6e59ed13
commit 1eed0e1e99
4 changed files with 71 additions and 1 deletions

@ -25,6 +25,6 @@ RUN bun --filter '@ssr/common' build
COPY --from=depends /app/projects/backend ./projects/backend COPY --from=depends /app/projects/backend ./projects/backend
# Lint before starting # Lint before starting
RUN bun --filter 'website' lint RUN bun --filter 'backend' lint
CMD ["bun", "run", "--filter", "backend", "start"] CMD ["bun", "run", "--filter", "backend", "start"]

@ -0,0 +1,23 @@
import ky from "ky";
type ApiHealth = {
online: boolean;
};
/**
* Gets the health of the api server.
*
* @param url the url of the api
*/
export async function getApiHealth(url: string): Promise<ApiHealth> {
try {
await ky.get(url);
return {
online: true,
};
} catch {
return {
online: false,
};
}
}

@ -14,6 +14,7 @@ import NavBar from "../components/navbar/navbar";
import { Colors } from "@/common/colors"; import { Colors } from "@/common/colors";
import OfflineNetwork from "@/components/offline-network"; import OfflineNetwork from "@/components/offline-network";
import Script from "next/script"; import Script from "next/script";
import { ApiHealth } from "@/components/api/api-health";
const siteFont = localFont({ const siteFont = localFont({
src: "./fonts/JetBrainsMono.ttf", src: "./fonts/JetBrainsMono.ttf",
@ -79,6 +80,7 @@ export default function RootLayout({
<ThemeProvider attribute="class" defaultTheme="dark" enableSystem disableTransitionOnChange> <ThemeProvider attribute="class" defaultTheme="dark" enableSystem disableTransitionOnChange>
<QueryProvider> <QueryProvider>
<AnimatePresence> <AnimatePresence>
<ApiHealth />
<main className="flex flex-col min-h-screen gap-2 text-white w-full"> <main className="flex flex-col min-h-screen gap-2 text-white w-full">
<NavBar /> <NavBar />
<div className="z-[1] m-auto flex flex-col flex-grow items-center w-full md:max-w-[1600px]"> <div className="z-[1] m-auto flex flex-col flex-grow items-center w-full md:max-w-[1600px]">

@ -0,0 +1,45 @@
"use client";
import { useQuery } from "@tanstack/react-query";
import { useEffect, useRef, useState } from "react";
import { getApiHealth } from "@ssr/common/utils/api-utils";
import { config } from "../../../config";
import { useToast } from "@/hooks/use-toast";
import { useIsFirstRender } from "@uidotdev/usehooks";
export function ApiHealth() {
const { toast } = useToast();
const firstRender = useIsFirstRender();
const [online, setOnline] = useState<boolean>(true);
const previousOnlineStatus = useRef<boolean>(true);
useQuery({
queryKey: ["api-health"],
queryFn: async () => {
const status = (await getApiHealth(config.siteApi)).online;
setOnline(status);
return status;
},
refetchInterval: 1000 * 15,
});
useEffect(() => {
if (firstRender) {
return;
}
// Trigger toast only if the online status changes
if (previousOnlineStatus.current !== online) {
toast({
title: `The API is now ${online ? "Online" : "Offline"}!`,
description: online ? "The API has recovered connectivity." : "The API has lost connectivity.",
variant: online ? "success" : "destructive",
});
}
// Update the previous online status
previousOnlineStatus.current = online;
}, [firstRender, online, toast]);
return <></>;
}