cre-sync/components/control-center/StatusIndicator.tsx
BusyBee3333 4e6467ffb0 Add CRESync CRM application with Setup page
- Build complete Next.js CRM for commercial real estate
- Add authentication with JWT sessions and role-based access
- Add GoHighLevel API integration for contacts, conversations, opportunities
- Add AI-powered Control Center with tool calling
- Add Setup page with onboarding checklist (/setup)
- Add sidebar navigation with Setup menu item
- Fix type errors in onboarding API, GHL services, and control center tools
- Add Prisma schema with SQLite for local development
- Add UI components with clay morphism design system

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 17:30:55 -05:00

226 lines
6.2 KiB
TypeScript

'use client';
import React from 'react';
import { AlertTriangle, Wifi, WifiOff, Loader2 } from 'lucide-react';
import { cn } from '@/lib/utils';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/tooltip';
type ConnectionStatus = 'connected' | 'connecting' | 'error' | 'idle';
interface StatusIndicatorProps {
/** Current connection status */
status: ConnectionStatus;
/** Whether MCP (Model Context Protocol) is connected */
mcpConnected?: boolean;
/** Optional custom label to display */
label?: string;
}
/**
* Status configuration for each connection state
*/
const STATUS_CONFIG: Record<
ConnectionStatus,
{
color: string;
bgColor: string;
pulseColor?: string;
text: string;
icon: React.ReactNode;
}
> = {
connected: {
color: 'bg-green-500',
bgColor: 'bg-green-100',
pulseColor: 'bg-green-400',
text: 'Connected',
icon: <Wifi className="w-3.5 h-3.5 text-green-600" />,
},
connecting: {
color: 'bg-yellow-500',
bgColor: 'bg-yellow-100',
pulseColor: 'bg-yellow-400',
text: 'Connecting...',
icon: <Loader2 className="w-3.5 h-3.5 text-yellow-600 animate-spin" />,
},
error: {
color: 'bg-red-500',
bgColor: 'bg-red-100',
text: 'Connection Error',
icon: <WifiOff className="w-3.5 h-3.5 text-red-600" />,
},
idle: {
color: 'bg-gray-400',
bgColor: 'bg-gray-100',
text: 'Idle',
icon: <Wifi className="w-3.5 h-3.5 text-gray-500" />,
},
};
/**
* StatusIndicator - Shows connection status for the Control Center
*
* Displays a colored dot indicator with tooltip showing detailed status.
* Also shows warning if MCP is not connected.
*/
export const StatusIndicator: React.FC<StatusIndicatorProps> = ({
status,
mcpConnected = true,
label,
}) => {
const config = STATUS_CONFIG[status];
const showMcpWarning = !mcpConnected;
return (
<TooltipProvider>
<div className="flex items-center gap-2">
{/* Main status indicator */}
<Tooltip>
<TooltipTrigger asChild>
<div
className={cn(
'flex items-center gap-2',
'px-3 py-1.5',
'bg-[#F0F4F8]',
'rounded-full',
'shadow-[3px_3px_6px_#c5c9d1,-3px_-3px_6px_#ffffff]',
'cursor-default',
'transition-all duration-200'
)}
>
{/* Status dot with pulse animation for active states */}
<div className="relative flex items-center justify-center">
<span
className={cn(
'w-2.5 h-2.5',
'rounded-full',
config.color,
'relative z-10'
)}
/>
{config.pulseColor && (
<span
className={cn(
'absolute',
'w-2.5 h-2.5',
'rounded-full',
config.pulseColor,
'animate-ping',
'opacity-75'
)}
/>
)}
</div>
{/* Status text/label */}
<span className="text-xs font-medium text-gray-600">
{label || config.text}
</span>
</div>
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">
<div className="flex items-center gap-2">
{config.icon}
<span>{config.text}</span>
</div>
</TooltipContent>
</Tooltip>
{/* MCP Warning indicator */}
{showMcpWarning && (
<Tooltip>
<TooltipTrigger asChild>
<div
className={cn(
'flex items-center gap-1.5',
'px-2.5 py-1.5',
'bg-amber-50',
'border border-amber-200',
'rounded-full',
'cursor-default',
'transition-all duration-200'
)}
>
<AlertTriangle className="w-3.5 h-3.5 text-amber-600" />
<span className="text-xs font-medium text-amber-700">
Limited
</span>
</div>
</TooltipTrigger>
<TooltipContent side="bottom" className="max-w-[200px] text-xs">
<div className="flex flex-col gap-1">
<span className="font-medium text-amber-700">
MCP Not Connected
</span>
<span className="text-gray-600">
Some features may be unavailable. Tool execution will be limited.
</span>
</div>
</TooltipContent>
</Tooltip>
)}
</div>
</TooltipProvider>
);
};
/**
* Compact version of StatusIndicator - just shows the dot
*/
export const StatusDot: React.FC<{
status: ConnectionStatus;
className?: string;
}> = ({ status, className }) => {
const config = STATUS_CONFIG[status];
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<div
className={cn(
'relative flex items-center justify-center',
'w-4 h-4',
className
)}
>
<span
className={cn(
'w-2.5 h-2.5',
'rounded-full',
config.color,
'relative z-10'
)}
/>
{config.pulseColor && (
<span
className={cn(
'absolute',
'w-2.5 h-2.5',
'rounded-full',
config.pulseColor,
'animate-ping',
'opacity-75'
)}
/>
)}
</div>
</TooltipTrigger>
<TooltipContent side="right" className="text-xs">
<div className="flex items-center gap-2">
{config.icon}
<span>{config.text}</span>
</div>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
};
export default StatusIndicator;