my-portfolio/dist/editor/js/editor.js
rodude123 b28e7b2da5
All checks were successful
🚀 Deploy website on push / 🎉 Deploy (push) Successful in 24s
Various fixes for the blog and editor. As well as finally adding in the carousel!
Signed-off-by: rodude123 <rodude123@gmail.com>
2024-11-04 22:17:42 +00:00

1 line
35 KiB
JavaScript

let dateOptions={month:"short",year:"numeric"},textareaLoaded=!1,editors={},posts=null;const smallPaddingElements=["figcaption","li"];function goToPage(e){document.querySelectorAll(".editor section").forEach((t=>{t.style.display="none",t.id===e&&(t.style.display="flex")}))}function viewToPlainText(e){let t="";if(e.is("$text")||e.is("$textProxy"))t=e.data;else if(e.is("element","br"))t="\n";else{let a=null;for(const l of e.getChildren()){const e=viewToPlainText(l);a&&(a.is("containerElement")||l.is("containerElement"))&&(smallPaddingElements.includes(a.name)||smallPaddingElements.includes(l.name)?t+="\n":t+="\n\n"),t+=e,a=l}}return t}function addActiveClass(e){document.querySelectorAll("nav.sideNav ul li a").forEach((t=>{t.classList.remove("active"),t.id===e&&t.classList.add("active")}))}function editProjectItem(e){document.querySelector(`#projectItem${e}`).classList.toggle("editing"),document.querySelector(`#title${e}proj`).toggleAttribute("disabled"),document.querySelector(`#info${e}proj`).toggleAttribute("disabled")}function createEditors(...e){e.forEach((e=>{ClassicEditor.create(document.querySelector(`#${e}`),{placeholder:"Write something amazing...",simpleUpload:{uploadUrl:"/api/blog/uploadPostImage",headers:{Authorization:"Bearer "+localStorage.getItem("token")}},style:{definitions:[{name:"Button Primary",element:"a",classes:["btn","btnPrimary"]},{name:"Button Primary",element:"button",classes:["btn","btnPrimary"]}]},codeBlock:{languages:[{language:"plaintext",label:"Plain text"},{language:"abap",label:"ABAP"},{language:"abnf",label:"ABNF"},{language:"actionscript",label:"ActionScript"},{language:"ada",label:"Ada"},{language:"agda",label:"Agda"},{language:"al",label:"AL"},{language:"antlr4",label:"ANTLR4"},{language:"apacheconf",label:"Apache Configuration"},{language:"apex",label:"Apex"},{language:"apl",label:"APL"},{language:"applescript",label:"AppleScript"},{language:"aql",label:"AQL"},{language:"arduino",label:"Arduino"},{language:"arff",label:"ARFF"},{language:"asciidoc",label:"AsciiDoc"},{language:"aspnet",label:"ASP.NET (C#)"},{language:"asm6502",label:"6502 Assembly"},{language:"autohotkey",label:"AutoHotkey"},{language:"autoit",label:"AutoIt"},{language:"bash",label:"Bash"},{language:"basic",label:"BASIC"},{language:"batch",label:"Batch"},{language:"bbcode",label:"BBcode"},{language:"bison",label:"Bison"},{language:"bnf",label:"BNF"},{language:"brainfuck",label:"Brainfuck"},{language:"brightscript",label:"BrightScript"},{language:"bro",label:"Bro"},{language:"c",label:"C"},{language:"concurnas",label:"Concurnas"},{language:"csharp",label:"C#"},{language:"cpp",label:"C++"},{language:"cil",label:"CIL"},{language:"clojure",label:"Clojure"},{language:"cmake",label:"CMake"},{language:"coffeescript",label:"CoffeeScript"},{language:"concurnas",label:"Concurnas"},{language:"crystal",label:"Crystal"},{language:"css-extras",label:"CSS Extras"},{language:"css",label:"CSS"},{language:"d",label:"D"},{language:"dart",label:"Dart"},{language:"dax",label:"DAX"},{language:"dhall",label:"Dhall"},{language:"diff",label:"Diff"},{language:"django",label:"Django/Jinja2"},{language:"dns-zone-file",label:"DNS zone file"},{language:"docker",label:"Docker"},{language:"ebnf",label:"EBNF"},{language:"editorconfig",label:"EditorConfig"},{language:"eiffel",label:"Eiffel"},{language:"ejs",label:"EJS"},{language:"elixir",label:"Elixir"},{language:"elm",label:"Elm"},{language:"etlua",label:"Embedded Lua"},{language:"erb",label:"ERB"},{language:"erlang",label:"Erlang"},{language:"excel-formula",label:"Excel Formula"},{language:"fsharp",label:"F#"},{language:"factor",label:"Factor"},{language:"firestore-security-rules",label:"Firestore security rules"},{language:"flow",label:"Flow"},{language:"fortran",label:"Fortran"},{language:"ftl",label:"FreeMarker Template Language"},{language:"gcode",label:"G-code"},{language:"gdscript",label:"GDScript"},{language:"gedcom",label:"GEDCOM"},{language:"gherkin",label:"Gherkin"},{language:"git",label:"Git"},{language:"glsl",label:"GLSL"},{language:"gml",label:"GameMaker Language"},{language:"go",label:"Go"},{language:"graphql",label:"GraphQL"},{language:"groovy",label:"Groovy"},{language:"haml",label:"Haml"},{language:"handlebars",label:"Handlebars"},{language:"haskell",label:"Haskell"},{language:"haxe",label:"Haxe"},{language:"hcl",label:"HCL"},{language:"hlsl",label:"HLSL"},{language:"http",label:"HTTP"},{language:"hpkp",label:"HTTP Public-Key-Pins"},{language:"hsts",label:"HTTP Strict-Transport-Security"},{language:"ichigojam",label:"IchigoJam"},{language:"icon",label:"Icon"},{language:"ignore",label:"Ignore"},{language:"inform7",label:"Inform 7"},{language:"ini",label:"Ini"},{language:"io",label:"Io"},{language:"j",label:"J"},{language:"java",label:"Java"},{language:"javadoc",label:"JavaDoc"},{language:"javadoclike",label:"JavaDoc-like"},{language:"javascript",label:"JavaScript"},{language:"javastacktrace",label:"Java stack trace"},{language:"jolie",label:"Jolie"},{language:"jq",label:"JQ"},{language:"js-extras",label:"JS Extras"},{language:"js-templates",label:"JS Templates"},{language:"jsdoc",label:"JSDoc"},{language:"json",label:"JSON"},{language:"json5",label:"JSON5"},{language:"jsonp",label:"JSONP"},{language:"jsstacktrace",label:"JS stack trace"},{language:"jsx",label:"React JSX"},{language:"julia",label:"Julia"},{language:"keyman",label:"Keyman"},{language:"kotlin",label:"Kotlin"},{language:"latex",label:"LaTeX"},{language:"latte",label:"Latte"},{language:"less",label:"Less"},{language:"lilypond",label:"LilyPond"},{language:"liquid",label:"Liquid"},{language:"lisp",label:"Lisp"},{language:"livescript",label:"LiveScript"},{language:"llvm",label:"LLVM IR"},{language:"log",label:"Log file"},{language:"lolcode",label:"LOLCODE"},{language:"lua",label:"Lua"},{language:"makefile",label:"Makefile"},{language:"markdown",label:"Markdown"},{language:"markup-templating",label:"Markup templating"},{language:"matlab",label:"MATLAB"},{language:"mel",label:"MEL"},{language:"mizar",label:"Mizar"},{language:"mongodb",label:"MongoDB"},{language:"monkey",label:"Monkey"},{language:"moonscript",label:"MoonScript"},{language:"n1ql",label:"N1QL"},{language:"n4js",label:"N4JS"},{language:"nand2tetris-hdl",label:"Nand To Tetris HDL"},{language:"nasm",label:"NASM"},{language:"neon",label:"NEON"},{language:"nginx",label:"nginx"},{language:"nim",label:"Nim"},{language:"nix",label:"Nix"},{language:"nsis",label:"NSIS"},{language:"objectivec",label:"Objective-C"},{language:"ocaml",label:"OCaml"},{language:"opencl",label:"OpenCL"},{language:"oz",label:"Oz"},{language:"parigp",label:"PARI/GP"},{language:"parser",label:"Parser"},{language:"pascal",label:"Pascal"},{language:"pascaligo",label:"Pascaligo"},{language:"pcaxis",label:"PC-Axis"},{language:"peoplecode",label:"PeopleCode"},{language:"perl",label:"Perl"},{language:"php",label:"PHP"},{language:"phpdoc",label:"PHPDoc"},{language:"php-extras",label:"PHP Extras"},{language:"plsql",label:"PL/SQL"},{language:"powerquery",label:"PowerQuery"},{language:"powershell",label:"PowerShell"},{language:"processing",label:"Processing"},{language:"prolog",label:"Prolog"},{language:"properties",label:".properties"},{language:"protobuf",label:"Protocol Buffers"},{language:"pug",label:"Pug"},{language:"puppet",label:"Puppet"},{language:"pure",label:"Pure"},{language:"purebasic",label:"PureBasic"},{language:"python",label:"Python"},{language:"q",label:"Q (kdb+ database)"},{language:"qml",label:"QML"},{language:"qore",label:"Qore"},{language:"r",label:"R"},{language:"racket",label:"Racket"},{language:"jsx",label:"React JSX"},{language:"tsx",label:"React TSX"},{language:"reason",label:"Reason"},{language:"regex",label:"Regex"},{language:"renpy",label:"Ren'py"},{language:"rest",label:"reST (reStructuredText)"},{language:"rip",label:"Rip"},{language:"roboconf",label:"Roboconf"},{language:"robotframework",label:"Robot Framework"},{language:"ruby",label:"Ruby"},{language:"rust",label:"Rust"},{language:"sas",label:"SAS"},{language:"sass",label:"Sass (Sass)"},{language:"scss",label:"Sass (Scss)"},{language:"scala",label:"Scala"},{language:"scheme",label:"Scheme"},{language:"shell-session",label:"Shell session"},{language:"smali",label:"Smali"},{language:"smalltalk",label:"Smalltalk"},{language:"smarty",label:"Smarty"},{language:"solidity",label:"Solidity (Ethereum)"},{language:"solution-file",label:"Solution file"},{language:"soy",label:"Soy (Closure Template)"},{language:"sparql",label:"SPARQL"},{language:"splunk-spl",label:"Splunk SPL"},{language:"sqf",label:"SQF: Status Quo Function (Arma 3)"},{language:"sql",label:"SQL"},{language:"stan",label:"Stan"},{language:"stata",label:"Stata"},{language:"step21",label:"STEP Part 21"},{language:"stylus",label:"Stylus"},{language:"swift",label:"Swift"},{language:"tap",label:"TAP"},{language:"tcl",label:"Tcl"},{language:"textile",label:"Textile"},{language:"toml",label:"TOML"},{language:"tt2",label:"Template Toolkit 2"},{language:"turtle",label:"Turtle"},{language:"twig",label:"Twig"},{language:"typescript",label:"TypeScript"},{language:"t4-cs",label:"T4 Text Templates (C#)"},{language:"t4-vb",label:"T4 Text Templates (VB)"},{language:"t4-templating",label:"T4 templating"},{language:"unrealscript",label:"UnrealScript"},{language:"vala",label:"Vala"},{language:"vbnet",label:"VB.Net"},{language:"velocity",label:"Velocity"},{language:"verilog",label:"Verilog"},{language:"vhdl",label:"VHDL"},{language:"vim",label:"vim"},{language:"visual-basic",label:"Visual Basic"},{language:"warpscript",label:"WarpScript"},{language:"wasm",label:"WebAssembly"},{language:"wiki",label:"Wiki markup"},{language:"xeora",label:"Xeora"},{language:"xojo",label:"Xojo (REALbasic)"},{language:"xquery",label:"XQuery"},{language:"yaml",label:"YAML"},{language:"zephir",label:"Zephir"}]},mediaEmbed:{previewsInData:!0,providers:[{name:"youtube",url:[/^(?:m\.)?youtube\.com\/watch\?v=([\w-]+)(?:&t=(\d+))?/,/^(?:m\.)?youtube\.com\/v\/([\w-]+)(?:\?t=(\d+))?/,/^youtube\.com\/embed\/([\w-]+)(?:\?start=(\d+))?/,/^youtu\.be\/([\w-]+)(?:\?t=(\d+))?/],html:e=>{const t=e[1],a=e[2];return`<iframe width="560" height="315" style="text-align:center;" src="https://www.youtube.com/embed/${t}${a?`?start=${a}`:""}" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>`}}]}}).then((t=>{editors[e]=t})).catch((e=>{console.error("Oops, something went wrong!"),console.error("Please, report the following error on https://github.com/ckeditor/ckeditor5/issues with the build id and the error stack trace:"),console.warn("Build id: 1eo8ioyje2om-vgar4aghypdm"),console.error(e)}))}))}function editPostItem(e){posts.forEach((t=>{t.ID===e&&(document.querySelector("#editPostTitle").value=t.title,document.querySelector("#editIsFeatured").checked=1===t.featured,document.querySelector("#editPostCategories").value=t.categories,document.querySelector("#editPostAbstract").value=t.abstract,editors.CKEditorEditPost.setData(t.body),document.querySelector("#editPostForm input[type='submit']").id=e)}))}function showErrorMessage(e,t){document.querySelector(`#${t}Error`).classList.remove("hidden"),document.querySelector(`#${t}Error div`).innerText=e}function showSuccessMessage(e,t){document.querySelector(`#${t}Success`).classList.remove("hidden"),document.querySelector(`#${t}Success 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,a,l,o,n=!1){let r=e+"e",i=document.createElement("form");i.id="timelineItem"+r,i.classList.add("timelineItem"),i.onsubmit=t=>updateEduItem(e,t),i.innerHTML=`\n <div class="modifyBtnContainer">\n <button class="edit" type="button" id="edit${r}" onclick="editCVItem('${r}')"><i class="fa-solid fa-pen-to-square"></i></button>\n <button class="delete" type="button" id="delete${r}" onclick="deleteEduItem(${e})"><i class="fa-solid fa-trash"></i></button>\n </div>\n <div class="dateContainer formControl">\n <input type="date" name="dateFrom${r}" id="dateFrom${r}" onload="this.max = new Date().toISOString().split('T')[0]" value="${t}">\n -\n <input type="date" name="dateTo${r}" id="dateTo${r}" value="${a}">\n </div>\n <h3 class="timelineHeader" id="timelineHeader${r}">${new Date(t).toLocaleString("en-gb",dateOptions)} - ${new Date(a).toLocaleString("en-gb",dateOptions)}</h3>\n <div class="gradeContainer formControl">\n <label for="grade${r}">Grade:</label>\n <input type="text" name="grade${r}" id="grade${r}" value="${l}" disabled>\n </div>\n <div class="formControl">\n <textarea class="courseText" name="course${r}" id="course${r}" cols="10" rows="3" disabled>${o}</textarea>\n </div>\n \n <div class="error hidden" id="eduError${r}">\n <button class="close" type="button" onclick="this.parentElement.classList.toggle('hidden');">&times;</button>\n <div></div>\n </div>\n <input type="submit" value="Change">\n `,n?document.querySelector("#edu").prepend(i):document.getElementById("edu").appendChild(i)}function addWorkData(e,t,a,l,o,n,r=!1){let i=e+"w",d=document.createElement("form");d.id="timelineItem"+i,d.classList.add("timelineItem"),d.onsubmit=t=>updateWorkItem(e,t),d.innerHTML=`\n <div class="modifyBtnContainer">\n <button class="edit" type="button" id="edit${i}" onclick="editCVItem('${i}')"><i class="fa-solid fa-pen-to-square"></i></button>\n <button class="delete" type="button" id="delete${i}" onclick="deleteWorkItem(${e})"><i class="fa-solid fa-trash"></i></button>\n </div>\n <div class="dateContainer formControl">\n <input type="date" name="dateFrom${i}" id="dateFrom${i}" onload="this.max = new Date().toISOString().split('T')[0]" value="${t}">\n -\n <input type="date" name="dateTo${i}" id="dateTo${i}" value="${"Present"===a?"":a}">\n </div>\n <h3 class="timelineHeader" id="timelineHeader${i}">${new Date(t).toLocaleString("en-gb",dateOptions)} - ${"Present"===a?"Present":new Date(a).toLocaleString("en-gb",dateOptions)}</h3>\n <div class="companyAreaContainer formControl">\n <input type="text" name="companyName${i}" id="companyName${i}" value="${l}" disabled>\n -\n <input type="text" name="area${i}" id="area${i}" value="${o}" disabled> \n </div>\n <div class="formControl">\n <textarea class="jobTitleText" name="jobTitle${i}" id="jobTitle${i}" cols="10" rows="3" disabled>${n}</textarea>\n </div>\n \n <div class="error hidden" id="workError${i}">\n <button class="close" type="button" onclick="this.parentElement.classList.toggle('hidden');">&times;</button>\n <div></div>\n </div>\n <input type="submit" value="Change">\n\t`,r?document.querySelector("#work").prepend(d):document.getElementById("work").appendChild(d)}function updateEduItem(e,t){t.preventDefault();let a={};a.dateFrom=document.querySelector(`#dateFrom${e}e`).value,a.dateTo=document.querySelector(`#dateTo${e}e`).value,a.grade=document.querySelector(`#grade${e}e`).value,a.course=document.querySelector(`#course${e}e`).value,fetch("/api/timelineData/edu/"+e,{method:"PATCH",body:JSON.stringify(a),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 a={};a.dateFrom=document.querySelector(`#dateFrom${e}w`).value,a.dateTo=document.querySelector(`#dateTo${e}w`).value,a.companyName=document.querySelector(`#companyName${e}w`).value,a.area=document.querySelector(`#area${e}w`).value,a.title=document.querySelector(`#jobTitle${e}w`).value,fetch("/api/timelineData/work/"+e,{method:"PATCH",body:JSON.stringify(a),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 a={};a.title=document.querySelector(`#title${e}proj`).value,a.isMainProject=document.querySelector(`#isMainProject${e}proj`).checked?"true":"false",a.information=document.querySelector(`#info${e}proj`).value,a.projectLink=document.querySelector(`#viewProj${e}proj`).value,a.gitLink=document.querySelector(`#git${e}proj`).value;let l=new FormData;l.append("img",document.querySelector(`#img${e}proj`).files[0]),fetch("/api/projectData/"+e,{method:"PATCH",body:JSON.stringify(a),headers:{"Content-Type":"application/json",Authorization:"Bearer "+localStorage.getItem("token")}}).then((t=>{if(t.ok)return"undefined"===l.get("img")?("true"===a.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}proj`).setAttribute("disabled",""),void document.querySelector(`#info${e}proj`).setAttribute("disabled","")):(console.log("updating image"),fetch("/api/projectImage/"+e,{method:"POST",body:l,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((a=>{if(t.ok)return"true"===a.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}proj`).setAttribute("disabled",""),document.querySelector(`#info${e}proj`).setAttribute("disabled",""),void(document.querySelector(`#projectImage${e}`).src=a.imgLocation);401!==t.status?(document.querySelector(`#projError${e}`).classList.remove("hidden"),document.querySelector(`#projError${e} div`).innerHTML=a.error):window.location.href="./"}))))}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,a,l,o,n,r){let i=document.createElement("form"),d=e+"proj";if(i.id="projectItem"+e,i.classList.add("projItem"),i.onsubmit=t=>updateProjectItem(e,t),i.innerHTML=`\n <div class="modifyBtnContainer">\n <button class="edit" type="button" id="edit${d}" onclick="editProjectItem(${e})"><i class="fa-solid fa-pen-to-square"></i></button>\n <button class="delete" type="button" id="delete${d}" onclick="deleteProjectItem(${e})"><i class="fa-solid fa-trash"></i></button>\n </div>\n <img class="displayedImage" id="projectImage${d}" src="${a}" alt="image preivew of the project">\n <div class="formControl imageContainer">\n <input type="file" name="img${d}" id="img${d}">\n </div>\n <div class="formControl projectTitleContainer">\n <input type="text" name="title${d}" id="title${d}" value="${l}" disabled>\n </div>\n <div class="formControl isMainProject">\n <label class="checkContainer" for="isMainProject${d}">Is It The Main Project\n <input type="checkbox" id="isMainProject${d}" name="isMainProject${d}" ${"true"===t?"checked=''":""}>\n <span class="checkmark"></span>\n </label>\n </div>\n <div class="formControl infoContainer">\n <textarea name="info${d}" id="info${d}" disabled>${o}</textarea>\n </div>\n <div class="formControl viewProjContainer">\n <input type="text" name="viewProj${d}" id="viewProj${d}" value="${n}">\n </div> \n <div class="formControl gitContainer">\n <input type="text" name="git${d}" id="git${d}" value="${r}">\n </div> \n <div class="error hidden" id="projError${d}">\n <button class="close" type="button" onclick="this.parentElement.classList.toggle('hidden');">&times;</button>\n <div></div>\n </div>\n <input type="submit" value="Change">\n <div class="linkContainer">\n <a href="${"N/A"===n?"#":n}" class="btn btnPrimary boxShadowIn boxShadowOut"${"N/A"===n?'disabled="disabled"':""}>View Project</a>\n <a href="${"N/A"===r?"#":r}" class="btn btnOutline boxShadowIn boxShadowOut">${"N/A"===r?'disabled="disabled"':""}Git</a>\n </div>\n `,"true"===t)return document.querySelectorAll(".isMainProject input").forEach((e=>e.checked=!1)),void document.querySelector("#projList").prepend(i);document.querySelector("#projList").appendChild(i)}function deletePostItem(e){fetch("/api/blog/post/"+e,{method:"DELETE",headers:{Authorization:"Bearer "+localStorage.getItem("token")}}).then((t=>{t.ok?document.querySelector(`#postInfo${e}`).remove():401!==t.status?t.json().then((e=>alert(e.error))):window.location.href="./"}))}function addPostInfo(e,t,a,l){let o=document.createElement("tr"),n=e+"post";o.id="postInfo"+e,o.innerHTML=`\n <td>\n ${t}\n </td>\n <td>\n ${new Date(a).toLocaleDateString()}\n </td>\n <td>\n ${new Date(l).toLocaleDateString()}\n </td>\n <td>\n <button class="edit" type="button" id="edit${n}" onclick="editPostItem(${e})"><i class="fa-solid fa-pen-to-square"></i></button>\n <button class="delete" type="button" id="delete${n}" onclick="deletePostItem(${e})"><i class="fa-solid fa-trash"></i></button>\n </td>\n `,document.querySelector("#editPost table tbody").appendChild(o)}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<t.length;e++)addEduData(t[e].ID,t[e].startPeriod,t[e].endPeriod,t[e].grade,t[e].course);else document.querySelector("#edu").innerHTML="No education data found"})))),fetch("/api/timelineData/work").then((e=>e.json().then((t=>{if(e.ok)for(let e=0;e<t.length;e++){let a="0000-00-00"===t[e].endPeriod?"Present":t[e].endPeriod;addWorkData(t[e].ID,t[e].startPeriod,a,t[e].companyName,t[e].area,t[e].title)}else document.querySelector("#edu").innerHTML="No education data found"})))),fetch("/api/projectData").then((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"})))),fetch("/api/blog/post").then((e=>e.json().then((t=>{e.ok&&(posts=t,t.forEach((e=>{addPostInfo(e.ID,e.title,e.dateCreated,e.dateModified)})))})))),createEditors("CKEditorAddPost","CKEditorEditPost","CKEditorNewsletter")})),document.querySelector("body").addEventListener("click",(()=>{if(textareaLoaded)return;const e=document.querySelectorAll("main.editor textarea");for(let t=0;t<e.length;t++)console.log("height: "+e[t].scrollHeight+"px"),e[t].setAttribute("style","height:"+e[t].scrollHeight+"px;overflow-y:hidden;"),e[t].oninput=e=>{e.target.style.height="0",e.target.style.height=e.target.scrollHeight+15+"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((a=>{if(e.ok)return addEduData(a.ID,t.get("dateFrom"),t.get("dateTo"),t.get("grade"),t.get("course"),!0),void document.querySelector("#addEdu").reset();401!==e.status?showErrorMessage(a.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((a=>{if(e.ok){let e=""===t.get("dateTo")?"Present":t.get("dateTo ");return addWorkData(a.ID,t.get("dateFrom"),e,t.get("companyName"),t.get("area"),t.get("title"),!0),void document.querySelector("#addWork").reset()}401!==e.status?showErrorMessage(a.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 a=new FormData;a.append("img",document.querySelector("#projImg").files[0]);let l=0;fetch("/api/projectData",{method:"POST",body:t,headers:{Authorization:"Bearer "+localStorage.getItem("token")}}).then((e=>e.json().then((o=>{if(e.ok)return"undefined"===a.get("img")?(addProject(o.ID,t.get("isMainProject"),"../imgs/placeholder.png",t.get("title"),t.get("information"),t.get("projectLink"),t.get("gitLink")),void document.querySelector("#addProj").reset()):(l=o.ID,fetch("/api/projectImage/"+o.ID,{method:"POST",body:a,headers:{Authorization:"Bearer "+localStorage.getItem("token")}}));401!==e.status?showErrorMessage(o.error,"proj"):window.location.href="./"})).then((e=>e.json().then((a=>{if(e.ok)return addProject(l,t.get("isMainProject"),a.imgLocation,t.get("title"),t.get("information"),t.get("projectLink"),t.get("gitLink")),void document.querySelector("#addProj").reset();401!==e.status?showErrorMessage(a.error,"proj"):window.location.href="./"}))))))})),document.querySelector("#addPostForm").addEventListener("submit",(e=>{if(e.preventDefault(),""===editors.CKEditorAddPost.getData())return void showErrorMessage("Post body cannot be empty","addPost");let t=new FormData;t.append("title",document.querySelector("#postTitle").value),t.append("featured",document.querySelector("#isFeatured").checked?"1":"0"),t.append("abstract",document.querySelector("#postAbstract").value),t.append("body",editors.CKEditorAddPost.getData()),t.append("bodyText",viewToPlainText(editors.CKEditorAddPost.editing.view.document.getRoot())),t.append("dateCreated",(new Date).toISOString().slice(0,19).replace("T"," ")),t.append("categories",document.querySelector("#postCategories").value.toLowerCase()),t.append("headerImg",document.querySelector("#headerImg").files[0]),fetch("/api/blog/post",{method:"POST",body:t,headers:{Authorization:"Bearer "+localStorage.getItem("token")}}).then((e=>e.json().then((a=>{if(e.ok)return document.querySelector("#addPostForm").reset(),editors.CKEditorAddPost.setData(""),addPostInfo(a.ID,t.get("title"),t.get("dateCreated"),t.get("dateModified")),void showSuccessMessage("Post added successfully","addPost");401!==e.status?e.json().then((e=>showErrorMessage(e.error,"addPost"))):window.location.href="./"}))))})),document.querySelector("#editPostForm").addEventListener("submit",(e=>{e.preventDefault();let t=document.querySelector("#editPostForm input[type='submit']").id;if(""===t)return void showErrorMessage("Currently not editing any post","editPost");if(""===editors.CKEditorEditPost.getData())return void showErrorMessage("Post body cannot be empty","editPost");let a={};a.title=document.querySelector("#editPostTitle").value,a.featured=document.querySelector("#editIsFeatured").checked?"1":"0",a.abstract=document.querySelector("#editPostAbstract").value,a.body=editors.CKEditorEditPost.getData(),a.bodyText=viewToPlainText(editors.CKEditorEditPost.editing.view.document.getRoot()),a.dateModified=(new Date).toISOString().slice(0,19).replace("T"," "),a.categories=document.querySelector("#editPostCategories").value.toLowerCase();let l=new FormData;l.append("headerImg",document.querySelector("#editHeaderImg").files[0]),fetch("/api/blog/post/"+t,{method:"PATCH",body:JSON.stringify(a),headers:{"Content-Type":"application/json",Authorization:"Bearer "+localStorage.getItem("token")}}).then((e=>{if(e.ok)return"undefined"===l.get("headerImg")?(document.querySelector("#editPostForm").reset(),document.querySelector("#editPostForm input[type='submit']").id="",editors.CKEditorEditPost.setData(""),void showSuccessMessage("Post edited successfully","editPost")):fetch("/api/blog/headerImage/"+t,{method:"POST",body:l,headers:{Authorization:"Bearer "+localStorage.getItem("token")}});401!==e.status?e.json().then((e=>showErrorMessage(e.error,"editPost"))):window.location.href="./"})).then((e=>e.json().then((t=>{if(e.ok)return document.querySelector("#editPostForm").reset(),document.querySelector("#editPostForm input[type='submit']").id="",console.log(),editors.CKEditorEditPost.setData(""),void showSuccessMessage("Post edited successfully","editPost");401!==e.status?showErrorMessage(t.error,"editPost"):window.location.href="./"}))))})),document.querySelector("#sendNewsletterForm").addEventListener("submit",(e=>{e.preventDefault();let t=new FormData;t.append("subject",document.querySelector("#newsletterSubject").value),t.append("message",editors.CKEditorNewsletter.getData()),fetch("/api/blog/newsletter",{method:"POST",body:t,headers:{Authorization:"Bearer "+localStorage.getItem("token")}}).then((e=>e.json().then((t=>{if(e.ok)return document.querySelector("#sendNewsletterForm").reset(),editors.CKEditorNewsletter.setData(""),void showSuccessMessage("Newsletter sent successfully","newsletter");401!==e.status?showErrorMessage(t.error,"newsletter"):window.location.href="./"}))))})),document.querySelector("#goToCV").addEventListener("click",(()=>{textareaLoaded=!1,addActiveClass("goToCV"),goToPage("curriculumVitae")})),document.querySelector("#goToProjects").addEventListener("click",(()=>{textareaLoaded=!1,addActiveClass("goToProjects"),goToPage("projects")})),document.querySelector("#blog").addEventListener("click",(()=>{document.querySelector("nav.sideNav ul li.dropdown ul").classList.toggle("active"),document.querySelector("#blog i.fa").classList.toggle("fa-caret-down"),document.querySelector("#blog i.fa").classList.toggle("fa-caret-right")})),document.querySelector("#goToAddPost").addEventListener("click",(()=>{textareaLoaded=!1,addActiveClass("goToAddPost"),goToPage("addPost"),document.querySelector("#blog").classList.add("active")})),document.querySelector("#goToEditPost").addEventListener("click",(()=>{textareaLoaded=!1,addActiveClass("goToEditPost"),goToPage("editPost"),document.querySelector("#blog").classList.add("active")})),document.querySelector("#goToNewsletter").addEventListener("click",(()=>{textareaLoaded=!1,addActiveClass("goToNewsletter"),goToPage("newsletter")})),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"))),document.querySelector("#addPostError .close").addEventListener("click",(()=>document.querySelector("#addPostError").classList.toggle("hidden"))),document.querySelector("#addPostSuccess .close").addEventListener("click",(()=>document.querySelector("#addPostSuccess").classList.toggle("hidden"))),document.querySelector("#editPostError .close").addEventListener("click",(()=>document.querySelector("#editPostError").classList.toggle("hidden"))),document.querySelector("#editPostSuccess .close").addEventListener("click",(()=>document.querySelector("#editPostSuccess").classList.toggle("hidden")));