diff --git a/admin/component/post.js b/admin/component/post.js
index 38a5e7d..aca63d2 100644
--- a/admin/component/post.js
+++ b/admin/component/post.js
@@ -1,17 +1,271 @@
(() => {
- function create(tag) {
- return document.createElement(tag);
+ let listData = {
+ page: -1,
+ limit: -1,
+ allPostCount: -1
+ };
+
+ async function fetchPost(mode, data) {
+ let queryData = {
+ method: "GET",
+ url: "../ajax/posts.php"
+ }
+
+ switch (mode) {
+ case "page":
+ queryData.url += `?page=${data}`;
+ if (listData["page"] != -1 && data > Math.ceil(listData['allPostCount'] / listData['limit'])) {
+ // we don't have that much post
+ pageManager.snackbar('頁數不存在');
+ router.navigate('/post');
+ return;
+ }
+ break;
+ case "user":
+ queryData.url += `?username=${data}`;
+ pageManager.setHeader(`${data} 的文章`);
+ break;
+ case "pid":
+ queryData.url += `?pid=${data}`;
+ break;
+ default:
+ break;
+ }
+
+ try {
+ let res = await axios.request(queryData);
+ if (mode == "page") {
+ listData.allPostCount = parseInt(res.data["all_posts_count"]);
+ listData.page = parseInt(res.data["page"]);
+ listData.limit = parseInt(res.data["page_limit"]);
+ }
+
+ if (mode == "pid") {
+ let likeData = await axios.request({
+ url: `../ajax/like.php?pid=${data}&fetch`,
+ method: "GET"
+ });
+ renderPostPage(data, res.data.post, likeData.data);
+ } else {
+ renderPage(mode, res.data);
+ }
+
+ } catch (error) {
+ console.error(error);
+ if (error.response) {
+ if (error.response.status == 404) {
+ pageManager.snackbar("找不到文章");
+ }
+ } else {
+ pageManager.snackbar("讀取資料時發生錯誤。");
+ }
+ } finally {
+ bindListener(mode);
+ finish();
+ }
+ }
+
+ function renderPage(mode, data) {
+ let doc = pageManager.document;
+ doc.innerHTML = "";
+
+ var wrapper = create('div', "table wrapper");
+ var table = create('table', "ts sortable celled striped table");
+
+ let thead = create('thead');
+ (["標題", "讚", "留言", "日期", "管理"]).forEach((e, _i) => {
+ let th = create('th'); th.textContent = e;
+ thead.appendChild(th);
+ })
+ table.appendChild(thead);
+
+ var tbody = create('tbody');
+ for (post of data["posts"]) {
+ let tr = create("tr");
+ (["title", "likes_count", "comments_count", "time"]).forEach((e, _i) => {
+ let td = create('td');
+ if (e != "title") td.classList.add("collapsing");
+ if (e.indexOf("count") != -1) td.classList.add("center", "aligned");
+
+ if (e == "title") {
+ td.innerHTML = `${post[e]}`;
+ } else {
+ td.textContent = post[e];
+ }
+ tr.appendChild(td);
+ });
+
+ let action = `
| `;
+ tr.insertAdjacentHTML("beforeend", action);
+
+ tbody.appendChild(tr);
+ }
+
+ table.appendChild(tbody);
+ wrapper.appendChild(table);
+ doc.appendChild(wrapper);
+
+ if (mode === "page") doc.appendChild(pagination(listData["allPostCount"], listData["limit"], listData["page"]));
+ }
+
+ function renderPostPage(pid, data, likeData) {
+ let doc = pageManager.document;
+ doc.innerHTML = "";
+
+ let segment = create('div', "ts clearfix primary segment");
+ let title = create('div', "ts big header");
+ let cardContainer = create('div', "ts stackable three cards");
+ title.innerHTML = data["title"];
+ title.insertAdjacentHTML("beforeend", ``);
+ segment.appendChild(title);
+
+ data["length"] = data["content"].length;
+ let iconName = {
+ "length": "font",
+ "likes_count": "like outline",
+ "comments_count": "comments"
+ };
+
+ let statLabel = {
+ "length": "文章字數",
+ "likes_count": "獲得讚數",
+ "comments_count": "留言數量"
+ };
+
+ let statTemplate = ``;
+ Object.keys(iconName).forEach((e, _i) => {
+ let card = create('div', "ts card");
+ let content = create('div', "content");
+ let symbol = create('div', "symbol");
+ let icon = create('i', `${iconName[e]} icon`);
+
+ content.innerHTML = statTemplate.replace("{{ value }}", data[e]).replace("{{ label }}", statLabel[e]);
+ symbol.appendChild(icon);
+ card.appendChild(content);
+ card.appendChild(symbol);
+
+ cardContainer.appendChild(card);
+ });
+ segment.appendChild(cardContainer);
+
+ let likersDetail = create('details', "ts accordion");
+ let detailContent = create('div', "content");
+ likersDetail.insertAdjacentHTML("beforeend", ` 按讚的人`);
+ let likersList = create('div', "ts link list");
+ for (let username of likeData["likers"]) {
+ let item = create('a', "item");
+ item.href = `/user/${username}`;
+ item.setAttribute("data-navigo", "");
+ item.textContent = username;
+ likersList.appendChild(item);
+ }
+ if (!likeData["likers"].length) {
+ likersList.insertAdjacentHTML("beforeend", `(無)
`);
+ }
+ detailContent.appendChild(likersList);
+ likersDetail.appendChild(detailContent);
+ segment.appendChild(likersDetail);
+
+ let actionsContainer = create('div', "ts separated right floated buttons");
+ let actionClass = {
+ "編輯": "basic",
+ "預覽": "primary",
+ "刪除": "negative"
+ };
+ let actionParams = {
+ "編輯": `?edit=${pid}`,
+ "預覽": `?pid=${pid}`,
+ "刪除": `?del=${pid}`
+ };
+ Object.keys(actionClass).forEach((e, _i) => {
+ let button = create('a', "ts button");
+ button.classList.add(actionClass[e]);
+ button.target = "_blank";
+ button.href = "../post.php" + actionParams[e];
+ button.textContent = e;
+ actionsContainer.appendChild(button);
+ });
+ segment.appendChild(actionsContainer);
+ doc.appendChild(segment);
+ doc.insertAdjacentHTML("beforeend", ` -1 ? listData["page"] : 1)}" data-navigo>返回列表`);
+ }
+
+ function pagination(all, limit, currentPage) {
+ let totalPage = Math.ceil(all / limit);
+ let pagination = create('div'); pagination.className = "ts basic center aligned padded segment";
+ let buttons = create('div'); buttons.className = "ts small separated buttons";
+
+ if (currentPage > 1) buttons.innerHTML += ``;
+ buttons.innerHTML += `${currentPage} / ${totalPage}
`;
+ if (currentPage != totalPage) buttons.innerHTML += ``;
+
+ pagination.appendChild(buttons);
+ return pagination;
+ }
+
+ function bindListener(mode) {
+ if (mode == "page" || mode == "user") {
+ var selector = "tbody";
+ } else if (mode == "pid") {
+ var selector = ".ts.primary.segment";
+ }
+
+ $(selector).on('click', 'a.negative', function(e) {
+ e.preventDefault();
+
+ let el = e.currentTarget;
+ let pid = el.dataset.pid;
+ showModal(pid);
+ });
+
+ function showModal(pid) {
+ swal({
+ type: 'question',
+ title: '確定要刪除嗎?',
+ showCancelButton: true,
+ confirmButtonText: '確定',
+ cancelButtonText: '取消'
+ }).then((result) => {
+ if (result.value) { // confirm
+ axios.request({
+ method: "GET",
+ url: "../post.php?del=" + pid
+ }).then(function (res) {
+ pageManager.snackbar('刪除成功');
+ router.navigate('/post'); // reload
+ }).catch(function (err) {
+ switch (err.response.status) {
+ case 404:
+ pageManager.snackbar('找不到文章');
+ case 403:
+ pageManager.snackbar('權限不足');
+ }
+ });
+ }
+ });
+ }
+ }
+
+ function finish() {
+ ts('table').tablesort();
+ router.updatePageLinks();
+ setTimeout(() => {
+ pageManager.setLoaderState(false)
+ }, 1000);
+ }
+
+ function create(tag, className="") {
+ let el = document.createElement(tag);
+ el.className = className;
+ return el;
}
pageManager.register("post", function () {
return {
render: function (...args) {
pageManager.setHeader("文章");
- setTimeout(() => {
- pageManager.document.innerHTML = args[0] + args[1];
- pageManager.setLoaderState(false)
- }, 500);
+ fetchPost(...args);
}
}
});
-})();
+})();
\ No newline at end of file
diff --git a/ajax/posts.php b/ajax/posts.php
index 90590ce..0c7dc41 100644
--- a/ajax/posts.php
+++ b/ajax/posts.php
@@ -66,7 +66,7 @@ if (isset($_GET['pid'])) {
"SELECT `post`.*, `user`.name FROM `post` INNER JOIN `user` ON `post`.username = `user`.username WHERE `post`.username = '%s' ORDER BY `time`",
array($_GET['username'])
));
- $all_posts_count = cavern_query_result("SELECT COUNT(*) AS `count` FROM `post` WHERE `username` = '%s'", array($_GET['username']))['row']['count'];
+ $all_posts_count = sizeOf($post_list);
} else {
$post_list = article_list(cavern_query_result(
"SELECT `post`.*, `user`.name FROM `post` INNER JOIN `user` ON `post`.username = `user`.username ORDER BY `time` DESC LIMIT %d,%d",
@@ -86,9 +86,8 @@ if (isset($_GET['pid'])) {
$post = array(
'username' => $article->author,
'name' => $article->name,
- 'pid' => $article->pid,
+ 'pid' => intval($article->pid),
'title' => $article->title,
- 'content' => $article->content,
'time' => $article->time,
'likes_count' => $article->likes_count,
'comments_count' => $article->comments_count,