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;
+};