diff --git a/ErrorEncountered b/ErrorEncountered index 5901b42..076f780 100644 --- a/ErrorEncountered +++ b/ErrorEncountered @@ -8,3 +8,7 @@ import Requestapi from "./requestapi"; Here the "./requestapi" should match exactly with the name of the file in the disk. Case sensitive. Even "Requestapi" should match the "export default Requestapi" in the component + + +In useContext the object name is case sensitive. You need to use the same name in all the components +where the context is used. \ No newline at end of file diff --git a/src/App.js b/src/App.js index bbb56ce..2195bc6 100644 --- a/src/App.js +++ b/src/App.js @@ -3,7 +3,10 @@ import "./App.css"; import Countries from "./Countries"; import Navbar from "./Navbar"; import Footer from "./Footer"; +import QuizCountryCurrency from "./QuizCountryCurrency"; +import QuizMaster from "./QuizMaster"; import { CountryContext } from "./CountryContext"; +import { BrowserRouter as Router, Switch, Route } from "react-router-dom"; function App() { const [countrydata, setCountrydata] = useState([]); @@ -13,13 +16,20 @@ function App() { ]); return ( -
- - - - -
+ +
+ + + + + + {/* */} + {/* */} + + +
+
); } diff --git a/src/Countries.css b/src/Countries.css index 432e321..bbfb1cf 100644 --- a/src/Countries.css +++ b/src/Countries.css @@ -2,15 +2,15 @@ display: flex; /* flex-wrap: wrap; */ /* margin-top: 80px; */ - /* margin-left: 5px; */ + margin-left: 10px; /* margin-bottom: 20px; */ - background-image: linear-gradient( + /* background-image: linear-gradient( 180deg, transparent, rgba(75, 75, 78, 0.61), rgb(110, 17, 17) - ); + ); */ } .countries__list { diff --git a/src/Countries.js b/src/Countries.js index 9d87df2..8e0c3a2 100644 --- a/src/Countries.js +++ b/src/Countries.js @@ -30,7 +30,11 @@ function Countries() { name={country.name} flag={country.flag} capital={country.capital} - currency={country.currencies[0].name} + currency={ + country.currencies[0].name + + " - " + + country.currencies[0].symbol + } /> ))} diff --git a/src/CountryCapitalQuiz.css b/src/CountryCapitalQuiz.css new file mode 100644 index 0000000..834b6c3 --- /dev/null +++ b/src/CountryCapitalQuiz.css @@ -0,0 +1,19 @@ +.countrycapitalquiz { + /* border: 1px solid red; */ + display: flex; + flex-direction: column; + text-align: center; +} + +.countrycapitalquiz__question { + /* border: 2px solid blue; */ +} + +.countrycapitalquiz__answers { + /* border: 2px solid green; */ + margin-top: 20px; +} + +.countrycapitalquiz_checkanswer { + margin-top: 20px !important; +} diff --git a/src/CountryCapitalQuiz.js b/src/CountryCapitalQuiz.js new file mode 100644 index 0000000..19cfa8d --- /dev/null +++ b/src/CountryCapitalQuiz.js @@ -0,0 +1,79 @@ +import React, { useState } from "react"; +import Radio from "@material-ui/core/Radio"; +import RadioGroup from "@material-ui/core/RadioGroup"; +import FormControlLabel from "@material-ui/core/FormControlLabel"; +import FormControl from "@material-ui/core/FormControl"; +import FormLabel from "@material-ui/core/FormLabel"; +import FormHelperText from "@material-ui/core/FormHelperText"; +import Button from "@material-ui/core/Button"; + +import "./CountryCapitalQuiz.css"; + +function CountryCapitalQuiz(props) { + console.log("I am in CountryCapitalQuiz"); + const [value, setValue] = useState(""); + const [error, setError] = useState(false); + const [helperText, setHelperText] = useState("What do you think?"); + + const handleRadioChange = (event) => { + setValue(event.target.value); + setHelperText(" "); + setError(false); + }; + + const handleSubmit = (event) => { + console.log("Initial value of radio", value); + event.preventDefault(); + + if (value === props.question.capital) { + setHelperText("You got it!"); + setError(false); + } else if (value === "") { + setHelperText("Please select an option."); + setError(true); + } else { + setHelperText("Sorry, wrong answer!"); + setError(true); + } + }; + + return ( +
+
+
+

What is the capital of {props.question.name}?

+
+
+
+ + {/* + What is the capital of {props.question.name} + */} + + {props.question.options.map((o) => ( + } label={o} /> + ))} + + {helperText} + + +
+
+
+
+ ); +} + +export default CountryCapitalQuiz; diff --git a/src/Footer.css b/src/Footer.css index 80ada83..93a1344 100644 --- a/src/Footer.css +++ b/src/Footer.css @@ -6,6 +6,11 @@ background-color: rgb(0, 8, 59); /* z-index: 99; */ height: 40px; + position: sticky; + bottom: 0; + left: 0; + right: 0; + width: 100%; } .footer__texts { diff --git a/src/Navbar.css b/src/Navbar.css index 1bd74d9..2fd081c 100644 --- a/src/Navbar.css +++ b/src/Navbar.css @@ -22,11 +22,18 @@ .nav__logo { /* position: fixed; */ - width: 160px; - left: 10px; + width: 260px; + height: 40px; + /* left: 10px; */ object-fit: contain; } +.nav__quizlogo { + width: 100px; + height: 30px; + margin-left: 20px; + object-fit: contain; +} .nav__logosearch { justify-content: space-evenly; } @@ -48,7 +55,7 @@ } .nav__badge { - margin-left: 20px; + margin-left: 10px; } .nav__badgeicon { diff --git a/src/Navbar.js b/src/Navbar.js index 25bbf5e..d24e955 100644 --- a/src/Navbar.js +++ b/src/Navbar.js @@ -1,9 +1,11 @@ import React, { useState, useEffect, useContext } from "react"; import "./Navbar.css"; import logo from "./images/c3f2.png"; +import quiz_logo from "./images/quiz.png"; import { CountryContext } from "./CountryContext"; import Badge from "@material-ui/core/Badge"; import PublicIcon from "@material-ui/icons/Public"; +import { Link } from "react-router-dom"; const base_url = "https://restcountries.eu/rest/v2/all/"; const url_country = "https://restcountries.eu/rest/v2/name/"; @@ -81,8 +83,9 @@ function Navbar() { return (
- C3F-Logo - + + C3F-Logo +
setInput(event.target.value)} /> - + */}
+ + quiz-logo +
); } diff --git a/src/QuizCountryCurrency.css b/src/QuizCountryCurrency.css new file mode 100644 index 0000000..6478dbf --- /dev/null +++ b/src/QuizCountryCurrency.css @@ -0,0 +1,4 @@ +.quizcountrycurrency { + display: flex; + margin-top: 100px; +} diff --git a/src/QuizCountryCurrency.js b/src/QuizCountryCurrency.js new file mode 100644 index 0000000..cbf7527 --- /dev/null +++ b/src/QuizCountryCurrency.js @@ -0,0 +1,128 @@ +import React, { useContext, useState } from "react"; +import "./QuizCountryCurrency.css"; +import { CountryContext } from "./CountryContext"; +import { + getRandomNumbersArray, + getRandomIntInclusive, + FisherYatesShuffle, +} from "./Utilities"; +import Radio from "@material-ui/core/Radio"; +import RadioGroup from "@material-ui/core/RadioGroup"; +import FormControlLabel from "@material-ui/core/FormControlLabel"; +import FormControl from "@material-ui/core/FormControl"; +import FormLabel from "@material-ui/core/FormLabel"; +import CountryCapitalQuiz from "./CountryCapitalQuiz"; + +function QuizCountryCurrency() { + const { countrydata } = useContext(CountryContext); + //console.table("countrydata", countrydata); + let country_arr = []; + let quiz_countries = []; + //If the context has data then proceed + if (countrydata.length > 0) { + //Copy the country data to a temporary array with index + + let counter = 0; + countrydata.map((c) => { + counter++; + //Only copy countries with capital + if (c.capital) { + //console.log("Quiz -- No capital", c.name); + + country_arr.push({ + id: counter, + name: c.name, + capital: c.capital, + }); + } + return country_arr; + }); + + let quiz_country_count = country_arr.length; + let no_of_questions = 10; + //console.log("Quiz - country_arr", country_arr); + console.log("Quiz - no of countries", quiz_country_count); + + if (quiz_country_count > 0) { + //Select random "n" countries for the quiz + const random_array = getRandomNumbersArray( + 1, + quiz_country_count, + no_of_questions + ); + console.log("Quiz --> RandomArray", random_array); + + random_array.map((a) => { + var find_country = country_arr.find((f) => f.id === a); + + quiz_countries.push({ + id: find_country.id, + name: find_country.name, + capital: find_country.capital, + options: [], + }); + }); + + console.log("Quiz --> quiz_countries", quiz_countries); + let arr_options = []; + var rand250 = 0; + //Build the options for answers + quiz_countries.forEach((element) => { + while (arr_options.length < 3) { + rand250 = getRandomIntInclusive(1, quiz_country_count); + + //Make sure the new number is not already added + //And the option should not be the element itself. It will be added later. + if (arr_options.indexOf(rand250) < 0 && element !== rand250) { + arr_options.push(rand250); + } + } + //Add the correct answer + arr_options.push(element.id); + + //Shuffle the answer so that it's not always at the 4th position + FisherYatesShuffle(arr_options); + + // console.log("Quiz --> arr_options after shuffle", arr_options); + let arr_cap = []; + + arr_options.map((o) => { + var find_country = country_arr.find((f) => f.id === o); + //console.log("Quiz --> find_country", find_country.capital); + arr_cap.push(find_country.capital); + }); + element.options = arr_cap.slice(); + //reset for the next quiz + arr_cap.length = 0; + arr_options.length = 0; + //console.log("Quiz --> final element", element); + }); + + console.log("Quiz --> final countries", quiz_countries); + } + } + + const [value, setValue] = useState(""); + const handleChange = (event) => { + setValue(event.target.value); + }; + const [id, setId] = useState(0); + + return ( +
+

Country Capital Quiz

+ +
+ + {/* */} + {/* */} +
+
+ ); +} + +export default QuizCountryCurrency; diff --git a/src/QuizMaster.css b/src/QuizMaster.css new file mode 100644 index 0000000..6d5a873 --- /dev/null +++ b/src/QuizMaster.css @@ -0,0 +1,27 @@ +.quizmaster { + margin-top: 80px; + display: flex; + /* flex-direction: row; */ + justify-content: center; + /* border: 2px solid red; */ + min-height: calc(100vh - 40px - 80px); +} + +.quizmaster__questions { + width: 900px; + display: flex; + justify-content: space-between; + /* border: 2px solid green; */ +} + +.quizmaster__questions > Button { + /* margin auto to horizontally center the elements in it's container */ + margin: auto; + height: 40px; + width: 120px !important; +} + +.quizmaster__next { + float: right; + width: 120px !important; +} diff --git a/src/QuizMaster.js b/src/QuizMaster.js new file mode 100644 index 0000000..f7b42b5 --- /dev/null +++ b/src/QuizMaster.js @@ -0,0 +1,101 @@ +import React, { useState } from "react"; +import "./QuizMaster.css"; +import CountryCapitalQuiz from "./CountryCapitalQuiz"; +import Button from "@material-ui/core/Button"; +import FastRewindIcon from "@material-ui/icons/FastRewind"; +import FastForwardIcon from "@material-ui/icons/FastForward"; + +function QuizMaster() { + const [countrylist] = useState([ + { + id: 237, + name: "Ukraine", + capital: "Kiev", + options: ["Kiev", "New Delhi", "Tallinn", "Gaborone"], + }, + { + id: 215, + name: "Sudan", + capital: "Khartoum", + options: ["King Edward Point", "Khartoum", "St. Peter Port", "Bucharest"], + }, + { + id: 150, + name: "Montenegro", + capital: "Podgorica", + options: ["Podgorica", "Moscow", "Bern", "Dublin"], + }, + { + id: 19, + name: "Bangladesh", + capital: "Dhaka", + options: ["Dakar", "Dhaka", "Washington, D.C.", "Moroni"], + }, + { + id: 2, + name: "Ă…land Islands", + capital: "Mariehamn", + options: ["Mariehamn", "Andorra la Vella", "Roseau", "Mogadishu"], + }, + { + id: 193, + name: "Saint Pierre and Miquelon", + capital: "Saint-Pierre", + options: ["Saint-Pierre", "Bishkek", "Funafuti", "Brussels"], + }, + { + id: 162, + name: "Niger", + capital: "Niamey", + options: ["Jamestown", "Niamey", "Stockholm", "Manila"], + }, + { + id: 177, + name: "Philippines", + capital: "Manila", + options: ["Plymouth", "Manila", "Basseterre", "Mogadishu"], + }, + { + id: 105, + name: "India", + capital: "New Delhi", + options: ["New Delhi", "Beijing", "Madrid", "Washington, D.C."], + }, + { + id: 203, + name: "Singapore", + capital: "Singapore", + options: ["Philipsburg", "Guatemala City", "Singapore", "Banjul"], + }, + ]); + + const [id, setId] = useState(0); + + return ( +
+
+ + + +
+
+ ); +} + +export default QuizMaster; diff --git a/src/Utilities.js b/src/Utilities.js new file mode 100644 index 0000000..ace7e21 --- /dev/null +++ b/src/Utilities.js @@ -0,0 +1,60 @@ +/** + * + * Logic to generate the country capital quiz + * + */ + +export function getRandomIntInclusive(min, max) { + min = Math.ceil(min); + max = Math.floor(max); + //The maximum is inclusive and the minimum is inclusive + return Math.floor(Math.random() * (max - min + 1)) + min; +} + +// Fisher-Yates (aka Knuth) Shuffle. +export function FisherYatesShuffle(array) { + var currentIndex = array.length, + temporaryValue, + randomIndex; + + // While there remain elements to shuffle... + while (0 !== currentIndex) { + // Pick a remaining element... + randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex -= 1; + + // And swap it with the current element. + temporaryValue = array[currentIndex]; + array[currentIndex] = array[randomIndex]; + array[randomIndex] = temporaryValue; + } + + return array; +} + +// Durstenfeld shuffle, an optimized version of Fisher-Yates: +export function DurstenfeldShuffle(array) { + for (var i = array.length - 1; i > 0; i--) { + var j = Math.floor(Math.random() * (i + 1)); + var temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } + + return array; +} + +export function getRandomNumbersArray(rand_min, rand_max, op_arr_len) { + var arr = []; + let rand = 0; + //Select "n" random countries from the list of "max" countries + while (arr.length < op_arr_len) { + rand = getRandomIntInclusive(rand_min, rand_max); + + //Make sure the new number is not already added + if (arr.indexOf(rand) < 0) { + arr.push(rand); + } + } + return arr; +} diff --git a/src/images/quiz.png b/src/images/quiz.png new file mode 100644 index 0000000..3ff6329 Binary files /dev/null and b/src/images/quiz.png differ