From 46b6024f9ab9d135f59ebc4d2ec78a26c082e15b Mon Sep 17 00:00:00 2001
From: Ilenia <26656284+ilenia-magoni@users.noreply.github.com>
Date: Fri, 20 Sep 2024 21:08:36 +0200
Subject: [PATCH] chore(curriculum): add football team cards lab to frontend
cert (#56129)
Co-authored-by: Dario-DC <105294544+Dario-DC@users.noreply.github.com>
Co-authored-by: Jessica Wilkins <67210629+jdwilkin4@users.noreply.github.com>
---
client/i18n/locales/english/intro.json | 7 +-
.../lab-football-team-cards/index.md | 9 +
.../_meta/lab-football-team-cards/meta.json | 11 +
.../66e7ee20b79186306fc12da5.md | 598 ++++++++++++++++++
4 files changed, 624 insertions(+), 1 deletion(-)
create mode 100644 client/src/pages/learn/front-end-development/lab-football-team-cards/index.md
create mode 100644 curriculum/challenges/_meta/lab-football-team-cards/meta.json
create mode 100644 curriculum/challenges/english/25-front-end-development/lab-football-team-cards/66e7ee20b79186306fc12da5.md
diff --git a/client/i18n/locales/english/intro.json b/client/i18n/locales/english/intro.json
index d98c9438da8..a0911d23bc6 100644
--- a/client/i18n/locales/english/intro.json
+++ b/client/i18n/locales/english/intro.json
@@ -2055,7 +2055,12 @@
]
},
"uglc": { "title": "199", "intro": [] },
- "vonu": { "title": "200", "intro": [] },
+ "lab-football-team-cards": {
+ "title": "Build a Set of Football Team Cards",
+ "intro": [
+ "One common aspect of building web applications is processing datasets and outputting information to the screen. In this project, you will use DOM manipulation, object destructuring, event handling, and data filtering to build a set of football team cards."
+ ]
+ },
"iejn": { "title": "201", "intro": [] },
"arrr": { "title": "202", "intro": [] },
"kaqq": { "title": "203", "intro": [] },
diff --git a/client/src/pages/learn/front-end-development/lab-football-team-cards/index.md b/client/src/pages/learn/front-end-development/lab-football-team-cards/index.md
new file mode 100644
index 00000000000..9ede2323076
--- /dev/null
+++ b/client/src/pages/learn/front-end-development/lab-football-team-cards/index.md
@@ -0,0 +1,9 @@
+---
+title: Introduction to the Build a Set of Football Team Cards
+block: lab-football-team-cards
+superBlock: front-end-development
+---
+
+## Introduction to the Build a Set of Football Team Cards
+
+One common aspect of building web applications: processing datasets, and then outputting information to the screen. In this sports team cards project, you'll have to use DOM manipulation, object destructuring, event handling, and data filtering.
diff --git a/curriculum/challenges/_meta/lab-football-team-cards/meta.json b/curriculum/challenges/_meta/lab-football-team-cards/meta.json
new file mode 100644
index 00000000000..9320dfe13a8
--- /dev/null
+++ b/curriculum/challenges/_meta/lab-football-team-cards/meta.json
@@ -0,0 +1,11 @@
+{
+ "name": "Build a Set of Football Team Cards",
+ "isUpcomingChange": true,
+ "usesMultifileEditor": true,
+ "dashedName": "lab-football-team-cards",
+ "order": 200,
+ "superBlock": "front-end-development",
+ "challengeOrder": [{ "id": "66e7ee20b79186306fc12da5", "title": "Build a Set of Football Team Cards" }],
+ "helpCategory": "JavaScript",
+ "blockType": "lab"
+}
diff --git a/curriculum/challenges/english/25-front-end-development/lab-football-team-cards/66e7ee20b79186306fc12da5.md b/curriculum/challenges/english/25-front-end-development/lab-football-team-cards/66e7ee20b79186306fc12da5.md
new file mode 100644
index 00000000000..2341b02f78f
--- /dev/null
+++ b/curriculum/challenges/english/25-front-end-development/lab-football-team-cards/66e7ee20b79186306fc12da5.md
@@ -0,0 +1,598 @@
+---
+id: 66e7ee20b79186306fc12da5
+title: Build a Set of Football Team Cards
+challengeType: 14
+dashedName: lab-football-team-cards
+demoType: onClick
+---
+
+# --description--
+
+In this lab, you will build a set of football team cards. The user should be able to use the dropdown menu and filter between the different players based on their positions.
+
+**Objective:** Fulfill the user stories below and get all the tests to pass to complete the lab.
+
+**User Stories:**
+
+1. You should create a `footballTeam` object with the following properties: `team`, `year`, `headCoach`, `players`.
+1. The `team` property should contain the name of the team as a string.
+1. The `year` property should contain the year as a number.
+1. The `headCoach` property should contain the name of the head coach as a string.
+1. The `players` property should be an array containing at least four elements.
+1. Each element in the `players` array should be an object with properties `name`, `position`, `isCaptain`.
+1. The `name` property should contain the name of the player as a string.
+1. The `position` property should have one of the following values: `"forward"`, `"midfielder"`, `"defender"`, or `"goalkeeper"`.
+1. The `isCaptain` property should have value of a boolean. One of the players should have their `isCaptain` property set to `true`.
+1. You should display the `coach`, `team` and `year` values on the page. These values should be displayed in the HTML elements with the `id` values of `head-coach`, `team` and `year`.
+1. You should display the players data on the page inside the `#player-cards` element, each player should be displayed in a `div` with class of `player-card`, and nested in it, an `h2` containing the name of the player, and `(Captain)` in case of the player being captain, and a `p` containing `Position:` and the position of the player.
+
+ ```html
+
+
Sergio Batista
+
Position: midfielder
+
+
+
(Captain) Diego Maradona
+
Position: midfielder
+
+ ```
+
+1. When the dropdown menu is used to select one of the positions, only players of that position should be shown. If the `"All Players"` option is selected, then all of the players should display on the page.
+
+# --hints--
+
+You should have a `footballTeam` variable.
+
+```js
+assert.exists(footballTeam);
+```
+
+The `footballTeam` variable should be an object with four properties: `team`, `year`, `headCoach` and `players`.
+
+```js
+assert.isObject(footballTeam);
+assert.containsAllKeys(footballTeam, ['team', 'year', 'headCoach', 'players']);
+```
+
+The `team` property should be a string.
+
+```js
+assert.isString(footballTeam.team);
+```
+
+The `year` property should be a number.
+
+```js
+assert.isNumber(footballTeam.year);
+```
+
+The `headCoach` property should be a string.
+
+```js
+assert.isString(footballTeam.headCoach);
+```
+
+The `players` property should be an array of at least four objects, each object should have the keys `name`, `position`, `isCaptain`.
+
+```js
+assert.isArray(footballTeam.players);
+assert.isAtLeast(footballTeam.players.length, 4);
+footballTeam.players.forEach(player => {
+ assert.isObject(player);
+ assert.containsAllKeys(player, ['name', 'position', 'isCaptain']);
+})
+```
+
+The `name` property should have value of a string.
+
+```js
+footballTeam.players.forEach(({name}) => assert.isString(name));
+```
+
+The `position` property should have one of values `"forward"`, `"midfielder"`, `"defender"`, or `"goalkeeper"`.
+
+```js
+footballTeam.players.forEach(({position}) => {
+ assert.isString(position);
+ assert.oneOf(position, ["forward", "midfielder", "defender", "goalkeeper"]);
+});
+```
+
+The `isCaptain` property should have value of a boolean, and there should be only one captain.
+
+```js
+footballTeam.players.forEach(({isCaptain}) => assert.isBoolean(isCaptain));
+const listOfCaptains = footballTeam.players.filter(({isCaptain}) => isCaptain);
+assert.lengthOf(listOfCaptains, 1);
+```
+
+You should display the `coach`, `team` and `year` values from the `footballTeam` object in the HTML elements with the `id` values of `head-coach`, `team` and `year`.
+
+```js
+const teamElement = document.querySelector('.team-stats #team');
+const yearElement = document.querySelector('.team-stats #year');
+const headCoachElement = document.querySelector('.team-stats #head-coach');
+assert.equal(teamElement?.innerText.trim(), footballTeam.team);
+assert.equal(yearElement?.innerText.trim(), footballTeam.year);
+assert.equal(headCoachElement?.innerText.trim(), footballTeam.headCoach);
+```
+
+When the option `All players` is selected, all players should be shown within `#player-cards`.
+
+```js
+const select = document.querySelector('#players')
+select.value = 'all';
+select.dispatchEvent(new Event('change'))
+const playerCards = document.querySelectorAll('.player-card');
+const arrayFromPage = Array.from(playerCards).map(el => ({
+ name: el.querySelector('h2').innerText.replace('(Captain)', '').trim(),
+ position: el.querySelector('p').innerText.replace('Position:', '').trim(),
+ isCaptain: /Captain/.test(el.querySelector('h2').innerText)
+ }))
+
+assert.sameDeepMembers(arrayFromPage, footballTeam.players);
+```
+
+When the option `Position Forward` is selected, only forward players should be shown within `#player-cards`.
+
+```js
+const forwards = footballTeam.players.filter(({position}) => position === 'forward')
+const select = document.querySelector('#players')
+select.value = 'forward';
+select.dispatchEvent(new Event('change'))
+const playerCards = document.querySelectorAll('.player-card');
+const arrayFromPage = Array.from(playerCards).map(el => ({
+ name: el.querySelector('h2').innerText.replace('(Captain)', '').trim(),
+ position: el.querySelector('p').innerText.replace('Position:', '').trim(),
+ isCaptain: /Captain/.test(el.querySelector('h2').innerText)
+ }))
+
+assert.sameDeepMembers(arrayFromPage, forwards);
+```
+
+When the option `Position Midfielder` is selected, only midfielder players should be shown within `#player-cards`.
+
+```js
+const midfielders = footballTeam.players.filter(({position}) => position === 'midfielder')
+const select = document.querySelector('#players')
+select.value = 'midfielder';
+select.dispatchEvent(new Event('change'))
+const playerCards = document.querySelectorAll('.player-card');
+const arrayFromPage = Array.from(playerCards).map(el => ({
+ name: el.querySelector('h2').innerText.replace('(Captain)', '').trim(),
+ position: el.querySelector('p').innerText.replace('Position:', '').trim(),
+ isCaptain: /Captain/.test(el.querySelector('h2').innerText)
+ }))
+
+assert.sameDeepMembers(arrayFromPage, midfielders);
+```
+
+When the option `Position Defender` is selected, only defender players should be shown within `#player-cards`.
+
+```js
+const defenders = footballTeam.players.filter(({position}) => position === 'defender')
+const select = document.querySelector('#players')
+select.value = 'defender';
+select.dispatchEvent(new Event('change'))
+const playerCards = document.querySelectorAll('.player-card');
+const arrayFromPage = Array.from(playerCards).map(el => ({
+ name: el.querySelector('h2').innerText.replace('(Captain)', '').trim(),
+ position: el.querySelector('p').innerText.replace('Position:', '').trim(),
+ isCaptain: /Captain/.test(el.querySelector('h2').innerText)
+ }))
+
+assert.sameDeepMembers(arrayFromPage, defenders);
+```
+
+When the option `Position Goalkeeper` is selected, only goalkeeper players should be shown.
+
+```js
+const goalkeepers = footballTeam.players.filter(({position}) => position === 'goalkeeper')
+const select = document.querySelector('#players')
+select.value = 'goalkeeper';
+select.dispatchEvent(new Event('change'))
+const playerCards = document.querySelectorAll('.player-card');
+const arrayFromPage = Array.from(playerCards).map(el => ({
+ name: el.querySelector('h2').innerText.replace('(Captain)', '').trim(),
+ position: el.querySelector('p').innerText.replace('Position:', '').trim(),
+ isCaptain: /Captain/.test(el.querySelector('h2').innerText)
+ }))
+
+assert.sameDeepMembers(arrayFromPage, goalkeepers);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+ Build a Set of Football Team Cards
+
+
+
+
+