Skip to content

Commit

Permalink
Add challenge leaderboard page
Browse files Browse the repository at this point in the history
  • Loading branch information
tmalahie committed Jan 23, 2022
1 parent 706b8e2 commit ce5392c
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 6 deletions.
4 changes: 3 additions & 1 deletion challenge-consts.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@ function getChallengeColors() {
function getChallengeDifficulty($challenge) {
$difficulties = getChallengeDifficulties();
$colors = getChallengeColors();
$rewards = getChallengeRewards();
$diffId = $challenge['difficulty'];
return array(
'level' => $diffId,
'name' => $difficulties[$diffId],
'color' => $colors[$diffId]
'color' => $colors[$diffId],
'pts' => $rewards[$diffId]
);
}
?>
3 changes: 2 additions & 1 deletion v2/app/hooks/useChallengeDifficulties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import useSmoothFetch from "./useSmoothFetch";
export type ChallengeDifficulty = {
level: number,
name: string,
color: string
color: string,
pts: number
}
function useChallengeDifficulties() {
const { data: difficultiesData } = useSmoothFetch<{ data: ChallengeDifficulty[] }>(`/api/getChallengeDifficulties.php`, {
Expand Down
2 changes: 1 addition & 1 deletion v2/app/pages/challenges/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const ChallengesList: NextPage = () => {
{moderate && <ValidationTips />}
{remoderate && <ReValidationTips />}
{!rateChallenges && <div className={styles["challenges-list-sublinks"]}>
<img src="images/cups/cup2.png" alt="Cup" /> <a href="challengeRanking.php">{language ? 'Challenges leaderboard' : 'Classement des défis'}</a>{"   "}
<img src="images/cups/cup2.png" alt="Cup" /> <Link href="/leaderboard/challenges">{language ? 'Challenges leaderboard' : 'Classement des défis'}</Link>{"   "}
<img src="images/ministar0.png" alt="Star" className={styles.icStar} /> <Link href="/challenges?rate">{language ? 'Rate challenges' : 'Noter les défis'}</Link>
</div>}
{!rateChallenges && <ChallengesListSearch />}
Expand Down
2 changes: 1 addition & 1 deletion v2/app/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,7 @@ const Home: NextPage = () => {
</Skeleton>
{user?.roles.clvalidator && <PendingChallenges />}
<Link href="/challenges"><a className={cx(styles.right_section_actions, commonStyles.action_button)}>{language ? 'Display all' : 'Afficher tout'}</a></Link>
<div id={styles.challenge_ranking}><a href="/challengeRanking.php">{language ? 'Challenge points - Leaderboard' : 'Classement des points défis'}</a></div>
<div id={styles.challenge_ranking}><Link href="/leaderboard/challenges">{language ? 'Challenge points - Leaderboard' : 'Classement des points défis'}</Link></div>
<h2>{language ? 'Recent activity' : 'Activité récente'}</h2>
<Skeleton loading={commentsLoading || recordsLoading} id={styles.comments_section} className={styles.right_subsection}>
{activityPayload?.map((activity) => (
Expand Down
129 changes: 129 additions & 0 deletions v2/app/pages/leaderboard/challenges.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { NextPage } from "next";
import Head from 'next/head'
import ClassicPage, { commonStyles } from "../../components/ClassicPage/ClassicPage";
import styles from "../../styles/Leaderboard.module.scss";
import pageStyles from "../../styles/ChallengeLeaderboard.module.scss";
import useLanguage, { plural } from "../../hooks/useLanguage";
import WithAppContext from "../../components/WithAppContext/WithAppContext";
import Leaderboard from "../../components/Leaderboard/Leaderboard";
import useAuthUser from "../../hooks/useAuthUser";
import Link from "next/link";
import { FormEvent, MouseEvent, useEffect, useState } from "react";
import { useRouter } from "next/router";
import { usePaging } from "../../hooks/usePaging";
import usePlayerAutoComplete from "../../hooks/usePlayerAutoComplete";
import useChallengeDifficulties from "../../hooks/useChallengeDifficulties";
import Ad from "../../components/Ad/Ad";
import cx from "classnames";

const ChallengesLeaderboard: NextPage = () => {
const language = useLanguage();
const router = useRouter();
const authUser = useAuthUser();
const { battle } = router.query;
const isBattle = battle != null;

const [username, setUsername] = useState("");
const { paging, currentPage, setCurrentPage } = usePaging(20);
const [pageChanging, setPageChanging] = useState(false);

useEffect(() => {
setPageChanging(false);
}, [isBattle])

function handlePageChange(page) {
setUsername("");
setCurrentPage(page);
}
function handleSearch(e: FormEvent<HTMLFormElement>) {
e.preventDefault();
setCurrentPage(1);
setUsername(e.currentTarget.elements["username"].value);
}

const challengeDifficulties = useChallengeDifficulties();

usePlayerAutoComplete({
inputSelector: "#username",
onSelect: (event, term) => {
event.preventSubmit();
setCurrentPage(1);
setUsername(term);
}
});

const [isRankingInfo, setIsRankingInfo] = useState(false);
function toggleRankingInfo(e: MouseEvent) {
e.preventDefault();
setIsRankingInfo(!isRankingInfo);
}

return (
<ClassicPage title={`${language ? 'Challenges leaderboard':'Classement défis'} - Mario Kart PC`} className={cx(styles.Leaderboard, pageStyles.ChallengeLeaderboard)} page="game">
<Head>
<link rel="stylesheet" href="/styles/auto-complete.css" />
</Head>
<h1>{ language ? 'Challenge points - Leaderboard':'Classement des points défis' }</h1>
{ language ? <div id={pageStyles.ranking_explain}>
This page displays the ranking of the players with the most points in the MKPC challenge mode
<a href="#null" onClick={toggleRankingInfo}>[Read more]</a>.
<div id={pageStyles.ranking_info}>
<Link href="/challenges">Challenges</Link> are actions to perform in the game (Ex: &quot;Complete a track in less than 1:30&quot;).
They are created by members thanks to the <strong>challenge editor</strong>. Anyone can create challenges, including you!<br />
When you complete a challenge, you win a certain amount of <strong>challenge points</strong> depending on the difficulty of the challenge. Your position in the ranking is determined by your number of challenge points.
<ul>
{challengeDifficulties.map(difficulty => <li>
A challenge <strong>{difficulty.name}</strong> gives you <strong>{ plural("%n pt%s", difficulty.pts) }</strong>.
</li>)}
</ul>
</div>
</div> : <div id={pageStyles.ranking_explain}>
Cette page affiche le classement des joueurs ayant le plus de points dans le mode défis de MKPC
{" "}<a href="#null" onClick={toggleRankingInfo}>[En savoir plus]</a>.
{isRankingInfo && <div id={pageStyles.ranking_info}>
Les <Link href="/challenges">défis</Link> sont des actions à réaliser sur le jeu (Ex : &quot;Finir un circuit en moins de 1:30&quot;).
Ils sont créés par les membres via l'<strong>éditeur de défis</strong>. N'importe qui peut créer des défis, vous aussi !<br />
Lorsque vous réussissez un défi, vous gagnez un certain nombre de <strong>points défis</strong> en fonction de la difficulté. Ce sont ces points défis qui déterminent votre place dans le classement.
<ul>
{challengeDifficulties.map(difficulty => <li>
Un défi <strong>{difficulty.name}</strong> rapporte <strong>{plural("%n pt%s", difficulty.pts)}</strong>
</li>)}
</ul>
</div>}
</div>}
<p className={styles.pub}>
<Ad bannerId="6691323567" width={468} height={60} />
</p>
<form method="post" action={"/leaderboard/challenge"} onSubmit={handleSearch}>
<blockquote>
<p>
<label htmlFor="username"><strong>{ language ? 'See player':'Voir joueur' }</strong></label>
{" : "}
<input type="text" name="username" id="username" defaultValue={username || authUser.name} />
{" "}
<input type="submit" value={ language ? 'Validate':'Valider' } className={commonStyles.action_button} /></p>
</blockquote>
</form>

<Leaderboard fetcherOptions={
{
disabled: pageChanging,
endpoint: "/api/online-game/leaderboard",
query: {
mode: "challenge"
},
reloadDeps: [pageChanging, isBattle]
}
} username={username} pager={{
paging,
currentPage,
onSetPage: handlePageChange,
}} />

<p><Link href={"/challenges"}>{ language ? 'Back to challenges list':'Retour à la liste des défis' }</Link><br />
<Link href="/">{ language ? 'Back to Mario Kart PC':'Retour à Mario Kart PC' }</Link></p>
</ClassicPage>
);
}

export default WithAppContext(ChallengesLeaderboard);
6 changes: 5 additions & 1 deletion v2/app/pages/leaderboard/online.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import useScript from "../../hooks/useScript";
import { useRouter } from "next/router";
import { usePaging } from "../../hooks/usePaging";
import usePlayerAutoComplete from "../../hooks/usePlayerAutoComplete";
import Ad from "../../components/Ad/Ad";

const OnlineLeaderboard: NextPage = () => {
const language = useLanguage();
Expand Down Expand Up @@ -69,6 +70,9 @@ const OnlineLeaderboard: NextPage = () => {
</>
}
</div>
<div className={styles.pub}>
<Ad bannerId="6691323567" width={468} height={60} />
</div>
<form method="post" action={"/leaderboard/online"} onSubmit={handleSearch}>
<blockquote>
<p>
Expand All @@ -95,7 +99,7 @@ const OnlineLeaderboard: NextPage = () => {
onSetPage: handlePageChange,
}} />

<p><a href={`online.php${isBattle ? '?battle':''}`}>{ language ? 'Back to the online mode home':'Retour à l\'accueil du mode en ligne' }</a><br />
<p><a href={`/online.php${isBattle ? '?battle':''}`}>{ language ? 'Back to the online mode home':'Retour à l\'accueil du mode en ligne' }</a><br />
<Link href="/">{ language ? 'Back to Mario Kart PC':'Retour à Mario Kart PC' }</Link></p>
</ClassicPage>
);
Expand Down
2 changes: 1 addition & 1 deletion v2/app/pages/leaderboard/timetrial.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const OnlineLeaderboard: NextPage = () => {
<div className={styles.pub}>
<Ad bannerId="6691323567" width={468} height={60} />
</div>
<form method="post" action={"/leaderboard/online"} onSubmit={handleSearch}>
<form method="post" action={"/leaderboard/timetrial"} onSubmit={handleSearch}>
<blockquote>
<p>
<label htmlFor="username"><strong>{ language ? 'See player':'Voir joueur' }</strong></label>
Expand Down
20 changes: 20 additions & 0 deletions v2/app/styles/ChallengeLeaderboard.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.ChallengeLeaderboard {
#ranking_explain {
max-width: 650px;
margin-left: auto;
margin-right: auto;
text-align: justify;
a {
position: relative;
top: -1px;
}
}
#ranking_info {
text-align: left;
margin-top: 10px;
}
#ranking_info ul {
margin: 5px 0;
padding-left: 25px;
}
}

0 comments on commit ce5392c

Please sign in to comment.