diff --git a/challenge-baby-name-picker/AddToFav.js b/challenge-baby-name-picker/AddToFav.js
new file mode 100644
index 000000000..f0a4aeea5
--- /dev/null
+++ b/challenge-baby-name-picker/AddToFav.js
@@ -0,0 +1,20 @@
+import React from "react";
+
+const AddToFav = ({ favorites }) => {
+ return (
+
+
+
Favorites:
+ {favorites.map((name) => {
+ return (
+
+ {name}
+
+ );
+ })}
+
+
+ );
+};
+
+export default AddToFav;
diff --git a/challenge-baby-name-picker/App.css b/challenge-baby-name-picker/App.css
new file mode 100644
index 000000000..9abeacfaf
--- /dev/null
+++ b/challenge-baby-name-picker/App.css
@@ -0,0 +1,109 @@
+body {
+ width: 80%;
+ margin-left: 10%;
+}
+h3 {
+ font-size: 30px;
+ font-weight: 700;
+ font-style: oblique;
+}
+.fav {
+ font-size: 28px;
+ font-weight: 400;
+ background-color: rgb(105, 163, 218);
+}
+.filter_search-container {
+ background: linear-gradient(
+ rgba(99, 29, 190, 0.722),
+ rgba(255, 192, 203, 0.677)
+ );
+ width: 100%;
+ height: 150px;
+}
+.chosen {
+ transform: translateY(20px);
+ transition: all 1s;
+}
+.boys_btn {
+ background-color: #1c975bb4;
+ font-size: 25px;
+ margin: 15px;
+ font-weight: 600;
+}
+.girls_btn {
+ background-color: rgba(139, 25, 122, 0.558);
+ font-size: 25px;
+ margin: 15px;
+ font-weight: 600;
+}
+.all_btn {
+ background-color: rgb(81, 122, 161);
+ font-size: 25px;
+ margin: 15px;
+ width: 90px;
+ font-weight: 600;
+}
+.bg-image {
+ background-image: url("../background.jpg");
+ height: auto;
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: cover;
+ position: relative;
+}
+.female {
+ background-color: rgba(139, 25, 122, 0.558);
+}
+.male {
+ background-color: #1c975bb4;
+}
+.search-box {
+ width: 70%;
+ height: 50px;
+ background-color: rgba(139, 25, 122, 0.558);
+ border-color: #1c975bb4;
+ font-size: 25px;
+ border-style: groove;
+ border-width: 5px;
+ margin-top: 2%;
+}
+.App-content {
+ text-align: center;
+ font-size: 30px;
+ margin-top: 5%;
+}
+
+.App-logo {
+ height: 40vmin;
+ pointer-events: none;
+}
+
+@media (prefers-reduced-motion: no-preference) {
+ .App-logo {
+ animation: App-logo-spin infinite 20s linear;
+ }
+}
+
+.App-header {
+ background-color: #282c34;
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ font-size: calc(10px + 2vmin);
+ color: white;
+}
+
+.App-link {
+ color: #61dafb;
+}
+
+@keyframes App-logo-spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
diff --git a/challenge-baby-name-picker/App.js b/challenge-baby-name-picker/App.js
new file mode 100644
index 000000000..5e830b622
--- /dev/null
+++ b/challenge-baby-name-picker/App.js
@@ -0,0 +1,13 @@
+import "../styles/App.css";
+import React from "react";
+import Names from "./Names";
+
+const App = () => {
+ return (
+
+
+
+ );
+};
+
+export default App;
diff --git a/challenge-baby-name-picker/Names.js b/challenge-baby-name-picker/Names.js
new file mode 100644
index 000000000..7aed0b26f
--- /dev/null
+++ b/challenge-baby-name-picker/Names.js
@@ -0,0 +1,67 @@
+import React, { useState } from "react";
+import AddToFav from "./AddToFav";
+import babyNamesData from "../data/babyNamesData.json";
+import SearchAndSort from "./SearchAndSort";
+
+const Names = () => {
+ const [names, setNames] = useState(babyNamesData);
+ const [favorites, setFavorites] = useState([]);
+
+ return (
+
+
+
+
+
+
+ {names
+ .sort((a, b) => a.name.localeCompare(b.name))
+ .map((name, index) => {
+ if (name.sex === "f" && !favorites.includes(name.name)) {
+ return (
+ {
+ if (!favorites.includes(name.name)) {
+ setFavorites([...favorites, name.name]);
+ setNames(names.filter((n) => n.name !== name.name));
+ }
+ }}
+ >
+ {name.name}
+
+ );
+ } else if (name.sex === "m" && !favorites.includes(name.name)) {
+ return (
+ {
+ if (!favorites.includes(name.name)) {
+ setFavorites([...favorites, name.name]);
+ setNames(names.filter((n) => n.name !== name.name));
+ }
+ }}
+ >
+ {name.name}
+
+ );
+ } else return null;
+ })}
+
+
+
+ );
+};
+
+export default Names;
diff --git a/challenge-baby-name-picker/SearchAndSort.js b/challenge-baby-name-picker/SearchAndSort.js
new file mode 100644
index 000000000..8747784a3
--- /dev/null
+++ b/challenge-baby-name-picker/SearchAndSort.js
@@ -0,0 +1,83 @@
+import React, { useState } from "react";
+import "../styles/App.css";
+
+const SearchAndSort = ({ names, setNames, allNames }) => {
+ const [search, setSearch] = useState(allNames);
+ const [sort, setSort] = useState({
+ boys: false,
+ girls: false,
+ all: true,
+ });
+
+ return (
+
+ {
+ setNames(
+ search.filter((item) =>
+ item.name.toLowerCase().includes(e.target.value.toLowerCase())
+ )
+ );
+ }}
+ className="search-box"
+ />
+ {
+ if (!sort.boys) {
+ setSort({ boys: true, girls: false, all: false });
+ setNames(names.filter((item) => item.sex === "m"));
+ setSearch(names.filter((item) => item.sex === "m"));
+ }
+ }}
+ >
+ {" "}
+ Boys{" "}
+
+ |
+ {
+ if (!sort.girls) {
+ setSort({ boys: false, girls: true, all: false });
+ setNames(names.filter((item) => item.sex === "f"));
+ setSearch(names.filter((item) => item.sex === "f"));
+ }
+ }}
+ >
+ {" "}
+ Girls{" "}
+ {" "}
+ {"|"}
+ {
+ if (!sort.all) {
+ setSort({ boys: false, girls: false, all: true });
+ setNames(names);
+ setSearch(names);
+ }
+ }}
+ >
+ {" "}
+ All{" "}
+
+
+ );
+};
+
+export default SearchAndSort;
diff --git a/challenge-baby-name-picker/background.jpg b/challenge-baby-name-picker/background.jpg
new file mode 100644
index 000000000..cf5375d5f
Binary files /dev/null and b/challenge-baby-name-picker/background.jpg differ
diff --git a/challenge-countries/App.css b/challenge-countries/App.css
new file mode 100644
index 000000000..b8520b88e
--- /dev/null
+++ b/challenge-countries/App.css
@@ -0,0 +1,117 @@
+.main {
+ margin: 0 auto;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ width: 80%;
+ background: whitesmoke;
+ justify-content: space-around;
+}
+.countries {
+ display: flex;
+ flex-direction: column;
+ margin-top: -2rem;
+ border-style: solid;
+ background-color: whitesmoke;
+}
+.darkMode {
+ display: flex;
+ flex-direction: column;
+ margin-top: -2rem;
+ border-style: solid;
+ background: rgb(55, 55, 56);
+}
+.country-info {
+ display: flex;
+ flex-direction: column;
+ width: 22%;
+ background: rgb(255, 255, 255);
+ margin: 1%;
+ height: 24rem;
+ align-items: center;
+ border-radius: 5px;
+ border-radius: 0.5rem;
+}
+
+.country-info img {
+ width: 100%;
+ object-fit: cover;
+ height: 11rem;
+ border-top-left-radius: 0.4rem;
+ border-top-right-radius: 0.4rem;
+}
+/*.country-dark {
+ display: flex;
+ flex-direction: column;
+ width: 25%;
+ background: rgb(55, 55, 56);
+ margin: 1%;
+ height: 10%;
+ align-items: center;
+ border-radius: 5px;
+}
+*/
+ul {
+ list-style-type: none;
+ padding: 3%;
+ align-self: start;
+ font-size: 16px;
+ margin: 3px;
+}
+li {
+ padding: 3px;
+}
+.input-search {
+ margin-left: 10%;
+ height: 2.8rem;
+ width: 30%;
+ border-radius: 0.4rem;
+ font-size: 20px;
+ font-weight: 900;
+}
+.select-search {
+ display: flex;
+ align-items: center;
+ height: 150px;
+ margin-top: 4rem;
+}
+::placeholder {
+ padding-left: 1%;
+ color: black;
+}
+select {
+ margin-left: 90rem;
+ margin-top: -6.5rem;
+ margin-bottom: 8rem;
+ height: 3rem;
+ width: 15rem;
+ font-weight: 900;
+ font-size: 20px;
+ border-radius: 0.4rem;
+ padding-left: 1.5rem;
+}
+h2 {
+ margin-left: 3rem;
+}
+h5 {
+ font-size: 20px;
+ align-self: start;
+ margin-left: 15px;
+}
+header {
+ display: flex;
+ justify-content: space-between;
+ margin-top: 2rem;
+ height: 5rem;
+ background: rgb(255, 255, 255);
+}
+button {
+ border-style: none;
+ background: rgb(255, 255, 255);
+ margin-right: 4rem;
+ font-size: 20px;
+ font-weight: 600;
+}
+.glass {
+ margin-left: -3%;
+}
diff --git a/challenge-countries/App.js b/challenge-countries/App.js
new file mode 100644
index 000000000..5d49e237a
--- /dev/null
+++ b/challenge-countries/App.js
@@ -0,0 +1,67 @@
+import React, { useState } from "react";
+import "./App.css";
+import Country from "./Country";
+import Data from "./allCountries.json";
+import Options from "./Options";
+
+function App() {
+ const [searchTerm, setSearchTerm] = useState("");
+ const [country, setCountry] = useState(Data);
+ const [clicked, setClicked] = useState(true);
+
+ const clickHandler = () => {
+ setClicked(!clicked);
+ };
+
+ const handleSearch = (event) => {
+ const value = event.target.value;
+ setSearchTerm(value);
+ setCountry(
+ country.filter((country) => {
+ return country.name.toLowerCase().includes(value.toLowerCase());
+ })
+ );
+ };
+
+ return (
+
+
+ Where In The World?
+
+
+
+
+
+
+
+
setCountry(country)} />
+
+
+ {country.map((country) => {
+ return (
+
+ );
+ })}
+
+
+
+ );
+}
+
+export default App;
diff --git a/challenge-countries/Country.js b/challenge-countries/Country.js
new file mode 100644
index 000000000..31ce8e439
--- /dev/null
+++ b/challenge-countries/Country.js
@@ -0,0 +1,23 @@
+import React from "react";
+import "./App.css";
+
+const Country = (props) => {
+ return (
+
+

+
{props.Name}
+
+ -
+ Population: {props.Population}
+
+ -
+ Region: {props.Region}
+
+ -
+ Capital: {props.Capital}
+
+
+
+ );
+};
+export default Country;
diff --git a/challenge-countries/Options.js b/challenge-countries/Options.js
new file mode 100644
index 000000000..d1db5c2ac
--- /dev/null
+++ b/challenge-countries/Options.js
@@ -0,0 +1,27 @@
+import React from "react";
+import "./App.css";
+
+const Options = (props) => {
+ const onChangeHandler = (event) => {
+ if (event.target.value === "All") {
+ props.onSelecting(props.data);
+ } else {
+ props.onSelecting(
+ props.data.filter((country) => country.region === event.target.value)
+ );
+ }
+ };
+
+ return (
+
+ );
+};
+export default Options;
diff --git a/challenge-countries/index.html b/challenge-countries/index.html
new file mode 100644
index 000000000..30e7e6a79
--- /dev/null
+++ b/challenge-countries/index.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Countries React
+
+
+
+
+
+
+
diff --git a/challenge-high-score-tables/App.css b/challenge-high-score-tables/App.css
new file mode 100644
index 000000000..3d5f55d2d
--- /dev/null
+++ b/challenge-high-score-tables/App.css
@@ -0,0 +1,93 @@
+@import url("https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Rubik+Moonrocks&display=swap");
+
+.App {
+ text-align: center;
+}
+.bg-img {
+ background-image: url("../styles/gamerbackground.jpg");
+ background-repeat: no-repeat;
+ background-attachment: fixed;
+ background-size: 100% 110%;
+}
+h1 {
+ font-size: 60px;
+ font-family: "Rubik Moonrocks", sans-serif;
+ color: rgb(210, 194, 194);
+ text-align: left;
+ margin-left: 7%;
+}
+h2 {
+ font-size: 40px;
+ font-family: "Rubik Moonrocks", sans-serif;
+ color: rgb(210, 194, 194);
+ text-align: left;
+ margin-left: 15%;
+}
+button {
+ margin-left: -40%;
+ background-color: rgb(83, 27, 42);
+ padding: 20px 40px 20px 40px;
+ border-radius: 10%;
+ border-color: rgb(210, 194, 194);
+ border-width: 5px;
+ border-style: groove;
+ color: rgb(210, 194, 194);
+ font-family: "Press Start 2P", sans-serif;
+ font-size: 20px;
+}
+.list {
+ list-style-type: none;
+ display: grid;
+ grid-template-columns: 2fr 2fr;
+ border-width: 10px;
+ border-color: rgb(83, 27, 42);
+ border-style: groove;
+ width: 35%;
+ margin-left: 10%;
+ margin-bottom: 10px;
+ font-family: "Press Start 2P", sans-serif;
+ background-color: rgba(155, 169, 169, 0.7);
+}
+
+.name {
+ grid-column: 1;
+ font-size: 25px;
+ font-weight: 600;
+ margin: 5px;
+}
+.score {
+ grid-column: 2;
+ font-size: 25px;
+ font-weight: 600;
+ margin: 5px;
+}
+
+@media (prefers-reduced-motion: no-preference) {
+ .App-logo {
+ animation: App-logo-spin infinite 20s linear;
+ }
+}
+
+.App-header {
+ background-color: #ffffff;
+ min-height: 5vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ font-size: calc(10px + 2vmin);
+ color: rgb(255, 255, 255);
+}
+
+.App-link {
+ color: #61dafb;
+}
+
+@keyframes App-logo-spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
diff --git a/challenge-high-score-tables/App.js b/challenge-high-score-tables/App.js
new file mode 100644
index 000000000..5310e1e27
--- /dev/null
+++ b/challenge-high-score-tables/App.js
@@ -0,0 +1,38 @@
+import "../styles/App.css";
+import React, { useState } from "react";
+import WorldWideTable from "./WorldWideTable";
+import CountryHighScore from "./CountryHighScore";
+import scores from "../data/scores";
+
+function App() {
+ const [ascending, setAscending] = useState(false);
+
+ const changeOrder = () => {
+ setAscending(!ascending);
+ };
+
+ return (
+
+
+
HIGH SCORES PER COUNTRY
+
+ {scores
+ .sort((a, b) => a.name.localeCompare(b.name))
+ .map((country, index) => {
+ return (
+
+ );
+ })}
+
+ );
+}
+
+export default App;
diff --git a/challenge-high-score-tables/CountryHighScore.js b/challenge-high-score-tables/CountryHighScore.js
new file mode 100644
index 000000000..93844bbe7
--- /dev/null
+++ b/challenge-high-score-tables/CountryHighScore.js
@@ -0,0 +1,19 @@
+import React from "react";
+import Scores from "./Scores";
+
+const CountryHighScore = (props) => {
+ return (
+
+
HIGH SCORES: {props.countryName}
+
+ {props.countryScores
+ .sort(props.order ? (a, b) => a.s - b.s : (a, b) => b.s - a.s)
+ .map((player, index) => {
+ return ;
+ })}
+
+
+ );
+};
+
+export default CountryHighScore;
diff --git a/challenge-high-score-tables/Scores.js b/challenge-high-score-tables/Scores.js
new file mode 100644
index 000000000..6c83ddc40
--- /dev/null
+++ b/challenge-high-score-tables/Scores.js
@@ -0,0 +1,12 @@
+import React from "react";
+
+const Scores = (props) => {
+ return (
+
+ {props.name}
+ {props.score}
+
+ );
+};
+
+export default Scores;
diff --git a/challenge-high-score-tables/WorldWideTable.js b/challenge-high-score-tables/WorldWideTable.js
new file mode 100644
index 000000000..8bc5c5afb
--- /dev/null
+++ b/challenge-high-score-tables/WorldWideTable.js
@@ -0,0 +1,27 @@
+import React from "react";
+import Scores from "./Scores";
+
+const WorldWideTable = (props) => {
+ let worldHighScore = [];
+
+ props.scores.forEach((country) => {
+ country.scores.forEach((player) => {
+ worldHighScore.push(player);
+ });
+ });
+
+ return (
+
+
WORLD WIDE BEST SCORES
+
+ {worldHighScore
+ .sort((a, b) => b.s - a.s)
+ .map((player, index) => {
+ return ;
+ })}
+
+
+ );
+};
+
+export default WorldWideTable;
diff --git a/challenge-high-score-tables/gamerbackground.jpg b/challenge-high-score-tables/gamerbackground.jpg
new file mode 100644
index 000000000..93f58cb8a
Binary files /dev/null and b/challenge-high-score-tables/gamerbackground.jpg differ
diff --git a/challenge-high-score-tables/index.html b/challenge-high-score-tables/index.html
new file mode 100644
index 000000000..9de38a23b
--- /dev/null
+++ b/challenge-high-score-tables/index.html
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ React High Score Tables KatarzynaRuksza
+
+
+
+
+
+
+
diff --git a/challenge-job-listing/App.css b/challenge-job-listing/App.css
new file mode 100644
index 000000000..abf507cc0
--- /dev/null
+++ b/challenge-job-listing/App.css
@@ -0,0 +1,177 @@
+* {
+ box-sizing: border-box;
+}
+:root {
+ --DarkCyan: hsl(180, 29%, 50%);
+ --BackgroundCyan: hsl(180, 52%, 96%);
+ --LightGreyCyan: hsl(180, 31%, 95%);
+ --DarkGreyCyan: hsl(180, 8%, 52%);
+ --VeryDarkCyan: hsl(180, 14%, 20%);
+}
+.App {
+ font-family: "League Spartan", sans-serif;
+ font-size: 15px;
+ background-color: var(--BackgroundCyan);
+}
+.header-img {
+ width: 100%;
+ height: 120px;
+ background-color: var(--DarkCyan);
+ overflow: hidden;
+}
+.img {
+ width: 100%;
+ height: 100%;
+ /* position: relative;
+ right: 120px; */
+}
+
+.logo {
+ width: 100px;
+ height: 100px;
+ border-radius: 50%;
+ margin-right: 20px;
+}
+.job-detail {
+ display: flex;
+ flex-direction: row;
+ color: var(--DarkGreyCyan);
+ align-items: center;
+}
+.dot {
+ background-color: var(--DarkGreyCyan);
+ width: 3px;
+ height: 3px;
+ border-radius: 50%;
+ margin: 0 10px;
+}
+.description {
+ display: flex;
+ flex-direction: column;
+ text-align: left;
+}
+.description {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ text-align: left;
+}
+.new {
+ background-color: var(--DarkCyan);
+ border-radius: 20px;
+ font-size: 12px;
+ color: #fff;
+ padding: 0.4rem 0.3rem 0.2rem 0.4rem;
+ margin-left: 10px;
+ margin-right: 5px;
+}
+.featured {
+ background-color: #000;
+ color: #fff;
+ border-radius: 20px;
+ font-size: 12px;
+ padding: 0.4rem 0.4rem 0.2rem 0.4rem;
+}
+.card {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ margin-left: 2rem;
+}
+.card-container {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+ background-color: #fff;
+ margin: 2rem 3rem;
+ box-shadow: 0px 10px 18px -3px var(--DarkCyan);
+ border-radius: 3px;
+}
+.card-container:hover {
+ border-left: 4px solid var(--DarkCyan);
+}
+.company {
+ color: var(--DarkCyan);
+}
+.position {
+ font-size: 18px;
+ font-weight: 700;
+}
+.position:hover {
+ color: var(--DarkCyan);
+ cursor: pointer;
+}
+.description {
+ margin-right: 50px;
+}
+.button {
+ margin-right: 2rem;
+}
+.languages-button {
+ background-color: var(--LightGreyCyan);
+ color: var(--DarkCyan);
+ padding: 0.5rem 0.6rem;
+ border-radius: 3px;
+ font-weight: 700;
+ border: none;
+ margin: 0 5px;
+}
+.languages-button:hover {
+ background-color: var(--DarkCyan);
+ color: var(--LightGreyCyan);
+ cursor: pointer;
+}
+.filters {
+ background-color: #fff;
+ box-shadow: 0px 10px 18px -3px var(--DarkCyan);
+ border-radius: 3px;
+ padding: 2rem;
+ margin: 2rem 3rem;
+ position: relative;
+ bottom: 80px;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+}
+.filter {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+}
+.clear {
+ border: none;
+ color: var(--DarkCyan);
+ font-weight: 700;
+ background-color: #fff;
+ font-size: 20px;
+}
+.clear-button:hover {
+ border-bottom: 3px solid var(--DarkCyan);
+}
+.filters-container {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ margin: 0 5px;
+}
+.filters-p {
+ background-color: var(--LightGreyCyan);
+ color: var(--DarkCyan);
+ padding: 0.4rem 0.6rem;
+ border-radius: 3px;
+ font-weight: 700;
+}
+.filters-button {
+ background-color: var(--DarkCyan);
+ color: var(--BackgroundCyan);
+ border: none;
+ padding: 0.4rem 0.6rem;
+ border-radius: 3px;
+ font-weight: 700;
+}
+.filters-button:hover {
+ background-color: #000;
+ cursor: pointer;
+}
diff --git a/challenge-job-listing/App.js b/challenge-job-listing/App.js
new file mode 100644
index 000000000..14e25f236
--- /dev/null
+++ b/challenge-job-listing/App.js
@@ -0,0 +1,38 @@
+import "./App.css";
+import React, { useState, useEffect } from "react";
+import data from "./data.json";
+import JobList from "./JobList";
+import Header from "./Header";
+import Filters from "./Filters";
+
+function App() {
+ const [filters, setFilters] = useState([]);
+ const [filteredData, setFilteredData] = useState(data);
+
+ useEffect(() => {
+ setFilteredData(data);
+ let filter = filters.map((searchWord) => {
+ return data.filter(
+ (item) =>
+ item.languages.includes(searchWord) ||
+ item.role.includes(searchWord) ||
+ item.level.includes(searchWord)
+ );
+ });
+ filter.map((item) => setFilteredData(item));
+ }, [filters]);
+
+ return (
+
+
+
+ 0 ? filteredData : data}
+ />
+
+ );
+}
+
+export default App;
diff --git a/challenge-job-listing/App.test.js b/challenge-job-listing/App.test.js
new file mode 100644
index 000000000..1f03afeec
--- /dev/null
+++ b/challenge-job-listing/App.test.js
@@ -0,0 +1,8 @@
+import { render, screen } from '@testing-library/react';
+import App from './App';
+
+test('renders learn react link', () => {
+ render();
+ const linkElement = screen.getByText(/learn react/i);
+ expect(linkElement).toBeInTheDocument();
+});
diff --git a/challenge-job-listing/Filters.js b/challenge-job-listing/Filters.js
new file mode 100644
index 000000000..cdfb56d9c
--- /dev/null
+++ b/challenge-job-listing/Filters.js
@@ -0,0 +1,43 @@
+import React from "react";
+
+const Filters = (props) => {
+ const onClickClear = () => {
+ props.setFilters([]);
+ };
+
+ const onClickDelete = (index) => {
+ props.setFilters((prevState) =>
+ prevState.filter((item, index1) => index !== index1)
+ );
+ };
+
+ return props.filters.length > 0 ? (
+
+
+ {props.filters.map((item, index) => {
+ return (
+
+ );
+ })}
+
+
+
+
+
+ ) : (
+ ""
+ );
+};
+
+export default Filters;
diff --git a/challenge-job-listing/Header.js b/challenge-job-listing/Header.js
new file mode 100644
index 000000000..a17eb8f30
--- /dev/null
+++ b/challenge-job-listing/Header.js
@@ -0,0 +1,17 @@
+import React from "react";
+
+const Header = () => {
+ return (
+
+
+

+
+
+ );
+};
+
+export default Header;
diff --git a/challenge-job-listing/Job.js b/challenge-job-listing/Job.js
new file mode 100644
index 000000000..b0e804673
--- /dev/null
+++ b/challenge-job-listing/Job.js
@@ -0,0 +1,60 @@
+import React from "react";
+
+const Job = (props) => {
+ return (
+
+
+
+

+
+
+
+
{props.item.company}
+ {props.item.new ?
NEW!
: ""}
+ {props.item.featured ?
FEATURED
: ""}
+
+
{props.item.position}
+
+
{props.item.postedAt}
+
+
{props.item.location}
+
+
+
+
+
+
+
+ {props.item.languages.map((item) => {
+ return (
+
+ );
+ })}
+
+
+ );
+};
+
+export default Job;
diff --git a/challenge-job-listing/JobList.js b/challenge-job-listing/JobList.js
new file mode 100644
index 000000000..7aef37e7e
--- /dev/null
+++ b/challenge-job-listing/JobList.js
@@ -0,0 +1,17 @@
+import React from "react";
+import Job from "./Job";
+
+const JobList = (props) => {
+ return props.jobData.map((item) => {
+ return (
+
+ );
+ });
+};
+
+export default JobList;
diff --git a/challenge-job-listing/account.svg b/challenge-job-listing/account.svg
new file mode 100644
index 000000000..caa550d57
--- /dev/null
+++ b/challenge-job-listing/account.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/challenge-job-listing/bg-header-desktop.svg b/challenge-job-listing/bg-header-desktop.svg
new file mode 100644
index 000000000..b30a718e3
--- /dev/null
+++ b/challenge-job-listing/bg-header-desktop.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/challenge-job-listing/bg-header-mobile.svg b/challenge-job-listing/bg-header-mobile.svg
new file mode 100644
index 000000000..5c5fa42f2
--- /dev/null
+++ b/challenge-job-listing/bg-header-mobile.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/challenge-job-listing/data.json b/challenge-job-listing/data.json
new file mode 100644
index 000000000..81f5beca4
--- /dev/null
+++ b/challenge-job-listing/data.json
@@ -0,0 +1,152 @@
+[
+ {
+ "id": 1,
+ "company": "Photosnap",
+ "logo": "./images/photosnap.svg",
+ "new": true,
+ "featured": true,
+ "position": "Senior Frontend Developer",
+ "role": "Frontend",
+ "level": "Senior",
+ "postedAt": "1d ago",
+ "contract": "Full Time",
+ "location": "USA Only",
+ "languages": ["HTML", "CSS", "JavaScript"],
+ "tools": []
+ },
+ {
+ "id": 2,
+ "company": "Manage",
+ "logo": "./images/manage.svg",
+ "new": true,
+ "featured": true,
+ "position": "Fullstack Developer",
+ "role": "Fullstack",
+ "level": "Midweight",
+ "postedAt": "1d ago",
+ "contract": "Part Time",
+ "location": "Remote",
+ "languages": ["Python"],
+ "tools": ["React"]
+ },
+ {
+ "id": 3,
+ "company": "Account",
+ "logo": "./images/account.svg",
+ "new": true,
+ "featured": false,
+ "position": "Junior Frontend Developer",
+ "role": "Frontend",
+ "level": "Junior",
+ "postedAt": "2d ago",
+ "contract": "Part Time",
+ "location": "USA Only",
+ "languages": ["JavaScript"],
+ "tools": ["React", "Sass"]
+ },
+ {
+ "id": 4,
+ "company": "MyHome",
+ "logo": "./images/myhome.svg",
+ "new": false,
+ "featured": false,
+ "position": "Junior Frontend Developer",
+ "role": "Frontend",
+ "level": "Junior",
+ "postedAt": "5d ago",
+ "contract": "Contract",
+ "location": "USA Only",
+ "languages": ["CSS", "JavaScript"],
+ "tools": []
+ },
+ {
+ "id": 5,
+ "company": "Loop Studios",
+ "logo": "./images/loop-studios.svg",
+ "new": false,
+ "featured": false,
+ "position": "Software Engineer",
+ "role": "Fullstack",
+ "level": "Midweight",
+ "postedAt": "1w ago",
+ "contract": "Full Time",
+ "location": "Worldwide",
+ "languages": ["JavaScript"],
+ "tools": ["Ruby", "Sass"]
+ },
+ {
+ "id": 6,
+ "company": "FaceIt",
+ "logo": "./images/faceit.svg",
+ "new": false,
+ "featured": false,
+ "position": "Junior Backend Developer",
+ "role": "Backend",
+ "level": "Junior",
+ "postedAt": "2w ago",
+ "contract": "Full Time",
+ "location": "UK Only",
+ "languages": ["Ruby"],
+ "tools": ["RoR"]
+ },
+ {
+ "id": 7,
+ "company": "Shortly",
+ "logo": "./images/shortly.svg",
+ "new": false,
+ "featured": false,
+ "position": "Junior Developer",
+ "role": "Frontend",
+ "level": "Junior",
+ "postedAt": "2w ago",
+ "contract": "Full Time",
+ "location": "Worldwide",
+ "languages": ["HTML", "JavaScript"],
+ "tools": ["Sass"]
+ },
+ {
+ "id": 8,
+ "company": "Insure",
+ "logo": "./images/insure.svg",
+ "new": false,
+ "featured": false,
+ "position": "Junior Frontend Developer",
+ "role": "Frontend",
+ "level": "Junior",
+ "postedAt": "2w ago",
+ "contract": "Full Time",
+ "location": "USA Only",
+ "languages": ["JavaScript"],
+ "tools": ["Vue", "Sass"]
+ },
+ {
+ "id": 9,
+ "company": "Eyecam Co.",
+ "logo": "./images/eyecam-co.svg",
+ "new": false,
+ "featured": false,
+ "position": "Full Stack Engineer",
+ "role": "Fullstack",
+ "level": "Midweight",
+ "postedAt": "3w ago",
+ "contract": "Full Time",
+ "location": "Worldwide",
+ "languages": ["JavaScript", "Python"],
+ "tools": ["Django"]
+ },
+ {
+ "id": 10,
+ "company": "The Air Filter Company",
+ "logo": "./images/the-air-filter-company.svg",
+ "new": false,
+ "featured": false,
+ "position": "Front-end Dev",
+ "role": "Frontend",
+ "level": "Junior",
+ "postedAt": "1mo ago",
+ "contract": "Part Time",
+ "location": "Worldwide",
+ "languages": ["JavaScript"],
+ "tools": ["React", "Sass"]
+ }
+]
diff --git a/challenge-job-listing/eyecam-co.svg b/challenge-job-listing/eyecam-co.svg
new file mode 100644
index 000000000..a339e7ffb
--- /dev/null
+++ b/challenge-job-listing/eyecam-co.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/challenge-job-listing/faceit.svg b/challenge-job-listing/faceit.svg
new file mode 100644
index 000000000..9a3737bc2
--- /dev/null
+++ b/challenge-job-listing/faceit.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/challenge-job-listing/favicon-32x32.png b/challenge-job-listing/favicon-32x32.png
new file mode 100644
index 000000000..1e2df7f08
Binary files /dev/null and b/challenge-job-listing/favicon-32x32.png differ
diff --git a/challenge-job-listing/icon-remove.svg b/challenge-job-listing/icon-remove.svg
new file mode 100644
index 000000000..80a7bedf3
--- /dev/null
+++ b/challenge-job-listing/icon-remove.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/challenge-job-listing/index.css b/challenge-job-listing/index.css
new file mode 100644
index 000000000..ec2585e8c
--- /dev/null
+++ b/challenge-job-listing/index.css
@@ -0,0 +1,13 @@
+body {
+ margin: 0;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
+ sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+code {
+ font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
+ monospace;
+}
diff --git a/challenge-job-listing/index.js b/challenge-job-listing/index.js
new file mode 100644
index 000000000..d563c0fb1
--- /dev/null
+++ b/challenge-job-listing/index.js
@@ -0,0 +1,17 @@
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import './index.css';
+import App from './App';
+import reportWebVitals from './reportWebVitals';
+
+const root = ReactDOM.createRoot(document.getElementById('root'));
+root.render(
+
+
+
+);
+
+// If you want to start measuring performance in your app, pass a function
+// to log results (for example: reportWebVitals(console.log))
+// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
+reportWebVitals();
diff --git a/challenge-job-listing/insure.svg b/challenge-job-listing/insure.svg
new file mode 100644
index 000000000..c2aa416bd
--- /dev/null
+++ b/challenge-job-listing/insure.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/challenge-job-listing/logo.svg b/challenge-job-listing/logo.svg
new file mode 100644
index 000000000..9dfc1c058
--- /dev/null
+++ b/challenge-job-listing/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/challenge-job-listing/loop-studios.svg b/challenge-job-listing/loop-studios.svg
new file mode 100644
index 000000000..ba80a4210
--- /dev/null
+++ b/challenge-job-listing/loop-studios.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/challenge-job-listing/manage.svg b/challenge-job-listing/manage.svg
new file mode 100644
index 000000000..e92131539
--- /dev/null
+++ b/challenge-job-listing/manage.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/challenge-job-listing/myhome.svg b/challenge-job-listing/myhome.svg
new file mode 100644
index 000000000..2c830bce3
--- /dev/null
+++ b/challenge-job-listing/myhome.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/challenge-job-listing/photosnap.svg b/challenge-job-listing/photosnap.svg
new file mode 100644
index 000000000..3e60d286d
--- /dev/null
+++ b/challenge-job-listing/photosnap.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/challenge-job-listing/reportWebVitals.js b/challenge-job-listing/reportWebVitals.js
new file mode 100644
index 000000000..5253d3ad9
--- /dev/null
+++ b/challenge-job-listing/reportWebVitals.js
@@ -0,0 +1,13 @@
+const reportWebVitals = onPerfEntry => {
+ if (onPerfEntry && onPerfEntry instanceof Function) {
+ import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
+ getCLS(onPerfEntry);
+ getFID(onPerfEntry);
+ getFCP(onPerfEntry);
+ getLCP(onPerfEntry);
+ getTTFB(onPerfEntry);
+ });
+ }
+};
+
+export default reportWebVitals;
diff --git a/challenge-job-listing/setupTests.js b/challenge-job-listing/setupTests.js
new file mode 100644
index 000000000..8f2609b7b
--- /dev/null
+++ b/challenge-job-listing/setupTests.js
@@ -0,0 +1,5 @@
+// jest-dom adds custom jest matchers for asserting on DOM nodes.
+// allows you to do things like:
+// expect(element).toHaveTextContent(/react/i)
+// learn more: https://github.com/testing-library/jest-dom
+import '@testing-library/jest-dom';
diff --git a/challenge-job-listing/shortly.svg b/challenge-job-listing/shortly.svg
new file mode 100644
index 000000000..2622da499
--- /dev/null
+++ b/challenge-job-listing/shortly.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/challenge-job-listing/the-air-filter-company.svg b/challenge-job-listing/the-air-filter-company.svg
new file mode 100644
index 000000000..52cda188e
--- /dev/null
+++ b/challenge-job-listing/the-air-filter-company.svg
@@ -0,0 +1 @@
+
\ No newline at end of file