Files
cupcontrol/frontend/src/components/site-header.tsx
2025-12-25 22:32:04 +01:00

86 lines
2.7 KiB
TypeScript

import { Separator } from "@/components/ui/separator";
import { SidebarTrigger } from "@/components/ui/sidebar";
import { ModeToggle } from "./mode-toggle";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { Button } from "./ui/button";
import { useEffect, useState } from "react";
export function SiteHeader() {
const [oldLoginState, setOldLoginState] = useState(false);
const queryClient = useQueryClient();
const { data: pingResult } = useQuery({
queryKey: ["ping"],
queryFn: async () => {
let res = await fetch("/api/scp/ping");
return (await res.text()) === "true";
},
refetchInterval: 30000,
});
const { data: isLoggedIn } = useQuery({
queryKey: ["is_scp_logged_in"],
queryFn: async () => {
let res = await fetch("/api/scp/auth/is_logged_in");
return (await res.text()) === "true";
},
refetchInterval: 5000,
});
useEffect(() => {
if (isLoggedIn) {
if (!oldLoginState) {
queryClient.invalidateQueries({ queryKey: ["user"] });
setOldLoginState(true);
}
}
}, [isLoggedIn]);
async function startFlow() {
let res = await fetch("/api/scp/auth/start_flow");
if (res.ok && window) {
let url = await res.text();
window.open(url, "_blank")?.focus();
}
}
return (
<header className="flex h-(--header-height) shrink-0 items-center gap-2 border-b transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-(--header-height)">
<div className="flex w-full items-center gap-1 px-4 lg:gap-2 lg:px-6">
<SidebarTrigger className="-ml-1" />
<div className="flex flex-row gap-2 justify-center items-center">
<span>Netcup</span>
{pingResult ? (
isLoggedIn ? (
<div className="bg-green-500 rounded-[100%] animate-pulse w-4 h-4 ">
&nbsp;
</div>
) : (
<div className="bg-yellow-500 rounded-[100%] animate-pulse w-4 h-4 ">
&nbsp;
</div>
)
) : (
<div className="bg-red-700 rounded-[100%] animate-pulse w-4 h-4">
&nbsp;
</div>
)}
</div>
{!isLoggedIn && pingResult && (
<Button variant="outline" size="sm" onClick={startFlow}>
Login to Netcup SCP
</Button>
)}
<Separator
orientation="vertical"
className="mx-2 data-[orientation=vertical]:h-4"
/>
<h1 className="text-base font-medium">Documents</h1>
<div className="ml-auto flex items-center gap-2">
<ModeToggle />
</div>
</div>
</header>
);
}