2020-07-29 21:11:28 +00:00
<!doctype html>
< html lang = "en" >
< head >
<!-- Required meta tags -->
< meta charset = "utf-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1, shrink-to-fit=no" >
< link rel = "apple-touch-icon" sizes = "180x180" href = "/apple-touch-icon.png" >
< link rel = "icon" type = "image/png" sizes = "32x32" href = "/favicon-32x32.png" >
< link rel = "icon" type = "image/png" sizes = "16x16" href = "/favicon-16x16.png" >
< link rel = "manifest" href = "/site.webmanifest" >
< link rel = "mask-icon" href = "/safari-pinned-tab.svg" color = "#5bbad5" >
< meta name = "msapplication-TileColor" content = "#603cba" >
< meta name = "theme-color" content = "#ffffff" >
<!-- Bootstrap CSS -->
< script >
// To grab theme preference
function getCookie(cname) {
let name = cname + "=";
let decodedCookie = decodeURIComponent(document.cookie);
let ca = decodedCookie.split(';');
for (let c of ca) {
while(c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
{{ if .bs5 }}
const bsVersion = 5;
{{ else }}
const bsVersion = 4;
{{ end }}
2020-08-27 20:10:56 +00:00
var cssFile = "{{ .cssFile }}";
2020-07-29 21:11:28 +00:00
var css = document.createElement('link');
css.setAttribute('rel', 'stylesheet');
css.setAttribute('type', 'text/css');
var cssCookie = getCookie("css");
if (cssCookie.includes('bs' + bsVersion)) {
2020-08-27 20:10:56 +00:00
cssFile = cssCookie;
} else if (cssCookie.includes('bs')) {
if (cssCookie.includes('jf')) {
cssFile = 'bs' + bsVersion + '-jf.css';
} else {
cssFile = 'bs' + bsVersion + '.css';
}
document.cookie = 'css=' + cssFile;
}
css.setAttribute('href', cssFile);
2020-07-29 21:11:28 +00:00
document.head.appendChild(css);
2020-09-05 16:32:49 +00:00
// store whether ombi is enabled, 1 or 0.
var ombiEnabled = {{ .ombiEnabled }}
2020-07-29 21:11:28 +00:00
< / script >
{{ if not .bs5 }}
< script src = "https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity = "sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin = "anonymous" > < / script >
{{ end }}
< script src = "https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity = "sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin = "anonymous" > < / script >
{{ if .bs5 }}
< script src = "https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js" integrity = "sha384-oesi62hOLfzrys4LxRF63OJCXdXDipiYWBnvTl9Y9/TRlw5xlKIEHpNyvvDShgf/" crossorigin = "anonymous" > < / script >
{{ else }}
< script src = "https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity = "sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin = "anonymous" > < / script >
{{ end }}
< link rel = "stylesheet" href = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" >
< title > Admin< / title >
< / head >
< body class = "smooth-transition" >
< div class = "modal fade" id = "login" role = "dialog" aria-labelledby = "login" aria-hidden = "true" data-backdrop = "static" >
< div class = "modal-dialog modal-dialog-centered" role = "document" >
< div class = "modal-content" >
< div class = "modal-header" >
< h5 class = "modal-title" id = "loginTitle" > Login< / h5 >
< / div >
< div class = "modal-body" id = "formBody" >
< form action = "#" method = "POST" id = "loginForm" >
< div class = "form-group" >
< label for = "username" > Username< / label >
< input type = "text" class = "form-control" id = "username" name = "username" placeholder = "Username" required >
< label for = "password" > Password< / label >
< input type = "password" class = "form-control" id = "password" name = "password" placeholder = "Password" required >
< / div >
< / form >
< / div >
< div class = "modal-footer" >
< button type = "submit" id = "loginSubmit" class = "btn btn-primary" form = "loginForm" > Login< / button >
< / div >
< / div >
< / div >
< / div >
< div class = "modal fade" id = "settingsMenu" role = "dialog" aria-labelledby = "settings menu" aria-hidden = "true" >
< div class = "modal-dialog modal-dialog-centered" role = "document" >
< div class = "modal-content" >
< div class = "modal-header" >
< h5 class = "modal-title" id = "settingsTitle" > Settings< / h5 >
< button type = "button" class = "close" data-dismiss = "modal" aria-label = "Close" >
< span aria-hidden = "true" > × < / span >
< / button >
< / div >
< div class = "modal-body" >
2020-09-05 16:49:23 +00:00
< ul class = "list-group list-group-flush" style = "margin-bottom: 1rem;" >
2020-07-29 21:11:28 +00:00
< p > Note: < sup class = "text-danger" > *< / sup > Indicates required field, < sup class = "text-danger" > R< / sup > Indicates changes require a restart.< / p >
2020-08-31 14:29:35 +00:00
< button type = "button" class = "list-group-item list-group-item-action" id = "openAbout" >
2020-09-05 16:49:23 +00:00
About < i class = "fa fa-info-circle settingIcon" > < / i >
2020-08-31 14:29:35 +00:00
< / button >
2020-07-29 21:11:28 +00:00
< button type = "button" class = "list-group-item list-group-item-action" id = "openDefaultsWizard" >
2020-09-05 16:49:23 +00:00
New User Defaults < i class = "fa fa-user settingIcon" > < / i >
2020-07-29 21:11:28 +00:00
< / button >
2020-09-05 16:32:49 +00:00
{{ if .ombiEnabled }}
< button type = "button" class = "list-group-item list-group-item-action" id = "openOmbiDefaults" >
2020-09-05 16:49:23 +00:00
Ombi User Defaults < i class = "fa fa-chain-broken settingIcon" > < / i >
2020-09-05 16:32:49 +00:00
< / button >
{{ end }}
2020-07-29 21:11:28 +00:00
< / ul >
< div class = "list-group list-group-flush" id = "settingsList" >
< / div >
< / div >
< div class = "modal-footer" id = "settingsFooter" >
< button type = "button" class = "btn btn-secondary" data-dismiss = "modal" > Close< / button >
< button type = "button" class = "btn btn-primary" id = "settingsSave" > Save< / button >
< / div >
< / div >
< / div >
< / div >
< div class = "modal fade" id = "users" role = "dialog" aria-labelledby = "users" aria-hidden = "true" >
< div class = "modal-dialog modal-dialog-centered" role = "document" >
< div class = "modal-content" >
< div class = "modal-header" >
< h5 class = "modal-title" id = "usersTitle" > Users< / h5 >
< button type = "button" class = "close" data-dismiss = "modal" aria-label = "Close" >
< span aria-hidden = "true" > × < / span >
< / button >
< / div >
< div class = "modal-body" >
< ul class = "list-group list-group-flush" id = "userList" >
< / ul >
< / div >
< div class = "modal-footer" id = "userFooter" >
< button type = "button" class = "btn btn-secondary" data-dismiss = "modal" > Close< / button >
< / div >
< / div >
< / div >
< / div >
< div class = "modal fade" id = "userDefaults" role = "dialog" aria-labelledby = "users" aria-hidden = "true" >
< div class = "modal-dialog modal-dialog-centered" role = "document" >
< div class = "modal-content" >
< div class = "modal-header" >
2020-09-17 15:51:19 +00:00
< h5 class = "modal-title" id = "defaultsTitle" > < / h5 >
2020-07-29 21:11:28 +00:00
< button type = "button" class = "close" data-dismiss = "modal" aria-label = "Close" >
< span aria-hidden = "true" > × < / span >
< / button >
< / div >
< div class = "modal-body" >
2020-09-17 15:51:19 +00:00
< p id = "userDefaultsDescription" > < / p >
< div class = "mb-3" id = "defaultsSourceSection" >
< label for = "defaultsSource" > Use settings from:< / label >
< select class = "form-select" id = "defaultsSource" aria-label = "User settings source" >
< option value = "userTemplate" selected > Use existing user template< / option >
< option value = "fromUser" > Source from existing user< / option >
< / select >
< / div >
2020-07-29 21:11:28 +00:00
< div id = "defaultUserRadios" > < / div >
< div class = "checkbox" >
2020-09-17 15:51:19 +00:00
< input type = "checkbox" value = "" style = "margin-right: 1rem;" id = "storeDefaultHomescreen" checked >
< label for = "storeDefaultHomescreen" id = "storeHomescreenLabel" > < / label >
2020-07-29 21:11:28 +00:00
< / div >
< / div >
< div class = "modal-footer" id = "defaultsFooter" >
< button type = "button" class = "btn btn-secondary" data-dismiss = "modal" > Close< / button >
< button type = "button" class = "btn btn-primary" id = "storeDefaults" > Submit< / button >
< / div >
< / div >
< / div >
< / div >
2020-09-05 16:32:49 +00:00
{{ if .ombiEnabled }}
< div class = "modal fade" id = "ombiDefaults" role = "dialog" aria-labelledby = "Ombi Users" aria-hidden = "true" >
< div class = "modal-dialog modal-dialog-centered" role = "document" >
< div class = "modal-content" >
< div class = "modal-header" >
< h5 class = "modal-title" id = "ombiTitle" > Ombi user defaults< / h5 >
< button type = "button" class = "close" data-dismiss = "modal" aria-label = "Close" >
< span aria-hidden = "true" > × < / span >
< / button >
< / div >
< div class = "modal-body" >
< p > Create an Ombi user and configure it to your liking, then choose it from below to store the settings and permissions as a template for all new users.< / p >
< div id = "ombiUserRadios" > < / div >
< / div >
< div class = "modal-footer" id = "ombiFooter" >
< button type = "button" class = "btn btn-secondary" data-dismiss = "modal" > Close< / button >
< button type = "button" class = "btn btn-primary" id = "storeOmbiDefaults" > Submit< / button >
< / div >
< / div >
< / div >
< / div >
{{ end }}
2020-07-29 21:11:28 +00:00
< div class = "modal fade" id = "restartModal" role = "dialog" aria-labelledby = "Restart Warning" aria-hidden = "true" >
< div class = "modal-dialog modal-dialog-centered" role = "document" >
< div class = "modal-content" >
< div class = "modal-header" >
< h5 class = "modal-title" > Warning< / h5 >
< / div >
< div class = "modal-body" >
< p > A restart is needed to apply some settings. Restart now, later, or cancel?< / p >
< / div >
< div class = "modal-footer" >
< button type = "button" class = "btn btn-light" data-dismiss = "modal" > Cancel< / button >
< button type = "button" class = "btn btn-secondary" id = "applyRestarts" data-dismiss = "modal" > Apply, Restart later< / button >
< button type = "button" class = "btn btn-primary" id = "applyAndRestart" data-dismiss = "modal" > Apply & Restart< / button >
< / div >
< / div >
< / div >
< / div >
< div class = "modal fade" id = "refreshModal" role = "dialog" aria-labelledby = "Refresh page notice" aria-hidden = "true" >
< div class = "modal-dialog modal-dialog-centered" role = "document" >
< div class = "modal-content" >
< div class = "modal-header" >
< h5 class = "modal-title" > Settings applied.< / h5 >
< / div >
< div class = "modal-body" >
< p > Refresh the page in a few seconds.< / p >
< / div >
< / div >
< / div >
< / div >
2020-08-31 14:29:35 +00:00
< div class = "modal fade" id = "aboutModal" role = "dialog" aria-labelledby = "About jfa-go" aria-hidden = "true" >
< div class = "modal-dialog modal-dialog-centered" role = "document" >
< div class = "modal-content" >
< div class = "modal-header" >
< h5 class = "modal-title" > About< / h5 >
< button type = "button" class = "close" data-dismiss = "modal" aria-label = "Close" >
< span aria-hidden = "true" > × < / span >
< / button >
< / div >
< div class = "modal-body" >
< img src = "banner.svg" alt = "jfa-go banner" >
< p > < a href = "https://github.com/hrfee/jfa-go" > < i class = "fa fa-github" > < / i > jfa-go< / a > < / p >
< p > Version < i > {{ .version }}< / i > < / p >
< p > Commit < i > {{ .commit }}< / i > < / p >
< p > < a href = "https://github.com/hrfee/jfa-go/blob/main/LICENSE" > Available under the MIT License.< / a > < / p >
< / div >
< / div >
< / div >
< / div >
2020-07-29 21:11:28 +00:00
< div class = "pageContainer" >
2020-09-17 15:51:19 +00:00
< h1 > < a id = "invitesTabButton" class = "text-button" > invites < / a > < a id = "accountsTabButton" class = "text-button text-muted" > accounts< / a > < / h1 >
2020-07-29 21:11:28 +00:00
< div class = "btn-group" role = "group" id = "headerButtons" >
< button type = "button" class = "btn btn-primary" id = "openSettings" >
Settings < i class = "fa fa-cog" > < / i >
< / button >
2020-08-19 21:30:54 +00:00
< button type = "button" class = "btn btn-danger" id = "logoutButton" style = "display: none;" >
Logout < i class = "fa fa-sign-out" > < / i >
< / button >
2020-07-29 21:11:28 +00:00
< / div >
2020-09-17 15:51:19 +00:00
< div id = "invitesTab" >
< div class = "card mb-3 tabGroup" >
< div class = "card-header" > Current Invites< / div >
< ul class = "list-group list-group-flush" id = "invites" >
< / ul >
< / div >
< div class = "linkForm" >
< div class = "card mb-3" >
< div class = "card-header" > Generate Invite< / div >
< div class = "card-body" >
< form action = "#" method = "POST" id = "inviteForm" class = "container" >
< div class = "row align-items-start" >
< div class = "col-sm" >
< div class = "form-group" >
< label for = "days" > Days< / label >
< select class = "form-control form-select" id = "days" name = "days" >
< / select >
< / div >
< div class = "form-group" >
< label for = "hours" > Hours< / label >
< select class = "form-control form-select" id = "hours" name = "hours" >
< / select >
< / div >
< div class = "form-group" >
< label for = "minutes" > Minutes< / label >
< select class = "form-control form-select" id = "minutes" name = "minutes" >
< / select >
< / div >
2020-07-29 21:11:28 +00:00
< / div >
2020-09-17 15:51:19 +00:00
< div class = "col" >
< div class = "form-group" >
< label for = "multiUseCount" >
Multiple uses
< / label >
< div class = "input-group" >
< div class = "input-group-text" >
< input class = "form-check-input" type = "checkbox" onchange = "document.getElementById('multiUseCount').disabled = !this.checked; document.getElementById('noUseLimit').disabled = !this.checked" aria-label = "Checkbox to allow choice of invite usage limit" name = "multiple-uses" id = "multiUseEnabled" >
< / div >
< input type = "number" class = "form-control" name = "remaining-uses" id = "multiUseCount" >
2020-07-29 21:11:28 +00:00
< / div >
< / div >
2020-09-17 15:51:19 +00:00
< div class = "form-group form-check" style = "margin-top: 1rem; margin-bottom: 1rem;" >
< input class = "form-check-input" type = "checkbox" value = "" name = "no-limit" id = "noUseLimit" onchange = "document.getElementById('multiUseCount').disabled = this.checked; if (this.checked) { document.getElementById('noLimitWarning').style = 'display: block;' } else { document.getElementById('noLimitWarning').style = 'display: none;'; }" >
< label class = "form-check-label" for = "noUseLimit" >
No use limit
< / label >
< div id = "noLimitWarning" class = "form-text" style = "display: none;" > Warning: Unlimited usage invites pose a risk if published online.< / div >
< / div >
{{ if .email_enabled }}
< div class = "form-group" >
< label for = "send_to_address" > Send invite to address< / label >
< div class = "input-group" >
< div class = "input-group-text" >
< input class = "form-check-input" type = "checkbox" onchange = "document.getElementById('send_to_address').disabled = !this.checked;" aria-label = "Checkbox to allow input of email address" id = "send_to_address_enabled" >
< / div >
< input type = "email" class = "form-control" placeholder = "example@example.com" id = "send_to_address" disabled >
2020-07-29 21:11:28 +00:00
< / div >
< / div >
2020-09-17 15:51:19 +00:00
{{ end }}
2020-07-29 21:11:28 +00:00
< / div >
< / div >
2020-09-17 15:51:19 +00:00
< div class = "row" >
< div class = "col" >
< div class = "form-group d-flex float-right" >
< button type = "submit" id = "generateSubmit" class = "btn btn-primary" style = "margin-top: 1rem;" >
Generate
< / button >
< / div >
2020-07-29 21:11:28 +00:00
< / div >
< / div >
2020-09-17 15:51:19 +00:00
< / form >
< / div >
< / div >
< / div >
< / div >
< div id = "accountsTab" class = "unfocused" >
< div class = "card mb-3 tabGroup" >
2020-09-17 20:23:45 +00:00
< div class = "card-header d-flex" style = "align-items: center;" >
< div > Accounts< / div >
< div class = "ml-auto" >
<!-- <button type="button" class="btn btn - secondary">Add User</button> -->
2020-09-17 15:51:19 +00:00
< button type = "button" class = "btn btn-primary unfocused" id = "accountsTabSetDefaults" > Set Defaults< / button >
2020-09-17 20:23:45 +00:00
< button type = "button" class = "btn btn-danger unfocused" id = "accountsTabDelete" > < / button >
2020-09-17 15:51:19 +00:00
< / div >
< / div >
2020-09-17 20:34:25 +00:00
< div class = "card-body table-responsive" >
2020-09-17 15:51:19 +00:00
< table class = "table table-hover table-striped table-borderless" >
< thead >
< tr >
< th scope = "col" > < input class = "form-check-input" type = "checkbox" value = "" id = "selectAll" > < / th >
< th scope = "col" > Username< / th >
< th scope = "col" > Email Address< / th >
< th scope = "col" > Last Active< / th >
< th scope = "col" > Admin?< / th >
< th scope = "col" > < i > View settings< / i > < / th >
< / tr >
< / thead >
< tbody id = "accountsList" >
< / tbody >
< / table >
2020-07-29 21:11:28 +00:00
< / div >
< / div >
< / div >
< div class = "contactBox" >
< p > {{ .contactMessage }}< / p >
< / div >
< / div >
< script src = "serialize.js" > < / script >
< script >
{{ if .bs5 }}
function createModal(id, find = false) {
2020-09-16 16:36:14 +00:00
let modal;
2020-07-29 21:11:28 +00:00
if (find) {
2020-09-16 16:36:14 +00:00
modal = bootstrap.Modal.getInstance(document.getElementById(id));
} else {
modal = new bootstrap.Modal(document.getElementById(id));
2020-07-29 21:11:28 +00:00
}
2020-09-16 16:36:14 +00:00
document.getElementById(id).addEventListener('shown.bs.modal', function () {
document.body.classList.add("modal-open");
});
return {
modal: modal,
show: function() {
let temp = this.modal.show();
return temp
},
hide: function() { return this.modal.hide(); }
};
2020-07-29 21:11:28 +00:00
}
{{ else }}
let send_to_addess_enabled = document.getElementById('send_to_address_enabled');
if (typeof(send_to_address_enabled) != 'undefined') {
send_to_address_enabled.classList.remove('form-check-input');
}
let multiUseEnabled = document.getElementById('multiUseEnabled');
if (typeof(multiUseEnabled) != 'undefined') {
multiUseEnabled.classList.remove('form-check-input');
}
function createModal(id, find = false) {
2020-09-16 16:36:14 +00:00
$('#' + id).on('shown.bs.modal', function () {
document.body.classList.add("modal-open");
});
2020-07-29 21:11:28 +00:00
return {
show: function() {
2020-09-16 16:36:14 +00:00
let temp = $('#' + id).modal('show');
return temp
2020-07-29 21:11:28 +00:00
},
hide: function() {
return $('#' + id).modal('hide');
}
};
}
{{ end }}
function triggerTooltips() {
{{ if .bs5 }}
document.getElementById('settingsMenu').addEventListener('shown.bs.modal', function() {
{{ else }}
$('#settingsMenu').on('shown.bs.modal', function() {
{{ end }}
// Hacky way to ensure anything dependent on checkbox state is disabled if necessary by just clicking them
let checkboxes = document.getElementById('settingsMenu').querySelectorAll('input[type="checkbox"]');
for (checkbox of checkboxes) {
checkbox.click();
checkbox.click();
}
let tooltips = [].slice.call(document.querySelectorAll('a[data-toggle="tooltip"]'));
tooltips.map(function(el) {
{{ if .bs5 }}
return new bootstrap.Tooltip(el);
{{ else }}
return $(el).tooltip();
{{ end }}
});
});
}
{{ if .notifications }}
const notifications_enabled = true;
{{ else }}
const notifications_enabled = false;
{{ end }}
< / script >
2020-09-17 15:51:19 +00:00
< script src = "accounts.js" > < / script >
2020-07-29 21:11:28 +00:00
< script src = "admin.js" > < / script >
< / body >
< / html >