| | <!doctype html> |
| | <html> |
| |
|
| | <head> |
| | <meta charset="UTF-8"> |
| | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| | <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> |
| | <script src="https://cdn.tailwindcss.com?plugins=forms,typography,aspect-ratio,line-clamp"></script> |
| | <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"> |
| | <link href="https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.2.1/flowbite.min.css" rel="stylesheet" /> |
| | <script> |
| | function fetchAndDisplaySubmissionInfo() { |
| | const articleLoadingSpinner = document.getElementById('articleLoadingSpinner'); |
| | articleLoadingSpinner.classList.remove('hidden'); |
| | fetch('/submission_info') |
| | .then(response => { |
| | if (!response.ok) { |
| | throw new Error('Network response was not ok'); |
| | } |
| | return response.json(); |
| | }) |
| | .then(data => { |
| | |
| | const contentDiv = document.getElementById('content'); |
| | contentDiv.innerHTML = marked.parse(data.response); |
| | addTargetBlankToLinks(); |
| | articleLoadingSpinner.classList.add('hidden'); |
| | }) |
| | .catch(error => { |
| | console.error('There has been a problem with your fetch operation:', error); |
| | articleLoadingSpinner.classList.add('hidden'); |
| | }); |
| | } |
| | |
| | function fetchAndDisplaySubmissions() { |
| | const apiEndpoint = '/my_submissions'; |
| | const articleLoadingSpinner = document.getElementById('articleLoadingSpinner'); |
| | articleLoadingSpinner.classList.remove('hidden'); |
| | |
| | const requestOptions = { |
| | method: 'POST', |
| | headers: { |
| | 'Content-Type': 'application/json', |
| | } |
| | }; |
| | |
| | fetch(apiEndpoint, requestOptions) |
| | .then(response => { |
| | if (!response.ok) { |
| | throw new Error('Network response was not ok'); |
| | } |
| | return response.json(); |
| | }) |
| | .then(data => { |
| | const contentDiv = document.getElementById('content'); |
| | const teamNameDiv = `<h2>${data.response.team_name}</h2>` |
| | |
| | |
| | if (data.response.submissions && data.response.submissions.length > 0 && data.response.error.length == 0) { |
| | |
| | let tableHTML = teamNameDiv; |
| | tableHTML += '<table border="1"><tr><th width: 17%;>Datetime</th><th style="width: 40%;">Submission ID</th><th style="width: 20%;">Score</th><th style="width: 8%;">Status</th><th style="width: 15%;">Error</th></tr>'; |
| | |
| | |
| | data.response.submissions.forEach(submission => { |
| | logFileLink = submission.log_file_url === "" ? "" : `<a href="${submission.log_file_url}" target="_blank">log_file.txt</a>`; |
| | tableHTML += `<tr> |
| | <td>${submission.datetime}</td> |
| | <td>${submission.submission_id}</td> |
| | <td>${submission.score}</td> |
| | <td>${submission.status}</td> |
| | <td>${submission.error_message}<br> ${logFileLink}</td> |
| | </tr>`; |
| | }); |
| | |
| | |
| | tableHTML += '</table>'; |
| | |
| | contentDiv.innerHTML = marked.parse(data.response.submission_text) + tableHTML; |
| | } else { |
| | |
| | contentDiv.innerHTML = teamNameDiv + marked.parse(data.response.submission_text) + marked.parse(data.response.error); |
| | } |
| | document.getElementById('updateTeamNameButton').addEventListener('click', function () { |
| | updateTeamName(); |
| | }); |
| | articleLoadingSpinner.classList.add('hidden'); |
| | }) |
| | .catch(error => { |
| | console.error('There was a problem with the fetch operation:', error); |
| | articleLoadingSpinner.classList.add('hidden'); |
| | }); |
| | } |
| | |
| | function showSubmissionModal() { |
| | const modal = document.getElementById('submission-modal'); |
| | modal.classList.add('flex'); |
| | modal.classList.remove('hidden'); |
| | } |
| | |
| | document.addEventListener('DOMContentLoaded', function () { |
| | function hideSubmissionModal() { |
| | const modal = document.getElementById('submission-modal'); |
| | modal.classList.remove('flex'); |
| | modal.classList.add('hidden'); |
| | } |
| | |
| | function addTargetBlankToLinks() { |
| | const content = document.getElementById('content'); |
| | const links = content.getElementsByTagName('a'); |
| | |
| | for (let i = 0; i < links.length; i++) { |
| | if (!links[i].hasAttribute('target')) { |
| | links[i].setAttribute('target', '_blank'); |
| | } |
| | } |
| | } |
| | |
| | function fetchAndDisplayCompetitionInfo() { |
| | const articleLoadingSpinner = document.getElementById('articleLoadingSpinner'); |
| | articleLoadingSpinner.classList.remove('hidden'); |
| | fetch('/competition_info') |
| | .then(response => { |
| | if (!response.ok) { |
| | throw new Error('Network response was not ok'); |
| | } |
| | return response.json(); |
| | }) |
| | .then(data => { |
| | |
| | const contentDiv = document.getElementById('content'); |
| | contentDiv.style.display = 'block'; |
| | contentDiv.innerHTML = marked.parse(data.response); |
| | addTargetBlankToLinks(); |
| | articleLoadingSpinner.classList.add('hidden'); |
| | }) |
| | .catch(error => { |
| | console.error('There has been a problem with your fetch operation:', error); |
| | articleLoadingSpinner.classList.add('hidden'); |
| | }); |
| | } |
| | |
| | function fetchAndDisplayDatasetInfo() { |
| | const articleLoadingSpinner = document.getElementById('articleLoadingSpinner'); |
| | articleLoadingSpinner.classList.remove('hidden'); |
| | fetch('/dataset_info') |
| | .then(response => { |
| | if (!response.ok) { |
| | throw new Error('Network response was not ok'); |
| | } |
| | return response.json(); |
| | }) |
| | .then(data => { |
| | |
| | const contentDiv = document.getElementById('content'); |
| | contentDiv.innerHTML = marked.parse(data.response); |
| | addTargetBlankToLinks(); |
| | articleLoadingSpinner.classList.add('hidden'); |
| | }) |
| | .catch(error => { |
| | console.error('There has been a problem with your fetch operation:', error); |
| | articleLoadingSpinner.classList.add('hidden'); |
| | }); |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | function fetchAndDisplayTeamInfo() { |
| | const apiEndpoint = '/team_info'; |
| | const articleLoadingSpinner = document.getElementById('articleLoadingSpinner'); |
| | articleLoadingSpinner.classList.remove('hidden'); |
| | |
| | const requestOptions = { |
| | method: 'POST', |
| | headers: { |
| | 'Content-Type': 'application/json', |
| | } |
| | }; |
| | fetch(apiEndpoint, requestOptions) |
| | .then(response => { |
| | if (!response.ok) { |
| | throw new Error('Network response was not ok'); |
| | } |
| | return response.json(); |
| | }) |
| | .then(data => { |
| | |
| | const contentDiv = document.getElementById('content'); |
| | if (data.team_exists) { |
| | contentHTML = "<h2>Team</h2>"; |
| | contentHTML += "<p>" + data.team_name + "</p>"; |
| | contentDiv.innerHTML = marked.parse(contentHTML); |
| | } else { |
| | contentDiv.innerHTML = marked.parse(data.response); |
| | } |
| | contentDiv.innerHTML = marked.parse(data.response); |
| | articleLoadingSpinner.classList.add('hidden'); |
| | }) |
| | .catch(error => { |
| | console.error('There has been a problem with your fetch operation:', error); |
| | articleLoadingSpinner.classList.add('hidden'); |
| | }); |
| | } |
| | |
| | function fetchAndDisplayRules() { |
| | const articleLoadingSpinner = document.getElementById('articleLoadingSpinner'); |
| | articleLoadingSpinner.classList.remove('hidden'); |
| | fetch('/rules') |
| | .then(response => { |
| | if (!response.ok) { |
| | throw new Error('Network response was not ok'); |
| | } |
| | return response.json(); |
| | }) |
| | .then(data => { |
| | |
| | const contentDiv = document.getElementById('content'); |
| | contentDiv.innerHTML = marked.parse(data.response); |
| | addTargetBlankToLinks(); |
| | articleLoadingSpinner.classList.add('hidden'); |
| | }) |
| | .catch(error => { |
| | console.error('There has been a problem with your fetch operation:', error); |
| | articleLoadingSpinner.classList.add('hidden'); |
| | }); |
| | } |
| | function fetchAndDisplayLeaderboard() { |
| | const articleLoadingSpinner = document.getElementById('articleLoadingSpinner'); |
| | articleLoadingSpinner.classList.remove('hidden'); |
| | |
| | fetch('/leaderboard', { |
| | method: 'POST', |
| | headers: { |
| | 'Content-Type': 'application/json' |
| | }, |
| | }).then(response => { |
| | if (!response.ok) { |
| | throw new Error('Network response was not ok'); |
| | } |
| | return response.json(); |
| | }).then(data => { |
| | const contentDiv = document.getElementById('content'); |
| | contentDiv.innerHTML = marked.parse(data.response); |
| | articleLoadingSpinner.classList.add('hidden'); |
| | }).catch(error => { |
| | console.error('There has been a problem with your fetch operation:', error); |
| | articleLoadingSpinner.classList.add('hidden'); |
| | }); |
| | } |
| | |
| | const homeLink = document.getElementById('home'); |
| | const datasetLink = document.getElementById('dataset'); |
| | |
| | |
| | const rulesLink = document.getElementById('rules'); |
| | const leaderBoardLink = document.getElementById('leaderboard'); |
| | |
| | leaderBoardLink.addEventListener('click', function (event) { |
| | event.preventDefault(); |
| | fetchAndDisplayLeaderboard(); |
| | }); |
| | |
| | |
| | homeLink.addEventListener('click', function (event) { |
| | event.preventDefault(); |
| | fetchAndDisplayCompetitionInfo(); |
| | }); |
| | |
| | datasetLink.addEventListener('click', function (event) { |
| | event.preventDefault(); |
| | fetchAndDisplayDatasetInfo(); |
| | }); |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | rulesLink.addEventListener('click', function (event) { |
| | event.preventDefault(); |
| | fetchAndDisplayRules(); |
| | }); |
| | |
| | |
| | |
| | fetchAndDisplayCompetitionInfo(); |
| | |
| | document.querySelector('#submission-modal .cancel').addEventListener('click', function () { |
| | hideSubmissionModal(); |
| | }); |
| | }); |
| | |
| | </script> |
| |
|
| | <script> |
| | function makeApiRequest(url, callback) { |
| | var xhr = new XMLHttpRequest(); |
| | xhr.open("GET", url, true); |
| | xhr.onreadystatechange = function () { |
| | if (xhr.readyState === 4 && xhr.status === 200) { |
| | var response = JSON.parse(xhr.responseText); |
| | callback(response.response); |
| | } |
| | }; |
| | xhr.send(); |
| | } |
| | |
| | function checkOAuth() { |
| | var url = "/login_status"; |
| | const submissionInfo = document.getElementById('submission_info'); |
| | const mySubmissions = document.getElementById('my_submissions'); |
| | const newSubmission = document.getElementById('new_submission'); |
| | makeApiRequest(url, function ({is_login, is_admin, is_registered, is_white_team}) { |
| | const registerRemoveStyle = ["pointer-events-none", "text-gray-400", "cursor-not-allowed"]; |
| | const registerNewStyle = ["ext-gray-900", "hover:bg-gray-100"] |
| | if (is_login) { |
| | document.getElementById("loginButton").style.display = "none"; |
| | document.getElementById("logoutButton").style.display = "block"; |
| | } else { |
| | document.getElementById("loginButton").style.display = "block"; |
| | document.getElementById("logoutButton").style.display = "none"; |
| | } |
| | if (is_admin) { |
| | document.getElementById("admin").classList.remove("hidden"); |
| | } |
| | if (is_registered) { |
| | document.getElementById("updateTeamInfo").style.display = "block"; |
| | } |
| | submissionInfo.addEventListener('click', function (event) { |
| | event.preventDefault(); |
| | if (is_registered) { |
| | fetchAndDisplaySubmissionInfo(); |
| | } else { |
| | alert(`You need to register to access the "Submission Information."`) |
| | } |
| | }); |
| | mySubmissions.addEventListener('click', function (event) { |
| | event.preventDefault(); |
| | if (is_white_team) { |
| | fetchAndDisplaySubmissions(); |
| | } else { |
| | alert(`Access to "SUBMIT" will be granted after we manually review your registration. This process usually takes up to 24 hours.`) |
| | } |
| | }); |
| | newSubmission.addEventListener('click', function (event) { |
| | event.preventDefault(); |
| | if (is_white_team) { |
| | showSubmissionModal(); |
| | } else { |
| | alert(`Access to "SUBMIT" will be granted after we manually review your registration. This process usually takes up to 24 hours.`) |
| | } |
| | }); |
| | if (is_login && !is_registered) { |
| | document.getElementById("registerButton").style.display = "block"; |
| | } |
| | }); |
| | } |
| | window.onload = checkOAuth; |
| | </script> |
| | </head> |
| |
|
| | <body class="flex h-screen"> |
| | |
| | <aside id="sidebar-multi-level-sidebar" |
| | class="fixed top-0 left-0 z-40 w-64 h-screen transition-transform -translate-x-full sm:translate-x-0" |
| | aria-label="Sidebar"> |
| | <div class="h-full px-3 py-4 overflow-y-auto"> |
| | <ul class="space-y-2 font-medium"> |
| | <li> |
| | <a href="#" id="home" |
| | class="flex items-center p-2 text-gray-900 rounded-lg hover:bg-gray-100 group"> |
| | <svg class="w-5 h-5 text-gray-500 transition duration-75 group-hover:text-gray-900" |
| | viewBox="0 0 22 21" xmlns="http://www.w3.org/2000/svg" fill="currentColor"> |
| | <path d="M1,10 L11,1 L21,10 L21,20 L1,20 Z" /> |
| | <path d="M6,20 L6,14 L16,14 L16,20" /> |
| | </svg> |
| |
|
| | <span class="ms-3">Home</span> |
| | </a> |
| | </li> |
| | <li> |
| | <a href="#" id="dataset" |
| | class="flex items-center p-2 text-gray-900 rounded-lg hover:bg-gray-100 group"> |
| | <svg class="flex-shrink-0 w-5 h-5 text-gray-500 transition duration-75 group-hover:text-gray-900" |
| | aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" |
| | viewBox="0 0 18 18"> |
| | <path |
| | d="M6.143 0H1.857A1.857 1.857 0 0 0 0 1.857v4.286C0 7.169.831 8 1.857 8h4.286A1.857 1.857 0 0 0 8 6.143V1.857A1.857 1.857 0 0 0 6.143 0Zm10 0h-4.286A1.857 1.857 0 0 0 10 1.857v4.286C10 7.169 10.831 8 11.857 8h4.286A1.857 1.857 0 0 0 18 6.143V1.857A1.857 1.857 0 0 0 16.143 0Zm-10 10H1.857A1.857 1.857 0 0 0 0 11.857v4.286C0 17.169.831 18 1.857 18h4.286A1.857 1.857 0 0 0 8 16.143v-4.286A1.857 1.857 0 0 0 6.143 10Zm10 0h-4.286A1.857 1.857 0 0 0 10 11.857v4.286c0 1.026.831 1.857 1.857 1.857h4.286A1.857 1.857 0 0 0 18 16.143v-4.286A1.857 1.857 0 0 0 16.143 10Z" /> |
| | </svg> |
| | <span class="flex-1 ms-3 whitespace-nowrap">Dataset</span> |
| | </a> |
| | </li> |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | <span id="rules"></span> |
| | <li> |
| | <a href="#" id="leaderboard" |
| | class="flex items-center p-2 text-gray-900 rounded-lg hover:bg-gray-100 group"> |
| | <svg class="flex-shrink-0 w-5 h-5 text-gray-500 transition duration-75 group-hover:text-gray-900" |
| | aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" |
| | viewBox="0 0 18 21"> |
| | <path d="M2,4 L20,4 L20,16 L2,16 Z" /> |
| | <path d="M6,17 L16,17 L16,18 L6,18 Z" /> |
| | </svg> |
| | <span class="flex-1 ms-3 text-left rtl:text-right whitespace-nowrap">Leaderboard</span> |
| | </a> |
| | </li> |
| | <li> |
| | <button type="button" |
| | class="flex items-center w-full p-2 text-base text-gray-900 transition duration-75 rounded-lg group hover:bg-gray-100" |
| | aria-controls="submissions-dropdown" data-collapse-toggle="submissions-dropdown"> |
| | <svg class="flex-shrink-0 w-5 h-5 text-gray-500 transition duration-75 group-hover:text-gray-900" |
| | aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" |
| | viewBox="0 0 20 20"> |
| | <path d="M5 5V.13a2.96 2.96 0 0 0-1.293.749L.879 3.707A2.96 2.96 0 0 0 .13 5H5Z" /> |
| | <path |
| | d="M6.737 11.061a2.961 2.961 0 0 1 .81-1.515l6.117-6.116A4.839 4.839 0 0 1 16 2.141V2a1.97 1.97 0 0 0-1.933-2H7v5a2 2 0 0 1-2 2H0v11a1.969 1.969 0 0 0 1.933 2h12.134A1.97 1.97 0 0 0 16 18v-3.093l-1.546 1.546c-.413.413-.94.695-1.513.81l-3.4.679a2.947 2.947 0 0 1-1.85-.227 2.96 2.96 0 0 1-1.635-3.257l.681-3.397Z" /> |
| | <path |
| | d="M8.961 16a.93.93 0 0 0 .189-.019l3.4-.679a.961.961 0 0 0 .49-.263l6.118-6.117a2.884 2.884 0 0 0-4.079-4.078l-6.117 6.117a.96.96 0 0 0-.263.491l-.679 3.4A.961.961 0 0 0 8.961 16Zm7.477-9.8a.958.958 0 0 1 .68-.281.961.961 0 0 1 .682 1.644l-.315.315-1.36-1.36.313-.318Zm-5.911 5.911 4.236-4.236 1.359 1.359-4.236 4.237-1.7.339.341-1.699Z" /> |
| | </svg> |
| | <span class="flex-1 ms-3 text-left rtl:text-right whitespace-nowrap">Submissions</span> |
| | <svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" |
| | viewBox="0 0 10 6"> |
| | <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" |
| | d="m1 1 4 4 4-4" /> |
| | </svg> |
| | </button> |
| | <ul id="submissions-dropdown" class="py-2 space-y-2"> |
| | <li> |
| | <a href="#" id="submission_info" |
| | class="flex items-center w-full p-2 transition duration-75 rounded-lg pl-11 group ext-gray-900 hover:bg-gray-100">Submission |
| | information</a> |
| | </li> |
| | <li> |
| | <a href="#" id="my_submissions" |
| | class="flex items-center w-full p-2 transition duration-75 rounded-lg pl-11 group ext-gray-900 hover:bg-gray-100">My |
| | submissions</a> |
| | </li> |
| | <li> |
| | <a href="#" id="new_submission" |
| | class="flex items-center w-full p-2 transition duration-75 rounded-lg pl-11 group ext-gray-900 hover:bg-gray-100">New |
| | submission</a> |
| | </li> |
| | </ul> |
| | </li> |
| | <li> |
| | <a href="#" id="admin" |
| | class="flex items-center p-2 text-gray-900 rounded-lg hover:bg-gray-100 group hidden"> |
| | <svg class="flex-shrink-0 w-5 h-5 text-gray-500 transition duration-75 group-hover:text-gray-900" |
| | aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" |
| | viewBox="0 0 24 24"> |
| | <path |
| | d="M12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5zm7.43-3.5c.04-.33.07-.66.07-1s-.03-.67-.07-1l2.11-1.65c.19-.15.23-.42.12-.63l-2-3.46c-.11-.21-.35-.3-.57-.24l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.57 2.18 14.3 2 14 2h-4c-.3 0-.57.18-.64.45L8.98 5.1c-.61.25-1.17.58-1.69.98l-2.49-1c-.22-.06-.46.03-.57.24l-2 3.46c-.11.21-.07.48.12.63l2.11 1.65c-.04.33-.07.66-.07 1s.03.67.07 1L2.46 14.1c-.19.15-.23.42-.12.63l2 3.46c.11.21.35.3.57.24l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.07.27.34.45.64.45h4c.3 0 .57-.18.64-.45l.38-2.65c.61-.25 1.17-.58 1.69-.98l2.49 1c.22.06.46-.03.57-.24l2-3.46c.11-.21.07-.48-.12-.63l-2.11-1.65zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5z" /> |
| | </svg> |
| | <span class="flex-1 ms-3 whitespace-nowrap">Admin</span> |
| | </a> |
| | </li> |
| | <li id="registerButton" style="display: none;"> |
| | <a href="#" |
| | class="flex justify-center items-center bg-blue-400 hover:bg-blue-600 text-white text-center font-bold py-2 px-4 rounded transition duration-200 ease-in-out"> |
| | Register |
| | </a> |
| | </li> |
| | <li id="loginButton" style="display: none;"> |
| | <a href="/login/huggingface" |
| | class="flex justify-center items-center bg-blue-400 hover:bg-blue-600 text-white text-center font-bold py-2 px-4 rounded transition duration-200 ease-in-out"> |
| | Login with Hugging Face |
| | </a> |
| | </li> |
| | <li id="updateTeamInfo" style="display: none;"> |
| | <a href="/update_team_info_page" |
| | class="flex justify-center items-center bg-green-600 hover:bg-green-800 text-white text-center font-bold py-2 px-4 rounded transition duration-200 ease-in-out"> |
| | Update Team Info |
| | </a> |
| | </li> |
| | <li id="logoutButton" style="display: none;"> |
| | <a href="/logout" |
| | class="flex justify-center items-center bg-red-400 hover:bg-red-600 text-white text-center font-bold py-2 px-4 rounded transition duration-200 ease-in-out"> |
| | Logout |
| | </a> |
| | </li> |
| | </ul> |
| |
|
| | <footer> |
| | <div class="w-full mx-auto max-w-screen-xl p-4 md:flex md:items-center md:justify-between"> |
| | <span class="text-sm text-gray-500 sm:text-center">Powered by <a |
| | href="https://github.com/huggingface/competitions" target="_blank" |
| | class="hover:underline">Hugging Face |
| | Competitions</a> |
| | </span> |
| | </div> |
| | <div class="text-center"> |
| | <span class="text-xs text-gray-400">{{version}} |
| | </span> |
| | </div> |
| | </footer> |
| | </div> |
| | </aside> |
| | <div class="p-1 sm:ml-64 overflow-x-hidden"> |
| | <img src={{logo}} alt="Competition logo"> |
| | <hr class="mt-3 mb-2"> |
| | <div id="articleLoadingSpinner" role="status" |
| | class="hidden absolute -translate-x-1/2 -translate-y-1/2 top-2/4 left-1/2"> |
| | <div class="animate-spin rounded-full h-32 w-32 border-b-2 border-gray-900"></div> |
| | <span class="sr-only">Loading...</span> |
| | </div> |
| | <article class="prose w-full mx-auto max-w-screen-xl p-4 md:flex md:items-center md:justify-between" |
| | id="content"> |
| | </article> |
| | </div> |
| | <div id="submission-modal" tabindex="-1" |
| | class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full"> |
| | <div id="loadingSpinner" role="status" |
| | class="hidden absolute -translate-x-1/2 -translate-y-1/2 top-2/4 left-1/2"> |
| | <div class="animate-spin rounded-full h-32 w-32 border-b-2 border-gray-900"></div> |
| | <span class="sr-only">Loading...</span> |
| | </div> |
| | <div class="form-container max-w-5xl mx-auto mt-3 p-6 shadow-2xl bg-white"> |
| | <p class="text-lg font-medium text-gray-900">New Submission</p> |
| | <form action="#" method="post" class="gap-2" enctype="multipart/form-data"> |
| | {% if competition_type == 'generic' %} |
| | <div class="form-group"> |
| | <label class="block mb-2 text-sm font-medium text-gray-900" for="submission_file">Upload |
| | file</label> |
| | <input |
| | class="block w-full text-sm text-gray-900 border border-gray-300 rounded-lg cursor-pointer bg-gray-50 focus:outline-none " |
| | id="submission_file" type="file" name="submission_file"> |
| | </div> |
| | {% endif %} |
| | {% if competition_type == 'script' %} |
| | <div class="form-group"> |
| | <label for="hub_model" class="text-sm font-medium text-gray-700">Hub Model |
| | </label> |
| | <input type="text" name="hub_model" id="hub_model" |
| | class="mt-1 block w-full border border-gray-300 px-3 py-1.5 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500" |
| | placeholder="username/my-model"> |
| | </div> |
| | {% endif %} |
| | <div class="form-group mt-2"> |
| | <label for="submission_comment" class="text-sm font-medium text-gray-700">Submission description |
| | (optional) |
| | </label> |
| | <textarea id="submission_comment" name="submission_comment" rows="5" |
| | class="p-2.5 w-full text-sm text-gray-900" placeholder=" "></textarea> |
| | </div> |
| | <div class="form-actions mt-6"> |
| | <button data-modal-hide="submission-modal" type="button" |
| | class="confirm text-white bg-green-600 hover:bg-green-800 focus:ring-4 focus:outline-none focus:ring-green-300font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center me-2"> |
| | Submit |
| | </button> |
| | <button data-modal-hide="submission-modal" type="button" |
| | class="cancel text-white bg-red-600 hover:bg-red-100 focus:ring-4 focus:outline-none focus:ring-red-200 rounded-lg border border-red-200 text-sm font-medium px-5 py-2.5 hover:text-red-900 focus:z-10">Cancel</button> |
| | </div> |
| | </form> |
| | <hr class="mt-3"> |
| | <div id="error-message" style="color: red;"></div> |
| | <div id="success-message" style="color: green;"></div> |
| | </div> |
| | </div> |
| | <div id="admin-modal" tabindex="-1" |
| | class="hidden fixed inset-0 z-40 flex items-center justify-center w-full h-full bg-black bg-opacity-50"> |
| | <div id="adminLoadingSpinner" role="status" |
| | class="hidden fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50"> |
| | <div class="animate-spin rounded-full h-32 w-32 border-b-2 border-gray-900"></div> |
| | <span class="sr-only">Loading...</span> |
| | </div> |
| | <div class="relative w-full max-w-5xl p-4"> |
| | <div class="relative bg-white rounded-lg shadow-2xl"> |
| | <button type="button" |
| | class="absolute top-3 right-3 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 inline-flex justify-center items-center" |
| | data-modal-hide="admin-modal"> |
| | <svg class="w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" |
| | viewBox="0 0 14 14"> |
| | <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" |
| | d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" /> |
| | </svg> |
| | <span class="sr-only">Close</span> |
| | </button> |
| | <div class="p-6 md:p-8 text-center"> |
| | <h3 class="mb-5 text-lg font-medium text-gray-900">Admin</h3> |
| | <div class="tabs"> |
| | <ul class="flex border-b"> |
| | <li class="mr-1"> |
| | <a class="tab bg-white inline-block py-2 px-4 text-blue-500 hover:text-blue-800 font-semibold" |
| | href="#config">Config</a> |
| | </li> |
| | <li class="mr-1"> |
| | <a class="tab bg-white inline-block py-2 px-4 text-blue-500 hover:text-blue-800 font-semibold" |
| | href="#competition-desc">Competition Desc</a> |
| | </li> |
| | <li class="mr-1"> |
| | <a class="tab bg-white inline-block py-2 px-4 text-blue-500 hover:text-blue-800 font-semibold" |
| | href="#dataset-desc">Dataset Desc</a> |
| | </li> |
| | <li class="mr-1"> |
| | <a class="tab bg-white inline-block py-2 px-4 text-blue-500 hover:text-blue-800 font-semibold" |
| | href="#submission-desc">Submission Desc</a> |
| | </li> |
| | <li class="mr-1"> |
| | <a class="tab bg-white inline-block py-2 px-4 text-blue-500 hover:text-blue-800 font-semibold" |
| | href="#rules-desc">Rules</a> |
| | </li> |
| | </ul> |
| | </div> |
| | <div id="tab-contents" |
| | class="text-xs font-normal text-left overflow-y-auto max-h-[calc(100vh-400px)] border-t border-gray-200 pt-4"> |
| | <div id="config"> |
| | <textarea id="config-textarea" class="w-full h-64 p-2 border rounded">Loading..</textarea> |
| | <p class="text-xs text-gray-500">Note: The config should be a valid JSON object. To learn |
| | details about entries, click <a |
| | href="https://huggingface.co/docs/competitions/competition_repo#confjson" |
| | target="_blank">here</a>. |
| | </p> |
| | </div> |
| | <div id="competition-desc" class="hidden"> |
| | <textarea id="competition-desc-textarea" |
| | class="w-full h-64 p-2 border rounded">Loading..</textarea> |
| | </div> |
| | <div id="dataset-desc" class="hidden"> |
| | <textarea id="dataset-desc-textarea" |
| | class="w-full h-64 p-2 border rounded">Loading..</textarea> |
| | </div> |
| | <div id="submission-desc" class="hidden"> |
| | <textarea id="submission-desc-textarea" |
| | class="w-full h-64 p-2 border rounded">Loading..</textarea> |
| | </div> |
| | <div id="rules-desc" class="hidden"> |
| | <textarea id="rules-desc-textarea" |
| | class="w-full h-64 p-2 border rounded">Loading..</textarea> |
| | </div> |
| | </div> |
| | <button id="save-button" class="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-700"> |
| | Save |
| | </button> |
| | </div> |
| | </div> |
| | </div> |
| | </div> |
| | <script src="https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.2.1/flowbite.min.js"></script> |
| | <script> |
| | document.addEventListener("DOMContentLoaded", function () { |
| | const content = document.getElementById('content'); |
| | const links = content.getElementsByTagName('a'); |
| | |
| | for (let i = 0; i < links.length; i++) { |
| | if (!links[i].hasAttribute('target')) { |
| | links[i].setAttribute('target', '_blank'); |
| | } |
| | } |
| | }); |
| | </script> |
| | </body> |
| |
|
| | <script> |
| | document.addEventListener("DOMContentLoaded", function () { |
| | document.querySelectorAll('.tabs a').forEach(tab => { |
| | tab.addEventListener('click', event => { |
| | event.preventDefault(); |
| | document.querySelectorAll('.tabs a').forEach(t => t.classList.remove('active')); |
| | tab.classList.add('active'); |
| | |
| | document.querySelectorAll('#tab-contents > div').forEach(content => content.classList.add('hidden')); |
| | const selectedTab = document.querySelector(tab.getAttribute('href')); |
| | selectedTab.classList.remove('hidden'); |
| | }); |
| | }); |
| | |
| | async function fetchAdminCompInfo() { |
| | const adminLoadingSpinner = document.getElementById('adminLoadingSpinner'); |
| | adminLoadingSpinner.classList.remove('hidden'); |
| | try { |
| | const response = await fetch("/admin/comp_info", { |
| | method: "POST", |
| | headers: { |
| | "Content-Type": "application/json" |
| | } |
| | }); |
| | const data = await response.json(); |
| | if (response.ok) { |
| | populateAdminModal(data.response); |
| | } else { |
| | alert(data.response || "Failed to fetch competition info"); |
| | } |
| | } catch (error) { |
| | console.error("Error fetching admin competition info:", error); |
| | alert("An error occurred while fetching competition info."); |
| | } finally { |
| | adminLoadingSpinner.classList.add('hidden'); |
| | } |
| | } |
| | |
| | function populateAdminModal(data) { |
| | document.getElementById("config-textarea").value = JSON.stringify(data.config, null, 2); |
| | document.getElementById("competition-desc-textarea").value = data.markdowns["competition_desc"] || ""; |
| | document.getElementById("dataset-desc-textarea").value = data.markdowns["dataset_desc"] || ""; |
| | document.getElementById("submission-desc-textarea").value = data.markdowns["submission_desc"] || ""; |
| | document.getElementById("rules-desc-textarea").value = data.markdowns["rules"] || "No rules available."; |
| | } |
| | |
| | document.querySelectorAll(".tab").forEach(tab => { |
| | tab.addEventListener("click", function (event) { |
| | event.preventDefault(); |
| | const targetId = this.getAttribute("href").substring(1); |
| | |
| | document.querySelectorAll("#tab-contents > div").forEach(content => { |
| | content.classList.add("hidden"); |
| | }); |
| | document.getElementById(targetId).classList.remove("hidden"); |
| | |
| | document.querySelectorAll(".tab").forEach(t => { |
| | t.classList.remove("text-blue-800"); |
| | t.classList.add("text-blue-500"); |
| | }); |
| | this.classList.remove("text-blue-500"); |
| | this.classList.add("text-blue-800"); |
| | }); |
| | }); |
| | |
| | document.getElementById("admin").addEventListener("click", function () { |
| | document.getElementById("admin-modal").classList.remove("hidden"); |
| | fetchAdminCompInfo(); |
| | }); |
| | |
| | document.querySelector("[data-modal-hide='admin-modal']").addEventListener("click", function () { |
| | document.getElementById("admin-modal").classList.add("hidden"); |
| | }); |
| | |
| | document.getElementById("save-button").addEventListener("click", async function () { |
| | const adminLoadingSpinner = document.getElementById('adminLoadingSpinner'); |
| | adminLoadingSpinner.classList.remove('hidden'); |
| | |
| | const config = document.getElementById("config-textarea").value; |
| | const competitionDesc = document.getElementById("competition-desc-textarea").value; |
| | const datasetDesc = document.getElementById("dataset-desc-textarea").value; |
| | const submissionDesc = document.getElementById("submission-desc-textarea").value; |
| | const rulesDesc = document.getElementById("rules-desc-textarea").value; |
| | |
| | const data = { |
| | config: JSON.parse(config), |
| | markdowns: { |
| | competition_desc: competitionDesc, |
| | dataset_desc: datasetDesc, |
| | submission_desc: submissionDesc, |
| | rules: rulesDesc |
| | } |
| | }; |
| | |
| | try { |
| | const response = await fetch("/admin/update_comp_info", { |
| | method: "POST", |
| | headers: { |
| | "Content-Type": "application/json" |
| | }, |
| | body: JSON.stringify(data) |
| | }); |
| | const result = await response.json(); |
| | if (response.ok) { |
| | alert(result.response || "Successfully updated competition info"); |
| | } else { |
| | alert(result.response || "Failed to update competition info"); |
| | } |
| | } catch (error) { |
| | console.error("Error updating competition info:", error); |
| | alert("An error occurred while updating competition info."); |
| | } finally { |
| | adminLoadingSpinner.classList.add('hidden'); |
| | } |
| | }); |
| | |
| | }); |
| | </script> |
| |
|
| | <script> |
| | document.addEventListener('DOMContentLoaded', function () { |
| | document.querySelector('.confirm').addEventListener('click', function (event) { |
| | event.preventDefault(); |
| | document.getElementById('error-message').textContent = ''; |
| | document.getElementById('success-message').textContent = ''; |
| | const loadingSpinner = document.getElementById('loadingSpinner'); |
| | loadingSpinner.classList.remove('hidden'); |
| | |
| | var formData = new FormData(); |
| | var competitionType = '{{ competition_type }}'; |
| | |
| | if (competitionType === 'generic') { |
| | var submissionFile = document.getElementById('submission_file').files[0]; |
| | formData.append('submission_file', submissionFile); |
| | formData.append('hub_model', 'None'); |
| | } else if (competitionType === 'script') { |
| | var hubModel = document.getElementById('hub_model').value; |
| | if (!hubModel) { |
| | alert('Hub model is required.'); |
| | return; |
| | } |
| | formData.append('hub_model', hubModel); |
| | } else { |
| | alert('Invalid competition type.'); |
| | return; |
| | } |
| | |
| | var submissionComment = document.getElementById('submission_comment').value; |
| | formData.append('submission_comment', submissionComment); |
| | |
| | fetch('/new_submission', { |
| | method: 'POST', |
| | body: formData |
| | }) |
| | .then(response => response.json()) |
| | .then(data => { |
| | loadingSpinner.classList.add('hidden'); |
| | document.getElementById('success-message').textContent = data.response; |
| | |
| | }) |
| | .catch((error) => { |
| | console.error('Error:', error); |
| | loadingSpinner.classList.add('hidden'); |
| | document.getElementById('error-message').textContent = error; |
| | }); |
| | }); |
| | }); |
| | </script> |
| |
|
| | <script> |
| | function updateSelectedSubmissions() { |
| | const selectedSubmissions = document.querySelectorAll('input[name="selectedSubmissions"]:checked'); |
| | const articleLoadingSpinner = document.getElementById('articleLoadingSpinner'); |
| | articleLoadingSpinner.classList.remove('hidden'); |
| | let selectedSubmissionIds = []; |
| | selectedSubmissions.forEach((submission) => { |
| | selectedSubmissionIds.push(submission.value); |
| | }); |
| | |
| | const updateEndpoint = '/update_selected_submissions'; |
| | const requestOptions = { |
| | method: 'POST', |
| | headers: { |
| | 'Content-Type': 'application/json', |
| | }, |
| | body: JSON.stringify({ |
| | "submission_ids": selectedSubmissionIds.join(',') |
| | }) |
| | }; |
| | |
| | fetch(updateEndpoint, requestOptions) |
| | .then(response => { |
| | if (!response.ok) { |
| | throw new Error('Network response was not ok'); |
| | } |
| | return response.json(); |
| | }) |
| | .then(data => { |
| | if (data.success) { |
| | |
| | console.log('Update successful'); |
| | articleLoadingSpinner.classList.add('hidden'); |
| | } else { |
| | |
| | console.log('Update failed'); |
| | articleLoadingSpinner.classList.add('hidden'); |
| | alert(data.error); |
| | } |
| | |
| | fetchAndDisplaySubmissions(); |
| | }) |
| | .catch(error => { |
| | console.error('There was a problem with the fetch operation for updating:', error); |
| | }); |
| | } |
| | </script> |
| |
|
| | <script> |
| | function updateTeamName() { |
| | const teamName = document.getElementById('team_name').value; |
| | const articleLoadingSpinner = document.getElementById('articleLoadingSpinner'); |
| | articleLoadingSpinner.classList.remove('hidden'); |
| | |
| | const updateEndpoint = '/update_team_name'; |
| | const requestOptions = { |
| | method: 'POST', |
| | headers: { |
| | 'Content-Type': 'application/json', |
| | }, |
| | body: JSON.stringify({ |
| | "new_team_name": teamName |
| | }) |
| | }; |
| | |
| | fetch(updateEndpoint, requestOptions) |
| | .then(response => { |
| | if (!response.ok) { |
| | throw new Error('Network response was not ok'); |
| | } |
| | return response.json(); |
| | }) |
| | .then(data => { |
| | if (data.success) { |
| | |
| | console.log('Update successful'); |
| | articleLoadingSpinner.classList.add('hidden'); |
| | } else { |
| | |
| | console.log('Update failed'); |
| | articleLoadingSpinner.classList.add('hidden'); |
| | alert(data.error); |
| | } |
| | |
| | fetchAndDisplaySubmissions(); |
| | }) |
| | .catch(error => { |
| | console.error('There was a problem with the fetch operation for updating:', error); |
| | }); |
| | } |
| | </script> |
| |
|
| | <script> |
| | function showAdminModal() { |
| | const modal = document.getElementById('admin-modal'); |
| | modal.classList.add('flex'); |
| | modal.classList.remove('hidden'); |
| | } |
| | |
| | function hideAdminModal() { |
| | const modal = document.getElementById('admin-modal'); |
| | modal.classList.remove('flex'); |
| | modal.classList.add('hidden'); |
| | } |
| | |
| | document.querySelector('#admin').addEventListener('click', function () { |
| | showAdminModal(); |
| | }); |
| | |
| | document.querySelector('[data-modal-hide="admin-modal"]').addEventListener('click', function () { |
| | hideAdminModal(); |
| | }); |
| | </script> |
| |
|
| |
|
| | <script> |
| | document.getElementById("registerButton").addEventListener("click", function () { |
| | window.location.href = "/register_page"; |
| | }); |
| | </script> |
| |
|
| | </html> |