This commit is contained in:
2025-03-21 17:15:55 +09:00
parent 97236619f0
commit 2175abbc80
18 changed files with 341 additions and 135 deletions
@@ -3384,4 +3384,59 @@ button.small,
text-align: left;
}
}
/*Login Popup*/
.login_overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 1000;
}
.login_popup {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: white;
padding: 20px;
border-radius: 5px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
}
.login_form {
display: none;
}
.login_form h2 {
margin-top: 0;
}
.login_form input {
display: block;
width: 100%;
margin-bottom: 10px;
padding: 5px;
}
/*.login_form button {*/
/* width: 100%;*/
/* padding: 10px;*/
/* background-color: #4CAF50;*/
/* color: white;*/
/* border: none;*/
/* cursor: pointer;*/
/*}*/
.login_close {
position: absolute;
top: 10px;
right: 10px;
font-size: 20px;
cursor: pointer;
}
+3 -3
View File
@@ -48,9 +48,9 @@
border-radius: 10px;
background: #00000044;
}
#title_field {
font-size: 20px;
}
/*#title_field {*/
/*font-size: 20px;*/
/*}*/
.pop_layer .pop_container {
padding: 20px 25px;
+1 -1
View File
@@ -167,4 +167,4 @@ footer {
height: 5vh;
min-height: 5vh;
position: relative;
}
}
+2 -2
View File
@@ -16,8 +16,8 @@ let baseData = {
'writeTime' : 0,
}
function goToEditor(path,id,sk) {
location.href = path + id+"?token="+sk;
function goToEditor(id) {
location.href = getMainPath() + '/blog/editor/' + id;
}
+103 -1
View File
@@ -1,4 +1,10 @@
document.addEventListener('DOMContentLoaded', function() {
const loginForm = document.getElementById('loginFormElement');
loginForm.addEventListener('submit', function(e) {
e.preventDefault(); // 기본 폼 제출 동작 방지
submitLoginForm();
});
});
onload = function() {
history.replaceState({}, null, location.pathname);
// var accToken = get_cookie("access")
@@ -8,6 +14,31 @@ onload = function() {
document.cookie = "access=; expires=Thu, 01 Jan 1970 00:00:01 GMT;"
document.cookie = "refresh=; expires=Thu, 01 Jan 1970 00:00:01 GMT;"
document.cookie = "CLEAR=; expires=Thu, 01 Jan 1970 00:00:01 GMT;"
var currentList = [{"page":["posts"],"id":"menu_posts"},{"page":["licenses"],"id":"menu_drop"},{"page":["licenses"],"id":"menu_drop"}]
if(location.pathname.length > 1) {
// 1. 모든 'current' 클래스를 가진 요소를 선택하고 제거
// const currentElements = document.querySelectorAll('.current');
// currentElements.forEach(element => {
// element.classList.remove('current');
// });
currentList.forEach(element => {
element.page.forEach((page, index) => {
console.log(location.pathname);
if (location.pathname.includes(page)) {
const targetElement = document.getElementById(element.id);
if (targetElement) {
targetElement.classList.add('current');
}
}
})
})
} else {
const targetElement = document.getElementById('menu_home');
if (targetElement) {
targetElement.classList.add('current');
}
}
}
// onbeforeunload = function () {
// var accToken = get_cookie("access")
@@ -260,4 +291,75 @@ function layer_popup(el){
function urldecode(t){
return decodeURI(t)
}
function openLoginPopup(formType) {
document.getElementById('overlay').style.display = 'block';
document.getElementById('loginForm').style.display = formType === 'login' ? 'block' : 'none';
document.getElementById('signupForm').style.display = formType === 'signup' ? 'block' : 'none';
if(formType === 'login') {
const loginIdInput = document.getElementById('loginId');
loginIdInput.focus();
}
}
function closePopup() {
document.getElementById('overlay').style.display = 'none';
}
//
// function submitForm(formType) {
// alert(formType === 'login' ? '로그인 시도' : '회원가입 시도');
// closePopup();
// }
function submitLoginForm() {
// const id = document.getElementById('loginId').value;
// const password = document.getElementById('loginPassword').value;
let user_id = document.getElementById('loginId')
let user_pw = document.getElementById('loginPassword')
let data = {
'user_id': user_id.value,
'user_pw': user_pw.value,
}
postLogin(getMainPath()+"/user/login.ajax",user_pw.data,JSON.stringify(data),user_pw.data, function (data) {
closePopup()
if (data.isOk) {
document.cookie = "access=" + data.token.split(";")[0]+";"
window.sessionStorage.setItem("REFRESH",data.refresh.split(";")[0])
document.location.replace(location.href)
} else {
if (data.resultCode === 7100) {
if(confirm(`너 누구임 정보 없는데?!\n${data.resultMsg}[${data.resultCode}]\n가입 할래!?`)){
document.location.replace(getMainPath() + "/user/join")
}
} else {
alert(`너 누구임?!\n${data.resultMsg}[${data.resultCode}]`)
}
}
})
// AJAX 요청
// fetch('/login', {
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// },
// body: JSON.stringify({ id, password }),
// })
// .then(response => response.json())
// .then(data => {
// if (data.success) {
// alert('로그인 성공!');
// // 로그인 성공 후 처리 (예: 페이지 리다이렉트)
// } else {
// alert('로그인 실패: ' + data.message);
// }
// })
// .catch(error => {
// console.error('Error:', error);
// alert('로그인 중 오류가 발생했습니다.');
// });
}
@@ -23,30 +23,19 @@
baseData.firstPostLon = [[${srcPost.firstPostLon}]];
baseData.writeTime = [[${srcPost.writeTime}]];
getLocation()
var style = getComputedStyle(document.body)
console.log(style.getPropertyValue('--ContentVerticalMargin'))
console.log(window.c)
console.log(style.getPropertyValue('--FooterHeight'))
console.log(style.getPropertyValue('--TopHeight'))
document.querySelector("#title_field").value = baseData.title
var editorHeght = (
document.querySelector('#main_layer').getBoundingClientRect().height -
(
Number(style.getPropertyValue('--ButtonHegit').replace("px","") * 3)
+ Number(style.getPropertyValue('--TopHeight').replace("px",""))
)
)
// var style = getComputedStyle(document.body)
// console.log(style.getPropertyValue('--ContentVerticalMargin'))
// console.log(window.c)
// console.log(style.getPropertyValue('--FooterHeight'))
// console.log(style.getPropertyValue('--TopHeight'))
editor = new toastui.Editor({
el: document.querySelector('#editor'),
previewStyle: 'tab',
height: editorHeght + 'px',
height: '900px',
width:'95%',
theme:'dark',
usageStatistics : false,
toolbar:null,
initialValue:baseData.content,
theme:"dark",
initialEditType:"wysiwyg",
hooks: {
addImageBlobHook: (blob, callback) => {
@@ -84,24 +73,32 @@
</script>
</th:block>
<th:block layout:fragment="content" id="content">
<div id="main_layer">
<section class="wrapper style2" >
<th:block th:if="${PERMISSION == 'OK'}">
<div class="container" >
<header class="major">
<h3><label for="title_field"><input id="title_field" th:value="${srcPost.title}"></label></h3>
<p th:text="${#temporals.format(T(java.time.Instant).ofEpochMilli(srcPost.writeTime).atZone(T(java.time.ZoneId).systemDefault()).toLocalDateTime(), 'yyyy-MM-dd HH:mm:ss')}"></p>
</header>
</div>
</th:block>
</section>
<section class="wrapper style2">
<th:block th:if="${PERMISSION != 'OK'}">
<h1>권한이 없는 뎁쇼?!</h1>
</th:block>
<th:block th:if="${PERMISSION == 'OK'}">
<label for="title_field"></label><input id="title_field" class="write_option">
<div id="editor" ></div>
<div class="write_controllbox">
<div class="write_option btn-example" to="#popLayer1" onclick="openPopup(this)" ></div>
<div class="write_option btn-example" to="#popLayer2" onclick="openPopup(this)" id="hashtag_field"></div>
<label for="location_field"></label><input class="write_option" readonly id="location_field"/>
</div>
<h1><button id="save" class="write_option" style="width: 100%; position: relative" onclick="save()">저장하셈</button></h1>
</th:block>
</div>
</section>
</th:block>
<th:block layout:fragment="popup_layer">
<div id="popLayer1" class="pop_layer">
@@ -14,17 +14,6 @@
let onChange = () => {console.log(editor.getMarkdown())}
document.addEventListener("DOMContentLoaded", onLoaded);
function onLoaded() {
// 1. 모든 'current' 클래스를 가진 요소를 선택하고 제거
const currentElements = document.querySelectorAll('.current');
currentElements.forEach(element => {
element.classList.remove('current');
});
// 2. 특정 조건에 맞는 요소에 'current' 클래스 추가 (예: ID가 'targetElement'인 요소)
const targetElement = document.getElementById('menu_posts');
if (targetElement) {
targetElement.classList.add('current');
}
}
</script>
@@ -65,30 +54,16 @@
<div class="col-6 col-12-narrower imp-narrower">
<div id="content">
<article>
<header>
<h2>Two Sidebar</h2>
<p>Yup. Two sidebars at the same time.</p>
</header>
<span class="image featured"><img src="images/banner.jpg" alt="" /></span>
<p>Phasellus quam turpis, feugiat sit amet ornare in, hendrerit in lectus.
Praesent semper mod quis eget mi. Etiam eu ante risus. Aliquam erat volutpat.
Aliquam luctus et mattis lectus sit amet pulvinar. Nam turpis nisi
consequat etiam lorem ipsum dolor sit amet nullam.</p>
<h3>And Yet Another Subheading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas ac quam risus, at tempus
justo. Sed dictum rutrum massa eu volutpat. Quisque vitae hendrerit sem. Pellentesque lorem felis,
ultricies a bibendum id, bibendum sit amet nisl. Mauris et lorem quam. Maecenas rutrum imperdiet
rhoncus dui quis euismod. Maecenas lorem tellus, congue et condimentum ac, ullamcorper non sapien.
Donec sagittis massa et leo semper a scelerisque metus faucibus. Morbi congue mattis mi.
Phasellus sed nisl vitae risus tristique volutpat. Cras rutrum commodo luctus.</p>
<p>Phasellus odio risus, faucibus et viverra vitae, eleifend ac purus. Praesent mattis, enim
quis hendrerit porttitor, sapien tortor viverra magna, sit amet rhoncus nisl lacus nec arcu.
Maecenas tortor mauris, consectetur pellentesque dapibus eget, tincidunt vitae arcu.
Vestibulum purus augue, tincidunt sit amet iaculis id, porta eu purus.</p>
<section class="col-6 col-12-narrower imp-narrower" th:each="post : ${Posts}">
<!-- <span th:text="${cell}"></span>-->
<div class="box post" onclick="goToViewer(this)" th:data="${post.id}">
<a href="#" class="image left"><img th:src="${#strings.length(post.image) > 0} ? ${post.image} : 'images/pic01.jpg'" alt="" /></a>
<div class="inner">
<h3 th:text="${#strings.length(post.title) > 0} ? ${post.title} : ('untitled[' + ${#temporals.format(T(java.time.Instant).ofEpochMilli(post.writeTime).atZone(T(java.time.ZoneId).systemDefault()).toLocalDateTime(), 'yyyy-MM-dd HH:mm:ss')} + ']')"></h3>
<p th:text="${#strings.abbreviate(post.html, 80)}" class="ellipsis"></p>
</div>
</div>
</section>
</article>
</div>
@@ -30,12 +30,22 @@
initialValue:baseData.content,
});
}
function loadEditor() {
goToEditor([[${srcPost.id}]]);
}
</script>
</th:block>
<th:block layout:fragment="content" id="content">
<section class="wrapper style2">
<div class="container">
<header class="major" >
<div class="container" th:if="${PERMISSION == 'OK'}" onclick="loadEditor()">
<header class="major">
<h2 id="title_layer" th:text="${srcPost.title}">A gigantic heading you can use for whatever</h2>
<p th:text="${#temporals.format(T(java.time.Instant).ofEpochMilli(srcPost.writeTime).atZone(T(java.time.ZoneId).systemDefault()).toLocalDateTime(), 'yyyy-MM-dd HH:mm:ss')}"></p>
</header>
</div>
<div class="container" th:if="${PERMISSION != 'OK'}" onclick="openLoginPopup('login')">
<header class="major">
<h2 id="title_layer" th:text="${srcPost.title}">A gigantic heading you can use for whatever</h2>
<p th:text="${#temporals.format(T(java.time.Instant).ofEpochMilli(srcPost.writeTime).atZone(T(java.time.ZoneId).systemDefault()).toLocalDateTime(), 'yyyy-MM-dd HH:mm:ss')}"></p>
</header>
@@ -51,7 +51,7 @@
<section class="col-6 col-12-narrower" th:each="post : ${row}">
<!-- <span th:text="${cell}"></span>-->
<div class="box post" onclick="goToViewer(this)" th:data="${post.id}">
<a href="#" class="image left"><img th:src="${#strings.length(post.image) > 0} ? ${post.image} : 'images/pic01.jpg'" alt="" /></a>
<a href="#" class="image left"><img th:src="${#strings.length(post.image) > 0} ? ${post.image} : 'images/pic01.jpg'" alt="" /></a>
<div class="inner">
<h3 th:text="${#strings.length(post.title) > 0} ? ${post.title} : ('untitled[' + ${#temporals.format(T(java.time.Instant).ofEpochMilli(post.writeTime).atZone(T(java.time.ZoneId).systemDefault()).toLocalDateTime(), 'yyyy-MM-dd HH:mm:ss')} + ']')"></h3>
<p th:text="${#strings.abbreviate(post.html, 80)}" class="ellipsis"></p>
@@ -73,7 +73,12 @@
</div>
</section>
<section class="col-4 col-12-narrower">
<div class="box highlight">
<div class="box highlight" th:if="${PERMISSION == 'OK'}" onclick=gotoWrite()>
<i class="icon solid major fa-pencil-alt"></i>
<h3>글쓰기[Writing]</h3>
<p>오직 주인장 만의 권한 임요. 그냥 내가 쓰기 편하게 여기 놔둔 메뉴임. 님들은 못씀요.<br>[Only the owner has the authority. This is just a menu that I put here for my convenience. You can't use it.]</p>
</div>
<div class="box highlight" th:if="${PERMISSION != 'OK'}" onclick="openLoginPopup('login')">
<i class="icon solid major fa-pencil-alt"></i>
<h3>글쓰기[Writing]</h3>
<p>오직 주인장 만의 권한 임요. 그냥 내가 쓰기 편하게 여기 놔둔 메뉴임. 님들은 못씀요.<br>[Only the owner has the authority. This is just a menu that I put here for my convenience. You can't use it.]</p>
@@ -14,10 +14,8 @@
let onChange = () => {console.log(editor.getMarkdown())}
document.addEventListener("DOMContentLoaded", onLoaded);
function onLoaded() {
var h = document.querySelector('#main_layer').getBoundingClientRect().height + 'px'
editor = new toastui.Editor({
el: document.querySelector('#editor'),
height: '500px',
width:'100%',
viewer: true,
usageStatistics : false,
@@ -137,15 +135,15 @@
"> - **Embedded license files**: [jcl-over-slf4j-2.0.16.jar/META-INF/LICENSE.txt](jcl-over-slf4j-2.0.16.jar/META-INF/LICENSE.txt)\n" +
"\n" +
"\n"
,
theme:"dark",
});
}
</script>
</th:block>
<th:block layout:fragment="content" id="content">
<div id="main_layer" style="background:#30303594;">
<div id="editor" ></div>
</div>
<section class="wrapper style1">
<div class="container">
<div id="editor" ></div>
</div>
</section>
</th:block>
</html>
@@ -9,10 +9,14 @@
<!-- Nav -->
<nav id="nav">
<ul>
<li id="menu_home" class="current"><a th:href="@{/}">Home</a></li>
<li id="menu_home" ><a th:href="@{/}">Home</a></li>
<li id="menu_posts"><a href="blog/posts">Posts</a></li>
<li id="menu_sec"><a href="left-sidebar">Left Sidebar</a></li>
<li id="menu_thr"><a href="right-sidebar">Right Sidebar</a></li>
<li id="menu_four"><a href="two-sidebar">Two Sidebar</a></li>
<li id="menu_drop">
<a href="#">Dropdown</a>
<a href="#">About</a>
<ul>
<li><a href="#">Lorem dolor</a></li>
<li><a href="#">Magna phasellus</a></li>
@@ -27,13 +31,9 @@
<li><a href="#">Veroeros feugiat</a></li>
</ul>
</li>
<li><a href="#">Veroeros feugiat</a></li>
<li><a th:href="@{/licenses}">Licenses</a></li>
</ul>
</li>
<li id="menu_sec"><a href="left-sidebar">Left Sidebar</a></li>
<li id="menu_thr"><a href="right-sidebar">Right Sidebar</a></li>
<li id="menu_four"><a href="two-sidebar">Two Sidebar</a></li>
</ul>
</nav>
@@ -19,6 +19,26 @@
</div>
<th:block th:replace="~{fragments/footer :: footer}"></th:block>
</div>
<div id="overlay" class="login_overlay">
<div id="popup" class="login_popup">
<div id="loginForm" class="login_form">
<h2>로그인</h2>
<form id="loginFormElement" onsubmit="return false;">
<input type="text" th:data="${enc}" id="loginId" placeholder="아이디" required>
<input type="password" th:data="${type}" id="loginPassword" placeholder="비밀번호" required>
<button type="submit" class="button">로그인</button>
</form>
</div>
<div id="signupForm" class="login_form">
<h2>회원가입</h2>
<input type="text" placeholder="아이디" required>
<input type="password" placeholder="비밀번호" required>
<input type="email" placeholder="이메일" required>
<button onclick="submitForm('signup')">가입하기</button>
</div>
<span class="login_close" onclick="closePopup()">&times;</span>
</div>
</div>
<!-- Scripts -->
<script th:src="@{/assets/js/jquery.min.js}"></script>
<script th:src="@{/assets/js/jquery.dropotron.min.js}"></script>