50 lines
1.7 KiB
TypeScript
50 lines
1.7 KiB
TypeScript
import type { ConnectionStatus, ServiceType } from '../../types/connection'
|
|
import { ActionButton } from '../ui/ActionButton'
|
|
import './ServiceCard.scss'
|
|
|
|
interface Props {
|
|
serviceType: ServiceType
|
|
label: string
|
|
icon: string
|
|
status: ConnectionStatus | null
|
|
onConnect: () => void
|
|
onDisconnect: () => void
|
|
onSearch: () => void
|
|
}
|
|
|
|
export function ServiceCard({ serviceType: _serviceType, label, icon, status, onConnect, onDisconnect, onSearch }: Readonly<Props>) {
|
|
const connected = status?.connected ?? false
|
|
|
|
const formatExpiry = (iso: string | null) => {
|
|
if (!iso) return null
|
|
const d = new Date(iso)
|
|
return d.toLocaleDateString(undefined, { dateStyle: 'medium' })
|
|
}
|
|
|
|
return (
|
|
<div className="service-card">
|
|
<div className="service-card__info">
|
|
<div className="service-card__icon">{icon}</div>
|
|
<div>
|
|
<p className="service-card__name">{label}</p>
|
|
<p className="service-card__meta">
|
|
<span className={`service-card__badge service-card__badge--${connected ? 'connected' : 'disconnected'}`}>
|
|
{connected ? 'Connected' : 'Not connected'}
|
|
</span>
|
|
{connected && status?.username && <span>{status.username}</span>}
|
|
{connected && status?.expiresAt && (
|
|
<span>· expires {formatExpiry(status.expiresAt)}</span>
|
|
)}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div className="service-card__actions">
|
|
<ActionButton variant={connected ? 'disconnect' : 'connect'} onClick={connected ? onDisconnect : onConnect}>
|
|
{connected ? 'Disconnect' : 'Connect'}
|
|
</ActionButton>
|
|
{connected && (<ActionButton variant='search' onClick={onSearch}>Search</ActionButton>)}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|