From 7e2732df62626a143fa2cd905c2adf62d11c4125 Mon Sep 17 00:00:00 2001 From: Ibrahim-Halil-Kuray <71791007+Ibrahim-Halil-Kuray@users.noreply.github.com> Date: Sat, 28 Oct 2023 16:16:01 +0200 Subject: [PATCH 01/13] json files are gathered in one folder --- src/{ => data}/advanced.json | 0 src/{ => data}/beginner.json | 0 src/{ => data}/expert.json | 0 src/{ => data}/programmingLanguages.json | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename src/{ => data}/advanced.json (100%) rename src/{ => data}/beginner.json (100%) rename src/{ => data}/expert.json (100%) rename src/{ => data}/programmingLanguages.json (100%) diff --git a/src/advanced.json b/src/data/advanced.json similarity index 100% rename from src/advanced.json rename to src/data/advanced.json diff --git a/src/beginner.json b/src/data/beginner.json similarity index 100% rename from src/beginner.json rename to src/data/beginner.json diff --git a/src/expert.json b/src/data/expert.json similarity index 100% rename from src/expert.json rename to src/data/expert.json diff --git a/src/programmingLanguages.json b/src/data/programmingLanguages.json similarity index 100% rename from src/programmingLanguages.json rename to src/data/programmingLanguages.json From 5d9ec3a2dbafc9b3e161b9d6382704c099df8142 Mon Sep 17 00:00:00 2001 From: Ibrahim-Halil-Kuray <71791007+Ibrahim-Halil-Kuray@users.noreply.github.com> Date: Sun, 29 Oct 2023 10:29:54 +0100 Subject: [PATCH 02/13] Test data --- public/advanced.json | 35 +++++++++++++++++++++++++++++++++++ public/expert.json | 30 ++++++++++++++++++++++++++++++ src/data/advanced.json | 0 src/data/expert.json | 0 4 files changed, 65 insertions(+) create mode 100644 public/advanced.json create mode 100644 public/expert.json delete mode 100644 src/data/advanced.json delete mode 100644 src/data/expert.json diff --git a/public/advanced.json b/public/advanced.json new file mode 100644 index 0000000..10a13cf --- /dev/null +++ b/public/advanced.json @@ -0,0 +1,35 @@ +[ + { + "question": "What is the key difference between Python 2 and Python 3?", + "options": [ + "Python 2 is no longer supported by the Python Software Foundation.", + "Python 3 has a different syntax and introduces new features.", + "Python 2 is faster than Python 3.", + "Python 3 is not backward compatible with Python 2." + ], + "correct_answer": 1, + "explanation": "Python 2 and Python 3 have significant differences in syntax and features. Python 3 was introduced to address some design flaws in Python 2 and to improve the language overall." + }, + { + "question": "What is the key difference between Python 2 and Python 3?", + "options": [ + "Python 2 is no longer supported by the Python Software Foundation.", + "Python 3 has a different syntax and introduces new features.", + "Python 2 is faster than Python 3.", + "Python 3 is not backward compatible with Python 2." + ], + "correct_answer": 1, + "explanation": "Python 2 and Python 3 have significant differences in syntax and features. Python 3 was introduced to address some design flaws in Python 2 and to improve the language overall." + }, + { + "question": "What is the key difference between Python 2 and Python 3?", + "options": [ + "Python 2 is no longer supported by the Python Software Foundation.", + "Python 3 has a different syntax and introduces new features.", + "Python 2 is faster than Python 3.", + "Python 3 is not backward compatible with Python 2." + ], + "correct_answer": 1, + "explanation": "Python 2 and Python 3 have significant differences in syntax and features. Python 3 was introduced to address some design flaws in Python 2 and to improve the language overall." + } +] \ No newline at end of file diff --git a/public/expert.json b/public/expert.json new file mode 100644 index 0000000..70f7079 --- /dev/null +++ b/public/expert.json @@ -0,0 +1,30 @@ + +[ +{ + "question": "True or False: In Python, '==' and 'is' operators are used interchangeably to compare two objects.", + "options": [ + "True", + "False" + ], + "correct_answer": 1, + "explanation": "False. In Python, '==' is used to compare the values of two objects, while 'is' is used to check if two objects refer to the same memory location." +}, +{ + "question": "True or False: In Python, '==' and 'is' operators are used interchangeably to compare two objects.", + "options": [ + "True", + "False" + ], + "correct_answer": 1, + "explanation": "False. In Python, '==' is used to compare the values of two objects, while 'is' is used to check if two objects refer to the same memory location." +}, +{ + "question": "True or False: In Python, '==' and 'is' operators are used interchangeably to compare two objects.", + "options": [ + "True", + "False" + ], + "correct_answer": 1, + "explanation": "False. In Python, '==' is used to compare the values of two objects, while 'is' is used to check if two objects refer to the same memory location." +} +] \ No newline at end of file diff --git a/src/data/advanced.json b/src/data/advanced.json deleted file mode 100644 index e69de29..0000000 diff --git a/src/data/expert.json b/src/data/expert.json deleted file mode 100644 index e69de29..0000000 From bbe10a7305207dfa350e2e3a31595a1b30be1d58 Mon Sep 17 00:00:00 2001 From: Ibrahim-Halil-Kuray <71791007+Ibrahim-Halil-Kuray@users.noreply.github.com> Date: Sun, 29 Oct 2023 10:30:04 +0100 Subject: [PATCH 03/13] Create Difficulty.tsx --- src/components/Difficulty.tsx | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/components/Difficulty.tsx diff --git a/src/components/Difficulty.tsx b/src/components/Difficulty.tsx new file mode 100644 index 0000000..bc5141f --- /dev/null +++ b/src/components/Difficulty.tsx @@ -0,0 +1,27 @@ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import React, { useState } from 'react'; + +interface DifficultyProps { + onSelectDifficulty: (selectedDifficulty: string) => void; +} + +const Difficulty: React.FC = ({ onSelectDifficulty }) => { + const difficulties = ['Beginner', 'Advanced', 'Expert']; + + return ( +
+

Choose a difficulty level please:

+ +
+ ); +}; + +export default Difficulty; From 85e51f472f83505b20c0c2a27e672c94ab98cc6a Mon Sep 17 00:00:00 2001 From: Ibrahim-Halil-Kuray <71791007+Ibrahim-Halil-Kuray@users.noreply.github.com> Date: Sun, 29 Oct 2023 10:30:09 +0100 Subject: [PATCH 04/13] Create Language.tsx --- src/components/Language.tsx | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/components/Language.tsx diff --git a/src/components/Language.tsx b/src/components/Language.tsx new file mode 100644 index 0000000..0ab8298 --- /dev/null +++ b/src/components/Language.tsx @@ -0,0 +1,35 @@ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import React, { useState } from 'react'; + +interface LanguageProps { + onSelectLanguage: (selectedLanguage: string) => void; +} + +const Language: React.FC = ({ onSelectLanguage }) => { + const languages = [ + 'Javascript', + 'Python', + 'PHP', + 'React', + 'Angular', + 'Vue', + 'Tailwind', + ]; + + return ( +
+

Choose a programming language to test yourself please:

+
    + {languages.map((language, index) => ( +
  • + +
  • + ))} +
+
+ ); +}; + +export default Language; From a4f20398126ac9901b1d706bdf74844c68aa3ed5 Mon Sep 17 00:00:00 2001 From: Ibrahim-Halil-Kuray <71791007+Ibrahim-Halil-Kuray@users.noreply.github.com> Date: Sun, 29 Oct 2023 10:33:23 +0100 Subject: [PATCH 05/13] Update App.tsx imports exports --- src/App.tsx | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index a2ee1fa..04f6127 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,26 +1,10 @@ -import React from 'react'; -import logo from './logo.svg'; -import './App.css'; +import React, { useState } from 'react'; +import Language from './components/Language'; +import Difficulty from './components/Difficulty'; +import Questions from './components/Questions'; -const App: React.FunctionComponent = () => { - return ( -
-
- logo -

- Edit src/App.tsx and save to reload. -

- - Learn React - -
-
- ); +const App: React.FC = () => { + return
; }; export default App; From e764de50a9fd93f2f7a2bfa96bef77750ae75a03 Mon Sep 17 00:00:00 2001 From: Ibrahim-Halil-Kuray <71791007+Ibrahim-Halil-Kuray@users.noreply.github.com> Date: Sun, 29 Oct 2023 10:34:00 +0100 Subject: [PATCH 06/13] Update App.tsx useStates --- src/App.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/App.tsx b/src/App.tsx index 04f6127..58bb7c4 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,6 +4,20 @@ import Difficulty from './components/Difficulty'; import Questions from './components/Questions'; const App: React.FC = () => { + const [selectedLanguage, setSelectedLanguage] = useState(null); + const [selectedDifficulty, setSelectedDifficulty] = useState( + null + ); + const [apiUrl, setApiUrl] = useState(null); + + const handleLanguageSelect = (language: string) => { + setSelectedLanguage(language); + }; + + const handleDifficultySelect = (difficulty: string) => { + setSelectedDifficulty(difficulty); + }; + return
; }; From a76a845765b38d8b8fa470b5943cf6ab98a2a6e2 Mon Sep 17 00:00:00 2001 From: Ibrahim-Halil-Kuray <71791007+Ibrahim-Halil-Kuray@users.noreply.github.com> Date: Sun, 29 Oct 2023 10:34:45 +0100 Subject: [PATCH 07/13] Update App.tsx difficulty --- src/App.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/App.tsx b/src/App.tsx index 58bb7c4..fe4ea57 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -16,6 +16,15 @@ const App: React.FC = () => { const handleDifficultySelect = (difficulty: string) => { setSelectedDifficulty(difficulty); + + // difficulty lvl depending on users choice + if (difficulty === 'Beginner') { + setApiUrl('http://localhost:3000/expert.json'); + } else if (difficulty === 'Advanced') { + setApiUrl('http://localhost:3000/advanced.json'); + } else if (difficulty === 'Expert') { + setApiUrl('https://www.api.org/sda125'); + } }; return
; From 25d16bc1753be4603b2791c805b5cd56ad01d1bc Mon Sep 17 00:00:00 2001 From: Ibrahim-Halil-Kuray <71791007+Ibrahim-Halil-Kuray@users.noreply.github.com> Date: Sun, 29 Oct 2023 10:35:20 +0100 Subject: [PATCH 08/13] Update App.tsx --- src/App.tsx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/App.tsx b/src/App.tsx index fe4ea57..90fc7e3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -27,7 +27,21 @@ const App: React.FC = () => { } }; - return
; + return ( +
+ {!selectedLanguage ? ( + + ) : !selectedDifficulty ? ( + + ) : apiUrl ? ( + + ) : ( +
+

Uploading...

+
+ )} +
+ ); }; export default App; From 7cff3139fed64b656999bef1c2548ff0d21e0686 Mon Sep 17 00:00:00 2001 From: Ibrahim-Halil-Kuray <71791007+Ibrahim-Halil-Kuray@users.noreply.github.com> Date: Sun, 29 Oct 2023 10:37:28 +0100 Subject: [PATCH 09/13] Create Questions.tsx --- src/components/Questions.tsx | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/components/Questions.tsx diff --git a/src/components/Questions.tsx b/src/components/Questions.tsx new file mode 100644 index 0000000..ea2390c --- /dev/null +++ b/src/components/Questions.tsx @@ -0,0 +1,25 @@ +import React, { useState, useEffect } from 'react'; + +interface QuestionsProps { + apiUrl: string; // get data from backend +} + +interface Question { + question: string; + options: string[]; + correct_answer: number; + explanation: string; +} + +const Questions: React.FC = ({ apiUrl }) => { + const [questions, setQuestions] = useState([]); + const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0); + const [userAnswers, setUserAnswers] = useState([]); + const [isTimeUp, setIsTimeUp] = useState(false); + const [isAnswered, setIsAnswered] = useState(false); + const [timer, setTimer] = useState(0); + + return
; +}; + +export default Questions; From 5c47271aa9ea8c390b079824902ec5f1cd35f674 Mon Sep 17 00:00:00 2001 From: Ibrahim-Halil-Kuray <71791007+Ibrahim-Halil-Kuray@users.noreply.github.com> Date: Sun, 29 Oct 2023 10:37:37 +0100 Subject: [PATCH 10/13] Update Questions.tsx --- src/components/Questions.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/components/Questions.tsx b/src/components/Questions.tsx index ea2390c..def7b40 100644 --- a/src/components/Questions.tsx +++ b/src/components/Questions.tsx @@ -19,6 +19,21 @@ const Questions: React.FC = ({ apiUrl }) => { const [isAnswered, setIsAnswered] = useState(false); const [timer, setTimer] = useState(0); + useEffect(() => { + fetch(apiUrl) + .then((response) => response.json()) + .then((data) => { + setQuestions(data); + // Time, depending on questions type + const questionType = + data[0].options.length > 2 ? 'multiple' : 'trueFalse'; + setTimer(questionType === 'multiple' ? 90 : 60); + }) + .catch((error) => { + console.error('can not communicate with the api:', error); + }); + }, [apiUrl]); + return
; }; From a1a26a9e73fd2562222a123185ee9f4eaf18022d Mon Sep 17 00:00:00 2001 From: Ibrahim-Halil-Kuray <71791007+Ibrahim-Halil-Kuray@users.noreply.github.com> Date: Sun, 29 Oct 2023 10:37:45 +0100 Subject: [PATCH 11/13] Update Questions.tsx --- src/components/Questions.tsx | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/components/Questions.tsx b/src/components/Questions.tsx index def7b40..e83f73a 100644 --- a/src/components/Questions.tsx +++ b/src/components/Questions.tsx @@ -34,6 +34,32 @@ const Questions: React.FC = ({ apiUrl }) => { }); }, [apiUrl]); + useEffect(() => { + let interval: NodeJS.Timeout; + + if (timer > 0 && currentQuestionIndex < questions.length && !isTimeUp) { + interval = setInterval(() => { + if (timer > 0) { + setTimer(timer - 1); + } else { + clearInterval(interval); + setIsTimeUp(true); + // when time is up, next q + goToNextQuestion(); + } + }, 1000); + } + return () => { + clearInterval(interval); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [timer, currentQuestionIndex, questions, isTimeUp]); + const handleAnswerQuestion = (selectedOption: number) => { + const correctAnswer = questions[currentQuestionIndex].correct_answer; + setUserAnswers([...userAnswers, selectedOption === correctAnswer ? 1 : 0]); + setIsAnswered(true); + }; + return
; }; From b47443a095a594e8b9c6d35b6cf0a892ef7f56c7 Mon Sep 17 00:00:00 2001 From: Ibrahim-Halil-Kuray <71791007+Ibrahim-Halil-Kuray@users.noreply.github.com> Date: Sun, 29 Oct 2023 10:37:51 +0100 Subject: [PATCH 12/13] Update Questions.tsx --- src/components/Questions.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/components/Questions.tsx b/src/components/Questions.tsx index e83f73a..1a5daba 100644 --- a/src/components/Questions.tsx +++ b/src/components/Questions.tsx @@ -60,6 +60,15 @@ const Questions: React.FC = ({ apiUrl }) => { setIsAnswered(true); }; + const goToNextQuestion = () => { + if (currentQuestionIndex < questions.length - 1) { + setCurrentQuestionIndex(currentQuestionIndex + 1); + setIsAnswered(false); + } else { + // Show result + } + }; + return
; }; From 506989e85640eae29869f2b7389b09f778203263 Mon Sep 17 00:00:00 2001 From: Ibrahim-Halil-Kuray <71791007+Ibrahim-Halil-Kuray@users.noreply.github.com> Date: Sun, 29 Oct 2023 10:39:05 +0100 Subject: [PATCH 13/13] Update Questions.tsx At the moment, we need some css and add what to do when all questions answered. --- src/components/Questions.tsx | 49 +++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/components/Questions.tsx b/src/components/Questions.tsx index 1a5daba..fb8589f 100644 --- a/src/components/Questions.tsx +++ b/src/components/Questions.tsx @@ -69,7 +69,54 @@ const Questions: React.FC = ({ apiUrl }) => { } }; - return
; + return ( +
+ {timer > 0 && !isTimeUp &&

Timer: {timer} second

} + + {questions.length > 0 && currentQuestionIndex < questions.length ? ( +
+

Question {currentQuestionIndex + 1}

+

{questions[currentQuestionIndex].question}

+
    + {questions[currentQuestionIndex].options.map((option, index) => ( +
  • + +
  • + ))} +
+ {isAnswered && ( +
+

+ Correct:{' '} + { + questions[currentQuestionIndex].options[ + questions[currentQuestionIndex].correct_answer + ] + } +

+ +
+ )} +
+ ) : ( +
+

You have have answred all question

+

+ Correct answers:{' '} + {userAnswers.filter((answer) => answer === 1).length} +

+

+ Wrong answers: {userAnswers.filter((answer) => answer === 0).length} +

+
+ )} +
+ ); }; export default Questions;