2021-02-17 12:01:36 +00:00

512 lines
22 KiB
Cheetah

{{define "content"}}
<script src="/assets/js/modalbackdrop.js"></script>
{{template "substitutions" .}}
<div class="content">
<div class="container-fluid">
<div class="row">
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h4 class="card-title">Settings</h4>
</div>
<div class="card-body">
<form onsubmit="updateSettings(); return false;">
<div class="row">
<div class="col-md-2 pr-1">
<div class="form-group">
<label>Prefix (Max len. 8)</label>
<input name="prefix" type="text" class="form-control" placeholder="t!" id="prefix">
</div>
</div>
<div class="col-md-1 px-1">
<div class="form-group">
<label>Ticket Limit</label>
<select class="custom-select mr-sm-2" id="ticket_limit" name="ticketlimit">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
</select>
</div>
</div>
<div class="col-md-3 px-1">
<div class="form-group">
<label>Ping @everyone on ticket open</label>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="pingeveryone" value="on"
id="ping_everyone" style="width:30px;height:30px;">
</div>
</div>
</div>
<div class="col-md-2 px-1">
<div class="form-group">
<label>Allow users to close tickets</label>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="userscanclose" value="on"
id="users_can_close" style="width:30px;height:30px;">
</div>
</div>
</div>
<div class="col-md-2 px-1">
<div class="form-group">
<label>Ticket close confirmation</label>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="on"
id="close_confirmation" style="width:30px;height:30px;">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<label>Welcome Message (Max len. 1000)
<i class="fas fa-question pointer" onclick="showSubstitutionModal()"></i>
</label>
<textarea name="welcomeMessage" class="form-control" rows="3" id="welcome_message"></textarea>
</div>
</div>
<div class="row">
<div class="col-md-4 pr-1">
<label>Archive Channel</label>
<div class="input-group mb-3">
<div class="input-group-prepend">
<div class="input-group-text">#</div>
</div>
<select class="form-control" name="archive_channel" id="archive_channel">
</select>
</div>
</div>
<div class="col-md-4 px-1">
<div class="form-group">
<label>Channel Category</label>
<select class="form-control" name="category" id="category">
</select>
</div>
</div>
</div>
<label>Ticket Naming Scheme</label>
<div class="form-check">
<input class="form-check-input" type="radio" name="namingscheme" id="naming-by-id" value="id">
<label class="form-check-label white" for="naming-by-id">
Ticket ID (#ticket-1)
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="namingscheme" id="naming-by-username"
value="username">
<label class="form-check-label white" for="naming-by-username">
Username (#ryan-1)
</label>
</div>
<div class="row">
<div class="col-md-2 pr-1">
<div class="form-group">
<button class="btn btn-primary btn-fill" type="submit"><i class="fas fa-paper-plane"></i>
Submit
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<!-- Claim settings -->
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h4 class="card-title">Claim Settings</h4>
</div>
<div class="card-body">
<form onsubmit="updateClaimSettings(); return false;">
<div class="row">
<div class="col-md-6 pr-1">
<div class="form-group">
<label>Support Reps Can View Claimed Tickets</label>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="can_view" value="on" id="can_view"
style="width:30px;height:30px;" onclick="canViewChanged();">
</div>
</div>
</div>
<div class="col-md-6 pr-1">
<div class="form-group">
<label>Support Reps Can Type In Claimed Tickets</label>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="can_type" value="on" id="can_type"
style="width:30px;height:30px;">
</div>
</div>
</div>
</div>
<div class="row" style="padding-top: 20px">
<div class="col-md-12 pr-1">
<div class="form-group">
<button class="btn btn-primary btn-fill" type="submit"><i class="fas fa-paper-plane"></i>
Submit
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<div aria-live="polite" aria-atomic="true" style="position: relative;">
<div style="position: absolute; right: 10px" id="toast-container">
</div>
</div>
<div class="row">
<!-- Autoclose settings -->
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h4 class="card-title">Auto-Close</h4>
<div class="alert alert-danger">This feature is currently disabled. Changing the settings below may not currently be fully functional</div>
</div>
<div class="card-body">
<form onsubmit="updateAutoCloseSettings(); return false;">
<div class="row">
<div class="col-md-1 pr-1">
<div class="form-group">
<label>Enabled</label>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="enabled" value="on" id="autoclose_enabled"
style="width:30px;height:30px;">
</div>
</div>
</div>
<div class="col-md-2 pr-1">
<div class="form-group">
<label>Close on user leave</label>
<div class="form-check">
<input class="form-check-input" type="checkbox" name="enabled" value="on"
id="autoclose_on_user_leave" style="width:30px;height:30px;">
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label>Time since open with no message</label>
<div class="row">
<div class="input-group col-md-4">
<input type="text" class="form-control" id="sinceopen_days">
<div class="input-group-append">
<div class="input-group-text">d</div>
</div>
</div>
<div class="input-group col-md-4">
<input type="text" class="form-control" id="sinceopen_hours">
<div class="input-group-append">
<div class="input-group-text">h</div>
</div>
</div>
<div class="input-group col-md-4">
<input type="text" class="form-control" id="sinceopen_minutes">
<div class="input-group-append">
<div class="input-group-text">m</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label>Time since last message</label>
<div class="row">
<div class="input-group col-md-4">
<input type="text" class="form-control" id="sincelast_days">
<div class="input-group-append">
<div class="input-group-text">d</div>
</div>
</div>
<div class="input-group col-md-4">
<input type="text" class="form-control" id="sincelast_hours">
<div class="input-group-append">
<div class="input-group-text">h</div>
</div>
</div>
<div class="input-group col-md-4">
<input type="text" class="form-control" id="sincelast_minutes">
<div class="input-group-append">
<div class="input-group-text">m</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row" style="padding-top: 20px">
<div class="col-md-2 pr-1">
<div class="form-group">
<button class="btn btn-primary btn-fill" type="submit"><i class="fas fa-paper-plane"></i>
Submit
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
async function getSettings() {
const res = await axios.get('/api/{{.guildId}}/settings');
return res.data;
}
async function getChannels() {
const res = await axios.get('/api/{{.guildId}}/channels');
return res.data;
}
async function fillArchiveChannels(channels, archiveChannelId) {
const container = document.getElementById('archive_channel');
channels.filter((ch) => ch.type === 0).forEach((ch) => {
const node = document.createElement("option");
const text = document.createTextNode(ch.name);
node.appendChild(text);
node.value = ch.id;
if (archiveChannelId === ch.id) {
node.selected = true;
}
container.appendChild(node);
});
}
async function fillCategories(channels, categoryId) {
const container = document.getElementById('category');
channels.filter((ch) => ch.type === 4).forEach((ch) => {
const node = document.createElement("option");
const text = document.createTextNode(ch.name);
node.appendChild(text);
node.value = ch.id;
if (categoryId === ch.id) {
node.selected = true;
}
container.appendChild(node);
});
}
async function loadData() {
const settings = await getSettings();
if (settings.ticket_limit < 1) {
settings.ticket_limit = 5;
}
document.getElementById("prefix").value = settings.prefix;
document.getElementById("welcome_message").value = settings.welcome_message;
document.getElementById("ticket_limit").selectedIndex = settings.ticket_limit - 1;
document.getElementById("ping_everyone").checked = settings.ping_everyone;
document.getElementById("users_can_close").checked = settings.users_can_close;
document.getElementById("close_confirmation").checked = settings.close_confirmation;
if (settings.naming_scheme === "username") {
document.getElementById("naming-by-username").checked = true;
} else {
document.getElementById("naming-by-id").checked = true;
}
const channels = await getChannels();
await fillArchiveChannels(channels, settings.archive_channel);
await fillCategories(channels, settings.category);
}
</script>
<script>
async function getClaimSettings() {
const res = await axios.get('/api/{{.guildId}}/claimsettings');
return res.data;
}
async function loadClaimSettings() {
const settings = await getClaimSettings();
document.getElementById('can_view').checked = settings.support_can_view;
document.getElementById('can_type').checked = settings.support_can_type;
}
async function updateClaimSettings() {
const data = {
support_can_view: document.getElementById('can_view').checked,
support_can_type: document.getElementById('can_type').checked
};
const res = await axios.post('/api/{{.guildId}}/claimsettings', data);
if (res.status === 200 && res.data.success) {
notifySuccess("Your settings have been saved.");
} else {
notifyError(res.data.error);
}
}
function canViewChanged() {
const isChecked = document.getElementById('can_view').checked;
if (isChecked) {
document.getElementById('can_type').disabled = false;
} else {
document.getElementById('can_type').disabled = true;
document.getElementById('can_type').checked = false;
}
}
</script>
<script>
const minuteNanos = 60 * 1000 * 1000 * 1000;
const hourNanos = 60 * minuteNanos;
const dayNanos = 24 * hourNanos;
function fromNanoSeconds(nanoseconds) {
const days = Math.floor(nanoseconds / dayNanos);
nanoseconds -= (days * dayNanos);
const hours = Math.floor(nanoseconds / hourNanos);
nanoseconds -= (hours * hourNanos);
const minutes = Math.floor(nanoseconds / minuteNanos);
return [days, hours, minutes];
}
async function loadAutoCloseSettings() {
const res = await axios.get('/api/{{.guildId}}/autoclose');
const settings = res.data;
document.getElementById('autoclose_enabled').checked = settings.enabled;
document.getElementById('autoclose_on_user_leave').checked = settings.on_user_leave;
const sinceOpen = fromNanoSeconds(settings.since_open_with_no_response);
document.getElementById('sinceopen_days').value = sinceOpen[0];
document.getElementById('sinceopen_hours').value = sinceOpen[1];
document.getElementById('sinceopen_minutes').value = sinceOpen[2];
const sinceLast = fromNanoSeconds(settings.since_last_message);
document.getElementById('sincelast_days').value = sinceLast[0];
document.getElementById('sincelast_hours').value = sinceLast[1];
document.getElementById('sincelast_minutes').value = sinceLast[2];
}
function toNanoSeconds(days, hours, minutes) {
return days * dayNanos + hours * hourNanos + minutes * minuteNanos;
}
async function updateAutoCloseSettings() {
const data = {
enabled: document.getElementById('autoclose_enabled').checked,
on_user_leave: document.getElementById('autoclose_on_user_leave').checked,
since_open_with_no_response: toNanoSeconds(document.getElementById('sinceopen_days').value, document.getElementById('sinceopen_hours').value, document.getElementById('sinceopen_minutes').value),
since_last_message: toNanoSeconds(document.getElementById('sincelast_days').value, document.getElementById('sincelast_hours').value, document.getElementById('sincelast_minutes').value),
};
const res = await axios.post('/api/{{.guildId}}/autoclose', data);
if (res.status !== 200 || !res.data.success) {
notifyError(res.data.error);
return;
}
notifySuccess('Auto close settings updated');
}
</script>
<script>
async function updateSettings() {
const data = {
'prefix': document.getElementById('prefix').value,
'welcome_message': document.getElementById("welcome_message").value,
'ticket_limit': parseInt(document.getElementById('ticket_limit').options[document.getElementById('ticket_limit').selectedIndex].value),
'ping_everyone': document.getElementById("ping_everyone").checked,
'users_can_close': document.getElementById("users_can_close").checked,
'close_confirmation': document.getElementById("close_confirmation").checked,
'naming_scheme': document.querySelector('input[name="namingscheme"]:checked').value,
'archive_channel': document.getElementById('archive_channel').options[document.getElementById('archive_channel').selectedIndex].value,
'category': document.getElementById('category').options[document.getElementById('category').selectedIndex].value
};
const res = await axios.post('/api/{{.guildId}}/settings', data);
if (res.status === 200) {
const success = showValidations(res.data);
if (success) {
notifySuccess("Your settings have been saved.");
}
} else {
notifyError("A severe error occurred. Please check your console for more information.");
console.log(res);
}
}
function showValidations(data) {
let success = true;
if (!data.prefix) {
success = false;
notify("Warning", "Your prefix has not been saved.<br />Prefixes must be between 1 - 8 characters in length.")
}
if (!data.welcome_message) {
success = false;
notify("Warning", "Your welcome message has not been saved.<br />Welcome messages must be between 1 - 1000 characters in length.")
}
if (!data.ticket_limit) {
success = false;
notify("Warning", "Your ticket limit has not been saved.<br />Ticket limits must be in the range 1 - 10.")
}
if (!data.archive_channel) {
success = false;
notify("Warning", "Your archive channel has not been saved.")
}
if (!data.category) {
success = false;
notify("Warning", "Your channel category has not been saved.")
}
if (!data.naming_scheme) {
success = false;
notify("Warning", "Your archive channel has not been saved.")
}
return success;
}
</script>
<script>
withLoadingScreen(async () => {
await loadData();
await loadClaimSettings();
await loadAutoCloseSettings();
});
</script>
</div>
{{end}}