@@ -4,13 +4,15 @@ import { useState, useEffect, useMemo } from 'react'
44import Image from 'next/image'
55import ThumbnailRibbon from './components/ThumbnailRibbon'
66import AnnotationViewer from './components/AnnotationViewer'
7- import { ImageData , Annotation , PromptAnnotation } from './types'
7+ import PlatformBadge from './components/PlatformBadge'
8+ import { ImageData , Annotation , PromptAnnotation , PlatformInfo } from './types'
89import { Sparkles , ChevronDown , Loader2 , ExternalLink , Sun , Moon } from 'lucide-react'
910
1011export default function Dashboard ( ) {
1112 const [ images , setImages ] = useState < ImageData [ ] > ( [ ] )
1213 const [ selectedImageIndex , setSelectedImageIndex ] = useState ( 0 )
1314 const [ annotations , setAnnotations ] = useState < Record < string , Annotation [ ] > > ( { } )
15+ const [ platformInfo , setPlatformInfo ] = useState < PlatformInfo | null > ( null )
1416 const [ selectedModel , setSelectedModel ] = useState < string > ( '' )
1517 const [ selectedPromptKey , setSelectedPromptKey ] = useState < string > ( '' )
1618 const [ loading , setLoading ] = useState ( true )
@@ -87,13 +89,23 @@ export default function Dashboard() {
8789 return [ ]
8890 } , [ annotations , selectedImageIndex , images , selectedModel ] )
8991
92+ // Get current model annotation (includes platform override if present)
93+ const currentModelAnnotation = useMemo ( ( ) => {
94+ if ( ! images [ selectedImageIndex ] || ! selectedModel ) return null
95+ const imageAnnotations = annotations [ images [ selectedImageIndex ] . id ] || [ ]
96+ return imageAnnotations . find ( a => a . model === selectedModel ) || null
97+ } , [ annotations , selectedImageIndex , images , selectedModel ] )
98+
9099 // Get current prompt annotation
91100 const currentPromptAnnotation = useMemo ( ( ) => {
92- if ( ! images [ selectedImageIndex ] || ! selectedModel || ! selectedPromptKey ) return null
93- const imageAnnotations = annotations [ images [ selectedImageIndex ] . id ] || [ ]
94- const modelAnnotation = imageAnnotations . find ( a => a . model === selectedModel )
95- return modelAnnotation ?. prompts [ selectedPromptKey ] || null
96- } , [ annotations , selectedImageIndex , images , selectedModel , selectedPromptKey ] )
101+ if ( ! currentModelAnnotation || ! selectedPromptKey ) return null
102+ return currentModelAnnotation . prompts [ selectedPromptKey ] || null
103+ } , [ currentModelAnnotation , selectedPromptKey ] )
104+
105+ // Get effective platform (annotation override or default)
106+ const effectivePlatform = useMemo ( ( ) => {
107+ return currentModelAnnotation ?. platform || platformInfo
108+ } , [ currentModelAnnotation , platformInfo ] )
97109
98110 async function loadAnnotationsForImage ( imageId : string ) {
99111 setImageLoading ( true )
@@ -104,6 +116,11 @@ export default function Dashboard() {
104116 const data = await response . json ( )
105117 setAnnotations ( prev => ( { ...prev , [ imageId ] : data . annotations || [ ] } ) )
106118
119+ // Extract platform info from metadata if available
120+ if ( data . metadata ?. platform ) {
121+ setPlatformInfo ( data . metadata . platform )
122+ }
123+
107124 // Auto-select first model and prompt if nothing selected
108125 if ( data . annotations && data . annotations . length > 0 ) {
109126 const firstAnnotation = data . annotations [ 0 ]
@@ -300,7 +317,7 @@ export default function Dashboard() {
300317 </ h3 >
301318 < div className = "flex-1 overflow-auto" >
302319 { currentPromptAnnotation ? (
303- < AnnotationViewer annotation = { currentPromptAnnotation } />
320+ < AnnotationViewer annotation = { currentPromptAnnotation } platform = { effectivePlatform } />
304321 ) : (
305322 < div className = "text-agi-teal-500 dark:text-zinc-500 text-center py-8" >
306323 { ! selectedModel ? 'Select a vision model to explore annotations' :
@@ -324,17 +341,25 @@ export default function Dashboard() {
324341
325342 { /* Footer */ }
326343 < footer className = "glass-footer px-6 py-3" >
327- < div className = "text-center text-sm text-agi-teal-600 dark:text-zinc-400" >
328- © 2025{ ' ' }
329- < a
330- href = "https://annotation.garden"
331- target = "_blank"
332- rel = "noopener noreferrer"
333- className = "text-agi-teal dark:text-agi-teal-400 hover:text-agi-orange transition-colors inline-flex items-center gap-1"
334- >
335- Annotation Garden Initiative
336- < ExternalLink className = "w-3 h-3" />
337- </ a >
344+ < div className = "flex flex-col md:flex-row items-center justify-between gap-2" >
345+ < div className = "text-sm text-agi-teal-600 dark:text-zinc-400" >
346+ © 2025{ ' ' }
347+ < a
348+ href = "https://annotation.garden"
349+ target = "_blank"
350+ rel = "noopener noreferrer"
351+ className = "text-agi-teal dark:text-agi-teal-400 hover:text-agi-orange transition-colors inline-flex items-center gap-1"
352+ >
353+ Annotation Garden Initiative
354+ < ExternalLink className = "w-3 h-3" />
355+ </ a >
356+ </ div >
357+ { platformInfo && (
358+ < div className = "flex items-center gap-2" >
359+ < span className = "text-xs text-agi-teal-500 dark:text-zinc-500" > Inference Platform:</ span >
360+ < PlatformBadge platform = { platformInfo } />
361+ </ div >
362+ ) }
338363 </ div >
339364 </ footer >
340365 </ main >
0 commit comments