mirror of
https://github.com/Akif9748/akf-forum.git
synced 2024-11-22 20:10:40 +03:00
Added usermenu & hide last seen
This commit is contained in:
parent
02364c91ed
commit
47cda470e2
3 changed files with 111 additions and 92 deletions
|
@ -52,16 +52,15 @@ Akf-forum has got an API for AJAX (fetch), other clients etc. And, you can learn
|
||||||
- categories page is need a update, thread count in category
|
- categories page is need a update, thread count in category
|
||||||
- Disable last seen button for web.
|
- Disable last seen button for web.
|
||||||
- old contents / titles add to forum interface
|
- old contents / titles add to forum interface
|
||||||
- add ban button to user profile.
|
- add ban button to user profile.?
|
||||||
- change password.
|
- change password.
|
||||||
- add approval threads page.
|
- add approval threads page.
|
||||||
- who liked a message for web.
|
- who liked a message for web.
|
||||||
- edit config from web admin panel.
|
- edit config from web admin panel.
|
||||||
- user.state for ban, delete, etc.
|
|
||||||
- Add a feature list to README.md
|
- Add a feature list to README.md
|
||||||
- delete admin???
|
- delete admin???
|
||||||
- change category name
|
- change category name
|
||||||
|
- theme support++, directly edit html!
|
||||||
## Major Version History
|
## Major Version History
|
||||||
- V4: Caching
|
- V4: Caching
|
||||||
- V3: New Theme
|
- V3: New Theme
|
||||||
|
|
|
@ -38,7 +38,7 @@ app.patch("/:id", async (req, res) => {
|
||||||
if (req.user.id !== member.id && !user.admin) return res.error(403, "You have not got permission for this.");
|
if (req.user.id !== member.id && !user.admin) return res.error(403, "You have not got permission for this.");
|
||||||
if (!Object.keys(req.body).some(Boolean)) return res.error(400, "Missing member informations in request body.");
|
if (!Object.keys(req.body).some(Boolean)) return res.error(400, "Missing member informations in request body.");
|
||||||
|
|
||||||
const { name, about, theme, admin, deleted } = req.body;
|
const { name, about, theme, admin, deleted, hideLastSeen } = req.body;
|
||||||
|
|
||||||
if ((admin?.length || "deleted" in req.body) && !req.user.admin) return res.error(403, "You have not got permission for edit 'admin' and 'deleted' information, or bad request.");
|
if ((admin?.length || "deleted" in req.body) && !req.user.admin) return res.error(403, "You have not got permission for edit 'admin' and 'deleted' information, or bad request.");
|
||||||
const { names, desp } = req.app.get("limits");
|
const { names, desp } = req.app.get("limits");
|
||||||
|
@ -56,6 +56,9 @@ app.patch("/:id", async (req, res) => {
|
||||||
|
|
||||||
if (typeof admin === "boolean" || ["false", "true"].includes(admin)) member.admin = admin;
|
if (typeof admin === "boolean" || ["false", "true"].includes(admin)) member.admin = admin;
|
||||||
if (deleted === false) member.deleted = false;
|
if (deleted === false) member.deleted = false;
|
||||||
|
|
||||||
|
if (typeof hideLastSeen === "boolean") member.hideLastSeen = hideLastSeen;
|
||||||
|
|
||||||
member.edited = true;
|
member.edited = true;
|
||||||
|
|
||||||
res.complate(await member.save());
|
res.complate(await member.save());
|
||||||
|
@ -67,8 +70,8 @@ app.post("/:id/ban", async (req, res) => {
|
||||||
const { member } = req;
|
const { member } = req;
|
||||||
for (const ip of member.ips)
|
for (const ip of member.ips)
|
||||||
try {
|
try {
|
||||||
await BanModel.create({ ip, reason: `Ban for ${member.name}`, authorID: req.user.id });
|
await BanModel.create({ ip, reason: `Ban for ${member.name}`, authorID: req.user.id });
|
||||||
req.app.ips.push(ip);
|
req.app.ips.push(ip);
|
||||||
} catch {
|
} catch {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
189
views/user.ejs
189
views/user.ejs
|
@ -13,99 +13,116 @@
|
||||||
|
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<% if (!member.discordID && discord && user?.id === member.id) { %>
|
<% if(user?.admin || user?.id === member.id){ %>
|
||||||
<a href="<%=discord%>" class="btn-outline-primary">Auth with discord</a>
|
|
||||||
<% } else if(member.discordID && user?.id === member.id) { %>
|
|
||||||
<a class="btn-outline-primary" id="un_discord">Unauth with discord!</a>
|
|
||||||
<% } %>
|
|
||||||
<% if (user?.admin || user?.id === member.id) { %>
|
|
||||||
<a href="/users/<%=member.id%>/avatar" class="btn-outline-primary">Upload avatar</a>
|
|
||||||
<link rel="stylesheet" href="/css/modal.css" />
|
|
||||||
|
|
||||||
<a class="btn-outline-primary" id="toogle">Edit user!</a>
|
|
||||||
|
|
||||||
<div class="modal no-active" id="user-edit">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-close">
|
|
||||||
<i id="toogle" class="fa-solid fa-square-xmark"></i>
|
|
||||||
</div>
|
|
||||||
<h1 class="title" style="text-align:center;">Edit <a class="see" href="/users/<%= member.id %>"><%= member.name %></a></h1>
|
|
||||||
<div class="content">
|
|
||||||
<form id="form" class="see" style="box-shadow:none">
|
|
||||||
<input type="text" name="name" placeholder="<%=member.name%>" class="input">
|
|
||||||
|
|
||||||
<textarea class="input" name="about" rows="4" cols="60" name="content" placeholder="<%=member.about%>"></textarea>
|
|
||||||
<% if (user?.admin){ %>
|
|
||||||
Is Admin? <input id='admin' type='checkbox' value='true' name='admin' <%=member.admin ? "checked": ""%>>
|
|
||||||
<input id='adminHidden' type='hidden' value='false' name='admin'>
|
|
||||||
<% } %>
|
|
||||||
|
|
||||||
<button class="btn-primary" style="width:100%;">Update User!</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="module">
|
|
||||||
import request from "../../js/request.js";
|
|
||||||
|
|
||||||
const form = document.getElementById("form");
|
|
||||||
|
|
||||||
document.addEventListener("click", async e => {
|
|
||||||
if (e.target.id == "delete") {
|
|
||||||
const response = await request("/api/users/<%= member.id %>", "DELETE");
|
|
||||||
if (response.state !== "DELETED") return
|
|
||||||
alert("User is deleted!");
|
|
||||||
location.reload()
|
|
||||||
} else if (e.target.id == "undelete") {
|
|
||||||
const response = await request("/api/users/<%= member.id %>/", "PATCH", {
|
|
||||||
deleted: false
|
|
||||||
});
|
|
||||||
if (response.state == "DELETED") return;
|
|
||||||
alert("User is undeleted successfully!");
|
|
||||||
location.reload()
|
|
||||||
} else if (e.target.id == "un_discord") {
|
|
||||||
const response = await fetch("/auth/discord/", {
|
|
||||||
method: "DELETE"
|
|
||||||
});
|
|
||||||
alert(await response.text());
|
|
||||||
location.reload()
|
|
||||||
} else if (e.target.id == "toogle")
|
|
||||||
document.getElementById('user-edit').classList.toggle('no-active')
|
|
||||||
|
|
||||||
});
|
|
||||||
form.addEventListener("submit", async e => {
|
|
||||||
e.preventDefault();
|
|
||||||
document.getElementById('adminHidden').disabled = document.getElementById("admin").checked;
|
|
||||||
|
|
||||||
const object = {};
|
|
||||||
new FormData(e.target).forEach((value, key) => object[key] = value);
|
|
||||||
|
|
||||||
const res = await request("/api/users/<%=member.id%>", "PATCH", object);
|
|
||||||
if (res) alert(`User is updated!`);
|
|
||||||
location.reload();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<% } %>
|
|
||||||
|
|
||||||
<% if (member.deleted) {%>
|
|
||||||
<h1>This user has been deleted!</h1>
|
|
||||||
<a id="undelete" class="btn-primary">Undelete user! </a>
|
|
||||||
<% } else if (user?.admin){ %>
|
|
||||||
<a id="delete" class="btn-outline-primary">Delete user! </a>
|
|
||||||
<% } %>
|
|
||||||
<% if (user?.admin) {%>
|
|
||||||
<details>
|
<details>
|
||||||
<summary class="btn-outline-primary">IP adresses of user:</summary>
|
<summary class="btn-outline-primary">User Menu:</summary>
|
||||||
|
|
||||||
|
<% if (!member.discordID && discord && user?.id === member.id) { %>
|
||||||
|
<a href="<%=discord%>" class="btn-outline-primary">DC auth</a>
|
||||||
|
<% } else if(member.discordID && user?.id === member.id) { %>
|
||||||
|
<a class="btn-outline-primary" id="un_discord">Unauth DC!</a>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<a href="/users/<%=member.id%>/avatar" class="btn-outline-primary">Upload avatar</a>
|
||||||
|
<link rel="stylesheet" href="/css/modal.css" />
|
||||||
|
|
||||||
|
<a class="btn-outline-primary" id="toogle">Edit user!</a>
|
||||||
|
|
||||||
|
<div class="modal no-active" id="user-edit">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-close">
|
||||||
|
<i id="toogle" class="fa-solid fa-square-xmark"></i>
|
||||||
|
</div>
|
||||||
|
<h1 class="title" style="text-align:center;">Edit <a class="see" href="/users/<%= member.id %>"><%= member.name %></a></h1>
|
||||||
|
<div class="content">
|
||||||
|
<form id="form" class="see" style="box-shadow:none">
|
||||||
|
<input type="text" name="name" placeholder="<%=member.name%>" class="input">
|
||||||
|
|
||||||
|
<textarea class="input" name="about" rows="4" cols="60" name="content" placeholder="<%=member.about%>"></textarea>
|
||||||
|
<% if (user?.admin){ %>
|
||||||
|
Is Admin? <input id='admin' type='checkbox' value='true' name='admin' <%=member.admin ? "checked": ""%>>
|
||||||
|
<input id='adminHidden' type='hidden' value='false' name='admin'>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
<button class="btn-primary" style="width:100%;">Update User!</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
import request from "../../js/request.js";
|
||||||
|
|
||||||
|
const form = document.getElementById("form");
|
||||||
|
|
||||||
|
document.addEventListener("click", async e => {
|
||||||
|
if (e.target.id == "delete") {
|
||||||
|
const response = await request("/api/users/<%= member.id %>", "DELETE");
|
||||||
|
if (response.state !== "DELETED") return
|
||||||
|
alert("User is deleted!");
|
||||||
|
location.reload()
|
||||||
|
} else if (e.target.id == "undelete") {
|
||||||
|
const response = await request("/api/users/<%= member.id %>/", "PATCH", {
|
||||||
|
deleted: false
|
||||||
|
});
|
||||||
|
if (response.state == "DELETED") return;
|
||||||
|
alert("User is undeleted successfully!");
|
||||||
|
location.reload()
|
||||||
|
} else if (e.target.id == "un_discord") {
|
||||||
|
const response = await fetch("/auth/discord/", {
|
||||||
|
method: "DELETE"
|
||||||
|
});
|
||||||
|
alert(await response.text());
|
||||||
|
location.reload()
|
||||||
|
} else if (e.target.id.startsWith("last_")) {
|
||||||
|
let hideLastSeen = e.target.id.replace("last_", "") == "hide" ? true : false;
|
||||||
|
const response = await request("/api/users/<%= member.id %>/", "PATCH", {
|
||||||
|
hideLastSeen
|
||||||
|
});
|
||||||
|
alert(`Last seen is ${!hideLastSeen?"un":""}hided!`);
|
||||||
|
location.reload()
|
||||||
|
|
||||||
|
} else if (e.target.id == "toogle")
|
||||||
|
document.getElementById('user-edit').classList.toggle('no-active')
|
||||||
|
|
||||||
|
});
|
||||||
|
form.addEventListener("submit", async e => {
|
||||||
|
e.preventDefault();
|
||||||
|
document.getElementById('adminHidden').disabled = document.getElementById("admin").checked;
|
||||||
|
|
||||||
|
const object = {};
|
||||||
|
new FormData(e.target).forEach((value, key) => object[key] = value);
|
||||||
|
|
||||||
|
const res = await request("/api/users/<%=member.id%>", "PATCH", object);
|
||||||
|
if (res) alert(`User is updated!`);
|
||||||
|
location.reload();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<% if (member.hideLastSeen) {%>
|
||||||
|
<a id="last_unhide" class="btn-primary">Unhide last seen! </a>
|
||||||
|
<% } else { %>
|
||||||
|
<a id="last_hide" class="btn-outline-primary">Hide last seen! </a>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
<% if (member.deleted) {%>
|
||||||
|
<h1>This user has been deleted!</h1>
|
||||||
|
<a id="undelete" class="btn-primary">Undelete user! </a>
|
||||||
|
<% } else if (user?.admin){ %>
|
||||||
|
<a id="delete" class="btn-outline-primary">Delete user! </a>
|
||||||
|
<% } %>
|
||||||
|
<% if (user?.admin) {%>
|
||||||
|
<h2>IP adresses of the user:</h2>
|
||||||
<select>
|
<select>
|
||||||
<% for(const ip of member.ips) { %>
|
<% for(const ip of member.ips) { %>
|
||||||
<option><%= ip %></option>
|
<option><%= ip %></option>
|
||||||
<% } %>
|
<% } %>
|
||||||
</select>
|
</select>
|
||||||
</details>
|
|
||||||
|
|
||||||
|
<% } %>
|
||||||
|
</details>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
<div class="box" style="justify-content:center;">
|
<div class="box" style="justify-content:center;">
|
||||||
|
|
Loading…
Reference in a new issue