348 lines
12 KiB
Cheetah
348 lines
12 KiB
Cheetah
{{define "content"}}
|
|
<div class="tcontent-container">
|
|
<div class="team-card-container">
|
|
<div class="tcard">
|
|
<div class="tcard-title">
|
|
<span>Support Teams</span>
|
|
</div>
|
|
<div class="tcard-body">
|
|
<h2><b>Create Team</b></h2>
|
|
<div id="team-creation-wrapper">
|
|
<form class="team-creation-form" onsubmit="createTeam(); return false">
|
|
<input type="text" class="form-control team-creation-name" id="team-creation-name" placeholder="Team Name">
|
|
<button class="btn btn-primary btn-fill" type="submit" style="margin-left: 2%"><i class="fas fa-paper-plane"></i> Create</button>
|
|
</form>
|
|
</div>
|
|
|
|
<h2 style="margin-top: 2%"><b>Manage Teams</b></h2>
|
|
<div class="flex-center">
|
|
<div class="dropdown" style="width: 100%">
|
|
<button class="btn btn-primary btn-fill dropdown-toggle" type="button" id="teamDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="width: 100%">
|
|
Select a team
|
|
</button>
|
|
|
|
<div class="dropdown-menu" id="team-selector" aria-labelledby="teamDropdown" style="width: 100%">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="columns">
|
|
<div class="column" style="padding-right: 1%">
|
|
<h3>Manage Members</h3>
|
|
<table class="table table-hover">
|
|
<tbody id="members-body">
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="column" style="padding-left: 1%">
|
|
<div class="trow" style="position: relative">
|
|
<h3>Add Member</h3>
|
|
<div class="inline">
|
|
<input type="text" class="form-control add-search" id="add-search-user" placeholder="Username">
|
|
<button type="button" class="btn btn-primary btn-fill add-search-btn" id="user-search-btn" onclick="searchUser()"><i class="fas fa-search search-icon"></i></button>
|
|
</div>
|
|
|
|
<div id="user-dropdown-wrapper">
|
|
<select id="add-search-user-dropdown" class="search-dropdown" size="4"></select>
|
|
<button type="button" class="btn btn-primary btn-fill add-button" onclick="addUser()"><i class="fas fa-plus"></i> Add Selected User</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="trow" style="position:relative;">
|
|
<h3>Add Role</h3>
|
|
<div class="inline">
|
|
<input
|
|
type="text" class="form-control add-search" id="add-search-role" placeholder="Role Name"
|
|
oninput="updateRoleSearch()" onfocusin="showRoleDropdown()">
|
|
|
|
<div id="role-dropdown-wrapper">
|
|
<select id="add-search-role-dropdown" class="search-dropdown" size="4"></select>
|
|
<button type="button" class="btn btn-primary btn-fill add-button" onclick="addRole()"><i class="fas fa-plus"></i> Add Selected Role</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
let activeTeam = 'default';
|
|
let roles = [];
|
|
|
|
function showUserDropdown() {
|
|
const dropdown = document.getElementById('user-dropdown-wrapper');
|
|
dropdown.style.display = 'block';
|
|
|
|
const input = document.getElementById('add-search-user');
|
|
input.style.borderBottomLeftRadius = '0';
|
|
|
|
const searchBtn = document.getElementById('user-search-btn');
|
|
searchBtn.style.borderBottomRightRadius = '0';
|
|
}
|
|
|
|
function hideUserDropdown() {
|
|
const dropdown = document.getElementById('user-dropdown-wrapper');
|
|
dropdown.style.display = 'none';
|
|
|
|
const input = document.getElementById('add-search-user');
|
|
input.style.borderBottomLeftRadius = '4px';
|
|
|
|
const searchBtn = document.getElementById('user-search-btn');
|
|
searchBtn.style.borderBottomRightRadius = '0.25rem';
|
|
}
|
|
|
|
function showRoleDropdown() {
|
|
const dropdown = document.getElementById('role-dropdown-wrapper');
|
|
dropdown.style.display = 'block';
|
|
|
|
const input = document.getElementById('add-search-role');
|
|
input.style.borderBottomLeftRadius = '0';
|
|
|
|
updateRoleSearch();
|
|
}
|
|
|
|
function hideRoleDropdown() {
|
|
const dropdown = document.getElementById('role-dropdown-wrapper');
|
|
dropdown.style.display = 'none';
|
|
|
|
const input = document.getElementById('add-search-role');
|
|
input.style.borderBottomLeftRadius = '4px';
|
|
}
|
|
|
|
function updateRoleSearch() {
|
|
const input = document.getElementById('add-search-role');
|
|
|
|
const dropdown = document.getElementById('add-search-role-dropdown');
|
|
dropdown.innerHTML = '';
|
|
|
|
roles.filter((role) => role.name.toLowerCase().includes(input.value.toLowerCase())).forEach((role) => {
|
|
const option = createElement('option', 'search-dropdown-item');
|
|
option.id = role.id;
|
|
option.appendChild(document.createTextNode(role.name));
|
|
dropdown.appendChild(option);
|
|
});
|
|
}
|
|
|
|
async function searchUser() {
|
|
showUserDropdown();
|
|
|
|
const query = document.getElementById('add-search-user').value;
|
|
|
|
const res = await axios.get('/api/{{.guildId}}/members/search?query=' + encodeURIComponent(query));
|
|
if (res.status !== 200) {
|
|
if (res.status === 429){
|
|
notifyRatelimit();
|
|
} else {
|
|
notifyError(res.data.error);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
const dropdown = document.getElementById('add-search-user-dropdown');
|
|
dropdown.innerHTML = '';
|
|
for (const member of res.data) {
|
|
const option = createElement('option', 'search-dropdown-item');
|
|
option.id = member.user.id;
|
|
option.appendChild(document.createTextNode(`${member.user.username}#${member.user.discriminator}`));
|
|
dropdown.appendChild(option);
|
|
}
|
|
}
|
|
|
|
async function addUser() {
|
|
const dropdown = document.getElementById('add-search-user-dropdown');
|
|
const option = dropdown.options[dropdown.selectedIndex];
|
|
|
|
if (option === undefined) {
|
|
notifyError("You need to select a user");
|
|
return;
|
|
}
|
|
|
|
const res = await axios.put('/api/{{.guildId}}/team/' + activeTeam + '/' + option.id + '?type=0');
|
|
if (res.status !== 200) {
|
|
notifyError(res.data.error);
|
|
return;
|
|
}
|
|
|
|
await displayTeam(activeTeam);
|
|
notifySuccess("Added user to support team!")
|
|
}
|
|
|
|
async function addRole() {
|
|
const dropdown = document.getElementById('add-search-role-dropdown');
|
|
const option = dropdown.options[dropdown.selectedIndex];
|
|
|
|
if (option === undefined) {
|
|
notifyError("You need to select a role");
|
|
return;
|
|
}
|
|
|
|
const res = await axios.put('/api/{{.guildId}}/team/' + activeTeam + '/' + option.id + '?type=1');
|
|
if (res.status !== 200) {
|
|
notifyError(res.data.error);
|
|
return;
|
|
}
|
|
|
|
await displayTeam(activeTeam);
|
|
notifySuccess("Added role to support team!")
|
|
}
|
|
|
|
// hide user dropdown
|
|
window.addEventListener('click', (e) => {
|
|
const allowedElements = ['search-dropdown', 'search-dropdown-item', 'add-button', 'add-search-btn', 'add-search', 'search-icon'];
|
|
|
|
const wrapper = document.getElementById('user-dropdown-wrapper');
|
|
if (window.getComputedStyle(wrapper).display !== 'none') {
|
|
if(!allowedElements.some((clazz) => e.target.classList.contains(clazz))) {
|
|
hideUserDropdown();
|
|
}
|
|
}
|
|
});
|
|
|
|
// hide role dropdown
|
|
window.addEventListener('click', (e) => {
|
|
const allowedElements = ['search-dropdown', 'search-dropdown-item', 'add-button', 'add-search'];
|
|
|
|
const wrapper = document.getElementById('role-dropdown-wrapper');
|
|
if (window.getComputedStyle(wrapper).display !== 'none') {
|
|
if(!allowedElements.some((clazz) => e.target.classList.contains(clazz))) {
|
|
hideRoleDropdown();
|
|
}
|
|
}
|
|
});
|
|
|
|
async function displayTeam(id) {
|
|
const res = await axios.get('/api/{{.guildId}}/team/' + id);
|
|
if (res.status !== 200) {
|
|
if (res.status === 429){
|
|
notifyRatelimit();
|
|
} else {
|
|
notifyError(res.data.error);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
activeTeam = id;
|
|
|
|
const table = document.getElementById('members-body');
|
|
table.innerHTML = '';
|
|
if (res.data) {
|
|
for (const entity of res.data) {
|
|
const tr = document.createElement('tr');
|
|
appendTd(tr, entity.name);
|
|
appendButton(tr, "Remove", () => removeMember(id, entity.id, entity.type), 'float-right');
|
|
table.appendChild(tr);
|
|
}
|
|
}
|
|
}
|
|
|
|
async function removeMember(teamId, snowflake, entityType) {
|
|
const res = await axios.delete('/api/{{.guildId}}/team/' + teamId + '/' + snowflake + '?type=' + entityType);
|
|
if (res.status !== 200) {
|
|
if (res.status === 429){
|
|
notifyRatelimit();
|
|
} else {
|
|
notifyError(res.data.error);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (entityType === 0) { // user
|
|
notifySuccess("Support user removed successfully")
|
|
} else if (entityType === 1) { //role
|
|
notifySuccess("Support role removed successfully")
|
|
}
|
|
|
|
await displayTeam(activeTeam);
|
|
}
|
|
|
|
async function createTeam() {
|
|
const input = document.getElementById('team-creation-name');
|
|
const data = {
|
|
name: input.value
|
|
};
|
|
|
|
const res = await axios.post('/api/{{.guildId}}/team', data);
|
|
if (res.status !== 200) {
|
|
if (res.status === 429){
|
|
notifyRatelimit();
|
|
} else {
|
|
notifyError(res.data.error);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
input.value = '';
|
|
await loadTeams();
|
|
notifySuccess("Team created successfully");
|
|
}
|
|
|
|
async function deleteTeam(id) {
|
|
const res = await axios.delete('/api/{{.guildId}}/team/' + id);
|
|
if (res.status !== 200) {
|
|
notifyError(res.data.error);
|
|
return;
|
|
}
|
|
|
|
notifySuccess("Team deleted successfully");
|
|
await displayTeam('default');
|
|
}
|
|
|
|
function appendTeam(id, name) {
|
|
const wrapper = document.getElementById('team-selector');
|
|
|
|
const option = createElement('a', 'dropdown-item', 'team-item');
|
|
option.onclick = () => displayTeam(id);
|
|
option.appendChild(document.createTextNode(name));
|
|
|
|
if (id !== 'default') {
|
|
const deleteIcon = createElement('i', 'fas', 'fa-window-close', 'delete-team-icon');
|
|
deleteIcon.onclick = () => deleteTeam(id);
|
|
option.appendChild(deleteIcon);
|
|
}
|
|
|
|
wrapper.appendChild(option);
|
|
}
|
|
|
|
async function loadTeams() {
|
|
const res = await axios.get('/api/{{.guildId}}/team');
|
|
if (res.status !== 200) {
|
|
notifyError(res.data.error);
|
|
return;
|
|
}
|
|
|
|
const wrapper = document.getElementById('team-selector');
|
|
wrapper.innerHTML = '';
|
|
|
|
appendTeam('default', 'Default');
|
|
for (const team of res.data) {
|
|
appendTeam(team.id, team.name);
|
|
}
|
|
}
|
|
|
|
async function loadRoles() {
|
|
const res = await axios.get('/api/{{.guildId}}/roles');
|
|
if (res.status !== 200) {
|
|
notifyError(res.data.error);
|
|
return;
|
|
}
|
|
|
|
roles = res.data.roles;
|
|
}
|
|
|
|
async function loadData() {
|
|
await loadRoles();
|
|
await loadTeams();
|
|
await displayTeam('default');
|
|
}
|
|
|
|
withLoadingScreen(loadData);
|
|
</script>
|
|
{{end}} |