Finished user component

This commit is contained in:
Tony Yang 2019-06-02 03:31:28 +08:00
parent 79db56cb1d
commit 8199198816
Signed by: t510599
GPG Key ID: D88388851C28715D
2 changed files with 290 additions and 13 deletions

View File

@ -13,11 +13,15 @@ if (!$user->valid) {
send_error(403, "nopermission");
}
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// modify account data
if ($_SERVER["REQUEST_METHOD"] == "PATCH" || $_SERVER["REQUEST_METHOD"] == "POST") {
// patch: modify; post: create
if (!validate_csrf()) {
send_error(403, "csrf");
}
if ($_SERVER["REQUEST_METHOD"] == "PATCH") {
parse_str(file_get_contents('php://input'), $_POST);
// hack
}
if (isset($_POST['username']) && (isset($_POST['name']) || isset($_POST['password']))) {
// modify account data
@ -25,8 +29,18 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
try {
$target_user = new User($username);
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// create new user, but user exists
send_error(409, "userexists");
}
} catch (NoUserException $e) {
send_error(404, "nouser");
if ($_SERVER["REQUEST_METHOD"] == "PATCH") {
// modify one that not exist -> error
send_error(404, "nouser");
} else if ($_SERVER["REQUEST_METHOD"] == "POST") {
// create new user
$SQL->query("INSERT INTO `user` (`username`) VALUES ('%s')", array($username));
}
}
if (trim($_POST['password']) != '') {
@ -48,8 +62,21 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
} else {
send_error(400, "noemail");
}
$SQL->query("UPDATE `user` SET `muted`='%d' WHERE `username`='%s'", array($_POST['muted'], $username));
if (isset($_POST["muted"])) {
$muted = 1;
} else {
$muted = 0;
}
$level = intval($_POST['role']);
if ($level > 9) {
$level = 9;
} else if ($level < 0) {
$level = 0;
}
$SQL->query("UPDATE `user` SET `muted`='%d' AND `level`='%d' WHERE `username`='%s'", array($muted, $level, $username));
header("Content-Type: application/json");
echo json_encode(array("status" => TRUE, "modified" => $username));
@ -69,7 +96,9 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") {
"username" => $data['username'],
"name" => $data['name'],
"email" => $data['email'],
"role" => cavern_level_to_role($data['level'])
"level" => intval($data['level']),
"role" => cavern_level_to_role($data['level']),
"muted" => (($data["muted"] == 1) ? TRUE : FALSE)
);
} while ($user_query['row'] = $user_query['query']->fetch_assoc());
}

View File

