Python 64.6%
TypeScript 33.7%
CSS 0.8%
1import { BookOpen, ExternalLink } from 'lucide-react';2import type { ToolCallView } from '@/lib/types';34interface Source { index: number; course: string; module: string; section: string; page: string; url: string; excerpt: string }56export function CourseSourceCard({ call }: { call: ToolCallView }) {7 const p = call.payload as { query?: string; sources?: Source[] };8 const sources = p.sources || [];9 if (!sources.length) return <p className="text-sm text-neutral-muted">Aucun passage trouvé dans le matériel du cours.</p>;10 return (11 <ul className="grid gap-2 sm:grid-cols-2">12 {sources.map((s) => (13 <li key={s.index}>14 <a href={s.url || '#'} target={s.url ? '_blank' : undefined} rel="noopener noreferrer" className="block rounded-xl border border-neutral-line bg-white p-3 hover:bg-neutral-surface h-full">15 <span className="inline-flex items-center gap-1.5 text-[11px] font-semibold text-uqo-blue bg-uqo-blue-light rounded-md px-1.5 py-0.5"><BookOpen size={11} /> S{s.index} · {s.course}</span>16 <span className="block text-sm font-medium text-uqo-blue-dark mt-1.5 line-clamp-1">{s.module}</span>17 <span className="block text-xs text-neutral-muted line-clamp-1">{s.section && s.section !== s.module ? s.section : ''} {s.url && <ExternalLink size={10} className="inline" />}</span>18 <span className="block text-xs text-neutral-text/80 mt-1 line-clamp-3">{s.excerpt}</span>19 </a>20 </li>21 ))}22 </ul>23 );24}25