mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-01-08 03:04:00 -05:00
feat(curriculum): adding reusable profile card component workshop (#57400)
Co-authored-by: Dario-DC <105294544+Dario-DC@users.noreply.github.com> Co-authored-by: Tom <20648924+moT01@users.noreply.github.com> Co-authored-by: Zaira <33151350+zairahira@users.noreply.github.com>
This commit is contained in:
@@ -3342,7 +3342,12 @@
|
||||
"In these lecture videos, you will learn about working with data in React."
|
||||
]
|
||||
},
|
||||
"cdfr": { "title": "263", "intro": [] },
|
||||
"workshop-reusable-profile-card-component": {
|
||||
"title": "Build a Reusable Profile Card Component",
|
||||
"intro": [
|
||||
"In this workshop, you will learn how to work with props by building a reusable profile card component."
|
||||
]
|
||||
},
|
||||
"lab-mood-board": {
|
||||
"title": "Build a Mood Board",
|
||||
"intro": [
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Introduction to the Reusable Profile Card Component
|
||||
block: workshop-reusable-profile-card-component
|
||||
superBlock: full-stack-developer
|
||||
---
|
||||
|
||||
## Introduction to the Reusable Profile Card Component
|
||||
|
||||
This is a test for the new project-based curriculum.
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "Build a Reusable Profile Card Component",
|
||||
"isUpcomingChange": true,
|
||||
"blockType": "workshop",
|
||||
"blockLayout": "challenge-grid",
|
||||
"usesMultifileEditor": true,
|
||||
"hasEditableBoundaries": true,
|
||||
"dashedName": "workshop-reusable-profile-card-component",
|
||||
"superBlock": "full-stack-developer",
|
||||
"challengeOrder": [
|
||||
{
|
||||
"id": "674ef11f75254548672d998c",
|
||||
"title": "Step 1"
|
||||
},
|
||||
{
|
||||
"id": "674ef2d357676e50e4691658",
|
||||
"title": "Step 2"
|
||||
},
|
||||
{
|
||||
"id": "674ef2d357676e50e4691659",
|
||||
"title": "Step 3"
|
||||
},
|
||||
{
|
||||
"id": "674ef2d357676e50e469165a",
|
||||
"title": "Step 4"
|
||||
},
|
||||
{
|
||||
"id": "674ef2d357676e50e469165b",
|
||||
"title": "Step 5"
|
||||
},
|
||||
{
|
||||
"id": "674ef2d357676e50e469165c",
|
||||
"title": "Step 6"
|
||||
},
|
||||
{
|
||||
"id": "674ef2d357676e50e469165d",
|
||||
"title": "Step 7"
|
||||
}
|
||||
],
|
||||
"helpCategory": "JavaScript"
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
---
|
||||
id: 674ef11f75254548672d998c
|
||||
title: Step 1
|
||||
challengeType: 0
|
||||
dashedName: step-1
|
||||
demoType: onLoad
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this project, you will learn how to work with props by building a reusable profile card component.
|
||||
|
||||
Start by using the `export` keyword to create a `Card` functional component with `name`, `title`, and `bio` as the props. Don't forget to make sure they're all wrapped in a curly brace. That way, you destructure them instead of accessing them from `props`.
|
||||
|
||||
Also, return a pair of parentheses with an empty string inside of them for now.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create and export a `Card` functional component. Don't forget to return an empty string inside it.
|
||||
|
||||
```js
|
||||
const mockedComponent = Enzyme.mount(
|
||||
React.createElement(window.index.Card)
|
||||
);
|
||||
|
||||
assert.lengthOf(mockedComponent.find('Card'), 1);
|
||||
```
|
||||
|
||||
Your `Card` component should have a `name`, `title`, and `bio` props.
|
||||
|
||||
```js
|
||||
const mockedComponent = Enzyme.mount(
|
||||
React.createElement(window.index.Card)
|
||||
);
|
||||
|
||||
const componentFunction = mockedComponent.type();
|
||||
const propsSource = componentFunction.toString();
|
||||
|
||||
assert.match(propsSource, /\bname\b/);
|
||||
assert.match(propsSource, /\btitle\b/);
|
||||
assert.match(propsSource, /\bbio\b/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Reusable Card component</title>
|
||||
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
|
||||
|
||||
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
||||
<script
|
||||
data-plugins="transform-modules-umd"
|
||||
type="text/babel"
|
||||
src="index.jsx"
|
||||
></script>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script
|
||||
data-plugins="transform-modules-umd"
|
||||
type="text/babel"
|
||||
data-presets="react"
|
||||
data-type="module"
|
||||
>
|
||||
import { App } from './index.jsx';
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<App />
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
}
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: 5px solid var(--dark-orange);
|
||||
border-radius: 10px;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
margin: 10px 0;
|
||||
background-color: var(--light-grey);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
border-bottom: 4px solid var(--dark-orange);
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.card {
|
||||
width: 300px;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```jsx
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,116 @@
|
||||
---
|
||||
id: 674ef2d357676e50e4691658
|
||||
title: Step 2
|
||||
challengeType: 0
|
||||
dashedName: step-2
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside the return, remove the empty string, then create a `div` element with a `className` of `card`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should not have an empty string in your Card component.
|
||||
|
||||
```js
|
||||
assert.notMatch(code, /""/)
|
||||
```
|
||||
|
||||
You should create a `div` element with the `className` `card` at the top level of your `Card` component.
|
||||
|
||||
```js
|
||||
const mockedComponent = Enzyme.mount(
|
||||
React.createElement(window.index.Card)
|
||||
);
|
||||
|
||||
assert.equal(mockedComponent.childAt(0).type(), 'div');
|
||||
assert.isTrue(mockedComponent.childAt(0).hasClass('card'));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Reusable Card component</title>
|
||||
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
|
||||
|
||||
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
||||
<script
|
||||
data-plugins="transform-modules-umd"
|
||||
type="text/babel"
|
||||
src="index.jsx"
|
||||
></script>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script
|
||||
data-plugins="transform-modules-umd"
|
||||
type="text/babel"
|
||||
data-presets="react"
|
||||
data-type="module"
|
||||
>
|
||||
import { App } from './index.jsx';
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<App />
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
}
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: 5px solid var(--dark-orange);
|
||||
border-radius: 10px;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
margin: 10px 0;
|
||||
background-color: var(--light-grey);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
border-bottom: 4px solid var(--dark-orange);
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.card {
|
||||
width: 300px;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```jsx
|
||||
export function Card({ name, title, bio }) {
|
||||
return (
|
||||
--fcc-editable-region--
|
||||
""
|
||||
--fcc-editable-region--
|
||||
)
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,166 @@
|
||||
---
|
||||
id: 674ef2d357676e50e4691659
|
||||
title: Step 3
|
||||
challengeType: 0
|
||||
dashedName: step-3
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside the `div` element, create an `h2` element and interpolate the `name` prop as its text.
|
||||
|
||||
Also, inside the `div`, create a paragraph with the `className` of `card-title` to interpolate the `title` prop, and another paragraph to interpolate the `bio` prop.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should create an `h2` element inside your `div` element.
|
||||
|
||||
```js
|
||||
const mockedComponent = Enzyme.mount(
|
||||
React.createElement(window.index.Card)
|
||||
);
|
||||
|
||||
const h2Elem = mockedComponent.find('h2');
|
||||
|
||||
assert.equal(h2Elem.parent().type(), 'div');
|
||||
```
|
||||
|
||||
Your `h2` element should have `{name}` as its text content.
|
||||
|
||||
```js
|
||||
const mockedComponent = Enzyme.mount(
|
||||
React.createElement(window.index.Card, { name: 'nameVal' })
|
||||
);
|
||||
|
||||
const h2Elem = mockedComponent.find('h2');
|
||||
|
||||
assert.equal(h2Elem.text(), 'nameVal');
|
||||
```
|
||||
|
||||
You should create a `p` tag with the `className` of `card-title` inside your `div` element.
|
||||
|
||||
```js
|
||||
const mockedComponent = Enzyme.mount(
|
||||
React.createElement(window.index.Card)
|
||||
);
|
||||
|
||||
const pElem = mockedComponent.find('p.card-title');
|
||||
|
||||
assert.equal(pElem.parent().type(), 'div');
|
||||
```
|
||||
|
||||
Your `p` element with `className` of `card-title` should have `{title}` as its text content.
|
||||
|
||||
```js
|
||||
const mockedComponent = Enzyme.mount(
|
||||
React.createElement(window.index.Card, { title: 'titleVal' })
|
||||
);
|
||||
|
||||
const pElem = mockedComponent.find('p.card-title');
|
||||
|
||||
assert.equal(pElem.text(), 'titleVal');
|
||||
assert.equal(pElem.parent().type(), 'div');
|
||||
```
|
||||
|
||||
You should create another `p` element with `{bio}` as its text.
|
||||
|
||||
```js
|
||||
const mockedComponent = Enzyme.mount(
|
||||
React.createElement(window.index.Card, { bio: 'bioVal' })
|
||||
);
|
||||
|
||||
const secondPElem = mockedComponent.children().childAt(2)
|
||||
|
||||
assert.equal(secondPElem.type(), 'p')
|
||||
assert.equal(secondPElem.text(), 'bioVal');
|
||||
assert.equal(secondPElem.parent().type(), 'div');
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Reusable Card component</title>
|
||||
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
|
||||
|
||||
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
||||
<script
|
||||
data-plugins="transform-modules-umd"
|
||||
type="text/babel"
|
||||
src="index.jsx"
|
||||
></script>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script
|
||||
data-plugins="transform-modules-umd"
|
||||
type="text/babel"
|
||||
data-presets="react"
|
||||
data-type="module"
|
||||
>
|
||||
import { App } from './index.jsx';
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<App />
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
}
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: 5px solid var(--dark-orange);
|
||||
border-radius: 10px;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
margin: 10px 0;
|
||||
background-color: var(--light-grey);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
border-bottom: 4px solid var(--dark-orange);
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.card {
|
||||
width: 300px;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```jsx
|
||||
export function Card({ name, title, bio }) {
|
||||
return (
|
||||
--fcc-editable-region--
|
||||
<div className="card">
|
||||
|
||||
</div>
|
||||
--fcc-editable-region--
|
||||
)
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,117 @@
|
||||
---
|
||||
id: 674ef2d357676e50e469165a
|
||||
title: Step 4
|
||||
challengeType: 0
|
||||
dashedName: step-4
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
To start using the `Card` component, use the `export` keyword to create an `App` functional component.
|
||||
|
||||
Inside the `App` component, return a pair of parentheses containing an empty string.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should export an `App` functional component.
|
||||
|
||||
```js
|
||||
const mockedComponent = Enzyme.mount(
|
||||
React.createElement(window.index.App)
|
||||
);
|
||||
|
||||
assert.lengthOf(mockedComponent.find('App'), 1);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Reusable Card component</title>
|
||||
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
|
||||
|
||||
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
||||
<script
|
||||
data-plugins="transform-modules-umd"
|
||||
type="text/babel"
|
||||
src="index.jsx"
|
||||
></script>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script
|
||||
data-plugins="transform-modules-umd"
|
||||
type="text/babel"
|
||||
data-presets="react"
|
||||
data-type="module"
|
||||
>
|
||||
import { App } from './index.jsx';
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<App />
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
}
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: 5px solid var(--dark-orange);
|
||||
border-radius: 10px;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
margin: 10px 0;
|
||||
background-color: var(--light-grey);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
border-bottom: 4px solid var(--dark-orange);
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.card {
|
||||
width: 300px;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```jsx
|
||||
export function Card({ name, title, bio }) {
|
||||
return (
|
||||
<div className="card">
|
||||
<h2>{name}</h2>
|
||||
<p className="card-title">{title}</p>
|
||||
<p>{bio}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
@@ -0,0 +1,126 @@
|
||||
---
|
||||
id: 674ef2d357676e50e469165b
|
||||
title: Step 5
|
||||
challengeType: 0
|
||||
dashedName: step-5
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Inside your return statement, replace the empty string with a `div` element with a `className` property of `flex-container`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should not have an empty string in your Card component.
|
||||
|
||||
```js
|
||||
assert.notMatch(code, /""/)
|
||||
```
|
||||
|
||||
You should create a `div` element with the class `flex-container`.
|
||||
|
||||
```js
|
||||
const mockedComponent = Enzyme.mount(
|
||||
React.createElement(window.index.App)
|
||||
);
|
||||
|
||||
assert.equal(mockedComponent.childAt(0).type(), 'div');
|
||||
assert.isTrue(mockedComponent.childAt(0).hasClass('flex-container'));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Reusable Card component</title>
|
||||
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
|
||||
|
||||
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
||||
<script
|
||||
data-plugins="transform-modules-umd"
|
||||
type="text/babel"
|
||||
src="index.jsx"
|
||||
></script>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script
|
||||
data-plugins="transform-modules-umd"
|
||||
type="text/babel"
|
||||
data-presets="react"
|
||||
data-type="module"
|
||||
>
|
||||
import { App } from './index.jsx';
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<App />
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
}
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: 5px solid var(--dark-orange);
|
||||
border-radius: 10px;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
margin: 10px 0;
|
||||
background-color: var(--light-grey);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
border-bottom: 4px solid var(--dark-orange);
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.card {
|
||||
width: 300px;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```jsx
|
||||
export function Card({ name, title, bio }) {
|
||||
return (
|
||||
<div className="card">
|
||||
<h2>{name}</h2>
|
||||
<p className="card-title">{title}</p>
|
||||
<p>{bio}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
--fcc-editable-region--
|
||||
""
|
||||
--fcc-editable-region--
|
||||
);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,144 @@
|
||||
---
|
||||
id: 674ef2d357676e50e469165c
|
||||
title: Step 6
|
||||
challengeType: 0
|
||||
dashedName: step-6
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now, use the `Card` component with the `name` prop set to `"Mark"`, the `title` prop set to `"Frontend developer"`, and the `bio` set to `"I like to work with different frontend technologies and play video games."`
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use the `Card` component as an element with a `name` prop set to `"Mark"`.
|
||||
|
||||
```js
|
||||
const mockedComponent = Enzyme.mount(React.createElement(window.index.App));
|
||||
const cardItem = mockedComponent.find(window.index.Card);
|
||||
|
||||
const cardItemsProps = cardItem.props()
|
||||
|
||||
assert.equal(cardItem.props().name, "Mark")
|
||||
```
|
||||
|
||||
You should use the `Card` component as an element with a `title` prop set to `"Frontend developer"`.
|
||||
|
||||
```js
|
||||
const mockedComponent = Enzyme.mount(React.createElement(window.index.App));
|
||||
const cardItem = mockedComponent.find(window.index.Card);
|
||||
|
||||
const cardItemsProps = cardItem.props()
|
||||
|
||||
assert.equal(cardItem.props().title, "Frontend developer")
|
||||
```
|
||||
|
||||
You should use the `Card` component as an element with a `bio` prop set to `"I like to work with different frontend technologies and play video games."`.
|
||||
|
||||
```js
|
||||
const mockedComponent = Enzyme.mount(React.createElement(window.index.App));
|
||||
const cardItem = mockedComponent.find(window.index.Card);
|
||||
|
||||
const cardItemsProps = cardItem.props()
|
||||
|
||||
assert.equal(cardItem.props().bio, "I like to work with different frontend technologies and play video games.")
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Reusable Card component</title>
|
||||
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
|
||||
|
||||
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
||||
<script
|
||||
data-plugins="transform-modules-umd"
|
||||
type="text/babel"
|
||||
src="index.jsx"
|
||||
></script>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script
|
||||
data-plugins="transform-modules-umd"
|
||||
type="text/babel"
|
||||
data-presets="react"
|
||||
data-type="module"
|
||||
>
|
||||
import { App } from './index.jsx';
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<App />
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
}
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: 5px solid var(--dark-orange);
|
||||
border-radius: 10px;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
margin: 10px 0;
|
||||
background-color: var(--light-grey);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
border-bottom: 4px solid var(--dark-orange);
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.card {
|
||||
width: 300px;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```jsx
|
||||
export function Card({ name, title, bio }) {
|
||||
return (
|
||||
<div className="card">
|
||||
<h2>{name}</h2>
|
||||
<p className="card-title">{title}</p>
|
||||
<p>{bio}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
<div className="flex-container">
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,265 @@
|
||||
---
|
||||
id: 674ef2d357676e50e469165d
|
||||
title: Step 7
|
||||
challengeType: 0
|
||||
dashedName: step-7
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Again, use the `Card` component two more times with the following:
|
||||
|
||||
| Props | First Card Values | Second Card Values |
|
||||
|-------|------------------------------------------------------------|-----------------------------------------------------|
|
||||
| `name` | `"Tiffany"` | `"Doug"`|
|
||||
| `title` | `"Engineering manager"` | `"Backend developer"` |
|
||||
| `bio` | `"I have worked in tech for 15 years and love to help people grow in this industry."` | `"I have been a software developer for over 20 years and I love working with Go and Rust."`|
|
||||
|
||||
With that, your reusable profile card component project is complete!
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use the `Card` component as an element with the appropriate props and first card values.
|
||||
|
||||
```js
|
||||
const mockedComponent = Enzyme.mount(React.createElement(window.index.App));
|
||||
const cardItems = mockedComponent.find(window.index.Card);
|
||||
|
||||
const propsList = cardItems.map(item => item.props());
|
||||
|
||||
assert.deepEqual(propsList[1], {
|
||||
name: 'Tiffany',
|
||||
title: 'Engineering manager',
|
||||
bio: 'I have worked in tech for 15 years and love to help people grow in this industry.'
|
||||
});
|
||||
```
|
||||
|
||||
You should use the `Card` component as an element with the appropriate props and second card values.
|
||||
|
||||
```js
|
||||
const mockedComponent = Enzyme.mount(React.createElement(window.index.App));
|
||||
const cardItems = mockedComponent.find(window.index.Card);
|
||||
|
||||
const propsList = cardItems.map(item => item.props());
|
||||
|
||||
assert.deepEqual(propsList[2], {
|
||||
name: 'Doug',
|
||||
title: 'Backend developer',
|
||||
bio: 'I have been a software developer for over 20 years and I love working with Go and Rust.'
|
||||
});
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Reusable Card component</title>
|
||||
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
|
||||
|
||||
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
||||
<script
|
||||
data-plugins="transform-modules-umd"
|
||||
type="text/babel"
|
||||
src="index.jsx"
|
||||
></script>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script
|
||||
data-plugins="transform-modules-umd"
|
||||
type="text/babel"
|
||||
data-presets="react"
|
||||
data-type="module"
|
||||
>
|
||||
import { App } from './index.jsx';
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<App />
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
}
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: 5px solid var(--dark-orange);
|
||||
border-radius: 10px;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
margin: 10px 0;
|
||||
background-color: var(--light-grey);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
border-bottom: 4px solid var(--dark-orange);
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.card {
|
||||
width: 300px;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```jsx
|
||||
export function Card({ name, title, bio }) {
|
||||
return (
|
||||
<div className="card">
|
||||
<h2>{name}</h2>
|
||||
<p className="card-title">{title}</p>
|
||||
<p>{bio}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
<div className="flex-container">
|
||||
<Card
|
||||
name="Mark"
|
||||
title="Frontend developer"
|
||||
bio="I like to work with different frontend technologies and play video games."
|
||||
/>
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```html
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Reusable Card component</title>
|
||||
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
|
||||
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
|
||||
|
||||
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
||||
<script
|
||||
data-plugins="transform-modules-umd"
|
||||
type="text/babel"
|
||||
src="index.jsx"
|
||||
></script>
|
||||
<link rel="stylesheet" href="./styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script
|
||||
data-plugins="transform-modules-umd"
|
||||
type="text/babel"
|
||||
data-presets="react"
|
||||
data-type="module"
|
||||
>
|
||||
import { App } from './index.jsx';
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<App />
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
}
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: 5px solid var(--dark-orange);
|
||||
border-radius: 10px;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
margin: 10px 0;
|
||||
background-color: var(--light-grey);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
border-bottom: 4px solid var(--dark-orange);
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.card {
|
||||
width: 300px;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```jsx
|
||||
export function Card({ name, title, bio }) {
|
||||
return (
|
||||
<div className="card">
|
||||
<h2>{name}</h2>
|
||||
<p className="card-title">{title}</p>
|
||||
<p>{bio}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
<div className="flex-container">
|
||||
<Card
|
||||
name="Mark"
|
||||
title="Frontend developer"
|
||||
bio="I like to work with different frontend technologies and play video games."
|
||||
/>
|
||||
|
||||
<Card
|
||||
name="Tiffany"
|
||||
title="Engineering manager"
|
||||
bio="I have worked in tech for 15 years and love to help people grow in this industry."
|
||||
/>
|
||||
|
||||
<Card
|
||||
name="Doug"
|
||||
title="Backend developer"
|
||||
bio="I have been a software developer for over 20 years and I love working with Go and Rust."
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
@@ -556,6 +556,7 @@
|
||||
{ "dashedName": "workshop-reusable-mega-navbar" },
|
||||
{ "dashedName": "lab-reusable-footer" },
|
||||
{ "dashedName": "lecture-working-with-data-in-react" },
|
||||
{ "dashedName": "workshop-reusable-profile-card-component" },
|
||||
{ "dashedName": "lab-mood-board" },
|
||||
{ "dashedName": "review-react-basics" },
|
||||
{ "dashedName": "quiz-react-basics" }
|
||||
|
||||
Reference in New Issue
Block a user