From 9825f7b3dea58fc82d7a29bd2d43d9e81829c508 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Th=C3=A9o?= <43091603+glazk0@users.noreply.github.com>
Date: Fri, 21 Apr 2023 10:27:48 +0200
Subject: [PATCH] Add missing stuff & changing leaderboard
---
app/dashboard/leaderboard/page.tsx | 6 +-
app/dashboard/puzzles/[id]/page.tsx | 24 +++--
app/dashboard/puzzles/page.tsx | 19 +++-
app/page.tsx | 2 +-
lib/groups.ts | 12 +--
lib/leaderboard.ts | 19 ++--
lib/players.ts | 9 +-
lib/puzzles.ts | 52 ++++++----
ui/Console.tsx | 2 +-
ui/Leaderboard.tsx | 65 +++---------
ui/Puzzle.tsx | 8 +-
ui/Puzzles.tsx | 156 ++++++++++++++++++++--------
ui/ToHTML.tsx | 12 +--
ui/events/podium/PodiumStep.tsx | 4 +-
14 files changed, 225 insertions(+), 165 deletions(-)
diff --git a/app/dashboard/leaderboard/page.tsx b/app/dashboard/leaderboard/page.tsx
index ba22a15..d88d78a 100644
--- a/app/dashboard/leaderboard/page.tsx
+++ b/app/dashboard/leaderboard/page.tsx
@@ -1,12 +1,10 @@
import Leaderboard from '@/ui/Leaderboard';
-import { cookies } from 'next/headers';
export const metadata = {
- title: 'Tableau des scores - Peer-at Code',
+ title: 'Tableau des scores',
description: 'Suivez la progression des élèves en direct'
};
export default async function Page() {
- const token = cookies().get('token')?.value;
- return ;
+ return ;
}
diff --git a/app/dashboard/puzzles/[id]/page.tsx b/app/dashboard/puzzles/[id]/page.tsx
index bba8d8a..09a97f1 100644
--- a/app/dashboard/puzzles/[id]/page.tsx
+++ b/app/dashboard/puzzles/[id]/page.tsx
@@ -1,4 +1,5 @@
import { getPuzzle } from '@/lib/puzzles';
+import { getURL } from '@/lib/utils';
import Puzzle from '@/ui/Puzzle';
import SWRFallback from '@/ui/SWRFallback';
import type { Metadata } from 'next';
@@ -15,7 +16,22 @@ export async function generateMetadata({ params }: { params: { id: number } }):
const puzzle = await getPuzzle({ token, id });
- return { title: `${puzzle.name} - Peer-at Code` };
+ if (!puzzle) {
+ notFound();
+ }
+
+ return {
+ title: puzzle.name,
+ openGraph: {
+ title: puzzle.name,
+ type: 'website',
+ url: getURL(`/dashboard/puzzles/${puzzle.id}`)
+ // IMAGES WITH OG IMAGE
+ },
+ twitter: {
+ title: puzzle.name
+ }
+ };
}
export default async function Page({ params: { id } }: { params: { id: number } }) {
@@ -25,11 +41,7 @@ export default async function Page({ params: { id } }: { params: { id: number }
notFound();
}
- const puzzle = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/puzzle/${id}`, {
- headers: {
- Authorization: `Bearer ${token}`
- }
- }).then((res) => res.json());
+ const puzzle = await getPuzzle({ token, id });
if (!puzzle) {
notFound();
diff --git a/app/dashboard/puzzles/page.tsx b/app/dashboard/puzzles/page.tsx
index cd703a6..62bef6c 100644
--- a/app/dashboard/puzzles/page.tsx
+++ b/app/dashboard/puzzles/page.tsx
@@ -1,20 +1,29 @@
import { cookies } from 'next/headers';
import Puzzles from '@/ui/Puzzles';
+import SWRFallback from '@/ui/SWRFallback';
+import { getPuzzles } from '@/lib/puzzles';
+import { notFound } from 'next/navigation';
export const metadata = {
- title: 'Puzzles - Peer-at Code'
+ title: 'Puzzles'
};
export default async function Page() {
const cookieStore = cookies();
- const token = cookieStore.get('token')?.value;
+ const token = cookieStore.get('token')!.value;
+
+ const puzzles = await getPuzzles({ token });
+
+ if (!puzzles) {
+ notFound();
+ }
return (
- {/*
*/}
-
- {/* */}
+
+
+
);
}
diff --git a/app/page.tsx b/app/page.tsx
index 3a5cea6..3d88e0a 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -11,7 +11,7 @@ export default function Page() {
- Commencer
+ Commencer l'aventure
diff --git a/lib/groups.ts b/lib/groups.ts
index b03740b..18f9482 100644
--- a/lib/groups.ts
+++ b/lib/groups.ts
@@ -1,23 +1,21 @@
-import fetcher from './fetcher';
-
export const getGroups = async ({ token }: { token: string }): Promise
=> {
- const { data, status } = await fetcher.get(`/groups`, {
+ const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/groups`, {
headers: {
Authorization: `Bearer ${token}`
}
});
- const groups = data;
+ const groups = (await res.json()) as Group[];
- if (status !== 200) {
+ if (!res.ok) {
throw new Error('Failed to fetch groups');
}
if (!groups) {
- return [] as Group[];
+ return [];
}
- return groups as Group[];
+ return groups;
};
export type Group = {
diff --git a/lib/leaderboard.ts b/lib/leaderboard.ts
index 525957b..b41f53a 100644
--- a/lib/leaderboard.ts
+++ b/lib/leaderboard.ts
@@ -1,24 +1,23 @@
-import fetcher from './fetcher';
import { type Group } from './groups';
export const getScores = async ({ token }: { token: string }): Promise => {
- const { data, status } = await fetcher.get(`/leaderboard`, {
+ const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/leaderboard`, {
headers: {
Authorization: `Bearer ${token}`
}
});
- const scores = data;
+ const scores = (await res.json()) as Score[];
- if (status !== 200) {
+ if (!res.ok) {
throw new Error('Failed to fetch scores');
}
if (!scores) {
- return [] as Score[];
+ return [];
}
- return scores as Score[];
+ return scores;
};
export const getScoresEvent = async ({
@@ -28,16 +27,16 @@ export const getScoresEvent = async ({
token: string;
id: number;
}): Promise => {
- const { data, status } = await fetcher.get(`/leaderboard/${id}`, {
+ const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/leaderboard/${id}`, {
headers: {
Authorization: `Bearer ${token}`
}
});
- const scores = data;
+ const scores = (await res.json()) as ScoreEvent;
- if (status !== 200) {
- throw new Error('Failed to fetch scores');
+ if (!res.ok) {
+ throw new Error('Failed to fetch event scores');
}
if (!scores) {
diff --git a/lib/players.ts b/lib/players.ts
index 845e098..9cf09d3 100644
--- a/lib/players.ts
+++ b/lib/players.ts
@@ -1,4 +1,3 @@
-import fetcher from './fetcher';
import { type Group } from './groups';
export const getPlayer = async ({
@@ -8,15 +7,15 @@ export const getPlayer = async ({
token: string;
username?: string;
}): Promise => {
- const { data, status } = await fetcher.get(`/player/${username}`, {
+ const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/player/${username}`, {
headers: {
Authorization: `Bearer ${token}`
}
});
- const player = data;
+ const player = (await res.json()) as Player;
- if (status !== 200) {
+ if (!res.ok) {
throw new Error('Failed to fetch player');
}
@@ -24,7 +23,7 @@ export const getPlayer = async ({
return null;
}
- return player as Player;
+ return player;
};
export type Player = {
diff --git a/lib/puzzles.ts b/lib/puzzles.ts
index 158a41d..570162d 100644
--- a/lib/puzzles.ts
+++ b/lib/puzzles.ts
@@ -1,15 +1,13 @@
-import fetcher from './fetcher';
-
export const getChapters = async ({ token }: { token: string }): Promise => {
- const { data, status } = await fetcher.get(`/chapters`, {
+ const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/chapters`, {
headers: {
Authorization: `Bearer ${token}`
}
});
- const chapters = data;
+ const chapters = (await res.json()) as Chapter[];
- if (status !== 200) {
+ if (!res.ok) {
throw new Error('Failed to fetch puzzles');
}
@@ -17,7 +15,7 @@ export const getChapters = async ({ token }: { token: string }): Promise => {
- const { data, status } = await fetcher.get(`/chapter/${id}`, {
+ const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/chapter/${id}`, {
headers: {
Authorization: `Bearer ${token}`
}
});
- const chapter = data;
+ const chapter = (await res.json()) as Chapter;
- if (status !== 200) {
+ if (!res.ok) {
throw new Error('Failed to fetch puzzles');
}
@@ -43,40 +41,50 @@ export const getChapter = async ({
return null;
}
- return chapter as Chapter;
+ return chapter;
};
export const getPuzzles = async ({ token }: { token: string }): Promise => {
const chapters = await getChapters({ token });
- for (let i = 0; i < chapters.length; i++) {
- const chapter = chapters[i];
- const chapterData = await getChapter({ token, id: chapter.id });
- if (!chapterData) continue;
- chapters[i].puzzles = chapterData.puzzles;
+ if (!chapters) {
+ return [];
}
- return chapters as Chapter[];
+ for (let i = 0; i < chapters.length; i++) {
+ let chapter = chapters[i];
+ chapter = (await getChapter({ token, id: chapter.id })) as Chapter;
+ if (!chapter) continue;
+ chapters[i].puzzles = chapter.puzzles;
+ }
+
+ return chapters;
};
-export const getPuzzle = async ({ token, id }: { token: string; id: number }): Promise => {
- const { data, status } = await fetcher.get(`/puzzle/${id}`, {
+export const getPuzzle = async ({
+ token,
+ id
+}: {
+ token: string;
+ id: number;
+}): Promise => {
+ const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/puzzle/${id}`, {
headers: {
Authorization: `Bearer ${token}`
}
});
- const puzzle = data;
+ const puzzle = (await res.json()) as Puzzle;
- if (status !== 200) {
+ if (!res.ok) {
throw new Error('Failed to fetch puzzle');
}
if (!puzzle) {
- return {} as Puzzle;
+ return null;
}
- return puzzle as Puzzle;
+ return puzzle;
};
export type Puzzle = {
diff --git a/ui/Console.tsx b/ui/Console.tsx
index 9dc2823..6e588bc 100644
--- a/ui/Console.tsx
+++ b/ui/Console.tsx
@@ -7,7 +7,7 @@ export default function Console({ text, className }: { text: string; className?:
const [message, setMessage] = useState('');
const [typingIndex, setTypingIndex] = useState(0);
- const typingDelay = 400; // The delay between each character being typed, in milliseconds
+ const typingDelay = 200; // The delay between each character being typed, in milliseconds
useEffect(() => {
const intervalId = setInterval(() => {
diff --git a/ui/Leaderboard.tsx b/ui/Leaderboard.tsx
index 1c4c046..5365b85 100644
--- a/ui/Leaderboard.tsx
+++ b/ui/Leaderboard.tsx
@@ -1,19 +1,15 @@
'use client';
-import { useLeaderboard } from '@/lib/hooks/use-leaderboard';
-import { cn } from '@/lib/utils';
-import { useMemo, useState } from 'react';
-import AvatarComponent from './Avatar';
-import Select from './Select';
-import { type ScoreEvent } from '@/lib/leaderboard';
import useSWRSubscription, { type SWRSubscription } from 'swr/subscription';
-import { useGroups } from '@/lib/hooks/use-groups';
+
+import { type ScoreEvent } from '@/lib/leaderboard';
+import { cn } from '@/lib/utils';
+import Podium from '@/ui/events/podium/Podium';
const SCORE_COLORS = ['text-yellow-400', 'text-gray-400', 'text-orange-400'];
-export default function Leaderboard({ token }: { token: string }) {
- // const { data, isLoading } = useLeaderboard({ token });
-
+export default function Leaderboard() {
+ // TODO CHANGER CECI
const CHAPITRE_EVENT = 3;
const subscription: SWRSubscription = (key, { next }) => {
@@ -31,34 +27,17 @@ export default function Leaderboard({ token }: { token: string }) {
};
const { data } = useSWRSubscription(
- `wss://${process.env.NEXT_PUBLIC_API_URL?.split('//')[1]}/rleaderboard${CHAPITRE_EVENT}`,
+ `wss://${process.env.NEXT_PUBLIC_API_URL?.split('//')[1]}/rleaderboard/${CHAPITRE_EVENT}`,
subscription
);
- const [filter, setFilter] = useState('');
-
- let options = [] as { value: string; title: string }[];
-
- const { data: groups } = useGroups({ token });
-
- console.log(groups);
-
- if (groups) {
- options = groups
- .filter((group) => group.chapter === null)
- .map((group) => ({ value: group.name, title: group.name }))
- .filter((group, index, self) => self.findIndex((g) => g.value === group.value) === index)
- .sort((a, b) => a.title.localeCompare(b.title));
-
- options.unshift({ value: '', title: 'Tous' });
- }
-
- const filteredData = useMemo(() => {
- if (filter) {
- return data?.groups.filter((group) => group.name === filter);
- }
- return data;
- }, [data, filter]);
+ const scores = [data?.groups]
+ .flat()
+ .sort((a, b) => a!.rank - b!.rank)
+ .map((group, place) => ({
+ ...group,
+ place
+ }));
return (
@@ -67,23 +46,9 @@ export default function Leaderboard({ token }: { token: string }) {
Tableau des scores
Suivez la progression des élèves en direct
- {/* {(filteredData && (
-