├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── public
├── favicon.ico
├── img
│ ├── angular.png
│ ├── css.png
│ ├── game-preview.png
│ ├── html.png
│ ├── js.png
│ ├── nodejs.png
│ ├── react.png
│ ├── scss.png
│ └── vue.png
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
└── src
├── App.js
├── components
├── Card.js
└── Cards.js
├── index.css
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React Memory Game
2 | ## Step by step tutorial available on [YouTube](https://youtu.be/qhOZoJPMg6w)
3 |
4 | 
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "memory-game",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.15.1",
7 | "@testing-library/react": "^11.2.7",
8 | "@testing-library/user-event": "^12.8.3",
9 | "react": "^17.0.2",
10 | "react-dom": "^17.0.2",
11 | "react-scripts": "4.0.3",
12 | "web-vitals": "^1.1.2"
13 | },
14 | "scripts": {
15 | "start": "react-scripts start",
16 | "build": "react-scripts build",
17 | "test": "react-scripts test",
18 | "eject": "react-scripts eject"
19 | },
20 | "eslintConfig": {
21 | "extends": [
22 | "react-app",
23 | "react-app/jest"
24 | ]
25 | },
26 | "browserslist": {
27 | "production": [
28 | ">0.2%",
29 | "not dead",
30 | "not op_mini all"
31 | ],
32 | "development": [
33 | "last 1 chrome version",
34 | "last 1 firefox version",
35 | "last 1 safari version"
36 | ]
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0shuvo0/react-memory-game/7d15e0352b76c06a2208ed6db92b370021bad792/public/favicon.ico
--------------------------------------------------------------------------------
/public/img/angular.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0shuvo0/react-memory-game/7d15e0352b76c06a2208ed6db92b370021bad792/public/img/angular.png
--------------------------------------------------------------------------------
/public/img/css.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0shuvo0/react-memory-game/7d15e0352b76c06a2208ed6db92b370021bad792/public/img/css.png
--------------------------------------------------------------------------------
/public/img/game-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0shuvo0/react-memory-game/7d15e0352b76c06a2208ed6db92b370021bad792/public/img/game-preview.png
--------------------------------------------------------------------------------
/public/img/html.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0shuvo0/react-memory-game/7d15e0352b76c06a2208ed6db92b370021bad792/public/img/html.png
--------------------------------------------------------------------------------
/public/img/js.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0shuvo0/react-memory-game/7d15e0352b76c06a2208ed6db92b370021bad792/public/img/js.png
--------------------------------------------------------------------------------
/public/img/nodejs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0shuvo0/react-memory-game/7d15e0352b76c06a2208ed6db92b370021bad792/public/img/nodejs.png
--------------------------------------------------------------------------------
/public/img/react.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0shuvo0/react-memory-game/7d15e0352b76c06a2208ed6db92b370021bad792/public/img/react.png
--------------------------------------------------------------------------------
/public/img/scss.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0shuvo0/react-memory-game/7d15e0352b76c06a2208ed6db92b370021bad792/public/img/scss.png
--------------------------------------------------------------------------------
/public/img/vue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0shuvo0/react-memory-game/7d15e0352b76c06a2208ed6db92b370021bad792/public/img/vue.png
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0shuvo0/react-memory-game/7d15e0352b76c06a2208ed6db92b370021bad792/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0shuvo0/react-memory-game/7d15e0352b76c06a2208ed6db92b370021bad792/public/logo512.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import Cards from './components/Cards'
2 |
3 | function App() {
4 | return (
5 |
6 |
Memory Game - React
7 |
8 |
9 | );
10 | }
11 |
12 | export default App;
13 |
--------------------------------------------------------------------------------
/src/components/Card.js:
--------------------------------------------------------------------------------
1 | function Card({item, id, handleClick}){
2 | const itemClass = item.stat ? " active " + item.stat : ""
3 |
4 | return (
5 | handleClick(id)}>
6 |

7 |
8 | )
9 | }
10 |
11 | export default Card
--------------------------------------------------------------------------------
/src/components/Cards.js:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import Card from './Card'
3 |
4 | function Cards(){
5 | const [items, setItems] = useState([
6 | { id: 1, img: '/img/html.png', stat: "" },
7 | { id: 1, img: '/img/html.png', stat: "" },
8 | { id: 2, img: '/img/css.png', stat: "" },
9 | { id: 2, img: '/img/css.png', stat: "" },
10 | { id: 3, img: '/img/js.png', stat: "" },
11 | { id: 3, img: '/img/js.png', stat: "" },
12 | { id: 4, img: '/img/scss.png', stat: "" },
13 | { id: 4, img: '/img/scss.png', stat: "" },
14 | { id: 5, img: '/img/react.png', stat: "" },
15 | { id: 5, img: '/img/react.png', stat: "" },
16 | { id: 6, img: '/img/vue.png', stat: "" },
17 | { id: 6, img: '/img/vue.png', stat: "" },
18 | { id: 7, img: '/img/angular.png', stat: "" },
19 | { id: 7, img: '/img/angular.png', stat: "" },
20 | { id: 8, img: '/img/nodejs.png', stat: "" },
21 | { id: 8, img: '/img/nodejs.png', stat: "" }
22 | ].sort(() => Math.random() - 0.5))
23 |
24 | const [prev, setPrev] = useState(-1)
25 |
26 | function check(current){
27 | if(items[current].id == items[prev].id){
28 | items[current].stat = "correct"
29 | items[prev].stat = "correct"
30 | setItems([...items])
31 | setPrev(-1)
32 | }else{
33 | items[current].stat = "wrong"
34 | items[prev].stat = "wrong"
35 | setItems([...items])
36 | setTimeout(() => {
37 | items[current].stat = ""
38 | items[prev].stat = ""
39 | setItems([...items])
40 | setPrev(-1)
41 | }, 1000)
42 | }
43 | }
44 |
45 | function handleClick(id){
46 | if(prev === -1){
47 | items[id].stat = "active"
48 | setItems([...items])
49 | setPrev(id)
50 | }else{
51 | check(id)
52 | }
53 | }
54 |
55 | return (
56 |
57 | { items.map((item, index) => (
58 |
59 | )) }
60 |
61 | )
62 | }
63 |
64 | export default Cards
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | *{
2 | margin: 0;
3 | padding: 0;
4 | }
5 | html, body{
6 | height: 100%;
7 | }
8 | body{
9 | font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
10 | background-color: #fae19d;
11 | display: flex;
12 | justify-content: center;
13 | align-items: center;
14 | }
15 |
16 | h1{
17 | text-align: center;
18 | margin-bottom: 1em;
19 | }
20 | .container{
21 | height: 700px;
22 | width: 700px;
23 | display: grid;
24 | grid-template-columns: repeat(4, 1fr);
25 | grid-template-rows: repeat(4, 1fr);
26 | gap: 1em;
27 | }
28 |
29 | .card{
30 | background-color: #fff;
31 | display: flex;
32 | justify-content: center;
33 | align-items: center;
34 | border-radius: 5px;
35 | transform: rotateY(180deg);
36 | animation: 2s hideCard linear;
37 | transition: transform 0.5s;
38 | }
39 | @keyframes hideCard{
40 | 0%, 70%{
41 | transform: rotateY(0);
42 | }
43 | 100%{
44 | transform: rotateY(180deg);
45 | }
46 | }
47 | .card img{
48 | max-width: 80%;
49 | max-height: 80%;
50 | transition: transform 0.5s;
51 | transform: scale(0);
52 | animation: 2s hideImage linear;
53 | }
54 | @keyframes hideImage{
55 | 0%, 70%{
56 | transform: scale(1);
57 | }
58 | 100%{
59 | transform: scale(0);
60 | }
61 | }
62 |
63 | .card.active{
64 | transform: rotateY(0);
65 | }
66 | .card.correct{
67 | background-color: #65e469;
68 | }
69 | .card.wrong{
70 | background-color: #fd245a;
71 | }
72 | .card.active img{
73 | transform: scale(1);
74 | }
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | ReactDOM.render(
6 |
7 |
8 | ,
9 | document.getElementById('root')
10 | );
11 |
--------------------------------------------------------------------------------