diff --git a/dist/api/index.php b/dist/api/index.php index fcd86b4..07fce1d 100644 --- a/dist/api/index.php +++ b/dist/api/index.php @@ -59,6 +59,139 @@ $app->get("/timelineData/{timeline}", function (Request $request, Response $resp return $response->withStatus(404); }); +$app->patch("/timelineData/{timeline}/{id}", function (Request $request, Response $response, array $args) +{ + global $timelineData; + $data = $request->getParsedBody(); + if ($args["timeline"] == "edu" && $args["id"] != "undefined") + { + 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) + { + if (empty($data["dateFrom"]) || empty($data["dateTo"]) || empty($data["companyName"]) || empty($data["area"]) || empty($data["title"])) + { + // 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->updateWorkData($data["dateFrom"], $data["dateTo"], $data["companyName"], $data["area"], $data["title"], $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); + } + + $response->getBody()->write(json_encode(array("error" => "The correct data was not sent"))); + return $response->withStatus(400); +}); + +$app->delete("/timelineData/{timeline}/{id}", function (Request $request, Response $response, array $args) +{ + global $timelineData; + if ($args["timeline"] == "edu" && $args["id"] != null) + { + if (!$timelineData->deleteEduData($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) + { + if (!$timelineData->deleteWorkData($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); + } + + $response->getBody()->write(json_encode(array("error" => "The correct data was not sent"))); + return $response->withStatus(400); +}); + +$app->post("/timelineData/{timeline}", function (Request $request, Response $response, array $args) +{ + global $timelineData; + $data = $request->getParsedBody(); + if ($args["timeline"] == "edu") + { + 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); + } + + $insertedID = $timelineData->addEduData($data["dateFrom"], $data["dateTo"], $data["grade"], $data["course"]); + if (!is_int($insertedID)) + { + // uh oh something went wrong + $response->getBody()->write(json_encode(array("error" => "Something went wrong"))); + return $response->withStatus(500); + } + + $response->getBody()->write(json_encode(array("ID" => $insertedID))); + return $response->withStatus(200); + } + + if ($args["timeline"] == "work") + { + if (empty($data["dateFrom"]) || empty($data["companyName"]) || empty($data["area"]) || empty($data["title"])) + { + // 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 (empty($data["dateTo"])) + { + $data["dateTo"] = ""; + } + + $insertedID = $timelineData->addWorkData($data["dateFrom"], $data["dateTo"], $data["companyName"], $data["area"], $data["title"]); + if (!is_int($insertedID)) + { + // uh oh something went wrong + $response->getBody()->write(json_encode(array("error" => "Something went wrong"))); + return $response->withStatus(500); + } + + $response->getBody()->write(json_encode(array("ID" => $insertedID))); + return $response->withStatus(200); + } + + $response->getBody()->write(json_encode(array("error" => "The correct data was not sent"))); + return $response->withStatus(400); +}); + $app->get("/projectData", function (Request $request, Response $response) { global $projectData; @@ -373,39 +506,7 @@ $app->post("/user/changePassword", function (Request $request, Response $respons return $response->withStatus(500); }); -$app->patch("/timelineData/{timeline}/{id}", function (Request $request, Response $response, array $args) -{ - 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); -}); + diff --git a/dist/api/timelineData.php b/dist/api/timelineData.php index 29f5cd5..fe62458 100644 --- a/dist/api/timelineData.php +++ b/dist/api/timelineData.php @@ -1,5 +1,7 @@ prepare("SELECT startPeriod, endPeriod, companyName, area, title FROM work ORDER BY work.startPeriod DESC;"); + $stmt = $conn->prepare("SELECT ID, startPeriod, endPeriod, companyName, area, title FROM work ORDER BY work.startPeriod DESC;"); $stmt->execute(); // set the resulting array to associative $result = $stmt->fetchAll(PDO::FETCH_ASSOC); - + if ($result) { return $result; @@ -71,4 +73,103 @@ class timelineData return $stmt->execute(); } + /** + * Update work data + * @param string $dateFrom - Start date + * @param string $dateTo - End date + * @param string $companyName - Company name + * @param string $area - Area + * @param string $title - Title + * @param string $id - ID of the work data + * @return bool - True if successful, false if not + */ + public function updateWorkData(string $dateFrom, string $dateTo, string $companyName, string $area, string $title, string $id): bool + { + $conn = dbConn(); + $stmt = $conn->prepare("UPDATE work SET startPeriod = :dateFrom, endPeriod = :dateTo, companyName = :companyName, area = :area, title = :title WHERE ID = :id;"); + $stmt->bindParam(":dateFrom", $dateFrom); + $stmt->bindParam(":dateTo", $dateTo); + $stmt->bindParam(":companyName", $companyName); + $stmt->bindParam(":area", $area); + $stmt->bindParam(":title", $title); + $stmt->bindParam(":id", $id); + return $stmt->execute(); + } + + /** + * Delete education data by ID + * @param int $id + * @return bool - True if successful, false if not + */ + function deleteEduData(int $id): bool + { + $conn = dbConn(); + $stmt = $conn->prepare("DELETE FROM edu WHERE ID = :id;"); + $stmt->bindParam(":id", $id); + return $stmt->execute(); + } + + /** + * Delete work data by ID + * @param int $id + * @return bool - True if successful, false if not + */ + function deleteWorkData(int $id): bool + { + $conn = dbConn(); + $stmt = $conn->prepare("DELETE FROM work WHERE ID = :id;"); + $stmt->bindParam(":id", $id); + return $stmt->execute(); + } + + /** + * Create new education data + * @param string $dateFrom - Start date + * @param string $dateTo - End date + * @param string $grade - Grade + * @param string $course - Course + * @return bool|int - ID of the new education data or false if not successful + */ + function addEduData(string $dateFrom, string $dateTo, string $grade, string $course): bool|int + { + $conn = dbConn(); + $stmt = $conn->prepare("INSERT INTO edu (startPeriod, endPeriod, grade, course) VALUES (:dateFrom, :dateTo, :grade, :course);"); + $stmt->bindParam(":dateFrom", $dateFrom); + $stmt->bindParam(":dateTo", $dateTo); + $stmt->bindParam(":grade", $grade); + $stmt->bindParam(":course", $course); + + if($stmt->execute()) + { + return $conn->lastInsertId(); + } + return false; + } + + /** + * Create new work data + * @param string $dateFrom - Start date + * @param string $dateTo - End date + * @param string $companyName - Company name + * @param string $area - Area + * @param string $title - Title + * @return bool|int - ID of the new work data if successful, false if not + */ + function addWorkData(string $dateFrom, string $dateTo, string $companyName, string $area, string $title): bool|int + { + $conn = dbConn(); + $stmt = $conn->prepare("INSERT INTO work (startPeriod, endPeriod, companyName, area, title) VALUES (:dateFrom, :dateTo, :companyName, :area, :title);"); + $stmt->bindParam(":dateFrom", $dateFrom); + $stmt->bindParam(":dateTo", $dateTo); + $stmt->bindParam(":companyName", $companyName); + $stmt->bindParam(":area", $area); + $stmt->bindParam(":title", $title); + + if($stmt->execute()) + { + return $conn->lastInsertId(); + } + return false; + } + } diff --git a/dist/editor/css/main.css b/dist/editor/css/main.css index f71a59c..326ca32 100644 --- a/dist/editor/css/main.css +++ b/dist/editor/css/main.css @@ -1 +1 @@ -/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}:root{--mainHue:80;--mainSat:60%;--mainLight:50%;--primaryDefault:hsla(var(--mainHue), var(--mainSat), var(--mainLight), 1);--primaryHover:hsla(var(--mainHue), var(--mainSat), calc(var(--mainLight) - 10%), 1);--timelineItemBrdr:hsla(var(--mainHue), var(--mainSat), calc(var(--mainLight) - 20%), 1);--errorDefault:hsla(0, calc(var(--mainSat) + 10%),calc(var(--mainLight) + 10%), 1);--errorHover:hsla(0, calc(var(--mainSat) + 10%), calc(var(--mainLight) - 10%), 1);--grey:hsla(0, 0%, 39%, 1);--notAvailableDefault:hsla(0, 0%, 39%, 1);--notAvailableHover:hsla(0, 0%,32%, 1);--mutedGrey:hsla(0, 0%, 78%, 1);--mutedBlack:hsla(0, 0%, 0%, 0.25);--navBack:hsla(0, 0%, 30%, 1);--titleFS:2.25rem;--generalFS:1.125rem;--headingFS:1.5rem}*{box-sizing:border-box}html{scroll-behavior:smooth}body{font-family:Noto Sans KR,sans-serif;font-style:normal;font-weight:500;font-size:var(--generalFS);line-height:1.625rem}a:visited{color:inherit}h1,nav{font-family:Share Tech Mono,monospace;font-style:normal;font-weight:400;font-size:var(--titleFS);line-height:2.5625rem;text-transform:lowercase}h2{font-family:Noto Sans KR,sans-serif;font-style:normal;font-weight:500;font-size:var(--headingFS);line-height:2.1875rem}a.btn,form input[type=submit]{text-decoration:none;display:inline-block;padding:1em 2em;border-radius:.625em;border:.3215em solid var(--primaryDefault);color:#fff;text-align:center}form input[type=submit]{padding:1.1em 2em}a.btn:hover,form input[type=submit]:hover{border:.3215em solid var(--primaryHover)}a.btnPrimary,form input[type=submit]{background:var(--primaryDefault);cursor:pointer}a.btnOutline{background:#fff;color:var(--primaryDefault)}a.btnPrimary[disabled]{pointer-events:none;background:var(--notAvailableDefault);border:.3215em solid var(--notAvailableDefault)}a.btnPrimary[disabled]:hover{background:var(--notAvailableHover);border:.3215em solid var(--notAvailableHover)}a.btnPrimary:hover,form input[type=submit]:hover{background:var(--primaryHover)}a.btn:active,form input[type=submit]:active{padding:.8rem 1.8rem}.boxShadowOut:hover{box-shadow:0 6px 4px 0 var(--mutedBlack)}.boxShadowIn:active{box-shadow:inset 0 6px 4px 0 var(--mutedBlack)}.textShadow:hover{text-shadow:0 6px 4px var(--mutedBlack)}form .formControl{width:100%}form .formControl input:not([type=submit]),form .formControl textarea{width:100%;border:4px solid var(--primaryDefault);background:0 0;outline:0;-webkit-border-radius:1em;-moz-border-radius:1em;border-radius:.5em;padding:0 .5em}form .formControl textarea{padding:.5em}form .formControl input:not([type=submit]).invalid:invalid,form .formControl textarea.invalid:invalid{border:4px solid var(--errorDefault)}form .formControl input:not([type=submit]).invalid:invalid:focus,form .formControl textarea.invalid:invalid:focus{border:4px solid var(--errorHover);box-shadow:0 4px 2px 0 var(--mutedBlack)}form .formControl input:not([type=submit]):focus,form .formControl textarea:focus{border:4px solid var(--primaryHover)}form .formControl input:not([type=submit]){height:3em}form .formControl{width:100%}form input[type=submit]{align-self:flex-start}form .formControl input:not([type=submit]),form .formControl textarea{width:100%;border:4px solid var(--primaryDefault);background:0 0;outline:0;-webkit-border-radius:1em;-moz-border-radius:1em;border-radius:.5em;padding:0 .5em}form .formControl textarea{padding:.5em}form .formControl input:not([type=submit]).invalid:invalid,form .formControl textarea.invalid:invalid{border:4px solid var(--errorDefault)}form .formControl input:not([type=submit]).invalid:invalid:focus,form .formControl textarea.invalid:invalid:focus{border:4px solid var(--errorHover);box-shadow:0 4px 2px 0 var(--mutedBlack)}form .formControl input:not([type=submit]):focus,form .formControl textarea:focus{border:4px solid var(--primaryHover)}form .formControl input:not([type=submit]){height:3em}form .formControl i.fa-eye,form .formControl i.fa-eye-slash{margin-left:-40px;cursor:pointer;color:var(--primaryDefault)}form .formControl input:not([type=submit]):focus+i.fa-eye,form .formControl input:not([type=submit]):focus+i.fa-eye-slash{color:var(--primaryHover)}section#about,section#curriculumVitae h1{padding:0 5rem}h1{text-transform:none}body,html{height:100%}main.login{height:100%;display:flex;flex-direction:column;justify-content:center;align-items:center;background-image:radial-gradient(var(--primaryDefault),#597226)}div.container{flex-direction:column;justify-content:center;align-items:center;background-color:#fff;padding:2em 5em;-webkit-border-radius:1em;-moz-border-radius:1em;border-radius:1em;box-shadow:0 6px 4px 0 var(--mutedBlack);-webkit-transform:translateX(-150vw);-moz-transform:translateX(-150vw);-ms-transform:translateX(-150vw);-o-transform:translateX(-150vw);transform:translateX(-150vw);-webkit-transition:transform .4s ease-in-out;-moz-transition:transform .4s ease-in-out;-ms-transition:transform .4s ease-in-out;-o-transition:transform .4s ease-in-out;transition:transform .4s ease-in-out;overflow:hidden}div.container.shown{-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}div.container form{display:flex;flex-direction:column;justify-content:center;align-items:center;gap:1em}div#login #password{font-family:Verdana,serif;letter-spacing:.125em}div#login input[type=submit]{margin:0}div.error{background:var(--errorDefault);color:#fff;padding:.5em .8em;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;display:flex;justify-content:center;align-items:center;align-self:flex-start;flex-direction:row-reverse;position:relative;height:75px;visibility:visible;overflow:hidden;-webkit-transition:all .5s ease-in-out;-moz-transition:all .5s ease-in-out;-ms-transition:all .5s ease-in-out;-o-transition:all .5s ease-in-out;transition:all .5s ease-in-out;opacity:1;margin-top:1em}div.error button{border:none;background:0 0;outline:0;cursor:pointer;color:#fff;font-size:1.25rem;margin-top:-5px;position:absolute;transform:translate(0,0);transform-origin:0 0;right:10px;top:10px}div.error.hidden{opacity:0;visibility:hidden;height:0;margin:0;padding:0}div.error button:hover{text-shadow:-1px 2px var(--mutedBlack)}div.btnContainer{width:100%;display:flex;flex-direction:row;justify-content:space-between;align-items:center}div.btnContainer a:not(.btn){color:#000}nav{font-size:var(--headingFS)}nav.sideNav{height:100%;width:250px;z-index:1;position:fixed;top:0;left:0;background-color:var(--primaryHover);overflow-x:hidden;-webkit-transition:.5s;-moz-transition:.5s;-ms-transition:.5s;-o-transition:.5s;transition:.5s;padding-top:60px}nav.sideNav ul li{list-style:none}nav.sideNav a{padding:8px 8px 8px 0;text-decoration:none;color:#fff;display:block;-webkit-transition:.3s;-moz-transition:.3s;-ms-transition:.3s;-o-transition:.3s;transition:.3s}nav.sideNav .closeBtn{position:absolute;top:0;right:25px;margin-left:50px;font-size:var(--titleFS);display:none}nav.sideNav ul li span{visibility:hidden}nav.sideNav ul li .active span,nav.sideNav ul li a:hover span{visibility:visible}span#navOpen{font-size:var(--titleFS);cursor:pointer}main.editor{margin-left:250px}.title{display:flex;flex-direction:column;justify-content:center;align-items:center}#navOpen{visibility:hidden;padding:.25em 0 0 .25em;align-self:flex-start}section#curriculumVitae,section#projects,section#settings{margin:0 2em}input[type=submit]{margin-top:2em}.delete,.edit{border:none;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;outline:0;background-color:var(--primaryDefault);color:#fff;cursor:pointer}div.editorContainer{display:flex;flex-direction:row;justify-content:center;align-items:baseline;gap:2em;margin-bottom:.5em}div.editorContainer>*{width:45%}div.modifyBtnContainer{display:flex;flex-direction:row;justify-content:space-between;align-items:center;margin-bottom:.5em}div.dateContainer{display:flex;flex-direction:row;justify-content:center;align-items:center;gap:1em;margin-bottom:.5em}section#curriculumVitae .timeline{position:relative;max-width:30em;gap:1em;display:flex;flex-direction:column;height:100%}section#curriculumVitae .timelineItem{color:#fff;border:2px solid var(--timelineItemBrdr);-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;padding:0 1rem;position:relative;background-color:var(--primaryHover)}section#curriculumVitae .timelineItem.editing{color:#000;border:5px solid var(--primaryDefault);padding:.5em;background-color:#fff}form div.gradeContainer.formControl{display:flex;flex-direction:row;justify-content:flex-start;align-items:center}section#curriculumVitae form.timelineItem:not(.editing) .delete,section#curriculumVitae form.timelineItem:not(.editing) .edit{color:var(--primaryHover);background-color:#fff}section#curriculumVitae form.timelineItem:not(.editing) div.dateContainer{display:none}section#curriculumVitae form.timelineItem.editing .timelineHeader{display:none}section#curriculumVitae form.timelineItem.editing div.gradeContainer.formControl{gap:1em;margin-bottom:.5em}section#curriculumVitae form.timelineItem:not(.editing) .formControl .courseText,section#curriculumVitae form.timelineItem:not(.editing) div.gradeContainer.formControl input{outline:0;border:none;color:#fff;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}section#curriculumVitae form.timelineItem:not(.editing) div.gradeContainer.formControl input{padding:0 .25em}section#curriculumVitae form.timelineItem:not(.editing) div.formControl .courseText{padding:0}section#curriculumVitae form.timelineItem:not(.editing) input[type=submit]{display:none}.courseText{resize:none}@media only screen and (max-width:75em){nav.sideNav .closeBtn{display:block}} \ No newline at end of file +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}:root{--mainHue:80;--mainSat:60%;--mainLight:50%;--primaryDefault:hsla(var(--mainHue), var(--mainSat), var(--mainLight), 1);--primaryHover:hsla(var(--mainHue), var(--mainSat), calc(var(--mainLight) - 10%), 1);--timelineItemBrdr:hsla(var(--mainHue), var(--mainSat), calc(var(--mainLight) - 20%), 1);--errorDefault:hsla(0, calc(var(--mainSat) + 10%),calc(var(--mainLight) + 10%), 1);--errorHover:hsla(0, calc(var(--mainSat) + 10%), calc(var(--mainLight) - 10%), 1);--grey:hsla(0, 0%, 39%, 1);--notAvailableDefault:hsla(0, 0%, 39%, 1);--notAvailableHover:hsla(0, 0%,32%, 1);--mutedGrey:hsla(0, 0%, 78%, 1);--mutedBlack:hsla(0, 0%, 0%, 0.25);--navBack:hsla(0, 0%, 30%, 1);--titleFS:2.25rem;--generalFS:1.125rem;--headingFS:1.5rem}*{box-sizing:border-box}html{scroll-behavior:smooth}body{font-family:Noto Sans KR,sans-serif;font-style:normal;font-weight:500;font-size:var(--generalFS);line-height:1.625rem}a:visited{color:inherit}h1,nav{font-family:Share Tech Mono,monospace;font-style:normal;font-weight:400;font-size:var(--titleFS);line-height:2.5625rem;text-transform:lowercase}h2{font-family:Noto Sans KR,sans-serif;font-style:normal;font-weight:500;font-size:var(--headingFS);line-height:2.1875rem}a.btn,form input[type=submit]{text-decoration:none;display:inline-block;padding:1em 2em;border-radius:.625em;border:.3215em solid var(--primaryDefault);color:#fff;text-align:center}form input[type=submit]{padding:1.1em 2em}a.btn:hover,form input[type=submit]:hover{border:.3215em solid var(--primaryHover)}a.btnPrimary,form input[type=submit]{background:var(--primaryDefault);cursor:pointer}a.btnOutline{background:#fff;color:var(--primaryDefault)}a.btnPrimary[disabled]{pointer-events:none;background:var(--notAvailableDefault);border:.3215em solid var(--notAvailableDefault)}a.btnPrimary[disabled]:hover{background:var(--notAvailableHover);border:.3215em solid var(--notAvailableHover)}a.btnPrimary:hover,form input[type=submit]:hover{background:var(--primaryHover)}a.btn:active,form input[type=submit]:active{padding:.8rem 1.8rem}.boxShadowOut:hover{box-shadow:0 6px 4px 0 var(--mutedBlack)}.boxShadowIn:active{box-shadow:inset 0 6px 4px 0 var(--mutedBlack)}.textShadow:hover{text-shadow:0 6px 4px var(--mutedBlack)}form .formControl{width:100%}form .formControl input:not([type=submit]),form .formControl textarea{width:100%;border:4px solid var(--primaryDefault);background:0 0;outline:0;-webkit-border-radius:1em;-moz-border-radius:1em;border-radius:.5em;padding:0 .5em}form .formControl textarea{padding:.5em}form .formControl input:not([type=submit]).invalid:invalid,form .formControl textarea.invalid:invalid{border:4px solid var(--errorDefault)}form .formControl input:not([type=submit]).invalid:invalid:focus,form .formControl textarea.invalid:invalid:focus{border:4px solid var(--errorHover);box-shadow:0 4px 2px 0 var(--mutedBlack)}form .formControl input:not([type=submit]):focus,form .formControl textarea:focus{border:4px solid var(--primaryHover)}form .formControl input:not([type=submit]){height:3em}form .formControl{width:100%}form input[type=submit]{align-self:flex-start}form .formControl input:not([type=submit]),form .formControl textarea{width:100%;border:4px solid var(--primaryDefault);background:0 0;outline:0;-webkit-border-radius:1em;-moz-border-radius:1em;border-radius:.5em;padding:0 .5em}form .formControl textarea{padding:.5em}form .formControl input:not([type=submit]).invalid:invalid,form .formControl textarea.invalid:invalid{border:4px solid var(--errorDefault)}form .formControl input:not([type=submit]).invalid:invalid:focus,form .formControl textarea.invalid:invalid:focus{border:4px solid var(--errorHover);box-shadow:0 4px 2px 0 var(--mutedBlack)}form .formControl input:not([type=submit]):focus,form .formControl textarea:focus{border:4px solid var(--primaryHover)}form .formControl input:not([type=submit]){height:3em}form .formControl i.fa-eye,form .formControl i.fa-eye-slash{margin-left:-40px;cursor:pointer;color:var(--primaryDefault)}form .formControl input:not([type=submit]):focus+i.fa-eye,form .formControl input:not([type=submit]):focus+i.fa-eye-slash{color:var(--primaryHover)}section#about,section#curriculumVitae h1{padding:0 5rem}h1{text-transform:none}body,html{height:100%}main.login{height:100%;display:flex;flex-direction:column;justify-content:center;align-items:center;background-image:radial-gradient(var(--primaryDefault),#597226)}div.container{flex-direction:column;justify-content:center;align-items:center;background-color:#fff;padding:2em 5em;-webkit-border-radius:1em;-moz-border-radius:1em;border-radius:1em;box-shadow:0 6px 4px 0 var(--mutedBlack);-webkit-transform:translateX(-150vw);-moz-transform:translateX(-150vw);-ms-transform:translateX(-150vw);-o-transform:translateX(-150vw);transform:translateX(-150vw);-webkit-transition:transform .4s ease-in-out;-moz-transition:transform .4s ease-in-out;-ms-transition:transform .4s ease-in-out;-o-transition:transform .4s ease-in-out;transition:transform .4s ease-in-out;overflow:hidden}div.container.shown{-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}div.container form{display:flex;flex-direction:column;justify-content:center;align-items:center;gap:1em}div#login #password{font-family:Verdana,serif;letter-spacing:.125em}div#login input[type=submit]{margin:0}div.error{background:var(--errorDefault);color:#fff;padding:.5em .8em;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;display:flex;justify-content:center;align-items:center;align-self:flex-start;flex-direction:row-reverse;position:relative;height:75px;visibility:visible;overflow:hidden;-webkit-transition:all .5s ease-in-out;-moz-transition:all .5s ease-in-out;-ms-transition:all .5s ease-in-out;-o-transition:all .5s ease-in-out;transition:all .5s ease-in-out;opacity:1;margin-top:1em}div.error button{border:none;background:0 0;outline:0;cursor:pointer;color:#fff;font-size:1.25rem;margin-top:-5px;position:absolute;transform:translate(0,0);transform-origin:0 0;right:10px;top:10px}div.error.hidden{opacity:0;visibility:hidden;height:0;margin:0;padding:0}div.error button:hover{text-shadow:-1px 2px var(--mutedBlack)}div.btnContainer{width:100%;display:flex;flex-direction:row;justify-content:space-between;align-items:center}div.btnContainer a:not(.btn){color:#000}nav{font-size:var(--headingFS)}nav.sideNav{height:100%;width:250px;z-index:1;position:fixed;top:0;left:0;background-color:var(--primaryHover);overflow-x:hidden;-webkit-transition:.5s;-moz-transition:.5s;-ms-transition:.5s;-o-transition:.5s;transition:.5s;padding-top:60px}nav.sideNav ul li{list-style:none}nav.sideNav a{padding:8px 8px 8px 0;text-decoration:none;color:#fff;display:block;-webkit-transition:.3s;-moz-transition:.3s;-ms-transition:.3s;-o-transition:.3s;transition:.3s}nav.sideNav .closeBtn{position:absolute;top:0;right:25px;margin-left:50px;font-size:var(--titleFS);display:none}nav.sideNav ul li span{visibility:hidden}nav.sideNav ul li .active span,nav.sideNav ul li a:hover span{visibility:visible}span#navOpen{font-size:var(--titleFS);cursor:pointer}main.editor{margin-left:250px}.title{display:flex;flex-direction:column;justify-content:center;align-items:center}#navOpen{visibility:hidden;padding:.25em 0 0 .25em;align-self:flex-start}section#curriculumVitae,section#projects,section#settings{margin:0 2em}input[type=submit]{margin-top:2em}.delete,.edit{border:none;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;outline:0;background-color:var(--primaryDefault);color:#fff;cursor:pointer}.timelineHeader{font-weight:400}div.editorContainer{display:flex;flex-direction:row;justify-content:center;align-items:baseline;gap:2em;margin-bottom:.5em}div.editorContainer>*{width:45%}div.modifyBtnContainer{display:flex;flex-direction:row;justify-content:space-between;align-items:center;margin-bottom:.5em}div.companyAreaContainer,div.dateContainer{display:flex;flex-direction:row;justify-content:flex-start;align-items:center;gap:1em;margin-bottom:.5em}section#curriculumVitae .timeline{position:relative;max-width:30em;gap:1em;display:flex;flex-direction:column;height:100%}section#curriculumVitae .timelineItem{color:#fff;border:2px solid var(--timelineItemBrdr);-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;padding:0 1rem;position:relative;background-color:var(--primaryHover)}section#curriculumVitae .timelineItem.editing{color:#000;border:5px solid var(--primaryDefault);padding:.5em;background-color:#fff}form div.gradeContainer.formControl{display:flex;flex-direction:row;justify-content:flex-start;align-items:center}section#curriculumVitae form.timelineItem:not(.editing) .delete,section#curriculumVitae form.timelineItem:not(.editing) .edit{color:var(--primaryHover);background-color:#fff}section#curriculumVitae form.timelineItem:not(.editing) div.dateContainer{display:none}section#curriculumVitae form.timelineItem.editing .timelineHeader{display:none}section#curriculumVitae form.timelineItem.editing div.gradeContainer.formControl{gap:1em;margin-bottom:.5em}section#curriculumVitae form.timelineItem:not(.editing) .formControl .courseText,section#curriculumVitae form.timelineItem:not(.editing) .formControl .jobTitleText,section#curriculumVitae form.timelineItem:not(.editing) div.companyAreaContainer.formControl input,section#curriculumVitae form.timelineItem:not(.editing) div.gradeContainer.formControl input{outline:0;border:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}section#curriculumVitae form.timelineItem:not(.editing) div.companyAreaContainer.formControl>*,section#curriculumVitae form.timelineItem:not(.editing) div.gradeContainer.formControl>*{color:#e5e5e5}section#curriculumVitae form.timelineItem:not(.editing) .formControl .courseText,section#curriculumVitae form.timelineItem:not(.editing) .formControl .jobTitleText{color:#fff}section#curriculumVitae form.timelineItem:not(.editing) div.gradeContainer.formControl input{padding:0 .25em}section#curriculumVitae form.timelineItem:not(.editing) .formControl .courseText,section#curriculumVitae form.timelineItem:not(.editing) div.formControl .courseText{padding:0}section#curriculumVitae form.timelineItem:not(.editing) input[type=submit]{display:none}.courseText{resize:none}section#curriculumVitae form.timelineItem:not(.editing) div.companyAreaContainer input{width:30%}@media only screen and (max-width:75em){nav.sideNav .closeBtn{display:block}} \ No newline at end of file diff --git a/dist/editor/editor.html b/dist/editor/editor.html index 2c5f687..5c7095f 100644 --- a/dist/editor/editor.html +++ b/dist/editor/editor.html @@ -1 +1 @@ -Editor

Editor

curriculum vitae

Education

Work

\ No newline at end of file +Editor

Editor

curriculum vitae

Education

Work

\ No newline at end of file diff --git a/dist/editor/js/editor.js b/dist/editor/js/editor.js index 9544b59..69639fc 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).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 +let dateOptions={month:"short",year:"numeric"};function edit(e){if(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,n,r,a=!1){let d=e+"e",i=document.createElement("form");i.id="timelineItem"+d,i.classList.add("timelineItem"),i.onsubmit=t=>updateEduItem(e,t),i.innerHTML=`\n
\n \n \n
\n
\n \n -\n \n
\n

${new Date(t).toLocaleString("en-gb",dateOptions)} - ${new Date(o).toLocaleString("en-gb",dateOptions)}

\n
\n \n \n
\n
\n \n
\n \n \n \n `,a?document.querySelector("#edu").prepend(i):document.getElementById("edu").appendChild(i)}function addWorkData(e,t,o,n,r,a,d=!1){let i=e+"w",l=document.createElement("form");l.id="timelineItem"+i,l.classList.add("timelineItem"),l.onsubmit=t=>updateWorkItem(e,t),l.innerHTML=`\n
\n \n \n
\n
\n \n -\n \n
\n

${new Date(t).toLocaleString("en-gb",dateOptions)} - ${"Present"===o?"":new Date(o).toLocaleString("en-gb",dateOptions)}

\n
\n \n -\n \n
\n
\n \n
\n \n \n \n\t`,d?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="./"}))}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{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:{Authentication: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?(document.querySelector("#eduError").classList.remove("hidden"),document.querySelector("#eduError div").innerHTML=o.error):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:{Authentication: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("#addEdu").reset()}401!==e.status?(document.querySelector("#eduError").classList.remove("hidden"),document.querySelector("#eduError div").innerHTML=o.error):window.location.href="./"}))))})); \ No newline at end of file diff --git a/dist/js/main.js b/dist/js/main.js index 5936e6f..ae15f45 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