From 534e185c55e71d0180bbe85c16ffe5a23a9d5eb6 Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Tue, 26 Jul 2022 08:21:40 +0500 Subject: [PATCH] add styles --- src/components/Card/Card.module.scss | 16 +++++++-- .../CardsField/CardsField.module.scss | 13 ++----- src/components/CardsField/CardsField.tsx | 22 ++++++++++-- .../GoToMenuButton/GoToMenuButton.module.scss | 4 +++ .../GoToMenuButton/GoToMenuButton.tsx | 20 +++++++++++ .../UI/BottomPanel/BottomPanel.module.scss | 1 + src/components/UI/BottomPanel/BottomPanel.tsx | 8 +++-- src/components/UI/Button/Button.module.scss | 18 ++++++++-- src/components/UI/Button/Button.tsx | 7 ++-- src/context/MatchGameContext.tsx | 36 ++++++++++++++++--- src/pages/MatchGame/MatchGame.module.scss | 4 +++ src/pages/MatchGame/MatchGame.tsx | 29 +++++++-------- src/pages/MatchMenu/MatchMenu.module.scss | 1 + src/pages/MatchMenu/MatchMenu.tsx | 3 ++ src/pages/Options/Options.module.scss | 4 ++- src/pages/Options/Options.tsx | 3 +- 16 files changed, 143 insertions(+), 46 deletions(-) create mode 100644 src/components/GoToMenuButton/GoToMenuButton.module.scss create mode 100644 src/components/GoToMenuButton/GoToMenuButton.tsx diff --git a/src/components/Card/Card.module.scss b/src/components/Card/Card.module.scss index 918eba5..f65567b 100644 --- a/src/components/Card/Card.module.scss +++ b/src/components/Card/Card.module.scss @@ -1,14 +1,14 @@ @import url('https://fonts.googleapis.com/css2?family=Pacifico&display=swap'); -.CardWrapper{ +.CardWrapper { display: flex; align-items: center; justify-content: center; transition: opacity 1300ms ease-in; .Card { - width: 100px; - height: 100px; + width: 80px; + height: 80px; font-family: 'Pacifico', sans-serif; font-size: 48px; display: flex; @@ -56,3 +56,13 @@ } +@media(max-width: 400px) { + .CardWrapper { + .Card { + width: 50px; + height: 50px; + } + } + +} + diff --git a/src/components/CardsField/CardsField.module.scss b/src/components/CardsField/CardsField.module.scss index e6f5d04..47a63cc 100644 --- a/src/components/CardsField/CardsField.module.scss +++ b/src/components/CardsField/CardsField.module.scss @@ -3,15 +3,8 @@ position: relative; border: 2px solid #fff; border-radius: 10px; - width: 500px; - height: 500px; + min-height: 500px; display: grid; - grid-template-columns: 1fr 1fr 1fr; - grid-template-rows: 1fr 1fr 1fr 1fr; - grid-auto-flow: row; - grid-template-areas: - ". . ." - ". . ." - ". . ." - ". . ."; + gap: 15px; + padding: 20px; } diff --git a/src/components/CardsField/CardsField.tsx b/src/components/CardsField/CardsField.tsx index 65f76d7..8c19bc2 100644 --- a/src/components/CardsField/CardsField.tsx +++ b/src/components/CardsField/CardsField.tsx @@ -1,3 +1,4 @@ +import { DiffLevel, FieldSize } from 'pages/Options/Options'; import React, { useCallback, useEffect, useState } from 'react'; import { v4 as uuidv4 } from 'uuid'; @@ -34,7 +35,7 @@ const CardsField: React.FC = ({cards, isGameStarted = false, fi const [cardsState, setCardsState] = useState(getInitialConfig(isNewGame)); const [currentCardPare, setCurrentCardPare] = useState({first: null, second: null}) - const {addMistakesCount} = useMatchGame(); + const {addMistakesCount, filedSize, diffLevel} = useMatchGame(); function getInitialConfig(isNewGame: boolean): CardComponentProps[] { if (!isNewGame) { @@ -142,8 +143,25 @@ const CardsField: React.FC = ({cards, isGameStarted = false, fi )); } + function getStyles(): React.CSSProperties { + const size = { + gridTemplateColumns: '', + gridTemplateRows: '', + }; + + if (diffLevel === DiffLevel.Easy) size.gridTemplateColumns = 'repeat(3, 1fr)'; + if (diffLevel === DiffLevel.Normal) size.gridTemplateColumns = 'repeat(4, 1fr)'; + if (diffLevel === DiffLevel.Hard) size.gridTemplateColumns = 'repeat(5, 1fr)'; + + if (filedSize === FieldSize.Small) size.gridTemplateRows = 'repeat(2, 1fr)'; + if (filedSize === FieldSize.Normal) size.gridTemplateRows = 'repeat(4, 1fr)'; + if (filedSize === FieldSize.Big) size.gridTemplateRows = 'repeat(6, 1fr)'; + + return size; + } + return ( -
+
{renderCards()}
); diff --git a/src/components/GoToMenuButton/GoToMenuButton.module.scss b/src/components/GoToMenuButton/GoToMenuButton.module.scss new file mode 100644 index 0000000..65b9f1f --- /dev/null +++ b/src/components/GoToMenuButton/GoToMenuButton.module.scss @@ -0,0 +1,4 @@ +.Button { + width: 45px; + height: 45px; +} diff --git a/src/components/GoToMenuButton/GoToMenuButton.tsx b/src/components/GoToMenuButton/GoToMenuButton.tsx new file mode 100644 index 0000000..1957396 --- /dev/null +++ b/src/components/GoToMenuButton/GoToMenuButton.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import Button from 'components/UI/Button/Button'; +import { useMatchGame } from 'context/MatchGameContext'; + +import cls from './GoToMenuButton.module.scss'; + +const GoToMenuButton = () => { + const {setCurrentMenuItem, setIsGameStarted} = useMatchGame(); + + function onClickHandler() { + setIsGameStarted?.(false); + setCurrentMenuItem?.('menu') + } + + return ( + + ); +}; + +export default GoToMenuButton; diff --git a/src/components/UI/BottomPanel/BottomPanel.module.scss b/src/components/UI/BottomPanel/BottomPanel.module.scss index a1f6e05..5da5c4e 100644 --- a/src/components/UI/BottomPanel/BottomPanel.module.scss +++ b/src/components/UI/BottomPanel/BottomPanel.module.scss @@ -7,5 +7,6 @@ align-items: center; border: 2px solid #fff; border-radius: 10px; + max-width: 100%; } diff --git a/src/components/UI/BottomPanel/BottomPanel.tsx b/src/components/UI/BottomPanel/BottomPanel.tsx index 34ec1a9..e5ac9ca 100644 --- a/src/components/UI/BottomPanel/BottomPanel.tsx +++ b/src/components/UI/BottomPanel/BottomPanel.tsx @@ -2,11 +2,13 @@ import React from 'react'; import cls from './BottomPanel.module.scss'; -type BottomPanelProps = {} +type BottomPanelProps = { + style?: React.CSSProperties; +} -const BottomPanel: React.FC = ({children}) => { +const BottomPanel: React.FC = ({children, style}) => { return ( -
+
{ children }
); diff --git a/src/components/UI/Button/Button.module.scss b/src/components/UI/Button/Button.module.scss index b771bb6..a8b79f8 100644 --- a/src/components/UI/Button/Button.module.scss +++ b/src/components/UI/Button/Button.module.scss @@ -9,18 +9,32 @@ font-size: 22px; text-transform: uppercase; text-align: center; - letter-spacing: 3px; font-weight: 600; color: #524f4e; background: white; box-shadow: 0 8px 15px rgba(0, 0, 0, .1); transition: .3s; - &:hover, &:focus { + &:hover { background: #7986cb; box-shadow: 0 15px 20px rgba(121, 134, 203, 0.4); color: white; transform: translateY(-7px); cursor: pointer; } + &:active { + color: #524f4e; + transform: translateY(-5px); + } } + +@media (max-width: 400px) { + .Button { + width: 120px; + margin: 5px; + font-size: 20px; + letter-spacing: normal; + padding: 0; + } +} + diff --git a/src/components/UI/Button/Button.tsx b/src/components/UI/Button/Button.tsx index dd284e9..3b47e65 100644 --- a/src/components/UI/Button/Button.tsx +++ b/src/components/UI/Button/Button.tsx @@ -3,12 +3,13 @@ import cls from './Button.module.scss'; type ButtonProps = { className?: string, - onClick: (e: React.MouseEvent) => void + onClick: (e: React.MouseEvent) => void; + style?: React.CSSProperties; } -const Button: React.FC = ({children, className, onClick}) => { +const Button: React.FC = ({children, className, style, onClick}) => { return ( - ); diff --git a/src/context/MatchGameContext.tsx b/src/context/MatchGameContext.tsx index 81eec28..239743d 100644 --- a/src/context/MatchGameContext.tsx +++ b/src/context/MatchGameContext.tsx @@ -22,21 +22,43 @@ interface MatchGameContextType { const MatchGameContext = React.createContext({}); export const useMatchGame = () => useContext(MatchGameContext); +function getInitialSize() { + const sizeFromLocalStorage = localStorage.getItem('match-game:size'); + return sizeFromLocalStorage ? JSON.parse(sizeFromLocalStorage) : FieldSize.Small; +} + +function getInitialDiffLevel() { + const diffLevelFromLocalStorage = localStorage.getItem('match-game:diffLevel'); + return diffLevelFromLocalStorage ? JSON.parse(diffLevelFromLocalStorage) : DiffLevel.Easy; +} + +function getInitialTime() { + const timeFromLocalStorage = localStorage.getItem('match-game:time'); + return timeFromLocalStorage ? JSON.parse(timeFromLocalStorage) : 0; +} + +function getInitialMistakesCount() { + const mistakesCountFromLocalStorage = localStorage.getItem('match-game:mistakesCount'); + return mistakesCountFromLocalStorage ? JSON.parse(mistakesCountFromLocalStorage) : 0; +} + export const MatchGameProvider: React.FC = ({children}) => { - const [mistakesCount, setMistakesCount] = useState(0) - const [gameTime, setGameTime] = useState(0); + const [mistakesCount, setMistakesCount] = useState(getInitialMistakesCount) + const [gameTime, setGameTime] = useState(getInitialTime); const [currentMenuItem, setCurrentMenuItem] = useState('menu'); const [isGameStarted, setIsGameStarted] = useState(false); const [isGameFinished, setIsGameFinished] = useState(false); - const [filedSize, setFieldSize] = useState(FieldSize.Small); - const [diffLevel, setDiffLevel] = useState(DiffLevel.Easy); + const [filedSize, setFieldSize] = useState(getInitialSize); + const [diffLevel, setDiffLevel] = useState(getInitialDiffLevel); const addMistakesCount = () => { + localStorage.setItem('match-game:mistakesCount', JSON.stringify(mistakesCount + 1)); return setMistakesCount(prev => prev + 1) }; const changeGameTime = (time: number) => { setGameTime(time); + localStorage.setItem('match-game:time', JSON.stringify(time)); } const resetGameProgress = () => { @@ -44,12 +66,18 @@ export const MatchGameProvider: React.FC = ({children}) => { setGameTime(0); setIsGameStarted(false); setIsGameFinished(false); + localStorage.removeItem('match-game:cards'); + localStorage.removeItem('match-game:time'); + localStorage.removeItem('match-game:mistakesCount'); } const saveOptions = (options: OptionsType) => { setFieldSize(options.size); setDiffLevel(options.diffLevel); + + localStorage.setItem('match-game:size', JSON.stringify(options.size)); + localStorage.setItem('match-game:diffLevel', JSON.stringify(options.diffLevel)); } return ( diff --git a/src/pages/MatchGame/MatchGame.module.scss b/src/pages/MatchGame/MatchGame.module.scss index e69de29..81f2e99 100644 --- a/src/pages/MatchGame/MatchGame.module.scss +++ b/src/pages/MatchGame/MatchGame.module.scss @@ -0,0 +1,4 @@ +.MatchGameField { + width: 500px; + max-width: 100%; +} diff --git a/src/pages/MatchGame/MatchGame.tsx b/src/pages/MatchGame/MatchGame.tsx index bee61ec..ae911d4 100644 --- a/src/pages/MatchGame/MatchGame.tsx +++ b/src/pages/MatchGame/MatchGame.tsx @@ -1,3 +1,4 @@ +import GoToMenuButton from 'components/GoToMenuButton/GoToMenuButton'; import React, { useEffect, useState } from 'react'; import BottomPanel from 'components/UI/BottomPanel/BottomPanel'; import Button from 'components/UI/Button/Button'; @@ -7,6 +8,8 @@ import Timer from 'components/UI/Timer/Timer'; import { createCards, randomizeElementInArray } from 'src/utils'; import { useMatchGame } from 'context/MatchGameContext'; +import cls from './MatchGame.module.scss'; + interface MatchGameProps { isNewGame: boolean; } @@ -22,7 +25,6 @@ const MatchGame: React.FC = ({isNewGame}) => { isGameFinished, isGameStarted, changeGameTime, - setCurrentMenuItem, diffLevel, filedSize } = useMatchGame(); @@ -51,12 +53,10 @@ const MatchGame: React.FC = ({isNewGame}) => { } function retryGame() { - setIsGameFinished?.(false); - setIsGameStarted?.(false); setIsTimerStarted?.(false); - setCards(prev => randomizeElementInArray(prev.map(el => ({...el, disabled: true, isMatched: false, toggled: true})))) - resetGameProgress?.(); + + setCards(prev => randomizeElementInArray(prev.map(el => ({...el, disabled: true, isMatched: false, toggled: true})))) } function finishGame() { @@ -68,15 +68,10 @@ const MatchGame: React.FC = ({isNewGame}) => { setCards(randomizeElementInArray([...cards])); } - function goToMenu() { - setIsGameStarted?.(false); - setCurrentMenuItem?.('menu'); - } - function renderRetryStatePanel() { return ( <> - + ) @@ -85,12 +80,12 @@ const MatchGame: React.FC = ({isNewGame}) => { function renderStartStatePanel() { return isTimerStarted ? <> - + : <> - - + + {isNewGame && } } @@ -109,7 +104,7 @@ const MatchGame: React.FC = ({isNewGame}) => { } return ( - <> +
{ isGameFinished @@ -117,10 +112,10 @@ const MatchGame: React.FC = ({isNewGame}) => { : }
- + { renderPanelByState(panelState) } - +
); }; diff --git a/src/pages/MatchMenu/MatchMenu.module.scss b/src/pages/MatchMenu/MatchMenu.module.scss index 05167d4..40bc12e 100644 --- a/src/pages/MatchMenu/MatchMenu.module.scss +++ b/src/pages/MatchMenu/MatchMenu.module.scss @@ -9,6 +9,7 @@ ul { list-style: none; margin: 0; + padding: 0; li { text-align: center; cursor: pointer; diff --git a/src/pages/MatchMenu/MatchMenu.tsx b/src/pages/MatchMenu/MatchMenu.tsx index 920171b..f0cb15c 100644 --- a/src/pages/MatchMenu/MatchMenu.tsx +++ b/src/pages/MatchMenu/MatchMenu.tsx @@ -25,6 +25,9 @@ const MatchMenu: React.FC = () => { function clickItemHandler(item: MenuItem) { setCurrentMenuItem?.(item); + if (item === 'exit') { + window.location = 'https://google.com' as any; + } } function canContinueGame() { diff --git a/src/pages/Options/Options.module.scss b/src/pages/Options/Options.module.scss index 8dbb827..0dab0ce 100644 --- a/src/pages/Options/Options.module.scss +++ b/src/pages/Options/Options.module.scss @@ -9,10 +9,12 @@ border-radius: 10px; color: #ffffff; margin-bottom: 20px; + max-width: 100%; ul { list-style: none; margin: 0; + padding: 0; } h2 { @@ -24,7 +26,7 @@ display: flex; justify-content: space-between; align-items: center; - font-size: 30px; + font-size: 1.5rem; .button { width: 45px; diff --git a/src/pages/Options/Options.tsx b/src/pages/Options/Options.tsx index 7582efd..5850d62 100644 --- a/src/pages/Options/Options.tsx +++ b/src/pages/Options/Options.tsx @@ -1,3 +1,4 @@ +import GoToMenuButton from 'components/GoToMenuButton/GoToMenuButton'; import BottomPanel from 'components/UI/BottomPanel/BottomPanel'; import Button from 'components/UI/Button/Button'; import { useMatchGame } from 'context/MatchGameContext'; @@ -62,7 +63,7 @@ const Options: React.FC = () => {
- +