@ -1,16 +1,264 @@
(() => {
function create(tag) {
return document.createElement(tag);
async function fetchUser(mode, data="") {
try {
switch (mode) {
case "list":
pageManager.setHeader("使用者列表");
var res = await axios.request({
url: "ajax/user.php",
method: "GET"
});
renderList(res.data);
break;
case "username":
pageManager.setHeader("修改資料");
var res = await axios.request({
url: "../ajax/user.php?username=" + data,
method: "GET"
});
renderForm(mode, res.data)
break;
case "add":
pageManager.setHeader("新增使用者");
renderForm(mode);
break;
}
} catch (e) {
console.error(e);
}
bindListener(mode);
setTimeout(() => {
pageManager.setLoaderState(false)
}, 1000);
}
function renderList(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 (user of data["list"]) {
let tr = create("tr");
(["username", "name", "email", "role", "muted"]).forEach((e, _i) => {
let td = create('td');
if (e != "name") td.classList.add("collapsing");
if (e == "muted") {
td.classList.add("center", "aligned");
if (user[e]) td.innerHTML = `<i class="negative ban icon"></i>`;
} else if (e == "email") {
td.innerHTML = `<a href="mailto:${user[e]}">${user[e]}</a>`;
} else {
td.textContent = user[e];
}
tr.appendChild(td);
});
let action = `<td class="left aligned collapsing">` +
`<a class="ts circular icon button" href="/user/${user['username']}" data-navigo><i class="pencil icon"></i></a>`;
if (user.level != 9) {
action += `<a class="ts negative circular icon button" href="./user/delete/${user['username']}" data-username="${user['username']}"><i class="user delete icon"></i></a>`;
}
action += `</td>`;
tr.insertAdjacentHTML("beforeend", action);
tbody.appendChild(tr);
}
table.appendChild(tbody);
wrapper.appendChild(table);
doc.appendChild(wrapper);
}
function renderForm(mode, data={}) {
let doc = pageManager.document;
doc.innerHTML = "";
let fieldName = {
"username": "帳號",
"name": "暱稱",
"email": "信箱",
"password": "密碼",
"role": "權限",
"muted": "禁言"
};
let levelRole = {
0: "會員",
1: "作者",
8: "管理員",
9: "站長"
};
let formContainer = create('div'); formContainer.className = "ts form";
let form = create('form'); form.method = "POST"; form.action = "ajax/user.php"; form.name = "config"; form.id = "config"; form.className = "clearfix";
form.autocomplete = "new-password";
if (mode == "username") {
var avatarSrc = `https://www.gravatar.com/avatar/${data["hash"]}?d=https%3A%2F%2Ftocas-ui.com%2Fassets%2Fimg%2F5e5e3a6.png&amp;s=500`;
form.insertAdjacentHTML("beforeend", `<div class="field">` +
`<label>頭貼</label><div class="ts center aligned flatted borderless segment">` +
`<img src="${avatarSrc}" class="ts rounded image" id="avatar"></div></div>`
);
}
Object.keys(fieldName).forEach((e, _i) => {
let field = create('div', "field");
let label = create('label');
label.textContent = fieldName[e];
if (e == "role") {
var input = create('select'); input.name = e;
[0, 1, 8, 9].forEach((opt, _i) => {
let option = create('option');
option.value = opt;
option.textContent = levelRole[opt];
if (data["level"] == opt) {
option.selected = "selected";
}
input.appendChild(option);
});
} else if (e == "password") {
var input = create('input'); input.name = e; input.type = "password";
} else if (e == "muted") {
var input = create('div', "ts toggle checkbox");
let checkbox = create('input'); checkbox.id = "muted"; checkbox.type = "checkbox";
checkbox.value = "on";
let label = create('label'); label.setAttribute("for", "muted");
if (data[e]) {
checkbox.checked = "checked";
}
input.appendChild(checkbox);
input.appendChild(label);
} else {
var input = create('input'); input.name = e; input.type = "text";
if (mode == "username") {
input.value = data[e];
}
}
if (e == "username" && mode == "username") {
input.disabled = "disabled";
}
field.appendChild(label);
field.appendChild(input);
form.appendChild(field);
});
form.insertAdjacentHTML("beforeend", `<input class="ts right floated primary button" value="送出" type="submit">`);
formContainer.appendChild(form);
doc.appendChild(formContainer);
}
function sendData(mode, data) {
let fd = new URLSearchParams(data).toString();
axios.request({
method: (mode == "add" ? "POST" : "PATCH"),
url: "ajax/user.php",
data: fd
}).then((res) => {
pageManager.snackbar("操作成功!");
router.navigate("/user");
}).catch((err) => {
switch (err.response.data.status) {
case "userexists":
pageManager.snackbar("使用者已經存在");
break;
case "nouser":
pageManager.snackbar("使用者不存在");
break;
case "noname":
pageManager.snackbar("請填寫暱稱");
break;
case "noemail":
pageManager.snackbar("請填寫信箱");
break;
case "emailused":
pageManager.snackbar("信箱已被其他使用者使用");
break;
default:
pageManager.snackbar("發生錯誤");
break;
}
});
}
function deleteUser(username) {
axios.request({
method: "DELETE",
url: "ajax/user.php?username=" + username
}).then((res) =>{
pageManager.snackbar("刪除成功。");
pageManager.load("user", "list");
}).catch((err) => {
switch (err.response.data.status) {
case "nouser":
pageManager.snackbar("使用者不存在");
break;
case "deleteowner":
pageManager.snackbar("你不能刪掉站長!");
break;
default:
pageManager.snackbar("刪除使用者時發生錯誤")
break;
}
});
}
function bindListener(mode) {
router.updatePageLinks();
if (mode == "list") {
$('tbody').on('click', 'a.negative', function(e) {
e.preventDefault();
let el = e.currentTarget;
let username = el.dataset.username;
showModal(username);
});
function showModal(username) {
swal({
type: 'question',
title: '確定要刪除嗎?',
showCancelButton: true,
confirmButtonText: '確定',
cancelButtonText: '取消'
}).then((result) => {
if (result.value) { // confirm
deleteUser(username);
}
});
}
} else {
$('form').on('submit', function (e) {
e.preventDefault();
sendData(mode, new FormData(this));
})
}
}
function create(tag, className="") {
let el = document.createElement(tag);
el.className = className;
return el;
}
pageManager.register("user", function () {
return {
render: function (...args) {
pageManager.setHeader("使用者");
setTimeout(() => {
pageManager.document.innerHTML = args[0];
pageManager.setLoaderState(false)
}, 500);
fetchUser(...args);
}
}
});