Files
buzz/components/ui/status.tsx
T
dmgnr f7bd43087d
Build and Push Image / build-backend (push) Successful in 1m4s
Build and Push Image / build-frontend (push) Successful in 2m52s
Build and Push Image / push (push) Successful in 1m16s
feat: add mobile upload
2026-08-29 15:32:47 +07:00

82 lines
2.4 KiB
TypeScript

"use client"
import type { ComponentProps, HTMLAttributes } from "react"
import { Badge } from "@/components/ui/badge"
import { cn } from "@/lib/utils"
export type StatusProps = ComponentProps<typeof Badge> & {
status: "online" | "offline" | "maintenance" | "degraded"
}
export const Status = ({ className, status, ...props }: StatusProps) => (
<Badge
className={cn("flex items-center gap-2", "group", status, className)}
variant="secondary"
{...(props as any)}
/>
)
export type StatusIndicatorProps = HTMLAttributes<HTMLSpanElement>
export const StatusIndicator = ({ className, ...props }: StatusIndicatorProps) => (
<span className={cn("relative flex h-2 w-2", className)} {...(props as any)}>
<span
className={cn(
"absolute inline-flex h-full w-full animate-ping rounded-full opacity-75",
"group-[.online]:bg-emerald-500",
"group-[.offline]:bg-red-500",
"group-[.maintenance]:bg-blue-500",
"group-[.degraded]:bg-amber-500",
)}
/>
<span
className={cn(
"relative inline-flex h-2 w-2 rounded-full",
"group-[.online]:bg-emerald-500",
"group-[.offline]:bg-red-500",
"group-[.maintenance]:bg-blue-500",
"group-[.degraded]:bg-amber-500",
)}
/>
</span>
)
export type StatusLabelProps = HTMLAttributes<HTMLSpanElement>
export const StatusLabel = ({ className, children, ...props }: StatusLabelProps) => (
<span className={cn("text-muted-foreground", className)} {...(props as any)}>
{children ?? (
<>
<span className="hidden group-[.online]:block">Online</span>
<span className="hidden group-[.offline]:block">Offline</span>
<span className="hidden group-[.maintenance]:block">Maintenance</span>
<span className="hidden group-[.degraded]:block">Degraded</span>
</>
)}
</span>
)
// Demo
export function Demo() {
return (
<div className="fixed inset-0 flex flex-wrap items-center justify-center gap-4">
<Status status="online">
<StatusIndicator />
<StatusLabel />
</Status>
<Status status="offline">
<StatusIndicator />
<StatusLabel />
</Status>
<Status status="maintenance">
<StatusIndicator />
<StatusLabel />
</Status>
<Status status="degraded">
<StatusIndicator />
<StatusLabel />
</Status>
</div>
)
}