From ffa6468b708307e4898c1b92da67dff2fa76b6e6 Mon Sep 17 00:00:00 2001 From: UnEpicier Date: Mon, 19 Feb 2024 08:46:05 +0100 Subject: [PATCH] :sparkles: Add ability to delete all leaderboard --- src/assets/difficulty.tsx | 72 ++++++++++++++++++++++ src/assets/size.tsx | 20 ++++++ src/components/Leaderboard/leaderboard.tsx | 63 ++++++++++++++----- src/components/Leaderboard/styles.scss | 21 ++++--- src/utils/generics.ts | 7 +++ 5 files changed, 161 insertions(+), 22 deletions(-) create mode 100644 src/assets/difficulty.tsx create mode 100644 src/assets/size.tsx diff --git a/src/assets/difficulty.tsx b/src/assets/difficulty.tsx new file mode 100644 index 0000000..69fd602 --- /dev/null +++ b/src/assets/difficulty.tsx @@ -0,0 +1,72 @@ +const Difficulty = (props: any) => { + return ( + + + + + + + + ); +}; + +export default Difficulty; diff --git a/src/assets/size.tsx b/src/assets/size.tsx new file mode 100644 index 0000000..c12268a --- /dev/null +++ b/src/assets/size.tsx @@ -0,0 +1,20 @@ +const Size = (props: any) => { + return ( + + + + ); +}; + +export default Size; diff --git a/src/components/Leaderboard/leaderboard.tsx b/src/components/Leaderboard/leaderboard.tsx index 0f34c55..e5cee4a 100644 --- a/src/components/Leaderboard/leaderboard.tsx +++ b/src/components/Leaderboard/leaderboard.tsx @@ -3,7 +3,7 @@ // --------------------------------------------------------------------------------------------------------------------- // ------------------------------------------------------ React -------------------------------------------------------- -import { useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; // --------------------------------------------------------------------------------------------------------------------- // ----------------------------------------------- Context & Stockage -------------------------------------------------- @@ -12,8 +12,9 @@ import { useRecoilState } from 'recoil'; import { gameStateAtom } from '../../contexts/gameState'; // --------------------------------------------------------------------------------------------------------------------- -// ------------------------------------------------------ Types -------------------------------------------------------- -import { LeaderBoardItem } from '../../types/game'; +// -------------------------------------------------- Utils & Types ---------------------------------------------------- +import { Difficulty, LeaderBoardItem } from '../../types/game'; +import { getDifficultyLabel } from '../../utils/generics'; // --------------------------------------------------------------------------------------------------------------------- // ----------------------------------------------------- Assets -------------------------------------------------------- @@ -22,6 +23,8 @@ import Replay from '../../assets/replay'; import Settings from '../../assets/settings'; import TimerIcon from '../../assets/timer'; import Trash from '../../assets/trash'; +import DifficultyIcon from '../../assets/difficulty'; +import Size from '../../assets/size'; import './styles.scss'; // --------------------------------------------------------------------------------------------------------------------- @@ -37,18 +40,30 @@ const LeaderBoard = () => { const [gameState, setGameState] = useRecoilState(gameStateAtom); const [data, setData] = useState([]); + const [, updateLeaderboard] = useState({}); + const forceUpdate = useCallback(() => updateLeaderboard({}), []); + + const getData = async () => { + const storeData = await store.getItem(`${gameState.difficulty}:${gameState.gridSize}`); + + setData(storeData || []); + }; + useEffect(() => { - const getData = async () => { - const storeData = await store.getItem(`${gameState.difficulty}:${gameState.gridSize}`); - - setData(storeData || []); - }; - if (data.length === 0) { getData(); } }, [data.length]); + const clearAllLeaderboards = async () => { + const keys = await store.keys(); + + for (let i = 0; i < keys.length; i++) { + await store.removeItem(keys[i]); + } + getData(); + }; + return ( <>

Time Leaderboard

@@ -60,6 +75,14 @@ const LeaderBoard = () => { Date

+

+ + Difficulté +

+

+ + Taille +

Time @@ -75,6 +98,8 @@ const LeaderBoard = () => { > {index + 1} {item.date} + {getDifficultyLabel(gameState.difficulty as Difficulty)} + {gameState.gridSize} {item.time} ); @@ -91,11 +116,19 @@ const LeaderBoard = () => { Paramètres + + diff --git a/src/components/Leaderboard/styles.scss b/src/components/Leaderboard/styles.scss index 5c700b2..6475ae2 100644 --- a/src/components/Leaderboard/styles.scss +++ b/src/components/Leaderboard/styles.scss @@ -9,14 +9,14 @@ display: flex; flex-direction: column; width: 95svw; - max-width: 500px; + max-width: 600px; border-radius: 5px; background-color: #fff; overflow: hidden; & > .header { display: grid; - grid-template-columns: 1em repeat(2, 1fr); + grid-template-columns: 1em 1fr 1fr 0.7fr 1fr; gap: 30px; padding: 15px 20px; background-color: #333; @@ -47,7 +47,9 @@ & > .score { display: grid; - grid-template-columns: 1em repeat(2, 1fr); + grid-template-columns: 1em 1fr 1fr 0.7fr 1fr; + align-items: center; + justify-content: center; gap: 30px; padding: 10px 20px; background-color: #e1e1e1; @@ -59,7 +61,7 @@ } &:last-child { - justify-self: end; + text-align: right; font-weight: 600; } } @@ -73,7 +75,8 @@ .controls { display: grid; - grid-template-columns: repeat(3, 1fr); + grid-template-columns: repeat(2, 1fr); + grid-template-rows: repeat(2, 1fr); gap: 10px; width: 100%; @@ -100,12 +103,16 @@ background-color: #f39440; } + &.replay { + background-color: #f39440; + } + &.clear { background-color: #ca5940; } - &.replay { - background-color: #f39440; + &.clearAll { + background-color: hsl(0, 57%, 52%); } & > svg { diff --git a/src/utils/generics.ts b/src/utils/generics.ts index c2f0488..b6af4d0 100644 --- a/src/utils/generics.ts +++ b/src/utils/generics.ts @@ -44,3 +44,10 @@ export const saveToLocalStorage = async (time: string, difficulty: Difficulty, g await store.setItem(`${difficulty}:${gridSize}`, leaderboard); }; + +export const getDifficultyLabel = (difficulty: Difficulty): string => { + if (difficulty == 'beginner') return 'Débutant'; + if (difficulty == 'intermediate') return 'Intermédiaire'; + if (difficulty == 'expert') return 'Expert'; + return difficulty; +};