| import { useState, useEffect } from 'react'; |
| import ResponseBlock from './ResponseBlock'; |
|
|
| function useWindowWidth() { |
| const [w, setW] = useState(typeof window !== 'undefined' ? window.innerWidth : 1200); |
| useEffect(() => { |
| const h = () => setW(window.innerWidth); |
| window.addEventListener('resize', h); |
| return () => window.removeEventListener('resize', h); |
| }, []); |
| return w; |
| } |
|
|
| export default function ResponseCarousel({ neonResponse, comparisonResponses, offset = 0, showPrePromptIndicator = false }) { |
| const screenWidth = useWindowWidth(); |
| const isMobile = screenWidth <= 480; |
| const isTablet = screenWidth <= 900; |
| const visible = isMobile ? 1 : (isTablet ? 1 : 2); |
| const visibleComparisons = comparisonResponses.slice(offset, offset + visible); |
|
|
| return ( |
| <div className={`carousel-track ${isMobile ? 'carousel-track--stacked' : ''} ${isTablet && !isMobile ? 'carousel-track--tablet' : ''}`}> |
| <div className="carousel-sticky"> |
| <ResponseBlock |
| response={neonResponse} |
| isNeonEmphasis={true} |
| showBadge={false} |
| showModelName={true} |
| showPersona={true} |
| showFooterParams={false} |
| showPrePromptIndicator={showPrePromptIndicator} |
| /> |
| </div> |
| <div className="carousel-scrollable"> |
| {visibleComparisons.map((r, i) => ( |
| <ResponseBlock |
| key={`${r.model_id}-${offset + i}`} |
| response={r} |
| showBadge={false} |
| showModelName={false} |
| showFooterParams={false} |
| isComparisonEmphasis={true} |
| showPrePromptIndicator={showPrePromptIndicator} |
| /> |
| ))} |
| {comparisonResponses.length === 0 && ( |
| <div className="carousel-empty">No comparison models selected</div> |
| )} |
| </div> |
| |
| <style>{` |
| .carousel-track { |
| display: grid; |
| grid-template-columns: 1fr 2fr; |
| gap: 12px; |
| align-items: stretch; |
| } |
| .carousel-track--tablet { |
| grid-template-columns: 1fr 1fr; |
| } |
| .carousel-track--stacked { |
| grid-template-columns: 1fr; |
| } |
| .carousel-sticky { |
| min-width: 0; |
| display: flex; |
| } |
| .carousel-scrollable { |
| display: flex; |
| gap: 12px; |
| min-width: 0; |
| overflow: hidden; |
| } |
| .carousel-scrollable .response-block { |
| flex: 1; |
| min-width: 0; |
| } |
| .carousel-empty { |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| flex: 1; |
| color: var(--text-muted); |
| font-size: 13px; |
| font-style: italic; |
| border: 1px dashed var(--border-primary); |
| border-radius: 12px; |
| padding: 24px; |
| } |
| `}</style> |
| </div> |
| ); |
| } |
|
|