Add leaderboards
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
@import 'tailwindcss';
|
@import 'tailwindcss';
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
@apply fixed top-0 left-0 w-60 h-screen bg-[#161616] flex flex-col border-e-[1px] border-[#2a2a2a];
|
@apply fixed top-0 left-0 w-60 h-screen bg-[#161616] flex flex-col border-e-[1px] border-[#2a2a2a] z-[999];
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-downloads {
|
.sidebar-downloads {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import './Sidebar.css'
|
|||||||
import Icon from '../Icon.png'
|
import Icon from '../Icon.png'
|
||||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
import { faCog, faDownload, faServer } from '@fortawesome/free-solid-svg-icons'
|
import { faCog, faDownload, faRankingStar, faServer } from '@fortawesome/free-solid-svg-icons'
|
||||||
import { faDiscord } from '@fortawesome/free-brands-svg-icons'
|
import { faDiscord } from '@fortawesome/free-brands-svg-icons'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { platform } from '@tauri-apps/plugin-os'
|
import { platform } from '@tauri-apps/plugin-os'
|
||||||
@@ -74,7 +74,8 @@ export default function Sidebar({ setShowPopup, setPopupMode, setFadeOut }: Side
|
|||||||
<nav className="nav-links">
|
<nav className="nav-links">
|
||||||
<a draggable={false} href="#installs" className={`link ${(window.location.hash || '#installs') === '#installs' ? 'active' : ''}`}><FontAwesomeIcon icon={faServer} className="mr-2" /> Installs</a>
|
<a draggable={false} href="#installs" className={`link ${(window.location.hash || '#installs') === '#installs' ? 'active' : ''}`}><FontAwesomeIcon icon={faServer} className="mr-2" /> Installs</a>
|
||||||
<a draggable={false} href="#settings" className={`link ${(window.location.hash || '#installs') === '#settings' ? 'active' : ''}`}><FontAwesomeIcon icon={faCog} className="mr-2" /> Settings</a>
|
<a draggable={false} href="#settings" className={`link ${(window.location.hash || '#installs') === '#settings' ? 'active' : ''}`}><FontAwesomeIcon icon={faCog} className="mr-2" /> Settings</a>
|
||||||
<a draggable={false} onClick={() => openUrl("https://berrydash.lncvrt.xyz/discord")} className="link"><FontAwesomeIcon icon={faDiscord} className="mr-2" />Community</a>
|
<a draggable={false} href="#leaderboards" className={`link ${(window.location.hash || '#installs') === '#leaderboards' ? 'active' : ''}`}><FontAwesomeIcon icon={faRankingStar} className="mr-1" /> Leaderboards</a>
|
||||||
|
<a draggable={false} onClick={() => openUrl("https://berrydash.lncvrt.xyz/discord")} className="link"><FontAwesomeIcon icon={faDiscord} className="mr-1" /> Community</a>
|
||||||
</nav>
|
</nav>
|
||||||
<div className='sidebar-downloads' onClick={() => { setPopupMode(1); setShowPopup(true); setFadeOut(false) }}>
|
<div className='sidebar-downloads' onClick={() => { setPopupMode(1); setShowPopup(true); setFadeOut(false) }}>
|
||||||
<p><FontAwesomeIcon icon={faDownload} /> Downloads</p>
|
<p><FontAwesomeIcon icon={faDownload} /> Downloads</p>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { listen } from '@tauri-apps/api/event'
|
|||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
import { faAdd, faRemove, faX } from '@fortawesome/free-solid-svg-icons'
|
import { faAdd, faRemove, faX } from '@fortawesome/free-solid-svg-icons'
|
||||||
import '@fontsource/roboto'
|
import '@fontsource/roboto'
|
||||||
|
import Leaderboards from './routes/Leaderboards'
|
||||||
|
|
||||||
function App () {
|
function App () {
|
||||||
const [hash, setHash] = useState(window.location.hash || '#installs')
|
const [hash, setHash] = useState(window.location.hash || '#installs')
|
||||||
@@ -108,6 +109,8 @@ function App () {
|
|||||||
return <Installs downloadProgress={downloadProgress} showPopup={showPopup} setShowPopup={setShowPopup} setPopupMode={setPopupMode} setFadeOut={setFadeOut} setSelectedVersionList={setSelectedVersionList} setVersionList={setVersionList} />
|
return <Installs downloadProgress={downloadProgress} showPopup={showPopup} setShowPopup={setShowPopup} setPopupMode={setPopupMode} setFadeOut={setFadeOut} setSelectedVersionList={setSelectedVersionList} setVersionList={setVersionList} />
|
||||||
} else if (hash === '#settings') {
|
} else if (hash === '#settings') {
|
||||||
return <Settings />
|
return <Settings />
|
||||||
|
} else if (hash === '#leaderboards') {
|
||||||
|
return <Leaderboards />
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/routes/Leaderboards.css
Normal file
17
src/routes/Leaderboards.css
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
@import 'tailwindcss';
|
||||||
|
|
||||||
|
.leaderboard-container {
|
||||||
|
@apply flex justify-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaderboard-scroll {
|
||||||
|
@apply h-[85vh] bg-[#161616] border border-[#242424] rounded-lg overflow-y-auto max-w-md w-full;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaderboard-entry {
|
||||||
|
@apply flex justify-between items-center m-2 p-4 rounded-lg text-gray-200 text-lg transition-colors cursor-default bg-[#242424] hover:bg-[#323232] border border-[#484848] hover:border-[#565656];
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaderboard-entry p.score {
|
||||||
|
@apply font-mono text-blue-500 text-lg;
|
||||||
|
}
|
||||||
45
src/routes/Leaderboards.tsx
Normal file
45
src/routes/Leaderboards.tsx
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import './Leaderboards.css'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { LeaderboardEntry } from '../types/LeaderboardEntry'
|
||||||
|
|
||||||
|
export default function Leaderboards() {
|
||||||
|
const [leaderboardData, setLeaderboardData] = useState<LeaderboardEntry[]>([])
|
||||||
|
|
||||||
|
function refresh() {
|
||||||
|
setLeaderboardData([])
|
||||||
|
axios
|
||||||
|
.get('https://berrydash.lncvrt.xyz/database/getTopPlayersAPI.php')
|
||||||
|
.then(res => setLeaderboardData(res.data))
|
||||||
|
.catch(e => console.error('Error fetching leaderboard data:', e))
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
refresh()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='mx-4 mt-4'>
|
||||||
|
<div className='flex justify-between items-center mb-4'>
|
||||||
|
<p className='text-3xl'>Leaderboards</p>
|
||||||
|
<button className='button text-3xl' onClick={refresh}>Refresh</button>
|
||||||
|
</div>
|
||||||
|
<div className='leaderboard-container'>
|
||||||
|
<div className='leaderboard-scroll'>
|
||||||
|
{leaderboardData.length ? (
|
||||||
|
leaderboardData.map((entry, i) => (
|
||||||
|
<div key={entry.username} className='leaderboard-entry'>
|
||||||
|
<p>#{i + 1} {entry.username}</p>
|
||||||
|
<p className='score'>{entry.scoreFormatted}</p>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<div className='flex justify-center items-center h-full'>
|
||||||
|
<p className='text-3xl'>Loading...</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
5
src/types/LeaderboardEntry.ts
Normal file
5
src/types/LeaderboardEntry.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export interface LeaderboardEntry {
|
||||||
|
username: string
|
||||||
|
score: bigint
|
||||||
|
scoreFormatted: string
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user