mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-09-24 23:01:18 +08:00
feat(curriculum): add event hub lab (#56157)
Co-authored-by: Dario-DC <105294544+Dario-DC@users.noreply.github.com>
This commit is contained in:
@@ -1733,7 +1733,12 @@
|
||||
"In this workshop, you will learn how to build an HTML only blog page using semantic elements including the <code>main</code>, <code>nav</code>, <code>article</code> and <code>footer</code> elements."
|
||||
]
|
||||
},
|
||||
"szcd": { "title": "13", "intro": [] },
|
||||
"lab-event-hub": {
|
||||
"title": "Build an Event Hub",
|
||||
"intro": [
|
||||
"In this lab, you will build an event hub using semantic HTML."
|
||||
]
|
||||
},
|
||||
"ijdq": { "title": "14", "intro": [] },
|
||||
"pwwg": { "title": "15", "intro": [] },
|
||||
"cfgp": { "title": "16", "intro": [] },
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Introduction to the Build an Event Hub
|
||||
block: lab-event-hub
|
||||
superBlock: front-end-development
|
||||
---
|
||||
|
||||
## Introduction to the Build an Event Hub
|
||||
|
||||
In this lab, you will build an event hub using semantic HTML.
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "Build an Event Hub",
|
||||
"isUpcomingChange": true,
|
||||
"usesMultifileEditor": true,
|
||||
"dashedName": "lab-event-hub",
|
||||
"order": 13,
|
||||
"superBlock": "front-end-development",
|
||||
"challengeOrder": [{ "id": "66ebd4ae2812430bb883c787", "title": "Build an Event Hub" }],
|
||||
"helpCategory": "HTML-CSS",
|
||||
"blockType": "lab"
|
||||
}
|
||||
+306
@@ -0,0 +1,306 @@
|
||||
---
|
||||
id: 66ebd4ae2812430bb883c787
|
||||
title: Build an Event Hub
|
||||
challengeType: 14
|
||||
dashedName: lab-event-hub
|
||||
demoType: onClick
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this lab you will utilize the semantic HTML elements to create the structure of a web page. You'll add content and images to make it look like a real event hub.
|
||||
|
||||
**Objective:** Fulfill the user stories below and get all the tests to pass to complete the lab.
|
||||
|
||||
**User Stories:**
|
||||
|
||||
1. You should have a `header` element.
|
||||
1. Inside the `header` element, you should have a `h1` element that contains the text `Event Hub`, and a `nav` element.
|
||||
1. Inside the `nav` element, you should have an unordered list of two items containing links to different sections of the page. The first item should have the text `Upcoming Events`, and the second item should have the text `Past Events`.
|
||||
1. Each link should be represented by an `a` element with an `href` attribute that links to the corresponding section of the page, `#upcoming-events` and `#past-events` respectively.
|
||||
1. You should have a `main` element that contains the different sections of the page.
|
||||
1. Inside the `main` element, you should have two `section` elements.
|
||||
1. The first `section` element should have an `id` attribute with the value `upcoming-events`
|
||||
1. Inside the `#upcoming-events` section, you should have:
|
||||
|
||||
- An `h2` element with the text `Upcoming Events`.
|
||||
- Two `article` elements. Each article should represent an event, and it should have :
|
||||
- A `h3` element for the event title.
|
||||
- A `p` element for the event description. You can add a date at the bottom if you like.
|
||||
|
||||
1. The second `section` element should have an `id` attribute with the value `past-events`.
|
||||
1. Inside the `#past-events` section, you should have:
|
||||
|
||||
- An `h2` element with the text `Past Events`.
|
||||
- Two `article` elements. Each article element should represent a past event, and it should have:
|
||||
- An `h3` element for the event title,
|
||||
- A `p` element for the event description. You can add a date at the bottom if you like.
|
||||
- An image element with the `src` attribute pointing to an image file and the `alt` attribute with a description of the image.
|
||||
|
||||
**Note:** You can use any text for the event descriptions and dates. You can use the following image URLs for the images if you like:
|
||||
|
||||
- `https://cdn.freecodecamp.org/curriculum/labs/past-event1.jpg`.
|
||||
- `https://cdn.freecodecamp.org/curriculum/labs/past-event2.jpg`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a `header` element.
|
||||
|
||||
```js
|
||||
assert.isNotNull(document.querySelector("header"));
|
||||
```
|
||||
|
||||
Your `header` element should come after the opening `body` tag.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelector("body")?.firstElementChild?.tagName, "HEADER");
|
||||
```
|
||||
|
||||
Inside the `header` element, you should have a `h1` element that contains the text `Event Hub`.
|
||||
|
||||
```js
|
||||
const h1Element = document.querySelector('header h1');
|
||||
assert.strictEqual(h1Element?.innerText, "Event Hub");
|
||||
```
|
||||
|
||||
Inside the `header` element, after the `h1` element, you should have a `nav` element.
|
||||
|
||||
```js
|
||||
assert.isNotNull(document.querySelector("header>h1+nav"));
|
||||
```
|
||||
|
||||
Your `nav` element should contain an unordered list of two items.
|
||||
|
||||
```js
|
||||
const liElements = document.querySelectorAll('header nav>ul>li');
|
||||
|
||||
assert.isNotNull('header nav>ul');
|
||||
assert.strictEqual(liElements.length, 2);
|
||||
```
|
||||
|
||||
The first item in the unordered list should be a link.
|
||||
|
||||
```js
|
||||
const firstLink = document.querySelectorAll('header nav ul li a')[0];
|
||||
assert.exists(firstLink);
|
||||
```
|
||||
|
||||
The second item in the unordered list should be a link.
|
||||
|
||||
```js
|
||||
const secondLink = document.querySelectorAll('header nav ul li a')[1];
|
||||
assert.exists(secondLink);
|
||||
```
|
||||
|
||||
The text of the first item in the unordered list should be `"Upcoming Events"`.
|
||||
|
||||
```js
|
||||
const firstLink = document.querySelectorAll('header nav>ul>li>a')[0];
|
||||
assert.strictEqual(firstLink.innerText, "Upcoming Events");
|
||||
```
|
||||
|
||||
The first item in the unordered list should have the `href` set to `#upcoming-events`.
|
||||
|
||||
```js
|
||||
const anchorElement = document.querySelectorAll("header nav>ul>li>a")[0];
|
||||
const hrefAttribute = anchorElement?.getAttribute("href");
|
||||
assert.strictEqual(hrefAttribute, "#upcoming-events");
|
||||
```
|
||||
|
||||
The second item in the unordered list should have the `href` set to `#past-events`.
|
||||
|
||||
```js
|
||||
const anchorElement = document.querySelectorAll("header nav>ul>li>a")[1];
|
||||
const hrefAttribute = anchorElement?.getAttribute("href");
|
||||
assert.strictEqual(hrefAttribute, "#past-events");
|
||||
```
|
||||
|
||||
You should have a `main` element after the `header` element closing tag.
|
||||
|
||||
```js
|
||||
const mainElement = document.querySelector("body>header+main");
|
||||
assert.isNotNull(mainElement);
|
||||
```
|
||||
|
||||
Inside the `main` element, you should have two `section` elements.
|
||||
|
||||
```js
|
||||
const sectionElements = document.querySelectorAll('body>header+main>section');
|
||||
assert.strictEqual(sectionElements.length, 2);
|
||||
```
|
||||
|
||||
Your first `section` element should have an `id` attribute with the value `upcoming-events`.
|
||||
|
||||
```js
|
||||
const firstSection = document.querySelectorAll('body>header+main>section')[0];
|
||||
const idAttribute = firstSection?.getAttribute("id");
|
||||
assert.strictEqual(idAttribute, "upcoming-events");
|
||||
```
|
||||
|
||||
Your second `section` element should have an `id` attribute with the value `past-events`.
|
||||
|
||||
```js
|
||||
const secondSection = document.querySelectorAll('body>header+main>section')[1];
|
||||
const idAttribute = secondSection?.getAttribute("id");
|
||||
assert.strictEqual(idAttribute, "past-events");
|
||||
```
|
||||
|
||||
Inside the `#upcoming-events` section, you should have an `h2` element with the text `Upcoming Events`.
|
||||
|
||||
```js
|
||||
const h2Element = document.querySelector('#upcoming-events h2');
|
||||
assert.strictEqual(h2Element?.innerText, "Upcoming Events");
|
||||
```
|
||||
|
||||
Inside the `#upcoming-events` section, you should have two `article` elements.
|
||||
|
||||
```js
|
||||
const articleElements = document.querySelectorAll('#upcoming-events article');
|
||||
assert.strictEqual(articleElements.length, 2);
|
||||
```
|
||||
|
||||
Both of the `article` elements inside the `#upcoming-events` section should have an `h3` element for the event title.
|
||||
|
||||
```js
|
||||
const h3Elements = document.querySelectorAll('#upcoming-events article h3');
|
||||
assert.strictEqual(h3Elements.length, 2);
|
||||
```
|
||||
|
||||
Both of the `article` elements inside the `#upcoming-events` section should have a paragraph element for the event description.
|
||||
|
||||
```js
|
||||
const pElement = document.querySelectorAll('#upcoming-events article h3+p').length;
|
||||
assert.strictEqual(pElement, 2);
|
||||
```
|
||||
|
||||
Inside the `#past-events` section, you should have an `h2` element with the text `Past Events`.
|
||||
|
||||
```js
|
||||
const h2Element = document.querySelector('#past-events h2');
|
||||
assert.strictEqual(h2Element?.innerText, "Past Events");
|
||||
```
|
||||
|
||||
Inside the `#past-events` section, you should have two `article` elements.
|
||||
|
||||
```js
|
||||
const articleElements = document.querySelectorAll('#past-events article');
|
||||
assert.strictEqual(articleElements.length, 2);
|
||||
```
|
||||
|
||||
Both of the `article` elements inside the `#past-events` section should have an `h3` element for the event title.
|
||||
|
||||
```js
|
||||
const h3Elements = document.querySelectorAll('#past-events article h3');
|
||||
assert.strictEqual(h3Elements.length, 2);
|
||||
```
|
||||
|
||||
Both of the `article` elements inside the `#past-events` section should have a paragraph element for the event description.
|
||||
|
||||
```js
|
||||
const pElement = document.querySelectorAll('#past-events article h3+p').length;
|
||||
assert.strictEqual(pElement, 2);
|
||||
```
|
||||
|
||||
Both of the `article` elements inside the `#past-events` section should have an image element.
|
||||
|
||||
```js
|
||||
const imgElements = document.querySelectorAll('#past-events article img');
|
||||
assert.strictEqual(imgElements.length, 2);
|
||||
```
|
||||
|
||||
Both of the image elements inside the `#past-events` section should have the `src` attribute pointing to an image file.
|
||||
|
||||
```js
|
||||
const imgElements = document.querySelectorAll('#past-events article img');
|
||||
assert.strictEqual(imgElements.length, 2);
|
||||
|
||||
for (let img of imgElements) {
|
||||
assert(img.getAttribute("src"));
|
||||
}
|
||||
```
|
||||
|
||||
Both of the image elements inside the `#past-events` section should have the `alt` attribute with a description of the image.
|
||||
|
||||
```js
|
||||
const imgElements = document.querySelectorAll('#past-events article img');
|
||||
assert.strictEqual(imgElements.length, 2);
|
||||
|
||||
for (let img of imgElements) {
|
||||
assert(img.getAttribute("alt"));
|
||||
}
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Event Hub</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Event Hub</title>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>Event Hub</h1>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="#upcoming-events">Upcoming Events</a></li>
|
||||
<li><a href="#past-events">Past Events</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
<main>
|
||||
<section id="upcoming-events">
|
||||
<h2>Upcoming Events</h2>
|
||||
<article>
|
||||
<h3>AI & Machine Learning Conference 2024</h3>
|
||||
<p>Join us for a deep dive into the latest advancements in artificial intelligence and machine learning. Industry leaders will share insights and case studies on how AI is transforming various sectors.</p>
|
||||
<p>Date: August 10, 2024</p>
|
||||
</article>
|
||||
<article>
|
||||
<h3>Web Development Bootcamp</h3>
|
||||
<p>A hands-on workshop designed for developers looking to enhance their skills in modern web technologies including React, Node.js, and GraphQL. Perfect for both beginners and experienced developers.</p>
|
||||
<p>Date: September 5, 2024</p>
|
||||
</article>
|
||||
</section>
|
||||
<section id="past-events">
|
||||
<h2>Past Events</h2>
|
||||
<article>
|
||||
<h3>Cybersecurity Summit 2024</h3>
|
||||
<p>An event focusing on the latest trends and threats in cybersecurity. Experts discussed strategies for protecting data and ensuring privacy in an increasingly digital world.</p>
|
||||
<p>Date: June 15, 2024</p>
|
||||
<img src="https://cdn.freecodecamp.org/curriculum/labs/past-event1.jpg" alt="Image from Cybersecurity Summit 2024">
|
||||
</article>
|
||||
<article>
|
||||
<h3>Blockchain Expo 2024</h3>
|
||||
<p>A comprehensive event covering the future of blockchain technology. Topics included decentralized finance (DeFi), smart contracts, and the impact of blockchain on various industries.</p>
|
||||
<p>Date: July 20, 2024</p>
|
||||
<img src="https://cdn.freecodecamp.org/curriculum/labs/past-event2.jpg" alt="Image from Blockchain Expo 2024">
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user