Files
spiceflow/client/src/lib/components/SessionCard.svelte
2026-01-20 14:04:19 -05:00

81 lines
2.5 KiB
Svelte

<script lang="ts">
import { createEventDispatcher } from 'svelte';
import type { Session } from '$lib/api';
export let session: Session;
const dispatch = createEventDispatcher<{ delete: void }>();
function handleDelete(event: MouseEvent) {
event.preventDefault();
event.stopPropagation();
dispatch('delete');
}
$: externalId = session['external-id'] || session.externalId || '';
$: updatedAt = session['updated-at'] || session.updatedAt || session['created-at'] || session.createdAt || '';
$: shortId = externalId.slice(0, 8);
function formatTime(iso: string): string {
if (!iso) return '';
const date = new Date(iso);
const now = new Date();
const diff = now.getTime() - date.getTime();
const minutes = Math.floor(diff / 60000);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
if (days > 0) return `${days}d ago`;
if (hours > 0) return `${hours}h ago`;
if (minutes > 0) return `${minutes}m ago`;
return 'Just now';
}
const statusColors: Record<string, string> = {
idle: 'bg-zinc-600',
processing: 'bg-green-500 animate-pulse',
'awaiting-permission': 'bg-amber-500 animate-pulse'
};
$: statusColor = session.provider === 'tmux' ? 'bg-green-500' : statusColors[session.status];
const providerColors: Record<string, string> = {
claude: 'text-spice-400',
opencode: 'text-emerald-400',
tmux: 'text-cyan-400'
};
</script>
<a
href="/session/{session.id}"
class="card block hover:border-spice-500/50 transition-all active:scale-[0.98]"
>
<div class="flex items-start justify-between gap-3">
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 mb-1">
<span class="w-2 h-2 rounded-full {statusColor}"></span>
<span class="text-xs font-medium uppercase tracking-wide {providerColors[session.provider]}">
{session.provider}
</span>
</div>
<h3 class="font-medium text-zinc-100 truncate">
{session.title || `Session ${shortId}`}
</h3>
</div>
<div class="text-right flex-shrink-0 flex items-center gap-2">
<span class="text-xs text-zinc-500">{formatTime(updatedAt)}</span>
<button
on:click={handleDelete}
class="p-1 text-zinc-500 hover:text-red-400 hover:bg-red-500/10 rounded transition-colors"
title="Delete session"
>
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
</div>
</a>