From a84a70fdc2ed7609ecda57bf0baf644442f1f834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o?= <43091603+glazk0@users.noreply.github.com> Date: Mon, 1 May 2023 16:43:31 +0200 Subject: [PATCH] Added Dashboard page back --- app/dashboard/page.tsx | 179 +++++++++++++++++++-------------------- app/logout/page.tsx | 2 +- lib/fetcher.ts | 12 --- lib/nav-items.ts | 20 ++--- lib/players.ts | 7 ++ ui/Card.tsx | 27 ++++-- ui/CardTable.tsx | 45 ---------- ui/Leaderboard.tsx | 54 +++++++----- ui/Puzzles.tsx | 6 +- ui/ToHTML.tsx | 2 +- ui/UserAuthForm.tsx | 2 + ui/dashboard/Sidenav.tsx | 7 +- 12 files changed, 166 insertions(+), 197 deletions(-) delete mode 100644 lib/fetcher.ts delete mode 100644 ui/CardTable.tsx diff --git a/app/dashboard/page.tsx b/app/dashboard/page.tsx index 28e2b3e..3fa8b8e 100644 --- a/app/dashboard/page.tsx +++ b/app/dashboard/page.tsx @@ -1,104 +1,99 @@ 'use client'; +import { useContext } from 'react'; + import { UserContext } from '@/context/user'; import Card from '@/ui/Card'; -import { useContext } from 'react'; export default function Page() { const { data: me, isLoading } = useContext(UserContext); return ( -
-
-
-
-

Tableau de bord

-

Ceci est la page d'accueil du dashboard

-
-
- - - -
-
-
-
-
-
-

Guides

-
-
- Work in progress -
-
-
-
-

Historiques

-
-
- Work in progress -
-
-
- {/* TODO fix ça c'est pas responsive */} - {/*
-
-

Statistiques

-

Ceci est la page d'accueil du dashboard

-
-
- +
+

Tableau de bord

+

Ceci est la page d'accueil du dashboard

+
+
+
+ - -
-
*/} -
+ + +
+
+
+

Derniers puzzles

+

+ Voici les derniers puzzles que vous avez résolus ou essayer de résoudres +

+
+
+
    + {me?.completionsList && me.completionsList.length > 0 ? ( + me?.completionsList + .sort( + (a, b) => + a.score - b.score || + a.tries - b.tries || + a.puzzleName.localeCompare(b.puzzleName) + ) + .map((completion, key) => { + return ( +
  • +
    +
    + {completion.puzzleName} +
    +
    +
    +
    + + Essai{completion.tries > 1 ? 's' : ''} + + + {completion.tries} + +
    +
    + Score + + {completion.score} + +
    +
    +
  • + ); + }) + ) : ( +
  • + + {isLoading ? 'Chargement en cours...' : 'Aucun puzzles'} + +
  • + )} +
+
+
+
+ + ); } diff --git a/app/logout/page.tsx b/app/logout/page.tsx index 96e3e7b..509e0b7 100644 --- a/app/logout/page.tsx +++ b/app/logout/page.tsx @@ -8,7 +8,7 @@ export default function Page() { useEffect(() => { router.push('/'); - }, []); + }, [router]); return <>; } diff --git a/lib/fetcher.ts b/lib/fetcher.ts deleted file mode 100644 index 1803a9c..0000000 --- a/lib/fetcher.ts +++ /dev/null @@ -1,12 +0,0 @@ -import axios from 'axios'; - -const fetcher = axios.create({ - baseURL: process.env.NEXT_PUBLIC_API_URL, - headers: { - 'Content-Type': 'application/json', - Accept: 'application/json' - }, - insecureHTTPParser: true -}); - -export default fetcher; diff --git a/lib/nav-items.ts b/lib/nav-items.ts index 27f1e2d..8e2aecb 100644 --- a/lib/nav-items.ts +++ b/lib/nav-items.ts @@ -20,33 +20,33 @@ export type NavItem = { * @type {NavItem[]} */ export const navItems: NavItem[] = [ - // { - // name: 'Dashboard', - // slug: '', - // icon: 'dashboard-line', - // disabled: false - // }, + { + name: 'Dashboard', + slug: 'dashboard', + icon: 'dashboard-line', + disabled: false + }, { name: 'Classement', - slug: 'leaderboard', + slug: 'dashboard/leaderboard', icon: 'line-chart-line', disabled: false }, { name: 'Puzzles', - slug: 'puzzles', + slug: 'dashboard/puzzles', icon: 'code-s-slash-line', disabled: false }, { name: 'Badges', - slug: 'badges', + slug: 'dashboard/badges', icon: 'award-fill', disabled: false }, { name: 'Paramètres', - slug: 'settings', + slug: 'dashboard/settings', icon: 'equalizer-line', disabled: false } diff --git a/lib/players.ts b/lib/players.ts index 9cf09d3..5ea73de 100644 --- a/lib/players.ts +++ b/lib/players.ts @@ -38,6 +38,7 @@ export type Player = { tries: number; completions: number; rank: number; + completionsList: Completion[]; badges: Badge[] | null; }; @@ -46,3 +47,9 @@ export type Badge = { level: number; logo?: string; }; + +export type Completion = { + puzzleName: string; + tries: number; + score: number; +}; diff --git a/ui/Card.tsx b/ui/Card.tsx index be78a5b..e8dbb01 100644 --- a/ui/Card.tsx +++ b/ui/Card.tsx @@ -1,23 +1,28 @@ +import { getURL } from '@/lib/utils'; + +import AppLink from './AppLink'; import Icon from './Icon'; export default function Card({ isLoading, icon, title, - data + data, + link }: { isLoading: boolean; icon: string; title: string; data: any; + link?: string; }) { if (isLoading) return (
- - + +
); @@ -25,9 +30,19 @@ export default function Card({ return (
-
-

{data}

-

{title}

+
+
+

{data}

+

{title}

+
+ {link && ( + + + + )}
); diff --git a/ui/CardTable.tsx b/ui/CardTable.tsx deleted file mode 100644 index 6a4afca..0000000 --- a/ui/CardTable.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { type Puzzle } from '@/lib/puzzles'; - -import AppLink from './AppLink'; - -export default function CardTable({ puzzles }: { puzzles: Puzzle[] }) { - return ( - <> - //
- // - // {/* - // - // - // - // - // - // - // - // */} - // - // {puzzles.length && - // puzzles.map((puzzle) => ( - // - // - // - // - // - // - // - // ))} - // - //
ExerciceTentativeScoreDernier essai - // Reprendre - //
- // {puzzle.name} - // 3030010/10/2010 - // - // Reprendre - // - //
- //
- ); -} diff --git a/ui/Leaderboard.tsx b/ui/Leaderboard.tsx index 25b74ac..a0dd8f3 100644 --- a/ui/Leaderboard.tsx +++ b/ui/Leaderboard.tsx @@ -1,37 +1,40 @@ 'use client'; import { AnimatePresence, motion } from 'framer-motion'; -import useSWRSubscription, { type SWRSubscription } from 'swr/subscription'; -import { type ScoreEvent } from '@/lib/leaderboard'; +import { useLeaderboardEvent } from '@/lib/hooks/use-leaderboard'; import { cn } from '@/lib/utils'; import Podium from '@/ui/events/podium/Podium'; import { Timer } from './Timer'; +import { type ScoreEvent } from '@/lib/leaderboard'; +import useSWRSubscription, { type SWRSubscription } from 'swr/subscription'; const SCORE_COLORS = ['text-yellow-400', 'text-gray-400', 'text-orange-400']; -export default function Leaderboard() { +export default function Leaderboard({ token }: { token: string }) { // TODO CHANGER CECI const CHAPITRE_EVENT = 1; - const subscription: SWRSubscription = (key, { next }) => { - const socket = new WebSocket(key); + // const subscription: SWRSubscription = (key, { next }) => { + // const socket = new WebSocket(key); - socket.addEventListener('message', (event) => { - next(null, JSON.parse(event.data)); - }); + // socket.addEventListener('message', (event) => { + // next(null, JSON.parse(event.data)); + // }); - socket.addEventListener('error', (event) => { - console.error(event); - }); + // socket.addEventListener('error', (event) => { + // console.error(event); + // }); - return () => socket.close(); - }; + // return () => socket.close(); + // }; - const { data } = useSWRSubscription( - `wss://${process.env.NEXT_PUBLIC_API_URL?.split('//')[1]}/rleaderboard/${CHAPITRE_EVENT}`, - subscription - ); + // const { data } = useSWRSubscription( + // `wss://${process.env.NEXT_PUBLIC_API_URL?.split('//')[1]}/rleaderboard/${CHAPITRE_EVENT}`, + // subscription + // ); + + const { data, isLoading } = useLeaderboardEvent({ token: token, id: CHAPITRE_EVENT }); const scores = [data?.groups] .flat() @@ -60,8 +63,8 @@ export default function Leaderboard() { const tries = group.players.reduce((a, b) => a + b.tries, 0) || 0; return (
- + {group.rank}
{group.name} - + {group.players && group.players.length > 1 ? group.players .map((player) => player.pseudo || 'Anonyme') @@ -89,15 +97,15 @@ export default function Leaderboard() {
{/*
Puzzle{puzzles > 1 ? 's' : ''} - {puzzles} + {puzzles}
*/}
Essai{tries > 1 ? 's' : ''} - {tries} + {tries}
Score - + {group.players.reduce((a, b) => a + b.score, 0)}
diff --git a/ui/Puzzles.tsx b/ui/Puzzles.tsx index ffa520e..5246b30 100644 --- a/ui/Puzzles.tsx +++ b/ui/Puzzles.tsx @@ -257,14 +257,14 @@ function PuzzleProp({ puzzle, chapter }: { puzzle: Puzzle; chapter: Chapter }) { {puzzle.tags .filter((tag) => !['easy', 'medium', 'hard'].includes(tag.name)) .map((tag, i) => ( - + {tag.name} ))}
)}
@@ -292,7 +292,7 @@ function PuzzleProp({ puzzle, chapter }: { puzzle: Puzzle; chapter: Chapter }) {
)}
diff --git a/ui/ToHTML.tsx b/ui/ToHTML.tsx index 76ec86d..d4396e0 100644 --- a/ui/ToHTML.tsx +++ b/ui/ToHTML.tsx @@ -13,7 +13,7 @@ export default function ToHTML({ data, className }: { data: string; className?: a: ({ node, ...props }) => ( {!isSignIn && ( <> diff --git a/ui/dashboard/Sidenav.tsx b/ui/dashboard/Sidenav.tsx index 39cf498..77c3ec4 100644 --- a/ui/dashboard/Sidenav.tsx +++ b/ui/dashboard/Sidenav.tsx @@ -90,13 +90,12 @@ function NavItem({ onClick?: () => void; }) { const segment = useSelectedLayoutSegment(); - const pathname = segment?.split('/').pop() || ''; const isHttp = item.slug.includes('http'); - const isActive = pathname === item.slug || (item.slug === '' && !segment); + const pathname = item.slug.split('/').pop(); + const isActive = segment === pathname || (segment === null && pathname === 'dashboard'); return (