Spaces:
Running
Running
| 'use client'; | |
| import React from 'react'; | |
| interface Source { | |
| id: number; | |
| docName: string; | |
| page: number; | |
| support: string; | |
| } | |
| interface SourcesFootnotesProps { | |
| sources: Source[]; | |
| onOpenPage: (docName: string, page: number) => void; | |
| } | |
| export function SourcesFootnotes({ sources, onOpenPage }: SourcesFootnotesProps) { | |
| // Group sources by docName | |
| const grouped: Record<string, { pages: number[]; supports: string[] }> = {}; | |
| sources.forEach(src => { | |
| const key = src.docName; | |
| if (!grouped[key]) { | |
| grouped[key] = { pages: [], supports: [] }; | |
| } | |
| if (!grouped[key].pages.includes(src.page)) { | |
| grouped[key].pages.push(src.page); | |
| } | |
| if (src.support && !grouped[key].supports.includes(src.support)) { | |
| grouped[key].supports.push(src.support); | |
| } | |
| }); | |
| const docKeys = Object.keys(grouped); | |
| return ( | |
| <div style={{ padding: '1.25rem 1.5rem 1.5rem', borderTop: '1px solid var(--border-subtle)' }}> | |
| {/* Label */} | |
| <div style={{ | |
| display: 'flex', | |
| alignItems: 'center', | |
| justifyContent: 'space-between', | |
| marginBottom: '0.625rem', | |
| }}> | |
| <div className="section-label" style={{ marginBottom: 0 }}> | |
| Sources & Footnotes | |
| </div> | |
| <span style={{ fontSize: '0.65rem', color: 'var(--text-muted)', fontStyle: 'italic' }}> | |
| {sources.length} reference{sources.length !== 1 ? 's' : ''} | |
| </span> | |
| </div> | |
| {/* Footnotes */} | |
| <div className="footnote-list" style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem' }}> | |
| {docKeys.map((docName, idx) => { | |
| const item = grouped[docName]; | |
| const supportText = item.supports[0] || 'Retrieved evidence'; | |
| return ( | |
| <div key={idx} className="footnote-item"> | |
| <div className="footnote-number">{idx + 1}</div> | |
| <div className="footnote-content" style={{ display: 'flex', flexDirection: 'column', gap: '0.15rem' }}> | |
| <div className="footnote-doc" style={{ fontWeight: 600, fontSize: '0.8rem', color: 'var(--text-primary)' }}> | |
| {docName} | |
| </div> | |
| <div className="footnote-support" style={{ fontSize: '0.72rem', color: 'var(--text-muted)', marginBottom: '0.25rem' }}> | |
| {supportText} | |
| </div> | |
| {/* Horizontal link list for pages */} | |
| <div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: '0.45rem', marginTop: '0.4rem' }}> | |
| {item.pages.map((pageNum) => ( | |
| <button | |
| key={pageNum} | |
| onClick={() => onOpenPage(docName, pageNum)} | |
| style={{ | |
| background: 'var(--enbd-blue-muted)', | |
| color: 'var(--enbd-blue)', | |
| border: '1px solid var(--enbd-blue-border)', | |
| padding: '0.2rem 0.65rem', | |
| fontSize: '0.68rem', | |
| borderRadius: '20px', | |
| cursor: 'pointer', | |
| fontWeight: 600, | |
| fontFamily: 'var(--font-body)', | |
| display: 'inline-flex', | |
| alignItems: 'center', | |
| gap: '0.25rem', | |
| transition: 'all var(--ease-fast)', | |
| letterSpacing: '0.01em', | |
| }} | |
| onMouseOver={e => { | |
| e.currentTarget.style.background = 'rgba(0, 85, 165, 0.14)'; | |
| e.currentTarget.style.boxShadow = '0 0 8px rgba(0, 85, 165, 0.14)'; | |
| }} | |
| onMouseOut={e => { | |
| e.currentTarget.style.background = 'var(--enbd-blue-muted)'; | |
| e.currentTarget.style.boxShadow = 'none'; | |
| }} | |
| > | |
| <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"> | |
| <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> | |
| <polyline points="14 2 14 8 20 8"/> | |
| </svg> | |
| Page {pageNum} | |
| </button> | |
| ))} | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| })} | |
| </div> | |
| </div> | |
| ); | |
| } | |