This commit is contained in:
2025-09-18 17:55:32 +09:00
parent 17aea8b43b
commit 5e0db4ff03
38 changed files with 3011 additions and 1228 deletions
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/default_layout}">
<th:block layout:fragment="head">
</th:block>
<th:block layout:fragment="content" id="content">
<section class="wrapper style2">
<div class="container">
<header class="major">
<h2 th:text="${srcPost.title}">소개글 제목</h2>
<p>
최종 수정일: <span th:text="${#temporals.format(T(java.time.Instant).ofEpochMilli(srcPost.modifyTime).atZone(T(java.time.ZoneId).systemDefault()).toLocalDateTime(), 'yyyy-MM-dd HH:mm')}"></span>
</p>
</header>
</div>
</section>
<section class="wrapper style1">
<div class="container">
<article>
<div id="editor"></div>
</article>
</div>
</section>
<link href="https://cdn.jsdelivr.net/npm/quill@2/dist/quill.snow.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/quill@2/dist/quill.js"></script>
<script>
// DOM 로드 완료 후 Quill 에디터를 읽기 전용(false)으로 초기화
document.addEventListener('DOMContentLoaded', function() {
initEditor(false);
});
</script>
</th:block>
</html>
@@ -0,0 +1,83 @@
<!DOCTYPE html>
<html
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/default_layout}">
<head>
<title>Bookmarks</title>
</head>
<th:block layout:fragment="content">
<section class="wrapper style2">
<div class="container">
<header class="major">
<h2>Bookmarks</h2>
<p>다른 사용자들이 저장한 유용한 페이지들을 둘러보세요.</p>
</header>
</div>
</section>
<section class="wrapper style1">
<div class="container">
<div class="row">
<div class="col-12" th:if="${bookmarksPage.empty}">
<p style="text-align: center;">아직 저장된 페이지가 없습니다.</p>
</div>
<div class="col-4 col-6-medium col-12-small" th:each="bookmark : ${bookmarksPage.content}">
<section class="box feature">
<a href="javascript:void(0);"
th:data-url="${bookmark.url}"
th:data-title="${bookmark.title}"
onclick="showBookmarkOptions(this)" class="image featured">
<img th:src="${bookmark.thumbnailUrl ?: '/images/pic01.jpg'}" alt="Thumbnail" />
</a>
<div class="inner">
<header>
<h3 th:text="${bookmark.title}">북마크 제목</h3>
<p th:if="${bookmark.userComment}" th:text="${bookmark.userComment}" style="font-style: italic; color: #007bff;"></p>
</header>
<p th:text="${#strings.abbreviate(bookmark.description, 100)}"></p>
<div class="bookmark-controls" style="margin-top: 1em; padding-top: 1em; border-top: 1px solid #eee;">
<div class="vote-controls" th:data-bookmark-id="${bookmark.id}" style="text-align: center; margin-bottom: 1em;">
<button class="button small alt" th:onclick="handleBookmarkVote(this, 'like')">
👍 (<span class="like-count" th:text="${bookmark.voteCount}">0</span>)
</button>
<button class="button small alt" th:onclick="handleBookmarkVote(this, 'unlike')" style="margin-left: 0.5em;">
👎 (<span class="unlike-count" th:text="${bookmark.unlikeCount}">0</span>)
</button>
</div>
<a href="javascript:void(0);" th:onclick="toggleCommentSection('[[${bookmark.id}]]')" class="button small fit">댓글 보기</a>
<div th:id="'comment-section-' + ${bookmark.id}" class="comment-section" style="display: none; margin-top: 1em;">
<div th:id="'comments-list-' + ${bookmark.id}" class="comments-list"></div>
<textarea th:id="'comment-input-' + ${bookmark.id}" placeholder="댓글을 입력하세요..." style="margin-top: 1em;"></textarea>
<button class="button small" th:onclick="submitBookmarkComment('[[${bookmark.id}]]')">등록</button>
</div>
</div>
<footer style="font-size: 0.8em; color: #888; text-align: right; margin-top: 1em;">
by <span th:text="${bookmark.userId}"></span>
</footer>
</div>
</section>
</div>
</div>
<nav th:if="${bookmarksPage.totalPages > 1}" style="text-align: center; margin-top: 2.5em;">
<ul class="pagination">
<li th:classappend="${bookmarksPage.first} ? 'disabled'">
<a th:href="@{/bookmarks(page=${bookmarksPage.number - 1})}" class="button alt small">Prev</a>
</li>
<li th:each="pageNum : ${#numbers.sequence(0, bookmarksPage.totalPages - 1)}">
<a th:href="@{/bookmarks(page=${pageNum})}"
th:text="${pageNum + 1}"
th:class="${pageNum == bookmarksPage.number} ? 'button small' : 'button alt small'"></a>
</li>
<li th:classappend="${bookmarksPage.last} ? 'disabled'">
<a th:href="@{/bookmarks(page=${bookmarksPage.number + 1})}" class="button alt small">Next</a>
</li>
</ul>
</nav>
</div>
</section>
</th:block>
</html>
@@ -7,11 +7,7 @@
>
<th:block layout:fragment="head">
<link href="https://cdn.jsdelivr.net/npm/quill@2/dist/quill.snow.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/quill-table-better@1/dist/quill-table-better.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/quill@2/dist/quill.js"></script>
<script src="https://cdn.jsdelivr.net/npm/quill-table-better@1/dist/quill-table-better.js"></script>
<script>document.addEventListener('DOMContentLoaded', function() {initEditor(true)});</script>
</th:block>
<body>
@@ -110,6 +106,11 @@
</div>
</div>
</div>
<link href="https://cdn.jsdelivr.net/npm/quill@2/dist/quill.snow.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/quill-table-better@1/dist/quill-table-better.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/quill@2/dist/quill.js"></script>
<script src="https://cdn.jsdelivr.net/npm/quill-table-better@1/dist/quill-table-better.js"></script>
<script>document.addEventListener('DOMContentLoaded', function() {initEditor(true)});</script>
</th:block>
</body>
</html>
@@ -1,7 +1,10 @@
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.w3.org/1999/xhtml" layout:decorate="~{layout/default_layout}">
<head>
<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/quill@2/dist/quill.snow.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/quill-table-better@1/dist/quill-table-better.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/quill@2/dist/quill.js"></script>
<script src="https://cdn.jsdelivr.net/npm/quill-table-better@1/dist/quill-table-better.js"></script>
</head>
<body>
<th:block layout:fragment="content" id="content">
@@ -0,0 +1,124 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/default_layout}">
<th:block layout:fragment="head">
<style>
.message-list { list-style: none; padding-left: 0; }
.message-item { border: 1px solid #ddd; border-radius: 5px; margin-bottom: 1em; }
.message-header { padding: 10px 15px; background: #f7f7f7; cursor: pointer; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; }
.message-item.unread .message-header { font-weight: bold; background: #fffbe5; border-left: 3px solid #FFA500; }
.message-content { padding: 15px; display: none; border-top: 1px solid #ddd; }
.message-content.active { display: block; }
.reply-form { margin-top: 1em; }
.message-title { flex-grow: 1; }
</style>
</th:block>
<th:block layout:fragment="content">
<section class="wrapper style1">
<div class="container">
<header class="major">
<h2 th:text="${pageTitle}"></h2>
</header>
<div class="box">
<ul class="message-list">
<li th:if="${#lists.isEmpty(messages)}">받은 쪽지가 없습니다.</li>
<li th:each="msg : ${messages}" class="message-item" th:classappend="${!msg.isRead} ? 'unread'" th:data-message-id="${msg.id}">
<div class="message-header" onclick="toggleMessage(this)">
<div class="message-title">
<span th:text="${msg.title}"></span>
<small style="margin-left: 1em; color: #777;" th:text="'보낸 사람: ' + ${msg.senderId}"></small>
</div>
<small th:text="${#temporals.format(T(java.time.Instant).ofEpochMilli(msg.timestamp).atZone(T(java.time.ZoneId).systemDefault()), 'yyyy-MM-dd HH:mm')}"></small>
</div>
<div class="message-content">
<p style="white-space: pre-wrap;" th:text="${msg.content}"></p>
<hr/>
<div class="reply-form">
<h4>답장 보내기</h4>
<form onsubmit="sendMessage(event, this)">
<input type="hidden" name="receiverId" th:value="${msg.senderId}" />
<div class="row gtr-50">
<div class="col-12">
<input type="text" name="title" placeholder="제목" th:value="'RE: ' + ${msg.title}" required />
</div>
<div class="col-12">
<textarea name="content" placeholder="내용" rows="4" required></textarea>
</div>
<div class="col-12">
<button type="submit" class="button primary">답장 전송</button>
</div>
</div>
</form>
</div>
</div>
</li>
</ul>
</div>
</div>
</section>
<script th:inline="javascript">
const csrfToken = document.querySelector('meta[name="_csrf"]')?.getAttribute('content');
const csrfHeader = document.querySelector('meta[name="_csrf_header"]')?.getAttribute('content');
async function toggleMessage(headerElement) {
const messageItem = headerElement.closest('.message-item');
const content = messageItem.querySelector('.message-content');
const messageId = messageItem.dataset.messageId;
const isOpening = !content.classList.contains('active');
// 모든 열린 쪽지 닫기
document.querySelectorAll('.message-content.active').forEach(c => {
if(c !== content) c.classList.remove('active');
});
content.classList.toggle('active');
if (isOpening && messageItem.classList.contains('unread')) {
const response = await fetch(`/messages/${messageId}/read`, {
method: 'POST',
headers: { [csrfHeader]: csrfToken }
});
if (response.ok) {
messageItem.classList.remove('unread');
// 헤더의 아이콘도 업데이트 할 수 있지만, 페이지 새로고침 전까지는 유지됩니다.
}
}
}
async function sendMessage(event, form) {
event.preventDefault();
const formData = new FormData(form);
const data = {
receiverId: formData.get('receiverId'),
title: formData.get('title'),
content: formData.get('content')
};
const submitButton = form.querySelector('button[type="submit"]');
submitButton.disabled = true;
submitButton.textContent = '전송 중...';
const response = await fetch('/messages/send', {
method: 'POST',
headers: { 'Content-Type': 'application/json', [csrfHeader]: csrfToken },
body: JSON.stringify(data)
});
if(response.ok) {
alert('답장을 성공적으로 보냈습니다.');
form.querySelector('textarea').value = ''; // 내용만 초기화
toggleMessage(form.closest('.message-item').querySelector('.message-header')); // 답장 후 창 닫기
} else {
alert('답장 보내기에 실패했습니다.');
}
submitButton.disabled = false;
submitButton.textContent = '답장 전송';
}
</script>
</th:block>
</html>
@@ -15,6 +15,49 @@
.user-list li, .post-list li { display: flex; justify-content: space-between; align-items: center; padding: 10px; border-bottom: 1px solid #eee; }
.user-list li:last-child, .post-list li:last-child { border-bottom: none; }
.button.small { margin-left: 0.5em; }
.custom-radio {
display: none; /* 기본 라디오 버튼 숨기기 */
}
.custom-label {
position: relative;
padding-left: 25px; /* 라벨 왼쪽에 가짜 버튼을 위한 공간 확보 */
cursor: pointer;
line-height: 20px;
display: inline-block;
color: #555; /* 라벨 텍스트 색상 */
}
/* 가짜 라디오 버튼 (원) 만들기 */
.custom-label::before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 18px;
height: 18px;
border: 2px solid #ddd;
border-radius: 50%; /* 원 모양 */
background: #fff;
}
/* 선택되었을 때 가짜 라디오 버튼 스타일 변경 */
.custom-radio:checked + .custom-label::before {
border-color: #FFA500; /* 테두리 색상 변경 (사이트의 포인트 색상) */
background: #FFA500; /* 배경 색상 채우기 */
}
/* 선택되었을 때 원 안에 작은 점 추가 */
.custom-radio:checked + .custom-label::after {
content: '';
position: absolute;
left: 6px;
top: 6px;
width: 8px;
height: 8px;
border-radius: 50%;
background: white;
}
</style>
</th:block>
@@ -31,10 +74,15 @@
<div class="tab-link" onclick="openTab(event, 'myPosts')">내가 쓴 글</div>
<div class="tab-link" onclick="openTab(event, 'myComments')">내가 쓴 댓글</div>
<div class="tab-link" onclick="openTab(event, 'myRanks')">내 게임 랭킹</div>
<div class="tab-link" onclick="openTab(event, 'myMessages')">쪽지함</div>
<div class="tab-link" onclick="openTab(event, 'myBookmarks')">저장한 페이지</div>
<th:block sec:authorize="hasRole('ADMIN')">
<div class="tab-link" onclick="openTab(event, 'userManagement')">회원 관리</div>
<div class="tab-link" onclick="openTab(event, 'postManagement')">게시물 관리</div>
<div class="tab-link" onclick="openTab(event, 'bannerManagement')">배너 관리</div>
<div class="tab-link" onclick="openTab(event, 'aboutManagement')">사이트 소개 관리</div>
</th:block>
</div>
@@ -78,7 +126,57 @@
</ul>
</div>
</div>
<div id="myBookmarks" class="tab-content">
<div class="box">
<h4>새 페이지 저장하기</h4>
<div id="bookmark-form">
<input type="url" id="bookmark-url-input" placeholder="저장할 페이지 URL을 입력하세요" style="margin-bottom: 1em;">
<div id="og-preview" style="display:none; border: 1px solid #ddd; padding: 1em; margin-bottom: 1em; border-radius: 5px;">
<img id="og-image" src="" style="max-width: 150px; float: left; margin-right: 1em;">
<h5 id="og-title"></h5>
<p id="og-description" style="font-size: 0.9em; color: #555;"></p>
</div>
<textarea id="bookmark-comment-input" placeholder="이 페이지에 대한 나의 생각 (선택)" rows="3"></textarea>
<div id="visibility-selector" style="margin-top: 1em; display: flex; align-items: center; flex-wrap: wrap;">
<strong style="margin-right: 1.5em;">공개 범위:</strong>
<div style="display: flex; align-items: center; margin-right: 1.5em;">
<input type="radio" name="visibility" id="visibility-private" value="PRIVATE" class="custom-radio" checked>
<label for="visibility-private" class="custom-label">비공개</label>
</div>
<div style="display: flex; align-items: center; margin-right: 1.5em;">
<input type="radio" name="visibility" id="visibility-members" value="MEMBERS" class="custom-radio">
<label for="visibility-members" class="custom-label">회원 공개</label>
</div>
<div style="display: flex; align-items: center;">
<input type="radio" name="visibility" id="visibility-public" value="PUBLIC" class="custom-radio">
<label for="visibility-public" class="custom-label">전체 공개</label>
</div>
</div>
<button id="save-bookmark-btn" class="button primary" style="margin-top: 1em;">저장하기</button>
</div>
</div>
<div class="box" style="margin-top: 2em;">
<h4>저장된 목록</h4>
<div id="bookmarks-list" class="row">
<div class="col-4 col-12-medium">
<section class="box feature">
<a href="#" class="image featured"><img src="/images/pic01.jpg" alt="" /></a>
<div class="inner">
<header>
<h2>카드 제목</h2>
<p>사용자 코멘트가 여기에 들어갑니다.</p>
</header>
<p style="font-size: 0.8em; color: #888;">원본 페이지 설명...</p>
</div>
</section>
</div>
</div>
</div>
</div>
<div id="myRanks" class="tab-content">
<div class="box">
<ul class="post-list">
@@ -104,7 +202,27 @@
</ul>
</div>
</div>
<div id="myMessages" class="tab-content">
<div class="box">
<ul class="post-list">
<li th:if="${#lists.isEmpty(myMessages)}">주고받은 쪽지가 없습니다.</li>
<li th:each="msg : ${myMessages}">
<div style="display: flex; align-items: center; gap: 1em;">
<span th:if="${msg.senderId == user.user_id}" class="tag-item" style="background: #e0f7fa;">보냄</span>
<span th:if="${msg.receiverId == user.user_id}" class="tag-item" style="background: #fffbe5;">받음</span>
<div style="min-width: 150px;">
<strong th:if="${msg.senderId == user.user_id}" th:text="'To: ' + ${msg.receiverId}"></strong>
<strong th:if="${msg.receiverId == user.user_id}" th:text="'From: ' + ${msg.senderId}"></strong>
</div>
<a th:href="@{/messages}" th:text="${msg.title}">쪽지 제목</a>
</div>
<span th:text="${#temporals.format(T(java.time.Instant).ofEpochMilli(msg.timestamp).atZone(T(java.time.ZoneId).systemDefault()), 'yyyy-MM-dd HH:mm')}"></span>
</li>
</ul>
</div>
</div>
<div id="userManagement" class="tab-content" sec:authorize="hasRole('ADMIN')">
<div class="box">
<h4>권한 요청</h4>
@@ -154,7 +272,8 @@
<ul class="post-list">
<li th:each="image : ${allImages}" th:id="'image-row-' + ${image.id}">
<div style="display: flex; align-items: center; gap: 1em;">
<img th:src="@{'/api/images/' + ${image.fileName}}" alt="Image Thumbnail" style="width: 100px; height: 60px; object-fit: cover; border-radius: 4px;"/>
<!-- <img th:src="${post.thumb != null and not #strings.isEmpty(post.thumb)} ? ${apiBaseUrl + post.thumb} : @{/images/pic01.jpg}" alt="Post Thumbnail" />-->
<img th:src="${apiBaseUrl + '/api/images/' + image.fileName + '?type=thumbnail'}" alt="Image Thumbnail" style="width: 100px; height: 60px; object-fit: cover; border-radius: 4px;"/>
<div>
<strong th:text="${image.fileName}"></strong><br>
<span th:if="${image.isBannerCandidate}" style="color: #2a9d8f; font-weight: bold;">(배너로 사용 중)</span>
@@ -170,6 +289,27 @@
</ul>
</div>
</div>
<div id="aboutManagement" class="tab-content" sec:authorize="hasRole('ADMIN')">
<div class="box">
<h4>사이트 소개글 관리</h4>
<p>
'사이트 소개' 페이지에 표시될 내용입니다. 글을 수정하면 이전 버전은 히스토리로 여기에 남게 됩니다.
</p>
<th:block th:with="latestAbout=${!#lists.isEmpty(aboutPostHistory) ? aboutPostHistory[0] : null}">
<a th:if="${latestAbout != null}" th:href="@{/blog/edit/{postId}(postId=${latestAbout.id})}" class="button primary">최신 소개글 수정</a>
<a th:if="${latestAbout == null}" th:href="@{/blog/edit(type='ABOUT_SITE')}" class="button">새 소개글 작성</a>
</th:block>
<h5 style="margin-top: 2em;">수정 히스토리</h5>
<ul class="post-list">
<li th:each="post : ${aboutPostHistory}">
<a th:href="@{'/blog/viewer/' + ${post.id}}" th:text="${post.title}">수정된 버전 제목</a>
<span th:text="|수정일: ${#dates.format(post.modifyTime, 'yyyy-MM-dd HH:mm')}|"></span>
</li>
<li th:if="${#lists.isEmpty(aboutPostHistory)}">작성된 소개글이 없습니다.</li>
</ul>
</div>
</div>
</div>
</section>
@@ -315,6 +455,83 @@
alert('작업 중 오류가 발생했습니다.');
});
}
document.addEventListener('DOMContentLoaded', function() {
const urlInput = document.getElementById('bookmark-url-input');
const preview = document.getElementById('og-preview');
let ogData = {}; // OG 파싱 결과를 저장할 변수
// URL 입력 필드에서 포커스가 벗어났을 때(onblur) OG 정보 파싱 API 호출
urlInput.addEventListener('blur', async function() {
const url = this.value.trim();
if (!url) return;
try {
const response = await fetch(`/api/og/parse?url=${encodeURIComponent(url)}`);
if (!response.ok) throw new Error('파싱 실패');
ogData = await response.json();
// 미리보기 UI 업데이트
document.getElementById('og-title').textContent = ogData.title || '제목 없음';
document.getElementById('og-description').textContent = ogData.description || '';
const ogImage = document.getElementById('og-image');
if (ogData.thumbnailUrl) {
ogImage.src = ogData.thumbnailUrl;
ogImage.style.display = 'block';
} else {
ogImage.style.display = 'none';
}
preview.style.display = 'block';
} catch (error) {
console.error(error);
preview.style.display = 'none';
alert('페이지 정보를 가져오는 데 실패했습니다. URL을 확인해주세요.');
}
});
// 저장 버튼 클릭 이벤트
document.getElementById('save-bookmark-btn').addEventListener('click', async function() {
const comment = document.getElementById('bookmark-comment-input').value.trim();
// [수정] 선택된 공개 범위(visibility) 값을 읽어오는 코드 추가
const visibility = document.querySelector('input[name="visibility"]:checked').value;
const bookmarkData = {
url: urlInput.value.trim(),
// title, description 등은 ogData에서 가져오는 것은 그대로 유지
title: ogData.title,
description: ogData.description,
thumbnailUrl: ogData.thumbnailUrl,
userComment: comment,
// [수정] bookmarkData 객체에 visibility 프로퍼티 추가
visibility: visibility
};
if (!bookmarkData.url) {
alert('URL을 입력해주세요.');
return;
}
// 서버에 북마크 저장 요청 (이하 코드는 동일)
const response = await fetch('/user/bookmarks/save', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
[csrfHeader]: csrfToken
},
body: JSON.stringify(bookmarkData)
});
if (response.ok) {
alert('페이지가 저장되었습니다.');
location.reload();
} else {
alert('저장에 실패했습니다.');
}
});
});
</script>
</th:block>
</html>
@@ -5,14 +5,7 @@
layout:decorate="~{layout/default_layout}">
<th:block layout:fragment="head">
<link href="https://cdn.jsdelivr.net/npm/quill@2/dist/quill.snow.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/quill-table-better@1/dist/quill-table-better.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/quill@2/dist/quill.js"></script>
<script src="https://cdn.jsdelivr.net/npm/quill-table-better@1/dist/quill-table-better.js"></script>
<script>document.addEventListener('DOMContentLoaded', function() {
initEditor(false)
fetchComments(serverData.id);
});</script>
</th:block>
<th:block layout:fragment="content" id="content">
@@ -108,5 +101,14 @@
</div>
</div>
</section>
<link href="https://cdn.jsdelivr.net/npm/quill@2/dist/quill.snow.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/quill-table-better@1/dist/quill-table-better.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/quill@2/dist/quill.js"></script>
<script src="https://cdn.jsdelivr.net/npm/quill-table-better@1/dist/quill-table-better.js"></script>
<script>document.addEventListener('DOMContentLoaded', function() {
initEditor(false)
fetchComments(serverData.id);
});</script>
</th:block>
</html>
@@ -1,5 +1,6 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">>
<th:block th:fragment="footer">
<script th:inline="javascript">
/*<![CDATA[*/
@@ -9,60 +10,66 @@
/*]]>*/
</script>
<div id="footer">
<div class="container">
<div class="row">
<section class="col-3 col-6-narrower col-12-mobilep">
<h3 id="ranking-title">Rank of Views</h3>
<ul class="rank_of_view" >
</ul>
</section>
<section class="col-3 col-6-narrower col-12-mobilep">
<h3>Recent of Posts</h3>
<ul class="recent_posts">
<div id="footer">
<div class="container">
<div class="row">
<section class="col-3 col-6-narrower col-12-mobilep">
<h3 id="ranking-title">Rank of Views</h3>
<ul class="rank_of_view" >
</ul>
</section>
<section class="col-3 col-6-narrower col-12-mobilep">
<h3>Recent of Posts</h3>
<ul class="recent_posts">
</ul>
</section>
<section class="col-6 col-12-narrower">
<h3>SEND TO ME(TELEGRAM BOT)</h3>
<div id="tlg_form" >
<div class="row gtr-50">
<div class="col-6 col-12-mobilep">
</ul>
</section>
<section class="col-6 col-12-narrower">
<h3>SEND TO ME(TELEGRAM BOT)</h3>
<div id="tlg_form" >
<div class="row gtr-50">
<div class="col-6 col-12-mobilep">
<div sec:authorize="isAuthenticated()">
<input type="text" name="name" id="name" placeholder="Name" th:value="${#authentication.principal.username}" readonly />
</div>
<div sec:authorize="isAnonymous()">
<input type="text" name="name" id="name" placeholder="Name" />
</div>
<div class="col-6 col-12-mobilep">
<input type="email" name="email" id="email" placeholder="Email" />
</div>
<div class="col-12">
<textarea name="message" id="message" placeholder="Message" rows="5"></textarea>
</div>
<div class="col-12">
<ul class="actions">
<li><input type="submit" class="button alt" value="Send Message" onclick="callSendTlg()" /></li>
</ul>
</div>
</div>
<div class="col-6 col-12-mobilep">
<input type="email" name="email" id="email" placeholder="Email" />
</div>
<div class="col-12">
<textarea name="message" id="message" placeholder="Message" rows="5"></textarea>
</div>
<div class="col-12">
<ul class="actions">
<li><input type="submit" class="button alt" value="Send Message" onclick="callSendTlg()" /></li>
</ul>
</div>
</div>
</section>
</div>
</div>
<!-- Icons -->
<ul class="icons">
<li><a href="#" class="icon brands fa-twitter"><span class="label">Twitter</span></a></li>
<li><a href="#" class="icon brands fa-facebook-f"><span class="label">Facebook</span></a></li>
<li><a href="#" class="icon brands fa-github"><span class="label">GitHub</span></a></li>
<li><a href="#" class="icon brands fa-linkedin-in"><span class="label">LinkedIn</span></a></li>
<li><a href="#" class="icon brands fa-google-plus-g"><span class="label">Google+</span></a></li>
</ul>
<!-- Copyright -->
<div class="copyright">
<ul class="menu">
<li>&copy;lunaticbum All rights reserved</li><li>Origin Design from:<a href="http://html5up.net">HTML5 UP</a></li>
</ul>
</div>
</section>
</div>
</div>
<!-- Icons -->
<ul class="icons">
<li><a href="#" class="icon brands fa-twitter"><span class="label">Twitter</span></a></li>
<li><a href="#" class="icon brands fa-facebook-f"><span class="label">Facebook</span></a></li>
<li><a href="#" class="icon brands fa-github"><span class="label">GitHub</span></a></li>
<li><a href="#" class="icon brands fa-linkedin-in"><span class="label">LinkedIn</span></a></li>
<li><a href="#" class="icon brands fa-google-plus-g"><span class="label">Google+</span></a></li>
</ul>
<!-- Copyright -->
<div class="copyright">
<ul class="menu">
<li>&copy;lunaticbum All rights reserved</li><li>Origin Design from:<a href="http://html5up.net">HTML5 UP</a></li>
</ul>
</div>
</div>
<script type="text/javascript">
@@ -15,19 +15,21 @@
<ul>
<li id="menu_home" ><a th:href="@{/}">Home</a></li>
<li id="menu_posts"><a href="blog/posts">Posts</a></li>
<li id="menu_nonogram"><a href="puzzle/play">Nonogram</a></li>
<li id="menu_2048"><a href="puzzle/2048">2048</a></li>
<li id="menu_sudoku"><a href="puzzle/sudoku">sudoku</a></li>
<li id="menu_spider"><a href="puzzle/spider">spider</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_bookmarks"><a href="/bookmarks">Bookmarks</a></li>
<li id="menu_drop">
<a href="#">Game</a>
<ul>
<li id="menu_nonogram"><a href="puzzle/play">Nonogram</a></li>
<li id="menu_2048"><a href="puzzle/2048">2048</a></li>
<li id="menu_sudoku"><a href="puzzle/sudoku">sudoku</a></li>
<li id="menu_spider"><a href="puzzle/spider">spider</a></li>
</ul>
</li>
<li id="menu_drop">
<a href="#">About</a>
<ul>
<li><a href="javascript:gotoWhere()">bums's where</a></li>
<li><a href="#">Magna phasellus</a></li>
<li><a href="#">Etiam sed tempus</a></li>
<li><a href="javascript:gotoBUMSpace()">BUM'sPase</a></li>
<li>
<a href="#">Submenu</a>
<ul>
@@ -46,9 +48,12 @@
</ul>
</li>
<th:block sec:authorize="isAuthenticated()">
<li><a th:href="@{/user/info}">내 정보</a></li>
</th:block>
<li sec:authorize="isAuthenticated()">
<a href="/user/info" th:text="${#authentication.principal.username}">사용자ID</a>
<a href="/messages" id="message-icon" style="display: none; color: #FFA500; margin-left: 5px;" title="새 쪽지">
쪽지함<i class="icon solid fa-envelope"></i>
</a>
</li>
<th:block sec:authorize="!isAuthenticated()">
<li id="menu_login">
<a class="open-login-popup" to="#loginPopup">Login</a>
@@ -73,7 +73,23 @@
</div>
</div>
</div>
<div id="iframe-viewer-popup" class="pop_layer" style="width: 90%; height: 90%; max-width: 1400px;">
<div class="pop_container" style="height: 100%; display: flex; flex-direction: column;">
<div class="pop_header" style="display: flex; justify-content: space-between; align-items: center; padding: 10px 20px; border-bottom: 1px solid #eee; background: #f8f8f8;">
<h4 id="iframe-viewer-title" style="margin: 0; font-size: 1em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"></h4>
<a href="#" class="btn_layerClose" style="font-size: 1.5em;" onclick="closePopup()">×</a>
</div>
<div class="pop_conts" style="flex-grow: 1; padding: 0;">
<iframe id="bookmark-iframe" src="" style="width: 100%; height: 100%; border: none;">
이 브라우저는 iframe을 지원하지 않습니다.
</iframe>
</div>
<div class="pop_footer" style="padding: 10px 20px; border-top: 1px solid #eee; background: #f8f8f8; text-align: center; font-size: 0.9em;">
콘텐츠가 표시되지 않나요?
<a id="iframe-open-new-tab-link" href="#" target="_blank" class="button small alt" style="margin-left: 1em; vertical-align: middle;" onclick="closePopup()">새 탭에서 열기</a>
</div>
</div>
</div>
<div id="unified-game-success-modal" class="pop_layer">
<div class="pop_container"> <div class="pop_conts"> <h2 id="ugsm-title">🎉 성공! 🎉</h2>
<p id="ugsm-message">여기에 성공 메시지가 표시됩니다.</p>