From ea320548b6d602edc6afeda4995e11de5173f438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Tue, 1 Sep 2026 19:02:32 +0200 Subject: [PATCH] Use shadcn Alert for the "no devices connected" hints Replaces the ad-hoc bp-glass Card used for the "No devices connected yet." placeholder in ButtplugConsole and ReplayPlayer with the shadcn Alert component (newly installed). Co-Authored-By: Claude Sonnet 5 --- components/control/ButtplugConsole.tsx | 11 ++-- components/sessions/ReplayPlayer.tsx | 12 ++-- components/ui/alert.tsx | 76 ++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 9 deletions(-) create mode 100644 components/ui/alert.tsx diff --git a/components/control/ButtplugConsole.tsx b/components/control/ButtplugConsole.tsx index 2edc212..17070b9 100644 --- a/components/control/ButtplugConsole.tsx +++ b/components/control/ButtplugConsole.tsx @@ -22,6 +22,8 @@ import { DeviceCard } from "./DeviceCard"; import { RecordControls } from "./RecordControls"; import { NameSessionDialog } from "./NameSessionDialog"; import { Card, CardContent } from "@/components/ui/card"; +import { Alert, AlertDescription } from "@/components/ui/alert"; +import { Info } from "lucide-react"; interface ActiveSession { id: number; @@ -240,12 +242,13 @@ export function ButtplugConsole() { {storeError &&

{storeError}

} {Object.keys(devices).length === 0 ? ( - - + + + No devices connected yet. Scan to discover nearby toys, then select one from your browser's pairing prompt. - - + + ) : (
{Object.values(devices).map((device) => ( diff --git a/components/sessions/ReplayPlayer.tsx b/components/sessions/ReplayPlayer.tsx index dd8d5db..48b21e4 100644 --- a/components/sessions/ReplayPlayer.tsx +++ b/components/sessions/ReplayPlayer.tsx @@ -11,7 +11,8 @@ import { disconnectAll, getButtplugClientHandle, getDevice, startScanning, stopS import { SessionPlayer, type SessionEventRow } from "@/lib/buttplug/player"; import { useButtplugStore } from "@/lib/buttplug/store"; import type { ActuatorInfo, ReplayDeviceSlot } from "@/lib/buttplug/types"; -import { Pause, Play } from "lucide-react"; +import { Info, Pause, Play } from "lucide-react"; +import { Alert, AlertDescription } from "@/components/ui/alert"; interface ReplayDataResponse { session: { @@ -163,12 +164,13 @@ export function ReplayPlayer({ sessionId }: { sessionId: number }) {
{connectedDevices.length === 0 && ( - - + + + No devices connected yet. Scan to discover nearby toys, then match them to this session's original device slots. - - + + )} ) : ( diff --git a/components/ui/alert.tsx b/components/ui/alert.tsx new file mode 100644 index 0000000..1fe3176 --- /dev/null +++ b/components/ui/alert.tsx @@ -0,0 +1,76 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const alertVariants = cva( + "group/alert relative grid w-full gap-0.5 rounded-lg border px-2.5 py-2 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4", + { + variants: { + variant: { + default: "bg-card text-card-foreground", + destructive: + "bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +function Alert({ + className, + variant, + ...props +}: React.ComponentProps<"div"> & VariantProps) { + return ( +
+ ) +} + +function AlertTitle({ className, ...props }: React.ComponentProps<"div">) { + return ( +
svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground", + className + )} + {...props} + /> + ) +} + +function AlertDescription({ + className, + ...props +}: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function AlertAction({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +export { Alert, AlertTitle, AlertDescription, AlertAction }