davidpomerenke's picture
Upload from GitHub Actions: added some transparency to model contribution info
0044d85 verified
import { useState, useEffect } from 'react'
import { PrimeReactProvider } from 'primereact/api'
import 'primereact/resources/themes/lara-light-cyan/theme.css'
import ModelTable from './components/ModelTable'
import LanguageTable from './components/LanguageTable'
import DatasetTable from './components/DatasetTable'
import WorldMap from './components/WorldMap'
import AutoComplete from './components/AutoComplete'
import LanguagePlot from './components/LanguagePlot'
import SpeakerPlot from './components/SpeakerPlot'
import HistoryPlot from './components/HistoryPlot'
import CostPlot from './components/CostPlot'
import { Carousel } from 'primereact/carousel'
import { Dialog } from 'primereact/dialog'
import { Button } from 'primereact/button'
function App () {
const [data, setData] = useState(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
const [selectedLanguages, setSelectedLanguages] = useState([])
const [dialogVisible, setDialogVisible] = useState(false)
const [aboutVisible, setAboutVisible] = useState(false)
const [contributeVisible, setContributeVisible] = useState(false)
useEffect(() => {
fetch('/api/data', {
method: 'POST',
body: JSON.stringify({ selectedLanguages })
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok')
}
return response.json()
})
.then(jsonData => {
setData(jsonData)
setLoading(false)
})
.catch(err => {
setError(err.message)
setLoading(false)
})
}, [selectedLanguages])
const [windowWidth, setWindowWidth] = useState(window.innerWidth)
const [windowHeight, setWindowHeight] = useState(window.innerHeight)
useEffect(() => {
const handleResize = () => {
setWindowWidth(window.innerWidth)
setWindowHeight(window.innerHeight)
}
window.addEventListener('resize', handleResize)
return () => window.removeEventListener('resize', handleResize)
}, [])
return (
<PrimeReactProvider>
<div style={{ minHeight: '100vh', display: 'flex', flexDirection: 'column', width: '100vw' }}>
<div style={{backgroundColor: '#fff3cd', color: '#856404', padding: '0.75rem 1.25rem', marginBottom: '1rem', border: '1px solid #ffeeba', borderRadius: '0.25rem', textAlign: 'center'}}>
<strong>Work in Progress:</strong> This dashboard is currently under active development. Evaluation results are not yet final.
<a href="https://github.com/datenlabor-bmz/ai-language-monitor" target="_blank" rel="noopener noreferrer" style={{
textDecoration: 'none',
color: '#856404',
float: 'right',
fontSize: '1.2rem',
fontWeight: 'bold',
padding: '0 0.5rem',
borderRadius: '3px',
backgroundColor: 'rgba(255,255,255,0.3)'
}}>
<i className="pi pi-github" title="View on GitHub" style={{ marginRight: '0.3rem' }} />
GitHub
</a>
</div>
<header
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
padding: '5vh 5vw',
width: '100%',
maxWidth: '1400px',
margin: '0 auto'
}}
>
<div>
<span
role='img'
aria-label='Globe Emoji'
style={{ fontSize: '40px' }}
>
🌍
</span>
</div>
<h1 style={{
fontSize: '2.5rem',
fontWeight: '600',
margin: '1rem 0 0.5rem 0',
color: '#333',
letterSpacing: '-0.01em'
}}>
AI Language Proficiency Monitor
</h1>
<p style={{
fontSize: '1.1rem',
color: '#666',
margin: '0 0 2.5rem 0',
fontWeight: '400',
maxWidth: '700px',
lineHeight: '1.5'
}}>
Comprehensive multilingual evaluation results for AI language models
</p>
<div style={{ display: 'flex', gap: '1rem', marginBottom: '1.5rem', flexWrap: 'wrap', justifyContent: 'center' }}>
<Button
label="πŸ“š About this tool"
className="p-button-text"
onClick={() => setAboutVisible(true)}
style={{
color: '#666',
border: '1px solid #ddd',
padding: '0.5rem 1rem',
borderRadius: '4px',
fontSize: '0.9rem'
}}
/>
<Button
label="πŸš€ Add your model (soon)"
className="p-button-text"
onClick={() => setContributeVisible(true)}
tooltip="This feature is on our roadmap and will be available soon."
tooltipOptions={{ position: 'bottom' }}
style={{
color: '#666',
border: '1px solid #ddd',
padding: '0.5rem 1rem',
borderRadius: '4px',
fontSize: '0.9rem'
}}
/>
</div>
{data && (
<AutoComplete
languages={data?.language_table}
onComplete={items => setSelectedLanguages(items)}
/>
)}
</header>
<main
style={{
display: 'flex',
flexDirection: 'column',
gap: '3rem',
width: '100%',
paddingBottom: '5vh',
padding: '1rem 15vw 5vh 15vw'
}}
>
{loading && (
<div style={{ width: '100%', textAlign: 'center' }}>
<i className='pi pi-spinner pi-spin' style={{ fontSize: '4rem' }} />
</div>
)}
{error && <div style={{ width: '100%', textAlign: 'center' }}><p>Error: {error}</p></div>}
{data && (
<>
<div style={{ width: '100%' }}>
<ModelTable
data={data.model_table}
selectedLanguages={selectedLanguages}
allLanguages={data.language_table || []}
/>
</div>
<div style={{ width: '100%' }}>
<LanguageTable
data={data.language_table}
selectedLanguages={selectedLanguages}
setSelectedLanguages={setSelectedLanguages}
totalModels={data.model_table?.length || 0}
/>
</div>
<div style={{ width: '100%' }}>
<DatasetTable data={data} />
</div>
<div
id='figure'
style={{
width: '100%',
position: 'relative'
}}
>
<Button
icon="pi pi-external-link"
className="p-button-text p-button-plain"
onClick={() => setDialogVisible(true)}
tooltip="Open in larger view"
style={{
position: 'absolute',
top: '10px',
right: '10px',
zIndex: 1,
color: '#666'
}}
/>
<Carousel
value={[
<WorldMap data={data.countries} />,
<LanguagePlot data={data} />,
<SpeakerPlot data={data} />,
<HistoryPlot data={data} />,
<CostPlot data={data} />,
]}
numScroll={1}
numVisible={1}
itemTemplate={item => item}
circular
style={{ width: '100%', minHeight: '650px' }}
/>
</div>
</>
)}
</main>
{/* About Dialog */}
<Dialog
visible={aboutVisible}
onHide={() => setAboutVisible(false)}
style={{ width: '600px' }}
modal
header="About this tool"
>
<div>
<p>The <i>AI Language Proficiency Monitor</i> presents comprehensive multilingual evaluation results of AI language models.</p>
<h4>Who is this for?</h4>
<ul>
<li><b>Practitioners</b> can pick the best model for a given language.</li>
<li><b>Policymakers and funders</b> can identify and prioritize neglected languages.</li>
<li><b>Model developers</b> can compete on our <i>AI Language Proficiency</i> metric.</li>
</ul>
<h4>⚑ Live Updates</h4>
<p>Benchmark results automatically refresh every night and include the most popular models from <a href="https://openrouter.ai" target="_blank" rel="noopener noreferrer">OpenRouter</a>, plus community-submitted models.</p>
<h4>Authors</h4>
<p>The AI Language Proficiency Monitor is a collaboration between BMZ's <a href="https://www.bmz-digital.global/en/overview-of-initiatives/the-bmz-data-lab/" target="_blank" rel="noopener noreferrer">Data Lab</a>, the BMZ-Initiative <a href="https://www.bmz-digital.global/en/overview-of-initiatives/fair-forward/" target="_blank" rel="noopener noreferrer">Fair Forward</a> (implemented by GIZ), and the <a href="https://www.dfki.de/en/web/research/research-departments/multilinguality-and-language-technology/ee-team" target="_blank" rel="noopener noreferrer">E&E group</a> of DFKI's Multilinguality and Language Technology Lab.</p>
<h4>πŸ”— Links</h4>
<p>
<a
href="https://github.com/datenlabor-bmz/ai-language-monitor"
target="_blank"
rel="noopener noreferrer"
style={{
color: '#666',
textDecoration: 'none',
display: 'inline-flex',
alignItems: 'center',
gap: '0.5rem'
}}
>
<i className="pi pi-github" style={{ fontSize: '1.2rem' }} />
View source code on GitHub
</a>
</p>
</div>
</Dialog>
{/* Contribute Dialog */}
<Dialog
visible={contributeVisible}
onHide={() => setContributeVisible(false)}
style={{ width: '600px' }}
modal
header="Add your model & Contribute"
>
<div>
<h4>πŸš€ Submit Your Model</h4>
<p>Have a custom fine-tuned model you'd like to see on the leaderboard?</p>
<p><a href="https://forms.gle/ckvY9pS7XLcHYnaV8" target="_blank" rel="noopener noreferrer" style={{ color: '#28a745', fontWeight: 'bold' }}>β†’ Submit your model here</a></p>
<h4>πŸ”§ Contribute to Development</h4>
<p>Help us expand language coverage and add new evaluation tasks:</p>
<p><a href="https://github.com/datenlabor-bmz/ai-language-monitor/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer" style={{ color: '#007bff', fontWeight: 'bold' }}>β†’ Contribution guidelines</a></p>
</div>
</Dialog>
{/* Full-screen Dialog for Charts */}
<Dialog
visible={dialogVisible}
onHide={() => setDialogVisible(false)}
style={{ width: '90vw', height: '90vh' }}
maximizable
modal
header={null}
>
{data && (
<div style={{ width: '100%', height: '100%' }}>
<Carousel
value={[
<WorldMap data={data.countries} width={windowWidth * 0.7} height={windowHeight * 0.6} />,
<LanguagePlot data={data} width={windowWidth * 0.7} height={windowHeight * 0.6} />,
<SpeakerPlot data={data} width={windowWidth * 0.7} height={windowHeight * 0.6} />,
<HistoryPlot data={data} width={windowWidth * 0.7} height={windowHeight * 0.6} />,
<CostPlot data={data} />,
]}
numScroll={1}
numVisible={1}
itemTemplate={item => item}
circular
style={{ width: '100%', height: 'calc(90vh - 120px)' }}
/>
</div>
)}
</Dialog>
</div>
</PrimeReactProvider>
)
}
export default App