From 7b04af165ed313ccd0050a7a8dcc19b426a2e87e Mon Sep 17 00:00:00 2001 From: rodude123 Date: Sun, 9 Oct 2022 23:32:50 +0100 Subject: [PATCH] Being able to edit a timeline item fully working as currently tested. Signed-off-by: rodude123 --- dist/api/index.php | 36 +++++++++++++++++-- dist/api/middleware.php | 1 + dist/api/timelineData.php | 25 +++++++++++-- dist/editor/js/editor.js | 2 +- dist/editor/js/index.js | 2 +- src/api/index.php | 36 +++++++++++++++++-- src/api/middleware.php | 1 + src/api/timelineData.php | 25 +++++++++++-- src/editor/js/editor.js | 75 +++++++++++++++++++++++---------------- src/editor/js/index.js | 4 +-- 10 files changed, 163 insertions(+), 44 deletions(-) diff --git a/dist/api/index.php b/dist/api/index.php index 2c657ca..fcd86b4 100644 --- a/dist/api/index.php +++ b/dist/api/index.php @@ -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(); diff --git a/dist/api/middleware.php b/dist/api/middleware.php index b194905..ece8897 100644 --- a/dist/api/middleware.php +++ b/dist/api/middleware.php @@ -33,6 +33,7 @@ class middleware */ function baseMiddleware(App $app): void { + $app->addBodyParsingMiddleware(); $app->addRoutingMiddleware(); } diff --git a/dist/api/timelineData.php b/dist/api/timelineData.php index 71e5c45..29f5cd5 100644 --- a/dist/api/timelineData.php +++ b/dist/api/timelineData.php @@ -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(); + } + } diff --git a/dist/editor/js/editor.js b/dist/editor/js/editor.js index d25d547..9544b59 100644 --- a/dist/editor/js/editor.js +++ b/dist/editor/js/editor.js @@ -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;eupdateItem(e,t),n.innerHTML=`\n
\n \n \n
\n
\n \n -\n \n
\n\t\t\t\t\t

${new Date(t[e].startPeriod).toLocaleString("en-gb",dateOptions)} - ${new Date(t[e].endPeriod).toLocaleString("en-gb",dateOptions)}

\n
\n \n \n
\n\t\t\t\t\t
\n\t\t\t\t\t \n\t\t\t\t\t
\n\t\t\t\t\t\n \n\t\t\t\t\t\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"})); \ No newline at end of file +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;eupdateEduItem(n,e),o.innerHTML=`\n
\n \n \n
\n
\n \n -\n \n
\n\t\t\t\t\t

${new Date(t[e].startPeriod).toLocaleString("en-gb",dateOptions)} - ${new Date(t[e].endPeriod).toLocaleString("en-gb",dateOptions)}

\n
\n \n \n
\n\t\t\t\t\t
\n\t\t\t\t\t \n\t\t\t\t\t
\n\t\t\t\t\t\n \n\t\t\t\t\t\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"})); \ No newline at end of file diff --git a/dist/editor/js/index.js b/dist/editor/js/index.js index 6a51c04..342abca 100644 --- a/dist/editor/js/index.js +++ b/dist/editor/js/index.js @@ -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")})); \ No newline at end of file +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")})); \ No newline at end of file diff --git a/src/api/index.php b/src/api/index.php index 2c657ca..fcd86b4 100644 --- a/src/api/index.php +++ b/src/api/index.php @@ -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(); diff --git a/src/api/middleware.php b/src/api/middleware.php index b194905..ece8897 100644 --- a/src/api/middleware.php +++ b/src/api/middleware.php @@ -33,6 +33,7 @@ class middleware */ function baseMiddleware(App $app): void { + $app->addBodyParsingMiddleware(); $app->addRoutingMiddleware(); } diff --git a/src/api/timelineData.php b/src/api/timelineData.php index 71e5c45..29f5cd5 100644 --- a/src/api/timelineData.php +++ b/src/api/timelineData.php @@ -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(); + } + } diff --git a/src/editor/js/editor.js b/src/editor/js/editor.js index 0f57117..d95dd0d 100644 --- a/src/editor/js/editor.js +++ b/src/editor/js/editor.js @@ -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 = `
- - + +
- + - - +
-

${new Date(json[i]["startPeriod"]).toLocaleString('en-gb', dateOptions)} - ${new Date(json[i]["endPeriod"]).toLocaleString('en-gb', dateOptions)}

+

${new Date(json[i]["startPeriod"]).toLocaleString('en-gb', dateOptions)} - ${new Date(json[i]["endPeriod"]).toLocaleString('en-gb', dateOptions)}

- - + +
- +
-