Finished polishing site-wide admin control panel

This commit is contained in:
rainbow napkin 2026-10-28 21:48:49 -04:00
parent 3c37080cb7
commit 441fb56f37
6 changed files with 136 additions and 12 deletions

View file

@ -23,8 +23,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. %>
</head> </head>
<body> <body>
<%- include('partial/navbar', {user}); %> <%- include('partial/navbar', {user}); %>
<h1 class="panel-title"><%= instance %> Admin Panel</h1> <div id="admin-panel-list-container">
<div id="admin-nav-list">
</div>
<div class="admin-panel-container-div"> <div class="admin-panel-container-div">
<h1 class="panel-title"><%= instance %> Admin Panel</h1>
<div class="admin-panel-list-container-div">
<%- include('partial/adminPanel/channelList', {chanGuide, unescape}) %> <%- include('partial/adminPanel/channelList', {chanGuide, unescape}) %>
<%- include('partial/adminPanel/userList', {user, userList, rankEnum, unescape}) %> <%- include('partial/adminPanel/userList', {user, userList, rankEnum, unescape}) %>
<%- include('partial/adminPanel/permList', {permList, rankEnum}) %> <%- include('partial/adminPanel/permList', {permList, rankEnum}) %>
@ -32,6 +36,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. %>
<%- include('partial/adminPanel/tokeCommandList') %> <%- include('partial/adminPanel/tokeCommandList') %>
<%- include('partial/adminPanel/emoteList') %> <%- include('partial/adminPanel/emoteList') %>
</div> </div>
</div>
</div>
</body> </body>
<footer> <footer>
<%- include('partial/scripts', {user}); %> <%- include('partial/scripts', {user}); %>

View file

