diff --git a/package.json b/package.json
index 6fea90829acf3ccb3569d738bb240abb65f913df..b8dac5dae6dcc33cde540638e1c2ecbb82b00bca 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,7 @@
     "@testing-library/jest-dom": "^5.16.5",
     "@testing-library/react": "^13.4.0",
     "@testing-library/user-event": "^13.5.0",
+    "ramda": "^0.28.0",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
     "react-router-dom": "^6.4.3",
diff --git a/src/components/CharBox.js b/src/components/CharBox.js
index dbf5f1ce6ec5a228f09890fd1eab0f12e6bcb4d6..d92c1e80a6dbc012f40438db3602973b69c043e4 100644
--- a/src/components/CharBox.js
+++ b/src/components/CharBox.js
@@ -1,83 +1,10 @@
+import './style/Boxes.css';
 import React from "react";
-// import { Answer } from "../constant/Answer";
 
 export default function CharBox(props) {
-
-    let correctBox = {
-        backgroundColor: "green",
-        color: "white",
-        width: "50px",
-        height: "50px",
-        display: "inline-block",
-        textAlign: "center",
-        verticalAlign: "middle",
-        lineHeight: "50px",
-        margin: "5px",
-        border: "1px solid black"
-    };
-
-    let missplacedBox = {
-        backgroundColor: "yellow",
-        color: "black",
-        width: "50px",
-        height: "50px",
-        display: "inline-block",
-        textAlign: "center",
-        verticalAlign: "middle",
-        lineHeight: "50px",
-        margin: "5px",
-        border: "1px solid black"
-    };
-
-    let wrongBox = {
-        backgroundColor: "red",
-        color: "white",
-        width: "50px",
-        height: "50px",
-        display: "inline-block",
-        textAlign: "center",
-        verticalAlign: "middle",
-        lineHeight: "50px",
-        margin: "5px",
-        border: "1px solid black"
-    };
-
-    let defaultBox = {
-        backgroundColor: "white",
-        color: "black",
-        width: "50px",
-        height: "50px",
-        display: "inline-block",
-        textAlign: "center",
-        verticalAlign: "middle",
-        lineHeight: "50px",
-        margin: "5px",
-        border: "1px solid black"
-    };
-
-    const [charState, setCharState] = React.useState(props.char);
-    const [boxStyle, setBoxStyle] = React.useState(defaultBox);
-
-    const changeBoxStyle = (answer) => {
-        if (answer === "Correct") {
-            return correctBox;
-        } else if (answer === "Misplaced") {
-            return missplacedBox;
-        } else if (answer === "Wrong") {
-            return wrongBox;
-        }
-        return defaultBox;
-    }
-    
-    React.useEffect(() => {
-        // console.log(props);
-        setCharState(props.char);
-        setBoxStyle(changeBoxStyle(props.answer));
-    }, [props]); // eslint-disable-line react-hooks/exhaustive-deps
-
     return (
-        <div style={boxStyle}>
-            {charState.toUpperCase()}
+        <div class={"char-box " + (props.answer ? props.answer + "-box" : "default-box")}>
+            {props.char.toUpperCase()}
         </div>
     );
 }
\ No newline at end of file
diff --git a/src/components/WordBox.js b/src/components/WordBox.js
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..86578b816077d8dbad1ff7e10b67c65fddff2655 100644
--- a/src/components/WordBox.js
+++ b/src/components/WordBox.js
@@ -0,0 +1,16 @@
+import React from "react";
+import CharBox from "./CharBox";
+
+const WordBox = (props) => {
+  return (
+      <div className="word-box">
+        <CharBox char={props.chars[0].char} answer={props.chars[0].answer}/>
+        <CharBox char={props.chars[1].char} answer={props.chars[1].answer}/>
+        <CharBox char={props.chars[2].char} answer={props.chars[2].answer}/>
+        <CharBox char={props.chars[3].char} answer={props.chars[3].answer}/>
+        <CharBox char={props.chars[4].char} answer={props.chars[4].answer}/>
+      </div>
+  );
+}
+
+export default WordBox;
\ No newline at end of file
diff --git a/src/components/WordInput.js b/src/components/WordInput.js
index ca15a6ca03f22887255c3f28c6b65912b5f52d87..e84f7b4a3b87b02ba6288d136dcc470a290ffcd8 100644
--- a/src/components/WordInput.js
+++ b/src/components/WordInput.js
@@ -1,44 +1,79 @@
 import React from "react";
 import { validateInput } from "../helpers/validateInput";
 import CharBox from "./CharBox";
+import WordBox from "./WordBox";
 
 const WordInput = () => {
+    const NUM_TRY = 6;
+    const WORD_LENGTH = 5;
     
+    const [currentTry, setCurrentTry] = React.useState(0);
     const [word, setWord] = React.useState([]);
-    const [charBox, setCharBox] = React.useState([]);
+    const [allWords, setAllWords] = React.useState([]);
+    const [inputBox, setInputBox] = React.useState([]);
+
+    const resetInputBox = () => {
+        const initInputBox = [];
+        for (let i = 0; i < WORD_LENGTH; i++) {
+            initInputBox.push(<CharBox char=""/>);
+        }
+        setInputBox(initInputBox);
+        setWord([]);
+    }
 
     React.useEffect(() => {
         const charBoxes = [];
-        for (let i = 0; i < 5; i++) {
-            charBoxes.push(<CharBox char=""/>);
+        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} />]);
         }
-        setCharBox(charBoxes);
+        resetInputBox();
     }, []);
 
