| 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; |