@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. %>
<h3>Permissions:</h3> <h3>Permissions:</h3>
<div class="dynamic-container"> <div class="dynamic-container">
<form action="javascript:" id="admin-perm-list-field" class="admin-list-field"> <form action="javascript:" id="admin-perm-list-field" class="admin-list-field">
<h4 class="admin-list-field-container">Global Permissions:</h4>
<% Object.keys(permList).forEach((key)=>{ %> <% Object.keys(permList).forEach((key)=>{ %>
<% if(key != "channelOverrides"){ %> <% if(key != "channelOverrides"){ %>
<span class="admin-list-field-container"> <span class="admin-list-field-container">
@ -29,6 +30,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. %>
</span> </span>
<% } %> <% } %>
<% }); %> <% }); %>
</form>
<form action="javascript:" id="admin-perm-list-field" class="admin-list-field">
<h4 class="admin-list-field-container">Channel Overrides:</h4> <h4 class="admin-list-field-container">Channel Overrides:</h4>
<% Object.keys(permList.channelOverrides).forEach((key)=>{ %> <% Object.keys(permList.channelOverrides).forEach((key)=>{ %>
<% if(key != "channelOverrides"){ %> <% if(key != "channelOverrides"){ %>

View file

@ -14,20 +14,49 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.*/ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
/* We should turn this into a base style shared with the version used in the profile page*/
.admin-list-div{ .admin-list-div{
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin: 0 0.5em; margin: 0 0.5em;
} }
.admin-panel-container-div{ /*Little hacky but this keeps initial max-height from fucking up resizing*/
margin: 0 auto 5em; .admin-list-div div.dynamic-container.resizable:not([style*="height"]){
height: 68vh;
max-height: 68vh;
}
.admin-panel-list-container-div{
margin: 0 auto;
max-width: 100%; max-width: 100%;
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(45em, 1fr)); grid-template-columns: repeat(auto-fit, minmax(45em, 1fr));
} }
#admin-nav-list {
position: sticky;
top: 0;
bottom: 0;
left: 0;
width: 7.5em;
margin: 4em 1em 0 0;
}
#admin-nav-list button{
height: 3.5em;
width:100%;
text-align: center;
}
#admin-panel-list-container {
display: flex;
}
.admin-panel-container-div{
width: 100%;
}
.admin-list-entry-title-row{ .admin-list-entry-title-row{
box-shadow: none; box-shadow: none;
@ -58,6 +87,11 @@ img.admin-list-entry-item{
margin-bottom: 0.5em; margin-bottom: 0.5em;
} }
div#admin-perm-list-div div.dynamic-container{
display: flex;
justify-content: space-evenly;
}
.admin-perm-list-rank-select, .admin-chan-perm-list-rank-select{ .admin-perm-list-rank-select, .admin-chan-perm-list-rank-select{
width: 5em; width: 5em;
margin-left: 1em; margin-left: 1em;
@ -192,7 +226,6 @@ i.toke-command-list{
padding: 1em; padding: 1em;
overflow-y: auto; overflow-y: auto;
justify-items: center; justify-items: center;
max-height: 19.8em;
} }
div.emote-list-emote{ div.emote-list-emote{

View file

@ -274,6 +274,21 @@ a.admin-list-entry-item{
color: var(--accent1); color: var(--accent1);
} }
#admin-nav-list{
border-top: 1px var(--accent1) solid;
}
#admin-nav-list button{
border-radius: 0;
border-right: 1px var(--accent1) solid;
border-bottom: 1px var(--accent1) solid;
}
#admin-nav-list button:not(.positive-button, :hover){
background-color: var(--bg1);
color: var(--accent1);
}
div.control-prompt{ div.control-prompt{
border-radius: 1em; border-radius: 1em;
background-color: white; background-color: white;

View file

@ -294,6 +294,20 @@ a.admin-list-entry-item{
color: var(--accent1); color: var(--accent1);
} }
#admin-nav-list{
border-top: 1px var(--accent1) solid;
}
#admin-nav-list button{
border-radius: 0;
border-right: 1px var(--accent1) solid;
border-bottom: 1px var(--accent1) solid;
}
#admin-nav-list button:not(.positive-button, :hover){
background-image: var(--bg1-gradient);
}
div.control-prompt{ div.control-prompt{
border-radius: 0.2em; border-radius: 0.2em;
background-color: var(--bg2); background-color: var(--bg2);

View file

@ -14,6 +14,58 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.*/ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
class adminNavButtons{
constructor(){
this.navList = document.querySelector("#admin-nav-list");
this.buttons = new Map();
this.options = new Map([
["Channels", document.querySelector("#admin-channel-list-div")],
["Users", document.querySelector("#admin-user-list-div")],
["Global Permissions", document.querySelector("#admin-perm-list-div")],
["Global Bans", document.querySelector("#admin-ban-list-div")],
["Global Tokes", document.querySelector("#toke-command-list-div")],
["Global Emotes", document.querySelector("#emote-list-div")],
]);
//Render out buttons
this.renderButtons();
//Select the first option in the options map
this.displayOption(Array.from(this.options.keys())[0]);
}
renderButtons(){
//For erry list in the admin panel
for(const option of this.options.keys()){
//Create a button for it
const button = document.createElement('button');
button.innerText = option;
//Attatch an event listener to handle users clickin' der button
button.addEventListener('click',()=>{this.displayOption(option)});
//Drop button in the buttons map
this.buttons.set(option, button);
//Add that shit
this.navList.appendChild(button);
}
}
displayOption(selectedOption){
//For every option
for(const option of this.options.keys()){
//If we're on the selected option
if(option == selectedOption){
this.options.get(option).style.display = 'flex';
this.buttons.get(option).classList.add('positive-button');
}else{
this.options.get(option).style.display = 'none';
this.buttons.get(option).classList.remove('positive-button');
}
}
}
}
class adminUserList{ class adminUserList{
constructor(){ constructor(){
this.userNames = document.querySelectorAll(".admin-user-list-name"); this.userNames = document.querySelectorAll(".admin-user-list-name");
@ -500,6 +552,7 @@ class adminEmoteList{
} }
} }
const navButton = new adminNavButtons();
const userList = new adminUserList(); const userList = new adminUserList();
const permissionList = new adminPermissionList(); const permissionList = new adminPermissionList();
const userBanList = new adminUserBanList(); const userBanList = new adminUserBanList();