-
-
Save codecademydev/7c2835c2281c47c690e4139d9d3c3f17 to your computer and use it in GitHub Desktop.
Codecademy export
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import "./App.css"; | |
import React from "react"; | |
import { Score } from "./features/score/Score.js"; | |
import { Board } from "./features/board/Board.js"; | |
import { useDispatch } from "react-redux"; | |
import { setBoard, resetCards } from "./features/board/boardSlice.js"; | |
const App = () => { | |
const dispatch = useDispatch(); | |
const startGameHandler = () => { | |
dispatch(setBoard()); | |
}; | |
const tryAgainHandler = () => { | |
dispatch(resetCards()); | |
}; | |
return ( | |
<div className="App"> | |
<Score /> | |
<Board /> | |
<footer className="footer"> | |
<button onClick={startGameHandler} className="start-button"> | |
Start Game | |
</button> | |
<button onClick={tryAgainHandler} className="try-new-pair-button"> | |
Try New Pair | |
</button> | |
</footer> | |
</div> | |
); | |
}; | |
export default App; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import { CardRow } from "./cardRow/CardRow.js"; | |
import { useSelector } from "react-redux"; | |
import { selectBoard } from "./boardSlice.js"; | |
export const Board = () => { | |
const currentBoard = useSelector(selectBoard); | |
const numberOfCards = currentBoard.length; | |
const columns = 3; | |
const rows = Math.floor(numberOfCards / columns); | |
const getRowCards = (row) => { | |
const rowCards = []; | |
for (let j = 0; j < columns; j++) { | |
const cardIndex = row * columns + j; | |
rowCards.push(currentBoard[cardIndex]); | |
} | |
return rowCards; | |
}; | |
let content = []; | |
for (let row = 0; row < rows; row++) { | |
const rowCards = getRowCards(row); | |
content.push(<CardRow key={row} cards={rowCards} />); | |
} | |
return <div className="cards-container">{content}</div>; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const initialState = [ | |
{ id: 0, contents: "Provider", visible: true, matched: true }, | |
{ id: 1, contents: "Provider", visible: true, matched: true }, | |
{ id: 2, contents: "selector", visible: true, matched: true }, | |
{ id: 3, contents: "selector", visible: true, matched: true }, | |
{ id: 4, contents: "useSelector()", visible: true, matched: true }, | |
{ id: 5, contents: "useSelector()", visible: true, matched: true }, | |
{ id: 6, contents: "useDispatch()", visible: true, matched: true }, | |
{ id: 7, contents: "useDispatch()", visible: true, matched: true }, | |
{ id: 8, contents: "Pure Function", visible: true, matched: true }, | |
{ id: 9, contents: "Pure Function", visible: true, matched: true }, | |
{ id: 10, contents: "react-redux", visible: true, matched: true }, | |
{ id: 11, contents: "react-redux", visible: true, matched: true }, | |
]; | |
export const boardReducer = (state = initialState, action) => { | |
switch (action.type) { | |
case "board/setBoard": | |
let setState = []; | |
action.payload.forEach((element, index) => | |
setState.push({ | |
id: index, | |
contents: element, | |
visible: false, | |
matched: false, | |
}) | |
); | |
return setState; | |
case "board/flipCard": | |
let flipState = [...state]; | |
const cardID = action.payload; | |
flipState[cardID] = { ...state[cardID], visible: true }; | |
const [index1, index2] = flipState | |
.filter((card) => card.visible) | |
.map((card) => card.id); | |
if (index2 !== undefined) { | |
const card1 = flipState[index1]; | |
const card2 = flipState[index2]; | |
if (card1.contents === card2.contents) { | |
flipState[index1] = { ...card1, visible: false, matched: true }; | |
flipState[index2] = { ...card2, visible: false, matched: true }; | |
} | |
} | |
return flipState; | |
case "board/resetCards": | |
return state.map((card) => ({ ...card, visible: false })); | |
default: | |
return state; | |
} | |
}; | |
const wordPairs = [ | |
"Provider", | |
"Provider", | |
"selector", | |
"selector", | |
"useSelector()", | |
"useSelector()", | |
"useDispatch()", | |
"useDispatch()", | |
"Pure Function", | |
"Pure Function", | |
"react-redux", | |
"react-redux", | |
]; | |
const randomWords = () => { | |
let words = []; | |
let newWordPairs = [...wordPairs]; | |
const reps = newWordPairs.length; | |
for (let i = 0; i < reps; i++) { | |
const wordIndex = Math.floor(Math.random() * newWordPairs.length); | |
words.push(newWordPairs[wordIndex]); | |
newWordPairs.splice(wordIndex, 1); | |
} | |
return words; | |
}; | |
// action creators | |
export const setBoard = () => { | |
const words = randomWords(); | |
return { | |
type: "board/setBoard", | |
payload: words, | |
}; | |
}; | |
export const flipCard = (id) => { | |
return { | |
type: "board/flipCard", | |
payload: id, | |
}; | |
}; | |
export const resetCards = (indices) => { | |
return { | |
type: "board/resetCards", | |
}; | |
}; | |
export const selectBoard = (state) => | |
state.board.map((card) => ({ | |
id: card.id, | |
contents: card.contents, | |
})); | |
export const selectVisibleIDs = (state) => | |
state.board.filter((card) => card.visible).map((card) => card.id); | |
export const selectMatchedIDs = (state) => | |
state.board.filter((card) => card.matched).map((card) => card.id); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import { useSelector, useDispatch } from "react-redux"; | |
import { | |
selectVisibleIDs, | |
selectMatchedIDs, | |
flipCard, | |
resetCards, | |
} from "../../boardSlice.js"; | |
let cardLogo = | |
"https://static-assets.codecademy.com/Courses/Learn-Redux/matching-game/codecademy_logo.png"; | |
export const Card = ({ id, contents }) => { | |
const visibleIDs = useSelector(selectVisibleIDs); | |
const matchedIDs = useSelector(selectMatchedIDs); | |
const dispatch = useDispatch(); | |
const flipHandler = (id) => { | |
dispatch(flipCard(id)); | |
}; | |
const resetHandler = () => { | |
dispatch(resetCards()); | |
}; | |
let cardStyle = "resting"; | |
let click = () => flipHandler(id); | |
let cardText = ( | |
<img src={cardLogo} className="logo-placeholder" alt="Card option" /> | |
); | |
if (visibleIDs.includes(id) || matchedIDs.includes(id)) { | |
cardText = contents; | |
click = () => {}; | |
} | |
if (matchedIDs.includes(id)) { | |
cardStyle = "matched"; | |
} else if (visibleIDs.length === 2) { | |
cardStyle = "no-match"; | |
} | |
if (visibleIDs.length === 2) { | |
click = resetHandler; | |
} | |
return ( | |
<button onClick={click} className={`card ${cardStyle}`}> | |
{cardText} | |
</button> | |
); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import { Card } from "./card/Card.js"; | |
export const CardRow = ({ cards }) => { | |
const content = cards.map((card) => ( | |
<Card key={card.id} id={card.id} contents={card.contents} /> | |
)); | |
return <>{content}</>; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import url("https://fonts.googleapis.com/css2?family=Oxygen:wght@700&display=swap"); | |
html, | |
body { | |
margin: 0; | |
} | |
* { | |
font-family: "Oxygen", sans-serif; | |
font-weight: bold; | |
} | |
.card { | |
padding: 20px 0; | |
text-align: center; | |
border-radius: 6px; | |
border: solid 1px #141c3a; | |
background-color: #141c3a; | |
color: white; | |
cursor: pointer; | |
height: 75px; | |
font-size: 16px; | |
} | |
.card:hover, | |
.card:focus { | |
background-color: #2e4085; | |
} | |
.cards-container { | |
display: grid; | |
grid-template-columns: repeat(3, 138px); | |
grid-auto-rows: 1fr; | |
gap: 16px 16px; | |
margin: 0 auto; | |
width: fit-content; | |
padding: 24px 0 33px 0; | |
} | |
.card.selected { | |
background-color: initial; | |
color: #141c3a; | |
border: solid 1px #141c3a; | |
} | |
.card.matched { | |
color: #4fe0b0; | |
} | |
.card.no-match { | |
color: #fd4d3f; | |
} | |
.logo-placeholder { | |
width: 120px; | |
} | |
.score-container { | |
background-color: #f2f2f2; | |
padding: 18px 158px 23px 159px; | |
text-align: center; | |
font-size: 32px; | |
} | |
.footer > button { | |
width: 50%; | |
padding: 19px 40px 19px 40px; | |
font-size: 20px; | |
border: none; | |
color: #ffffff; | |
cursor: pointer; | |
} | |
.start-button { | |
background-color: #141c3a; | |
} | |
.start-button:hover, | |
.start-button:focus { | |
background-color: #2c3f81; | |
} | |
.try-new-pair-button { | |
background-color: #6400e4; | |
} | |
.try-new-pair-button:hover, | |
.try-new-pair-button:focus { | |
background-color: #7d1aff; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1" /> | |
<meta name="theme-color" content="#000000" /> | |
<link rel="stylesheet" href="./index.css" /> | |
<title>React App</title> | |
</head> | |
<body> | |
<div id="root"></div> | |
<script src="https://content.codecademy.com/courses/React/react-16-full.min.js"></script> | |
<script src="./src/index.compiled.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import ReactDOM from "react-dom"; | |
import App from "./App"; | |
import { store } from "./app/store.js"; | |
import { Provider } from "react-redux"; | |
ReactDOM.render( | |
<Provider store={store}> | |
<App /> | |
</Provider>, | |
document.getElementById("root") | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import { useSelector } from "react-redux"; | |
import { selectMatchedIDs } from "../board/boardSlice.js"; | |
export const Score = () => { | |
const cardsMatched = useSelector(selectMatchedIDs); | |
let matches = cardsMatched.length; | |
return <div className="score-container">Matched: {matches}</div>; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { combineReducers, createStore } from "redux"; | |
import { boardReducer } from "../features/board/boardSlice.js"; | |
const rootReducer = combineReducers({ | |
board: boardReducer, | |
}); | |
export const store = createStore(rootReducer); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment