initial commit
Recommender Build and Deploy (internal) / Build Recommender Image (push) Failing after 3m48s
Recommender Build and Deploy (internal) / Deploy Recommender (internal) (push) Has been skipped

This commit is contained in:
2026-03-25 17:34:37 -03:00
commit f9c7582e4d
52 changed files with 7022 additions and 0 deletions
@@ -0,0 +1,60 @@
import type { RecommendationSummary } from '../types/index.js';
interface SidebarProps {
list: RecommendationSummary[];
selectedId: string | null;
onSelect: (id: string) => void;
onNewClick: () => void;
}
function statusIcon(status: RecommendationSummary['status']): string {
switch (status) {
case 'done': return '✓';
case 'error': return '✗';
case 'running': return '⟳';
default: return '…';
}
}
function statusClass(status: RecommendationSummary['status']): string {
switch (status) {
case 'done': return 'status-done';
case 'error': return 'status-error';
case 'running': return 'status-running';
default: return 'status-pending';
}
}
export function Sidebar({ list, selectedId, onSelect, onNewClick }: SidebarProps) {
return (
<aside class="sidebar">
<div class="sidebar-header">
<span class="sidebar-title">Recommender</span>
</div>
<button class="btn-new" onClick={onNewClick}>
+ New Recommendation
</button>
<div class="sidebar-section-label">History</div>
<ul class="sidebar-list">
{list.length === 0 && (
<li class="sidebar-empty">No recommendations yet</li>
)}
{list.map((item) => (
<li
key={item.id}
class={`sidebar-item${selectedId === item.id ? ' selected' : ''}`}
onClick={() => onSelect(item.id)}
>
<span class={`sidebar-icon ${statusClass(item.status)}`}>
{statusIcon(item.status)}
</span>
<span class="sidebar-item-title">{item.title}</span>
</li>
))}
</ul>
</aside>
);
}