Openstatus www.openstatus.dev
at 4c0f4c00a38753a5d0dfd7e7b7b7706dec6f1503 57 lines 1.6 kB view raw
1import { statusDictionary } from "./utils"; 2 3export type Status = 4 | "operational" 5 | "degraded_performance" 6 | "partial_outage" 7 | "major_outage" 8 | "under_maintenance" 9 | "unknown" 10 | "incident"; 11 12export type StatusResponse = { status: Status }; 13 14export async function getStatus(slug: string): Promise<StatusResponse> { 15 const res = await fetch(`https://api.openstatus.dev/public/status/${slug}`, { 16 cache: "no-cache", 17 }); 18 19 if (res.ok) { 20 const data = (await res.json()) as StatusResponse; 21 return data; 22 } 23 24 return { status: "unknown" }; 25} 26 27export type StatusWidgetProps = { 28 slug: string; 29 href?: string; 30}; 31 32export async function StatusWidget({ slug, href }: StatusWidgetProps) { 33 const { status } = await getStatus(slug); 34 35 const { label, color } = statusDictionary[status]; 36 37 return ( 38 <a 39 className="inline-flex max-w-fit items-center gap-2 rounded-md border border-gray-200 px-3 py-1 text-gray-700 text-sm hover:bg-gray-100 hover:text-black dark:border-gray-800 dark:text-gray-300 dark:hover:bg-gray-900 dark:hover:text-white" 40 href={href || `https://${slug}.openstatus.dev`} 41 target="_blank" 42 rel="noreferrer" 43 > 44 {label} 45 <span className="relative flex h-2 w-2"> 46 {status === "operational" ? ( 47 <span 48 className={`absolute inline-flex h-full w-full animate-ping rounded-full ${color} opacity-75 duration-1000`} 49 /> 50 ) : null} 51 <span 52 className={`relative inline-flex h-2 w-2 rounded-full ${color}`} 53 /> 54 </span> 55 </a> 56 ); 57}