From cb10e7565a50ed020e5c32fda746604d58c5241b Mon Sep 17 00:00:00 2001 From: Fantom52r Date: Thu, 8 Aug 2024 15:30:25 +0300 Subject: [PATCH 01/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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)}
        ))} From 88f567bd878c3a83bfe95298fd971d259eb208d9 Mon Sep 17 00:00:00 2001 From: Fantom52r Date: Thu, 24 Oct 2024 04:38:27 +0300 Subject: [PATCH 11/17] cheatbox-almost ready --- src/API/leaders.js | 4 +- src/components/Cards/Cards.jsx | 74 +++++++++++++++++- src/components/Cards/Cards.module.css | 67 ++++++++++++++++ src/components/Cards/images/alohomora.png | Bin 0 -> 1874 bytes src/components/Cards/images/showallcard.png | Bin 0 -> 2513 bytes src/components/EndGameModal/EndGameModal.jsx | 13 ++- src/context/Context.jsx | 10 ++- src/pages/LeaderBoard/Image/magicBall.png | Bin 0 -> 1306 bytes .../LeaderBoard/Image/magicBallHollow.png | Bin 0 -> 902 bytes src/pages/LeaderBoard/Image/puzzleFull.png | Bin 0 -> 1343 bytes src/pages/LeaderBoard/Image/puzzleHollow.png | Bin 0 -> 1087 bytes src/pages/LeaderBoard/LeaderBoard.jsx | 31 +++++++- src/pages/LeaderBoard/LeaderBoard.module.css | 13 ++- src/pages/SelectLevelPage/SelectLevelPage.jsx | 12 ++- 14 files changed, 211 insertions(+), 13 deletions(-) create mode 100644 src/components/Cards/images/alohomora.png create mode 100644 src/components/Cards/images/showallcard.png create mode 100644 src/pages/LeaderBoard/Image/magicBall.png create mode 100644 src/pages/LeaderBoard/Image/magicBallHollow.png create mode 100644 src/pages/LeaderBoard/Image/puzzleFull.png create mode 100644 src/pages/LeaderBoard/Image/puzzleHollow.png diff --git a/src/API/leaders.js b/src/API/leaders.js index 0846ecf15..0753d0654 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/v2/leaderboard/", { method: "GET", }); const isResponseOk = response.ok; @@ -17,7 +17,7 @@ export async function getLeaders() { //добавление лидера в список export const addLeader = async data => { - const response = await fetch("https://wedev-api.sky.pro/api/leaderboard/", { + const response = await fetch("https://wedev-api.sky.pro/api/v2/leaderboard/", { method: "POST", body: JSON.stringify(data), }); diff --git a/src/components/Cards/Cards.jsx b/src/components/Cards/Cards.jsx index 23b2125a4..c050eb9c1 100644 --- a/src/components/Cards/Cards.jsx +++ b/src/components/Cards/Cards.jsx @@ -1,11 +1,13 @@ import { shuffle } from "lodash"; -import { useContext, useEffect, useState } from "react"; +import { useCallback, 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"; +import alohomora from "./images/alohomora.png"; +import showallcard from "./images/showallcard.png"; // Игра закончилась const STATUS_LOST = "STATUS_LOST"; @@ -15,6 +17,27 @@ const STATUS_IN_PROGRESS = "STATUS_IN_PROGRESS"; // Начало игры: игрок видит все карты в течении нескольких секунд const STATUS_PREVIEW = "STATUS_PREVIEW"; +const FIRST_HINT = { + title: "Прозрение", + description: "На 5 секунд показываются все карты. Таймер длительности игры на это время останавливается.", +}; + +const SECOND_HINT = { + title: "Алохомора", + description: " Открывается случайная пара карт.", +}; + +// const hintPopUp = ({ text }) => { +// return ( +//
        +//
        +//

        {text.title}

        +//

        +//
        +//
        +// ); +// }; + function getTimerValue(startDate, endDate) { if (!startDate && !endDate) { return { @@ -42,7 +65,7 @@ function getTimerValue(startDate, endDate) { * previewSeconds - сколько секунд пользователь будет видеть все карты открытыми до начала игры */ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { - const { isEasyMode, tries, setTries } = useContext(EasyContext); + const { isEasyMode, tries, setTries, setUsedHints } = useContext(EasyContext); // В cards лежит игровое поле - массив карт и их состояние открыта\закрыта const [cards, setCards] = useState([]); // Текущий статус игры @@ -53,6 +76,8 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { // Дата конца игры const [gameEndDate, setGameEndDate] = useState(null); + const [showHint, setShowHint] = useState({ isShow: false, text: "" }); + // Стейт для таймера, высчитывается в setInteval на основе gameStartDate и gameEndDate const [timer, setTimer] = useState({ seconds: 0, @@ -198,8 +223,28 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { }; }, [gameStartDate, gameEndDate]); + // if (showHint.isShow) { + // return ( + //
        + //
        + //

        {showHint.title}

        + //

        {showHint.description}

        + //
        + //
        + // ); + // } + const handleMouseOver = useCallback(() => { + if (!showHint.isShow || showHint.id !== 1) { + setShowHint({ isShow: true, id: 1, ...FIRST_HINT }); + } + }, [showHint]); + + const handleMouseOut = useCallback(() => { + setShowHint({ isShow: false, id: null }); + }, []); return (
        + {showHint.isShow &&
        }
        {status === STATUS_PREVIEW ? ( @@ -221,6 +266,31 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { )}
        +
        + + + +
        + {status === STATUS_IN_PROGRESS ? : null} {isEasyMode && Колличество жизней: {tries}}
        diff --git a/src/components/Cards/Cards.module.css b/src/components/Cards/Cards.module.css index 000c5006c..8a6681f07 100644 --- a/src/components/Cards/Cards.module.css +++ b/src/components/Cards/Cards.module.css @@ -70,3 +70,70 @@ margin-bottom: -12px; } + +.cheatBox { + width: 151px; + height: 68px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.popUpHint { + position: fixed; + opacity: 0.6; + background-color: #004980; + width: 100%; + height: 100vh; + z-index: 5000; +} + +.showAllCard { + display: flex; + justify-content: center; + align-items: center; + width: 68px; + height: 68px; + border-radius: 50%; + background-color: #c2f5ff; + border: none; + cursor: pointer; + position: relative; +} + +.alohomora { + display: flex; + justify-content: center; + align-items: center; + width: 68px; + height: 68px; + border-radius: 50%; + background-color: #c2f5ff; + border: none; + position: relative; + cursor: pointer; +} +.popUpHintContent { + position: absolute; + width: 222px; + height: 223px; + background-color: #c2f5ff; + padding: 25px 20px 20px 20px; + bottom: -230px; + z-index: 6000; + border-radius: 12px; +} + +.popUpHintContenTitle{ +font-size: 18px; +font-weight: 700; +line-height: 24px; +color: #004980; +} + +.popUpHintContentDescription{ +font-size: 18px; +font-weight: 400; +line-height: 24px; +margin-top: 10px; +} \ No newline at end of file diff --git a/src/components/Cards/images/alohomora.png b/src/components/Cards/images/alohomora.png new file mode 100644 index 0000000000000000000000000000000000000000..e323e39c01e313531b772ee5f53044108f19ab2b GIT binary patch literal 1874 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 { + await addLeader({ + name: leader.name, + time: leader.time, + achievements: usedHints ? achievements : [...achievements, 2], + }).then(res => { setAddLeader(res.leaders); nav("/leaderBoard"); + setAchievements([]); + setUsedHints(false); + setEasyMode(false); }); } catch (error) { setError(error.message); diff --git a/src/context/Context.jsx b/src/context/Context.jsx index ff14509f5..303d9a259 100644 --- a/src/context/Context.jsx +++ b/src/context/Context.jsx @@ -3,7 +3,15 @@ import { createContext, useState } from "react"; export const EasyContext = createContext(false); export const EasyProvider = ({ children }) => { + const [usedHints, setUsedHints] = useState(false); const [tries, setTries] = useState(3); const [isEasyMode, setEasyMode] = useState(false); - return {children}; + const [achievements, setAchievements] = useState([]); + return ( + + {children} + + ); }; diff --git a/src/pages/LeaderBoard/Image/magicBall.png b/src/pages/LeaderBoard/Image/magicBall.png new file mode 100644 index 0000000000000000000000000000000000000000..b59b52e7d79bdd69ff052b104cc780b1d6c7f867 GIT binary patch literal 1306 zcmV+#1?BpQP)z4)8@nqRb^l1VX@_P$($C9ZCVRDd>>pGNOq67sR2XO5D(5iU>N} zqJqXpg+#%bKLE)VzVq#mnaB5LW_=rH&tB6&k&))+c6VmJ?|tvb4AJxUA2+_tO&I~}x`wqJRRx9AeB5djDM0^Jv(RmKX8j8Up1rb*au$PsNUHY9Q( z0f2Y8P2b_~qRs~xv0o(@tlyT5R<8H?kp3+JfOj~deayOg2E0n(86p)`1|ZQtk3@7X zc$;>x%|Z!O15OnZ{)2cIg-2EI0iDxk5}-ESr)iL#ZB7l6DWIBs#yy^o(DLvn>Cvo> z>Rtxxhe1jYXakr**Z)=m4+z8T)Isnu$FM4PS%2?NQp~uTZkjzNLeZ) zfujgYK!gYcVg<#nF$lzMKdLH}x!Tc;0KmH@Q*a@SRAd-)yjK#&cT$%F))7_@#4Jjn zh=t<>iY4Gth}bspl}MX!P*WG=6In2+8yx}dHYe`}b%9ra%Sxn@DG8Nc6)-IeP=;av zP`6pUGxTy}0>wnT5ajnRNSy+#DySRmX&k6nR)f&_AK=M%lq!G(R0wWRB@ApfAwwcx2Gq}S?0s(9!YwGEBth1tthMIP#ssp7-2-?BO0aW7 z%3cX2Q6MuyHjs+1c^J7sV~gFO0JTgca1&cAD5RH?sw5fDKl4ZN1P$hXFFOWh={KDaVbOya%91jc{IyDc$CaKlwIf$EL~Ht|^j z|5~qtxGWTkGyq|_^Suu`=%R`2QWTT6-d*E^I;`4K++X9vBDL#9W*I36>y?C1e&RZ3 zW4LJ~lpT|#Bg;9Si!n)dqAqhmEN-1o;UhDNH)uwic^35VwI4$A$65nmxsq_%k&i(_ z!AFh+>zE!3rDI_wsNlKIpSTPHLs{?NtG9k80eKQH%a6%wmL_W^$v@+^J$QkOp%-Td}$_Q2+{ z8YJc7L<3TTQG)=1moT-oG$Z2tSs+JoP8%P6dTpEX7k4NY1;?FYywXSkO6EXqo-r=V z&b8s)FJ5~HC2kc)c2NwheN_4*dsXk+us-&P7^dnSu+*i;s*nh+z<4DH^!^Y!4(_rK|2%_E|@ zo=|Gv^tfq9~8=`Jr8{;Jg>e?eVxbC7QhHB34iU#N3`4l>^`PJHw*-%Bp67LE7Vz2kU0c)rVzKDt zayhJex)Y00NDoEa+}s?BD119j1f51+(2c!?g@sJycR{g2wrxS7P^d6f{V;XyqzO~i zwk<5Xq9~cjM<9fPX&PW!_WJShaTT%%z@N@F4E?=4^I6CriLgvibbSl52v7}U%{0xw zA|C;74rn>8>YtocAgush)8EO`&kLHS$x(&00+75ikL*Wa_-1ITwgPDd;06cg2$>9C zj0H$5V4m4O#GLTtBntotVBP`<2_UTi0c0QM2y9fq6y`%(0VIxEa??BogaG@g1q_G7 zHquXRBH2Kit!WuMvZZ#<&MM{QW$*Ip zs)3DV15yIB>c%lg^7EFZX?yszyJ0vi;#6&XZQ>CW3VCoG2fxMjqm!?v7oAQcjHyRJ zwBZS29>*VfNWISac~_blr|7uo3m|Xj6Za%mfMN%e@3&=H^6R3rIla0(Yogbyzg~1} zz<3o6XoXTDvqA?XelSYfz3c14@7=DeFlEQG>}o!r2US(?)zL|!|3v5FQao&g-=-5i z9{jw$g)oeQD2}8HJ`x-P8I~}p;8XX8F{O&`$&o(7FpNjuaWEJ*mtK`>sVXpzQ8i@X zD2nhrLl;G@Nnx^Y$a(3K6%;*kP-*)~rlv26jK@f2S c&-fql3&bK3uNoMtf&c&j07*qoM6N<$f|;O;@&Et; literal 0 HcmV?d00001 diff --git a/src/pages/LeaderBoard/Image/puzzleFull.png b/src/pages/LeaderBoard/Image/puzzleFull.png new file mode 100644 index 0000000000000000000000000000000000000000..49c30e1d19dd5af4db884e4197a2ac7f30525f5a GIT binary patch literal 1343 zcmV-F1;F}=P)YCXF$Zh!6|W;4A%qjCYUwqV{0P7;_mA z1!jeD$M!${=WzEpLmM!7T_K?{eOL6JUpIl#Zyp)Uc`WY?{5IaJ z|MU8`8Zb%<2}R;{QrR`$P$RAb^c;F);P?7UI6ZUV<7+!Bp?IThOQWOLwwHU2X$u!Z zfV7?A5MH82m<-yrcyT@Nyyj})Jqc95da`oMn(C}GfKSomW2j)_i9(&zkmxpnIO{`Di{j82X*s5rs48aUlilBstV-bE`BKr(^5s0c zqAHLx4g`dKES&)%51^hAEZ6Z{7l_j^^&Y_3?-6=X1DHDsC;^(c-q2_JzCFGo0k!=~ z!uKv`$rW<|&1o1w#3xZDViNIT$Vvp@sR#}X96qh%I4MKaElHAc4n&l|tjq9hNPFt9 zUY%T#fLeLt*%FSvOF3f;IUFZYK^2e;$RPe~6kJhtw(fh#p$b^t`-uWU+i?*Dq$M8D zCkZLDNLD0g{rZ6`10AfM+i-HNi`i^EKJ8p#8##H3XUno;;pYh(j<@o(oL$KJMIQ4wVc?gGbTQvl} zh9E9U66yn=oW}oeH1E3l^3|X-fBTsi^*pK0StjIxSZfa3Hz!Un##r?(_%XV#aIXuS z$c2KRY{@hc;}l37=>b2U>Ll{qoYe zmWSP27mv{fZ5aV`a&HaIr5+=7zcn%8{$8X~3lNJ*7jklp9-e3*Ez0=ano0YYkj10v zBGdBMv=N2WFx`1Q{(-jbQ04pF_LD>Oe2e5+j%rJ5o+EM32LtbWR zp;Zj|0OGGX*KLqvJH$}+p;G@+r0Dwio}ceM|8pdEBMpr zJ!jyaI(qYFmFI)6x2+eQH}w{r^!vJG+ds2}top#zqtAowxVV7HWU{NODut~u%om)y z($0eb!us#*(>hDwRdn2O90~veemxgj0Zd|H5w?FS7Pq4B%mp|&G@FD4|Ak@fBt3tB zc5X6+)Zi}p&|`e}WwBW7&I?Jb0b1>9M%h*rwPPM1*OOvyYQR3ap5N58?7E^T5G}H(JkNvSa0uh8ajW|5S$iSCAAkR2YFehohO9=b+p_w-n;W~! zaiosP^)$)D5QD)08_}p$U0G@032=IPS|Ob98b>SPaSB0yw4qRcr%fJ)xV*f?);-+7 zcDywg;4?%YA-ovG*UEKWgt&mK;dR3>R`#dku_7#&^MQ5nuLTbk1HI@F-PTM-15puY z`bVM-sdYS?7}UpbA7Q-bdyP_|u#E37V-e3-5Vy~gRb_1<0M&h0BItGwX_Oy7-k-id zaqPWtjN|%i%TJ$nQvp!@`{9G`ICd%kAILgQI+JkXT0UBt3S05olhUKz=zCn!WWV5z zhhw=-Q4s44v-rTIRen9X+>1RB*j-$jDt`IilTvXv>D`zMf^%PzxA8;+K@bA#EfPJ1 zK7Ksks6Kzb1@}}8;N72pVKdTdLE?zt=|1Cv#?AnjHk-ibBU*&}#P{2@b3zKm)>oDl zJvd4u$uV)K_^6O)JlB9oVd5PDG`y@V6$+JHHrFJA(1etV0kAw9+e@sYo^MZrHcBmu z5Dg{)f?mP!>SYy|mOAiI09zDWp6B1*0etXrNy*D{x!jwMQ3%&_lWw>c-T)in*hPBK zjcBUVv$G~4>~;W3SBdt4h!wxND8&2oPbc&sgCF`H^*;=^n+MB$(8B-#002ovPDHLk FV1m30|KI=s literal 0 HcmV?d00001 diff --git a/src/pages/LeaderBoard/LeaderBoard.jsx b/src/pages/LeaderBoard/LeaderBoard.jsx index 476cda8f6..fdbec28bb 100644 --- a/src/pages/LeaderBoard/LeaderBoard.jsx +++ b/src/pages/LeaderBoard/LeaderBoard.jsx @@ -3,12 +3,19 @@ import { Button } from "../../components/Button/Button"; import styles from "./LeaderBoard.module.css"; import { getLeaders } from "../../API/leaders"; import { Link } from "react-router-dom"; +import puzzleFull from "./Image/puzzleFull.png"; +import puzzleHollow from "./Image/puzzleHollow.png"; +import magicBall from "./Image/magicBall.png"; +import magicBallHollow from "./Image/magicBallHollow.png"; const LeaderBoard = () => { - const [leaders, setLeaders] = useState([{ position: "Позиция", name: "Пользователь", time: "Время" }]); + const [leaders, setLeaders] = useState([ + { position: "Позиция", name: "Пользователь", time: "Время", achievements: "Достижения" }, + ]); useEffect(() => { getLeaders().then(data => { setLeaders([...leaders, ...data.sort((a, b) => a.time - b.time)]); + console.log(data); }); }, []); @@ -31,9 +38,27 @@ const LeaderBoard = () => { {leaders.map((player, index) => (
        • -
        • {index === 0 ? player.position : player.id}
        • +
        • {index === 0 ? player.position : index}
        • {player.name}
        • -
        • {index === 0 ? player.time : timeFormat(player.time)}
        • +
        • + {index === 0 ? ( + player.achievements + ) : ( +
          + {player.achievements.includes(1) ? ( + puzzleFull + ) : ( + puzzleHollow + )} + {player.achievements.includes(2) ? ( + magickBall + ) : ( + magickBallHollow + )} +
          + )}{" "} +
        • +
        • {index === 0 ? player.time : timeFormat(player.time)}
      • ))} diff --git a/src/pages/LeaderBoard/LeaderBoard.module.css b/src/pages/LeaderBoard/LeaderBoard.module.css index bac7ded00..98e2a81bc 100644 --- a/src/pages/LeaderBoard/LeaderBoard.module.css +++ b/src/pages/LeaderBoard/LeaderBoard.module.css @@ -39,6 +39,11 @@ color: #999999; } +.achievementsBox{ + display: flex; + gap: 6px; +} + .firstColumn { width: 244px; } @@ -48,7 +53,13 @@ } .thirdColumn { - width: 102px; + width: 194px; + margin-right: 66px; + +} + +.fourthColumn { + width: 104px; } .leaderBoardTitle { diff --git a/src/pages/SelectLevelPage/SelectLevelPage.jsx b/src/pages/SelectLevelPage/SelectLevelPage.jsx index 10f4f451d..06801fed3 100644 --- a/src/pages/SelectLevelPage/SelectLevelPage.jsx +++ b/src/pages/SelectLevelPage/SelectLevelPage.jsx @@ -19,13 +19,17 @@ const levels = [ }, ]; export function SelectLevelPage() { - const { isEasyMode, setEasyMode } = useContext(EasyContext); + const { isEasyMode, setEasyMode, achievements, setAchievements } = useContext(EasyContext); const [level, setLevel] = useState(3); const navigate = useNavigate(); function onClick(value) { setLevel(value); } function onStart() { + if (level === 9 && !isEasyMode) { + setAchievements([...new Set([...achievements, 1])]); + } + navigate(`/game/${level}`); } return ( @@ -34,7 +38,11 @@ export function SelectLevelPage() {

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

          {levels.map(l => ( -
        • onClick(l.pairs)} className={clsx(styles.level, { [styles.active]: l.pairs === level })}> +
        • onClick(l.pairs)} + className={clsx(styles.level, { [styles.active]: l.pairs === level })} + key={l.level} + >
          {l.level}
        • ))} From fd857358483d4ff87ae26a0c6d2546e624febc88 Mon Sep 17 00:00:00 2001 From: Fantom52r Date: Sat, 26 Oct 2024 12:54:07 +0300 Subject: [PATCH 12/17] course-work-check for 26/10/2024 --- package-lock.json | 3 ++- src/components/Cards/Cards.jsx | 29 +++++++++++---------------- src/components/Cards/Cards.module.css | 29 +++++++++++++++++---------- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/package-lock.json b/package-lock.json index c20f8c388..19baf6a3f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12633,7 +12633,8 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" }, "node_modules/lodash.debounce": { "version": "4.0.8", diff --git a/src/components/Cards/Cards.jsx b/src/components/Cards/Cards.jsx index c050eb9c1..3b5d23af2 100644 --- a/src/components/Cards/Cards.jsx +++ b/src/components/Cards/Cards.jsx @@ -1,5 +1,5 @@ import { shuffle } from "lodash"; -import { useCallback, useContext, 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"; @@ -233,15 +233,7 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { //
        // ); // } - const handleMouseOver = useCallback(() => { - if (!showHint.isShow || showHint.id !== 1) { - setShowHint({ isShow: true, id: 1, ...FIRST_HINT }); - } - }, [showHint]); - const handleMouseOut = useCallback(() => { - setShowHint({ isShow: false, id: null }); - }, []); return (
        {showHint.isShow &&
        } @@ -269,25 +261,28 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) {
        diff --git a/src/components/Cards/Cards.module.css b/src/components/Cards/Cards.module.css index 8a6681f07..8064ddf7f 100644 --- a/src/components/Cards/Cards.module.css +++ b/src/components/Cards/Cards.module.css @@ -122,18 +122,25 @@ bottom: -230px; z-index: 6000; border-radius: 12px; + opacity: 0; + visibility: hidden; } +.showAllCard:hover .popUpHintContent { + opacity: 1; + visibility: visible; +} + -.popUpHintContenTitle{ -font-size: 18px; -font-weight: 700; -line-height: 24px; -color: #004980; +.popUpHintContenTitle { + font-size: 18px; + font-weight: 700; + line-height: 24px; + color: #004980; } -.popUpHintContentDescription{ -font-size: 18px; -font-weight: 400; -line-height: 24px; -margin-top: 10px; -} \ No newline at end of file +.popUpHintContentDescription { + font-size: 18px; + font-weight: 400; + line-height: 24px; + margin-top: 10px; +} From c06c85629453f6ca3d0de48c9db082b03704abd8 Mon Sep 17 00:00:00 2001 From: Fantom52r Date: Mon, 28 Oct 2024 02:07:03 +0300 Subject: [PATCH 13/17] hints_fix --- src/components/Cards/Cards.jsx | 30 +++++++++--------- src/components/Cards/Cards.module.css | 44 +++++++++++++++++++-------- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/src/components/Cards/Cards.jsx b/src/components/Cards/Cards.jsx index 3b5d23af2..6a48c95ee 100644 --- a/src/components/Cards/Cards.jsx +++ b/src/components/Cards/Cards.jsx @@ -76,7 +76,7 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { // Дата конца игры const [gameEndDate, setGameEndDate] = useState(null); - const [showHint, setShowHint] = useState({ isShow: false, text: "" }); + // const [showHint, setShowHint] = useState({ isShow: false, text: "" }); // Стейт для таймера, высчитывается в setInteval на основе gameStartDate и gameEndDate const [timer, setTimer] = useState({ @@ -236,7 +236,6 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { return (
        - {showHint.isShow &&
        }
        {status === STATUS_PREVIEW ? ( @@ -259,30 +258,29 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { )}
        -
        diff --git a/src/components/Cards/Cards.module.css b/src/components/Cards/Cards.module.css index 8064ddf7f..6b4537892 100644 --- a/src/components/Cards/Cards.module.css +++ b/src/components/Cards/Cards.module.css @@ -80,12 +80,14 @@ } .popUpHint { - position: fixed; opacity: 0.6; background-color: #004980; - width: 100%; - height: 100vh; + width: 150vh; + height: 150vh; z-index: 5000; + display: none; + position: absolute; + /* overflow: hidden; */ } .showAllCard { @@ -96,9 +98,9 @@ height: 68px; border-radius: 50%; background-color: #c2f5ff; - border: none; - cursor: pointer; position: relative; + cursor: pointer; + border: none; } .alohomora { @@ -109,10 +111,11 @@ height: 68px; border-radius: 50%; background-color: #c2f5ff; - border: none; position: relative; cursor: pointer; + border: none; } + .popUpHintContent { position: absolute; width: 222px; @@ -122,14 +125,7 @@ bottom: -230px; z-index: 6000; border-radius: 12px; - opacity: 0; - visibility: hidden; } -.showAllCard:hover .popUpHintContent { - opacity: 1; - visibility: visible; -} - .popUpHintContenTitle { font-size: 18px; @@ -144,3 +140,25 @@ line-height: 24px; margin-top: 10px; } + +.popUpHintActiveFirst { + display: none; +} +.showAllCard:hover .popUpHint { + display: block; +} +.showAllCard:hover .popUpHintActiveFirst { + display: block; +} + +.popUpHintActiveSecond { + display: none; +} + +.alohomora:hover .popUpHint { + display: block; +} + +.alohomora:hover .popUpHintActiveSecond { + display: block; +} From c4d20705e7f1e8da855516b5956b11a1e7830d76 Mon Sep 17 00:00:00 2001 From: Fantom52r Date: Wed, 30 Oct 2024 02:03:42 +0300 Subject: [PATCH 14/17] course-work.30/10/2024 --- public/index.html | 12 ++---------- src/components/Cards/Cards.jsx | 14 +++++--------- src/components/Cards/Cards.module.css | 11 ++++++----- src/components/modal/Modal.jsx | 10 ++++++++++ 4 files changed, 23 insertions(+), 24 deletions(-) create mode 100644 src/components/modal/Modal.jsx diff --git a/public/index.html b/public/index.html index c0103cf10..5e46aec0e 100644 --- a/public/index.html +++ b/public/index.html @@ -37,16 +37,8 @@ -
        - +
        diff --git a/src/components/Cards/Cards.jsx b/src/components/Cards/Cards.jsx index 6a48c95ee..dfef30a77 100644 --- a/src/components/Cards/Cards.jsx +++ b/src/components/Cards/Cards.jsx @@ -8,6 +8,7 @@ import { Card } from "../../components/Card/Card"; import { EasyContext } from "../../context/Context"; import alohomora from "./images/alohomora.png"; import showallcard from "./images/showallcard.png"; +import Modal from "../modal/Modal"; // Игра закончилась const STATUS_LOST = "STATUS_LOST"; @@ -259,8 +260,6 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) {
        - + +
        +
        {status === STATUS_IN_PROGRESS ? : null} diff --git a/src/components/Cards/Cards.module.css b/src/components/Cards/Cards.module.css index 6b4537892..dafdf9c7f 100644 --- a/src/components/Cards/Cards.module.css +++ b/src/components/Cards/Cards.module.css @@ -82,12 +82,11 @@ .popUpHint { opacity: 0.6; background-color: #004980; - width: 150vh; - height: 150vh; + width: 100%; + height: 100vh; z-index: 5000; display: none; - position: absolute; - /* overflow: hidden; */ + position: fixed; } .showAllCard { @@ -101,6 +100,7 @@ position: relative; cursor: pointer; border: none; + z-index: 7000; } .alohomora { @@ -114,6 +114,7 @@ position: relative; cursor: pointer; border: none; + z-index: 7000; } .popUpHintContent { @@ -144,7 +145,7 @@ .popUpHintActiveFirst { display: none; } -.showAllCard:hover .popUpHint { +.showAllCard:active .popUpHint { display: block; } .showAllCard:hover .popUpHintActiveFirst { diff --git a/src/components/modal/Modal.jsx b/src/components/modal/Modal.jsx new file mode 100644 index 000000000..2c073ea74 --- /dev/null +++ b/src/components/modal/Modal.jsx @@ -0,0 +1,10 @@ +import React from "react"; +import ReactDOM from "react-dom"; +// import styles from "../Card/Card.module.css"; + +const Modal = ({ children }) => { + const modalRoot = document.getElementById("modal-root"); + return ReactDOM.createPortal(<>{children}, modalRoot); +}; + +export default Modal; From 3dd3c389211fabfec084bf7ca92d19e93467a748 Mon Sep 17 00:00:00 2001 From: Fantom52r Date: Wed, 30 Oct 2024 04:13:01 +0300 Subject: [PATCH 15/17] course work-For-Check 30/10/2024 --- src/components/Cards/Cards.jsx | 58 ++++++++++++++++++++++++--- src/components/Cards/Cards.module.css | 1 - src/components/modal/Modal.jsx | 1 - 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/components/Cards/Cards.jsx b/src/components/Cards/Cards.jsx index dfef30a77..8f3bdf267 100644 --- a/src/components/Cards/Cards.jsx +++ b/src/components/Cards/Cards.jsx @@ -85,6 +85,11 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { minutes: 0, }); + const [isHovered, setIsHovered] = useState(false); + + const handleMouseOver = () => setIsHovered(true); + const handleMouseOut = () => setIsHovered(false); + function finishGame(status = STATUS_LOST) { setGameEndDate(new Date()); setStatus(status); @@ -234,7 +239,36 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { //
        // ); // } - + const [isUsedHint, setIsUsedHint] = useState(0); + + const handleClickAlohomora = () => { + if (isUsedHint > 2) return; + setUsedHints(true); + console.log(cards); + const obj = {}; + const filtredCards = cards.filter(element => !element.open); + for (let i = 0; i < filtredCards.length; i++) { + if (obj[filtredCards[i].suit + " " + filtredCards[i].rank]) { + obj[filtredCards[i].suit + " " + filtredCards[i].rank] += 1; + } else { + obj[filtredCards[i].suit + " " + filtredCards[i].rank] = 1; + } + } + const onlyPairsCards = Object.entries(obj).filter(([key, value]) => value === 2); + const randomPair = onlyPairsCards[Math.floor(Math.random() * onlyPairsCards.length)][0]; // Почему в этом случае лучше использовать Math.floor? + const suitOfRandomPair = randomPair.split(" ")[0]; + const rankOfRandomPair = randomPair.split(" ")[1]; + + const newCards = cards.map(el => { + if (el.suit === suitOfRandomPair && el.rank === rankOfRandomPair) { + return { ...el, open: true }; + } else { + return el; + } + }); + setIsUsedHint(prev => prev + 1); + setCards(newCards); + }; return (
        @@ -259,7 +293,12 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { )}
        - - - -
        -
        {status === STATUS_IN_PROGRESS ? : null} @@ -306,6 +347,11 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { />
        ) : null} + {isHovered && ( + +
        +
        + )}
        ); } diff --git a/src/components/Cards/Cards.module.css b/src/components/Cards/Cards.module.css index dafdf9c7f..18e97bb90 100644 --- a/src/components/Cards/Cards.module.css +++ b/src/components/Cards/Cards.module.css @@ -85,7 +85,6 @@ width: 100%; height: 100vh; z-index: 5000; - display: none; position: fixed; } diff --git a/src/components/modal/Modal.jsx b/src/components/modal/Modal.jsx index 2c073ea74..ef034e15a 100644 --- a/src/components/modal/Modal.jsx +++ b/src/components/modal/Modal.jsx @@ -1,6 +1,5 @@ import React from "react"; import ReactDOM from "react-dom"; -// import styles from "../Card/Card.module.css"; const Modal = ({ children }) => { const modalRoot = document.getElementById("modal-root"); From c3d01723c01a978de2ee09e6319e1e8001868541 Mon Sep 17 00:00:00 2001 From: Fantom52r Date: Fri, 1 Nov 2024 03:46:54 +0300 Subject: [PATCH 16/17] course-work-fow-check/NEW --- src/components/EndGameModal/EndGameModal.jsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/EndGameModal/EndGameModal.jsx b/src/components/EndGameModal/EndGameModal.jsx index d46b6eb9e..bb24b36b3 100644 --- a/src/components/EndGameModal/EndGameModal.jsx +++ b/src/components/EndGameModal/EndGameModal.jsx @@ -19,8 +19,6 @@ export function EndGameModal({ isWon, gameDurationSeconds, gameDurationMinutes, 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"; From badbff98d8e49c3a5d3e54bb1078f21fb7173b8e Mon Sep 17 00:00:00 2001 From: Fantom52r Date: Tue, 5 Nov 2024 02:17:37 +0300 Subject: [PATCH 17/17] course-work for final check --- src/components/Cards/Cards.jsx | 48 ++------------------------- src/pages/LeaderBoard/LeaderBoard.jsx | 1 - 2 files changed, 2 insertions(+), 47 deletions(-) diff --git a/src/components/Cards/Cards.jsx b/src/components/Cards/Cards.jsx index 8f3bdf267..eabbaf1c3 100644 --- a/src/components/Cards/Cards.jsx +++ b/src/components/Cards/Cards.jsx @@ -7,7 +7,6 @@ import { Button } from "../../components/Button/Button"; import { Card } from "../../components/Card/Card"; import { EasyContext } from "../../context/Context"; import alohomora from "./images/alohomora.png"; -import showallcard from "./images/showallcard.png"; import Modal from "../modal/Modal"; // Игра закончилась @@ -18,27 +17,11 @@ const STATUS_IN_PROGRESS = "STATUS_IN_PROGRESS"; // Начало игры: игрок видит все карты в течении нескольких секунд const STATUS_PREVIEW = "STATUS_PREVIEW"; -const FIRST_HINT = { - title: "Прозрение", - description: "На 5 секунд показываются все карты. Таймер длительности игры на это время останавливается.", -}; - const SECOND_HINT = { title: "Алохомора", description: " Открывается случайная пара карт.", }; -// const hintPopUp = ({ text }) => { -// return ( -//
        -//
        -//

        {text.title}

        -//

        -//
        -//
        -// ); -// }; - function getTimerValue(startDate, endDate) { if (!startDate && !endDate) { return { @@ -77,8 +60,6 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { // Дата конца игры const [gameEndDate, setGameEndDate] = useState(null); - // const [showHint, setShowHint] = useState({ isShow: false, text: "" }); - // Стейт для таймера, высчитывается в setInteval на основе gameStartDate и gameEndDate const [timer, setTimer] = useState({ seconds: 0, @@ -229,22 +210,11 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { }; }, [gameStartDate, gameEndDate]); - // if (showHint.isShow) { - // return ( - //
        - //
        - //

        {showHint.title}

        - //

        {showHint.description}

        - //
        - //
        - // ); - // } const [isUsedHint, setIsUsedHint] = useState(0); const handleClickAlohomora = () => { - if (isUsedHint > 2) return; + if (isUsedHint > 2 || gameStartDate - gameEndDate === 0) return; setUsedHints(true); - console.log(cards); const obj = {}; const filtredCards = cards.filter(element => !element.open); for (let i = 0; i < filtredCards.length; i++) { @@ -255,7 +225,7 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { } } const onlyPairsCards = Object.entries(obj).filter(([key, value]) => value === 2); - const randomPair = onlyPairsCards[Math.floor(Math.random() * onlyPairsCards.length)][0]; // Почему в этом случае лучше использовать Math.floor? + const randomPair = onlyPairsCards[Math.floor(Math.random() * onlyPairsCards.length)][0]; const suitOfRandomPair = randomPair.split(" ")[0]; const rankOfRandomPair = randomPair.split(" ")[1]; @@ -293,20 +263,6 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) { )}
        - -