-    document.onkeyup = function(e) {
+    document.onkeyup = async function(e) {
         if (e.key.length === 1){
             if (e.key.match(/[a-z]/i)) {
-                if (word.length >= 5) {
+                if (word.length >= WORD_LENGTH) {
                     return;
                 } else {
-                    setCharBox(prevState => {
+                    setInputBox(prevState => {
                         const newState = [...prevState];
                         newState[word.length] = <CharBox char={e.key} />;
                         return newState;
-                    });
-                    setWord([...word, e.key]);                }
+                    });    
+                    setWord([...word, e.key]);         
+                }
             }
         } else {
             if (e.key === "Enter") {
-                setCharBox([]);
-    
-                validateInput(word, "hello").flatMap((e, idx) => {
-                    setCharBox(prevState => [...prevState, <CharBox char={word[idx]} answer={e} />]);
-                    return charBox;
-                });
+                // 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
+
+                let currentInput = [];
+                const validatedInput = await validateInput(word, "kapal");
+                if (validatedInput["error"]) {
+                    console.log(validatedInput["error"]);
+                } else {
+                    validatedInput["result"].flatMap((e, idx) => {
+                        currentInput = [...currentInput, { char: word[idx], answer: e }];
+                    });
+                    setAllWords(prev => {
+                        const newState = [...prev];
+                        newState[currentTry] = <WordBox chars={currentInput} />;
+                        return newState;
+                    });
+                    setCurrentTry(prev => prev + 1);
+                    resetInputBox();
+                }
+
             } else if (e.key === "Backspace" && word.length > 0) {
                 setWord([...word.slice(0,-1)]);
-                setCharBox(prevState => {
+                setInputBox(prevState => {
                     const newState = [...prevState];
                     newState[word.length-1] = <CharBox char={""} />;
                     return newState;
@@ -49,7 +84,11 @@ const WordInput = () => {
     
     return (
         <div className="word-input">
-            {charBox}
+            {allWords.slice(0, currentTry)}
+            <div className="word-box input-box">
+                {inputBox}
+            </div>
+            {allWords.slice(currentTry+1, NUM_TRY+1)}
         </div>
     );
 }
diff --git a/src/components/style/Boxes.css b/src/components/style/Boxes.css
new file mode 100644
index 0000000000000000000000000000000000000000..42ab73e42561e62d4f93b7fb238843777db0e3de
--- /dev/null
+++ b/src/components/style/Boxes.css
@@ -0,0 +1,30 @@
+.char-box {
+    width: 50px;
+    height: 50px;
+    display: inline-block;
+    text-align: center;
+    vertical-align: middle;
+    line-height: 50px;
+    margin: 5px;
+    border: 1px solid black;
+}
+
+.correct-box {
+    background-color: green;
+    color: white;
+}
+
+.misplaced-box {
+    background-color: yellow;
+    color: black;
+}
+
+.incorrect-box {
+    background-color: red;
+    color: white;
+}
+
+.default-box {
+    background-color: white;
+    color: black;
+}
\ No newline at end of file
diff --git a/src/helpers/validateInput.js b/src/helpers/validateInput.js
index 23fc32089babc3dc914f784b3585f4aa98bb8c08..d4a5a19c5243811dbef9c56a0e9c451ff00065f1 100644
--- a/src/helpers/validateInput.js
+++ b/src/helpers/validateInput.js
@@ -1,28 +1,57 @@
-export function validateInput(input, actual) {
-    let initInput = input.split("");
-    let evaluateInput = actual.split("");
+import axios from 'axios';
+import { findIndex, includes, zipWith } from 'ramda';
 
-    const mappedInput = initInput.map((e, idx) => {
-        if (e === actual[idx]) {
-            evaluateInput.splice(idx, 1);
-            return "Correct";
-        } else {
-            const filteredActual = evaluateInput.map((elementActual, idxActual) => {
-                if (elementActual === e) {
-                    return [elementActual, idxActual];
-                } else {
-                    return undefined;
-                }
-            }).filter(x => x);
+export async function validateInput(input, actualString) {
+    const isValidLength = checkInputLength(input, 5);
+    if (!isValidLength) {
+        return { "result": null, "error": "Not enough characters" };
+    }
 
-            if (filteredActual.length === 0) {
-                return "Wrong";
-            } else if (e === filteredActual[0][0]) {
-                evaluateInput.splice(filteredActual[0][1], 1)
-                return "Misplaced";
-            }
+    const isInputDefined = await checkInputDefined(input);
+    if (isInputDefined["res"] === false) {
+        return { "result": null, "error": "Word is not defined" };
+    } else if (isInputDefined["error"]) {
+        return { "result": null, "error": "Validation error: " + isInputDefined["error"] };
+    }
+
+    let actual = actualString.split("");
+
+    const checkCorrect = (i, a) => {
+        const status = (i === a) ? "correct" : "incorrect";
+        return status;
+    }
+    const firstEvaluation = zipWith(checkCorrect, input, actual);
+  
+    const lastEvaluation = firstEvaluation.map((e, idx) => {
+        const word = input[idx];
+        if (e === "correct") {
+            actual[idx] = '';
         }
+        else if (e === "incorrect" && includes(word, actual)) {
+            const actualIdx = findIndex((i) => word === i)(actual);
+            actual[actualIdx] = '';
+            return "misplaced";
+        } 
+        return e;
     });
+    
+    return { "result": lastEvaluation, "error": null };
+}
 
-    return mappedInput;
+function checkInputLength(input, length) {
+    const isValid = (input.length === length) ? true : false;
+    return isValid;
+}
+
+// TODO: Replace backend URL to deployed one
+async function checkInputDefined(input) {
+    const response = await axios({
+        method: 'get',
+        url: 'http://localhost:8080/check/' + input.join(""),
+    });
+    if (response.statusText === "OK") {
+        return { "res": response.data, "error": null };
+    } else {
+        return { "res": null, "error": response.statusText };
+    }
 }