RafaelJaime's picture
Update src/App.js
e2da22a verified
raw
history blame
27.1 kB
import React, { useState, useEffect, useMemo } from 'react';
const UrologyLeaderboard = () => {
const [searchTerm, setSearchTerm] = useState('');
const [filterLicense, setFilterLicense] = useState('all');
const [sortBy, setSortBy] = useState('accuracy');
const [sortOrder, setSortOrder] = useState('desc');
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
const [refreshing, setRefreshing] = useState(false);
const [lastUpdated, setLastUpdated] = useState(null);
const mockData = [
{
model: "openai/gpt-4o-mini",
baseModel: "",
accuracy: 0.18543046357615803,
totalQuestions: 151,
correctAnswers: 28,
license: "API Service",
submitType: "openrouter",
submittedTime: "2025-05-22T16:53:10Z",
params: 0,
precision: "float16",
status: "FINISHED"
},
{
model: "anthropic/claude-3-sonnet",
baseModel: "claude-3-sonnet",
accuracy: 0.32450331125827815,
totalQuestions: 151,
correctAnswers: 49,
license: "API Service",
submitType: "openrouter",
submittedTime: "2025-05-22T14:30:25Z",
params: 0,
precision: "float16",
status: "FINISHED"
},
{
model: "meta-llama/llama-3.1-70b",
baseModel: "llama-3.1-70b",
accuracy: 0.27814569536423844,
totalQuestions: 151,
correctAnswers: 42,
license: "Apache 2.0",
submitType: "huggingface",
submittedTime: "2025-05-22T12:15:30Z",
params: 70000000000,
precision: "bfloat16",
status: "FINISHED"
},
{
model: "mistralai/mixtral-8x7b",
baseModel: "mixtral-8x7b",
accuracy: 0.23841059602649006,
totalQuestions: 151,
correctAnswers: 36,
license: "Apache 2.0",
submitType: "huggingface",
submittedTime: "2025-05-22T10:45:15Z",
params: 46700000000,
precision: "bfloat16",
status: "FINISHED"
},
{
model: "google/gemini-pro",
baseModel: "gemini-pro",
accuracy: 0.29801324503311255,
totalQuestions: 151,
correctAnswers: 45,
license: "API Service",
submitType: "google",
submittedTime: "2025-05-22T08:20:40Z",
params: 0,
precision: "float16",
status: "FINISHED"
},
{
model: "cohere/command-r-plus",
baseModel: "command-r-plus",
accuracy: 0.35761589403973510,
totalQuestions: 151,
correctAnswers: 54,
license: "API Service",
submitType: "cohere",
submittedTime: "2025-05-21T18:12:30Z",
params: 0,
precision: "float16",
status: "FINISHED"
},
{
model: "openai/gpt-4-turbo",
baseModel: "gpt-4-turbo",
accuracy: 0.41721854304635763,
totalQuestions: 151,
correctAnswers: 63,
license: "API Service",
submitType: "openai",
submittedTime: "2025-05-21T16:45:10Z",
params: 0,
precision: "float16",
status: "FINISHED"
},
{
model: "microsoft/phi-3-medium",
baseModel: "phi-3-medium",
accuracy: 0.21854304635761590,
totalQuestions: 151,
correctAnswers: 33,
license: "MIT",
submitType: "azure",
submittedTime: "2025-05-21T14:22:45Z",
params: 14000000000,
precision: "float16",
status: "FINISHED"
}
];
const loadData = async () => {
await new Promise(resolve => setTimeout(resolve, 1000));
return mockData;
};
const refreshData = async () => {
setRefreshing(true);
try {
const newData = await loadData();
const shuffledData = [...newData].sort(() => Math.random() - 0.5).slice(0, Math.floor(Math.random() * 3) + 6);
setData(shuffledData);
setLastUpdated(new Date());
} catch (error) {
console.error('Error refreshing data:', error);
} finally {
setRefreshing(false);
}
};
useEffect(() => {
const initializeData = async () => {
const initialData = await loadData();
setData(initialData);
setLastUpdated(new Date());
setLoading(false);
};
initializeData();
}, []);
const filteredAndSortedData = useMemo(() => {
let filtered = data.filter(item => {
const matchesSearch = item.model.toLowerCase().includes(searchTerm.toLowerCase()) ||
item.baseModel.toLowerCase().includes(searchTerm.toLowerCase());
const matchesFilter = filterLicense === 'all' || item.license === filterLicense;
return matchesSearch && matchesFilter;
});
return filtered.sort((a, b) => {
let aValue = a[sortBy];
let bValue = b[sortBy];
if (sortBy === 'submittedTime') {
aValue = new Date(aValue);
bValue = new Date(bValue);
}
if (sortOrder === 'desc') {
return bValue > aValue ? 1 : -1;
} else {
return aValue > bValue ? 1 : -1;
}
});
}, [data, searchTerm, filterLicense, sortBy, sortOrder]);
const getRankIcon = (index) => {
switch(index) {
case 0: return React.createElement('span', { style: { fontSize: '24px' } }, '🏆');
case 1: return React.createElement('span', { style: { fontSize: '24px' } }, '🥈');
case 2: return React.createElement('span', { style: { fontSize: '24px' } }, '🥉');
default: return React.createElement('span', {
style: { fontSize: '20px', fontWeight: 'bold', color: '#9ca3af' }
}, `#${index + 1}`);
}
};
const formatAccuracy = (accuracy) => {
return `${(accuracy * 100).toFixed(2)}%`;
};
const formatParams = (params) => {
if (params === 0) return 'API';
if (params >= 1e9) return `${(params / 1e9).toFixed(1)}B`;
if (params >= 1e6) return `${(params / 1e6).toFixed(1)}M`;
return params.toLocaleString();
};
const formatDate = (dateString) => {
return new Date(dateString).toLocaleDateString('en-US', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
};
const getSortIcon = (column) => {
if (sortBy !== column) {
return React.createElement('span', { style: { color: '#9ca3af' } }, '↕️');
}
return sortOrder === 'desc' ?
React.createElement('span', { style: { color: '#3b82f6' } }, '⬇️') :
React.createElement('span', { style: { color: '#3b82f6' } }, '⬆️');
};
const styles = {
container: {
minHeight: '100vh',
background: 'linear-gradient(135deg, #0f172a 0%, #1e3a8a 50%, #3730a3 100%)',
padding: '32px 16px'
},
innerContainer: {
maxWidth: '1200px',
margin: '0 auto'
},
header: {
textAlign: 'center',
marginBottom: '32px'
},
title: {
fontSize: '48px',
fontWeight: 'bold',
color: 'white',
marginBottom: '16px',
background: 'linear-gradient(to right, #60a5fa, #a78bfa)',
WebkitBackgroundClip: 'text',
backgroundClip: 'text',
color: 'transparent'
},
subtitle: {
fontSize: '20px',
color: '#d1d5db',
marginBottom: '24px'
},
statsContainer: {
display: 'flex',
justifyContent: 'center',
gap: '32px',
textAlign: 'center',
flexWrap: 'wrap'
},
statCard: {
background: 'rgba(255, 255, 255, 0.1)',
backdropFilter: 'blur(10px)',
border: '1px solid rgba(255, 255, 255, 0.2)',
borderRadius: '12px',
padding: '16px'
},
statNumber: {
fontSize: '24px',
fontWeight: 'bold',
color: 'white'
},
statLabel: {
fontSize: '14px',
color: '#d1d5db'
},
controlsContainer: {
marginBottom: '24px',
display: 'flex',
flexWrap: 'wrap',
gap: '16px',
alignItems: 'center',
justifyContent: 'space-between'
},
inputGroup: {
display: 'flex',
flexWrap: 'wrap',
gap: '16px',
alignItems: 'center'
},
inputContainer: {
position: 'relative'
},
inputIcon: {
position: 'absolute',
left: '12px',
top: '50%',
transform: 'translateY(-50%)',
color: '#9ca3af'
},
input: {
background: 'rgba(255, 255, 255, 0.1)',
backdropFilter: 'blur(10px)',
border: '1px solid rgba(255, 255, 255, 0.2)',
borderRadius: '8px',
color: 'white',
padding: '8px 12px 8px 40px',
outline: 'none',
fontSize: '14px'
},
select: {
background: 'rgba(255, 255, 255, 0.1)',
backdropFilter: 'blur(10px)',
border: '1px solid rgba(255, 255, 255, 0.2)',
borderRadius: '8px',
color: 'white',
padding: '8px 32px 8px 40px',
outline: 'none',
fontSize: '14px'
},
updateButton: {
background: '#059669',
color: 'white',
border: 'none',
borderRadius: '8px',
padding: '8px 16px',
cursor: 'pointer',
display: 'flex',
alignItems: 'center',
gap: '8px',
fontSize: '14px'
},
tableCard: {
background: 'rgba(255, 255, 255, 0.1)',
backdropFilter: 'blur(10px)',
border: '1px solid rgba(255, 255, 255, 0.2)',
borderRadius: '12px',
overflow: 'hidden'
},
tableContainer: {
overflowX: 'auto'
},
scrollContainer: {
maxHeight: '384px',
overflowY: 'auto'
},
table: {
width: '100%',
borderCollapse: 'collapse'
},
tableHeader: {
position: 'sticky',
top: 0,
background: 'rgba(255, 255, 255, 0.1)',
backdropFilter: 'blur(10px)',
borderBottom: '1px solid rgba(255, 255, 255, 0.1)'
},
th: {
padding: '16px 24px',
textAlign: 'left',
color: 'white',
fontWeight: '600'
},
thClickable: {
padding: '16px 24px',
textAlign: 'left',
color: 'white',
fontWeight: '600',
cursor: 'pointer'
},
tr: {
borderBottom: '1px solid rgba(255, 255, 255, 0.05)'
},
td: {
padding: '16px 24px'
},
progressBar: {
width: '100%',
background: '#374151',
borderRadius: '4px',
height: '8px'
},
progressFill: {
background: 'linear-gradient(to right, #3b82f6, #8b5cf6)',
height: '8px',
borderRadius: '4px',
transition: 'width 0.5s ease'
},
badge: {
padding: '4px 8px',
borderRadius: '12px',
fontSize: '12px',
fontWeight: '500'
},
badgeBlue: {
background: 'rgba(59, 130, 246, 0.2)',
color: '#93c5fd'
},
badgeGreen: {
background: 'rgba(34, 197, 94, 0.2)',
color: '#86efac'
},
badgePurple: {
background: 'rgba(147, 51, 234, 0.2)',
color: '#c4b5fd'
},
infoSection: {
marginTop: '32px',
display: 'flex',
flexDirection: 'column',
gap: '24px'
},
infoCard: {
background: 'rgba(255, 255, 255, 0.1)',
backdropFilter: 'blur(10px)',
border: '1px solid rgba(255, 255, 255, 0.2)',
borderRadius: '12px',
padding: '24px'
},
academicCard: {
background: 'rgba(255, 255, 255, 0.1)',
backdropFilter: 'blur(10px)',
border: '1px solid rgba(255, 255, 255, 0.2)',
borderRadius: '12px',
padding: '16px',
textAlign: 'center'
},
loadingContainer: {
minHeight: '100vh',
background: 'linear-gradient(135deg, #0f172a 0%, #1e3a8a 50%, #3730a3 100%)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
},
spinner: {
width: '64px',
height: '64px',
border: '2px solid transparent',
borderBottom: '2px solid white',
borderRadius: '50%',
animation: 'spin 1s linear infinite',
margin: '0 auto 16px'
}
};
if (loading) {
return React.createElement('div', { style: styles.loadingContainer },
React.createElement('div', { style: { textAlign: 'center' } },
React.createElement('div', { style: styles.spinner }),
React.createElement('p', { style: { color: 'white', fontSize: '20px' } }, 'Loading leaderboard...')
)
);
}
return React.createElement('div', null,
React.createElement('style', null, `
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.rotate {
animation: spin 1s linear infinite;
}
.hover-row:hover {
background: rgba(255, 255, 255, 0.05);
}
input::placeholder {
color: #9ca3af;
}
select option {
background: #1f2937;
color: white;
}
`),
React.createElement('div', { style: styles.container },
React.createElement('div', { style: styles.innerContainer },
React.createElement('div', { style: styles.header },
React.createElement('h1', { style: styles.title }, '🏆 Urology AI Leaderboard'),
React.createElement('p', { style: styles.subtitle }, 'Evaluating Natural Language Models on Urology Knowledge Assessment'),
React.createElement('div', { style: styles.statsContainer },
React.createElement('div', { style: styles.statCard },
React.createElement('div', { style: styles.statNumber }, data.length),
React.createElement('div', { style: styles.statLabel }, 'Models')
),
React.createElement('div', { style: styles.statCard },
React.createElement('div', { style: styles.statNumber }, '151'),
React.createElement('div', { style: styles.statLabel }, 'Questions')
),
React.createElement('div', { style: styles.statCard },
React.createElement('div', { style: styles.statNumber }, 'SAS Urology'),
React.createElement('div', { style: styles.statLabel }, 'Specialty')
)
)
),
React.createElement('div', { style: styles.controlsContainer },
React.createElement('div', { style: styles.inputGroup },
React.createElement('div', { style: styles.inputContainer },
React.createElement('span', { style: styles.inputIcon }, '🔍'),
React.createElement('input', {
type: 'text',
placeholder: 'Search model...',
value: searchTerm,
onChange: (e) => setSearchTerm(e.target.value),
style: styles.input
})
),
React.createElement('div', { style: styles.inputContainer },
React.createElement('span', { style: styles.inputIcon }, '📋'),
React.createElement('select', {
value: filterLicense,
onChange: (e) => setFilterLicense(e.target.value),
style: styles.select
},
React.createElement('option', { value: 'all' }, 'All licenses'),
React.createElement('option', { value: 'API Service' }, 'API Service'),
React.createElement('option', { value: 'Apache 2.0' }, 'Apache 2.0'),
React.createElement('option', { value: 'MIT' }, 'MIT')
)
)
),
React.createElement('button', {
onClick: refreshData,
disabled: refreshing,
style: { ...styles.updateButton, opacity: refreshing ? 0.5 : 1 }
},
React.createElement('span', { className: refreshing ? 'rotate' : '' }, '🔄'),
React.createElement('span', null, refreshing ? 'Updating...' : 'Update')
)
),
React.createElement('div', { style: styles.tableCard },
React.createElement('div', { style: styles.tableContainer },
React.createElement('div', { style: styles.scrollContainer },
React.createElement('table', { style: styles.table },
React.createElement('thead', { style: styles.tableHeader },
React.createElement('tr', null,
React.createElement('th', { style: styles.th }, 'Rank'),
React.createElement('th', { style: styles.th }, 'Model'),
React.createElement('th', {
style: styles.thClickable,
onClick: () => {
if (sortBy === 'accuracy') {
setSortOrder(sortOrder === 'desc' ? 'asc' : 'desc');
} else {
setSortBy('accuracy');
setSortOrder('desc');
}
}
},
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '4px' } },
React.createElement('span', null, '🎯'),
React.createElement('span', null, 'Accuracy'),
getSortIcon('accuracy')
)
),
React.createElement('th', { style: styles.th }, 'Answers'),
React.createElement('th', { style: styles.th }, 'Parameters'),
React.createElement('th', { style: styles.th }, 'License'),
React.createElement('th', {
style: styles.thClickable,
onClick: () => {
if (sortBy === 'submittedTime') {
setSortOrder(sortOrder === 'desc' ? 'asc' : 'desc');
} else {
setSortBy('submittedTime');
setSortOrder('desc');
}
}
},
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '4px' } },
React.createElement('span', null, '🕒'),
React.createElement('span', null, 'Date'),
getSortIcon('submittedTime')
)
)
)
),
React.createElement('tbody', null,
filteredAndSortedData.map((item, index) =>
React.createElement('tr', {
key: item.model,
style: styles.tr,
className: 'hover-row'
},
React.createElement('td', { style: styles.td }, getRankIcon(index)),
React.createElement('td', { style: styles.td },
React.createElement('div', { style: { display: 'flex', flexDirection: 'column' } },
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
React.createElement('span', { style: { color: 'white', fontWeight: '500' } }, item.model.split('/').pop()),
React.createElement('span', { style: { color: '#9ca3af', cursor: 'pointer' } }, '🔗')
),
React.createElement('span', { style: { fontSize: '14px', color: '#9ca3af' } }, item.model.split('/')[0])
)
),
React.createElement('td', { style: styles.td },
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '12px' } },
React.createElement('div', { style: { flex: 1 } },
React.createElement('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '4px' } },
React.createElement('span', { style: { color: 'white', fontWeight: '600' } }, formatAccuracy(item.accuracy))
),
React.createElement('div', { style: styles.progressBar },
React.createElement('div', {
style: { ...styles.progressFill, width: `${item.accuracy * 100}%` }
})
)
)
)
),
React.createElement('td', { style: styles.td },
React.createElement('div', { style: { textAlign: 'center' } },
React.createElement('div', { style: { color: 'white', fontWeight: '600' } }, `${item.correctAnswers}/${item.totalQuestions}`),
React.createElement('div', { style: { fontSize: '14px', color: '#9ca3af' } }, 'correct')
)
),
React.createElement('td', { style: styles.td },
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: '8px' } },
React.createElement('span', null, '⚡'),
React.createElement('span', { style: { color: 'white' } }, formatParams(item.params))
)
),
React.createElement('td', { style: styles.td },
React.createElement('span', {
style: {
...styles.badge,
...(item.license === 'API Service' ? styles.badgeBlue :
item.license === 'Apache 2.0' ? styles.badgeGreen : styles.badgePurple)
}
}, item.license)
),
React.createElement('td', { style: styles.td },
React.createElement('div', { style: { fontSize: '14px', color: '#d1d5db' } }, formatDate(item.submittedTime))
)
)
)
)
)
)
)
),
React.createElement('div', { style: styles.infoSection },
React.createElement('div', { style: styles.infoCard },
React.createElement('h3', { style: { fontSize: '20px', fontWeight: '600', color: 'white', marginBottom: '12px' } }, '📊 About This Evaluation'),
React.createElement('p', { style: { color: '#d1d5db', marginBottom: '12px' } }, 'This leaderboard evaluates natural language models on their ability to answer urology questions. Models must respond to multiple-choice questions about urological knowledge, demonstrating their understanding and mastery of this medical specialty.'),
React.createElement('p', { style: { color: '#d1d5db', marginBottom: '16px' } }, 'Questions are from the SAS (Servicio Andaluz de Salud) for the ', React.createElement('strong', null, 'Convocatoria Concurso Oposición'), ' - specialized medical examination for urology residents.'),
React.createElement('div', { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: '8px', color: '#d1d5db' } },
React.createElement('span', null, 'Dataset: ', React.createElement('a', {
href: 'https://huggingface.co/datasets/SASLeaderboard/results',
style: { color: '#60a5fa', textDecoration: 'none' },
target: '_blank',
rel: 'noopener noreferrer'
}, 'SASLeaderboard/results')),
lastUpdated && React.createElement('span', { style: { fontSize: '14px' } }, `Last updated: ${lastUpdated.toLocaleString('en-US')}`)
)
),
React.createElement('div', { style: styles.academicCard },
React.createElement('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '20px', flexWrap: 'wrap' } },
React.createElement('a', {
href: 'https://iesrafaelalberti.es/',
target: '_blank',
rel: 'noopener noreferrer',
style: { textDecoration: 'none', flexShrink: 0 }
},
React.createElement('img', {
src: 'https://avatars.githubusercontent.com/u/79144080?s=200&v=4',
alt: 'IES Rafael Alberti Logo',
style: {
width: '80px',
height: '80px',
cursor: 'pointer',
background: 'white',
borderRadius: '8px',
padding: '4px'
}
})
),
React.createElement('div', { style: { textAlign: 'center', flex: 1, minWidth: '200px' } },
React.createElement('h4', { style: { fontSize: '18px', fontWeight: '600', color: 'white', marginBottom: '16px', margin: '0 0 16px 0' } }, '🎓 Academic Project'),
React.createElement('div', { style: { display: 'flex', flexDirection: 'column', gap: '8px' } },
React.createElement('p', { style: { color: '#d1d5db', fontSize: '14px', margin: 0 } },
'Final project for ',
React.createElement('a', {
href: 'https://iesrafaelalberti.es/',
target: '_blank',
rel: 'noopener noreferrer',
style: { color: '#60a5fa', textDecoration: 'none', fontWeight: '600' }
}, 'IES Rafael Alberti')
),
React.createElement('p', { style: { color: '#d1d5db', fontSize: '14px', margin: 0 } },
'Course: ',
React.createElement('a', {
href: 'https://iesrafaelalberti.es/curso-especializacion-inteligencia-artificial-y-big-datatarde/',
target: '_blank',
rel: 'noopener noreferrer',
style: { color: '#60a5fa', textDecoration: 'none', fontWeight: '600' }
}, 'Artificial Intelligence and Big Data')
),
React.createElement('p', { style: { color: '#d1d5db', fontSize: '14px', margin: 0 } },
'Subject: Artificial Intelligence Models'
)
)
),
React.createElement('a', {
href: 'https://iesrafaelalberti.es/curso-especializacion-inteligencia-artificial-y-big-datatarde/',
target: '_blank',
rel: 'noopener noreferrer',
style: { textDecoration: 'none', flexShrink: 0 }
},
React.createElement('img', {
src: 'https://iesrafaelalberti.es/wp-content/uploads/2025/01/IA-Big-Data-cuadrado.png',
alt: 'AI and Big Data Course Logo',
style: {
width: '80px',
height: '80px',
cursor: 'pointer',
background: 'white',
borderRadius: '8px',
padding: '4px'
}
})
)
)
)
)
)
)
);
};
export default UrologyLeaderboard;