<script lang="ts">
import { projectsStore } from '$lib/stores/projects.svelte.js';
import type { ProjectItem } from '$lib/api.js';
let { onswitch }: { onswitch: (workingDir: string) => void } = $props();
function projectName(workingDir: string | null): string {
if (!workingDir) return 'Unknown';
const segments = workingDir.replace(/\/+$/, '').split('/');
return segments[segments.length - 1] || workingDir;
}
function projectInitial(workingDir: string | null): string {
return projectName(workingDir).charAt(0).toUpperCase();
}
</script>
<div class="project-list" role="listbox" aria-label="Projects">
{#if projectsStore.loading}
<div class="empty">Loading...</div>
{:else if projectsStore.projects.length === 0}
<div class="empty">No projects</div>
{:else}
{#each projectsStore.projects as project (project.id)}
{@const isActive = projectsStore.activeProjectId === project.id}
<div
class="project-item"
class:active={isActive}
onclick={() => { if (project.working_dir) onswitch(project.working_dir); }}
onkeydown={(e) => { if (e.key === 'Enter' && project.working_dir) onswitch(project.working_dir); }}
tabindex="0"
role="option"
aria-selected={isActive}
>
<div class="project-icon" class:active={isActive}>
{projectInitial(project.working_dir)}
</div>
<div class="project-info">
<div class="project-name">{projectName(project.working_dir)}</div>
<div class="project-path">{project.working_dir}</div>
</div>
{#if project.session_count > 0}
<span class="session-badge">{project.session_count}</span>
{/if}
</div>
{/each}
{/if}
</div>
<style>
.project-list {
padding: 0.25rem 0;
}
.empty {
padding: 1rem;
color: var(--fg-dim);
font-size: 0.875rem;
text-align: center;
}
.project-item {
display: flex;
align-items: center;
gap: 0.625rem;
padding: 0.5rem 1rem;
cursor: pointer;
border-left: 2px solid transparent;
transition: background 0.1s;
}
.project-item:hover {
background: var(--bg-elevated);
}
.project-item.active {
background: var(--bg-elevated);
border-left-color: var(--accent);
}
.project-item:focus-visible {
outline: 2px solid var(--accent);
outline-offset: -2px;
}
.project-icon {
width: 1.75rem;
height: 1.75rem;
border-radius: 6px;
background: var(--bg);
color: var(--fg-dim);
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
font-size: 0.75rem;
flex-shrink: 0;
}
.project-icon.active {
background: var(--accent-dim);
color: var(--accent);
}
.project-info {
flex: 1;
min-width: 0;
}
.project-name {
font-size: 0.875rem;
font-weight: 500;
color: var(--fg);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.project-item.active .project-name {
color: var(--fg-bright);
font-weight: 600;
}
.project-path {
font-size: 0.6875rem;
color: var(--fg-dim);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.session-badge {
font-size: 0.6875rem;
color: var(--fg-dim);
background: var(--bg);
padding: 0.125rem 0.375rem;
border-radius: 9999px;
flex-shrink: 0;
}
</style>