editor-cv #26
							
								
								
									
										36
									
								
								dist/api/index.php
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								dist/api/index.php
									
									
									
									
										vendored
									
									
								
							@ -373,10 +373,40 @@ $app->post("/user/changePassword", function (Request $request, Response $respons
 | 
			
		||||
    return $response->withStatus(500);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
$app->post("/projectData", function (Request $request, Response $response)
 | 
			
		||||
$app->patch("/timelineData/{timeline}/{id}", function (Request $request, Response $response, array $args)
 | 
			
		||||
{
 | 
			
		||||
    $response->getBody()->write(json_encode(array("test" => "test")));
 | 
			
		||||
    return $response;
 | 
			
		||||
    global $timelineData;
 | 
			
		||||
    if ($args["timeline"] == "edu" && $args["id"] != "undefined")
 | 
			
		||||
    {
 | 
			
		||||
        $data = $request->getParsedBody();
 | 
			
		||||
        if (empty($data["dateFrom"]) || empty($data["dateTo"]) || empty($data["grade"]) || empty($data["course"]))
 | 
			
		||||
        {
 | 
			
		||||
            // uh oh sent some empty data
 | 
			
		||||
            $response->getBody()->write(json_encode(array("error" => "Only some of the data was sent")));
 | 
			
		||||
            return $response->withStatus(400);
 | 
			
		||||
        } 
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        if (!$timelineData->updateEduData($data["dateFrom"], $data["dateTo"], $data["grade"], $data["course"], $args["id"]))
 | 
			
		||||
        {
 | 
			
		||||
            // uh oh something went wrong
 | 
			
		||||
            $response->getBody()->write(json_encode(array("error" => "Something went wrong")));
 | 
			
		||||
            return $response->withStatus(500);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        return $response->withStatus(200);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if ($args["timeline"] == "work" && $args["id"] != null)
 | 
			
		||||
    {
 | 
			
		||||
        
 | 
			
		||||
        return $response->withStatus(200);   
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    $response->getBody()->write(json_encode(array("error" => "The correct data was not sent")));
 | 
			
		||||
    return $response->withStatus(400);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
$app->run();
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								dist/api/middleware.php
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								dist/api/middleware.php
									
									
									
									
										vendored
									
									
								
							@ -33,6 +33,7 @@ class middleware
 | 
			
		||||
     */
 | 
			
		||||
    function baseMiddleware(App $app): void
 | 
			
		||||
    {
 | 
			
		||||
        $app->addBodyParsingMiddleware();
 | 
			
		||||
        $app->addRoutingMiddleware();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										25
									
								
								dist/api/timelineData.php
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								dist/api/timelineData.php
									
									
									
									
										vendored
									
									
								
							@ -17,7 +17,7 @@ class timelineData
 | 
			
		||||
    function getEduData(): array
 | 
			
		||||
    {
 | 
			
		||||
        $conn = dbConn();
 | 
			
		||||
        $stmt = $conn->prepare("SELECT startPeriod, endPeriod, grade, course  FROM edu ORDER BY startPeriod DESC;");
 | 
			
		||||
        $stmt = $conn->prepare("SELECT ID, startPeriod, endPeriod, grade, course  FROM edu ORDER BY startPeriod DESC;");
 | 
			
		||||
        $stmt->execute();
 | 
			
		||||
 | 
			
		||||
        // set the resulting array to associative
 | 
			
		||||
@ -49,5 +49,26 @@ class timelineData
 | 
			
		||||
        }
 | 
			
		||||
        return array("errorMessage" => "Error, work data not found");
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Update education data
 | 
			
		||||
     * @param string $dateFrom - Start date
 | 
			
		||||
     * @param string $dateTo - End date
 | 
			
		||||
     * @param string $grade - Grade
 | 
			
		||||
     * @param string $course - Course
 | 
			
		||||
     * @param string $id - ID of the education data
 | 
			
		||||
     * @return bool - True if successful, false if not
 | 
			
		||||
     */
 | 
			
		||||
    function updateEduData(string $dateFrom, string $dateTo, string $grade, string $course, string $id): bool
 | 
			
		||||
    {
 | 
			
		||||
        $conn = dbConn();
 | 
			
		||||
        $stmt = $conn->prepare("UPDATE edu SET startPeriod = :dateFrom, endPeriod = :dateTo, grade = :grade, course = :course WHERE ID = :id;");
 | 
			
		||||
        $stmt->bindParam(":dateFrom", $dateFrom);
 | 
			
		||||
        $stmt->bindParam(":dateTo", $dateTo);
 | 
			
		||||
        $stmt->bindParam(":grade", $grade);
 | 
			
		||||
        $stmt->bindParam(":course", $course);
 | 
			
		||||
        $stmt->bindParam(":id", $id);
 | 
			
		||||
        return $stmt->execute();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								dist/editor/js/editor.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/editor/js/editor.js
									
									
									
									
										vendored
									
									
								
							@ -1 +1 @@
 | 
			
		||||
let dateOptions={month:"short",year:"numeric"};function edit(e){document.querySelector("#timelineItem"+e).classList.toggle("editing"),document.querySelector("#grade"+e).removeAttribute("disabled"),document.querySelector("#course"+e).removeAttribute("disabled")}function updateItem(e,t){t.preventDefault();let n=new FormData;n.append("dateFrom",document.querySelector("#dateFrom"+e).value),n.append("dateTo",document.querySelector("#dateTo"+e).value),n.append("grade",document.querySelector("#grade"+e).value),n.append("course",document.querySelector("#course"+e).value),fetch("/api/timelineData/edu/"+e,{method:"PUT",body:n,headers:{Authorization:"Bearer "+localStorage.getItem("token")}}).then((t=>{if(t.ok)return document.querySelector("#timelineItem"+e).classList.toggle("editing"),document.querySelector("#grade"+e).setAttribute("disabled",""),void document.querySelector("#course"+e).setAttribute("disabled","");t.json().then((e=>{alert(e.message)}))}))}document.addEventListener("DOMContentLoaded",(()=>{document.querySelector("#dateFrom").max=(new Date).toISOString().split("T")[0],fetch("/api/timelineData/edu").then((e=>{e.json().then((t=>{if(e.ok)for(let e=0;e<t.length;e++){let n=document.createElement("form");n.id="timelineItem"+e,n.classList.add("timelineItem"),n.onsubmit=t=>updateItem(e,t),n.innerHTML=`\n                    <div class="modifyBtnContainer">\n                        <button class="edit" type="button" id="edit${e}" onclick="edit(${e})"><i class="fa-solid fa-pen-to-square"></i></button>\n                        <button class="delete" type="button" id="delete${e}"><i class="fa-solid fa-trash"></i></button>\n                    </div>\n                    <div class="dateContainer formControl">\n                        <input type="date" name="dateFrom${e}" id="dateFrom${e}" onload="this.max = new Date().toISOString().split('T')[0]" value="${t[e].startPeriod}">\n                        -\n                        <input type="date" name="dateTo${e}" id="dateTo${e}" value="${t[e].endPeriod}">\n                    </div>\n\t\t\t\t\t<h3 class="timelineHeader">${new Date(t[e].startPeriod).toLocaleString("en-gb",dateOptions)} - ${new Date(t[e].endPeriod).toLocaleString("en-gb",dateOptions)}</h3>\n                    <div class="gradeContainer formControl">\n                        <label for="grade${e}">Grade:</label>\n                        <input type="text" name="grade${e}" id="grade${e}" value="${t[e].grade}" disabled>\n                    </div>\n\t\t\t\t\t<div class="formControl">\n\t\t\t\t\t    <textarea class="courseText" name="course${e}" id="course${e}" cols="10" rows="3" disabled>${t[e].course}</textarea>\n\t\t\t\t\t</div>\n\t\t\t\t\t\n                    <div class="error hidden" id="eduError">\n                        <button class="close" type="button">×</button>\n                        <div></div>\n                    </div>\n\t\t\t\t\t<input type="submit" value="Change">\n\t\t\t\t`,document.getElementById("edu").appendChild(n)}else document.querySelector("#edu").innerHTML="No education data found"}))}))})),document.querySelector("#navOpen").addEventListener("click",(e=>{document.querySelector("nav.sideNav").style.removeProperty("width"),document.querySelector("main.editor").style.removeProperty("margin-left"),e.target.style.removeProperty("visibility")})),document.querySelector("#navClose").addEventListener("click",(()=>{document.querySelector("nav.sideNav").style.width="0",document.querySelector("main.editor").style.marginLeft="0",document.querySelector("#navOpen").style.visibility="visible"}));
 | 
			
		||||
let dateOptions={month:"short",year:"numeric"};function edit(e){document.querySelector("#timelineItem"+e).classList.toggle("editing"),document.querySelector("#grade"+e).toggleAttribute("disabled"),document.querySelector("#course"+e).toggleAttribute("disabled")}function updateEduItem(e,t){t.preventDefault();let n={};n.dateFrom=document.querySelector("#dateFrom"+e).value,n.dateTo=document.querySelector("#dateTo"+e).value,n.grade=document.querySelector("#grade"+e).value,n.course=document.querySelector("#course"+e).value,fetch("/api/timelineData/edu/"+e,{method:"PATCH",body:JSON.stringify(n),headers:{"Content-Type":"application/json",Authorization:"Bearer "+localStorage.getItem("token")}}).then((t=>{if(t.ok)return document.querySelector("#timelineHeader"+e).innerHTML=new Date(document.querySelector("#dateFrom"+e).value).toLocaleString("en-gb",dateOptions)+" - "+new Date(document.querySelector("#dateTo"+e).value).toLocaleString("en-gb",dateOptions),document.querySelector("#timelineItem"+e).classList.toggle("editing"),document.querySelector("#grade"+e).setAttribute("disabled",""),void document.querySelector("#course"+e).setAttribute("disabled","");401!==t.status?t.json().then((t=>{document.querySelector("#eduError"+e).classList.remove("hidden"),document.querySelector(`#eduError${e} div`).innerHTML=t.error})):window.location.href="./"}))}document.addEventListener("DOMContentLoaded",(()=>{document.querySelector("#dateFrom").max=(new Date).toISOString().split("T")[0],fetch("/api/timelineData/edu").then((e=>{e.json().then((t=>{if(e.ok)for(let e=0;e<t.length;e++){let n=t[e].ID,o=document.createElement("form");o.id="timelineItem"+n,o.classList.add("timelineItem"),o.onsubmit=e=>updateEduItem(n,e),o.innerHTML=`\n                    <div class="modifyBtnContainer">\n                        <button class="edit" type="button" id="edit${n}" onclick="edit(${n})"><i class="fa-solid fa-pen-to-square"></i></button>\n                        <button class="delete" type="button" id="delete${n}" onclick="deleteEduItem(${n})"><i class="fa- fa-trash"></i></button>\n                    </div>\n                    <div class="dateContainer formControl">\n                        <input type="date" name="dateFrom${n}" id="dateFrom${n}" onload="this.max = new Date().toISOString().split('T')[0]" value="${t[e].startPeriod}">\n                        -\n                        <input type="date" name="dateTo${n}" id="dateTo${n}" value="${t[e].endPeriod}">\n                    </div>\n\t\t\t\t\t<h3 class="timelineHeader" id="timelineHeader${n}">${new Date(t[e].startPeriod).toLocaleString("en-gb",dateOptions)} - ${new Date(t[e].endPeriod).toLocaleString("en-gb",dateOptions)}</h3>\n                    <div class="gradeContainer formControl">\n                        <label for="grade${n}">Grade:</label>\n                        <input type="text" name="grade${n}" id="grade${n}" value="${t[e].grade}" disabled>\n                    </div>\n\t\t\t\t\t<div class="formControl">\n\t\t\t\t\t    <textarea class="courseText" name="course${n}" id="course${n}" cols="10" rows="3" disabled>${t[e].course}</textarea>\n\t\t\t\t\t</div>\n\t\t\t\t\t\n                    <div class="error hidden" id="eduError${n}">\n                        <button class="close" type="button" onclick="this.parentElement.classList.toggle('hidden');">×</button>\n                        <div></div>\n                    </div>\n\t\t\t\t\t<input type="submit" value="Change">\n\t\t\t\t`,document.getElementById("edu").appendChild(o)}else document.querySelector("#edu").innerHTML="No education data found"}))}))})),document.querySelector("#navOpen").addEventListener("click",(e=>{document.querySelector("nav.sideNav").style.removeProperty("width"),document.querySelector("main.editor").style.removeProperty("margin-left"),e.target.style.removeProperty("visibility")})),document.querySelector("#navClose").addEventListener("click",(()=>{document.querySelector("nav.sideNav").style.width="0",document.querySelector("main.editor").style.marginLeft="0",document.querySelector("#navOpen").style.visibility="visible"}));
 | 
			
		||||
							
								
								
									
										2
									
								
								dist/editor/js/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/editor/js/index.js
									
									
									
									
										vendored
									
									
								
							@ -1 +1 @@
 | 
			
		||||
function showErrorMessage(e,t){document.querySelector(`#${t}Error`).classList.remove("hidden"),document.querySelector(`#${t}Error div`).innerText=e}function switchView(e,t){document.querySelector(e).classList.toggle("shown"),setTimeout((()=>document.querySelector(e).style.transform="translateX(150vw)"),500),setTimeout((()=>document.querySelector(e).style.display="none"),500),setTimeout((()=>document.querySelector(t).style.removeProperty("display")),200),setTimeout((()=>document.querySelector(t).classList.toggle("shown")),300),setTimeout((()=>document.querySelector(t).style.removeProperty("transform")),400)}document.addEventListener("DOMContentLoaded",(e=>{fetch("/api/user/isLoggedIn").then((e=>{e.ok&&(window.location.href="./editor.html")}))})),document.querySelector("#login form").addEventListener("submit",(e=>{e.preventDefault();let t=new FormData;if(e.target.username.value.length>0&&e.target.password.value.length>0)return t.append("username",e.target.username.value),t.append("password",e.target.password.value),void fetch("/api/user/login",{method:"POST",body:t}).then((e=>e.json())).then((e=>{if(res.ok)return localStorage.setItem("token",e.token),void(window.location.href="./editor.html");400!==res.status?showErrorMessage("Invalid username or password.","login"):showErrorMessage("Please type in a username and password.","login")}));showErrorMessage("Please type in a username and password.","login")})),document.querySelector("#loginError .close").addEventListener("click",(()=>document.querySelector("#loginError").classList.toggle("hidden"))),document.querySelector("#resetError .close").addEventListener("click",(()=>document.querySelector("#resetError").classList.toggle("hidden"))),document.querySelector("#changeError .close").addEventListener("click",(()=>document.querySelector("#changeError").classList.toggle("hidden"))),document.querySelectorAll("form i.fa-eye").forEach((e=>{e.addEventListener("click",(e=>{if("password"===e.target.previousElementSibling.type)return e.target.previousElementSibling.type="text",e.target.classList.remove("fa-eye"),void e.target.classList.add("fa-eye-slash");e.target.previousElementSibling.type="password",e.target.classList.remove("fa-eye-slash"),e.target.classList.add("fa-eye")}))})),document.querySelector("#resetPwd").addEventListener("click",(()=>{switchView("#login","#resetPassword")})),document.querySelector("#loginBtn").addEventListener("click",(()=>{switchView("#resetPassword","#login")})),document.querySelector("#resetPassword form").addEventListener("submit",(e=>{e.preventDefault();let t=new FormData;""!==e.target.email?(window.email=e.target.email.value,t.append("email",e.target.email.value),fetch(`/api/user/checkResetEmail/${e.target.email.value}`).then((e=>{e.ok&&switchView("#resetPassword","#checkResetCode"),showErrorMessage("Invalid email.","reset")}))):showErrorMessage("Please type in your email.","reset")})),document.querySelector("#checkResetCode form").addEventListener("submit",(e=>{e.preventDefault();let t=new FormData;""!==e.target.code.value?(t.append("code",e.target.code.value),fetch(`/api/user/checkResetCode/${e.target.code.value}`).then((e=>{e.ok&&switchView("#checkResetCode","#changePassword"),showErrorMessage("Invalid code.","resetCode")}))):showErrorMessage("Please type in your reset code.","check")})),document.querySelector("#changePassword form").addEventListener("submit",(e=>{e.preventDefault();let t=new FormData;""!==e.target.pass.value||""!==e.target.rePass.value?e.target.pass.value===e.target.rePass.value?(t.append("password",e.target.pass.value),fetch("/api/user/changePassword",{method:"POST",body:t}).then((e=>{e.ok&&switchView("#changePassword","#login"),showErrorMessage("Something went wrong.","change")}))):showErrorMessage("Passwords do not match.","change"):showErrorMessage("Please type in a new password.","change")}));
 | 
			
		||||
function showErrorMessage(e,t){document.querySelector(`#${t}Error`).classList.remove("hidden"),document.querySelector(`#${t}Error div`).innerText=e}function switchView(e,t){document.querySelector(e).classList.toggle("shown"),setTimeout((()=>document.querySelector(e).style.transform="translateX(150vw)"),500),setTimeout((()=>document.querySelector(e).style.display="none"),500),setTimeout((()=>document.querySelector(t).style.removeProperty("display")),200),setTimeout((()=>document.querySelector(t).classList.toggle("shown")),300),setTimeout((()=>document.querySelector(t).style.removeProperty("transform")),400)}document.addEventListener("DOMContentLoaded",(e=>{fetch("/api/user/isLoggedIn").then((e=>{e.ok&&(window.location.href="./editor.html")}))})),document.querySelector("#login form").addEventListener("submit",(e=>{e.preventDefault();let t=new FormData;if(e.target.username.value.length>0&&e.target.password.value.length>0)return t.append("username",e.target.username.value),t.append("password",e.target.password.value),void fetch("/api/user/login",{method:"POST",body:t}).then((e=>e.json().then((t=>{if(e.ok)return localStorage.setItem("token",t.token),void(window.location.href="./editor.html");400!==e.status?showErrorMessage("Invalid username or password.","login"):showErrorMessage("Please type in a username and password.","login")}))));showErrorMessage("Please type in a username and password.","login")})),document.querySelector("#loginError .close").addEventListener("click",(()=>document.querySelector("#loginError").classList.toggle("hidden"))),document.querySelector("#resetError .close").addEventListener("click",(()=>document.querySelector("#resetError").classList.toggle("hidden"))),document.querySelector("#changeError .close").addEventListener("click",(()=>document.querySelector("#changeError").classList.toggle("hidden"))),document.querySelectorAll("form i.fa-eye").forEach((e=>{e.addEventListener("click",(e=>{if("password"===e.target.previousElementSibling.type)return e.target.previousElementSibling.type="text",e.target.classList.remove("fa-eye"),void e.target.classList.add("fa-eye-slash");e.target.previousElementSibling.type="password",e.target.classList.remove("fa-eye-slash"),e.target.classList.add("fa-eye")}))})),document.querySelector("#resetPwd").addEventListener("click",(()=>{switchView("#login","#resetPassword")})),document.querySelector("#loginBtn").addEventListener("click",(()=>{switchView("#resetPassword","#login")})),document.querySelector("#resetPassword form").addEventListener("submit",(e=>{e.preventDefault();let t=new FormData;""!==e.target.email?(window.email=e.target.email.value,t.append("email",e.target.email.value),fetch(`/api/user/checkResetEmail/${e.target.email.value}`).then((e=>{e.ok&&switchView("#resetPassword","#checkResetCode"),showErrorMessage("Invalid email.","reset")}))):showErrorMessage("Please type in your email.","reset")})),document.querySelector("#checkResetCode form").addEventListener("submit",(e=>{e.preventDefault();let t=new FormData;""!==e.target.code.value?(t.append("code",e.target.code.value),fetch(`/api/user/checkResetCode/${e.target.code.value}`).then((e=>{e.ok&&switchView("#checkResetCode","#changePassword"),showErrorMessage("Invalid code.","resetCode")}))):showErrorMessage("Please type in your reset code.","check")})),document.querySelector("#changePassword form").addEventListener("submit",(e=>{e.preventDefault();let t=new FormData;""!==e.target.pass.value||""!==e.target.rePass.value?e.target.pass.value===e.target.rePass.value?(t.append("password",e.target.pass.value),fetch("/api/user/changePassword",{method:"POST",body:t}).then((e=>{e.ok&&switchView("#changePassword","#login"),showErrorMessage("Something went wrong.","change")}))):showErrorMessage("Passwords do not match.","change"):showErrorMessage("Please type in a new password.","change")}));
 | 
			
		||||
@ -373,10 +373,40 @@ $app->post("/user/changePassword", function (Request $request, Response $respons
 | 
			
		||||
    return $response->withStatus(500);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
$app->post("/projectData", function (Request $request, Response $response)
 | 
			
		||||
$app->patch("/timelineData/{timeline}/{id}", function (Request $request, Response $response, array $args)
 | 
			
		||||
{
 | 
			
		||||
    $response->getBody()->write(json_encode(array("test" => "test")));
 | 
			
		||||
    return $response;
 | 
			
		||||
    global $timelineData;
 | 
			
		||||
    if ($args["timeline"] == "edu" && $args["id"] != "undefined")
 | 
			
		||||
    {
 | 
			
		||||
        $data = $request->getParsedBody();
 | 
			
		||||
        if (empty($data["dateFrom"]) || empty($data["dateTo"]) || empty($data["grade"]) || empty($data["course"]))
 | 
			
		||||
        {
 | 
			
		||||
            // uh oh sent some empty data
 | 
			
		||||
            $response->getBody()->write(json_encode(array("error" => "Only some of the data was sent")));
 | 
			
		||||
            return $response->withStatus(400);
 | 
			
		||||
        } 
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        if (!$timelineData->updateEduData($data["dateFrom"], $data["dateTo"], $data["grade"], $data["course"], $args["id"]))
 | 
			
		||||
        {
 | 
			
		||||
            // uh oh something went wrong
 | 
			
		||||
            $response->getBody()->write(json_encode(array("error" => "Something went wrong")));
 | 
			
		||||
            return $response->withStatus(500);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        return $response->withStatus(200);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if ($args["timeline"] == "work" && $args["id"] != null)
 | 
			
		||||
    {
 | 
			
		||||
        
 | 
			
		||||
        return $response->withStatus(200);   
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    $response->getBody()->write(json_encode(array("error" => "The correct data was not sent")));
 | 
			
		||||
    return $response->withStatus(400);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
$app->run();
 | 
			
		||||
 | 
			
		||||
@ -33,6 +33,7 @@ class middleware
 | 
			
		||||
     */
 | 
			
		||||
    function baseMiddleware(App $app): void
 | 
			
		||||
    {
 | 
			
		||||
        $app->addBodyParsingMiddleware();
 | 
			
		||||
        $app->addRoutingMiddleware();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@ class timelineData
 | 
			
		||||
    function getEduData(): array
 | 
			
		||||
    {
 | 
			
		||||
        $conn = dbConn();
 | 
			
		||||
        $stmt = $conn->prepare("SELECT startPeriod, endPeriod, grade, course  FROM edu ORDER BY startPeriod DESC;");
 | 
			
		||||
        $stmt = $conn->prepare("SELECT ID, startPeriod, endPeriod, grade, course  FROM edu ORDER BY startPeriod DESC;");
 | 
			
		||||
        $stmt->execute();
 | 
			
		||||
 | 
			
		||||
        // set the resulting array to associative
 | 
			
		||||
@ -49,5 +49,26 @@ class timelineData
 | 
			
		||||
        }
 | 
			
		||||
        return array("errorMessage" => "Error, work data not found");
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Update education data
 | 
			
		||||
     * @param string $dateFrom - Start date
 | 
			
		||||
     * @param string $dateTo - End date
 | 
			
		||||
     * @param string $grade - Grade
 | 
			
		||||
     * @param string $course - Course
 | 
			
		||||
     * @param string $id - ID of the education data
 | 
			
		||||
     * @return bool - True if successful, false if not
 | 
			
		||||
     */
 | 
			
		||||
    function updateEduData(string $dateFrom, string $dateTo, string $grade, string $course, string $id): bool
 | 
			
		||||
    {
 | 
			
		||||
        $conn = dbConn();
 | 
			
		||||
        $stmt = $conn->prepare("UPDATE edu SET startPeriod = :dateFrom, endPeriod = :dateTo, grade = :grade, course = :course WHERE ID = :id;");
 | 
			
		||||
        $stmt->bindParam(":dateFrom", $dateFrom);
 | 
			
		||||
        $stmt->bindParam(":dateTo", $dateTo);
 | 
			
		||||
        $stmt->bindParam(":grade", $grade);
 | 
			
		||||
        $stmt->bindParam(":course", $course);
 | 
			
		||||
        $stmt->bindParam(":id", $id);
 | 
			
		||||
        return $stmt->execute();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -20,31 +20,32 @@ document.addEventListener('DOMContentLoaded', () =>
 | 
			
		||||
            {
 | 
			
		||||
                for (let i = 0; i < json.length; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    let id = json[i].ID;
 | 
			
		||||
                    let timelineItem = document.createElement("form")
 | 
			
		||||
                    timelineItem.id = "timelineItem" + i;
 | 
			
		||||
                    timelineItem.id = "timelineItem" + id;
 | 
			
		||||
                    timelineItem.classList.add("timelineItem");
 | 
			
		||||
                    timelineItem.onsubmit = e => updateItem(i, e);
 | 
			
		||||
                    timelineItem.onsubmit = e => updateEduItem(id, e);
 | 
			
		||||
                    timelineItem.innerHTML = `
 | 
			
		||||
                    <div class="modifyBtnContainer">
 | 
			
		||||
                        <button class="edit" type="button" id="edit${i}" onclick="edit(${i})"><i class="fa-solid fa-pen-to-square"></i></button>
 | 
			
		||||
                        <button class="delete" type="button" id="delete${i}"><i class="fa-solid fa-trash"></i></button>
 | 
			
		||||
                        <button class="edit" type="button" id="edit${id}" onclick="edit(${id})"><i class="fa-solid fa-pen-to-square"></i></button>
 | 
			
		||||
                        <button class="delete" type="button" id="delete${id}" onclick="deleteEduItem(${id})"><i class="fa- fa-trash"></i></button>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="dateContainer formControl">
 | 
			
		||||
                        <input type="date" name="dateFrom${i}" id="dateFrom${i}" onload="this.max = new Date().toISOString().split('T')[0]" value="${json[i]['startPeriod']}">
 | 
			
		||||
                        <input type="date" name="dateFrom${id}" id="dateFrom${id}" onload="this.max = new Date().toISOString().split('T')[0]" value="${json[i]['startPeriod']}">
 | 
			
		||||
                        -
 | 
			
		||||
                        <input type="date" name="dateTo${i}" id="dateTo${i}" value="${json[i]['endPeriod']}">
 | 
			
		||||
                        <input type="date" name="dateTo${id}" id="dateTo${id}" value="${json[i]['endPeriod']}">
 | 
			
		||||
                    </div>
 | 
			
		||||
					<h3 class="timelineHeader">${new Date(json[i]["startPeriod"]).toLocaleString('en-gb', dateOptions)} - ${new Date(json[i]["endPeriod"]).toLocaleString('en-gb', dateOptions)}</h3>
 | 
			
		||||
					<h3 class="timelineHeader" id="timelineHeader${id}">${new Date(json[i]["startPeriod"]).toLocaleString('en-gb', dateOptions)} - ${new Date(json[i]["endPeriod"]).toLocaleString('en-gb', dateOptions)}</h3>
 | 
			
		||||
                    <div class="gradeContainer formControl">
 | 
			
		||||
                        <label for="grade${i}">Grade:</label>
 | 
			
		||||
                        <input type="text" name="grade${i}" id="grade${i}" value="${json[i]['grade']}" disabled>
 | 
			
		||||
                        <label for="grade${id}">Grade:</label>
 | 
			
		||||
                        <input type="text" name="grade${id}" id="grade${id}" value="${json[i]['grade']}" disabled>
 | 
			
		||||
                    </div>
 | 
			
		||||
					<div class="formControl">
 | 
			
		||||
					    <textarea class="courseText" name="course${i}" id="course${i}" cols="10" rows="3" disabled>${json[i]['course']}</textarea>
 | 
			
		||||
					    <textarea class="courseText" name="course${id}" id="course${id}" cols="10" rows="3" disabled>${json[i]['course']}</textarea>
 | 
			
		||||
					</div>
 | 
			
		||||
					
 | 
			
		||||
                    <div class="error hidden" id="eduError">
 | 
			
		||||
                        <button class="close" type="button">×</button>
 | 
			
		||||
                    <div class="error hidden" id="eduError${id}">
 | 
			
		||||
                        <button class="close" type="button" onclick="this.parentElement.classList.toggle('hidden');">×</button>
 | 
			
		||||
                        <div></div>
 | 
			
		||||
                    </div>
 | 
			
		||||
					<input type="submit" value="Change">
 | 
			
		||||
@ -72,42 +73,56 @@ document.querySelector("#navClose").addEventListener("click", () =>
 | 
			
		||||
    document.querySelector("#navOpen").style.visibility = "visible";
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function edit(i)
 | 
			
		||||
/**
 | 
			
		||||
 * Switches the timeline item between edit and view mode
 | 
			
		||||
 * @param id the id of the timeline item
 | 
			
		||||
 */
 | 
			
		||||
function edit(id)
 | 
			
		||||
{
 | 
			
		||||
    document.querySelector("#timelineItem" + i).classList.toggle("editing");
 | 
			
		||||
    document.querySelector("#grade" + i).removeAttribute("disabled");
 | 
			
		||||
    document.querySelector("#course" + i).removeAttribute("disabled");
 | 
			
		||||
    document.querySelector("#timelineItem" + id).classList.toggle("editing");
 | 
			
		||||
    document.querySelector("#grade" + id).toggleAttribute("disabled");
 | 
			
		||||
    document.querySelector("#course" + id).toggleAttribute("disabled");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function updateItem(i, e)
 | 
			
		||||
function updateEduItem(id, e)
 | 
			
		||||
{
 | 
			
		||||
    e.preventDefault();
 | 
			
		||||
    let data = new FormData();
 | 
			
		||||
    data.append("dateFrom", document.querySelector("#dateFrom" + i).value);
 | 
			
		||||
    data.append("dateTo", document.querySelector("#dateTo" + i).value);
 | 
			
		||||
    data.append("grade", document.querySelector("#grade" + i).value);
 | 
			
		||||
    data.append("course", document.querySelector("#course" + i).value);
 | 
			
		||||
    
 | 
			
		||||
    fetch("/api/timelineData/edu/" + i, {
 | 
			
		||||
        method: "PUT",
 | 
			
		||||
        body: data,
 | 
			
		||||
    let data = {}
 | 
			
		||||
    data["dateFrom"] = document.querySelector("#dateFrom" + id).value;
 | 
			
		||||
    data["dateTo"] = document.querySelector("#dateTo" + id).value;
 | 
			
		||||
    data["grade"] = document.querySelector("#grade" + id).value;
 | 
			
		||||
    data["course"] = document.querySelector("#course" + id).value;
 | 
			
		||||
    
 | 
			
		||||
    fetch("/api/timelineData/edu/" + id, {
 | 
			
		||||
        method: "PATCH",
 | 
			
		||||
        body: JSON.stringify(data),
 | 
			
		||||
        headers: {
 | 
			
		||||
            "Content-Type": "application/json",
 | 
			
		||||
            "Authorization": "Bearer " + localStorage.getItem("token")
 | 
			
		||||
        }
 | 
			
		||||
    }).then(res =>
 | 
			
		||||
    {
 | 
			
		||||
        if (res.ok)
 | 
			
		||||
        {
 | 
			
		||||
            document.querySelector("#timelineItem" + i).classList.toggle("editing");
 | 
			
		||||
            document.querySelector("#grade" + i).setAttribute("disabled", "");
 | 
			
		||||
            document.querySelector("#course" + i).setAttribute("disabled", "");
 | 
			
		||||
            document.querySelector("#timelineHeader" + id).innerHTML = new Date(document.querySelector("#dateFrom" + id).value).toLocaleString('en-gb', dateOptions) + " - " + new Date(document.querySelector("#dateTo" + id).value).toLocaleString('en-gb', dateOptions);
 | 
			
		||||
            document.querySelector("#timelineItem" + id).classList.toggle("editing");
 | 
			
		||||
            document.querySelector("#grade" + id).setAttribute("disabled", "");
 | 
			
		||||
            document.querySelector("#course" + id).setAttribute("disabled", "");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (res.status === 401)
 | 
			
		||||
        {
 | 
			
		||||
            window.location.href = "./";
 | 
			
		||||
            return;
 | 
			
		||||
        }        
 | 
			
		||||
        
 | 
			
		||||
        res.json().then(json =>
 | 
			
		||||
        {
 | 
			
		||||
            alert(json.message);
 | 
			
		||||
        })
 | 
			
		||||
            document.querySelector("#eduError" + id).classList.remove("hidden");
 | 
			
		||||
            document.querySelector(`#eduError${id} div`).innerHTML = json.error;
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
@ -39,7 +39,7 @@ document.querySelector("#login form").addEventListener("submit", e =>
 | 
			
		||||
    {
 | 
			
		||||
            method: "POST", 
 | 
			
		||||
            body: loginData
 | 
			
		||||
        }).then(res => res.json()).then(json =>
 | 
			
		||||
        }).then(res => res.json().then(json =>
 | 
			
		||||
        {
 | 
			
		||||
            if (res.ok)
 | 
			
		||||
            {
 | 
			
		||||
@ -53,7 +53,7 @@ document.querySelector("#login form").addEventListener("submit", e =>
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            showErrorMessage("Invalid username or password.", "login");
 | 
			
		||||
        });
 | 
			
		||||
        }));
 | 
			
		||||
       return; 
 | 
			
		||||
    }
 | 
			
		||||
    showErrorMessage("Please type in a username and password.", "login");
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user