diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 0000000..8b314a5 Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/script.js b/assets/script.js index c97215d..c68b6ec 100644 --- a/assets/script.js +++ b/assets/script.js @@ -1,4 +1,33 @@ -let UserInfo; +let UserInfo = {}; +async function handleResponse(data, successMessage, failureMessage) { + const statusMessageContainer = document.getElementById("statusMessageContainer"); + + const statusMessage = document.createElement("div"); + statusMessage.classList.add("status-message"); + + if (data.Status === 'Success') { + statusMessage.innerText = successMessage; + statusMessage.classList.add("success"); + } else { + statusMessage.innerText = failureMessage; + statusMessage.classList.add("failure"); + } + + statusMessageContainer.appendChild(statusMessage); + + // Automatically remove the message after 3 seconds + setTimeout(() => { + statusMessage.style.opacity = "0"; + setTimeout(() => { + statusMessage.remove(); + }, 500); + }, 2000); +} + +async function showDashboardGreeting() { + document.getElementById("welcomeMsg").innerText = `Ahoj, ${UserInfo.FirstName}.`; +} + async function doAction(url, requestData, successMessage, failureMessage, silent = false) { try { const params = new URLSearchParams(); @@ -13,13 +42,13 @@ async function doAction(url, requestData, successMessage, failureMessage, silent }); if (!response.ok) { - throw new Error(`HTTP error! Status: ${response.status}`); + console.error(`HTTP error! Status: ${response.status}`); } const data = await response.json(); if (!silent) { - handleResponse(data, successMessage, failureMessage); + await handleResponse(data, successMessage, failureMessage); } return data; @@ -28,9 +57,9 @@ async function doAction(url, requestData, successMessage, failureMessage, silent } } -function handlePageResponse(data) { - const navbar = document.getElementById("navbar"); - const pageArea = document.getElementById("pagearea"); +async function handlePageResponse(data) { + const navbar = document.getElementById("navbar_container"); + const pageArea = document.getElementById("page_container"); if (data.Navigation) { navbar.innerHTML = data.Navigation; @@ -44,7 +73,7 @@ function handlePageResponse(data) { } } -function displayList(data, elementId, deleteFunction) { +async function displayList(data, elementId, deleteFunction) { const tableContainer = document.getElementById(elementId); tableContainer.innerHTML = ""; // Clear previous content @@ -92,11 +121,11 @@ async function doPageAction(requestData, wantsReturn = false) { }); if (!response.ok) { - throw new Error(`HTTP error! Status: ${response.status}`); + console.error(`HTTP error! Status: ${response.status}`); } const data = await response.json(); - handlePageResponse(data); + await handlePageResponse(data); if (wantsReturn) { return data; } @@ -105,7 +134,7 @@ async function doPageAction(requestData, wantsReturn = false) { } } -function initAjax() { +async function initAjax() { const links = document.querySelectorAll('.navsite_link, .navpage_link'); links.forEach(function (link) { @@ -118,26 +147,36 @@ function initAjax() { } }); }); - onPageLoad(); + const toggleButton = document.getElementById("toggle_button") + const navLinks = document.getElementById("navsite_list") + + toggleButton.addEventListener('click', () => { + navLinks.classList.toggle("active") + }) + await onPageLoad(); } document.addEventListener('DOMContentLoaded', initAjax); -function onPageLoad(){ +async function onPageLoad(){ + await restoreUserInfo(); let currentSite = localStorage.getItem("currentSite"); let currentPage = localStorage.getItem("currentPage"); if(currentSite === "home" && currentPage === "settings"){ if(document.getElementById("user-settings")){ - getUserInfo(); + await populateUserInfoFields(UserInfo); } if(document.getElementById("admin-settings")){ - listActivationCodes(); - listUsers(); + await listActivationCodes(true); + await listUsers(true); } } + if(currentSite === "home" && currentPage === "account") { + await showDashboardGreeting(); + } } -function navigateTo(site, page){ +async function navigateTo(site, page){ const data = { action: "getPage", site: site, @@ -150,39 +189,46 @@ function navigateTo(site, page){ }); } -function softReload(){ +async function softReload(){ let currentSite = localStorage.getItem("currentSite"); let currentPage = localStorage.getItem("currentPage"); - navigateTo(currentSite, currentPage); + await navigateTo(currentSite, currentPage); umami.track("softReload"); } -function refreshNavbar(){ +async function refreshNavbar(){ const data = { action: "getNavigation", }; - doPageAction(data); + await doPageAction(data); umami.track("refreshNavbar"); } -function logout() { +async function logout() { const data = { action: "logout", }; - doAction('/account', data, "Logout Successful!", "Logout failed.").then(() => { - refreshNavbar(); - navigateTo("", localStorage.getItem("defaultPage")); - umami.track("logout"); - }); + doAction('/account', data, "Logout Successful!", "Logout failed.") + .then(async () => { + await refreshNavbar(); + await navigateTo(localStorage.getItem("defaultSite"), localStorage.getItem("defaultPage")); + localStorage.clear(); + umami.track("logout"); + }) + .catch((error) => { + // Handle errors if needed + console.error("An error occurred during logout:", error); + }); } -function login() { +async function login() { const email = document.getElementById("login_email").value; const password = document.getElementById("login_password").value; - doLogin(email, password); - refreshNavbar(); - softReload(); + await doLogin(email, password); + await getUserInfo(); + await refreshNavbar(); + await softReload(); } async function doLogin(email, password) { @@ -196,7 +242,7 @@ async function doLogin(email, password) { umami.track("login"); } -function register() { +async function register() { const firstName = document.getElementById("register_firstName").value; const lastName = document.getElementById("register_lastName").value; const email = document.getElementById("register_email").value; @@ -212,7 +258,7 @@ function register() { activation_token: activationToken, }; - doRegister(data); + await doRegister(data); } async function doRegister(requestData) { @@ -222,7 +268,7 @@ async function doRegister(requestData) { //User settings start -function changePassword() { +async function changePassword() { const oldPassword = document.getElementById("changeOldPassword").value; const newPassword = document.getElementById("changeNewPassword").value; @@ -232,7 +278,7 @@ function changePassword() { new_password: newPassword, }; - doChangePassword(data, "Password change Successful!", "Password change failed."); + await doChangePassword(data, "Password change Successful!", "Password change failed."); } async function doChangePassword(requestData, successMessage, failureMessage) { @@ -240,7 +286,7 @@ async function doChangePassword(requestData, successMessage, failureMessage) { umami.track("passwordChange"); } -function updateUserProfile() { +async function updateUserProfile() { const firstName = document.getElementById("updateFirstName").value; const lastName = document.getElementById("updateLastName").value; const nickname = document.getElementById("updateNickname").value; @@ -254,11 +300,11 @@ function updateUserProfile() { minecraft_nick: minecraftNick, }; - doAction('/account', data, "Profile update Successful!", "Profile update failed."); + await doAction('/account', data, "Profile update Successful!", "Profile update failed."); umami.track("updateUserProfile"); } -function updateEmail() { +async function updateEmail() { const newEmail = document.getElementById("updateNewEmail").value; const data = { @@ -266,11 +312,11 @@ function updateEmail() { email: newEmail, }; - doAction('/account', data, "Email update Successful!", "Email update failed."); + await doAction('/account', data, "Email update Successful!", "Email update failed."); umami.track("updateEmail"); } -function populateUserInfoFields(userData) { +async function populateUserInfoFields(userData) { document.getElementById("updateFirstName").value = userData.FirstName || ""; document.getElementById("updateLastName").value = userData.LastName || ""; document.getElementById("updateNickname").value = userData.Nickname || ""; @@ -278,24 +324,36 @@ function populateUserInfoFields(userData) { document.getElementById("updateNewEmail").value = userData.Email || ""; } -function getUserInfo() { +async function restoreUserInfo(){ + for (let i = 0; i < localStorage.length; i++) { + let key = localStorage.key(i); + if (key.startsWith("UserInfo_")){ + let keyClean = key.replace("UserInfo_", ""); + UserInfo[keyClean] = localStorage.getItem(key); + } + } +} + +async function getUserInfo() { const data = { action: "get_user_info", }; - const result = doAction('/account', data, "User info retrieved Successfully!", "User info retrieval failed.", true); - - if (result && result.Status === "Success") { - populateUserInfoFields(result.UserInfo); - UserInfo = result.UserInfo; - } + doAction('/account', data, "User info retrieved Successfully!", "User info retrieval failed.", true) .then((result) => { + if (result && result.Status === "Success") { + result.UserInfo.forEach(function callback(value, index) { + localStorage.setItem("UserInfo_" + index, value); + UserInfo[index] = value; + }); + } + }); } //User settings end //Admin settings start -function addActivationCodes() { +async function addActivationCodes() { const count = document.getElementById("activationCodeCount").value; const data = { @@ -303,53 +361,54 @@ function addActivationCodes() { count: count, }; - const result = doAction('/account', data, "Activation codes added Successfully!", "Activation codes addition failed."); - - displayList(result.ActivationCodes, "codeListTable", deleteActivationCode); - umami.track("addActivationCodes"); + doAction('/account', data, "Activation codes added Successfully!", "Activation codes addition failed.").then((result) => { + displayList(result.ActivationCodes, "codeListTable", deleteActivationCode); + umami.track("addActivationCodes"); + }); } -function listUsers() { +async function listUsers(silent=false) { const data = { action: "list_users", }; - const result = doAction('/account', data, "User list retrieved Successfully!", "User list retrieval failed."); + doAction('/account', data, "User list retrieved Successfully!", "User list retrieval failed.", silent).then((result) => { - if (result && result.Status === "Success") { - displayList(result.Users, "userListTable", deleteUser); - } + if (result && result.Status === "Success") { + displayList(result.Users, "userListTable", deleteUser); + } + }); } -function listActivationCodes() { +async function listActivationCodes(silent=false) { const data = { action: "list_activation_codes", }; - const result = doAction('/account', data, "Activation code list retrieved Successfully!", "Activation code list retrieval failed."); - - displayList(result.ActivationCodes, "codeListTable", deleteActivationCode); + doAction('/account', data, "Activation code list retrieved Successfully!", "Activation code list retrieval failed.", silent).then((result) => { + displayList(result.ActivationCodes, "codeListTable", deleteActivationCode); + }); } -function deleteUser(userId) { +async function deleteUser(userId) { const data = { action: "delete_user", user_id: userId, }; - doAction('/account', data, "User deleted Successfully!", "User deletion failed."); - listUsers(); + await doAction('/account', data, "User deleted Successfully!", "User deletion failed."); + await listUsers(); umami.track("deleteUser"); } -function deleteActivationCode(activationCode) { +async function deleteActivationCode(activationCode) { const data = { action: "delete_activation_code", activation_code: activationCode, }; - doAction('/account', data, "Activation code deleted Successfully!", "Activation code deletion failed."); - listActivationCodes(); + await doAction('/account', data, "Activation code deleted Successfully!", "Activation code deletion failed."); + await listActivationCodes(); umami.track("deleteActivationCode"); } //Admin settings end diff --git a/assets/style.css b/assets/style.css index f84989a..84a0b4e 100644 --- a/assets/style.css +++ b/assets/style.css @@ -1,274 +1,339 @@ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700;800&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap'); -:root { - --primary-bg: rgb(27, 21, 41); - --secondary-bg: #1a1a1a; - --third-bg: #383838; - --primary-text: #d2d6e5; - --error: rgb(255, 55, 0); - --primary: #2a9dd6; - --primary-hover: #2489bb; +.dashboard +{ + height:100%; + text-align:center; + width:100%; } -body { - background: linear-gradient(127deg, var(--secondary-bg), var(--primary-bg)) no-repeat fixed; - background-size: cover; - height: 100%; +:root +{ + --error:#ff3700; + --primary:#2a9dd6; + --primary-bg:#1b1529; + --primary-hover:#2489bb; + --primary-text:#d2d6e5; + --secondary-bg:#1a1a1a; + --third-bg:#383838; +} + +body +{ + align-items:center; + background:linear-gradient(127deg,var(--secondary-bg), var(--primary-bg)) no-repeat fixed; + background-size:cover; + color:var(--primary-text); + display:flex; + flex-direction:column; + font-family:\'Poppins\', sans-serif; + height:100%; + margin:0; + min-height:100vh; + min-width:100vw; + padding:0; + width:100%; +} + +header h1 +{ + margin:0; + padding:0; +} + +header hr +{ + border-color:var(--primary); + opacity:0.5; + width:30%; +} + +header ul li +{ + list-style:circle; + width:fit-content; +} + +header ul +{ + display:flex; + flex-direction:column; + gap:0; + text-align:left; + width:fit-content; +} + +header +{ + align-items:center; + text-align:center; + width:100%; +} + +li a +{ + color:var(--primary-text); + padding-bottom:.45rem; + position:relative; + text-decoration:none; + transition:all .3s ease; +} + +li a:hover::after +{ + margin:0 auto; + width:85%; +} + +li +{ + list-style:none; +} + +li.navpage_item +{ + padding-left:20px; + padding-right:20px; +} + +nav +{ + display:flex; + flex-direction:row; + justify-content:space-between; + height: 55px; +} + +nav,footer +{ + -moz-box-shadow:0 20px 28px 0 rgba(0,0,0,0.6); + -webkit-box-shadow:0 20px 28px 0 rgba(0,0,0,0.6); + background-color:rgba(0,0,0,0.6); + box-shadow:0 20px 28px 0 rgba(0,0,0,0.6); + padding:1.2rem 1rem; +} + +table.list-table > tbody,table.list-table > tbody > th,table.list-table > tbody > tr,table.list-table > tbody > tr > td +{ + border:2px solid var(--primary); + border-collapse:collapse; +} + +ul +{ + display:flex; + flex-direction:row; + gap:2.5rem; + list-style:none; + padding-left:0; +} + +ul.navpage_list +{ + gap:10px; + background-color:var(--third-bg); + border:0 solid transparent; + display:none; + flex-direction:column; + max-height:0; + overflow:hidden; + position:fixed; + transition:max-height .3s ease, border .325s ease; + z-index:2; +} + +.back +{ + background-color:#2a9dd6; + border-radius:15px; + color:var(--primary-text); + padding:.35rem .65rem; + text-decoration:none; + transition:all .3s ease; +} + +.back:hover +{ + background-color:var(--primary-hover); + transition:all .3s ease; +} + +.feature-list +{ + display:block; + margin:auto; + width:fit-content; +} + +.feature-list-ul ul +{ + margin: 5px auto auto 20px; +} + +.navsite_item +{ + align-items:center; + justify-content:center; + text-align:center; + width:120px; +} + +.navsite_item:hover .navpage_list +{ + border:4px solid var(--primary-hover); + display:flex!important; + max-height:200px; +} + +.navsite_item:not(:hover) .navpage_list +{ + border:0 solid transparent; + max-height:0; + transition-delay:.1s; +} +#navsite_list, .navsite_list +{ + display:flex; + flex-direction:row; width: 100%; - font-family: 'Poppins', sans-serif; - color: var(--primary-text); - margin: 0; - padding: 0; - min-height: 100vh; - min-width: 100vw; - display: flex; - flex-direction: column; - align-items: center; + gap:3.25rem; } -nav { - display: flex; - flex-direction: row; - justify-content: space-between; -} - -ul { - display: flex; - flex-direction: row; - gap: 2.5rem; - list-style: none; - padding-left: 0; -} - -li { - list-style: none; -} - -li a { - position: relative; - padding-bottom: 0.45rem; - color: var(--primary-text); - text-decoration: none; - transition: all 0.3s ease; -} - -/*li a::after { - content: ""; +#toggle_button { position: absolute; - height: 4px; - width: 0; - bottom: 0; - left: 0; - background-color: var(--primary); - transition: all 0.3s ease; - border-radius: 15px; -}*/ - -li a:hover::after { - width: 85%; - margin: 0 auto; -} - -.wrapper-40x { - text-align: center; -} - -.wrapper-40x h1 { - font-size: 10rem; - margin: 0; -} - -.wrapper-40x .error { - color: var(--error); -} - -.wrapper-40x h3 { - margin-bottom: 2rem; -} - -.error-code { - color: var(--primary); -} - -.back { - color: var(--primary-text); - text-decoration: none; - background-color: #2a9dd6; - padding: 0.35rem 0.65rem; - transition: all 0.3s ease; - border-radius: 15px; -} - -.back:hover { - transition: all 0.3s ease; - background-color: var(--primary-hover); -} - -header { - width: 100%; - align-items: center; - text-align: center; -} -header h1 { - margin: 0; - padding: 0; -} -header a { - color: var(--primary); -} - -header hr { - border-color: var(--primary); - opacity: 0.5; - width: 30%; -} - -.navsite_list{ - display: flex; - flex-direction: row; - gap: 3.25rem; -} -.navpage_list{ + right: 1.5rem; display: none; flex-direction: column; + justify-content: space-between; + width: 2rem; + height: 1.5rem; } -.navsite_item { - justify-content: center; - align-items: center; - text-align: center; - width: 120px; +@media (max-width: 1050px) { + #toggle_button { + display: flex; + } + #navsite_list { + display: none; + position: fixed; + flex-direction: column; + width: 100%; + } + + #navsite_list li { + text-align: center; + width: 100%; + } + + #navsite_list.active { + display: flex; + -moz-box-shadow:0 20px 28px 0 rgba(0,0,0,0.6); + -webkit-box-shadow:0 20px 28px 0 rgba(0,0,0,0.6); + background-color:rgba(0,0,0,0.6); + box-shadow:0 20px 28px 0 rgba(0,0,0,0.6); + top: 80px; + width: 100%; + } + + nav { + flex-direction: column; + align-items: center; + background-color: rgba(0,0,0,0.6); + } } -.navsite_item:hover .navpage_list{ - display: flex !important; -} - - -.navpage_list { - background-color: var(--third-bg); - margin-top: 10px; - display: flex; - flex-direction: column; - overflow: hidden; - max-height: 0; - border: 0 solid transparent; - transition: max-height 0.3s ease, border 0.325s ease; - position: relative; - z-index: 999; -} - -.navsite_item:hover .navpage_list { - max-height: 200px; - border: 4px solid var(--primary-hover); -} - -.navsite_item:not(:hover) .navpage_list { - max-height: 0; - border: 0 solid transparent; - transition-delay: 0.1s; -} - - -li.navpage_item{ - padding-left: 20px; - padding-right: 20px; -} - -ul.navpage_list{ - gap: 10px; -} - -header ul { - display: flex; - flex-direction: column; - gap: 0; - text-align: left; - width: fit-content; -} -header ul li { - list-style: circle; - width: fit-content; -} - -.feature-list { - margin: auto; - width: fit-content; - display: block; -} - -.feature-list-ul { - margin: auto; -} - -.feature-list-ul ul { - margin-top: 5px; - margin-left: 20px; -} - -#StatusMessage { - display: none; +#statusMessageContainer{ position: fixed; - top: 20px; + top: 80px; right: 20px; - padding: 10px; - background-color: var(--third-bg); - color: var(--primary-text); - border-radius: 5px; - opacity: 0; + z-index: 510; + display: flex; + flex-direction: column; +} + +.status-message { + background-color: #dff0d8; /* Success background color */ + border: 1px solid #3c763d; /* Success border color */ + color: #3c763d; /* Success text color */ + padding: 15px; + margin-bottom: 10px; + opacity: 1; transition: opacity 0.5s ease-in-out; } -table.list-table > tbody, table.list-table > tbody > th, table.list-table > tbody > tr, table.list-table > tbody > tr > td { +.status-message.failure { + background-color: #f2dede; /* Failure background color */ + border: 1px solid #a94442; /* Failure border color */ + color: #a94442; /* Failure text color */ +} + +.wrapper-40x .error +{ + color:var(--error); +} + +.wrapper-40x h1 +{ + font-size:10rem; + margin:0; +} + +.wrapper-40x h3 +{ + margin-bottom:2rem; +} + +.wrapper-40x +{ + text-align:center; +} + +#navbar_container +{ + position:relative; + z-index:500; +} + +#navbar_container,#page_container,#footer_container +{ + width:100%; +} + +#page_container +{ + flex-grow:1; +} + +header a,.error-code +{ + color:var(--primary); +} + +input +{ + background-color: var(--third-bg); + border:2px solid var(--primary); + border-radius:50px; +} + +button{ + border-radius: 50px; border: 2px solid var(--primary); - border-collapse: collapse; + background: var(--third-bg); + color: var(--primary-text); + width: 175px; + transition-duration: 0.3s; } -/* */ -/* ZAČÍNAJ VŠETKO S ".dashboard" */ - - -.dashboard { - width: 100%; - height: 100%; - text-align: center; +button:hover { + background: var(--primary); + transition-duration: 0.3s; } -/* */ - -#loginForm input { +.form-container input { border-radius: 50px; background: none; border: 2px solid var(--primary); width: 175px; -} - -#register_Form input { - border-radius: 50px; - background: none; - border: 2px solid var(--primary); - width: 175px; -} - -#pagearea { - flex-grow: 1; -} - -#navbar, #footer { - padding: 1.2rem 1rem; - background-color: rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 20px 28px 0 rgba(0,0,0,0.2); - -moz-box-shadow: 0 20px 28px 0 rgba(0,0,0,0.2); - box-shadow: 0 20px 28px 0 rgba(0,0,0,0.2); -} - -#navbar { - height: 75px !important; - position: relative; - z-index: 500; -} - -#navbar, #pagearea, #footer { - width: 100%; } \ No newline at end of file diff --git a/lib/page.php b/lib/page.php index e87139a..a9e8b91 100644 --- a/lib/page.php +++ b/lib/page.php @@ -104,6 +104,7 @@ function renderPage($page_name = null, $site_name = null): array } } + $page = str_replace("__DEFAULT_LINK__", "/" . $routerConfig["default_site"] . "/" . $routerConfig["default_page"], $page); if(!is_string($page)){ $page = ""; } @@ -136,12 +137,23 @@ function getPage($site_name_in = null, $page_name_in = null): string $page_title = $page_name; } $dynamic_style = doDynamicStyling(); - $dynamic_script = generateScriptData([ + $dynamic_script_data = [ "currentPage" => $page_name, "currentSite" => $site_name, "currentTitle" => $page_title, "defaultPage" => $routerConfig["default_page"], - ]); + "defaultSite" => $routerConfig["default_site"], + ]; + if(isLoggedIn()){ + $dynamic_script_data += [ + "UserInfo_FirstName" => $_SESSION["first_name"], + "UserInfo_LastName" => $_SESSION["last_name"], + "UserInfo_Nickname" => $_SESSION["nickname"], + "UserInfo_Email" => $_SESSION["email"], + "UserInfo_MinecraftNick" => $_SESSION["minecraft_nickname"], + ]; + } + $dynamic_script = generateScriptData($dynamic_script_data); $navigation = generateNavigation(); diff --git a/templates/403.html b/templates/403.html index 0ff5cdb..e208ec7 100644 --- a/templates/403.html +++ b/templates/403.html @@ -2,5 +2,5 @@

TY KÁR KAM TO DEŠ

403

Našli sme stránku ktorú hľadáš, ale nemáš práva na ňu pristupovať: __TEMPLATE_PAGE_TITLE__.

- SPÄŤ DOMOV + SPÄŤ DOMOV \ No newline at end of file diff --git a/templates/404.html b/templates/404.html index 6b355d6..b488f26 100644 --- a/templates/404.html +++ b/templates/404.html @@ -2,5 +2,5 @@

TY KÁR KAM TO DEŠ

404

Nenašli sme stránku ktorú hľadáš: __TEMPLATE_PAGE_TITLE__.

- SPÄŤ DOMOV + SPÄŤ DOMOV \ No newline at end of file diff --git a/templates/500.html b/templates/500.html index 065835a..7a8643b 100644 --- a/templates/500.html +++ b/templates/500.html @@ -2,5 +2,5 @@

Niekto to pobabral

500

Nejaký neschopný vývojár nevedel robiť túto stránku.

- SPÄŤ DOMOV + SPÄŤ DOMOV \ No newline at end of file diff --git a/templates/dashboard.html b/templates/dashboard.html index 80b1e75..f93b64c 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -1,19 +1,3 @@ - - -

\ No newline at end of file diff --git a/templates/footer.html b/templates/footer.html index f95b076..f4a3e6a 100644 --- a/templates/footer.html +++ b/templates/footer.html @@ -1 +1,3 @@ -

Toto nie je oficiálna stránka Adlerky, jedná sa o neoficiálnu študentskú stránku

\ No newline at end of file + \ No newline at end of file diff --git a/templates/nav.html b/templates/nav.html index 1f7b86d..9b91fe3 100644 --- a/templates/nav.html +++ b/templates/nav.html @@ -1,6 +1,7 @@ \ No newline at end of file diff --git a/templates/skeleton.html b/templates/skeleton.html index d01550c..054136a 100644 --- a/templates/skeleton.html +++ b/templates/skeleton.html @@ -5,6 +5,7 @@ + __TEMPLATE__DYNAMIC__SCRIPT__ __TEMPLATE__DYNAMIC__STYLE__ @@ -12,13 +13,14 @@ Adlerka __TEMPLATE_PAGE_TITLE__ -