-
-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Who's branch is it anyway game page
Add a new page for the "Who's branch is it anyway" game. * **New Page and Components** - Add `src/pages/whos-branch.tsx` to create a new page component for the game. - Add `src/components/whos-branch/index.tsx` to implement the game logic and UI. - Add `src/components/whos-branch/question.tsx` to display game questions. - Add `src/components/whos-branch/score.tsx` to display the game score. * **Game Data** - Add `src/data/whos-branch.json` to store game data, including branches and questions. * **Navigation and Menu** - Modify `src/pages/index.tsx` to add a link to the new game page. - Modify `src/data/menu.ts` to add a menu item for the new game page. * **Testing** - Add `__tests__/pages/whos-branch.tests.tsx` to create tests for the game page, game logic, and UI. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/Vets-Who-Code/vets-who-code-app?shareId=XXXX-XXXX-XXXX-XXXX).
- Loading branch information
1 parent
6465554
commit 92ea5a1
Showing
8 changed files
with
248 additions
and
1 deletion.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import React from "react"; | ||
import { render, screen, fireEvent } from "@testing-library/react"; | ||
import "@testing-library/jest-dom/extend-expect"; | ||
import WhosBranchPage from "@pages/whos-branch"; | ||
import Game from "@components/whos-branch"; | ||
import questions from "@data/whos-branch.json"; | ||
|
||
describe("WhosBranchPage", () => { | ||
test("renders the breadcrumb", () => { | ||
render(<WhosBranchPage />); | ||
expect(screen.getByText("Home")).toBeInTheDocument(); | ||
expect(screen.getByText("Who's Branch")).toBeInTheDocument(); | ||
}); | ||
|
||
test("renders the game component", () => { | ||
render(<WhosBranchPage />); | ||
expect(screen.getByText(questions[0].question)).toBeInTheDocument(); | ||
}); | ||
}); | ||
|
||
describe("Game Component", () => { | ||
test("renders the first question", () => { | ||
render(<Game />); | ||
expect(screen.getByText(questions[0].question)).toBeInTheDocument(); | ||
}); | ||
|
||
test("handles correct answer", () => { | ||
render(<Game />); | ||
const correctOption = screen.getByText(questions[0].options[0]); | ||
fireEvent.click(correctOption); | ||
expect(screen.getByText(questions[1].question)).toBeInTheDocument(); | ||
}); | ||
|
||
test("handles incorrect answer", () => { | ||
render(<Game />); | ||
const incorrectOption = screen.getByText(questions[0].options[1]); | ||
fireEvent.click(incorrectOption); | ||
expect(screen.getByText(questions[1].question)).toBeInTheDocument(); | ||
}); | ||
|
||
test("displays score at the end", () => { | ||
render(<Game />); | ||
questions.forEach((question) => { | ||
const option = screen.getByText(question.options[0]); | ||
fireEvent.click(option); | ||
}); | ||
expect(screen.getByText("Your Score")).toBeInTheDocument(); | ||
}); | ||
}); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import React, { useState } from "react"; | ||
import questions from "@data/whos-branch.json"; | ||
import Question from "./question"; | ||
import Score from "./score"; | ||
|
||
const Game = () => { | ||
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0); | ||
const [score, setScore] = useState(0); | ||
const [showScore, setShowScore] = useState(false); | ||
|
||
const handleAnswerOptionClick = (isCorrect: boolean) => { | ||
if (isCorrect) { | ||
setScore(score + 1); | ||
} | ||
|
||
const nextQuestion = currentQuestionIndex + 1; | ||
if (nextQuestion < questions.length) { | ||
setCurrentQuestionIndex(nextQuestion); | ||
} else { | ||
setShowScore(true); | ||
} | ||
}; | ||
|
||
return ( | ||
<div className="game"> | ||
{showScore ? ( | ||
<Score score={score} totalQuestions={questions.length} /> | ||
) : ( | ||
<Question | ||
question={questions[currentQuestionIndex]} | ||
onAnswerOptionClick={handleAnswerOptionClick} | ||
/> | ||
)} | ||
</div> | ||
); | ||
}; | ||
|
||
export default Game; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import React from "react"; | ||
|
||
interface QuestionProps { | ||
question: { | ||
question: string; | ||
options: string[]; | ||
answer: string; | ||
}; | ||
onAnswerOptionClick: (isCorrect: boolean) => void; | ||
} | ||
|
||
const Question: React.FC<QuestionProps> = ({ question, onAnswerOptionClick }) => { | ||
return ( | ||
<div className="question"> | ||
<h2>{question.question}</h2> | ||
<div className="options"> | ||
{question.options.map((option, index) => ( | ||
<button | ||
key={index} | ||
onClick={() => onAnswerOptionClick(option === question.answer)} | ||
> | ||
{option} | ||
</button> | ||
))} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Question; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import React from "react"; | ||
|
||
interface ScoreProps { | ||
score: number; | ||
totalQuestions: number; | ||
} | ||
|
||
const Score: React.FC<ScoreProps> = ({ score, totalQuestions }) => { | ||
return ( | ||
<div className="score"> | ||
<h2>Your Score</h2> | ||
<p> | ||
{score} out of {totalQuestions} | ||
</p> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Score; |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
{ | ||
"branches": [ | ||
{ | ||
"name": "Army", | ||
"questions": [ | ||
{ | ||
"question": "What is the primary color of the Army uniform?", | ||
"options": ["Green", "Blue", "White", "Black"], | ||
"answer": "Green" | ||
}, | ||
{ | ||
"question": "What is the motto of the Army?", | ||
"options": ["Semper Fi", "This We'll Defend", "Aim High", "Always Ready"], | ||
"answer": "This We'll Defend" | ||
} | ||
] | ||
}, | ||
{ | ||
"name": "Navy", | ||
"questions": [ | ||
{ | ||
"question": "What is the primary color of the Navy uniform?", | ||
"options": ["Green", "Blue", "White", "Black"], | ||
"answer": "Blue" | ||
}, | ||
{ | ||
"question": "What is the motto of the Navy?", | ||
"options": ["Semper Fi", "This We'll Defend", "Aim High", "Semper Fortis"], | ||
"answer": "Semper Fortis" | ||
} | ||
] | ||
}, | ||
{ | ||
"name": "Air Force", | ||
"questions": [ | ||
{ | ||
"question": "What is the primary color of the Air Force uniform?", | ||
"options": ["Green", "Blue", "White", "Black"], | ||
"answer": "Blue" | ||
}, | ||
{ | ||
"question": "What is the motto of the Air Force?", | ||
"options": ["Semper Fi", "This We'll Defend", "Aim High", "Always Ready"], | ||
"answer": "Aim High" | ||
} | ||
] | ||
}, | ||
{ | ||
"name": "Marines", | ||
"questions": [ | ||
{ | ||
"question": "What is the primary color of the Marines uniform?", | ||
"options": ["Green", "Blue", "White", "Black"], | ||
"answer": "Blue" | ||
}, | ||
{ | ||
"question": "What is the motto of the Marines?", | ||
"options": ["Semper Fi", "This We'll Defend", "Aim High", "Always Ready"], | ||
"answer": "Semper Fi" | ||
} | ||
] | ||
}, | ||
{ | ||
"name": "Coast Guard", | ||
"questions": [ | ||
{ | ||
"question": "What is the primary color of the Coast Guard uniform?", | ||
"options": ["Green", "Blue", "White", "Black"], | ||
"answer": "Blue" | ||
}, | ||
{ | ||
"question": "What is the motto of the Coast Guard?", | ||
"options": ["Semper Fi", "This We'll Defend", "Aim High", "Always Ready"], | ||
"answer": "Always Ready" | ||
} | ||
] | ||
} | ||
] | ||
} |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import React, { useState } from "react"; | ||
import Breadcrumb from "@components/breadcrumb"; | ||
import Game from "@components/whos-branch"; | ||
|
||
const WhosBranchPage = () => { | ||
return ( | ||
<> | ||
<Breadcrumb pages={[{ path: "/", label: "Home" }]} currentPage="Who's Branch" /> | ||
<Game /> | ||
</> | ||
); | ||
}; | ||
|
||
export default WhosBranchPage; |