|
<!DOCTYPE html> |
|
<html lang="en"> |
|
|
|
<head> |
|
<meta charset="UTF-8" /> |
|
<title>LeRobot Worldwide Hackathon</title> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
|
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
|
|
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script> |
|
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> |
|
</head> |
|
|
|
<body class="bg-white"> |
|
<div id="root"></div> |
|
|
|
<script type="text/javascript"> |
|
const { useEffect, useState } = React; |
|
|
|
function App() { |
|
const [videos, setVideos] = useState([]); |
|
const [teamDatasets, setTeamDatasets] = useState({}); |
|
const [searchQuery, setSearchQuery] = useState(""); |
|
|
|
useEffect(() => { |
|
fetch("https://datasets-server.huggingface.co/rows?dataset=LeRobot-worldwide-hackathon%2Fsubmissions&config=default&split=train&offset=0&limit=100") |
|
.then(res => res.json()) |
|
.then(data => { |
|
const videoFiles = data.rows |
|
.map(row => row.row.video) |
|
.filter(url => typeof url === "string" && url.endsWith(".mp4")) |
|
.map(url => { |
|
const match = url.match(/(?:team|group)[-_ ]?(\d+)/i); |
|
const team = match ? match[1] : null; |
|
const label = team ? `Team ${team}` : "Unknown Team"; |
|
return { url, label, team }; |
|
}); |
|
setVideos(videoFiles); |
|
}); |
|
|
|
fetch("https://huggingface.co/api/datasets?author=LeRobot-worldwide-hackathon") |
|
.then(res => res.json()) |
|
.then(data => { |
|
const map = {}; |
|
data.forEach(entry => { |
|
const match = entry.id.match(/LeRobot-worldwide-hackathon\/team[_-]?(\d+)/i); |
|
if (match) { |
|
const team = match[1]; |
|
if (!map[team]) map[team] = []; |
|
map[team].push(`https://huggingface.co/spaces/lerobot/visualize_dataset?dataset=${entry.id}`); |
|
} |
|
}); |
|
setTeamDatasets(map); |
|
}); |
|
}, []); |
|
|
|
const filteredVideos = videos.filter(video => { |
|
return ( |
|
video.label.toLowerCase().includes(searchQuery) || |
|
video.url.toLowerCase().includes(searchQuery) |
|
); |
|
}); |
|
|
|
return React.createElement("div", { |
|
className: "min-h-screen p-6", |
|
style: { backgroundColor: "#3A3B3C" } |
|
}, |
|
React.createElement("style", { |
|
dangerouslySetInnerHTML: { |
|
__html: ` |
|
@keyframes gradientBG { |
|
0% { background-position: 0% 50%; } |
|
50% { background-position: 100% 50%; } |
|
100% { background-position: 0% 50%; } |
|
} |
|
` |
|
} |
|
}), |
|
React.createElement("h1", { |
|
className: "text-3xl font-bold mb-2 text-center text-white" |
|
}, "LeRobot Worldwide Hackathon"), |
|
React.createElement("p", { |
|
className: "text-white text-center mb-6" |
|
}, |
|
"🌍 Worldwide", React.createElement("br", null), |
|
"📅 June 2025, 14 at 09:00 AM (UTC+2) – June 2025, 15 at 06:00 PM (UTC+2)" |
|
), |
|
React.createElement("div", { |
|
className: "flex justify-center mb-6" |
|
}, |
|
React.createElement("input", { |
|
type: "text", |
|
placeholder: "Search videos…", |
|
className: "px-4 py-2 w-full max-w-md border rounded-md shadow-md", |
|
value: searchQuery, |
|
onChange: (e) => setSearchQuery(e.target.value.toLowerCase()) |
|
}) |
|
), |
|
React.createElement("div", { |
|
className: "columns-1 sm:columns-2 lg:columns-3 gap-4 space-y-4" |
|
}, filteredVideos.map((video, i) => |
|
React.createElement("div", { |
|
key: i, |
|
className: "break-inside-avoid bg-white rounded-2xl shadow-md overflow-hidden" |
|
}, |
|
React.createElement("video", { |
|
src: video.url, |
|
controls: true, |
|
autoplay: true, |
|
muted: true, |
|
loop: true, |
|
playsInline: true, |
|
className: "w-full h-auto" |
|
}), |
|
React.createElement("div", { |
|
className: "p-2 text-center text-sm font-medium text-gray-700" |
|
}, |
|
video.label, |
|
video.team && teamDatasets[video.team] && |
|
React.createElement("div", { |
|
className: "mt-1 space-y-1" |
|
}, |
|
teamDatasets[video.team].map((url, j) => |
|
React.createElement("div", { |
|
key: j |
|
}, |
|
React.createElement("a", { |
|
href: url, |
|
className: "text-blue-500 underline", |
|
target: "_blank" |
|
}, `Dataset: ${url.split('=')[1]}`) |
|
) |
|
) |
|
) |
|
) |
|
) |
|
)) |
|
); |
|
} |
|
|
|
ReactDOM.createRoot(document.getElementById("root")).render(React.createElement(App)); |
|
</script> |
|
</body> |
|
|
|
</html> |
|
|
|
|
|
|