2020-04-11 14:20:25 +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" >
2020-05-13 17:46:02 +00:00
< 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" >
2020-04-11 14:20:25 +00:00
<!-- Bootstrap CSS -->
2020-07-05 13:38:07 +00:00
2020-07-06 19:53:14 +00:00
< script >
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i < ca.length ; i + + ) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
};
{% if bs5 %}
2020-07-09 22:00:59 +00:00
const bsVersion = 5;
2020-07-06 19:53:14 +00:00
{% else %}
2020-07-09 22:00:59 +00:00
const bsVersion = 4;
2020-07-06 19:53:14 +00:00
{% endif %}
var css = document.createElement('link');
css.setAttribute('rel', 'stylesheet');
css.setAttribute('type', 'text/css');
var cssCookie = getCookie("css");
if (cssCookie.includes('bs' + bsVersion)) {
css.setAttribute('href', cssCookie);
} else {
css.setAttribute('href', '{{ css_file }}');
};
document.head.appendChild(css);
< / script >
2020-07-05 13:38:07 +00:00
{% 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 >
{% endif %}
2020-04-11 14:20:25 +00:00
< script src = "https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity = "sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin = "anonymous" > < / script >
2020-07-05 13:38:07 +00:00
{% 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 >
{% endif %}
2020-04-11 14:20:25 +00:00
< link rel = "stylesheet" href = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" >
< style >
2020-04-19 21:35:51 +00:00
.pageContainer {
2020-06-29 00:25:18 +00:00
margin: 5% 20% 5% 20%;
2020-04-19 21:35:51 +00:00
}
@media (max-width: 1100px) {
.pageContainer {
margin: 2%;
}
}
h1 {
/*margin: 20%;*/
2020-04-11 14:20:25 +00:00
margin-bottom: 5%;
}
.linkGroup {
2020-04-19 21:35:51 +00:00
/*margin: 20%;*/
2020-04-11 14:20:25 +00:00
margin-bottom: 5%;
margin-top: 5%;
}
.linkForm {
2020-04-19 21:35:51 +00:00
/*margin: 20%;*/
2020-04-11 14:20:25 +00:00
margin-top: 5%;
margin-bottom: 5%;
}
.contactBox {
2020-04-19 21:35:51 +00:00
/*margin: 20%;*/
2020-04-11 14:20:25 +00:00
margin-top: 5%;
color: grey;
}
2020-07-06 19:53:14 +00:00
.circle {
/*margin-left: 1rem;
width: 1rem;
height: 1rem;
border-radius: 50%;
z-index: 5000;*/
2020-07-10 15:15:17 +00:00
-webkit-transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190);
2020-07-06 19:53:14 +00:00
-moz-transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190);
-o-transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190);
transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190); /* easeInCubic */
}
.smooth-transition {
2020-07-10 15:15:17 +00:00
-webkit-transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190);
2020-07-06 19:53:14 +00:00
-moz-transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190);
-o-transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190);
2020-07-10 15:15:17 +00:00
transition: all 300ms cubic-bezier(0.550, 0.055, 0.675, 0.190); /* easeincubic */
}
.rotated {
transform: rotate(180deg);
-webkit-transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
-moz-transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
-o-transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000); /* easeInOutQuart */
}
.not-rotated {
transform: rotate(0deg);
-webkit-transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
-moz-transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
-o-transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
transition: all 150ms cubic-bezier(0.770, 0.000, 0.175, 1.000); /* easeInOutQuart */
2020-07-06 19:53:14 +00:00
}
2020-04-11 14:20:25 +00:00
< / style >
< title > Admin< / title >
< / head >
2020-07-06 19:53:14 +00:00
< body class = "smooth-transition" >
2020-07-03 20:07:04 +00:00
< div class = "modal fade" id = "login" role = "dialog" aria-labelledby = "login" aria-hidden = "true" data-backdrop = "static" >
2020-04-11 14:20:25 +00:00
< 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 >
2020-05-05 10:37:13 +00:00
< div id = "loginErrorArea" > < / div >
2020-04-11 14:20:25 +00:00
< / div >
< div class = "modal-footer" >
2020-05-05 10:37:13 +00:00
< button type = "submit" id = "loginSubmit" class = "btn btn-primary" form = "loginForm" > Login< / button >
2020-04-11 14:20:25 +00:00
< / div >
< / div >
< / div >
< / div >
2020-07-03 20:07:04 +00:00
< div class = "modal fade" id = "settingsMenu" role = "dialog" aria-labelledby = "settings menu" aria-hidden = "true" >
2020-06-08 12:33:04 +00:00
< 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" >
< ul class = "list-group list-group-flush" >
2020-06-30 20:24:07 +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-06-30 15:17:40 +00:00
< button type = "button" class = "list-group-item list-group-item-action" id = "openUsers" >
Users < i class = "fa fa-user" > < / i >
< / button >
< button type = "button" class = "list-group-item list-group-item-action" id = "openDefaultsWizard" >
New account defaults
< / button >
2020-06-08 12:33:04 +00:00
< / ul >
2020-06-30 15:17:40 +00:00
< div class = "list-group list-group-flush" id = "settingsList" >
< / div >
2020-06-08 12:33:04 +00:00
< / div >
< div class = "modal-footer" id = "settingsFooter" >
< button type = "button" class = "btn btn-secondary" data-dismiss = "modal" > Close< / button >
2020-06-30 15:17:40 +00:00
< button type = "button" class = "btn btn-primary" id = "settingsSave" > Save< / button >
2020-06-08 12:33:04 +00:00
< / div >
< / div >
< / div >
< / div >
2020-07-03 20:07:04 +00:00
< div class = "modal fade" id = "users" role = "dialog" aria-labelledby = "users" aria-hidden = "true" >
2020-04-20 19:37:39 +00:00
< 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 >
2020-07-03 20:07:04 +00:00
< div class = "modal fade" id = "userDefaults" role = "dialog" aria-labelledby = "users" aria-hidden = "true" >
2020-06-08 12:33:04 +00:00
< div class = "modal-dialog modal-dialog-centered" role = "document" >
< div class = "modal-content" >
< div class = "modal-header" >
< h5 class = "modal-title" id = "defaultsTitle" > New 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 account and configure it to your liking, then choose it from below to store the settings as a template for all new users.< / p >
< div id = "defaultUserRadios" > < / div >
< div class = "checkbox" >
< label > < input type = "checkbox" value = "" style = "margin-right: 1rem;" id = "storeDefaultHomescreen" checked > Store homescreen layout< / label >
< / 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-07-20 14:37:19 +00:00
< div class = "modal fade" id = "restartModal" role = "dialog" aria-labelledby = "Restart Warning" aria-hidden = "true" >
2020-06-30 15:17:40 +00:00
< 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" >
2020-07-20 14:37:19 +00:00
< p > A restart is needed to apply some settings. Restart now, later, or cancel?< / p >
2020-06-30 15:17:40 +00:00
< / div >
< div class = "modal-footer" >
2020-07-20 14:37:19 +00:00
< 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 >
2020-06-30 15:17:40 +00:00
< / div >
< / div >
< / div >
< / div >
2020-04-19 21:35:51 +00:00
< div class = "pageContainer" >
< h1 >
Accounts admin
< / h1 >
2020-07-06 19:53:14 +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 >
< / div >
2020-07-04 21:17:49 +00:00
< div class = "card mb-3 linkGroup" >
2020-04-19 21:35:51 +00:00
< div class = "card-header" > Current Invites< / div >
< ul class = "list-group list-group-flush" id = "invites" >
< / ul >
< / div >
< div class = "linkForm" >
2020-07-04 21:17:49 +00:00
< div class = "card mb-3" >
2020-04-19 21:35:51 +00:00
< div class = "card-header" > Generate Invite< / div >
< div class = "card-body" >
2020-07-09 22:00:59 +00:00
< form action = "#" method = "POST" id = "inviteForm" class = "container" >
< div class = "row align-items-start" >
< div class = "col" >
< 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-04-19 21:35:51 +00:00
< / div >
2020-07-09 22:00:59 +00:00
< div class = "col" >
< div class = "form-group" >
< label for = "multiUseCount" >
Multiple uses
< / label >
< div class = "input-group" >
< div class = "input-group-text" >
2020-07-10 15:15:17 +00:00
< 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" >
2020-07-09 22:00:59 +00:00
< / div >
< input type = "number" class = "form-control" name = "remaining-uses" id = "multiUseCount" >
< / div >
< / div >
< div class = "form-group form-check" style = "margin-top: 1rem; margin-bottom: 1rem;" >
2020-07-10 15:15:17 +00:00
< 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;'; }" >
2020-07-09 22:00:59 +00:00
< label class = "form-check-label" for = "noUseLimit" >
2020-07-10 15:15:17 +00:00
No use limit
2020-07-09 22:00:59 +00:00
< / label >
2020-07-10 15:15:17 +00:00
< div id = "noLimitWarning" class = "form-text" style = "display: none;" > Warning: Unlimited usage invites pose a risk if published online.< / div >
2020-07-09 22:00:59 +00:00
< / 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-04-19 21:35:51 +00:00
< / div >
2020-07-09 22:00:59 +00:00
< / div >
{% endif %}
< / div >
< / div >
< 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 >
2020-04-19 21:35:51 +00:00
< / div >
< / div >
2020-07-09 22:00:59 +00:00
< / div >
2020-04-19 21:35:51 +00:00
< / form >
< / div >
2020-04-17 14:24:56 +00:00
< / div >
2020-04-11 14:20:25 +00:00
< / div >
2020-04-19 21:35:51 +00:00
< div class = "contactBox" >
< p > {{ contactMessage }}< / p >
< / div >
2020-04-11 14:20:25 +00:00
< / div >
2020-07-03 21:22:47 +00:00
< script src = "serialize.js" > < / script >
2020-04-11 14:20:25 +00:00
< script src = "admin.js" > < / script >
< / body >
< / html >