diff --git a/src/components/PopUp.js b/src/components/PopUp.js new file mode 100644 index 0000000000000000000000000000000000000000..c360d9fe998172b054ef887a2ec1dad97480caaa --- /dev/null +++ b/src/components/PopUp.js @@ -0,0 +1,28 @@ +// Create function with text, button, and button function +// make pop up floating +import React from "react"; +import "./style/PopUp.css"; + +export default function PopUp(props) { + const [show, setShow] = React.useState(false); + + const handler = () => { + props.buttonHandler(); + props.onCloseHandler(); + setShow(false); + } + + React.useEffect(() => { + setShow(props.show) + }, [props.show]); + + return ( + <div className="pop-up" style={{ + visibility: show ? "visible" : "hidden", + }}> + <div>{props.text}</div> + <button onClick={handler}>{props.buttonText}</button> + </div> + ); +} + diff --git a/src/components/WordInput.js b/src/components/WordInput.js index e84f7b4a3b87b02ba6288d136dcc470a290ffcd8..022ba20b076f9849710ade07c65f3077b69c5714 100644 --- a/src/components/WordInput.js +++ b/src/components/WordInput.js @@ -1,35 +1,88 @@ import React from "react"; +import { getWord } from "../helpers/getWord"; import { validateInput } from "../helpers/validateInput"; import CharBox from "./CharBox"; import WordBox from "./WordBox"; +import PopUp from "./PopUp"; const WordInput = () => { const NUM_TRY = 6; const WORD_LENGTH = 5; + const [isEnabled, setIsEnabled] = React.useState(true); + const [neededWord, setNeededWord] = React.useState([]); const [currentTry, setCurrentTry] = React.useState(0); const [word, setWord] = React.useState([]); const [allWords, setAllWords] = React.useState([]); const [inputBox, setInputBox] = React.useState([]); + const [answer, setAnswer] = React.useState(""); + const [popUp, setPopUp] = React.useState({ + show: false, + text: "", + buttonText: "", + buttonHandler: () => {}, + }); + + const popUpCloseHandler = () => { + setPopUp({ + ...popUp, + show: false, + }); + }; + + const resetGame = () => { + setCurrentTry(0); + setWord([]); + setAllWords([]); + setInputBox([]); + setAnswer(""); + setPopUp({ + show: false, + text: "", + buttonText: "", + buttonHandler: () => {}, + }); + startGame(); + }; + + const startGame = () => { + const charBoxes = []; + getWord().then((response) => { + if (response.error != undefined) { + setPopUp({ + show: true, + text: response.error, + buttonText: "Refresh", + buttonHandler: () => {window.location.reload()}, + }); + } + setAnswer(response.res); + console.log(response.res) + }); + Array(WORD_LENGTH).fill().map((_, __) => (charBoxes.push({ char: "", answer: answer }))); + Array(NUM_TRY).fill().map((_, __) => (setAllWords(prev => [...prev, <WordBox chars={charBoxes} />]))); + resetInputBox(); + }; const resetInputBox = () => { const initInputBox = []; - for (let i = 0; i < WORD_LENGTH; i++) { - initInputBox.push(<CharBox char=""/>); - } + Array(WORD_LENGTH).fill().map((_, __) => (initInputBox.push(<CharBox char=""/>))); setInputBox(initInputBox); setWord([]); } + + const toggleSwitch = () => { + setIsEnabled(previousState => !previousState); + console.log(isEnabled); + } + + let button = null; + if (currentTry === 0) { + button = <button onClick={toggleSwitch}>{isEnabled ? "Easy" : "Hard"}</button>; + } React.useEffect(() => { - const charBoxes = []; - for (let i = 0; i < WORD_LENGTH; i++) { - charBoxes.push({ char: "", answer: "" }); - } - for (let i = 0; i < NUM_TRY; i++) { - setAllWords(prev => [...prev, <WordBox chars={charBoxes} />]); - } - resetInputBox(); + startGame(); }, []); document.onkeyup = async function(e) { @@ -48,29 +101,87 @@ const WordInput = () => { } } else { if (e.key === "Enter") { - // TODO: Check if user win - // TODO: Check if user lose - // TODO: Fix bug for character less than asked - // TODO: Call word (answer) randomizer API - // TODO: Handle error to be served on Pop-up/Dialog box + if (currentTry >= NUM_TRY) { + return; + } let currentInput = []; - const validatedInput = await validateInput(word, "kapal"); + const validatedInput = await validateInput(word, answer); if (validatedInput["error"]) { - console.log(validatedInput["error"]); + if (validatedInput["error"] === "Not enough characters") { + setPopUp({ + show: true, + text: validatedInput["error"], + buttonText: "Ok", + buttonHandler: () => {}, + }); + } else { + setPopUp({ + show: true, + text: validatedInput["error"], + buttonText: "Ok", + buttonHandler: () => {window.location.reload()}, + }); + } } else { + var correct = true; + + for (let i = 0; i < neededWord.length; i++) { + if (!word.includes(neededWord[i])) { + setPopUp({ + show: true, + text: "You need to use the letter that is already correct or misplaced in the word", + buttonText: "Ok", + buttonHandler: () => {}, + }); + return; + } + } + validatedInput["result"].flatMap((e, idx) => { currentInput = [...currentInput, { char: word[idx], answer: e }]; + if (e !== "correct") { + correct = false; + } + + if (isEnabled) { + if (e === "correct" || e === "misplaced") { + setNeededWord(prev => [...prev, word[idx]]) + } + } }); + setAllWords(prev => { const newState = [...prev]; newState[currentTry] = <WordBox chars={currentInput} />; return newState; }); - setCurrentTry(prev => prev + 1); - resetInputBox(); - } + if (correct) { + // User win + setPopUp({ + show: true, + text: "You win!", + buttonText: "Play again", + buttonHandler: resetGame, + }); + } + + if (currentTry === NUM_TRY - 1) { + // User lose + setCurrentTry(prev => prev + 1); + setPopUp({ + show: true, + text: "You lose! Correct answer is " + answer, + buttonText: "OK", + buttonHandler: resetGame, + }); + setInputBox(); + } else { + setCurrentTry(prev => prev + 1); + resetInputBox(); + } + } } else if (e.key === "Backspace" && word.length > 0) { setWord([...word.slice(0,-1)]); setInputBox(prevState => { @@ -89,6 +200,15 @@ const WordInput = () => { {inputBox} </div> {allWords.slice(currentTry+1, NUM_TRY+1)} + <PopUp + show={popUp.show} + text={popUp.text} + buttonText={popUp.buttonText} + buttonHandler={popUp.buttonHandler} + onCloseHandler={popUpCloseHandler} + /> + {button} + <p>Mode: {isEnabled ? "Hard" : "Easy"}</p> </div> ); } diff --git a/src/components/style/PopUp.css b/src/components/style/PopUp.css new file mode 100644 index 0000000000000000000000000000000000000000..81f07fea73258bff0b244937ecdef897e377bb28 --- /dev/null +++ b/src/components/style/PopUp.css @@ -0,0 +1,14 @@ +.pop-up { + position: absolute; + top: 25%; + left: 40%; + width: 20%; + height: 10%; + border-radius: 10px; + background-color: #fff; + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); + z-index: 100; + + padding-top: 1%; + font: 20px; +} \ No newline at end of file diff --git a/src/helpers/getWord.js b/src/helpers/getWord.js new file mode 100644 index 0000000000000000000000000000000000000000..631217660faf7e29a8bf95f22da6eb2b26e97a83 --- /dev/null +++ b/src/helpers/getWord.js @@ -0,0 +1,12 @@ +import axios from "axios"; + +export async function getWord() { + return await axios({ + url: "https://katla-backend-vzlajmqxxq-et.a.run.app/word/", + method: "GET" + }).then((response) => { + return { "res": response.data, "error": null }; + }).catch((error) => { + return { "res": null, "error": error }; + }); +} \ No newline at end of file diff --git a/src/helpers/validateInput.js b/src/helpers/validateInput.js index d4a5a19c5243811dbef9c56a0e9c451ff00065f1..312febc2e59862a70f7f1bba0a9dceac7629e556 100644 --- a/src/helpers/validateInput.js +++ b/src/helpers/validateInput.js @@ -43,15 +43,13 @@ function checkInputLength(input, length) { return isValid; } -// TODO: Replace backend URL to deployed one async function checkInputDefined(input) { - const response = await axios({ + return await axios({ method: 'get', - url: 'http://localhost:8080/check/' + input.join(""), - }); - if (response.statusText === "OK") { + url: 'https://katla-backend2-vzlajmqxxq-et.a.run.app/check/' + input.join(""), + }).then((response) => { return { "res": response.data, "error": null }; - } else { - return { "res": null, "error": response.statusText }; - } + }).catch((error) => { + return { "res": null, "error": error }; + }) } diff --git a/src/pages/Home.js b/src/pages/Home.js index cb1d732eed24a739935e0b99668027dc5482dfdd..d89ecb3fd2e4fbbfb6484ee530b6beffd6df605c 100644 --- a/src/pages/Home.js +++ b/src/pages/Home.js @@ -1,12 +1,9 @@ -import logo from '../logo.svg'; import React from 'react'; import WordInput from '../components/WordInput'; export default function Home() { const wordBoxes = []; - for (let i = 0; i < 1; i++) { - wordBoxes.push(<WordInput />); - } + wordBoxes.push(<WordInput />); return ( <div className="App">