Added the ability to see the timeline data in the editor and added in a basic form.
Signed-off-by: rodude123 <rodude123@gmail.com>
This commit is contained in:
@@ -17,7 +17,7 @@ class timelineData
|
||||
function getEduData(): array
|
||||
{
|
||||
$conn = dbConn();
|
||||
$stmt = $conn->prepare("SELECT DATE_FORMAT(startPeriod, '%b, %Y') as startPeriod, DATE_FORMAT(endPeriod, '%b, %Y') as endPeriod, grade, course FROM edu ORDER BY startPeriod DESC;");
|
||||
$stmt = $conn->prepare("SELECT startPeriod, endPeriod, grade, course FROM edu ORDER BY startPeriod DESC;");
|
||||
$stmt->execute();
|
||||
|
||||
// set the resulting array to associative
|
||||
@@ -37,7 +37,7 @@ class timelineData
|
||||
function getWorkData(): array
|
||||
{
|
||||
$conn = dbConn();
|
||||
$stmt = $conn->prepare("SELECT DATE_FORMAT(startPeriod, '%b, %Y') as startPeriod, DATE_FORMAT(endPeriod, '%b, %Y') as endPeriod, companyName, area, title FROM work ORDER BY work.startPeriod DESC;");
|
||||
$stmt = $conn->prepare("SELECT startPeriod, endPeriod, companyName, area, title FROM work ORDER BY work.startPeriod DESC;");
|
||||
$stmt->execute();
|
||||
|
||||
// set the resulting array to associative
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*** Main editor styles ***/
|
||||
|
||||
section#curriculumVitae, section#projects, section#settings {
|
||||
margin: 0 2em;
|
||||
}
|
||||
|
||||
input[type="submit"] {
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
.edit, .delete{
|
||||
border: none;
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
background-color: var(--primaryDefault);
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div.editorContainer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: baseline;
|
||||
gap: 2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
div.editorContainer > * {
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
div.modifyBtnContainer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
div.dateContainer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 1em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
section#curriculumVitae .timeline {
|
||||
position: relative;
|
||||
max-width: 30em;
|
||||
gap: 1em;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
section#curriculumVitae .timelineItem {
|
||||
color: #FFFFFF;
|
||||
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: #000000;
|
||||
border: 5px solid var(--primaryDefault);
|
||||
padding: 0.5em;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
form div.gradeContainer.formControl {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
section#curriculumVitae form.timelineItem:not(.editing) .edit,
|
||||
section#curriculumVitae form.timelineItem:not(.editing) .delete {
|
||||
color: var(--primaryHover);
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
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: 0.5em;
|
||||
}
|
||||
|
||||
section#curriculumVitae form.timelineItem:not(.editing) div.gradeContainer.formControl input,
|
||||
section#curriculumVitae form.timelineItem:not(.editing) .formControl .courseText {
|
||||
outline: none;
|
||||
border: none;
|
||||
color: #FFFFFF;
|
||||
-webkit-border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
section#curriculumVitae form.timelineItem:not(.editing) div.gradeContainer.formControl input {
|
||||
padding: 0 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;
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
@import "../../css/templateStyles.css";
|
||||
@import "login.css";
|
||||
@import "nav.css";
|
||||
@import "editor.css";
|
||||
|
||||
/*** Media Queries ***/
|
||||
|
||||
|
||||
@@ -71,6 +71,6 @@ main.editor {
|
||||
|
||||
#navOpen {
|
||||
visibility: hidden;
|
||||
padding-left: 0.25em;
|
||||
padding: 0.25em 0 0 0.25em;
|
||||
align-self: flex-start;
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<title>Editor</title>
|
||||
<link rel="stylesheet" href="css/main.css">
|
||||
<script src="https://kit.fontawesome.com/ed3c25598e.js" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="sideNav">
|
||||
@@ -17,8 +18,59 @@
|
||||
<main class="editor" style="margin-left: 250px;">
|
||||
<div class="title">
|
||||
<span id="navOpen">☰</span>
|
||||
|
||||
<h1>Editor</h1>
|
||||
</div>
|
||||
<section id="curriculumVitae">
|
||||
<h2>curriculum vitae</h2>
|
||||
<div class="cvGrid">
|
||||
<!-- https://codepen.io/keithwyland/pen/wqNqvy -->
|
||||
<div>
|
||||
<h3>Education</h3>
|
||||
|
||||
<div class="editorContainer">
|
||||
<form action="" method="POST">
|
||||
<div class="formControl">
|
||||
<label for="dateFrom">Date From</label>
|
||||
<input type="date" id="dateFrom" name="dateFrom">
|
||||
</div>
|
||||
|
||||
<div class="formControl">
|
||||
<label for="dateTo">Date To</label>
|
||||
<input type="date" id="dateTo" name="dateTo">
|
||||
</div>
|
||||
|
||||
<div class="formControl">
|
||||
<label for="grade">Grade</label>
|
||||
<input type="text" id="grade" name="grade">
|
||||
</div>
|
||||
|
||||
<div class="formControl">
|
||||
<label for="courseTitle">Course Title</label>
|
||||
<input type="text" id="courseTitle" name="courseTitle">
|
||||
</div>
|
||||
|
||||
<div class="error hidden" id="eduError">
|
||||
<button class="close" type="button">×</button>
|
||||
<div></div>
|
||||
</div>
|
||||
|
||||
<input type="submit" class="btn btnPrimary boxShadowIn boxShadowOut" value="Add new course">
|
||||
</form>
|
||||
|
||||
<div class="timeline" id="edu">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>Work</h3>
|
||||
|
||||
<div class="timeline" id="work">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<script src="js/editor.js"></script>
|
||||
|
||||
+101
-14
@@ -1,26 +1,113 @@
|
||||
|
||||
document.addEventListener('DOMContentLoaded', e =>
|
||||
let dateOptions = {month: 'short', year: 'numeric'};
|
||||
document.addEventListener('DOMContentLoaded', () =>
|
||||
{
|
||||
// check if the user is logged in, if not redirect to log in
|
||||
/* fetch('/api/user/isLoggedIn').then(res =>
|
||||
{
|
||||
if (!res.ok)
|
||||
/* fetch('/api/user/isLoggedIn').then(res =>
|
||||
{
|
||||
window.location.href = './';
|
||||
}
|
||||
});*/
|
||||
if (!res.ok)
|
||||
{
|
||||
window.location.href = './';
|
||||
}
|
||||
});*/
|
||||
document.querySelector("#dateFrom").max = new Date().toISOString().split("T")[0];
|
||||
|
||||
|
||||
fetch("/api/timelineData/edu").then(res =>
|
||||
{
|
||||
res.json().then(json =>
|
||||
{
|
||||
if (res.ok)
|
||||
{
|
||||
for (let i = 0; i < json.length; i++)
|
||||
{
|
||||
let timelineItem = document.createElement("form")
|
||||
timelineItem.id = "timelineItem" + i;
|
||||
timelineItem.classList.add("timelineItem");
|
||||
timelineItem.onsubmit = e => updateItem(i, e);
|
||||
timelineItem.innerHTML = `
|
||||
<div class="modifyBtnContainer">
|
||||
<button class="edit" type="button" id="edit${i}" onclick="edit(${i})"><i class="fa-solid fa-pen-to-square"></i></button>
|
||||
<button class="delete" type="button" id="delete${i}"><i class="fa-solid fa-trash"></i></button>
|
||||
</div>
|
||||
<div class="dateContainer formControl">
|
||||
<input type="date" name="dateFrom${i}" id="dateFrom${i}" onload="this.max = new Date().toISOString().split('T')[0]" value="${json[i]['startPeriod']}">
|
||||
-
|
||||
<input type="date" name="dateTo${i}" id="dateTo${i}" value="${json[i]['endPeriod']}">
|
||||
</div>
|
||||
<h3 class="timelineHeader">${new Date(json[i]["startPeriod"]).toLocaleString('en-gb', dateOptions)} - ${new Date(json[i]["endPeriod"]).toLocaleString('en-gb', dateOptions)}</h3>
|
||||
<div class="gradeContainer formControl">
|
||||
<label for="grade${i}">Grade:</label>
|
||||
<input type="text" name="grade${i}" id="grade${i}" value="${json[i]['grade']}" disabled>
|
||||
</div>
|
||||
<div class="formControl">
|
||||
<textarea class="courseText" name="course${i}" id="course${i}" cols="10" rows="3" disabled>${json[i]['course']}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="error hidden" id="eduError">
|
||||
<button class="close" type="button">×</button>
|
||||
<div></div>
|
||||
</div>
|
||||
<input type="submit" value="Change">
|
||||
`;
|
||||
document.getElementById("edu").appendChild(timelineItem);
|
||||
}
|
||||
return;
|
||||
}
|
||||
document.querySelector("#edu").innerHTML = "No education data found";
|
||||
})
|
||||
});
|
||||
})
|
||||
|
||||
document.querySelector("#navOpen").addEventListener("click", e =>
|
||||
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("nav.sideNav").style.removeProperty("width");
|
||||
document.querySelector("main.editor").style.removeProperty("margin-left");
|
||||
e.target.style.removeProperty("visibility");
|
||||
});
|
||||
|
||||
document.querySelector("#navClose").addEventListener("click", e =>
|
||||
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";
|
||||
});
|
||||
});
|
||||
|
||||
function edit(i)
|
||||
{
|
||||
document.querySelector("#timelineItem" + i).classList.toggle("editing");
|
||||
document.querySelector("#grade" + i).removeAttribute("disabled");
|
||||
document.querySelector("#course" + i).removeAttribute("disabled");
|
||||
}
|
||||
|
||||
function updateItem(i, e)
|
||||
{
|
||||
e.preventDefault();
|
||||
let data = new FormData();
|
||||
data.append("dateFrom", document.querySelector("#dateFrom" + i).value);
|
||||
data.append("dateTo", document.querySelector("#dateTo" + i).value);
|
||||
data.append("grade", document.querySelector("#grade" + i).value);
|
||||
data.append("course", document.querySelector("#course" + i).value);
|
||||
|
||||
fetch("/api/timelineData/edu/" + i, {
|
||||
method: "PUT",
|
||||
body: data,
|
||||
headers: {
|
||||
"Authorization": "Bearer " + localStorage.getItem("token")
|
||||
}
|
||||
}).then(res =>
|
||||
{
|
||||
if (res.ok)
|
||||
{
|
||||
document.querySelector("#timelineItem" + i).classList.toggle("editing");
|
||||
document.querySelector("#grade" + i).setAttribute("disabled", "");
|
||||
document.querySelector("#course" + i).setAttribute("disabled", "");
|
||||
return;
|
||||
}
|
||||
|
||||
res.json().then(json =>
|
||||
{
|
||||
alert(json.message);
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
@@ -39,10 +39,11 @@ document.querySelector("#login form").addEventListener("submit", e =>
|
||||
{
|
||||
method: "POST",
|
||||
body: loginData
|
||||
}).then(res =>
|
||||
}).then(res => res.json()).then(json =>
|
||||
{
|
||||
if (res.ok)
|
||||
{
|
||||
localStorage.setItem("token", json.token);
|
||||
window.location.href = "./editor.html";
|
||||
return;
|
||||
}
|
||||
|
||||
+3
-2
@@ -107,6 +107,7 @@ function StartTextAnimation(i)
|
||||
*/
|
||||
function getTimelineData()
|
||||
{
|
||||
let dateOptions = { year: "numeric", month: "short" };
|
||||
fetch("/api/timelineData/edu").then(res =>
|
||||
{
|
||||
res.json().then(json =>
|
||||
@@ -118,7 +119,7 @@ function getTimelineData()
|
||||
let timelineItem = document.createElement("div")
|
||||
timelineItem.classList.add("timelineItem");
|
||||
timelineItem.innerHTML = `
|
||||
<h3 class="timelineHeader">${item["startPeriod"]} - ${item["endPeriod"]}</h3>
|
||||
<h3 class="timelineHeader">${new Date(item["startPeriod"]).toLocaleString('en-gb', dateOptions)} - ${new Date(item["endPeriod"]).toLocaleString('en-gb', dateOptions)}</h3>
|
||||
<span>Grade: ${item["grade"]}</span>
|
||||
<p class="timelineText">${item["course"]}</p>
|
||||
`;
|
||||
@@ -139,7 +140,7 @@ function getTimelineData()
|
||||
let timelineItem = document.createElement("div")
|
||||
timelineItem.classList.add("timelineItem");
|
||||
timelineItem.innerHTML = `
|
||||
<h3 class="timelineHeader">${item["startPeriod"]} - ${item["endPeriod"]}</h3>
|
||||
<h3 class="timelineHeader">${new Date(item["startPeriod"]).toLocaleString('en-gb', dateOptions)} - ${new Date(item["endPeriod"]).toLocaleString('en-gb', dateOptions)}</h3>
|
||||
<span>${item["companyName"]} - ${item["area"]}</span>
|
||||
<p class="timelineText">${item["title"]}</p>
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user