diff --git a/dist/api/index.php b/dist/api/index.php
index 8219ffa..c686cfa 100644
--- a/dist/api/index.php
+++ b/dist/api/index.php
@@ -218,17 +218,17 @@ $app->patch("/projectData/{id}", function (Request $request, Response $response,
$data = $request->getParsedBody();
if ($args["id"] != "undefined")
{
- if (empty($data["title"]) || empty($data["isMainProject"]) || empty($data["information"]) || empty($data["projectLink"]) || empty($data["gitLink"]))
+ if (empty($data["title"]) || empty($data["isMainProject"]) || empty($data["information"]) || empty($data["gitLink"]))
{
// 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 (!$projectData->updateProjectData($args["id"], $data["title"], $data["isMainProject"], $data["information"], "", $data["projectLink"], $data["gitLink"]))
+ if (!$projectData->updateProjectData($args["id"], $data["title"], $data["isMainProject"], $data["information"], $data["projectLink"], $data["gitLink"]))
{
// uh oh something went wrong
- $response->getBody()->write(json_encode(array("error" => "Something went wrong")));
+ $response->getBody()->write(json_encode(array("error" => "Something went wrong", "data" => $projectData->updateProjectData($args["id"], $data["title"], $data["isMainProject"], $data["information"], $data["projectLink"], $data["gitLink"]))));
return $response->withStatus(500);
}
return $response;
@@ -243,13 +243,21 @@ $app->delete("/projectData/{id}", function (Request $request, Response $response
global $projectData;
if ($args["id"] != null)
{
- if (!$projectData->deleteProjectData($args["id"]))
+ $message = $projectData->deleteProjectData($args["id"]);
+ if ($message === "error")
{
// uh oh something went wrong
- $response->getBody()->write(json_encode(array("error" => "Something went wrong")));
+ $response->getBody()->write(json_encode(array("error" => "Something went wrong or the project with ID ".$args["id"]."does not exist")));
return $response->withStatus(500);
}
+ if ($message === "cannot delete")
+ {
+ //uh oh cannot delete the main project
+ $response->getBody()->write(json_encode(array("error" => "Cannot delete the main project")));
+ return $response->withStatus(409);
+ }
+
return $response;
}
@@ -261,7 +269,7 @@ $app->post("/projectData", function (Request $request, Response $response)
{
global $projectData;
$data = $request->getParsedBody();
- if (empty($data["title"]) || empty($data["isMainProject"]) || empty($data["information"]) || empty($data["projectLink"]) || empty($data["gitLink"]))
+ if (empty($data["title"]) || empty($data["isMainProject"]) || empty($data["information"]) || empty($data["gitLink"]))
{
// uh oh sent some empty data
$response->getBody()->write(json_encode(array("error" => "Only some of the data was sent")));
@@ -272,7 +280,7 @@ $app->post("/projectData", function (Request $request, Response $response)
if (!is_int($insertedID))
{
// uh oh something went wrong
- $response->getBody()->write(json_encode(array("error" => "Something went wrong")));
+ $response->getBody()->write(json_encode(array("error" => "Something went wrong", "message" => $insertedID)));
return $response->withStatus(500);
}
diff --git a/dist/api/projectData.php b/dist/api/projectData.php
index d72e614..9b25570 100644
--- a/dist/api/projectData.php
+++ b/dist/api/projectData.php
@@ -18,7 +18,7 @@ class projectData
function getProjectData(): array
{
$conn = dbConn();
- $stmt = $conn->prepare("SELECT ID, title, isMainProject, information, imgLocation, projectLink, gitLink FROM projects;");
+ $stmt = $conn->prepare("SELECT ID, title, isMainProject, information, imgLocation, projectLink, gitLink FROM projects ORDER BY isMainProject DESC;");
$stmt->execute();
// set the resulting array to associative
@@ -37,52 +37,66 @@ class projectData
* Update project data in the database with the given ID
* @param string $ID - ID of the project in the database to update
* @param string $title - Title of the project
- * @param bool $isMainProject - Is the project a main project or not
+ * @param string $isMainProject - Is the project a main project or not
* @param string $information - Information about the project
- * @param string $imgLocation - Location of the image
* @param string $projectLink - Link to the project
- * @param string $gitLink - Link to the github repository
+ * @param string $gitLink - Link to the git repository
* @return bool - True if project was updated, false if not and there was an error
*/
- function updateProjectData(string $ID, string $title, bool $isMainProject, string $information, string $imgLocation, string $projectLink, string $gitLink): bool
+ function updateProjectData(string $ID, string $title, string $isMainProject, string $information, string $projectLink, string $gitLink): bool
{
$conn = dbConn();
- $stmt = $conn->prepare("UPDATE projects SET title = :title, isMainProject = :isMainProject, information = :information, imgLocation = :imgLocation, projectLink = :projectLink, gitLink = :gitLink WHERE ID = :ID");
+
+ if ($isMainProject === "true")
+ {
+ $stmtMainProject = $conn->prepare("UPDATE projects SET isMainProject = 0;");
+ $stmtMainProject->execute();
+ }
+
+ $stmt = $conn->prepare("UPDATE projects SET title = :title, isMainProject = :isMainProject, information = :information, projectLink = :projectLink, gitLink = :gitLink WHERE ID = :ID");
$stmt->bindParam(":title", $title);
- $stmt->bindParam(":isMainProject", $isMainProject);
+ $isMainProj = ($isMainProject) ? 1 : 0;
+ $stmt->bindParam(":isMainProject", $isMainProj);
$stmt->bindParam(":information", $information);
- $stmt->bindParam(":imgLocation", $imgLocation);
$stmt->bindParam(":projectLink", $projectLink);
$stmt->bindParam(":gitLink", $gitLink);
$stmt->bindParam(":ID", $ID);
- $stmt->execute();
-
- if ($stmt->rowCount() > 0)
- {
- return true;
- }
-
- return false;
+ return $stmt->execute();
}
/**
* Delete project data from the database
* @param int $ID - ID of the project in the database to delete
- * @return bool - True if project was deleted, false if not and there was an error
+ * @return string - True if project was deleted, false if not and there was an error
*/
- function deleteProjectData(int $ID): bool
+ function deleteProjectData(int $ID): string
{
$conn = dbConn();
+
+ // check if the project is a main project if it is return false
+
+ $stmtMainProject = $conn->prepare("SELECT isMainProject FROM projects WHERE ID = :ID");
+ $stmtMainProject->bindParam(":ID", $ID);
+ $stmtMainProject->execute();
+ $result = $stmtMainProject->fetch(PDO::FETCH_ASSOC);
+
+ if ($result["isMainProject"] === "1")
+ {
+ return "cannot delete";
+ }
+
+ $this->deleteImage($ID);
+
$stmt = $conn->prepare("DELETE FROM projects WHERE ID = :ID");
$stmt->bindParam(":ID", $ID);
$stmt->execute();
if ($stmt->rowCount() > 0)
{
- return true;
+ return "ok";
}
- return false;
+ return "error";
}
/**
@@ -96,10 +110,18 @@ class projectData
*/
function addProjectData(string $title, string $isMainProject, string $information, string $projectLink, string $gitLink): int|bool
{
+
$conn = dbConn();
+ if ($isMainProject === "true")
+ {
+ $stmtMainProject = $conn->prepare("UPDATE projects SET isMainProject = 0;");
+ $stmtMainProject->execute();
+ }
+
$stmt = $conn->prepare("INSERT INTO projects (title, isMainProject, information, projectLink, gitLink) VALUES (:title, :isMainProject, :information, :projectLink, :gitLink)");
$stmt->bindParam(":title", $title);
- $stmt->bindParam(":isMainProject", $isMainProject);
+ $isMainProj = ($isMainProject) ? 1 : 0;
+ $stmt->bindParam(":isMainProject", $isMainProj);
$stmt->bindParam(":information", $information);
$stmt->bindParam(":projectLink", $projectLink);
$stmt->bindParam(":gitLink", $gitLink);
@@ -148,6 +170,7 @@ class projectData
if (file_exists($targetFile))
{
+ $this->deleteImage($ID);
// update the database with the new image location
$conn = dbConn();
$stmt = $conn->prepare("UPDATE projects SET imgLocation = :imgLocation WHERE ID = :ID");
@@ -165,4 +188,22 @@ class projectData
return "Couldn't upload the image";
}
+
+ /**
+ * Delete the image from the server
+ * @param int $ID - ID of the project in the database
+ */
+ private function deleteImage(int $ID): void
+ {
+ $conn = dbConn();
+ $imgStmt = $conn->prepare("SELECT imgLocation FROM projects WHERE ID = :ID");
+ $imgStmt->bindParam(":ID", $ID);
+ $imgStmt->execute();
+ $imgLocation = $imgStmt->fetch(PDO::FETCH_ASSOC)["imgLocation"];
+
+ if ($imgLocation != null)
+ {
+ unlink($imgLocation);
+ }
+ }
}
diff --git a/dist/editor/editor.html b/dist/editor/editor.html
index 5b468f7..eb9131f 100644
--- a/dist/editor/editor.html
+++ b/dist/editor/editor.html
@@ -1 +1 @@
-
Editor × ☰
Editor
\ No newline at end of file
+Editor × ☰
Editor
\ No newline at end of file
diff --git a/dist/editor/js/editor.js b/dist/editor/js/editor.js
index 2526df3..9c14cbe 100644
--- a/dist/editor/js/editor.js
+++ b/dist/editor/js/editor.js
@@ -1 +1 @@
-let dateOptions={month:"short",year:"numeric"},textareaLoaded=!1;function showErrorMessage(e,t){document.querySelector(`#${t}Error`).classList.remove("hidden"),document.querySelector(`#${t}Error div`).innerText=e}function editCVItem(e){if(textareaLoaded=!1,document.querySelector(`#timelineItem${e}`).classList.toggle("editing"),e.includes("e"))return document.querySelector(`#grade${e}`).toggleAttribute("disabled"),void document.querySelector(`#course${e}`).toggleAttribute("disabled");document.querySelector(`#companyName${e}`).toggleAttribute("disabled"),document.querySelector(`#area${e}`).toggleAttribute("disabled"),document.querySelector(`#jobTitle${e}`).toggleAttribute("disabled")}function addEduData(e,t,o,r,n,a=!1){let i=e+"e",d=document.createElement("form");d.id="timelineItem"+i,d.classList.add("timelineItem"),d.onsubmit=t=>updateEduItem(e,t),d.innerHTML=`\n \n \n \n
\n \n \n -\n \n
\n \n \n Grade: \n \n
\n \n ${n} \n
\n \n \n \n `,a?document.querySelector("#edu").prepend(d):document.getElementById("edu").appendChild(d)}function addWorkData(e,t,o,r,n,a,i=!1){let d=e+"w",l=document.createElement("form");l.id="timelineItem"+d,l.classList.add("timelineItem"),l.onsubmit=t=>updateWorkItem(e,t),l.innerHTML=`\n \n \n \n
\n \n \n -\n \n
\n \n \n \n -\n \n
\n \n ${a} \n
\n \n \n \n\t`,i?document.querySelector("#work").prepend(l):document.getElementById("work").appendChild(l)}function updateEduItem(e,t){t.preventDefault();let o={};o.dateFrom=document.querySelector(`#dateFrom${e}e`).value,o.dateTo=document.querySelector(`#dateTo${e}e`).value,o.grade=document.querySelector(`#grade${e}e`).value,o.course=document.querySelector(`#course${e}e`).value,fetch("/api/timelineData/edu/"+e,{method:"PATCH",body:JSON.stringify(o),headers:{"Content-Type":"application/json",Authorization:"Bearer "+localStorage.getItem("token")}}).then((t=>{if(t.ok)return document.querySelector(`#timelineHeader${e}e`).innerHTML=new Date(document.querySelector(`#dateFrom${e}e`).value).toLocaleString("en-gb",dateOptions)+" - "+new Date(document.querySelector(`#dateTo${e}e`).value).toLocaleString("en-gb",dateOptions),document.querySelector(`#timelineItem${e}e`).classList.toggle("editing"),document.querySelector(`#grade${e}e`).setAttribute("disabled",""),void document.querySelector(`#course${e}e`).setAttribute("disabled","");401!==t.status?t.json().then((t=>{document.querySelector(`#eduError${e}e`).classList.remove("hidden"),document.querySelector(`#eduError${e}e div`).innerHTML=t.error})):window.location.href="./"}))}function updateWorkItem(e,t){t.preventDefault();let o={};o.dateFrom=document.querySelector(`#dateFrom${e}w`).value,o.dateTo=document.querySelector(`#dateTo${e}w`).value,o.companyName=document.querySelector(`#companyName${e}w`).value,o.area=document.querySelector(`#area${e}w`).value,o.title=document.querySelector(`#jobTitle${e}w`).value,fetch("/api/timelineData/work/"+e,{method:"PATCH",body:JSON.stringify(o),headers:{"Content-Type":"application/json",Authorization:"Bearer "+localStorage.getItem("token")}}).then((t=>{if(t.ok)return document.querySelector(`#timelineHeader${e}w`).innerHTML=new Date(document.querySelector(`#dateFrom${e}w`).value).toLocaleString("en-gb",dateOptions)+" - "+new Date(document.querySelector(`#dateTo${e}w`).value).toLocaleString("en-gb",dateOptions),document.querySelector(`#timelineItem${e}w`).classList.toggle("editing"),document.querySelector(`#companyName${e}w`).setAttribute("disabled",""),document.querySelector(`#area${e}w`).setAttribute("disabled",""),void document.querySelector(`#jobTitle${e}w`).setAttribute("disabled","");401!==t.status?t.json().then((t=>{document.querySelector(`#workError${e}w`).classList.remove("hidden"),document.querySelector(`#workError${e}w div`).innerHTML=t.error})):window.location.href="./"}))}function deleteEduItem(e){fetch("/api/timelineData/edu/"+e,{method:"DELETE",headers:{Authorization:"Bearer "+localStorage.getItem("token")}}).then((t=>{t.ok?document.querySelector(`#timelineItem${e}e`).remove():401!==t.status?t.json().then((e=>alert(e.error))):window.location.href="./"}))}function deleteWorkItem(e){fetch("/api/timelineData/work/"+e,{method:"DELETE",headers:{Authorization:"Bearer "+localStorage.getItem("token")}}).then((t=>{t.ok?document.querySelector(`#timelineItem${e}w`).remove():401!==t.status?t.json().then((e=>alert(e.error))):window.location.href="./"}))}function updateProjectItem(e,t){t.preventDefault();let o={};o.title=document.querySelector(`#title${e}`).value,o.isMainProject=document.querySelector(`#isMainProject${e}`).checked,o.img=document.querySelector(`#img${e}`).files[0],o.information=document.querySelector(`#info${e}`).value,o.projectLink=document.querySelector(`#viewProj${e}`).value,o.gitLink=document.querySelector(`#git${e}`).value,fetch("/api/projectData/"+e,{method:"PATCH",body:JSON.stringify(o),headers:{"Content-Type":"application/json",Authorization:"Bearer "+localStorage.getItem("token")}}).then((t=>{if(t.ok)return document.querySelector(`#projectItem${e}`).classList.toggle("editing"),document.querySelector(`#title${e}`).setAttribute("disabled",""),void document.querySelector(`#info${e}`).setAttribute("disabled","");401!==t.status?t.json().then((t=>{document.querySelector(`#projError${e}`).classList.remove("hidden"),document.querySelector(`#projError${e} div`).innerHTML=t.error})):window.location.href="./"}))}function editProjectItem(e){document.querySelector(`#projectItem${e}`).classList.toggle("editing"),document.querySelector(`#title${e}`).removeAttribute("disabled"),document.querySelector(`#info${e}`).removeAttribute("disabled")}function deleteProjectItem(e){fetch("/api/projectData/"+e,{method:"DELETE",headers:{Authorization:"Bearer "+localStorage.getItem("token")}}).then((t=>{t.ok?document.querySelector(`#projectItem${e}`).remove():401!==t.status?t.json().then((e=>alert(e.error))):window.location.href="./"}))}function addProject(e,t,o,r,n,a){let i=document.createElement("form");i.id="projectItem"+e,i.classList.add("projItem"),i.onsubmit=t=>updateProjectItem(e,t),i.innerHTML=`\n \n \n \n
\n \n \n \n
\n \n \n
\n \n Is It The Main Project\n \n \n \n
\n \n ${r} \n
\n \n \n
\n \n \n
\n \n \n \n `,document.querySelector("#projList").appendChild(i)}document.addEventListener("DOMContentLoaded",(()=>{fetch("/api/user/isLoggedIn").then((e=>{e.ok||(window.location.href="./")})),document.querySelector("#dateFromE").max=(new Date).toISOString().split("T")[0],document.querySelector("#dateFromW").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{e.json().then((t=>{if(e.ok)for(let e=0;e{e.json().then((t=>{e.ok?t.forEach((e=>{addProject(e.ID,""===e.imgLocation?"../imgs/placeholder.png":e.imgLocation,e.title,e.information,e.projectLink,e.gitLink)})):document.querySelector("#projects").innerHTML="No project data found"}))}))})),document.querySelector("body").addEventListener("click",(()=>{if(textareaLoaded)return;const e=document.querySelectorAll("main.editor textarea");console.log(e);for(let t=0;t{e.target.style.height="0",e.target.style.height=e.target.scrollHeight+"px"};textareaLoaded=!0})),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"})),document.querySelector("#addEdu").addEventListener("submit",(e=>{e.preventDefault();let t=new FormData;t.append("dateFrom",document.querySelector("#dateFromE").value),t.append("dateTo",document.querySelector("#dateToE").value),t.append("grade",document.querySelector("#grade").value),t.append("course",document.querySelector("#courseTitle").value),fetch("/api/timelineData/edu",{method:"POST",body:t,headers:{Authorization:"Bearer "+localStorage.getItem("token")}}).then((e=>e.json().then((o=>{if(e.ok)return addEduData(o.ID,t.get("dateFrom"),t.get("dateTo"),t.get("grade"),t.get("course"),!0),void document.querySelector("#addEdu").reset();401!==e.status?showErrorMessage(o.error,"edu"):window.location.href="./"}))))})),document.querySelector("#addWork").addEventListener("submit",(e=>{e.preventDefault();let t=new FormData;t.append("dateFrom",document.querySelector("#dateFromW").value),t.append("dateTo",document.querySelector("#dateToW").value),t.append("companyName",document.querySelector("#company").value),t.append("area",document.querySelector("#area").value),t.append("title",document.querySelector("#jobTitle").value),fetch("/api/timelineData/work",{method:"POST",body:t,headers:{Authorization:"Bearer "+localStorage.getItem("token")}}).then((e=>e.json().then((o=>{if(e.ok){let e=null===t.get("dateTo")?"Present":t.get("dateTo ");return addWorkData(o.ID,t.get("dateFrom"),e,t.get("companyName"),t.get("area"),t.get("title"),!0),void document.querySelector("#addWork").reset()}401!==e.status?showErrorMessage(o.error,"work"):window.location.href="./"}))))})),document.querySelector("#addProj").addEventListener("submit",(e=>{e.preventDefault();let t=new FormData;t.append("title",document.querySelector("#projTitle").value),t.append("isMainProject",document.querySelector("#isMainProject").checked?"true":"false"),t.append("information",document.querySelector("#projInfo").value),t.append("projectLink",document.querySelector("#projLink").value),t.append("gitLink",document.querySelector("#gitLink").value);let o=new FormData;o.append("img",document.querySelector("#projImg").files[0]);let r=0;fetch("/api/projectData",{method:"POST",body:t,headers:{Authorization:"Bearer "+localStorage.getItem("token")}}).then((e=>e.json().then((n=>{if(e.ok)return"undefined"===o.get("img")?(addProject(n.ID,"../imgs/placeholder.png",t.get("title"),t.get("information"),t.get("projectLink"),t.get("gitLink")),void document.querySelector("#addProj").reset()):(r=n.ID,fetch("/api/projectImage/"+n.ID,{method:"POST",body:o,headers:{Authorization:"Bearer "+localStorage.getItem("token")}}));401!==e.status?showErrorMessage(n.error,"proj"):window.location.href="./"})).then((e=>e.json().then((o=>{if(e.ok)return addProject(r,o.imgLocation,t.get("title"),t.get("information"),t.get("projectLink"),t.get("gitLink")),void document.querySelector("#addProj").reset();401!==e.status?showErrorMessage(o.error,"proj"):window.location.href="./"}))))))})),document.querySelector("#goToCV").addEventListener("click",(()=>{textareaLoaded=!1,document.querySelector("#curriculumVitae").style.display="block",document.querySelector("#goToCV").classList.add("active"),document.querySelector("#projects").style.display="none",document.querySelector("#goToProjects").classList.remove("active")})),document.querySelector("#goToProjects").addEventListener("click",(()=>{textareaLoaded=!1,document.querySelector("#curriculumVitae").style.display="none",document.querySelector("#goToCV").classList.remove("active"),document.querySelector("#projects").style.display="block",document.querySelector("#goToProjects").classList.add("active")})),document.querySelector("#logout").addEventListener("click",(()=>{fetch("/api/user/logout").then((e=>{e.ok&&window.location.reload()}))})),document.querySelector("#eduError .close").addEventListener("click",(()=>document.querySelector("#eduError").classList.toggle("hidden"))),document.querySelector("#workError .close").addEventListener("click",(()=>document.querySelector("#workError").classList.toggle("hidden"))),document.querySelector("#projError .close").addEventListener("click",(()=>document.querySelector("#projError").classList.toggle("hidden")));
\ No newline at end of file
+let dateOptions={month:"short",year:"numeric"},textareaLoaded=!1;function showErrorMessage(e,t){document.querySelector(`#${t}Error`).classList.remove("hidden"),document.querySelector(`#${t}Error div`).innerText=e}function editCVItem(e){if(textareaLoaded=!1,document.querySelector(`#timelineItem${e}`).classList.toggle("editing"),e.includes("e"))return document.querySelector(`#grade${e}`).toggleAttribute("disabled"),void document.querySelector(`#course${e}`).toggleAttribute("disabled");document.querySelector(`#companyName${e}`).toggleAttribute("disabled"),document.querySelector(`#area${e}`).toggleAttribute("disabled"),document.querySelector(`#jobTitle${e}`).toggleAttribute("disabled")}function addEduData(e,t,o,r,n,a=!1){let i=e+"e",d=document.createElement("form");d.id="timelineItem"+i,d.classList.add("timelineItem"),d.onsubmit=t=>updateEduItem(e,t),d.innerHTML=`\n \n \n \n
\n \n \n -\n \n
\n \n \n Grade: \n \n
\n \n ${n} \n
\n \n \n \n `,a?document.querySelector("#edu").prepend(d):document.getElementById("edu").appendChild(d)}function addWorkData(e,t,o,r,n,a,i=!1){let d=e+"w",c=document.createElement("form");c.id="timelineItem"+d,c.classList.add("timelineItem"),c.onsubmit=t=>updateWorkItem(e,t),c.innerHTML=`\n \n \n \n
\n \n \n -\n \n
\n \n \n \n -\n \n
\n \n ${a} \n
\n \n \n \n\t`,i?document.querySelector("#work").prepend(c):document.getElementById("work").appendChild(c)}function updateEduItem(e,t){t.preventDefault();let o={};o.dateFrom=document.querySelector(`#dateFrom${e}e`).value,o.dateTo=document.querySelector(`#dateTo${e}e`).value,o.grade=document.querySelector(`#grade${e}e`).value,o.course=document.querySelector(`#course${e}e`).value,fetch("/api/timelineData/edu/"+e,{method:"PATCH",body:JSON.stringify(o),headers:{"Content-Type":"application/json",Authorization:"Bearer "+localStorage.getItem("token")}}).then((t=>{if(t.ok)return document.querySelector(`#timelineHeader${e}e`).innerHTML=new Date(document.querySelector(`#dateFrom${e}e`).value).toLocaleString("en-gb",dateOptions)+" - "+new Date(document.querySelector(`#dateTo${e}e`).value).toLocaleString("en-gb",dateOptions),document.querySelector(`#timelineItem${e}e`).classList.toggle("editing"),document.querySelector(`#grade${e}e`).setAttribute("disabled",""),void document.querySelector(`#course${e}e`).setAttribute("disabled","");401!==t.status?t.json().then((t=>{document.querySelector(`#eduError${e}e`).classList.remove("hidden"),document.querySelector(`#eduError${e}e div`).innerHTML=t.error})):window.location.href="./"}))}function updateWorkItem(e,t){t.preventDefault();let o={};o.dateFrom=document.querySelector(`#dateFrom${e}w`).value,o.dateTo=document.querySelector(`#dateTo${e}w`).value,o.companyName=document.querySelector(`#companyName${e}w`).value,o.area=document.querySelector(`#area${e}w`).value,o.title=document.querySelector(`#jobTitle${e}w`).value,fetch("/api/timelineData/work/"+e,{method:"PATCH",body:JSON.stringify(o),headers:{"Content-Type":"application/json",Authorization:"Bearer "+localStorage.getItem("token")}}).then((t=>{if(t.ok)return document.querySelector(`#timelineHeader${e}w`).innerHTML=new Date(document.querySelector(`#dateFrom${e}w`).value).toLocaleString("en-gb",dateOptions)+" - "+new Date(document.querySelector(`#dateTo${e}w`).value).toLocaleString("en-gb",dateOptions),document.querySelector(`#timelineItem${e}w`).classList.toggle("editing"),document.querySelector(`#companyName${e}w`).setAttribute("disabled",""),document.querySelector(`#area${e}w`).setAttribute("disabled",""),void document.querySelector(`#jobTitle${e}w`).setAttribute("disabled","");401!==t.status?t.json().then((t=>{document.querySelector(`#workError${e}w`).classList.remove("hidden"),document.querySelector(`#workError${e}w div`).innerHTML=t.error})):window.location.href="./"}))}function deleteEduItem(e){fetch("/api/timelineData/edu/"+e,{method:"DELETE",headers:{Authorization:"Bearer "+localStorage.getItem("token")}}).then((t=>{t.ok?document.querySelector(`#timelineItem${e}e`).remove():401!==t.status?t.json().then((e=>alert(e.error))):window.location.href="./"}))}function deleteWorkItem(e){fetch("/api/timelineData/work/"+e,{method:"DELETE",headers:{Authorization:"Bearer "+localStorage.getItem("token")}}).then((t=>{t.ok?document.querySelector(`#timelineItem${e}w`).remove():401!==t.status?t.json().then((e=>alert(e.error))):window.location.href="./"}))}function updateProjectItem(e,t){t.preventDefault();let o={};o.title=document.querySelector(`#title${e}`).value,o.isMainProject=document.querySelector(`#isMainProject${e}`).checked?"true":"false",o.information=document.querySelector(`#info${e}`).value,o.projectLink=document.querySelector(`#viewProj${e}`).value,o.gitLink=document.querySelector(`#git${e}`).value;let r=new FormData;r.append("img",document.querySelector(`#img${e}`).files[0]),fetch("/api/projectData/"+e,{method:"PATCH",body:JSON.stringify(o),headers:{"Content-Type":"application/json",Authorization:"Bearer "+localStorage.getItem("token")}}).then((t=>{if(t.ok)return"undefined"===r.get("img")?("true"===o.isMainProject&&(document.querySelectorAll(".isMainProject input").forEach((e=>e.checked=!1)),document.querySelector(`#isMainProject${e}`).checked=!0,document.querySelector("#projList").prepend(document.querySelector(`#projectItem${e}`))),document.querySelector(`#projectItem${e}`).classList.toggle("editing"),document.querySelector(`#title${e}`).setAttribute("disabled",""),void document.querySelector(`#info${e}`).setAttribute("disabled","")):(console.log("updating image"),fetch("/api/projectImage/"+e,{method:"POST",body:r,headers:{Authorization:"Bearer "+localStorage.getItem("token")}}));401!==t.status?t.json().then((t=>{document.querySelector(`#projError${e}`).classList.remove("hidden"),document.querySelector(`#projError${e} div`).innerHTML=t.error})):window.location.href="./"})).then((t=>t.json().then((r=>{if(t.ok)return"true"===o.isMainProject&&(document.querySelectorAll(".isMainProject input").forEach((e=>e.checked=!1)),document.querySelector(`#isMainProject${e}`).checked=!0,document.querySelector("#projList").prepend(document.querySelector(`#projectItem${e}`))),document.querySelector(`#projectItem${e}`).classList.toggle("editing"),document.querySelector(`#title${e}`).setAttribute("disabled",""),document.querySelector(`#info${e}`).setAttribute("disabled",""),void(document.querySelector(`#projectImage${e}`).src=r.imgLocation);401!==t.status?(document.querySelector(`#projError${e}`).classList.remove("hidden"),document.querySelector(`#projError${e} div`).innerHTML=projectDataError.error):window.location.href="./"}))))}function editProjectItem(e){document.querySelector(`#projectItem${e}`).classList.toggle("editing"),document.querySelector(`#title${e}`).removeAttribute("disabled"),document.querySelector(`#info${e}`).removeAttribute("disabled")}function deleteProjectItem(e){fetch("/api/projectData/"+e,{method:"DELETE",headers:{Authorization:"Bearer "+localStorage.getItem("token")}}).then((t=>{t.ok?document.querySelector(`#projectItem${e}`).remove():401!==t.status?t.json().then((e=>alert(e.error))):window.location.href="./"}))}function addProject(e,t,o,r,n,a,i){let d=document.createElement("form");if(d.id="projectItem"+e,d.classList.add("projItem"),d.onsubmit=t=>updateProjectItem(e,t),d.innerHTML=`\n \n \n \n
\n \n \n \n
\n \n \n
\n \n Is It The Main Project\n \n \n \n
\n \n ${n} \n
\n \n \n
\n \n \n
\n \n \n \n `,"true"===t)return document.querySelectorAll(".isMainProject input").forEach((e=>e.checked=!1)),void document.querySelector("#projList").prepend(d);document.querySelector("#projList").appendChild(d)}document.addEventListener("DOMContentLoaded",(()=>{fetch("/api/user/isLoggedIn").then((e=>{e.ok||(window.location.href="./")})),document.querySelector("#dateFromE").max=(new Date).toISOString().split("T")[0],document.querySelector("#dateFromW").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{e.json().then((t=>{if(e.ok)for(let e=0;e{e.json().then((t=>{e.ok?t.forEach((e=>{addProject(e.ID,"1"===e.isMainProject?"true":"false",""===e.imgLocation?"../imgs/placeholder.png":e.imgLocation,e.title,e.information,e.projectLink,e.gitLink)})):document.querySelector("#projList").innerHTML="No project data found"}))}))})),document.querySelector("body").addEventListener("click",(()=>{if(textareaLoaded)return;const e=document.querySelectorAll("main.editor textarea");console.log(e);for(let t=0;t{e.target.style.height="0",e.target.style.height=e.target.scrollHeight+"px"};textareaLoaded=!0})),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"})),document.querySelector("#addEdu").addEventListener("submit",(e=>{e.preventDefault();let t=new FormData;t.append("dateFrom",document.querySelector("#dateFromE").value),t.append("dateTo",document.querySelector("#dateToE").value),t.append("grade",document.querySelector("#grade").value),t.append("course",document.querySelector("#courseTitle").value),fetch("/api/timelineData/edu",{method:"POST",body:t,headers:{Authorization:"Bearer "+localStorage.getItem("token")}}).then((e=>e.json().then((o=>{if(e.ok)return addEduData(o.ID,t.get("dateFrom"),t.get("dateTo"),t.get("grade"),t.get("course"),!0),void document.querySelector("#addEdu").reset();401!==e.status?showErrorMessage(o.error,"edu"):window.location.href="./"}))))})),document.querySelector("#addWork").addEventListener("submit",(e=>{e.preventDefault();let t=new FormData;t.append("dateFrom",document.querySelector("#dateFromW").value),t.append("dateTo",document.querySelector("#dateToW").value),t.append("companyName",document.querySelector("#company").value),t.append("area",document.querySelector("#area").value),t.append("title",document.querySelector("#jobTitle").value),fetch("/api/timelineData/work",{method:"POST",body:t,headers:{Authorization:"Bearer "+localStorage.getItem("token")}}).then((e=>e.json().then((o=>{if(e.ok){let e=null===t.get("dateTo")?"Present":t.get("dateTo ");return addWorkData(o.ID,t.get("dateFrom"),e,t.get("companyName"),t.get("area"),t.get("title"),!0),void document.querySelector("#addWork").reset()}401!==e.status?showErrorMessage(o.error,"work"):window.location.href="./"}))))})),document.querySelector("#addProj").addEventListener("submit",(e=>{e.preventDefault();let t=new FormData;t.append("title",document.querySelector("#projTitle").value),t.append("isMainProject",document.querySelector("#isMainProject").checked?"true":"false"),t.append("information",document.querySelector("#projInfo").value),t.append("projectLink",document.querySelector("#projLink").value?document.querySelector("#projLink").value:"N/A"),t.append("gitLink",document.querySelector("#gitLink").value);let o=new FormData;o.append("img",document.querySelector("#projImg").files[0]);let r=0;fetch("/api/projectData",{method:"POST",body:t,headers:{Authorization:"Bearer "+localStorage.getItem("token")}}).then((e=>e.json().then((n=>{if(e.ok)return"undefined"===o.get("img")?(addProject(n.ID,t.get("isMainProject"),"../imgs/placeholder.png",t.get("title"),t.get("information"),t.get("projectLink"),t.get("gitLink")),void document.querySelector("#addProj").reset()):(r=n.ID,fetch("/api/projectImage/"+n.ID,{method:"POST",body:o,headers:{Authorization:"Bearer "+localStorage.getItem("token")}}));401!==e.status?showErrorMessage(n.error,"proj"):window.location.href="./"})).then((e=>e.json().then((o=>{if(e.ok)return addProject(r,t.get("isMainProject"),o.imgLocation,t.get("title"),t.get("information"),t.get("projectLink"),t.get("gitLink")),void document.querySelector("#addProj").reset();401!==e.status?showErrorMessage(o.error,"proj"):window.location.href="./"}))))))})),document.querySelector("#goToCV").addEventListener("click",(()=>{textareaLoaded=!1,document.querySelector("#curriculumVitae").style.display="block",document.querySelector("#goToCV").classList.add("active"),document.querySelector("#projects").style.display="none",document.querySelector("#goToProjects").classList.remove("active")})),document.querySelector("#goToProjects").addEventListener("click",(()=>{textareaLoaded=!1,document.querySelector("#curriculumVitae").style.display="none",document.querySelector("#goToCV").classList.remove("active"),document.querySelector("#projects").style.display="block",document.querySelector("#goToProjects").classList.add("active")})),document.querySelector("#logout").addEventListener("click",(()=>{fetch("/api/user/logout").then((e=>{e.ok&&window.location.reload()}))})),document.querySelector("#eduError .close").addEventListener("click",(()=>document.querySelector("#eduError").classList.toggle("hidden"))),document.querySelector("#workError .close").addEventListener("click",(()=>document.querySelector("#workError").classList.toggle("hidden"))),document.querySelector("#projError .close").addEventListener("click",(()=>document.querySelector("#projError").classList.toggle("hidden")));
\ No newline at end of file
diff --git a/dist/js/main.js b/dist/js/main.js
index 7e2797d..2b0ed16 100644
--- a/dist/js/main.js
+++ b/dist/js/main.js
@@ -1 +1 @@
-const scrollLimit=150;var dataText=["full stack developer","web designer","student","gamer","drummer"];function typeWriter(t,e,n){e_',setTimeout((function(){typeWriter(t,e+1,n)}),100)):"function"==typeof n&&setTimeout(n,700)}function StartTextAnimation(t){void 0===dataText[t]?setTimeout((function(){StartTextAnimation(0)}),1500):t{e.json().then((n=>{e.ok&&n.forEach((e=>{let n=document.createElement("div");n.classList.add("timelineItem"),n.innerHTML=`\n\t\t\t\t\t\n\t\t\t\t\tGrade: ${e.grade} \n\t\t\t\t\t${e.course}
\n\t\t\t\t`,document.getElementById("edu").appendChild(n)}))}))})),fetch("/api/timelineData/work").then((e=>{e.json().then((n=>{e.ok&&n.forEach((e=>{let n=document.createElement("div");n.classList.add("timelineItem");let o=null===e.endPeriod?"Present":new Date(e.endPeriod).toLocaleString("en-gb",t);n.innerHTML=`\n\t\t\t\t\t\n\t\t\t\t\t${e.companyName} - ${e.area} \n\t\t\t\t\t${e.title}
\n\t\t\t\t`,document.getElementById("work").appendChild(n)}))}))}))}function getProjectData(){fetch("/api/projectData").then((t=>{t.json().then((e=>{t.ok&&e.forEach((t=>{if("1"===t.isMainProject)return document.getElementById("mainProj").innerHTML=`\n\t\t\t\t\t\t${t.title} \n\t\t\t\t\t\t\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t
${t.information}
\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t`,null;document.querySelector("#otherProj div").innerHTML+=`\n \n
\n
\n
\n \t
${t.title} \n
${t.information}
\n
\n
\n
\n
\n `}))}))}))}window.onscroll=()=>{document.body.scrollTop>=150||document.documentElement.scrollTop>=150?document.querySelector("nav").classList.add("scrolled"):document.querySelector("nav").classList.remove("scrolled");let t="";document.querySelectorAll("section").forEach((e=>{const n=e.offsetTop;window.pageYOffset>=n-60&&(t=e.getAttribute("id"))})),document.querySelectorAll("nav ul li a").forEach((e=>{e.classList.remove("active"),e.href.includes(t)&&""!==t?e.classList.add("active"):""===t&&document.querySelector("nav ul li a").classList.add("active")}))},document.addEventListener("DOMContentLoaded",(()=>{StartTextAnimation(0),getTimelineData(),getProjectData()})),document.querySelector("#contactError .close").addEventListener("click",(()=>document.querySelector("#contactError").classList.toggle("hidden"))),document.querySelector("#goBackToTop").addEventListener("click",(()=>{window.scrollTo(0,0)})),document.querySelector("#contactForm").addEventListener("submit",(t=>{t.preventDefault();let e=new FormData;e.append("fName",document.querySelector("#fName").value),e.append("lName",document.querySelector("#lName").value),e.append("email",document.querySelector("#email").value),e.append("subject",document.querySelector("#subject").value),e.append("message",document.querySelector("#message").value);let n=!1;if(["#fName","#lName","#email","#subject","#message"].forEach((t=>{const e=document.querySelector(t);0===e.value.length?(e.classList.add("invalid"),n=!0):(e.classList.remove("invalid"),document.querySelector("#contactError").classList.remove("error"))})),n)return document.querySelector("#contactError").classList.add("error"),document.querySelector("#contactError").classList.remove("hidden"),void(document.querySelector("#contactError div").innerText="Please fill out all fields.");fetch("/api/contact",{method:"POST",body:e}).then((t=>{t.ok&&(document.querySelector("#contactError").classList.remove("hidden"),document.querySelector("#contactError div").innerText="Thanks for contacting me, I will get back to you as soon as possible.")}))}));
\ No newline at end of file
+const scrollLimit=150;var dataText=["full stack developer","web designer","student","gamer","drummer"];function typeWriter(t,e,n){e_',setTimeout((function(){typeWriter(t,e+1,n)}),100)):"function"==typeof n&&setTimeout(n,700)}function StartTextAnimation(t){void 0===dataText[t]?setTimeout((function(){StartTextAnimation(0)}),1500):t{e.json().then((n=>{e.ok&&n.forEach((e=>{let n=document.createElement("div");n.classList.add("timelineItem"),n.innerHTML=`\n\t\t\t\t\t\n\t\t\t\t\tGrade: ${e.grade} \n\t\t\t\t\t${e.course}
\n\t\t\t\t`,document.getElementById("edu").appendChild(n)}))}))})),fetch("/api/timelineData/work").then((e=>{e.json().then((n=>{e.ok&&n.forEach((e=>{let n=document.createElement("div");n.classList.add("timelineItem");let o=null===e.endPeriod?"Present":new Date(e.endPeriod).toLocaleString("en-gb",t);n.innerHTML=`\n\t\t\t\t\t\n\t\t\t\t\t${e.companyName} - ${e.area} \n\t\t\t\t\t${e.title}
\n\t\t\t\t`,document.getElementById("work").appendChild(n)}))}))}))}function getProjectData(){fetch("/api/projectData").then((t=>{t.json().then((e=>{t.ok&&e.forEach((t=>{if("1"===t.isMainProject)return document.getElementById("mainProj").innerHTML=`\n\t\t\t\t\t\t${t.title} \n\t\t\t\t\t\t\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t
${t.information}
\n\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t
\n\t\t\t\t\t\t
\n\t\t\t\t\t\t`,null;document.querySelector("#otherProj div").innerHTML+=`\n \n
\n
\n
\n \t
${t.title} \n
${t.information}
\n
\n
\n
\n
\n `}))}))}))}window.onscroll=()=>{document.body.scrollTop>=150||document.documentElement.scrollTop>=150?document.querySelector("nav").classList.add("scrolled"):document.querySelector("nav").classList.remove("scrolled");let t="";document.querySelectorAll("section").forEach((e=>{const n=e.offsetTop;window.pageYOffset>=n-60&&(t=e.getAttribute("id"))})),document.querySelectorAll("nav ul li a").forEach((e=>{e.classList.remove("active"),e.href.includes(t)&&""!==t?e.classList.add("active"):""===t&&document.querySelector("nav ul li a").classList.add("active")}))},document.addEventListener("DOMContentLoaded",(()=>{StartTextAnimation(0),getTimelineData(),getProjectData()})),document.querySelector("#contactError .close").addEventListener("click",(()=>document.querySelector("#contactError").classList.toggle("hidden"))),document.querySelector("#goBackToTop").addEventListener("click",(()=>{window.scrollTo(0,0)})),document.querySelector("#contactForm").addEventListener("submit",(t=>{t.preventDefault();let e=new FormData;e.append("fName",document.querySelector("#fName").value),e.append("lName",document.querySelector("#lName").value),e.append("email",document.querySelector("#email").value),e.append("subject",document.querySelector("#subject").value),e.append("message",document.querySelector("#message").value);let n=!1;if(["#fName","#lName","#email","#subject","#message"].forEach((t=>{const e=document.querySelector(t);0===e.value.length?(e.classList.add("invalid"),n=!0):(e.classList.remove("invalid"),document.querySelector("#contactError").classList.remove("error"))})),n)return document.querySelector("#contactError").classList.add("error"),document.querySelector("#contactError").classList.remove("hidden"),void(document.querySelector("#contactError div").innerText="Please fill out all fields.");fetch("/api/contact",{method:"POST",body:e}).then((t=>{t.ok&&(document.querySelector("#contactError").classList.remove("hidden"),document.querySelector("#contactError div").innerText="Thanks for contacting me, I will get back to you as soon as possible.")}))}));
\ No newline at end of file
diff --git a/src/api/index.php b/src/api/index.php
index 8219ffa..c686cfa 100644
--- a/src/api/index.php
+++ b/src/api/index.php
@@ -218,17 +218,17 @@ $app->patch("/projectData/{id}", function (Request $request, Response $response,
$data = $request->getParsedBody();
if ($args["id"] != "undefined")
{
- if (empty($data["title"]) || empty($data["isMainProject"]) || empty($data["information"]) || empty($data["projectLink"]) || empty($data["gitLink"]))
+ if (empty($data["title"]) || empty($data["isMainProject"]) || empty($data["information"]) || empty($data["gitLink"]))
{
// 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 (!$projectData->updateProjectData($args["id"], $data["title"], $data["isMainProject"], $data["information"], "", $data["projectLink"], $data["gitLink"]))
+ if (!$projectData->updateProjectData($args["id"], $data["title"], $data["isMainProject"], $data["information"], $data["projectLink"], $data["gitLink"]))
{
// uh oh something went wrong
- $response->getBody()->write(json_encode(array("error" => "Something went wrong")));
+ $response->getBody()->write(json_encode(array("error" => "Something went wrong", "data" => $projectData->updateProjectData($args["id"], $data["title"], $data["isMainProject"], $data["information"], $data["projectLink"], $data["gitLink"]))));
return $response->withStatus(500);
}
return $response;
@@ -243,13 +243,21 @@ $app->delete("/projectData/{id}", function (Request $request, Response $response
global $projectData;
if ($args["id"] != null)
{
- if (!$projectData->deleteProjectData($args["id"]))
+ $message = $projectData->deleteProjectData($args["id"]);
+ if ($message === "error")
{
// uh oh something went wrong
- $response->getBody()->write(json_encode(array("error" => "Something went wrong")));
+ $response->getBody()->write(json_encode(array("error" => "Something went wrong or the project with ID ".$args["id"]."does not exist")));
return $response->withStatus(500);
}
+ if ($message === "cannot delete")
+ {
+ //uh oh cannot delete the main project
+ $response->getBody()->write(json_encode(array("error" => "Cannot delete the main project")));
+ return $response->withStatus(409);
+ }
+
return $response;
}
@@ -261,7 +269,7 @@ $app->post("/projectData", function (Request $request, Response $response)
{
global $projectData;
$data = $request->getParsedBody();
- if (empty($data["title"]) || empty($data["isMainProject"]) || empty($data["information"]) || empty($data["projectLink"]) || empty($data["gitLink"]))
+ if (empty($data["title"]) || empty($data["isMainProject"]) || empty($data["information"]) || empty($data["gitLink"]))
{
// uh oh sent some empty data
$response->getBody()->write(json_encode(array("error" => "Only some of the data was sent")));
@@ -272,7 +280,7 @@ $app->post("/projectData", function (Request $request, Response $response)
if (!is_int($insertedID))
{
// uh oh something went wrong
- $response->getBody()->write(json_encode(array("error" => "Something went wrong")));
+ $response->getBody()->write(json_encode(array("error" => "Something went wrong", "message" => $insertedID)));
return $response->withStatus(500);
}
diff --git a/src/api/projectData.php b/src/api/projectData.php
index d72e614..9b25570 100644
--- a/src/api/projectData.php
+++ b/src/api/projectData.php
@@ -18,7 +18,7 @@ class projectData
function getProjectData(): array
{
$conn = dbConn();
- $stmt = $conn->prepare("SELECT ID, title, isMainProject, information, imgLocation, projectLink, gitLink FROM projects;");
+ $stmt = $conn->prepare("SELECT ID, title, isMainProject, information, imgLocation, projectLink, gitLink FROM projects ORDER BY isMainProject DESC;");
$stmt->execute();
// set the resulting array to associative
@@ -37,52 +37,66 @@ class projectData
* Update project data in the database with the given ID
* @param string $ID - ID of the project in the database to update
* @param string $title - Title of the project
- * @param bool $isMainProject - Is the project a main project or not
+ * @param string $isMainProject - Is the project a main project or not
* @param string $information - Information about the project
- * @param string $imgLocation - Location of the image
* @param string $projectLink - Link to the project
- * @param string $gitLink - Link to the github repository
+ * @param string $gitLink - Link to the git repository
* @return bool - True if project was updated, false if not and there was an error
*/
- function updateProjectData(string $ID, string $title, bool $isMainProject, string $information, string $imgLocation, string $projectLink, string $gitLink): bool
+ function updateProjectData(string $ID, string $title, string $isMainProject, string $information, string $projectLink, string $gitLink): bool
{
$conn = dbConn();
- $stmt = $conn->prepare("UPDATE projects SET title = :title, isMainProject = :isMainProject, information = :information, imgLocation = :imgLocation, projectLink = :projectLink, gitLink = :gitLink WHERE ID = :ID");
+
+ if ($isMainProject === "true")
+ {
+ $stmtMainProject = $conn->prepare("UPDATE projects SET isMainProject = 0;");
+ $stmtMainProject->execute();
+ }
+
+ $stmt = $conn->prepare("UPDATE projects SET title = :title, isMainProject = :isMainProject, information = :information, projectLink = :projectLink, gitLink = :gitLink WHERE ID = :ID");
$stmt->bindParam(":title", $title);
- $stmt->bindParam(":isMainProject", $isMainProject);
+ $isMainProj = ($isMainProject) ? 1 : 0;
+ $stmt->bindParam(":isMainProject", $isMainProj);
$stmt->bindParam(":information", $information);
- $stmt->bindParam(":imgLocation", $imgLocation);
$stmt->bindParam(":projectLink", $projectLink);
$stmt->bindParam(":gitLink", $gitLink);
$stmt->bindParam(":ID", $ID);
- $stmt->execute();
-
- if ($stmt->rowCount() > 0)
- {
- return true;
- }
-
- return false;
+ return $stmt->execute();
}
/**
* Delete project data from the database
* @param int $ID - ID of the project in the database to delete
- * @return bool - True if project was deleted, false if not and there was an error
+ * @return string - True if project was deleted, false if not and there was an error
*/
- function deleteProjectData(int $ID): bool
+ function deleteProjectData(int $ID): string
{
$conn = dbConn();
+
+ // check if the project is a main project if it is return false
+
+ $stmtMainProject = $conn->prepare("SELECT isMainProject FROM projects WHERE ID = :ID");
+ $stmtMainProject->bindParam(":ID", $ID);
+ $stmtMainProject->execute();
+ $result = $stmtMainProject->fetch(PDO::FETCH_ASSOC);
+
+ if ($result["isMainProject"] === "1")
+ {
+ return "cannot delete";
+ }
+
+ $this->deleteImage($ID);
+
$stmt = $conn->prepare("DELETE FROM projects WHERE ID = :ID");
$stmt->bindParam(":ID", $ID);
$stmt->execute();
if ($stmt->rowCount() > 0)
{
- return true;
+ return "ok";
}
- return false;
+ return "error";
}
/**
@@ -96,10 +110,18 @@ class projectData
*/
function addProjectData(string $title, string $isMainProject, string $information, string $projectLink, string $gitLink): int|bool
{
+
$conn = dbConn();
+ if ($isMainProject === "true")
+ {
+ $stmtMainProject = $conn->prepare("UPDATE projects SET isMainProject = 0;");
+ $stmtMainProject->execute();
+ }
+
$stmt = $conn->prepare("INSERT INTO projects (title, isMainProject, information, projectLink, gitLink) VALUES (:title, :isMainProject, :information, :projectLink, :gitLink)");
$stmt->bindParam(":title", $title);
- $stmt->bindParam(":isMainProject", $isMainProject);
+ $isMainProj = ($isMainProject) ? 1 : 0;
+ $stmt->bindParam(":isMainProject", $isMainProj);
$stmt->bindParam(":information", $information);
$stmt->bindParam(":projectLink", $projectLink);
$stmt->bindParam(":gitLink", $gitLink);
@@ -148,6 +170,7 @@ class projectData
if (file_exists($targetFile))
{
+ $this->deleteImage($ID);
// update the database with the new image location
$conn = dbConn();
$stmt = $conn->prepare("UPDATE projects SET imgLocation = :imgLocation WHERE ID = :ID");
@@ -165,4 +188,22 @@ class projectData
return "Couldn't upload the image";
}
+
+ /**
+ * Delete the image from the server
+ * @param int $ID - ID of the project in the database
+ */
+ private function deleteImage(int $ID): void
+ {
+ $conn = dbConn();
+ $imgStmt = $conn->prepare("SELECT imgLocation FROM projects WHERE ID = :ID");
+ $imgStmt->bindParam(":ID", $ID);
+ $imgStmt->execute();
+ $imgLocation = $imgStmt->fetch(PDO::FETCH_ASSOC)["imgLocation"];
+
+ if ($imgLocation != null)
+ {
+ unlink($imgLocation);
+ }
+ }
}
diff --git a/src/editor/editor.html b/src/editor/editor.html
index 693901a..87bbf56 100644
--- a/src/editor/editor.html
+++ b/src/editor/editor.html
@@ -13,7 +13,6 @@
diff --git a/src/editor/js/editor.js b/src/editor/js/editor.js
index 5568841..cc1442a 100644
--- a/src/editor/js/editor.js
+++ b/src/editor/js/editor.js
@@ -14,7 +14,6 @@ document.addEventListener('DOMContentLoaded', () =>
document.querySelector("#dateFromE").max = new Date().toISOString().split("T")[0];
document.querySelector("#dateFromW").max = new Date().toISOString().split("T")[0];
-
fetch("/api/timelineData/edu").then(res =>
{
res.json().then(json =>
@@ -56,11 +55,11 @@ document.addEventListener('DOMContentLoaded', () =>
{
json.forEach(item =>
{
- addProject(item["ID"], (item["imgLocation"] === "") ? "../imgs/placeholder.png" : item["imgLocation"], item["title"], item["information"], item["projectLink"], item["gitLink"]);
+ addProject(item["ID"], (item["isMainProject"] === "1" ? "true" : "false"), (item["imgLocation"] === "") ? "../imgs/placeholder.png" : item["imgLocation"], item["title"], item["information"], item["projectLink"], item["gitLink"]);
})
return;
}
- document.querySelector("#projects").innerHTML = "No project data found";
+ document.querySelector("#projList").innerHTML = "No project data found";
})
})
})
@@ -177,7 +176,7 @@ document.querySelector("#addProj").addEventListener("submit", e =>
data.append("title", document.querySelector("#projTitle").value);
data.append("isMainProject", document.querySelector("#isMainProject").checked ? "true" : "false");
data.append("information", document.querySelector("#projInfo").value);
- data.append("projectLink", document.querySelector("#projLink").value);
+ data.append("projectLink", (document.querySelector("#projLink").value) ? document.querySelector("#projLink").value : "N/A");
data.append("gitLink", document.querySelector("#gitLink").value);
let imgData = new FormData();
@@ -197,7 +196,7 @@ document.querySelector("#addProj").addEventListener("submit", e =>
{
if (imgData.get("img") === "undefined")
{
- addProject(newProjectData.ID, "../imgs/placeholder.png", data.get("title"), data.get("information"), data.get("projectLink"), data.get("gitLink"));
+ addProject(newProjectData.ID, data.get("isMainProject"),"../imgs/placeholder.png", data.get("title"), data.get("information"), data.get("projectLink"), data.get("gitLink"));
document.querySelector("#addProj").reset();
return;
}
@@ -220,11 +219,12 @@ document.querySelector("#addProj").addEventListener("submit", e =>
}
showErrorMessage(newProjectData.error, "proj");
+
}).then(res => res.json().then(newProjectImage =>
{
if (res.ok)
{
- addProject(newProjectID, newProjectImage.imgLocation, data.get("title"), data.get("information"), data.get("projectLink"), data.get("gitLink"));
+ addProject(newProjectID, data.get("isMainProject"), newProjectImage.imgLocation, data.get("title"), data.get("information"), data.get("projectLink"), data.get("gitLink"));
document.querySelector("#addProj").reset();
return;
}
@@ -574,12 +574,14 @@ function updateProjectItem(id, e)
e.preventDefault();
let data = {}
data["title"] = document.querySelector(`#title${id}`).value;
- data["isMainProject"] = document.querySelector(`#isMainProject${id}`).checked;
- data["img"] = document.querySelector(`#img${id}`).files[0];
+ data["isMainProject"] = document.querySelector(`#isMainProject${id}`).checked ? "true" : "false";
data["information"] = document.querySelector(`#info${id}`).value;
data["projectLink"] = document.querySelector(`#viewProj${id}`).value;
data["gitLink"] = document.querySelector(`#git${id}`).value;
+let imgData = new FormData();
+ imgData.append("img", document.querySelector(`#img${id}`).files[0]);
+
fetch("/api/projectData/" + id, {
method: "PATCH",
body: JSON.stringify(data),
@@ -591,9 +593,60 @@ function updateProjectItem(id, e)
{
if (res.ok)
{
+
+ if (imgData.get("img") === "undefined")
+ {
+
+ if (data["isMainProject"] === "true")
+ {
+ document.querySelectorAll(".isMainProject input").forEach(item => item.checked = false);
+ document.querySelector(`#isMainProject${id}`).checked = true;
+ document.querySelector("#projList").prepend(document.querySelector(`#projectItem${id}`));
+ }
+
+ document.querySelector(`#projectItem${id}`).classList.toggle("editing");
+ document.querySelector(`#title${id}`).setAttribute("disabled", "");
+ document.querySelector(`#info${id}`).setAttribute("disabled", "");
+ return;
+ }
+ console.log("updating image")
+ return fetch("/api/projectImage/" + id, {
+ method: "POST",
+ body: imgData,
+ headers: {
+ "Authorization": "Bearer " + localStorage.getItem("token")
+ }
+ });
+ }
+
+ if (res.status === 401)
+ {
+ window.location.href = "./";
+ return;
+ }
+
+ res.json().then(projectDataError =>
+ {
+ document.querySelector(`#projError${id}`).classList.remove("hidden");
+ document.querySelector(`#projError${id} div`).innerHTML = projectDataError.error;
+ });
+
+ }).then(res => res.json().then(updatedProjectImage =>
+ {
+ if (res.ok)
+ {
+
+ if (data["isMainProject"] === "true")
+ {
+ document.querySelectorAll(".isMainProject input").forEach(item => item.checked = false);
+ document.querySelector(`#isMainProject${id}`).checked = true;
+ document.querySelector("#projList").prepend(document.querySelector(`#projectItem${id}`));
+ }
+
document.querySelector(`#projectItem${id}`).classList.toggle("editing");
document.querySelector(`#title${id}`).setAttribute("disabled", "");
document.querySelector(`#info${id}`).setAttribute("disabled", "");
+ document.querySelector(`#projectImage${id}`).src = updatedProjectImage.imgLocation;
return;
}
@@ -603,12 +656,10 @@ function updateProjectItem(id, e)
return;
}
- res.json().then(json =>
- {
- document.querySelector(`#projError${id}`).classList.remove("hidden");
- document.querySelector(`#projError${id} div`).innerHTML = json.error;
- });
- });
+ document.querySelector(`#projError${id}`).classList.remove("hidden");
+ document.querySelector(`#projError${id} div`).innerHTML = projectDataError.error;
+
+ }));
}
@@ -655,13 +706,14 @@ function deleteProjectItem(id)
/**
* Adds a new project to the page
* @param {number} id the id of the project from the database
+ * @param {string} isMainProject is it the main project
* @param {string} imgLocation the relative path of the image
* @param {string} title the title of the project
* @param {string} information the information about the project
* @param {string} projectLink the link to the project
* @param {string} gitLink the link to the git repository
*/
-function addProject(id, imgLocation, title, information, projectLink, gitLink)
+function addProject(id , isMainProject, imgLocation, title, information, projectLink, gitLink)
{
let projectItem = document.createElement("form");
projectItem.id = "projectItem" + id;
@@ -672,7 +724,7 @@ function addProject(id, imgLocation, title, information, projectLink, gitLink)
-
+
@@ -681,7 +733,7 @@ function addProject(id, imgLocation, title, information, projectLink, gitLink)
Is It The Main Project
-
+
@@ -704,5 +756,14 @@ function addProject(id, imgLocation, title, information, projectLink, gitLink)
${(gitLink === "N/A") ? "disabled=\"disabled\"" : ""}Git
`;
+
+ if (isMainProject === "true")
+ {
+ document.querySelectorAll(".isMainProject input").forEach(item => item.checked = false);
+
+ document.querySelector("#projList").prepend(projectItem);
+ return;
+ }
+
document.querySelector("#projList").appendChild(projectItem);
}
diff --git a/src/js/main.js b/src/js/main.js
index 1f7d899..c92149f 100644
--- a/src/js/main.js
+++ b/src/js/main.js
@@ -171,7 +171,7 @@ function getProjectData()
document.getElementById("mainProj").innerHTML = `
${item["title"]}
-
+
${item["information"]}
@@ -186,7 +186,7 @@ function getProjectData()
document.querySelector("#otherProj div").innerHTML += `
-
+