From cb10e7565a50ed020e5c32fda746604d58c5241b Mon Sep 17 00:00:00 2001 From: Fantom52r Date: Thu, 8 Aug 2024 15:30:25 +0300 Subject: [PATCH 01/10] hw-1.END --- .eslintrc.json | 7 ++- docs/mvp-spec.md | 7 ++- lefthook.yml | 1 + package-lock.json | 14 +++++ package.json | 1 + src/components/Cards/Cards.jsx | 29 +++++++++- src/context/Context.jsx | 9 +++ src/index.js | 5 +- src/pages/SelectLevelPage/SelectLevelPage.jsx | 57 +++++++++++++------ .../SelectLevelPage.module.css | 28 +++++++++ 10 files changed, 135 insertions(+), 23 deletions(-) create mode 100644 src/context/Context.jsx diff --git a/.eslintrc.json b/.eslintrc.json index e37e1e072..13018ddc0 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -3,7 +3,12 @@ "plugins": ["prettier"], "rules": { "camelcase": ["error", { "properties": "never" }], - "prettier/prettier": "error", + "prettier/prettier": [ + "error", + { + "endOfLine": "auto" + } +], "eqeqeq": ["error", "always"], "no-unused-vars": ["error"] } diff --git a/docs/mvp-spec.md b/docs/mvp-spec.md index fab47685e..e083d7788 100644 --- a/docs/mvp-spec.md +++ b/docs/mvp-spec.md @@ -14,9 +14,10 @@ Количество карточек для каждого уровня сложности можете назначать и свои или выбрать готовый пресет. Предлагаем следующее пресеты: - - Легкий уровень - 6 карточек (3 пары) - - Средний уровень - 12 карточек (6 пар) - - Сложный уровень - 18 карточек (9 пар) + +- Легкий уровень - 6 карточек (3 пары) +- Средний уровень - 12 карточек (6 пар) +- Сложный уровень - 18 карточек (9 пар) Как только уровень сложности выбран, игроку показывается на игровой поле. diff --git a/lefthook.yml b/lefthook.yml index 87752f862..3a6272ee7 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -18,3 +18,4 @@ pre-commit: eslint: glob: "*.{js,jsx}" run: npm run lint +"prettier/prettier": ["error", { "endOfLine": "auto" }] diff --git a/package-lock.json b/package-lock.json index edaf5083f..c20f8c388 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "classnames": "^2.3.2", + "clsx": "^2.1.1", "gh-pages": "^6.0.0", "lodash": "^4.17.21", "react": "^18.2.0", @@ -6111,6 +6112,14 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -22658,6 +22667,11 @@ "wrap-ansi": "^7.0.0" } }, + "clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==" + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", diff --git a/package.json b/package.json index e9b7a089e..f9e347ea6 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "classnames": "^2.3.2", + "clsx": "^2.1.1", "gh-pages": "^6.0.0", "lodash": "^4.17.21", "react": "^18.2.0", diff --git a/src/components/Cards/Cards.jsx b/src/components/Cards/Cards.jsx index 7526a56c8..23b2125a4 100644 --- a/src/components/Cards/Cards.jsx +++ b/src/components/Cards/Cards.jsx @@ -1,10 +1,11 @@ import { shuffle } from "lodash"; -import { useEffect, useState } from "react"; +import { useContext, useEffect, useState } from "react"; import { generateDeck } from "../../utils/cards"; import styles from "./Cards.module.css"; import { EndGameModal } from "../../components/EndGameModal/EndGameModal"; import { Button } from "../../components/Button/Button"; import { Card } from "../../components/Card/Card"; +import { EasyContext } from "../../context/Context"; // Игра закончилась const STATUS_LOST = "STATUS_LOST"; @@ -41,6 +42,7 @@ function getTimerValue(startDate, endDate) { * previewSeconds - сколько секунд пользователь будет видеть все карты открытыми до начала игры */ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { + const { isEasyMode, tries, setTries } = useContext(EasyContext); // В cards лежит игровое поле - массив карт и их состояние открыта\закрыта const [cards, setCards] = useState([]); // Текущий статус игры @@ -73,6 +75,9 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { setGameEndDate(null); setTimer(getTimerValue(null, null)); setStatus(STATUS_PREVIEW); + if (isEasyMode) { + setTries(3); + } } /** @@ -127,6 +132,27 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { // "Игрок проиграл", т.к на поле есть две открытые карты без пары if (playerLost) { + if (isEasyMode) { + setTries(tries - 1); + if (tries === 1) { + finishGame(STATUS_LOST); + } else { + const newCards = cards.map(c => { + if (openCardsWithoutPair.find(card => card.id === c.id)) { + return { + ...c, + open: false, + }; + } + return c; + }); + + setTimeout(() => { + setCards(newCards); + }, 500); + } + return; + } finishGame(STATUS_LOST); return; } @@ -196,6 +222,7 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { )} {status === STATUS_IN_PROGRESS ? : null} + {isEasyMode && Колличество жизней: {tries}}
diff --git a/src/context/Context.jsx b/src/context/Context.jsx new file mode 100644 index 000000000..ff14509f5 --- /dev/null +++ b/src/context/Context.jsx @@ -0,0 +1,9 @@ +import { createContext, useState } from "react"; + +export const EasyContext = createContext(false); + +export const EasyProvider = ({ children }) => { + const [tries, setTries] = useState(3); + const [isEasyMode, setEasyMode] = useState(false); + return {children}; +}; diff --git a/src/index.js b/src/index.js index f689c5f0b..c955c852f 100644 --- a/src/index.js +++ b/src/index.js @@ -3,10 +3,13 @@ import ReactDOM from "react-dom/client"; import "./index.css"; import { RouterProvider } from "react-router-dom"; import { router } from "./router"; +import { EasyProvider } from "./context/Context"; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( - + + + , ); diff --git a/src/pages/SelectLevelPage/SelectLevelPage.jsx b/src/pages/SelectLevelPage/SelectLevelPage.jsx index 758942e51..1a05b05b5 100644 --- a/src/pages/SelectLevelPage/SelectLevelPage.jsx +++ b/src/pages/SelectLevelPage/SelectLevelPage.jsx @@ -1,28 +1,51 @@ -import { Link } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import styles from "./SelectLevelPage.module.css"; - +import { useContext, useState } from "react"; +import { EasyContext } from "../../context/Context"; +import clsx from "clsx"; +const levels = [ + { + level: 1, + pairs: 3, + }, + { + level: 2, + pairs: 6, + }, + { + level: 3, + pairs: 9, + }, +]; export function SelectLevelPage() { + const { isEasyMode, setEasyMode } = useContext(EasyContext); + const [level, setLevel] = useState(3); + const navigate = useNavigate(); + function onClick(value) { + setLevel(value); + } + function onStart() { + navigate(`/game/${level}`); + } return (

Выбери сложность

    -
  • - - 1 - -
  • -
  • - - 2 - -
  • -
  • - - 3 - -
  • + {levels.map(l => ( +
  • onClick(l.pairs)} className={clsx(styles.level, { [styles.active]: l.pairs === level })}> +
    {l.level}
    +
  • + ))}
+ + + +
); diff --git a/src/pages/SelectLevelPage/SelectLevelPage.module.css b/src/pages/SelectLevelPage/SelectLevelPage.module.css index 390ac0def..16bf415c6 100644 --- a/src/pages/SelectLevelPage/SelectLevelPage.module.css +++ b/src/pages/SelectLevelPage/SelectLevelPage.module.css @@ -62,3 +62,31 @@ .levelLink:visited { color: #0080c1; } + +.active { + outline: 4px dotted teal +} + +.checkbox { + width: 20px; + height: 20px; + border-radius: 5px; + border: 1px dotted teal; + background-color: white; +position: relative; +} +.label { + display: flex; + gap:10px; +} +.label input { +appearance: none; +} +.label input:checked + div::after{ +content:"\2714"; +display: block; +position: absolute; +top: 50%; +left: 50%; +transform:translate(-50%,-50%) +} From a1fb614c2f71374c703cc139fb2da32c3019d75d Mon Sep 17 00:00:00 2001 From: Fantom52r Date: Thu, 8 Aug 2024 16:34:07 +0300 Subject: [PATCH 02/10] h2-w . Backup --- src/API/leaders.js | 17 ++++++++ src/components/EndGameModal/EndGameModal.jsx | 8 +++- src/pages/LeaderBoard/LeaderBoard.jsx | 42 +++++++++++++++++++ src/pages/LeaderBoard/LeaderBoard.module.css | 4 ++ src/pages/SelectLevelPage/SelectLevelPage.jsx | 6 ++- src/router.js | 5 +++ 6 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 src/API/leaders.js create mode 100644 src/pages/LeaderBoard/LeaderBoard.jsx create mode 100644 src/pages/LeaderBoard/LeaderBoard.module.css diff --git a/src/API/leaders.js b/src/API/leaders.js new file mode 100644 index 000000000..200a65256 --- /dev/null +++ b/src/API/leaders.js @@ -0,0 +1,17 @@ +export async function getLeaders() { + try { + const response = await fetch("https://wedev-api.sky.pro/api/leaderboard", { + method: "GET", + }); + const isResponseOk = response.ok; + const result = await response.json(); + if (isResponseOk) { + return result.leaders; + } else { + throw new Error(result.error); + } + } catch (error) { + throw new Error(error.message); + } +} +// Написать функцию postNewLeader- будет отправлять на сервер новый результат diff --git a/src/components/EndGameModal/EndGameModal.jsx b/src/components/EndGameModal/EndGameModal.jsx index 722394833..4423a65a2 100644 --- a/src/components/EndGameModal/EndGameModal.jsx +++ b/src/components/EndGameModal/EndGameModal.jsx @@ -4,6 +4,7 @@ import { Button } from "../Button/Button"; import deadImageUrl from "./images/dead.png"; import celebrationImageUrl from "./images/celebration.png"; +import { Link } from "react-router-dom"; export function EndGameModal({ isWon, gameDurationSeconds, gameDurationMinutes, onClick }) { const title = isWon ? "Вы победили!" : "Вы проиграли!"; @@ -11,7 +12,11 @@ export function EndGameModal({ isWon, gameDurationSeconds, gameDurationMinutes, const imgSrc = isWon ? celebrationImageUrl : deadImageUrl; const imgAlt = isWon ? "celebration emodji" : "dead emodji"; - +// Добваить инпут Введения имени и кнопку по которой отправляется результат в лидерборд +// 'этот компонент принимает еще один пропс которы называется isLeader и он показывает нужно отправлять результат или нет . +// нужно проверять играешь ли ты на третьем уровне переменная PairsCount +// валидировать пустые поля и пробелы с помощью метода trim +// изменить переменную title проверять перед isWon переменную isleader если она тру то в title должна быть строка - вы попали на Лидерборд. return (
{imgAlt} @@ -22,6 +27,7 @@ export function EndGameModal({ isWon, gameDurationSeconds, gameDurationMinutes,
+ Перейти к Лидерборду
); } diff --git a/src/pages/LeaderBoard/LeaderBoard.jsx b/src/pages/LeaderBoard/LeaderBoard.jsx new file mode 100644 index 000000000..14080b0df --- /dev/null +++ b/src/pages/LeaderBoard/LeaderBoard.jsx @@ -0,0 +1,42 @@ +import React, { useEffect, useState } from "react"; +import { Button } from "../../components/Button/Button"; +import styles from "./LeaderBoard.module.css"; +import { getLeaders } from "../../API/leaders"; +import { Link } from "react-router-dom"; + +const LeaderBoard = () => { + const [leaders, setLeaders] = useState([]); + useEffect(() => { + getLeaders().then(data => { + setLeaders(data.sort((a, b) => a - b).splice(0, 10)); + }); + }, []); + return ( +
+
+

Лидерборд

+ + + +
+
+
    +
  • +
    Позиция
    +
    Пользователь
    +
    Время
    +
  • + {leaders.map((l, index) => ( +
  • +
    {index + 1}
    +
    {l.name}
    +
    {l.time}
    +
  • + ))} +
+
+
+ ); +}; + +export default LeaderBoard; diff --git a/src/pages/LeaderBoard/LeaderBoard.module.css b/src/pages/LeaderBoard/LeaderBoard.module.css new file mode 100644 index 000000000..db3eb547f --- /dev/null +++ b/src/pages/LeaderBoard/LeaderBoard.module.css @@ -0,0 +1,4 @@ +.top { + display: flex; + justify-content: space-between; +} \ No newline at end of file diff --git a/src/pages/SelectLevelPage/SelectLevelPage.jsx b/src/pages/SelectLevelPage/SelectLevelPage.jsx index 1a05b05b5..ea703e4a1 100644 --- a/src/pages/SelectLevelPage/SelectLevelPage.jsx +++ b/src/pages/SelectLevelPage/SelectLevelPage.jsx @@ -1,8 +1,9 @@ -import { useNavigate } from "react-router-dom"; +import { Link, useNavigate } from "react-router-dom"; import styles from "./SelectLevelPage.module.css"; import { useContext, useState } from "react"; import { EasyContext } from "../../context/Context"; import clsx from "clsx"; +import { Button } from "../../components/Button/Button"; const levels = [ { level: 1, @@ -45,7 +46,8 @@ export function SelectLevelPage() {
- + + Перейти к Лидерборду ); diff --git a/src/router.js b/src/router.js index da6e94b51..dee6ea7be 100644 --- a/src/router.js +++ b/src/router.js @@ -1,6 +1,7 @@ import { createBrowserRouter } from "react-router-dom"; import { GamePage } from "./pages/GamePage/GamePage"; import { SelectLevelPage } from "./pages/SelectLevelPage/SelectLevelPage"; +import LeaderBoard from "./pages/LeaderBoard/LeaderBoard"; export const router = createBrowserRouter( [ @@ -12,6 +13,10 @@ export const router = createBrowserRouter( path: "/game/:pairsCount", element: , }, + { + path: "/leaderboard", + element: , + }, ], /** * basename нужен для корректной работы в gh pages From 297ff529fa3b8f1ff7f04a327a309bb9d4146036 Mon Sep 17 00:00:00 2001 From: Fantom52r Date: Wed, 14 Aug 2024 00:38:58 +0300 Subject: [PATCH 03/10] HW/2-check --- src/components/EndGameModal/EndGameModal.jsx | 10 ++-- src/pages/LeaderBoard/LeaderBoard.jsx | 8 ++-- src/pages/LeaderBoard/LeaderBoard.module.css | 15 +++++- src/pages/SelectLevelPage/SelectLevelPage.jsx | 8 ++-- .../SelectLevelPage.module.css | 47 ++++++++++++++----- 5 files changed, 63 insertions(+), 25 deletions(-) diff --git a/src/components/EndGameModal/EndGameModal.jsx b/src/components/EndGameModal/EndGameModal.jsx index 4423a65a2..7a8875d0a 100644 --- a/src/components/EndGameModal/EndGameModal.jsx +++ b/src/components/EndGameModal/EndGameModal.jsx @@ -12,11 +12,11 @@ export function EndGameModal({ isWon, gameDurationSeconds, gameDurationMinutes, const imgSrc = isWon ? celebrationImageUrl : deadImageUrl; const imgAlt = isWon ? "celebration emodji" : "dead emodji"; -// Добваить инпут Введения имени и кнопку по которой отправляется результат в лидерборд -// 'этот компонент принимает еще один пропс которы называется isLeader и он показывает нужно отправлять результат или нет . -// нужно проверять играешь ли ты на третьем уровне переменная PairsCount -// валидировать пустые поля и пробелы с помощью метода trim -// изменить переменную title проверять перед isWon переменную isleader если она тру то в title должна быть строка - вы попали на Лидерборд. + // Добваить инпут Введения имени и кнопку по которой отправляется результат в лидерборд + // 'этот компонент принимает еще один пропс которы называется isLeader и он показывает нужно отправлять результат или нет . + // нужно проверять играешь ли ты на третьем уровне переменная PairsCount + // валидировать пустые поля и пробелы с помощью метода trim + // изменить переменную title проверять перед isWon переменную isleader если она тру то в title должна быть строка - вы попали на Лидерборд. return (
{imgAlt} diff --git a/src/pages/LeaderBoard/LeaderBoard.jsx b/src/pages/LeaderBoard/LeaderBoard.jsx index 14080b0df..a2c16af23 100644 --- a/src/pages/LeaderBoard/LeaderBoard.jsx +++ b/src/pages/LeaderBoard/LeaderBoard.jsx @@ -22,9 +22,11 @@ const LeaderBoard = () => {
  • -
    Позиция
    -
    Пользователь
    -
    Время
    +
    +

    Позиция

    +

    Пользователь

    +

    Время

    +
  • {leaders.map((l, index) => (
  • diff --git a/src/pages/LeaderBoard/LeaderBoard.module.css b/src/pages/LeaderBoard/LeaderBoard.module.css index db3eb547f..71d453b33 100644 --- a/src/pages/LeaderBoard/LeaderBoard.module.css +++ b/src/pages/LeaderBoard/LeaderBoard.module.css @@ -1,4 +1,15 @@ .top { - display: flex; - justify-content: space-between; + display: flex; + justify-content: space-between; +} + + +.leaders { + width: Hug (904px)px; +height: Hug (32px)px; +top: 237px; +left: 60px; +gap: 66px; +opacity: 0px; +color: #FFFFFF; } \ No newline at end of file diff --git a/src/pages/SelectLevelPage/SelectLevelPage.jsx b/src/pages/SelectLevelPage/SelectLevelPage.jsx index ea703e4a1..10f4f451d 100644 --- a/src/pages/SelectLevelPage/SelectLevelPage.jsx +++ b/src/pages/SelectLevelPage/SelectLevelPage.jsx @@ -41,13 +41,15 @@ export function SelectLevelPage() {
- - Перейти к Лидерборду + + + Перейти к Лидерборду +
); diff --git a/src/pages/SelectLevelPage/SelectLevelPage.module.css b/src/pages/SelectLevelPage/SelectLevelPage.module.css index 16bf415c6..2475bdfa0 100644 --- a/src/pages/SelectLevelPage/SelectLevelPage.module.css +++ b/src/pages/SelectLevelPage/SelectLevelPage.module.css @@ -64,7 +64,7 @@ } .active { - outline: 4px dotted teal + outline: 4px dotted teal; } .checkbox { @@ -73,20 +73,43 @@ border-radius: 5px; border: 1px dotted teal; background-color: white; -position: relative; + position: relative; + color: #7ac100; } .label { display: flex; - gap:10px; + gap: 5px; + flex-direction: row-reverse; + padding-bottom: 20px; + font-family: Roboto; + font-size: 24px; + font-weight: 400; + line-height: 32px; + text-align: center; +} +.label input { + appearance: none; } -.label input { -appearance: none; +.label input:checked + div::after { + content: "\2714"; + display: block; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); } -.label input:checked + div::after{ -content:"\2714"; -display: block; -position: absolute; -top: 50%; -left: 50%; -transform:translate(-50%,-50%) +.Link { + padding-top: 20px; + width: 192px; + height: 32px; + top: 571px; + left: 417px; + gap: 0px; + opacity: 0px; + font-family: Roboto; + font-size: 18px; + font-weight: 400; + line-height: 32px; + text-align: left; + color: #004980; } From 1c423c6c327e8cc9e4a411d3d78e6eaae93fc35d Mon Sep 17 00:00:00 2001 From: Fantom52r Date: Thu, 5 Sep 2024 18:22:37 +0300 Subject: [PATCH 04/10] HW-commit.05.09.2024 --- src/index.css | 11 ++++++ src/pages/LeaderBoard/LeaderBoard.jsx | 27 ++++++++------- src/pages/LeaderBoard/LeaderBoard.module.css | 35 +++++++++++++++----- 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/src/index.css b/src/index.css index 78f0d3a2b..38e57fd1c 100644 --- a/src/index.css +++ b/src/index.css @@ -1,3 +1,9 @@ +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + html { margin: 0; } @@ -35,3 +41,8 @@ ol { font-weight: 400; font-style: normal; } + +ul { + list-style-type: none; +} + diff --git a/src/pages/LeaderBoard/LeaderBoard.jsx b/src/pages/LeaderBoard/LeaderBoard.jsx index a2c16af23..703497f9b 100644 --- a/src/pages/LeaderBoard/LeaderBoard.jsx +++ b/src/pages/LeaderBoard/LeaderBoard.jsx @@ -8,31 +8,34 @@ const LeaderBoard = () => { const [leaders, setLeaders] = useState([]); useEffect(() => { getLeaders().then(data => { - setLeaders(data.sort((a, b) => a - b).splice(0, 10)); + setLeaders(data.sort((a, b) => a - b)); }); }, []); + console.log(leaders); return ( -
-
+
+

Лидерборд

-
    +
    • -
      -

      Позиция

      -

      Пользователь

      -

      Время

      -
      +
        +
      • Позиция
      • +
      • Пользователь
      • +
      • Время
      • +
    • {leaders.map((l, index) => (
    • -
      {index + 1}
      -
      {l.name}
      -
      {l.time}
      +
        +
      • {index + 1}
      • +
      • {l.name}
      • +
      • {l.time}
      • +
    • ))}
    diff --git a/src/pages/LeaderBoard/LeaderBoard.module.css b/src/pages/LeaderBoard/LeaderBoard.module.css index 71d453b33..4a6f40be5 100644 --- a/src/pages/LeaderBoard/LeaderBoard.module.css +++ b/src/pages/LeaderBoard/LeaderBoard.module.css @@ -1,15 +1,32 @@ -.top { +.leaderBoardBlock { + display: flex; + flex-direction: column; + align-items: center; + font-family: 'roboto'; +} + +.leaderBoarHeader { display: flex; justify-content: space-between; + color: white; + width: 944px; } +.players { + display: flex; + flex-direction: column; + align-items: center; +} .leaders { - width: Hug (904px)px; -height: Hug (32px)px; -top: 237px; -left: 60px; -gap: 66px; -opacity: 0px; -color: #FFFFFF; -} \ No newline at end of file + display: flex; + align-items: center; + list-style-type: none; + width: 944px; + height: 64px; + background-color: #ffffff; + border-radius: 12px; + color: #999999; + padding: 22px 16px; + font-size: 24px; +} From 4cca15e73e57963d42e6a0adf615969496b5fca3 Mon Sep 17 00:00:00 2001 From: Fantom52r Date: Sun, 8 Sep 2024 16:17:33 +0300 Subject: [PATCH 05/10] HW.leaderBoard/done --- src/pages/LeaderBoard/LeaderBoard.jsx | 27 +++++-------- src/pages/LeaderBoard/LeaderBoard.module.css | 42 ++++++++++++++++---- 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/src/pages/LeaderBoard/LeaderBoard.jsx b/src/pages/LeaderBoard/LeaderBoard.jsx index 703497f9b..77719d10e 100644 --- a/src/pages/LeaderBoard/LeaderBoard.jsx +++ b/src/pages/LeaderBoard/LeaderBoard.jsx @@ -4,37 +4,30 @@ import styles from "./LeaderBoard.module.css"; import { getLeaders } from "../../API/leaders"; import { Link } from "react-router-dom"; +// const COLUMNS_NAME = ["Позиция","Пользователь","Время"] const LeaderBoard = () => { - const [leaders, setLeaders] = useState([]); + const [leaders, setLeaders] = useState([{ position: "Позиция", name: "Пользователь", time: "Время" }]); useEffect(() => { getLeaders().then(data => { - setLeaders(data.sort((a, b) => a - b)); + setLeaders([...leaders, ...data.sort((a, b) => a - b)]); }); }, []); - console.log(leaders); return (
    -

    Лидерборд

    +

    Лидерборд

      -
    • -
        -
      • Позиция
      • -
      • Пользователь
      • -
      • Время
      • -
      -
    • - {leaders.map((l, index) => ( -
    • -
        -
      • {index + 1}
      • -
      • {l.name}
      • -
      • {l.time}
      • + {leaders.map((player, index) => ( +
      • +
          +
        • {index === 0 ? player.position : player.id}
        • +
        • {player.name}
        • +
        • {player.time}
      • ))} diff --git a/src/pages/LeaderBoard/LeaderBoard.module.css b/src/pages/LeaderBoard/LeaderBoard.module.css index 4a6f40be5..de53d7ce4 100644 --- a/src/pages/LeaderBoard/LeaderBoard.module.css +++ b/src/pages/LeaderBoard/LeaderBoard.module.css @@ -2,31 +2,59 @@ display: flex; flex-direction: column; align-items: center; - font-family: 'roboto'; + font-family: "StratosSkyeng"; } .leaderBoarHeader { display: flex; justify-content: space-between; + align-items: center; color: white; width: 944px; + height: 142px; + } .players { display: flex; flex-direction: column; align-items: center; + gap: 15px; } -.leaders { - display: flex; - align-items: center; - list-style-type: none; +.statisticItem { width: 944px; height: 64px; background-color: #ffffff; border-radius: 12px; - color: #999999; - padding: 22px 16px; +} + +.playerStatistic { + display: flex; + align-items: center; + height: 64px; font-size: 24px; + padding: 20px 16px; + } +.statisticItem:first-child { + color: #999999; +} + + +.firstColumn { + width: 244px; +} + +.secondColumn { + width: 558px; +} + +.thirdColumn { + width: 102px; +} + +.leaderBoardTitle { + font-weight: 400; + font-size: 32px; +} \ No newline at end of file From 8810d6fe0b87793eb6a2df451d1eb89acc499d4a Mon Sep 17 00:00:00 2001 From: Fantom52r Date: Wed, 11 Sep 2024 01:22:39 +0300 Subject: [PATCH 06/10] HW-2.Final/11/09/2024 --- src/pages/LeaderBoard/LeaderBoard.module.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/LeaderBoard/LeaderBoard.module.css b/src/pages/LeaderBoard/LeaderBoard.module.css index de53d7ce4..b3b8ccdb5 100644 --- a/src/pages/LeaderBoard/LeaderBoard.module.css +++ b/src/pages/LeaderBoard/LeaderBoard.module.css @@ -33,7 +33,7 @@ display: flex; align-items: center; height: 64px; - font-size: 24px; + font-size: 24px; padding: 20px 16px; } From d7dfcc725e59e8e56b491b67fa10d9440912e8ab Mon Sep 17 00:00:00 2001 From: Fantom52r Date: Sat, 21 Sep 2024 19:57:42 +0300 Subject: [PATCH 07/10] LeaderBoard.From 21/09/2024 --- src/API/leaders.js | 14 +++- src/components/EndGameModal/EndGameModal.jsx | 67 ++++++++++++++++---- src/pages/LeaderBoard/LeaderBoard.module.css | 17 +++-- 3 files changed, 81 insertions(+), 17 deletions(-) diff --git a/src/API/leaders.js b/src/API/leaders.js index 200a65256..3028de2be 100644 --- a/src/API/leaders.js +++ b/src/API/leaders.js @@ -14,4 +14,16 @@ export async function getLeaders() { throw new Error(error.message); } } -// Написать функцию postNewLeader- будет отправлять на сервер новый результат + +//добавление лидера в список +export const addLeader = async data => { + const response = await fetch("https://wedev-api.sky.pro/api/leaderboard/", { + method: "POST", + body: JSON.stringify(data), + }); + + if (!response.ok) { + throw new Error("Упс, ошибка"); + } + return response.json(); +}; diff --git a/src/components/EndGameModal/EndGameModal.jsx b/src/components/EndGameModal/EndGameModal.jsx index 7a8875d0a..52c63daaa 100644 --- a/src/components/EndGameModal/EndGameModal.jsx +++ b/src/components/EndGameModal/EndGameModal.jsx @@ -4,30 +4,75 @@ import { Button } from "../Button/Button"; import deadImageUrl from "./images/dead.png"; import celebrationImageUrl from "./images/celebration.png"; -import { Link } from "react-router-dom"; +import { Link, useNavigate, useParams } from "react-router-dom"; +import { useState } from "react"; +import { addLeader } from "../../API/leaders.js"; export function EndGameModal({ isWon, gameDurationSeconds, gameDurationMinutes, onClick }) { - const title = isWon ? "Вы победили!" : "Вы проиграли!"; + const { pairsCount } = useParams(); + const [error, setError] = useState(); + const nav = useNavigate(); + + const thirdLevelPairs = 9; + const isLeader = isWon && Number(pairsCount) === thirdLevelPairs; + const title = isLeader ? "Вы попали на лидерборд!" : isWon ? "Вы выйграли!" : "Вы проиграли!"; + + //const title = isWon ? "Вы выйграли!" : "Вы проиграли!"; const imgSrc = isWon ? celebrationImageUrl : deadImageUrl; const imgAlt = isWon ? "celebration emodji" : "dead emodji"; - // Добваить инпут Введения имени и кнопку по которой отправляется результат в лидерборд - // 'этот компонент принимает еще один пропс которы называется isLeader и он показывает нужно отправлять результат или нет . - // нужно проверять играешь ли ты на третьем уровне переменная PairsCount - // валидировать пустые поля и пробелы с помощью метода trim - // изменить переменную title проверять перед isWon переменную isleader если она тру то в title должна быть строка - вы попали на Лидерборд. + + const [leader, setAddLeader] = useState({ + name: "", + time: gameDurationMinutes.toString().padStart("2", "0") + gameDurationSeconds.toString().padStart("2", "0"), + }); + + const addLeaderToList = async e => { + e.preventDefault(); + if (leader.name === "") { + setError("Введите имя пользователя"); + return; + } + try { + await addLeader().then(res => { + setAddLeader(res.leaders); + nav("/leaderBoard"); + }); + } catch (error) { + setError(error.message); + } + }; + return (
        {imgAlt}

        {title}

        + {isLeader ? ( +
        + setAddLeader({ ...leader, name: e.target.value })} + id="name-input" + type="text" + name="name" + className={styles.input} + placeholder="Пользователь" + /> +
        + ) : null}

        Затраченное время:

        - {gameDurationMinutes.toString().padStart("2", "0")}.{gameDurationSeconds.toString().padStart("2", "0")} + {gameDurationMinutes.toString().padStart("2", "0")}: {gameDurationSeconds.toString().padStart("2", "0")}
        - - - Перейти к Лидерборду + + {isLeader ? ( + + + + ) : null} + {error &&

        {error}

        }
        ); } diff --git a/src/pages/LeaderBoard/LeaderBoard.module.css b/src/pages/LeaderBoard/LeaderBoard.module.css index b3b8ccdb5..bac7ded00 100644 --- a/src/pages/LeaderBoard/LeaderBoard.module.css +++ b/src/pages/LeaderBoard/LeaderBoard.module.css @@ -12,7 +12,6 @@ color: white; width: 944px; height: 142px; - } .players { @@ -33,15 +32,13 @@ display: flex; align-items: center; height: 64px; - font-size: 24px; + font-size: 24px; padding: 20px 16px; - } .statisticItem:first-child { color: #999999; } - .firstColumn { width: 244px; } @@ -57,4 +54,14 @@ .leaderBoardTitle { font-weight: 400; font-size: 32px; -} \ No newline at end of file +} + +/* .btnLeaderBoard { + font-family: Roboto; + font-size: 18px; + font-weight: 400; + line-height: 32px; + text-align: left; + background: #565EEF; + +} */ From 8fe5178a47182de6d2771886c5d9a122b77a82f8 Mon Sep 17 00:00:00 2001 From: Fantom52r Date: Sat, 21 Sep 2024 21:35:27 +0300 Subject: [PATCH 08/10] HW-2.Done --- src/API/leaders.js | 2 +- src/components/EndGameModal/EndGameModal.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/API/leaders.js b/src/API/leaders.js index 3028de2be..0846ecf15 100644 --- a/src/API/leaders.js +++ b/src/API/leaders.js @@ -1,6 +1,6 @@ export async function getLeaders() { try { - const response = await fetch("https://wedev-api.sky.pro/api/leaderboard", { + const response = await fetch("https://wedev-api.sky.pro/api/leaderboard/", { method: "GET", }); const isResponseOk = response.ok; diff --git a/src/components/EndGameModal/EndGameModal.jsx b/src/components/EndGameModal/EndGameModal.jsx index 52c63daaa..4ce815b1c 100644 --- a/src/components/EndGameModal/EndGameModal.jsx +++ b/src/components/EndGameModal/EndGameModal.jsx @@ -35,7 +35,7 @@ export function EndGameModal({ isWon, gameDurationSeconds, gameDurationMinutes, return; } try { - await addLeader().then(res => { + await addLeader({ name: leader.name, time: leader.time }).then(res => { setAddLeader(res.leaders); nav("/leaderBoard"); }); From 0fa8508fb856dd6dfb848a5c8b5624c1a56110a9 Mon Sep 17 00:00:00 2001 From: Fantom52r Date: Sat, 21 Sep 2024 22:09:47 +0300 Subject: [PATCH 09/10] HW-2/ SURE-DONE --- .../EndGameModal/EndGameModal.module.css | 42 ++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/components/EndGameModal/EndGameModal.module.css b/src/components/EndGameModal/EndGameModal.module.css index 9368cb8b5..4d18073f3 100644 --- a/src/components/EndGameModal/EndGameModal.module.css +++ b/src/components/EndGameModal/EndGameModal.module.css @@ -1,12 +1,15 @@ .modal { width: 480px; - height: 459px; + min-height: 459px; border-radius: 12px; background: #c2f5ff; display: flex; + gap: 10px; flex-direction: column; justify-content: center; align-items: center; + padding-top: 18px; + padding-bottom: 28px; } .image { @@ -23,8 +26,9 @@ font-style: normal; font-weight: 400; line-height: 48px; - margin-bottom: 28px; + width: 276px; + text-align: center; } .description { @@ -49,3 +53,37 @@ margin-bottom: 40px; } + +.btnLeaderBoard { + padding-top: 10px; + background: none; + border: none; + text-decoration: underline; + cursor: pointer; + font-size: 18px; + font-family: Roboto; + font-weight: 400; + line-height: 32px; + text-align: left; + color: #565eef; +} +.userBlockName { + margin-bottom: 10px; +} +.input { + width: 276px; + height: 45px; + top: 334px; + left: 374px; + gap: 0px; + border-radius: 10px; + opacity: 0px; + border: none; + margin-bottom: 30px; + font-family: Roboto; + font-size: 24px; + font-weight: 400; + line-height: 32px; + text-align: center; + color: #999999; +} From b65086b3b168a102c524ed008e70aa1005a95c3a Mon Sep 17 00:00:00 2001 From: Fantom52r Date: Tue, 24 Sep 2024 13:11:50 +0300 Subject: [PATCH 10/10] 24/09/2024/ HW-2/Done --- src/pages/LeaderBoard/LeaderBoard.jsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/pages/LeaderBoard/LeaderBoard.jsx b/src/pages/LeaderBoard/LeaderBoard.jsx index 77719d10e..476cda8f6 100644 --- a/src/pages/LeaderBoard/LeaderBoard.jsx +++ b/src/pages/LeaderBoard/LeaderBoard.jsx @@ -4,14 +4,20 @@ import styles from "./LeaderBoard.module.css"; import { getLeaders } from "../../API/leaders"; import { Link } from "react-router-dom"; -// const COLUMNS_NAME = ["Позиция","Пользователь","Время"] const LeaderBoard = () => { const [leaders, setLeaders] = useState([{ position: "Позиция", name: "Пользователь", time: "Время" }]); useEffect(() => { getLeaders().then(data => { - setLeaders([...leaders, ...data.sort((a, b) => a - b)]); + setLeaders([...leaders, ...data.sort((a, b) => a.time - b.time)]); }); }, []); + + const timeFormat = digit => { + let minutes = Math.floor(digit / 60); + let seconds = digit % 60; + return [minutes < 10 ? "0" + minutes : minutes, ":", seconds < 10 ? "0" + seconds : seconds]; + }; + return (
        @@ -27,7 +33,7 @@ const LeaderBoard = () => {
        • {index === 0 ? player.position : player.id}
        • {player.name}
        • -
        • {player.time}
        • +
        • {index === 0 ? player.time : timeFormat(player.time)}
        ))}