Upload files to "app/templates"

This commit is contained in:
chris 2025-03-24 01:47:11 +00:00
parent b342ed0116
commit ec7585b60e
5 changed files with 422 additions and 0 deletions

273
app/templates/account.html Normal file
View File

@ -0,0 +1,273 @@
{% extends "base.html" %}
{% block content %}
<div class="modal fade-in" id="add-ssh-key-modal">
<div class="modal-ux-header cyan darken-2 white-text">
<h2>Add SSH Public Key</h2>
</div>
<div class="modal-content modal-ux">
<form>
<div class="row">
<div class="input-field">
<i class="material-icons prefix">vpn_key</i>
<textarea class="materialize-textarea" id="ssh-pub-key" style="height: 200px;"></textarea>
<label for="ssh-pub-key">SSH public key</label>
</div>
</div>
<div class="row">
<div class="modal-footer">
<button id="btn-add-ssh-key" class="btn waves-effect waves-light right modal-close" onclick="add_ssh_key()" type="button">Submit<i class="material-icons right">send</i></button>
</div>
</div>
</form>
</div>
</div>
<div class="modal fade-in" id="remove-ssh-key-modal">
<div class="modal-ux-header cyan darken-2 white-text">
<h2>Confirm SSH Key Removal</h2>
</div>
<div class="modal-content modal-ux row">
<p>Are you sure you want to remove this ssh public key?</p>
<div class="modal-footer">
<button id="btn-confirm-ssh-key-remove" class="btn waves-effect waves-light red modal-close" type="button">Remove</button>
<button id="btn-confirm-ssh-key-remove" class="btn waves-effect waves-light modal-close" type="button">Cancel</button>
</div>
</div>
</div>
<div class="modal fade-in" id="change-password-modal">
<div class="modal-ux-header cyan darken-2 white-text">
<h2>Change Password</h2>
</div>
<div class="modal-ux modal-content">
<form>
<div class="input-field row">
<i class="material-icons prefix">password</i>
<input id="old-password" type="password" required>
<label for="old-password">Password</label>
</div>
<div class="input-field row">
<i class="material-icons prefix">password</i>
<input id="new-password" type="password" required>
<label for="new-password">New Password</label>
</div>
<div class="input-field row">
<i class="material-icons prefix">password</i>
<input id="confirm-password" type="password" required>
<label for="confirm-password">Confirm Password</label>
</div>
<div class="modal-footer row">
<button class="btn waves-effect waves-light modal-close" type="button">Cancel</button>
<button id="btn-change-password" class="btn waves-effect waves-light" type="button" onclick="change_password()">Submit<i class="material-icons right">send</i></button>
</div>
</form>
</div>
</div>
<div class="wrapper">
<div id="profile-page-header" class="card">
<div class="card-content">
<div class="row">
<div class="col s12 center-align">
<h1 class="card-title grey-text text-darken-4"><i class="material-icons prefix">account_circle</i>{{ current_user.name }}</h1>
</div>
</div>
</div>
</div>
<div id="profile-page-content" class="row">
<div class="col s12">
<ul class="collapsible popout white" data-collapsible="accordion">
<li>
<div class="collapsible-header"><i class="material-icons prefix">account_circle</i>Contact Info</div>
<div class="collapsible-body">
<ul class="collection">
<li class="collection-item">
<i class="material-icons">phone_android</i>
<span class="title">Phone</span>
<div class="input-field">
<input id="mobile-phone" value="{{ current_user.phone }}" disabled>
</div>
<button id="blank" class="btn hiddendiv" type="buton"></button>
<button id="cancel-new-phone" class="btn hiddendiv" type="button" onclick="cancel_edit_phone()">Cancel</button>
<button id="save-new-phone" class="btn hiddendiv" type="button" onclick="update_phone()">Save<i class="material-icons right">send</i></button>
<a id="phone-edit" href="#" onclick="edit_phone()"><i class="material-icons">edit</i></a>
</li>
<li class="collection-item">
<i class="material-icons">email</i>
<span class="title">Email</span>
<p>{{ current_user.email }}</p>
</li>
</ul>
</div>
</li>
<li>
<div class="collapsible-header"><i class="material-icons prefix">lock</i>Credentials</div>
<div class="collapsible-body">
<ul class="collection">
<li class="collection-item">
<i class="material-icons prefix">vpn_key</i>
<span class="title">SSH Public Keys</span>
{% for pub_key in current_user.ssh_pub_keys %}
<div class="row">
<div class="col s11">
<div class="input-field">
<textarea class="materialize-textarea" id="pub-key{{ loop.index0 }}" style="height: 150px;" disabled>{{ pub_key }}</textarea>
<label for="pub-key-{{ loop.index0 }}">Public Key {{ loop.index0 + 1 }}:</label>
</div>
</div>
<div class="col s1">
<a class="right modal-trigger" href="#remove-ssh-key-modal" onclick="del_ssh_key('{{ pub_key }}')">
<i class="material-icons red-text">remove</i>
</a>
</div>
</div>
<div class="divider"></div>
{% endfor %}
<div clas="row">
<p>Add public key <a class="modal-trigger right" href="#add-ssh-key-modal"><i class="material-icons">add</i></a></p>
</div>
</li>
<li class="collection-item">
<i class="material-icons">password</i>
<span class="title"><a class="modal-trigger" href="#change-password-modal">Change Password</a></span>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
</div>
<script>
$(document).ready(function() {
$('.modal').modal();
});
function add_ssh_key() {
let ssh_key = $("#ssh-pub-key").val();
console.log(ssh_key);
$.ajax({
url: "{{ url_for('auth.add_ssh_pub_key') }}",
type: "POST",
dataType: "json",
contentType: "application/json",
data: JSON.stringify({"pubkey": ssh_key}),
success: function(data, status) { window.location.reload(); },
complete: function(xhr, textStatus) {
if (xhr.status === 400) {
let message = xhr.responseJSON.error;
if (message === "INVALID_KEY") {
message = "Invalid SSH key given (does not conform to openSSH format)."
}
M.toast({html: '<span>' + message + '</span><button class="toast-action btn-flat" onclick="this.parentElement.remove();">&times;</button>'});
}
}
});
}
function del_ssh_key(key_to_del) {
console.log(key_to_del);
$('#btn-confirm-ssh-key-remove').click(function () {
$.ajax({
url: "{{ url_for('auth.add_ssh_pub_key') }}",
type: "DELETE",
dataType: "json",
contentType: "application/json",
data: JSON.stringify({"pubkey": key_to_del}),
success: function(data, status) { window.location.reload(); }
});
});
}
function cancel_edit_phone() {
let phone_field = $("#mobile-phone");
let phone_save_btn = $("#save-new-phone");
let phone_cancel_btn = $("#cancel-new-phone");
let phone_edit_icon = $("#phone-edit");
// Allow the field to be edited and show save the button
phone_field.prop("disabled", true);
phone_save_btn.addClass("hiddendiv");
phone_cancel_btn.addClass("hiddendiv");
phone_edit_icon.removeClass("hiddendiv");
phone_field.value("{{ current_user.phone }}");
}
function update_phone() {
let phone_field = $("#mobile-phone");
let phone_save_btn = $("#save-new-phone");
let phone_cancel_btn = $("#cancel-new-phone");
let phone_edit_icon = $("#phone-edit");
// Allow the field to be edited and show save the button
phone_field.prop("disabled", true);
phone_save_btn.addClass("hiddendiv");
phone_cancel_btn.addClass("hiddendiv");
phone_edit_icon.removeClass("hiddendiv");
$.ajax({
url: "{{ url_for('auth.update_phone') }}",
type: "POST",
dataType: "json",
contentType: "application/json",
data: JSON.stringify({"phone_number": phone_field.val()}),
success: function(data, status) {
M.toast({html: '<span>Phone number updated</span><button class="toast-action btn-flat" onclick="this.parentElement.remove();">&times;</button>'});
},
complete: function(xhr, textStatus) {
if (xhr.status === 400) {
let message = xhr.responseJSON.error;
M.toast({html: '<span>' + message + '</span><button class="toast-action btn-flat" onclick="this.parentElement.remove();">&times;</button>'});
}
}
})
}
function edit_phone() {
let phone_field = $("#mobile-phone");
let phone_save_btn = $("#save-new-phone");
let phone_cancel_btn = $("#cancel-new-phone");
let phone_edit_icon = $("#phone-edit");
// Allow the field to be edited and show save the button
phone_field.prop("disabled", false);
phone_save_btn.removeClass("hiddendiv");
phone_cancel_btn.removeClass("hiddendiv");
phone_edit_icon.addClass("hiddendiv");
}
function change_password() {
let old_pass = $("#old-password");
let new_pass = $("#new-password");
let confirm_pass = $("#confirm-password");
if (new_pass.val() !== confirm_pass.val()) {
new_pass.addClass('invalid');
new_pass.addClass('active');
confirm_pass.addClass('invalid');
confirm_pass.addClass('active');
M.toast({html: '<span>Passwords do not match</span><button class="toast-action btn-flat" onclick="this.parentElement.remove();">&times;</button>'});
}
else {
$.ajax({
url: "{{ url_for('auth.change_passwd') }}",
type: "POST",
dataType: "json",
contentType: "application/json",
data: JSON.stringify({"passwd": old_pass.val(), "new_passwd": new_pass.val()}),
success: function(data, status) {
window.location.reload();
},
complete: function(xhr, textStatus) {
console.log(xhr.status);
if (xhr.status === 405) {
old_pass.addClass('invalid');
old_pass.addClass('invalid');
M.toast({html: '<span>Password is incorrect</span><button class="toast-action btn-flat" onclick="this.parentElement.remove();">&times;</button>'});
}
}
});
}
}
</script>
{% endblock %}

