From 9734b0a680c6226057a4612672d8de98ef52df1c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D1=82=D0=B2=D0=BE=D0=B5=20=D0=B8=D0=BC=D1=8F?=
<твоя почта>
Date: Wed, 10 Apr 2024 22:17:03 +0400
Subject: [PATCH 1/7] =?UTF-8?q?=D0=B4=D0=B7=20=E2=84=961?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.eslintrc.json | 7 ++-
.vscode/settings.json | 5 ++
src/components/Cards/Cards.jsx | 52 ++++++++++++++++---
src/components/Cards/Cards.module.css | 16 +++++-
src/components/Cards/images/hearts.svg | 3 ++
src/pages/GamePage/GamePage.jsx | 5 +-
src/pages/SelectLevelPage/SelectLevelPage.jsx | 12 +++--
.../SelectLevelPage.module.css | 32 ++++++++++++
src/router.js | 2 +-
9 files changed, 121 insertions(+), 13 deletions(-)
create mode 100644 .vscode/settings.json
create mode 100644 src/components/Cards/images/hearts.svg
diff --git a/.eslintrc.json b/.eslintrc.json
index e37e1e072..7814cf6f2 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/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 000000000..50dba2289
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+ "cSpell.words": [
+ "закрыта"
+ ]
+}
\ No newline at end of file
diff --git a/src/components/Cards/Cards.jsx b/src/components/Cards/Cards.jsx
index 7526a56c8..41f5b9114 100644
--- a/src/components/Cards/Cards.jsx
+++ b/src/components/Cards/Cards.jsx
@@ -40,7 +40,7 @@ function getTimerValue(startDate, endDate) {
* pairsCount - сколько пар будет в игре
* previewSeconds - сколько секунд пользователь будет видеть все карты открытыми до начала игры
*/
-export function Cards({ pairsCount = 3, previewSeconds = 5 }) {
+export function Cards({ pairsCount = 3, previewSeconds = 5, isGameMode }) {
// В cards лежит игровое поле - массив карт и их состояние открыта\закрыта
const [cards, setCards] = useState([]);
// Текущий статус игры
@@ -57,6 +57,13 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) {
minutes: 0,
});
+ // Стейт для счетчика попыток
+ const [numberOfAttempts, setNumberOfAttempts] = useState(2);
+ const takeAwayTheAttempt = () => {
+ setNumberOfAttempts(numberOfAttempts - 1);
+ console.log(numberOfAttempts);
+ };
+
function finishGame(status = STATUS_LOST) {
setGameEndDate(new Date());
setStatus(status);
@@ -73,6 +80,7 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) {
setGameEndDate(null);
setTimer(getTimerValue(null, null));
setStatus(STATUS_PREVIEW);
+ setNumberOfAttempts(2);
}
/**
@@ -126,11 +134,25 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) {
const playerLost = openCardsWithoutPair.length >= 2;
// "Игрок проиграл", т.к на поле есть две открытые карты без пары
- if (playerLost) {
- finishGame(STATUS_LOST);
- return;
- }
+ if (isGameMode === "true") {
+ if (playerLost) {
+ takeAwayTheAttempt();
+ if (numberOfAttempts < 1) {
+ finishGame(STATUS_LOST);
+ return;
+ } else {
+ setTimeout(() => {
+ setCards(cards.map(card => (openCardsWithoutPair.includes(card) ? { ...card, open: false } : card)));
+ }, 1000);
+ }
+ }
+ } else {
+ if (playerLost) {
+ finishGame(STATUS_LOST);
+ return;
+ }
+ }
// ... игра продолжается
};
@@ -195,7 +217,25 @@ export function Cards({ pairsCount = 3, previewSeconds = 5 }) {
>
)}
- {status === STATUS_IN_PROGRESS ? : null}
+
+ {status === STATUS_IN_PROGRESS ? (
+ <>
+ {isGameMode === "true" ? (
+
diff --git a/src/components/Cards/Cards.module.css b/src/components/Cards/Cards.module.css
index 000c5006c..85675d4ae 100644
--- a/src/components/Cards/Cards.module.css
+++ b/src/components/Cards/Cards.module.css
@@ -67,6 +67,20 @@
font-style: normal;
font-weight: 400;
line-height: 32px;
-
margin-bottom: -12px;
}
+
+
+.attemptСounter {
+ display: flex;
+ gap: 10px;
+ color: red;
+ font-variant-numeric: lining-nums proportional-nums;
+ font-family: StratosSkyeng;
+ font-size: 30px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 30px;
+}
+
+
diff --git a/src/components/Cards/images/hearts.svg b/src/components/Cards/images/hearts.svg
new file mode 100644
index 000000000..0e3720b4f
--- /dev/null
+++ b/src/components/Cards/images/hearts.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/pages/GamePage/GamePage.jsx b/src/pages/GamePage/GamePage.jsx
index a4be871db..fa33617ba 100644
--- a/src/pages/GamePage/GamePage.jsx
+++ b/src/pages/GamePage/GamePage.jsx
@@ -4,10 +4,13 @@ import { Cards } from "../../components/Cards/Cards";
export function GamePage() {
const { pairsCount } = useParams();
+ const { isGameMode } = useParams();
+ console.log(isGameMode);
+ console.log(pairsCount);
return (
<>
-
+
>
);
}
diff --git a/src/pages/SelectLevelPage/SelectLevelPage.jsx b/src/pages/SelectLevelPage/SelectLevelPage.jsx
index 758942e51..22ccf6429 100644
--- a/src/pages/SelectLevelPage/SelectLevelPage.jsx
+++ b/src/pages/SelectLevelPage/SelectLevelPage.jsx
@@ -1,28 +1,34 @@
import { Link } from "react-router-dom";
import styles from "./SelectLevelPage.module.css";
+import { useState } from "react";
export function SelectLevelPage() {
+ const [checked, setChecked] = useState(false);
return (
);
diff --git a/src/pages/SelectLevelPage/SelectLevelPage.module.css b/src/pages/SelectLevelPage/SelectLevelPage.module.css
index 390ac0def..10fff2fd8 100644
--- a/src/pages/SelectLevelPage/SelectLevelPage.module.css
+++ b/src/pages/SelectLevelPage/SelectLevelPage.module.css
@@ -62,3 +62,35 @@
.levelLink:visited {
color: #0080c1;
}
+
+.gameMode {
+ color: #004980;
+ text-align: center;
+ font-variant-numeric: lining-nums proportional-nums;
+ font-family: StratosSkyeng;
+ font-size: 20px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 48px;
+ border-radius: 12px;
+}
+
+.gameMode input {
+ display: none;
+}
+
+.gameMode label {
+ background-color: white;
+ border-radius: 12px;
+ padding: 10px;
+}
+
+.gameMode input:checked+label {
+ color: white;
+ background-color: #004980;
+}
+
+.gameMode:hover {
+ color: white;
+ background-color: #004980;
+}
\ No newline at end of file
diff --git a/src/router.js b/src/router.js
index da6e94b51..a3429490b 100644
--- a/src/router.js
+++ b/src/router.js
@@ -9,7 +9,7 @@ export const router = createBrowserRouter(
element:
,
},
{
- path: "/game/:pairsCount",
+ path: "/game/:pairsCount/:isGameMode",
element:
,
},
],
From 85ed9f5c74fa94a11f205a442960e27f398d9249 Mon Sep 17 00:00:00 2001
From: NastyaTsyf <131529051+NastyaTsyf@users.noreply.github.com>
Date: Wed, 10 Apr 2024 22:19:29 +0400
Subject: [PATCH 2/7] Update README.md
---
README.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/README.md b/README.md
index 9b90842c4..a4c033e73 100644
--- a/README.md
+++ b/README.md
@@ -44,3 +44,6 @@ https://skypro-web-developer.github.io/react-memo/
Запускает eslint проверку кода, эта же команда запускается перед каждым коммитом.
Если не получается закоммитить, попробуйте запустить эту команду и исправить все ошибки и предупреждения.
+
+Предплагаемое время на выполнение ДЗ №1 5 часов
+фактическое время 6.5 часов
From a73cc10b0707c5131f0ed7ed4eff8a429505b472 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D1=82=D0=B2=D0=BE=D0=B5=20=D0=B8=D0=BC=D1=8F?=
<твоя почта>
Date: Sun, 28 Apr 2024 13:06:25 +0400
Subject: [PATCH 3/7] =?UTF-8?q?=D0=B4=D0=B7=20=E2=84=962?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/api.js | 27 +++++++
src/components/EndGameModal/EndGameModal.jsx | 71 ++++++++++++++++++-
.../EndGameModal/EndGameModal.module.css | 45 ++++++++++--
src/pages/LeaderboardPage/LeaderboardPage.jsx | 52 ++++++++++++++
.../LeaderboardPage.module.css | 64 +++++++++++++++++
src/pages/SelectLevelPage/SelectLevelPage.jsx | 7 +-
.../SelectLevelPage.module.css | 21 +++++-
src/router.js | 5 ++
8 files changed, 283 insertions(+), 9 deletions(-)
create mode 100644 src/api.js
create mode 100644 src/pages/LeaderboardPage/LeaderboardPage.jsx
create mode 100644 src/pages/LeaderboardPage/LeaderboardPage.module.css
diff --git a/src/api.js b/src/api.js
new file mode 100644
index 000000000..4e982df8b
--- /dev/null
+++ b/src/api.js
@@ -0,0 +1,27 @@
+//Получить список лидеров
+
+export async function getLeaders() {
+ const response = await fetch(`https://wedev-api.sky.pro/api/leaderboard`, { method: "GET" });
+ if (!response.status === 200) {
+ throw new Error("Не удалось получить список лидеров");
+ }
+ const data = await response.json();
+ return data;
+}
+
+export async function addLeaders({ name, time }) {
+ const response = await fetch(`https://wedev-api.sky.pro/api/leaderboard`, {
+ method: "POST",
+ body: JSON.stringify({
+ name,
+ time,
+ }),
+ });
+ if (!response.status === 201) {
+ throw new Error("Не удалось добавить в список лидеров");
+ } else if (response.status === 400) {
+ throw new Error("Введите Ваше имя");
+ }
+ const data = await response.json();
+ return data;
+}
diff --git a/src/components/EndGameModal/EndGameModal.jsx b/src/components/EndGameModal/EndGameModal.jsx
index 722394833..14b3a4ef5 100644
--- a/src/components/EndGameModal/EndGameModal.jsx
+++ b/src/components/EndGameModal/EndGameModal.jsx
@@ -4,9 +4,57 @@ import { Button } from "../Button/Button";
import deadImageUrl from "./images/dead.png";
import celebrationImageUrl from "./images/celebration.png";
+import { useNavigate, useParams } from "react-router-dom";
+import { useState } from "react";
+import { addLeaders } from "../../api";
export function EndGameModal({ isWon, gameDurationSeconds, gameDurationMinutes, onClick }) {
- const title = isWon ? "Вы победили!" : "Вы проиграли!";
+ const { isGameMode } = useParams();
+ const { pairsCount } = useParams();
+ const navigate = useNavigate();
+ const gameSeconds = gameDurationMinutes * 60 + gameDurationSeconds;
+ console.log(gameSeconds);
+ const [userData, setuserData] = useState({
+ name: " ",
+ time: gameSeconds,
+ });
+
+ const handleInputChange = e => {
+ const { name, value } = e.target; // Извлекаем имя поля и его значение
+
+ setuserData({
+ ...userData, // Копируем текущие данные из состояния
+ [name]: value, // Обновляем нужное поле
+ });
+ };
+
+ async function handleAddUser(e) {
+ e.preventDefault();
+ try {
+ await addLeaders(userData).then(data => {
+ navigate(`/leaderboard`);
+ });
+ } catch (error) {
+ alert(error.message);
+ }
+ }
+ async function handleAddUserButton(e) {
+ e.preventDefault();
+ try {
+ await addLeaders(userData).then(data => {
+ onClick();
+ });
+ } catch (error) {
+ alert(error.message);
+ }
+ }
+
+ let title = "";
+ if (pairsCount === "9") {
+ title = isWon ? "Вы попали на лидерборд!" : "Вы проиграли!";
+ } else {
+ title = isWon ? "Вы победили!" : "Вы проиграли!";
+ }
const imgSrc = isWon ? celebrationImageUrl : deadImageUrl;
@@ -16,12 +64,29 @@ export function EndGameModal({ isWon, gameDurationSeconds, gameDurationMinutes,
{title}
+ {isGameMode === "false" && pairsCount === "9" && isWon ? (
+
+ ) : null}
Затраченное время:
{gameDurationMinutes.toString().padStart("2", "0")}.{gameDurationSeconds.toString().padStart("2", "0")}
-
-
+
+ {isGameMode === "false" && pairsCount === "9" && isWon ? (
+
+ Перейти к лидерборду
+
+ ) : null}
);
}
diff --git a/src/components/EndGameModal/EndGameModal.module.css b/src/components/EndGameModal/EndGameModal.module.css
index 9368cb8b5..593431089 100644
--- a/src/components/EndGameModal/EndGameModal.module.css
+++ b/src/components/EndGameModal/EndGameModal.module.css
@@ -1,6 +1,7 @@
.modal {
width: 480px;
- height: 459px;
+ padding-top: 30px;
+ padding-bottom: 30px;
border-radius: 12px;
background: #c2f5ff;
display: flex;
@@ -23,7 +24,7 @@
font-style: normal;
font-weight: 400;
line-height: 48px;
-
+ text-align: center;
margin-bottom: 28px;
}
@@ -35,7 +36,6 @@
font-style: normal;
font-weight: 400;
line-height: 32px;
-
margin-bottom: 10px;
}
@@ -46,6 +46,43 @@
font-style: normal;
font-weight: 400;
line-height: 72px;
-
margin-bottom: 40px;
}
+
+
+.leaderboardLink {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ color: #004980;
+ text-align: center;
+ font-variant-numeric: lining-nums proportional-nums;
+ font-family: StratosSkyeng;
+ font-size: 18px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 32px;
+ text-decoration:underline
+}
+
+.leaderboardLink:hover {
+ text-decoration:none
+}
+
+.form{
+ padding-top: 10px;
+ padding-bottom: 20px;
+}
+.nameInput {
+ width:276px;
+ height:45px;
+ border-radius:10px;
+ border: none;
+ color: #999999;
+ text-align: center;
+ font-variant-numeric: lining-nums proportional-nums;
+ font-family: StratosSkyeng;
+ font-size: 24px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 32px;
+}
diff --git a/src/pages/LeaderboardPage/LeaderboardPage.jsx b/src/pages/LeaderboardPage/LeaderboardPage.jsx
new file mode 100644
index 000000000..4fcf6bf43
--- /dev/null
+++ b/src/pages/LeaderboardPage/LeaderboardPage.jsx
@@ -0,0 +1,52 @@
+import styles from "./LeaderboardPage.module.css";
+import { useEffect, useState } from "react";
+import { getLeaders } from "../../api";
+import { Button } from "../../components/Button/Button";
+import { useNavigate } from "react-router-dom";
+
+export function LeaderboardPage() {
+ const [leaders, setLeaders] = useState([]);
+ useEffect(() => {
+ getLeaders().then(leadersList => {
+ setLeaders(leadersList.leaders);
+ });
+ }, []);
+ const navigate = useNavigate();
+ const startTheGame = e => {
+ e.preventDefault();
+ navigate(`/`);
+ };
+
+ let i = 1;
+ return (
+
+
+
Лидерборд
+
+
+
+
+ );
+}
diff --git a/src/pages/LeaderboardPage/LeaderboardPage.module.css b/src/pages/LeaderboardPage/LeaderboardPage.module.css
new file mode 100644
index 000000000..86c985843
--- /dev/null
+++ b/src/pages/LeaderboardPage/LeaderboardPage.module.css
@@ -0,0 +1,64 @@
+* {
+ margin: 0;
+ padding: 0;
+}
+
+.container {
+ padding: 40px;
+}
+
+.header{
+ display: flex;
+ justify-content:space-between
+}
+
+.leaderboard {
+ padding-top: 40px;
+ display: flex;
+ flex-direction:column;
+ gap: 12px;
+}
+
+.headerTitle {
+ color: #FFFFFF;
+ font-variant-numeric: lining-nums proportional-nums;
+ font-family: StratosSkyeng;
+ font-size: 24px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 32px;
+ text-align: center;
+}
+
+.leadersItemTitle {
+ color: #999999;
+ list-style-type:none;
+ background-color: #FFFFFF;
+ padding: 10px 20px;
+ border-radius: 12px;
+ display: flex;
+ justify-content:space-between;
+ font-variant-numeric: lining-nums proportional-nums;
+ font-family: StratosSkyeng;
+ font-size: 24px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 32px;
+}
+
+.leadersItem {
+ list-style-type:none;
+ background-color: #FFFFFF;
+ padding: 10px 20px;
+ border-radius: 12px;
+ display: flex;
+ justify-content:space-between;
+ font-variant-numeric: lining-nums proportional-nums;
+ font-family: StratosSkyeng;
+ font-size: 24px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 32px;
+}
+
+
diff --git a/src/pages/SelectLevelPage/SelectLevelPage.jsx b/src/pages/SelectLevelPage/SelectLevelPage.jsx
index 22ccf6429..3a6bab369 100644
--- a/src/pages/SelectLevelPage/SelectLevelPage.jsx
+++ b/src/pages/SelectLevelPage/SelectLevelPage.jsx
@@ -27,7 +27,12 @@ export function SelectLevelPage() {
setChecked(!checked)} id="gameMode" />
-
+
+
+
+
+ Перейти к лидерборду
+
diff --git a/src/pages/SelectLevelPage/SelectLevelPage.module.css b/src/pages/SelectLevelPage/SelectLevelPage.module.css
index 10fff2fd8..4fe631cc3 100644
--- a/src/pages/SelectLevelPage/SelectLevelPage.module.css
+++ b/src/pages/SelectLevelPage/SelectLevelPage.module.css
@@ -80,7 +80,6 @@
}
.gameMode label {
- background-color: white;
border-radius: 12px;
padding: 10px;
}
@@ -93,4 +92,24 @@
.gameMode:hover {
color: white;
background-color: #004980;
+}
+
+.leaderboardLinkBox {
+ padding-top: 10px;
+ padding-bottom: 10px;
+}
+
+.leaderboardLink {
+ color: #004980;
+ text-align: center;
+ font-variant-numeric: lining-nums proportional-nums;
+ font-family: StratosSkyeng;
+ font-size: 18px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 32px;
+}
+
+.leaderboardLink:hover {
+ text-decoration:none
}
\ No newline at end of file
diff --git a/src/router.js b/src/router.js
index a3429490b..b3a22d233 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 { LeaderboardPage } from "./pages/LeaderboardPage/LeaderboardPage";
export const router = createBrowserRouter(
[
@@ -12,6 +13,10 @@ export const router = createBrowserRouter(
path: "/game/:pairsCount/:isGameMode",
element:
@@ -220,6 +251,58 @@ export function Cards({ pairsCount = 3, previewSeconds = 5, isGameMode }) {
{status === STATUS_IN_PROGRESS ? (
<>
+
+
+
+
+
{isGameMode === "true" ? (
) : null}
diff --git a/src/components/EndGameModal/EndGameModal.jsx b/src/components/EndGameModal/EndGameModal.jsx
index 14b3a4ef5..36d847b5e 100644
--- a/src/components/EndGameModal/EndGameModal.jsx
+++ b/src/components/EndGameModal/EndGameModal.jsx
@@ -8,15 +8,18 @@ import { useNavigate, useParams } from "react-router-dom";
import { useState } from "react";
import { addLeaders } from "../../api";
-export function EndGameModal({ isWon, gameDurationSeconds, gameDurationMinutes, onClick }) {
+export function EndGameModal({ isWon, gameDurationSeconds, gameDurationMinutes, onClick, achievementsArr }) {
+ console.log(achievementsArr);
+ isWon = true;
const { isGameMode } = useParams();
const { pairsCount } = useParams();
const navigate = useNavigate();
const gameSeconds = gameDurationMinutes * 60 + gameDurationSeconds;
- console.log(gameSeconds);
+
const [userData, setuserData] = useState({
name: " ",
time: gameSeconds,
+ achievements: achievementsArr,
});
const handleInputChange = e => {
diff --git a/src/lib.jsx b/src/lib.jsx
new file mode 100644
index 000000000..3b9be090d
--- /dev/null
+++ b/src/lib.jsx
@@ -0,0 +1,164 @@
+export const achievementsIcons = {
+ hardMode: (
+
+ ),
+ hardModeActive: (
+
+ ),
+ withoutSuperPowers: (
+
+ ),
+ withoutSuperPowersActive: (
+
+ ),
+};
diff --git a/src/pages/GamePage/GamePage.jsx b/src/pages/GamePage/GamePage.jsx
index fa33617ba..4c5404265 100644
--- a/src/pages/GamePage/GamePage.jsx
+++ b/src/pages/GamePage/GamePage.jsx
@@ -5,8 +5,6 @@ import { Cards } from "../../components/Cards/Cards";
export function GamePage() {
const { pairsCount } = useParams();
const { isGameMode } = useParams();
- console.log(isGameMode);
- console.log(pairsCount);
return (
<>
diff --git a/src/pages/LeaderboardPage/LeaderboardPage.jsx b/src/pages/LeaderboardPage/LeaderboardPage.jsx
index 4fcf6bf43..cc00e3f74 100644
--- a/src/pages/LeaderboardPage/LeaderboardPage.jsx
+++ b/src/pages/LeaderboardPage/LeaderboardPage.jsx
@@ -3,6 +3,7 @@ import { useEffect, useState } from "react";
import { getLeaders } from "../../api";
import { Button } from "../../components/Button/Button";
import { useNavigate } from "react-router-dom";
+import { achievementsIcons } from "../../lib";
export function LeaderboardPage() {
const [leaders, setLeaders] = useState([]);
@@ -28,6 +29,7 @@ export function LeaderboardPage() {
Позиция
Пользователь
+
Достижения
Время
{leaders
@@ -37,6 +39,16 @@ export function LeaderboardPage() {
# {i++}
{leader.name}
+
+
+ {leader.achievements.includes(1) ? achievementsIcons.hardModeActive : achievementsIcons.hardMode}
+
+
+ {leader.achievements.includes(2)
+ ? achievementsIcons.withoutSuperPowersActive
+ : achievementsIcons.withoutSuperPowers}
+
+
{Math.trunc(leader.time / 60)
.toString()
diff --git a/src/pages/LeaderboardPage/LeaderboardPage.module.css b/src/pages/LeaderboardPage/LeaderboardPage.module.css
index 86c985843..319d71573 100644
--- a/src/pages/LeaderboardPage/LeaderboardPage.module.css
+++ b/src/pages/LeaderboardPage/LeaderboardPage.module.css
@@ -61,4 +61,9 @@
line-height: 32px;
}
+.achievementsIcons{
+ display: flex;
+ gap: 6px;
+}
+
From a8b78b5d2861c6aa80e06b7c0f1a498a3b67570e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D1=82=D0=B2=D0=BE=D0=B5=20=D0=B8=D0=BC=D1=8F?=
<твоя почта>
Date: Fri, 21 Jun 2024 13:17:16 +0400
Subject: [PATCH 6/7] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?=
=?UTF-8?q?=D0=BD=D1=8B=20=D0=BF=D0=BE=D0=B4=D1=81=D0=BA=D0=B0=D0=B7=D0=BA?=
=?UTF-8?q?=D0=B8=20=D0=BF=D1=80=D0=B8=20=D0=BD=D0=B0=D0=B2=D0=B5=D0=B4?=
=?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/Cards/Cards.jsx | 104 +++++++++---------
src/components/Tooltip/Tooltip.jsx | 22 ++++
src/components/Tooltip/Tooltip.module.css | 25 +++++
src/pages/LeaderboardPage/LeaderboardPage.jsx | 23 ++--
4 files changed, 115 insertions(+), 59 deletions(-)
create mode 100644 src/components/Tooltip/Tooltip.jsx
create mode 100644 src/components/Tooltip/Tooltip.module.css
diff --git a/src/components/Cards/Cards.jsx b/src/components/Cards/Cards.jsx
index 5f78e7c7c..dcb983ff1 100644
--- a/src/components/Cards/Cards.jsx
+++ b/src/components/Cards/Cards.jsx
@@ -5,6 +5,8 @@ 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 { ToolTipComponent } from "../Tooltip/Tooltip";
+import { superPowerData } from "../../lib";
// Игра закончилась
const STATUS_LOST = "STATUS_LOST";
@@ -252,56 +254,58 @@ export function Cards({ pairsCount = 3, previewSeconds = 5, isGameMode }) {
{status === STATUS_IN_PROGRESS ? (
<>
-
-
-
+
+
+
+
+
{isGameMode === "true" ? (
diff --git a/src/components/Tooltip/Tooltip.jsx b/src/components/Tooltip/Tooltip.jsx
new file mode 100644
index 000000000..89c0daf10
--- /dev/null
+++ b/src/components/Tooltip/Tooltip.jsx
@@ -0,0 +1,22 @@
+import { useState } from "react";
+import styles from "./Tooltip.module.css";
+export function ToolTipComponent({ children, text, title }) {
+ const [showToolTip, setShowToolTip] = useState(false);
+ const onMouseEnterHandler = () => {
+ setShowToolTip(true);
+ };
+ const onMouseLeaveHandler = () => {
+ setShowToolTip(false);
+ };
+ return (
+
+ {children}
+ {showToolTip && (
+
+ )}
+
+ );
+}
diff --git a/src/components/Tooltip/Tooltip.module.css b/src/components/Tooltip/Tooltip.module.css
new file mode 100644
index 000000000..38e9cd91f
--- /dev/null
+++ b/src/components/Tooltip/Tooltip.module.css
@@ -0,0 +1,25 @@
+.container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+}
+
+.tooltip {
+ margin-top: 170px;
+ font-family: StratosSkyeng;
+ font-size: 18px;
+ font-style: normal;
+ position: absolute;
+ padding: 20px;
+ justify-content: center;
+ color: #004980;
+ background-color: #C2F5FF;
+ border-radius: 12px;
+ text-align: center;
+ white-space: pre-line;
+ font-weight: 400;
+ pointer-events: none;
+ z-index: 2;
+ max-height: 223px;
+}
\ No newline at end of file
diff --git a/src/pages/LeaderboardPage/LeaderboardPage.jsx b/src/pages/LeaderboardPage/LeaderboardPage.jsx
index cc00e3f74..4d07b46e4 100644
--- a/src/pages/LeaderboardPage/LeaderboardPage.jsx
+++ b/src/pages/LeaderboardPage/LeaderboardPage.jsx
@@ -3,7 +3,8 @@ import { useEffect, useState } from "react";
import { getLeaders } from "../../api";
import { Button } from "../../components/Button/Button";
import { useNavigate } from "react-router-dom";
-import { achievementsIcons } from "../../lib";
+import { achievementsIcons, achievementsText } from "../../lib";
+import { ToolTipComponent } from "../../components/Tooltip/Tooltip";
export function LeaderboardPage() {
const [leaders, setLeaders] = useState([]);
@@ -40,14 +41,18 @@ export function LeaderboardPage() {
# {i++}
{leader.name}
-
- {leader.achievements.includes(1) ? achievementsIcons.hardModeActive : achievementsIcons.hardMode}
-
-
- {leader.achievements.includes(2)
- ? achievementsIcons.withoutSuperPowersActive
- : achievementsIcons.withoutSuperPowers}
-
+
+
+ {leader.achievements.includes(1) ? achievementsIcons.hardModeActive : achievementsIcons.hardMode}
+
+
+
+
+ {leader.achievements.includes(2)
+ ? achievementsIcons.withoutSuperPowersActive
+ : achievementsIcons.withoutSuperPowers}
+
+
{Math.trunc(leader.time / 60)
From 1661ff94ef536665d8a464ab15f6d44a48b348ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D1=82=D0=B2=D0=BE=D0=B5=20=D0=B8=D0=BC=D1=8F?=
<твоя почта>
Date: Fri, 21 Jun 2024 13:17:54 +0400
Subject: [PATCH 7/7] 1
---
src/lib.jsx | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/lib.jsx b/src/lib.jsx
index 3b9be090d..335e37b2b 100644
--- a/src/lib.jsx
+++ b/src/lib.jsx
@@ -1,3 +1,15 @@
+export const superPowerData = {
+ alohomora: {
+ title: "Алохомора",
+ text: "Открывается случайная пара карт",
+ },
+};
+
+export const achievementsText = {
+ hardMode: "Игра пройдена в сложном режиме",
+ withoutSuperPowers: "Игра пройдена без супер-сил",
+};
+
export const achievementsIcons = {
hardMode: (