Files
k-tv/k-tv-frontend/app/(main)/tv/components/no-signal.tsx

63 lines
2.0 KiB
TypeScript

import { WifiOff, AlertTriangle, Loader2 } from "lucide-react";
type NoSignalVariant = "no-signal" | "error" | "loading";
interface NoSignalProps {
variant?: NoSignalVariant;
message?: string;
children?: React.ReactNode;
}
const VARIANTS: Record<
NoSignalVariant,
{ icon: React.ReactNode; heading: string; defaultMessage: string }
> = {
"no-signal": {
icon: <WifiOff className="h-10 w-10 text-zinc-600" />,
heading: "No Signal",
defaultMessage: "Nothing is scheduled to play right now.",
},
error: {
icon: <AlertTriangle className="h-10 w-10 text-zinc-600" />,
heading: "Playback Error",
defaultMessage: "Something went wrong. Try switching channels.",
},
loading: {
icon: <Loader2 className="h-10 w-10 animate-spin text-zinc-600" />,
heading: "Loading",
defaultMessage: "Tuning in…",
},
};
export function NoSignal({ variant = "no-signal", message, children }: NoSignalProps) {
const { icon, heading, defaultMessage } = VARIANTS[variant];
return (
<div className="relative flex h-full w-full flex-col items-center justify-center gap-4 bg-zinc-950 select-none overflow-hidden">
{/* Static noise texture */}
<div
aria-hidden
className="pointer-events-none absolute inset-0 opacity-[0.03]"
style={{
backgroundImage:
"url(\"data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E\")",
backgroundSize: "200px 200px",
}}
/>
{icon}
<div className="flex flex-col items-center gap-1 text-center">
<p className="text-sm font-semibold uppercase tracking-widest text-zinc-500">
{heading}
</p>
<p className="max-w-xs text-xs text-zinc-700">{message ?? defaultMessage}</p>
</div>
{children}
</div>
);
}
export type { NoSignalProps, NoSignalVariant };