27
app/templates/base.html Normal file
View File

@ -0,0 +1,27 @@
{% block head %}
<title>Quarter Homes Internal</title>
{% endblock %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="{{ url_for('static', filename='css/materialize.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/materialize.min.js') }}"></script>
<script>
$(document).ready(function(){
$('.collapsible').collapsible();
});
</script>
{% block flash_messages %}
{% include "includes/flash_messages.html" %}
{% endblock %}
{% block body_content %}
{% include "includes/navbar.html" %}
{% block content %}
{% endblock %}
{% endblock %}

View File

@ -0,0 +1,34 @@
{% extends "base.html" %}
{% block content %}
<div class="row">
<div class="col s4 offset-s4 white">
<div class="row">
<div class="title center"><h1>Directory</h1></div>
</div>
<div class="row">
<ul class="collapsible popout" data-collapsible="accordion">
{% for emp in users %}
<li>
<div class="collapsible-header"><i class="material-icons prefix">account_circle</i>{{ emp.full_name }}</div>
<div class="collapsible-body">
<ul class="collection">
<li class="collection-item">
<i class="material-icons">phone_android</i>
<span class="title">Phone</span>
<p>{{ emp.phone_num }}</p>
</li>
<li class="collection-item">
<i class="material-icons">email</i>
<span class="title">Email</span>
<p>{{ emp.email }}</p>
</li>
</ul>
</div>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,44 @@
{% extends "base.html" %}
{% block content %}
{% for env in envs %}
<div class="row">
<div class="col s6 offset-s3">
<div class="card">
<div class="card-content">
<span class="card-title"><a href="{{ env['url'] }}">{{ env['name'] }}</a> <div class="env-status right" data-url="{{ env['url'] }}"></div></span>
</div>
</div>
</div>
</div>
{% endfor %}
<script>
$(document).ready(function() {
function update_statuses() {
$(".env-status").each(function(idx, item) {
let url = $(this).data("url");
$.ajax({
url: "{{ url_for('main.server_status') }}",
type: "POST",
dataType: "json",
contentType: "application/json",
data: JSON.stringify({"url": url}),
success: function(data, status) {
if (data.status === "UP") {
$(item).html('<i class="material-icons green-text">done</i>');
} else {
$(item).html('<i class="material-icons red-text">error_outline</i>');
}
}
});
})
}
update_statuses();
var interval_status = setInterval(update_statuses, 5000);
});
</script>
{% endblock %}

44
app/templates/index.html Normal file
View File

@ -0,0 +1,44 @@
{% extends "base.html" %}
{% block content %}
<div class="row">
<div class="col s5 offset-s1">
<div class="card">
<div class="card-content">
<span class="card-title"><b><i class="material-icons prefix">link</i> Useful Links</b></span>
<div class="card-body">
<ul>
<li><a href="#" target="_blank"><img src="{{ url_for('static', filename='img/jira_logo_blue_153_153.png') }}" height="15"> Quarter Jira</a></li>
<li><a href="https://github.com/QuarterHomes" target="_blank"><i class="fa fa-github"></i> Codebase</a></li>
</ul>
</div>
</div>
</div>
<div class="card">
<div class="card-content">
<span class="card-title"><b><i class="material-icons prefix">article</i> Documentation</b></span>
<div class="card-body">
<ul>
<li><a href="#" target="_blank"><i class="fa fa-lock"></i> VPN config</a></li>
<li><a href="#" target="_blank"><i class="fa fa-server"></i> Connect to dev machine</a></li>
<li><a href="#" target="_blank"><i class="fa fa-desktop"></i> Dev environment setup</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="col s5">
<div class="card">
<div class="card-content">
<span class="card-title"><b><i class="fa fa-check"></i> Environment Status</b></span>
<div class="card-body">
<ul>
<li>Environment 1 <i class="material-icons prefix">check_circle_outline</i></li>
<li>Environment 2 <i class="material-icons prefix">error</i></li>
</ul>
</div>
</div>
</div>
</div>
</div>
{% endblock %}