From 6d2240976351efb75a46797853ceb8a7fb06c475 Mon Sep 17 00:00:00 2001 From: UnEpicier Date: Wed, 14 Feb 2024 22:19:55 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=84=20(leaderboard):=20Ability=20to=20?= =?UTF-8?q?replay=20a=20game=20or=20change=20game=20settings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 32 ++++ package.json | 2 + src/App.tsx | 8 +- src/assets/calendar.tsx | 92 ++++++++++++ src/assets/replay.tsx | 28 ++++ src/assets/settings.tsx | 20 +++ src/assets/timer.tsx | 24 +++ src/components/Leaderboard/leaderboard.tsx | 91 ++++++++---- src/components/Leaderboard/styles.scss | 163 +++++++++++++-------- src/contexts/gameState.ts | 2 +- 10 files changed, 366 insertions(+), 96 deletions(-) create mode 100644 src/assets/calendar.tsx create mode 100644 src/assets/replay.tsx create mode 100644 src/assets/settings.tsx create mode 100644 src/assets/timer.tsx diff --git a/package-lock.json b/package-lock.json index ca0065e..859ac23 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,10 +8,12 @@ "name": "demineur", "version": "0.0.0", "dependencies": { + "@types/localforage": "^0.0.34", "@types/node": "^20.11.16", "@types/react": "^18.2.53", "@types/react-dom": "^18.2.18", "commitizen": "^4.3.0", + "localforage": "^1.10.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", @@ -4137,6 +4139,15 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, + "node_modules/@types/localforage": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/@types/localforage/-/localforage-0.0.34.tgz", + "integrity": "sha512-tJxahnjm9dEI1X+hQSC5f2BSd/coZaqbIl1m3TCl0q9SVuC52XcXfV0XmoCU1+PmjyucuVITwoTnN8OlTbEXXA==", + "deprecated": "This is a stub types definition for localforage (https://github.com/localForage/localForage). localforage provides its own type definitions, so you don't need @types/localforage installed!", + "dependencies": { + "localforage": "*" + } + }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", @@ -9382,6 +9393,11 @@ "node": ">= 4" } }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + }, "node_modules/immer": { "version": "9.0.21", "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", @@ -12371,6 +12387,14 @@ "node": ">= 0.8.0" } }, + "node_modules/lie": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", + "integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==", + "dependencies": { + "immediate": "~3.0.5" + } + }, "node_modules/lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", @@ -12405,6 +12429,14 @@ "node": ">=8.9.0" } }, + "node_modules/localforage": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", + "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==", + "dependencies": { + "lie": "3.1.1" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", diff --git a/package.json b/package.json index cc84f8a..f438c58 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,12 @@ "eject": "react-scripts eject" }, "dependencies": { + "@types/localforage": "^0.0.34", "@types/node": "^20.11.16", "@types/react": "^18.2.53", "@types/react-dom": "^18.2.18", "commitizen": "^4.3.0", + "localforage": "^1.10.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", diff --git a/src/App.tsx b/src/App.tsx index 9c5a819..3943e4b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,18 +12,18 @@ import { gameStateAtom } from './contexts/gameState'; // --------------------------------------------------------------------------------------------------------------------- // --------------------------------------------------- Components ------------------------------------------------------ -import Grid from './components/Grid/Grid'; +import Home from './components/Home/Home'; import Timer from './components/Stats/Timer/Timer'; import MinesCounter from './components/Stats/MinesCounter/MinesCounter'; +import Grid from './components/Grid/Grid'; import Help from './components/Help/Help'; +import LeaderBoard from './components/Leaderboard/Leaderboard'; // --------------------------------------------------------------------------------------------------------------------- // ----------------------------------------------------- Styles -------------------------------------------------------- import Logo from './assets/logo'; -import './App.scss'; import Question from './assets/question'; -import Home from './components/Home/Home'; -import LeaderBoard from './components/Leaderboard/leaderboard'; +import './App.scss'; // --------------------------------------------------------------------------------------------------------------------- const App = () => { diff --git a/src/assets/calendar.tsx b/src/assets/calendar.tsx new file mode 100644 index 0000000..e7f4258 --- /dev/null +++ b/src/assets/calendar.tsx @@ -0,0 +1,92 @@ +const Calendar = (props: any) => { + return ( + + + + + + + + + + + + + + + ); +}; + +export default Calendar; diff --git a/src/assets/replay.tsx b/src/assets/replay.tsx new file mode 100644 index 0000000..43eecd1 --- /dev/null +++ b/src/assets/replay.tsx @@ -0,0 +1,28 @@ +const Replay = (props: any) => { + return ( + + + + + ); +}; + +export default Replay; diff --git a/src/assets/settings.tsx b/src/assets/settings.tsx new file mode 100644 index 0000000..cc39adf --- /dev/null +++ b/src/assets/settings.tsx @@ -0,0 +1,20 @@ +const Settings = (props: any) => { + return ( + + + + ); +}; + +export default Settings; diff --git a/src/assets/timer.tsx b/src/assets/timer.tsx new file mode 100644 index 0000000..6dbdbe6 --- /dev/null +++ b/src/assets/timer.tsx @@ -0,0 +1,24 @@ +const Timer = (props: any) => { + return ( + + + + + ); +}; + +export default Timer; diff --git a/src/components/Leaderboard/leaderboard.tsx b/src/components/Leaderboard/leaderboard.tsx index 881697a..3b0c1a1 100644 --- a/src/components/Leaderboard/leaderboard.tsx +++ b/src/components/Leaderboard/leaderboard.tsx @@ -1,50 +1,83 @@ -import React from 'react'; +import { useRecoilState } from 'recoil'; +import CalendarIcon from '../../assets/calendar'; +import Replay from '../../assets/replay'; +import Settings from '../../assets/settings'; +import TimerIcon from '../../assets/timer'; import './styles.scss'; +import { gameStateAtom } from '../../contexts/gameState'; const arrayBoard = [ - { date: '12/06/2014', time: '1.06' }, - { date: '12/06/2014', time: '1.06' }, - { date: '12/06/2014', time: '1.06' }, - { date: '12/06/2014', time: '1.06' }, - { date: '12/06/2014', time: '1.06' }, - { date: '12/06/2014', time: '1.06' }, - { date: '12/06/2014', time: '1.06' }, - { date: '12/06/2014', time: '1.06' }, - { date: '12/06/2014', time: '1.06' }, - { date: '12/06/2014', time: '1.06' }, - { date: '12/06/2014', time: '1.06' }, - { date: '12/06/2014', time: '1.06' }, - { date: '12/06/2014', time: '1.06' }, - { date: '12/06/2014', time: '1.06' }, - { date: '12/06/2014', time: '1.06' }, + { date: '12/06/2014', time: '1m 26s' }, + { date: '12/06/2014', time: '1m 26s' }, + { date: '12/06/2014', time: '1m 26s' }, + { date: '12/06/2014', time: '1m 26s' }, + { date: '12/06/2014', time: '1m 26s' }, + { date: '12/06/2014', time: '1m 26s' }, + { date: '12/06/2014', time: '1m 26s' }, + { date: '12/06/2014', time: '1m 26s' }, + { date: '12/06/2014', time: '1m 26s' }, + { date: '12/06/2014', time: '1m 26s' }, + { date: '12/06/2014', time: '1m 26s' }, + { date: '12/06/2014', time: '1m 26s' }, + { date: '12/06/2014', time: '1m 26s' }, + { date: '12/06/2014', time: '1m 26s' }, + { date: '12/06/2014', time: '1m 26s' }, ]; const LeaderBoard = () => { + const [, setGameState] = useRecoilState(gameStateAtom); + return ( -
-

Time Leaderboard

-
-
-

Day

-

Time

+ <> +

Time Leaderboard

+ +
+
+

#

+

+ + Date +

+

+ + Time +

-
+
{arrayBoard.map((item, index) => { return (
-

{item.date}

-

{item.time}

+ {index + 1} + {item.date} + {item.time}
); })} - ;
-
+ +
+ + + +
+ ); }; diff --git a/src/components/Leaderboard/styles.scss b/src/components/Leaderboard/styles.scss index e45fa8c..8d6bd73 100644 --- a/src/components/Leaderboard/styles.scss +++ b/src/components/Leaderboard/styles.scss @@ -1,72 +1,111 @@ -.boardContainer { +.title { + margin-bottom: 40px; + font-size: 2rem; + font-weight: 600; + color: #ffffff; +} + +.board { display: flex; flex-direction: column; - align-items: center; - justify-content: center; - height: 100vh; - width: 100vw; + width: 95svw; + max-width: 450px; + border-radius: 5px; + background-color: #fff; + overflow: hidden; + + & > .header { + display: grid; + grid-template-columns: 1em repeat(2, 1fr); + gap: 30px; + padding: 15px 20px; + background-color: #333; + + & > * { + display: flex; + flex-wrap: nowrap; + align-items: center; + gap: 10px; + font-size: 1.3em; + font-weight: 400; + color: #fff; + + & > svg { + height: 1.3em; + } + + &:last-child { + justify-content: flex-end; + } + } + } + + & > .scoresContainer { + height: 100%; + max-height: 400px; + overflow-y: auto; + + & > .score { + display: grid; + grid-template-columns: 1em repeat(2, 1fr); + gap: 30px; + padding: 10px 20px; + background-color: #e1e1e1; + color: #333; + + & > * { + &:first-child { + opacity: 0.5; + } + + &:last-child { + justify-self: end; + font-weight: 600; + } + } + + &:nth-child(2n) { + background-color: #ffffff; + } + } + } } -.titleBoard { - font-size: 1.5rem; - margin-bottom: 1rem; - font-weight: bold; -} +.controls { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 100px; + width: 100%; -.completeBoard { - display: flex; - flex-direction: column; - gap: 1em; - border: 2px solid #fff; - border-radius: 5px; - padding: 15px; - background-color: #fff; - width: 100%; - max-width: 400px; - -} + & > .controlButton { + display: flex; + flex-wrap: nowrap; + justify-content: center; + align-items: center; + gap: 10px; + padding: 10px 20px; + border: none; + border-radius: 5px; + font-size: 16px; + font-weight: 600; + transition: filter 0.3s ease; + color: #fff; + cursor: pointer; -.containerLittle { - overflow: scroll; - height: 100%; - max-height: 350px; - gap: 1em; -} + &:hover { + filter: brightness(1.1); + } -.lineInfo { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 10px; - border: 1.5px solid #fff; - border-radius: 3px; - padding: 10px; - background-color: #333; - color: #fff; - font-weight: 400; -} + &.home { + background-color: #ca5940; + } -.infoDate { - margin-left: 10px; -} + &.replay { + background-color: #f39440; + } -.infoScore { - text-align: right; - margin-right: 10px; -} - -.lineBoard { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 10px; - border: 1.5px solid #fff; - margin-bottom: 10px; - border-radius: 3px; - padding: 5px; - background-color: #e1e1e1; - color: #333; - font-weight: 400; -} - -.blockScore { - text-align: right; + & > svg { + width: 20px; + } + } } diff --git a/src/contexts/gameState.ts b/src/contexts/gameState.ts index 20ca51b..7e28bf9 100644 --- a/src/contexts/gameState.ts +++ b/src/contexts/gameState.ts @@ -3,7 +3,7 @@ import { atom } from 'recoil'; export const gameStateAtom = atom({ key: 'gameState', default: { - status: 'settings', + status: 'board', difficulty: 'begginer', gridSize: 20, bombs: 0,