Streamlined post form handlers for admin console
This commit is contained in:
		@@ -14,7 +14,7 @@ class Test:
 | 
				
			|||||||
        self._id = _id
 | 
					        self._id = _id
 | 
				
			||||||
        self.start_date = start_date
 | 
					        self.start_date = start_date
 | 
				
			||||||
        self.expiry_date = expiry_date
 | 
					        self.expiry_date = expiry_date
 | 
				
			||||||
        self.time_limit = None if time_limit == 'none' or time_limit == '' else int(time_limit)
 | 
					        self.time_limit = None if time_limit == 'none' or time_limit == '' or time_limit == None else int(time_limit)
 | 
				
			||||||
        self.creator = creator
 | 
					        self.creator = creator
 | 
				
			||||||
        self.dataset = dataset
 | 
					        self.dataset = dataset
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,7 +20,7 @@ body {
 | 
				
			|||||||
    padding-bottom: 40px;
 | 
					    padding-bottom: 40px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.form-signin {
 | 
					.form-display {
 | 
				
			||||||
    width: 100%;
 | 
					    width: 100%;
 | 
				
			||||||
    max-width: 420px;
 | 
					    max-width: 420px;
 | 
				
			||||||
    padding: 15px;
 | 
					    padding: 15px;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,392 +13,37 @@ for(let i = 0; i< dropdownItems.length; i++) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Form Processing Scripts
 | 
					// General Post Method Form Processing Script
 | 
				
			||||||
$('form[name=form-register]').submit(function(event) {
 | 
					$('form.form-post').submit(function(event) {
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    var $form = $(this);
 | 
					    var $form = $(this);
 | 
				
			||||||
    var alert = document.getElementById('alert-box');
 | 
					 | 
				
			||||||
    var data = $form.serialize();
 | 
					    var data = $form.serialize();
 | 
				
			||||||
 | 
					    var url = $(this).attr('action');
 | 
				
			||||||
    alert.innerHTML = '';
 | 
					    var rel_success = $(this).data('rel-success');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $.ajax({
 | 
					    $.ajax({
 | 
				
			||||||
        url: window.location.pathname,
 | 
					        url: url,
 | 
				
			||||||
        type: 'POST',
 | 
					        type: 'POST',
 | 
				
			||||||
        data: data,
 | 
					        data: data,
 | 
				
			||||||
        dataType: 'json',
 | 
					        dataType: 'json',
 | 
				
			||||||
        success: function(response) {
 | 
					        success: function(response) {
 | 
				
			||||||
            window.location.href = "/admin/login/";
 | 
					            window.location.href = rel_success;
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        error: function(response) {
 | 
					        error: function(response) {
 | 
				
			||||||
            if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) {
 | 
					            error_response(response);
 | 
				
			||||||
                alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                    <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                    ${response.responseJSON.error}
 | 
					 | 
				
			||||||
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                `;
 | 
					 | 
				
			||||||
            } else if (response.responseJSON.error instanceof Array) {
 | 
					 | 
				
			||||||
                for (var i = 0; i < response.responseJSON.error.length; i ++) {
 | 
					 | 
				
			||||||
                    alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                        <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                        ${response.responseJSON.error[i]}
 | 
					 | 
				
			||||||
                        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    `;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    event.preventDefault();
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$('form[name=form-login]').submit(function(event) {
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    var $form = $(this);
 | 
					 | 
				
			||||||
    var alert = document.getElementById('alert-box');
 | 
					 | 
				
			||||||
    var data = $form.serialize();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    alert.innerHTML = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.ajax({
 | 
					 | 
				
			||||||
        url: window.location.pathname,
 | 
					 | 
				
			||||||
        type: 'POST',
 | 
					 | 
				
			||||||
        data: data,
 | 
					 | 
				
			||||||
        dataType: 'json',
 | 
					 | 
				
			||||||
        success: function(response) {
 | 
					 | 
				
			||||||
            window.location.href = "/admin/dashboard/";
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        error: function(response) {
 | 
					 | 
				
			||||||
            if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) {
 | 
					 | 
				
			||||||
                alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                    <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                    ${response.responseJSON.error}
 | 
					 | 
				
			||||||
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                `;
 | 
					 | 
				
			||||||
            } else if (response.responseJSON.error instanceof Array) {
 | 
					 | 
				
			||||||
                for (var i = 0; i < response.responseJSON.error.length; i ++) {
 | 
					 | 
				
			||||||
                    alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                        <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                        ${response.responseJSON.error[i]}
 | 
					 | 
				
			||||||
                        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    `;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    event.preventDefault();
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$('form[name=form-reset]').submit(function(event) {
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    var $form = $(this);
 | 
					 | 
				
			||||||
    var alert = document.getElementById('alert-box');
 | 
					 | 
				
			||||||
    var data = $form.serialize();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    alert.innerHTML = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.ajax({
 | 
					 | 
				
			||||||
        url: window.location.pathname,
 | 
					 | 
				
			||||||
        type: 'POST',
 | 
					 | 
				
			||||||
        data: data,
 | 
					 | 
				
			||||||
        dataType: 'json',
 | 
					 | 
				
			||||||
        success: function(response) {
 | 
					 | 
				
			||||||
            window.location.href = "/admin/login/";
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        error: function(response) {
 | 
					 | 
				
			||||||
            if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) {
 | 
					 | 
				
			||||||
                alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                    <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                    ${response.responseJSON.error}
 | 
					 | 
				
			||||||
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                `;
 | 
					 | 
				
			||||||
            } else if (response.responseJSON.error instanceof Array) {
 | 
					 | 
				
			||||||
                for (var i = 0; i < response.responseJSON.error.length; i ++) {
 | 
					 | 
				
			||||||
                    alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                        <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                        ${response.responseJSON.error[i]}
 | 
					 | 
				
			||||||
                        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    `;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    event.preventDefault();
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$('form[name=form-update-password]').submit(function(event) {
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    var $form = $(this);
 | 
					 | 
				
			||||||
    var alert = document.getElementById('alert-box');
 | 
					 | 
				
			||||||
    var data = $form.serialize();
 | 
					 | 
				
			||||||
    console.log(data)
 | 
					 | 
				
			||||||
    alert.innerHTML = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.ajax({
 | 
					 | 
				
			||||||
        url: window.location.pathname,
 | 
					 | 
				
			||||||
        type: 'POST',
 | 
					 | 
				
			||||||
        data: data,
 | 
					 | 
				
			||||||
        dataType: 'json',
 | 
					 | 
				
			||||||
        success: function(response) {
 | 
					 | 
				
			||||||
            window.location.href = "/admin/login/";
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        error: function(response) {
 | 
					 | 
				
			||||||
            if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) {
 | 
					 | 
				
			||||||
                alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                    <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                    ${response.responseJSON.error}
 | 
					 | 
				
			||||||
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                `;
 | 
					 | 
				
			||||||
            } else if (response.responseJSON.error instanceof Array) {
 | 
					 | 
				
			||||||
                for (var i = 0; i < response.responseJSON.error.length; i ++) {
 | 
					 | 
				
			||||||
                    alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                        <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                        ${response.responseJSON.error[i]}
 | 
					 | 
				
			||||||
                        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    `;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    event.preventDefault();
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$('form[name=form-create-user]').submit(function(event) {
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    var $form = $(this);
 | 
					 | 
				
			||||||
    var alert = document.getElementById('alert-box');
 | 
					 | 
				
			||||||
    var data = $form.serialize();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    alert.innerHTML = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.ajax({
 | 
					 | 
				
			||||||
        url: window.location.pathname,
 | 
					 | 
				
			||||||
        type: 'POST',
 | 
					 | 
				
			||||||
        data: data,
 | 
					 | 
				
			||||||
        dataType: 'json',
 | 
					 | 
				
			||||||
        success: function(response) {
 | 
					 | 
				
			||||||
            window.location.reload();
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        error: function(response) {
 | 
					 | 
				
			||||||
            if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) {
 | 
					 | 
				
			||||||
                alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                    <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                    ${response.responseJSON.error}
 | 
					 | 
				
			||||||
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                `;
 | 
					 | 
				
			||||||
            } else if (response.responseJSON.error instanceof Array) {
 | 
					 | 
				
			||||||
                for (var i = 0; i < response.responseJSON.error.length; i ++) {
 | 
					 | 
				
			||||||
                    alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                        <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                        ${response.responseJSON.error[i]}
 | 
					 | 
				
			||||||
                        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    `;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    event.preventDefault();
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$('form[name=form-delete-user]').submit(function(event) {
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    var $form = $(this);
 | 
					 | 
				
			||||||
    var alert = document.getElementById('alert-box');
 | 
					 | 
				
			||||||
    var data = $form.serialize();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    alert.innerHTML = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.ajax({
 | 
					 | 
				
			||||||
        url: window.location.pathname,
 | 
					 | 
				
			||||||
        type: 'POST',
 | 
					 | 
				
			||||||
        data: data,
 | 
					 | 
				
			||||||
        dataType: 'json',
 | 
					 | 
				
			||||||
        success: function(response) {
 | 
					 | 
				
			||||||
            window.location.href = '/admin/settings/users/';
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        error: function(response) {
 | 
					 | 
				
			||||||
            if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) {
 | 
					 | 
				
			||||||
                alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                    <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                    ${response.responseJSON.error}
 | 
					 | 
				
			||||||
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                `;
 | 
					 | 
				
			||||||
            } else if (response.responseJSON.error instanceof Array) {
 | 
					 | 
				
			||||||
                for (var i = 0; i < response.responseJSON.error.length; i ++) {
 | 
					 | 
				
			||||||
                    alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                        <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                        ${response.responseJSON.error[i]}
 | 
					 | 
				
			||||||
                        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    `;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    event.preventDefault();
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$('form[name=form-update-user]').submit(function(event) {
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    var $form = $(this);
 | 
					 | 
				
			||||||
    var alert = document.getElementById('alert-box');
 | 
					 | 
				
			||||||
    var data = $form.serialize();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    alert.innerHTML = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.ajax({
 | 
					 | 
				
			||||||
        url: window.location.pathname,
 | 
					 | 
				
			||||||
        type: 'POST',
 | 
					 | 
				
			||||||
        data: data,
 | 
					 | 
				
			||||||
        dataType: 'json',
 | 
					 | 
				
			||||||
        success: function(response) {
 | 
					 | 
				
			||||||
            window.location.href = '/admin/settings/users';
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        error: function(response) {
 | 
					 | 
				
			||||||
            if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) {
 | 
					 | 
				
			||||||
                alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                    <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                    ${response.responseJSON.error}
 | 
					 | 
				
			||||||
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                `;
 | 
					 | 
				
			||||||
            } else if (response.responseJSON.error instanceof Array) {
 | 
					 | 
				
			||||||
                for (var i = 0; i < response.responseJSON.error.length; i ++) {
 | 
					 | 
				
			||||||
                    alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                        <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                        ${response.responseJSON.error[i]}
 | 
					 | 
				
			||||||
                        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    `;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    event.preventDefault();
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$('form[name=form-update-account]').submit(function(event) {
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    var $form = $(this);
 | 
					 | 
				
			||||||
    var alert = document.getElementById('alert-box');
 | 
					 | 
				
			||||||
    var data = $form.serialize();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    alert.innerHTML = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.ajax({
 | 
					 | 
				
			||||||
        url: window.location.pathname,
 | 
					 | 
				
			||||||
        type: 'POST',
 | 
					 | 
				
			||||||
        data: data,
 | 
					 | 
				
			||||||
        dataType: 'json',
 | 
					 | 
				
			||||||
        success: function(response) {
 | 
					 | 
				
			||||||
            window.location.href = '/admin/dashboard/';
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        error: function(response) {
 | 
					 | 
				
			||||||
            if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) {
 | 
					 | 
				
			||||||
                alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                    <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                    ${response.responseJSON.error}
 | 
					 | 
				
			||||||
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                `;
 | 
					 | 
				
			||||||
            } else if (response.responseJSON.error instanceof Array) {
 | 
					 | 
				
			||||||
                for (var i = 0; i < response.responseJSON.error.length; i ++) {
 | 
					 | 
				
			||||||
                    alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                        <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                        ${response.responseJSON.error[i]}
 | 
					 | 
				
			||||||
                        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    `;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    event.preventDefault();
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$('form[name=form-create-test]').submit(function(event) {
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    var $form = $(this);
 | 
					 | 
				
			||||||
    var alert = document.getElementById('alert-box');
 | 
					 | 
				
			||||||
    var data = $form.serialize();
 | 
					 | 
				
			||||||
    alert.innerHTML = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.ajax({
 | 
					 | 
				
			||||||
        url: window.location.pathname,
 | 
					 | 
				
			||||||
        type: 'POST',
 | 
					 | 
				
			||||||
        data: data,
 | 
					 | 
				
			||||||
        dataType: 'json',
 | 
					 | 
				
			||||||
        success: function(response) {
 | 
					 | 
				
			||||||
            window.location.href = '/admin/tests/';
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        error: function(response) {
 | 
					 | 
				
			||||||
            if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) {
 | 
					 | 
				
			||||||
                alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                    <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                    ${response.responseJSON.error}
 | 
					 | 
				
			||||||
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                `;
 | 
					 | 
				
			||||||
            } else if (response.responseJSON.error instanceof Array) {
 | 
					 | 
				
			||||||
                for (var i = 0; i < response.responseJSON.error.length; i ++) {
 | 
					 | 
				
			||||||
                    alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                        <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                        ${response.responseJSON.error[i]}
 | 
					 | 
				
			||||||
                        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    `;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    event.preventDefault();
 | 
					    event.preventDefault();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Form Upload Questions - Special case, needs to handle files.
 | 
				
			||||||
$('form[name=form-upload-questions]').submit(function(event) {
 | 
					$('form[name=form-upload-questions]').submit(function(event) {
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    var $form = $(this);
 | 
					    var $form = $(this);
 | 
				
			||||||
    var alert = document.getElementById('alert-box');
 | 
					 | 
				
			||||||
    var data = new FormData($form[0]);
 | 
					    var data = new FormData($form[0]);
 | 
				
			||||||
    var file = $('input[name=data_file]')[0].files[0]
 | 
					    var file = $('input[name=data_file]')[0].files[0]
 | 
				
			||||||
    data.append('file', file)
 | 
					    data.append('file', file)
 | 
				
			||||||
    alert.innerHTML = '';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $.ajax({
 | 
					    $.ajax({
 | 
				
			||||||
        url: window.location.pathname,
 | 
					        url: window.location.pathname,
 | 
				
			||||||
@@ -410,153 +55,84 @@ $('form[name=form-upload-questions]').submit(function(event) {
 | 
				
			|||||||
            window.location.reload();
 | 
					            window.location.reload();
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        error: function(response) {
 | 
					        error: function(response) {
 | 
				
			||||||
            if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) {
 | 
					            error_response(response);
 | 
				
			||||||
                alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                    <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                    ${response.responseJSON.error}
 | 
					 | 
				
			||||||
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                `;
 | 
					 | 
				
			||||||
            } else if (response.responseJSON.error instanceof Array) {
 | 
					 | 
				
			||||||
                for (var i = 0; i < response.responseJSON.error.length; i ++) {
 | 
					 | 
				
			||||||
                    alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                        <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                        ${response.responseJSON.error[i]}
 | 
					 | 
				
			||||||
                        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    `;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    event.preventDefault();
 | 
					    event.preventDefault();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
// Edit and Delete Test Button Handlers
 | 
					// Edit and Delete Test Button Handlers
 | 
				
			||||||
$('.delete-test').click(function(event) {
 | 
					$('.delete-test').click(function(event) {
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    _id = $(this).data('_id')
 | 
					    let _id = $(this).data('_id')
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $.ajax({
 | 
					    $.ajax({
 | 
				
			||||||
        url: `/admin/tests/delete/${_id}`,
 | 
					        url: `/admin/tests/delete/`,
 | 
				
			||||||
        type: 'GET',
 | 
					        type: 'POST',
 | 
				
			||||||
 | 
					        data: JSON.stringify({'_id': _id}),
 | 
				
			||||||
 | 
					        contentType: 'application/json',
 | 
				
			||||||
        success: function(response) {
 | 
					        success: function(response) {
 | 
				
			||||||
            window.location.href = '/admin/tests/';
 | 
					            window.location.href = '/admin/tests/';
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        error: function(response) {
 | 
					        error: function(response){
 | 
				
			||||||
            if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) {
 | 
					            error_response(response);
 | 
				
			||||||
                alert.innerHTML = alert.innerHTML + `
 | 
					        },
 | 
				
			||||||
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                    <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                    ${response.responseJSON.error}
 | 
					 | 
				
			||||||
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                `;
 | 
					 | 
				
			||||||
            } else if (response.responseJSON.error instanceof Array) {
 | 
					 | 
				
			||||||
                for (var i = 0; i < response.responseJSON.error.length; i ++) {
 | 
					 | 
				
			||||||
                    alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                        <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                        ${response.responseJSON.error[i]}
 | 
					 | 
				
			||||||
                        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    `;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    event.preventDefault();
 | 
					    event.preventDefault();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Edit and Delete Dataset Button Handlers
 | 
					// Edit Dataset Button Handlers
 | 
				
			||||||
$('.delete-question-dataset').click(function(event) {
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    var alert = document.getElementById('alert-box');
 | 
					 | 
				
			||||||
    alert.innerHTML = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    var filename = $(this).data('filename');
 | 
					 | 
				
			||||||
    var disabled = $(this).hasClass('disabled');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ( !disabled ) {        
 | 
					 | 
				
			||||||
        $.ajax({
 | 
					 | 
				
			||||||
            url: `/admin/settings/questions/delete/${filename}`,
 | 
					 | 
				
			||||||
            type: 'GET',
 | 
					 | 
				
			||||||
            success: function(response) {
 | 
					 | 
				
			||||||
                window.location.reload();
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            error: function(response) {
 | 
					 | 
				
			||||||
                if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) {
 | 
					 | 
				
			||||||
                    alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                        <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                        ${response.responseJSON.error}
 | 
					 | 
				
			||||||
                        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    `;
 | 
					 | 
				
			||||||
                } else if (response.responseJSON.error instanceof Array) {
 | 
					 | 
				
			||||||
                    for (var i = 0; i < response.responseJSON.error.length; i ++) {
 | 
					 | 
				
			||||||
                        alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                        <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                            <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                            ${response.responseJSON.error[i]}
 | 
					 | 
				
			||||||
                            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                        </div>
 | 
					 | 
				
			||||||
                        `;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    event.preventDefault();
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$('.edit-question-dataset').click(function(event) {
 | 
					$('.edit-question-dataset').click(function(event) {
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    var alert = document.getElementById('alert-box');
 | 
					 | 
				
			||||||
    alert.innerHTML = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    var filename = $(this).data('filename');
 | 
					    var filename = $(this).data('filename');
 | 
				
			||||||
 | 
					    var action = $(this).data('action');
 | 
				
			||||||
    var disabled = $(this).hasClass('disabled');
 | 
					    var disabled = $(this).hasClass('disabled');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ( !disabled ) {
 | 
					    if ( !disabled ) {
 | 
				
			||||||
        $.ajax({
 | 
					        $.ajax({
 | 
				
			||||||
            url: `/admin/settings/questions/default/${filename}`,
 | 
					            url: `/admin/settings/questions/${action}/`,
 | 
				
			||||||
            type: 'GET',
 | 
					            type: 'POST',
 | 
				
			||||||
 | 
					            data: JSON.stringify({'filename': filename}),
 | 
				
			||||||
 | 
					            contentType: 'application/json',
 | 
				
			||||||
            success: function(response) {
 | 
					            success: function(response) {
 | 
				
			||||||
                window.location.reload();
 | 
					                window.location.reload();
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            error: function(response) {
 | 
					            error: function(response){
 | 
				
			||||||
                if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) {
 | 
					                error_response(response);
 | 
				
			||||||
                    alert.innerHTML = alert.innerHTML + `
 | 
					            },
 | 
				
			||||||
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                        <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                        ${response.responseJSON.error}
 | 
					 | 
				
			||||||
                        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    `;
 | 
					 | 
				
			||||||
                } else if (response.responseJSON.error instanceof Array) {
 | 
					 | 
				
			||||||
                    for (var i = 0; i < response.responseJSON.error.length; i ++) {
 | 
					 | 
				
			||||||
                        alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                        <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                            <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                            ${response.responseJSON.error[i]}
 | 
					 | 
				
			||||||
                            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                        </div>
 | 
					 | 
				
			||||||
                        `;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    event.preventDefault();
 | 
					    event.preventDefault();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function error_response(response) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var alert = $("#alert-box");
 | 
				
			||||||
 | 
					    alert.html('');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) {
 | 
				
			||||||
 | 
					        alert.html(`
 | 
				
			||||||
 | 
					        <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
				
			||||||
 | 
					            <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
				
			||||||
 | 
					            ${response.responseJSON.error}
 | 
				
			||||||
 | 
					            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        `);
 | 
				
			||||||
 | 
					    } else if (response.responseJSON.error instanceof Array) {
 | 
				
			||||||
 | 
					        for (var i = 0; i < response.responseJSON.error.length; i ++) {
 | 
				
			||||||
 | 
					            alert.html(`
 | 
				
			||||||
 | 
					            <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
				
			||||||
 | 
					                <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
				
			||||||
 | 
					                ${response.responseJSON.error[i]}
 | 
				
			||||||
 | 
					                <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            `);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Dismiss Cookie Alert
 | 
					// Dismiss Cookie Alert
 | 
				
			||||||
$('#dismiss-cookie-alert').click(function(event){
 | 
					$('#dismiss-cookie-alert').click(function(event){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,9 +2,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
{% block content %}
 | 
					{% block content %}
 | 
				
			||||||
    <div class="form-container">
 | 
					    <div class="form-container">
 | 
				
			||||||
        <form name="form-update-account" class="form-signin">
 | 
					        <form name="form-update-account" class="form-display form-post" action="{{ url_for(request.endpoint, **request.view_args) }}" data-rel-success="{{ url_for('admin_views.home') }}">
 | 
				
			||||||
            {% include "admin/components/server-alerts.html" %}
 | 
					            {% include "admin/components/server-alerts.html" %}
 | 
				
			||||||
            <h2 class="form-signin-heading">Update Your Account</h2>
 | 
					            <h2 class="form-heading">Update Your Account</h2>
 | 
				
			||||||
            {{ form.hidden_tag() }}
 | 
					            {{ form.hidden_tag() }}
 | 
				
			||||||
            <div class="form-label-group">
 | 
					            <div class="form-label-group">
 | 
				
			||||||
                Please confirm <strong>your current password</strong> before making any changes to your user account.
 | 
					                Please confirm <strong>your current password</strong> before making any changes to your user account.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
{% block content %}
 | 
					{% block content %}
 | 
				
			||||||
    <div class="form-container">
 | 
					    <div class="form-container">
 | 
				
			||||||
        <form name="form-login" class="form-signin">
 | 
					        <form name="form-login" class="form-display form-post" action="{{ url_for(request.endpoint, **request.view_args) }}" data-rel-success="{{ url_for('admin_views.home') }}">
 | 
				
			||||||
            {% include "admin/components/server-alerts.html" %}
 | 
					            {% include "admin/components/server-alerts.html" %}
 | 
				
			||||||
            <h2 class="form">Log In</h2>
 | 
					            <h2 class="form">Log In</h2>
 | 
				
			||||||
            {{ form.hidden_tag() }}
 | 
					            {{ form.hidden_tag() }}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,9 +10,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
{% block content %}
 | 
					{% block content %}
 | 
				
			||||||
    <div class="form-container">
 | 
					    <div class="form-container">
 | 
				
			||||||
        <form name="form-register" action="" method="" class="form-signin">
 | 
					        <form name="form-register" class="form-display form-post" action="{{ url_for(request.endpoint, **request.view_args) }}" data-rel-success="{{ url_for('admin_auth.login') }}">
 | 
				
			||||||
            {% include "admin/components/server-alerts.html" %}
 | 
					            {% include "admin/components/server-alerts.html" %}
 | 
				
			||||||
            <h2 class="form-signin-heading">Register an Account</h2>
 | 
					            <h2 class="form-heading">Register an Account</h2>
 | 
				
			||||||
                {{ form.hidden_tag() }}
 | 
					                {{ form.hidden_tag() }}
 | 
				
			||||||
            <div class="form-label-group">
 | 
					            <div class="form-label-group">
 | 
				
			||||||
                {{ form.username(class_="form-control", autofocus=true, placeholder="Username") }}
 | 
					                {{ form.username(class_="form-control", autofocus=true, placeholder="Username") }}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,9 +2,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
{% block content %}
 | 
					{% block content %}
 | 
				
			||||||
<div class="form-container">
 | 
					<div class="form-container">
 | 
				
			||||||
    <form name="form-reset" class="form-signin">
 | 
					    <form name="form-reset" class="form-display form-post" action="{{ url_for(request.endpoint, **request.view_args) }}" data-rel-success="{{ url_for('admin_auth.login') }}">
 | 
				
			||||||
        {% include "admin/components/server-alerts.html" %}
 | 
					        {% include "admin/components/server-alerts.html" %}
 | 
				
			||||||
        <h2 class="form-signin-heading">Reset Password</h2>
 | 
					        <h2 class="form-heading">Reset Password</h2>
 | 
				
			||||||
        {{ form.hidden_tag() }}
 | 
					        {{ form.hidden_tag() }}
 | 
				
			||||||
        <div class="form-label-group">
 | 
					        <div class="form-label-group">
 | 
				
			||||||
            {{ form.username(class_="form-control", autofocus=true, placeholder="Enter Username") }}
 | 
					            {{ form.username(class_="form-control", autofocus=true, placeholder="Enter Username") }}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,9 +2,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
{% block content %}
 | 
					{% block content %}
 | 
				
			||||||
<div class="form-container">
 | 
					<div class="form-container">
 | 
				
			||||||
    <form name="form-update-password" class="form-signin">
 | 
					    <form name="form-update-password" class="form-display form-post" action="{{ url_for(request.endpoint, **request.view_args) }}" data-rel-success="{{ url_for('admin_auth.login') }}">
 | 
				
			||||||
        {% include "admin/components/server-alerts.html" %}
 | 
					        {% include "admin/components/server-alerts.html" %}
 | 
				
			||||||
        <h2 class="form-signin-heading">Update Password</h2>
 | 
					        <h2 class="form-heading">Update Password</h2>
 | 
				
			||||||
        {{ form.hidden_tag() }}
 | 
					        {{ form.hidden_tag() }}
 | 
				
			||||||
        <div class="form-label-group">
 | 
					        <div class="form-label-group">
 | 
				
			||||||
            {{ form.password(class_="form-control", placeholder="Password") }}
 | 
					            {{ form.password(class_="form-control", placeholder="Password") }}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,9 +2,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
{% block content %}
 | 
					{% block content %}
 | 
				
			||||||
    <div class="form-container">
 | 
					    <div class="form-container">
 | 
				
			||||||
        <form name="form-delete-user" class="form-signin">
 | 
					        <form name="form-delete-user" class="form-display form-post" action="{{ url_for(request.endpoint, **request.view_args) }}" data-rel-success="{{ url_for('admin_views.users') }}">
 | 
				
			||||||
            {% include "admin/components/server-alerts.html" %}
 | 
					            {% include "admin/components/server-alerts.html" %}
 | 
				
			||||||
            <h2 class="form-signin-heading">Delete User ‘{{ user.username }}’?</h2>
 | 
					            <h2 class="form-heading">Delete User ‘{{ user.username }}’?</h2>
 | 
				
			||||||
            {{ form.hidden_tag() }}
 | 
					            {{ form.hidden_tag() }}
 | 
				
			||||||
            <p>This action cannot be undone. Deleting an account will mean {{ user.username }} will no longer be able to log in to the admin console.</p>
 | 
					            <p>This action cannot be undone. Deleting an account will mean {{ user.username }} will no longer be able to log in to the admin console.</p>
 | 
				
			||||||
            <p>Are you sure you want to proceed?</p>
 | 
					            <p>Are you sure you want to proceed?</p>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,8 @@
 | 
				
			|||||||
{% extends "admin/components/datatable.html" %}
 | 
					{% extends "admin/components/datatable.html" %}
 | 
				
			||||||
{% block title %} SKA Referee Test | Upload Questions {% endblock %}
 | 
					{% block title %} SKA Referee Test | Upload Questions {% endblock %}
 | 
				
			||||||
{% block content %}
 | 
					{% block content %}
 | 
				
			||||||
    <h1>Manage Question Datasets</h1>
 | 
					 | 
				
			||||||
    {% include "admin/components/client-alerts.html" %}
 | 
					    {% include "admin/components/client-alerts.html" %}
 | 
				
			||||||
 | 
					    <h1>Manage Question Datasets</h1>
 | 
				
			||||||
    {% if data %}
 | 
					    {% if data %}
 | 
				
			||||||
        <table id="question-datasets-table" class="table table-striped" style="width:100%">
 | 
					        <table id="question-datasets-table" class="table table-striped" style="width:100%">
 | 
				
			||||||
            <thead>
 | 
					            <thead>
 | 
				
			||||||
@@ -56,14 +56,16 @@
 | 
				
			|||||||
                                href="#"
 | 
					                                href="#"
 | 
				
			||||||
                                class="btn btn-primary edit-question-dataset {% if element.filename == default %}disabled{% endif %}"
 | 
					                                class="btn btn-primary edit-question-dataset {% if element.filename == default %}disabled{% endif %}"
 | 
				
			||||||
                                data-filename="{{ element.filename }}"
 | 
					                                data-filename="{{ element.filename }}"
 | 
				
			||||||
 | 
					                                data-action="default"
 | 
				
			||||||
                                title="Make Default"
 | 
					                                title="Make Default"
 | 
				
			||||||
                            >
 | 
					                            >
 | 
				
			||||||
                                <i class="bi bi-file-earmark-text-fill button-icon"></i>
 | 
					                                <i class="bi bi-file-earmark-text-fill button-icon"></i>
 | 
				
			||||||
                            </button>
 | 
					                            </button>
 | 
				
			||||||
                            <a
 | 
					                            <a
 | 
				
			||||||
                                href="#"
 | 
					                                href="#"
 | 
				
			||||||
                                class="btn btn-danger delete-question-dataset {% if element.filename == default %}disabled{% endif %}"
 | 
					                                class="btn btn-danger edit-question-dataset {% if element.filename == default %}disabled{% endif %}"
 | 
				
			||||||
                                data-filename="{{ element.filename }}"
 | 
					                                data-filename="{{ element.filename }}"
 | 
				
			||||||
 | 
					                                data-action="delete"
 | 
				
			||||||
                                title="Delete Dataset"
 | 
					                                title="Delete Dataset"
 | 
				
			||||||
                            >
 | 
					                            >
 | 
				
			||||||
                                <i class="bi bi-file-earmark-excel-fill button-icon"></i>
 | 
					                                <i class="bi bi-file-earmark-excel-fill button-icon"></i>
 | 
				
			||||||
@@ -80,8 +82,8 @@
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    {% endif %}
 | 
					    {% endif %}
 | 
				
			||||||
    <div class="form-container">
 | 
					    <div class="form-container">
 | 
				
			||||||
        <form name="form-upload-questions" method="post" action="#" class="form-signin" enctype="multipart/form-data">
 | 
					        <form name="form-upload-questions" class="form-display" action="{{ url_for(request.endpoint, **request.view_args) }}" data-rel-success="" enctype="multipart/form-data">
 | 
				
			||||||
            <h2 class="form-signin-heading">Upload Question Dataset</h2>
 | 
					            <h2 class="form-heading">Upload Question Dataset</h2>
 | 
				
			||||||
            {{ form.hidden_tag() }}
 | 
					            {{ form.hidden_tag() }}
 | 
				
			||||||
            <div class="form-upload">
 | 
					            <div class="form-upload">
 | 
				
			||||||
                {{ form.data_file() }}
 | 
					                {{ form.data_file() }}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,9 +2,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
{% block content %}
 | 
					{% block content %}
 | 
				
			||||||
    <div class="form-container">
 | 
					    <div class="form-container">
 | 
				
			||||||
        <form name="form-update-user" class="form-signin">
 | 
					        <form name="form-update-user" class="form-display form-post" action="{{ url_for(request.endpoint, **request.view_args) }}" data-rel-success="{{ url_for('admin_views.users') }}">
 | 
				
			||||||
            {% include "admin/components/server-alerts.html" %}
 | 
					            {% include "admin/components/server-alerts.html" %}
 | 
				
			||||||
            <h2 class="form-signin-heading">Update User ‘{{ user.username }}’</h2>
 | 
					            <h2 class="form-heading">Update User ‘{{ user.username }}’</h2>
 | 
				
			||||||
            {{ form.hidden_tag() }}
 | 
					            {{ form.hidden_tag() }}
 | 
				
			||||||
            <div class="form-label-group">
 | 
					            <div class="form-label-group">
 | 
				
			||||||
                {{ form.email(class_="form-control", placeholder="Email Address", value = user.email) }}
 | 
					                {{ form.email(class_="form-control", placeholder="Email Address", value = user.email) }}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -71,8 +71,8 @@
 | 
				
			|||||||
        </tbody>
 | 
					        </tbody>
 | 
				
			||||||
    </table>
 | 
					    </table>
 | 
				
			||||||
    <div class="form-container">
 | 
					    <div class="form-container">
 | 
				
			||||||
        <form name="form-create-user" class="form-signin">
 | 
					        <form name="form-create-user" class="form-display form-post" action="{{ url_for(request.endpoint, **request.view_args) }}" data-rel-success="">
 | 
				
			||||||
            <h2 class="form-signin-heading">Create User</h2>
 | 
					            <h2 class="form-heading">Create User</h2>
 | 
				
			||||||
            {{ form.hidden_tag() }}
 | 
					            {{ form.hidden_tag() }}
 | 
				
			||||||
            <div class="form-label-group">
 | 
					            <div class="form-label-group">
 | 
				
			||||||
                {{ form.username(class_="form-control", placeholder="Enter Username") }}
 | 
					                {{ form.username(class_="form-control", placeholder="Enter Username") }}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,18 +43,18 @@
 | 
				
			|||||||
                        <td>
 | 
					                        <td>
 | 
				
			||||||
                            {% if test.time_limit == None -%}
 | 
					                            {% if test.time_limit == None -%}
 | 
				
			||||||
                                None
 | 
					                                None
 | 
				
			||||||
                            {% elif test.time_limit == '60' -%}
 | 
					                            {% elif test.time_limit == 60 -%}
 | 
				
			||||||
                                1 hour
 | 
					                                1 hour
 | 
				
			||||||
                            {% elif test.time_limit == '90' -%}
 | 
					                            {% elif test.time_limit == 90 -%}
 | 
				
			||||||
                                1 hour 30 min
 | 
					                                1 hour 30 min
 | 
				
			||||||
                            {% elif test.time_limit == '120' -%}
 | 
					                            {% elif test.time_limit == 120 -%}
 | 
				
			||||||
                                2 hours
 | 
					                                2 hours
 | 
				
			||||||
                            {% else -%}
 | 
					                            {% else -%}
 | 
				
			||||||
                                {{ test.time_limit }}
 | 
					                                {{ test.time_limit }}
 | 
				
			||||||
                            {% endif %}
 | 
					                            {% endif %}
 | 
				
			||||||
                        </td>
 | 
					                        </td>
 | 
				
			||||||
                        <td>
 | 
					                        <td>
 | 
				
			||||||
                            {{ test.attempts|length }}
 | 
					                            {{ test.entries|length }}
 | 
				
			||||||
                        </td>
 | 
					                        </td>
 | 
				
			||||||
                        <td class="row-actions">
 | 
					                        <td class="row-actions">
 | 
				
			||||||
                            <a
 | 
					                            <a
 | 
				
			||||||
@@ -86,8 +86,8 @@
 | 
				
			|||||||
    {% endif %}
 | 
					    {% endif %}
 | 
				
			||||||
    {% if form %}
 | 
					    {% if form %}
 | 
				
			||||||
        <div class="form-container">
 | 
					        <div class="form-container">
 | 
				
			||||||
            <form name="form-create-test" class="form-signin">
 | 
					            <form name="form-create-test" class="form-display form-post" action="{{ url_for(request.endpoint, **request.view_args) }}" data-rel-success="/admin/tests/">
 | 
				
			||||||
                <h2 class="form-signin-heading">Create Exam</h2>
 | 
					                <h2 class="form-heading">Create Exam</h2>
 | 
				
			||||||
                {{ form.hidden_tag() }}
 | 
					                {{ form.hidden_tag() }}
 | 
				
			||||||
                <div class="form-date-input">
 | 
					                <div class="form-date-input">
 | 
				
			||||||
                    {{ form.start_date(placeholder="Enter Start Date", class_ = "datepicker") }}
 | 
					                    {{ form.start_date(placeholder="Enter Start Date", class_ = "datepicker") }}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@ import secrets
 | 
				
			|||||||
from main import mail
 | 
					from main import mail
 | 
				
			||||||
from datetime import datetime, date, timedelta
 | 
					from datetime import datetime, date, timedelta
 | 
				
			||||||
from .models.tests import Test
 | 
					from .models.tests import Test
 | 
				
			||||||
from common.data_tools import get_default_dataset, get_time_options
 | 
					from common.data_tools import get_default_dataset, get_time_options, available_datasets
 | 
				
			||||||
 | 
					
 | 
				
			||||||
views = Blueprint(
 | 
					views = Blueprint(
 | 
				
			||||||
    'admin_views',
 | 
					    'admin_views',
 | 
				
			||||||
@@ -69,18 +69,6 @@ def disable_if_logged_in(function):
 | 
				
			|||||||
        return function(*args, **kwargs)
 | 
					        return function(*args, **kwargs)
 | 
				
			||||||
    return decorated_function
 | 
					    return decorated_function
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def available_datasets():
 | 
					 | 
				
			||||||
        files = glob(os.path.join(app.config["DATA_FILE_DIRECTORY"],'*.json'))
 | 
					 | 
				
			||||||
        default = get_default_dataset()
 | 
					 | 
				
			||||||
        output = []
 | 
					 | 
				
			||||||
        for file in files:
 | 
					 | 
				
			||||||
            filename = file.rsplit('/')[-1]
 | 
					 | 
				
			||||||
            label = f'{filename[:-5]} (Default)' if filename == default else filename[:-5]
 | 
					 | 
				
			||||||
            element = (filename, label)
 | 
					 | 
				
			||||||
            output.append(element)
 | 
					 | 
				
			||||||
        output.reverse()
 | 
					 | 
				
			||||||
        return output
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@views.route('/')
 | 
					@views.route('/')
 | 
				
			||||||
@views.route('/home/')
 | 
					@views.route('/home/')
 | 
				
			||||||
@views.route('/dashboard/')
 | 
					@views.route('/dashboard/')
 | 
				
			||||||
@@ -288,10 +276,11 @@ def questions():
 | 
				
			|||||||
        errors = [*form.errors]
 | 
					        errors = [*form.errors]
 | 
				
			||||||
        return jsonify({ 'error': errors}), 400
 | 
					        return jsonify({ 'error': errors}), 400
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@views.route('/settings/questions/delete/<filename>')
 | 
					@views.route('/settings/questions/delete/', methods=['POST'])
 | 
				
			||||||
@admin_account_required
 | 
					@admin_account_required
 | 
				
			||||||
@login_required
 | 
					@login_required
 | 
				
			||||||
def delete_questions(filename):
 | 
					def delete_questions():
 | 
				
			||||||
 | 
					    filename = request.get_json()['filename']
 | 
				
			||||||
    data_files = glob(os.path.join(app.config["DATA_FILE_DIRECTORY"],'*.json'))
 | 
					    data_files = glob(os.path.join(app.config["DATA_FILE_DIRECTORY"],'*.json'))
 | 
				
			||||||
    if any(filename in file for file in data_files):
 | 
					    if any(filename in file for file in data_files):
 | 
				
			||||||
        default = get_default_dataset()
 | 
					        default = get_default_dataset()
 | 
				
			||||||
@@ -309,10 +298,11 @@ def delete_questions(filename):
 | 
				
			|||||||
        return jsonify({'success': f'Question dataset {filename} has been deleted.'}), 200
 | 
					        return jsonify({'success': f'Question dataset {filename} has been deleted.'}), 200
 | 
				
			||||||
    return abort(404)
 | 
					    return abort(404)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@views.route('/settings/questions/default/<filename>')
 | 
					@views.route('/settings/questions/default/', methods=['POST'])
 | 
				
			||||||
@admin_account_required
 | 
					@admin_account_required
 | 
				
			||||||
@login_required
 | 
					@login_required
 | 
				
			||||||
def make_default_questions(filename):
 | 
					def make_default_questions():
 | 
				
			||||||
 | 
					    filename = request.get_json()['filename']
 | 
				
			||||||
    data_files = glob(os.path.join(app.config["DATA_FILE_DIRECTORY"],'*.json'))
 | 
					    data_files = glob(os.path.join(app.config["DATA_FILE_DIRECTORY"],'*.json'))
 | 
				
			||||||
    default_file_path = os.path.join(app.config['DATA_FILE_DIRECTORY'], '.default.txt')
 | 
					    default_file_path = os.path.join(app.config['DATA_FILE_DIRECTORY'], '.default.txt')
 | 
				
			||||||
    if any(filename in file for file in data_files):
 | 
					    if any(filename in file for file in data_files):
 | 
				
			||||||
@@ -369,7 +359,7 @@ def tests(filter=''):
 | 
				
			|||||||
@views.route('/tests/create/', methods=['POST'])
 | 
					@views.route('/tests/create/', methods=['POST'])
 | 
				
			||||||
@admin_account_required
 | 
					@admin_account_required
 | 
				
			||||||
@login_required
 | 
					@login_required
 | 
				
			||||||
def _tests():
 | 
					def create_test():
 | 
				
			||||||
    from .models.forms import CreateTest
 | 
					    from .models.forms import CreateTest
 | 
				
			||||||
    form = CreateTest()
 | 
					    form = CreateTest()
 | 
				
			||||||
    form.dataset.choices = available_datasets()
 | 
					    form.dataset.choices = available_datasets()
 | 
				
			||||||
@@ -405,8 +395,15 @@ def _tests():
 | 
				
			|||||||
        errors = [*form.expiry.errors, *form.time_limit.errors]
 | 
					        errors = [*form.expiry.errors, *form.time_limit.errors]
 | 
				
			||||||
        return jsonify({ 'error': errors}), 400
 | 
					        return jsonify({ 'error': errors}), 400
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@views.route('/tests/delete/<_id>/')
 | 
					@views.route('/tests/delete/', methods=['POST'])
 | 
				
			||||||
def delete_test(_id):
 | 
					def delete_test():
 | 
				
			||||||
 | 
					    _id = request.get_json()['_id']
 | 
				
			||||||
    if db.tests.find_one({'_id': _id}):
 | 
					    if db.tests.find_one({'_id': _id}):
 | 
				
			||||||
        return Test(_id = _id).delete()
 | 
					        return Test(_id = _id).delete()
 | 
				
			||||||
    return abort(404)
 | 
					    return jsonify({'error': 'Could not find the corresponding test to delete.'}), 404
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@views.route('/test/<id>/', methods=['GET','POST'])
 | 
				
			||||||
 | 
					def view_test(_id, filter=''):
 | 
				
			||||||
 | 
					    test = db.tests.find_one({'_id':_id})
 | 
				
			||||||
 | 
					    if not test:
 | 
				
			||||||
 | 
					        return abort(404)
 | 
				
			||||||
@@ -2,6 +2,7 @@ import os
 | 
				
			|||||||
import pathlib
 | 
					import pathlib
 | 
				
			||||||
from json import dump, loads
 | 
					from json import dump, loads
 | 
				
			||||||
from datetime import datetime, timedelta
 | 
					from datetime import datetime, timedelta
 | 
				
			||||||
 | 
					from glob import glob
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from flask.json import jsonify
 | 
					from flask.json import jsonify
 | 
				
			||||||
from main import app
 | 
					from main import app
 | 
				
			||||||
@@ -24,6 +25,18 @@ def get_default_dataset():
 | 
				
			|||||||
        default = default_file.read()
 | 
					        default = default_file.read()
 | 
				
			||||||
    return default
 | 
					    return default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def available_datasets():
 | 
				
			||||||
 | 
					        files = glob(os.path.join(app.config["DATA_FILE_DIRECTORY"],'*.json'))
 | 
				
			||||||
 | 
					        default = get_default_dataset()
 | 
				
			||||||
 | 
					        output = []
 | 
				
			||||||
 | 
					        for file in files:
 | 
				
			||||||
 | 
					            filename = file.rsplit('/')[-1]
 | 
				
			||||||
 | 
					            label = f'{filename[:-5]} (Default)' if filename == default else filename[:-5]
 | 
				
			||||||
 | 
					            element = (filename, label)
 | 
				
			||||||
 | 
					            output.append(element)
 | 
				
			||||||
 | 
					        output.reverse()
 | 
				
			||||||
 | 
					        return output
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def check_json_format(file):
 | 
					def check_json_format(file):
 | 
				
			||||||
    if not '.' in file.filename:
 | 
					    if not '.' in file.filename:
 | 
				
			||||||
        return False
 | 
					        return False
 | 
				
			||||||
@@ -168,7 +181,6 @@ def evaluate_answers(dataset: dict, answers: dict):
 | 
				
			|||||||
        'max': max
 | 
					        'max': max
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
def get_tags_list(dataset:dict):
 | 
					def get_tags_list(dataset:dict):
 | 
				
			||||||
    output = []
 | 
					    output = []
 | 
				
			||||||
    blocks = dataset['questions']
 | 
					    blocks = dataset['questions']
 | 
				
			||||||
@@ -180,7 +192,6 @@ def get_tags_list(dataset:dict):
 | 
				
			|||||||
                output = list(set(output) | set(question['tags']))
 | 
					                output = list(set(output) | set(question['tags']))
 | 
				
			||||||
    return output           
 | 
					    return output           
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
def get_time_options():
 | 
					def get_time_options():
 | 
				
			||||||
    time_options = [
 | 
					    time_options = [
 | 
				
			||||||
        ('none', 'None'),
 | 
					        ('none', 'None'),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,16 +28,16 @@ $("#btn-toggle-navigator").click(function(event){
 | 
				
			|||||||
        $(".navigator-text").fadeIn();
 | 
					        $(".navigator-text").fadeIn();
 | 
				
			||||||
        $(".review-text").fadeOut();
 | 
					        $(".review-text").fadeOut();
 | 
				
			||||||
        toggle_navigator = false;
 | 
					        toggle_navigator = false;
 | 
				
			||||||
        $quiz_navigator.focus();
 | 
					        $(window).scrollTop(0);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        $quiz_navigator.fadeOut();
 | 
					        $quiz_navigator.fadeOut();
 | 
				
			||||||
        if (toggle_settings) {
 | 
					        if (toggle_settings) {
 | 
				
			||||||
            $quiz_settings.fadeIn();
 | 
					            $quiz_settings.fadeIn();
 | 
				
			||||||
            $quiz_settings.focus()
 | 
					            $(window).scrollTop(0);
 | 
				
			||||||
            toggle_settings = false;
 | 
					            toggle_settings = false;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            $quiz_render.fadeIn();
 | 
					            $quiz_render.fadeIn();
 | 
				
			||||||
            $question_title.focus();
 | 
					            $(window).scrollTop(0);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    event.preventDefault();
 | 
					    event.preventDefault();
 | 
				
			||||||
@@ -51,17 +51,17 @@ $("#btn-toggle-settings").click(function(event){
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        $quiz_render.fadeOut();
 | 
					        $quiz_render.fadeOut();
 | 
				
			||||||
        $quiz_settings.fadeIn();
 | 
					        $quiz_settings.fadeIn();
 | 
				
			||||||
        $quiz_settings.focus()
 | 
					        $(window).scrollTop(0);
 | 
				
			||||||
        toggle_settings = false;
 | 
					        toggle_settings = false;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        $quiz_settings.fadeOut();
 | 
					        $quiz_settings.fadeOut();
 | 
				
			||||||
        if (toggle_navigator) {
 | 
					        if (toggle_navigator) {
 | 
				
			||||||
            $quiz_navigator.fadeIn();
 | 
					            $quiz_navigator.fadeIn();
 | 
				
			||||||
            toggle_navigator = false;
 | 
					            toggle_navigator = false;
 | 
				
			||||||
            $quiz_navigator.focus();
 | 
					            $(window).scrollTop(0);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            $quiz_render.fadeIn();
 | 
					            $quiz_render.fadeIn();
 | 
				
			||||||
            $question_title.focus();
 | 
					            $(window).scrollTop(0);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    event.preventDefault();
 | 
					    event.preventDefault();
 | 
				
			||||||
@@ -71,7 +71,7 @@ $(".btn-quiz-return").click(function(event){
 | 
				
			|||||||
    $quiz_navigator.fadeOut();
 | 
					    $quiz_navigator.fadeOut();
 | 
				
			||||||
    $quiz_settings.fadeOut();
 | 
					    $quiz_settings.fadeOut();
 | 
				
			||||||
    $quiz_render.fadeIn();
 | 
					    $quiz_render.fadeIn();
 | 
				
			||||||
    $question_title.focus();
 | 
					    $(window).scrollTop(0);
 | 
				
			||||||
    toggle_settings = false;
 | 
					    toggle_settings = false;
 | 
				
			||||||
    toggle_navigator = false;
 | 
					    toggle_navigator = false;
 | 
				
			||||||
    event.preventDefault();
 | 
					    event.preventDefault();
 | 
				
			||||||
@@ -85,9 +85,10 @@ $("#navigator-container").on("click", ".q-navigator-button", function(event){
 | 
				
			|||||||
    check_answered();
 | 
					    check_answered();
 | 
				
			||||||
    update_navigator();
 | 
					    update_navigator();
 | 
				
			||||||
    current_question = parseInt($(this).attr("name"));
 | 
					    current_question = parseInt($(this).attr("name"));
 | 
				
			||||||
 | 
					    $quiz_navigator.fadeOut();
 | 
				
			||||||
    $quiz_render.fadeIn();
 | 
					    $quiz_render.fadeIn();
 | 
				
			||||||
    $question_title.focus();
 | 
					    $question_title.focus();
 | 
				
			||||||
    $quiz_navigator.fadeOut();
 | 
					    $(window).scrollTop(0);
 | 
				
			||||||
    toggle_navigator = false;
 | 
					    toggle_navigator = false;
 | 
				
			||||||
    toggle_settings = false;
 | 
					    toggle_settings = false;
 | 
				
			||||||
    render_question();
 | 
					    render_question();
 | 
				
			||||||
@@ -164,25 +165,7 @@ $("#btn-start-quiz").click(function(event){
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        error: function(response) {
 | 
					        error: function(response) {
 | 
				
			||||||
            if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) {
 | 
					            error_response(response);
 | 
				
			||||||
                alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                    <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                    ${response.responseJSON.error}
 | 
					 | 
				
			||||||
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                `;
 | 
					 | 
				
			||||||
            } else if (response.responseJSON.error instanceof Array) {
 | 
					 | 
				
			||||||
                for (var i = 0; i < response.responseJSON.error.length; i ++) {
 | 
					 | 
				
			||||||
                    alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                        <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                        ${response.responseJSON.error[i]}
 | 
					 | 
				
			||||||
                        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    `;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -209,7 +192,7 @@ $("#q-review-answers").click(function(event){
 | 
				
			|||||||
        $(".navigator-text").fadeOut();
 | 
					        $(".navigator-text").fadeOut();
 | 
				
			||||||
        $(".review-text").fadeIn();
 | 
					        $(".review-text").fadeIn();
 | 
				
			||||||
        toggle_navigator = false;
 | 
					        toggle_navigator = false;
 | 
				
			||||||
        $quiz_navigator.focus();
 | 
					        $(window).scrollTop(0);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        $quiz_navigator.fadeOut();
 | 
					        $quiz_navigator.fadeOut();
 | 
				
			||||||
        if (toggle_settings) {
 | 
					        if (toggle_settings) {
 | 
				
			||||||
@@ -238,25 +221,7 @@ $(".quiz-button-submit").click(function(event){
 | 
				
			|||||||
            window.location.href = `/result/`;
 | 
					            window.location.href = `/result/`;
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        error: function(response) {
 | 
					        error: function(response) {
 | 
				
			||||||
            if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) {
 | 
					            error_response(response);
 | 
				
			||||||
                alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                    <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                    ${response.responseJSON.error}
 | 
					 | 
				
			||||||
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                `;
 | 
					 | 
				
			||||||
            } else if (response.responseJSON.error instanceof Array) {
 | 
					 | 
				
			||||||
                for (var i = 0; i < response.responseJSON.error.length; i ++) {
 | 
					 | 
				
			||||||
                    alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                        <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                        ${response.responseJSON.error[i]}
 | 
					 | 
				
			||||||
                        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    `;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -392,6 +357,7 @@ function render_question() {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    $question_options.html(options_output);
 | 
					    $question_options.html(options_output);
 | 
				
			||||||
    $question_title.focus();
 | 
					    $question_title.focus();
 | 
				
			||||||
 | 
					    $(window).scrollTop(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function check_answered() {
 | 
					function check_answered() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ $(document).ready(function() {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $('.test-code-input').keyup(function() {
 | 
					    $('.test-code-input').keyup(function() {
 | 
				
			||||||
        var input = $(this).val().split("-").join("").split("—").join(""); // remove hyphens and mdashes
 | 
					        var input = $(this).val().split("-").join("").split("—").join("");
 | 
				
			||||||
        if (input.length > 0) {
 | 
					        if (input.length > 0) {
 | 
				
			||||||
          input = input.match(new RegExp('.{1,4}', 'g')).join("—");
 | 
					          input = input.match(new RegExp('.{1,4}', 'g')).join("—");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -15,11 +15,8 @@ $(document).ready(function() {
 | 
				
			|||||||
$('form[name=form-quiz-start]').submit(function(event) {
 | 
					$('form[name=form-quiz-start]').submit(function(event) {
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    var $form = $(this);
 | 
					    var $form = $(this);
 | 
				
			||||||
    var alert = document.getElementById('alert-box');
 | 
					 | 
				
			||||||
    var data = $form.serialize();
 | 
					    var data = $form.serialize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    alert.innerHTML = ''
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.ajax({
 | 
					    $.ajax({
 | 
				
			||||||
        url: window.location.pathname,
 | 
					        url: window.location.pathname,
 | 
				
			||||||
        type: 'POST',
 | 
					        type: 'POST',
 | 
				
			||||||
@@ -31,31 +28,39 @@ $('form[name=form-quiz-start]').submit(function(event) {
 | 
				
			|||||||
            window.location.href = `/test/`;
 | 
					            window.location.href = `/test/`;
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        error: function(response) {
 | 
					        error: function(response) {
 | 
				
			||||||
            if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) {
 | 
					            error_response(response);
 | 
				
			||||||
                alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                    <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                    ${response.responseJSON.error}
 | 
					 | 
				
			||||||
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                `;
 | 
					 | 
				
			||||||
            } else if (response.responseJSON.error instanceof Array) {
 | 
					 | 
				
			||||||
                for (var i = 0; i < response.responseJSON.error.length; i ++) {
 | 
					 | 
				
			||||||
                    alert.innerHTML = alert.innerHTML + `
 | 
					 | 
				
			||||||
                    <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
					 | 
				
			||||||
                        <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
					 | 
				
			||||||
                        ${response.responseJSON.error[i]}
 | 
					 | 
				
			||||||
                        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                    `;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    event.preventDefault();
 | 
					    event.preventDefault();
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function error_response(response) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var alert = $("#alert-box");
 | 
				
			||||||
 | 
					    alert.html('');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (typeof response.responseJSON.error === 'string' || response.responseJSON.error instanceof String) {
 | 
				
			||||||
 | 
					        alert.html(`
 | 
				
			||||||
 | 
					        <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
				
			||||||
 | 
					            <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
				
			||||||
 | 
					            ${response.responseJSON.error}
 | 
				
			||||||
 | 
					            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        `);
 | 
				
			||||||
 | 
					    } else if (response.responseJSON.error instanceof Array) {
 | 
				
			||||||
 | 
					        for (var i = 0; i < response.responseJSON.error.length; i ++) {
 | 
				
			||||||
 | 
					            alert.html(`
 | 
				
			||||||
 | 
					            <div class="alert alert-danger alert-dismissible fade show" role="alert">
 | 
				
			||||||
 | 
					                <i class="bi bi-exclamation-triangle-fill" title="Danger"></i>
 | 
				
			||||||
 | 
					                ${response.responseJSON.error[i]}
 | 
				
			||||||
 | 
					                <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            `);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Dismiss Cookie Alert
 | 
					// Dismiss Cookie Alert
 | 
				
			||||||
$('#dismiss-cookie-alert').click(function(event){
 | 
					$('#dismiss-cookie-alert').click(function(event){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,10 +59,10 @@ def start():
 | 
				
			|||||||
            test = db.tests.find_one({'test_code': test_code})
 | 
					            test = db.tests.find_one({'test_code': test_code})
 | 
				
			||||||
            if not test:
 | 
					            if not test:
 | 
				
			||||||
                return jsonify({'error': 'The exam code you entered is invalid.'}), 400
 | 
					                return jsonify({'error': 'The exam code you entered is invalid.'}), 400
 | 
				
			||||||
            if test['expiry_date'] < datetime.utcnow():
 | 
					            if test['expiry_date'] + timedelta(days=1) < datetime.utcnow():
 | 
				
			||||||
                return jsonify({'error': f'The exam code you entered expired on {test["expiry_date"].strftime("%d %b %Y")}.'}), 400
 | 
					                return jsonify({'error': f'The exam code you entered expired on {test["expiry_date"].strftime("%d %b %Y")} UTC.'}), 400
 | 
				
			||||||
            if test['start_date'] > datetime.utcnow():
 | 
					            if test['start_date'] > datetime.utcnow():
 | 
				
			||||||
                return jsonify({'error': f'The exam has not yet opened. Your exam code will be valid from {test["start_date"].strftime("%d %b %Y %H:%M")}.'}), 400
 | 
					                return jsonify({'error': f'The exam has not yet opened. Your exam code will be valid from {test["start_date"].strftime("%d %b %Y %H:%M")} UTC.'}), 400
 | 
				
			||||||
            entry = {
 | 
					            entry = {
 | 
				
			||||||
                '_id': uuid4().hex,
 | 
					                '_id': uuid4().hex,
 | 
				
			||||||
                'name': encrypt(name),
 | 
					                'name': encrypt(name),
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user