import { useState, useEffect } from 'react' import { Card, CardContent, CardHeader, CardTitle } from '@core/components/ui/card' import { Badge } from '@core/components/ui/badge' import { Skeleton } from '@core/components/ui/skeleton' import { Terminal, CheckCircle } from 'lucide-react' import { apiFetch } from '@core/lib/api' interface CliInstance { id: string serial: string app_slug: string version: string first_seen_at: string last_signal_at: string claimed_at?: string claimed_by_person_id?: string } interface CliInstancesCardProps { accountId?: string personId?: string title?: string } export function CliInstancesCard({ accountId, personId, title = "CLI Installations" }: CliInstancesCardProps) { const [instances, setInstances] = useState([]) const [loading, setLoading] = useState(true) useEffect(() => { async function loadInstances() { if (!accountId && !personId) return try { setLoading(true) const endpoint = accountId ? `/custom_api/account-cli-instances?account_id=${accountId}` : `/custom_api/person-cli-instances?person_id=${personId}` const { data } = await apiFetch(endpoint) setInstances(data || []) } catch (e) { console.error('Failed to load CLI instances:', e) } finally { setLoading(false) } } loadInstances() }, [accountId, personId]) // Truncate serial for display const truncateSerial = (serial: string) => { if (!serial || serial.length < 20) return serial return `${serial.slice(0, 8)}***${serial.slice(-6)}` } if (loading) { return ( {title} ) } if (instances.length === 0) { return ( {title}

No CLI installations claimed yet

) } return (
{title} {instances.length}
{instances.map((instance) => (
{truncateSerial(instance.serial)} {instance.app_slug} v{instance.version}
First seen {new Date(instance.first_seen_at).toLocaleDateString()} {instance.last_signal_at && ( <> Active {new Date(instance.last_signal_at).toLocaleDateString()} )}
))}
) }