Move Code into repo
This commit is contained in:
56
app/templates/_formhelpers.jinja2
Normal file
56
app/templates/_formhelpers.jinja2
Normal file
@@ -0,0 +1,56 @@
|
||||
{% macro render_field(field, label=None, label_visible=true, right_url=None, right_label=None) -%}
|
||||
<div class="form-group {% if field.errors %}has-error{% endif %} {{ kwargs.pop('class_', '') }}">
|
||||
{% if field.type != 'HiddenField' and label_visible %}
|
||||
{% if not label %}{% set label=field.label.text %}{% endif %}
|
||||
<label for="{{ field.id }}" class="control-label">{{ label|safe }}</label>
|
||||
{% endif %}
|
||||
{{ field(class_='form-control', **kwargs) }}
|
||||
{% if field.errors %}
|
||||
{% for e in field.errors %}
|
||||
<p class="help-block text-danger">{{ e }}</p>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro render_checkbox_field(field, label=None) -%}
|
||||
{% if not label %}{% set label=field.label.text %}{% endif %}
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
{{ field(type='checkbox', **kwargs) }} {{ label }}
|
||||
</label>
|
||||
{% if field.errors %}
|
||||
{% for e in field.errors %}
|
||||
<p class="help-block text-danger">{{ e }}</p>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro render_radio_field(field) -%}
|
||||
{% for value, label, checked in field.iter_choices() %}
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" name="{{ field.id }}" id="{{ field.id }}" value="{{ value }}"{% if checked %} checked{% endif %}>
|
||||
{{ label }}
|
||||
</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if field.errors %}
|
||||
{% for e in field.errors %}
|
||||
<p class="help-block text-danger">{{ e }}</p>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro render_submit_field(field, label=None, tabindex=None) -%}
|
||||
{% if not label %}{% set label=field.label.text %}{% endif %}
|
||||
{#<button type="submit" class="form-control btn btn-default btn-primary">{{label}}</button>#}
|
||||
<input type="submit" class="btn btn-lg btn-block btn-primary {{ kwargs.pop('class_', '') }}" value="{{label}}"
|
||||
{% if tabindex %}tabindex="{{ tabindex }}"{% endif %}
|
||||
>
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro sentence_case(text) %}
|
||||
{{ text[0]|upper}}{{text[1:] }}
|
||||
{%- endmacro %}
|
21
app/templates/accounts/edit_gm_level.html.j2
Normal file
21
app/templates/accounts/edit_gm_level.html.j2
Normal file
@@ -0,0 +1,21 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
Edit GM Level for User {{ username }}
|
||||
{% endblock title %}
|
||||
|
||||
{% block content_before %}
|
||||
Edit GM Level for User {{ username }}
|
||||
{% endblock content_before %}
|
||||
|
||||
{% block content %}
|
||||
<form method=post>
|
||||
{{ form.csrf_token }}
|
||||
<div class="card shadow-sm mx-auto pb-3 bg-dark border-primary" style="width: 20rem;">
|
||||
<div class="card-body">
|
||||
{{ helper.render_field(form.gm_level) }}
|
||||
{{ helper.render_submit_field(form.submit) }}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock content %}
|
50
app/templates/accounts/index.html.j2
Normal file
50
app/templates/accounts/index.html.j2
Normal file
@@ -0,0 +1,50 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
Account Management
|
||||
{% endblock title %}
|
||||
|
||||
{% block content_before %}
|
||||
Account Management
|
||||
{% endblock content_before %}
|
||||
|
||||
{% block content %}
|
||||
<table class="table" id="accounts_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Actions</th>
|
||||
<th>Name</th>
|
||||
{% if config.USER_ENABLE_EMAIL %}
|
||||
<th>Email</th>
|
||||
{% endif %}
|
||||
<th>GM Level</th>
|
||||
<th>Locked</th>
|
||||
<th>Banned</th>
|
||||
<th>Muted</th>
|
||||
<th>Registered</th>
|
||||
{% if config.USER_ENABLE_EMAIL %}
|
||||
<th>Email Confirmed</th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block js %}
|
||||
{{ super () }}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
let accounts_table = $('#accounts_table').DataTable({
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"ajax": "{{ url_for('accounts.get') }}",
|
||||
"columnDefs": [
|
||||
{ "searchable": false, "targets": [0,7] },
|
||||
{ "orderable": false, "targets": [0] }
|
||||
]
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
30
app/templates/accounts/view.html.j2
Normal file
30
app/templates/accounts/view.html.j2
Normal file
@@ -0,0 +1,30 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
Viewing {{ account_data.username }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content_before %}
|
||||
Viewing {{ account_data.username }}
|
||||
{% if current_user.id == account_data.id %}
|
||||
<br/>
|
||||
Hey, this is you!
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% include 'partials/_account.html.j2' %}
|
||||
{% endblock content %}
|
||||
|
||||
|
||||
{% block content_after %}
|
||||
<br/>
|
||||
<br/>
|
||||
<h3 class="text-center">Characters</h3>
|
||||
<hr class="bg-primary"/>
|
||||
<div class="card-columns">
|
||||
{% for character in account_data.charinfo %}
|
||||
{% include 'partials/_character.html.j2' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock content_after %}
|
188
app/templates/admin/dashboard.html.j2
Normal file
188
app/templates/admin/dashboard.html.j2
Normal file
@@ -0,0 +1,188 @@
|
||||
{% extends "bootstrap/base.html" %}
|
||||
{% block title %}Key Creation{% endblock %}
|
||||
|
||||
{% block navbar %}
|
||||
<nav class="navbar navbar-default">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="{{ url_for('dashboard') }}">Dashboard</a>
|
||||
</div>
|
||||
<ul class="nav navbar-nav">
|
||||
</ul>
|
||||
<ul class="nav navbar-nav" style="float: right">
|
||||
<li class="active"><a href="#">Welcome {{ current_user.username }}!</a></li>
|
||||
<li><a href="{{ url_for('logout') }}">Logout</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
{% endblock navbar %}}
|
||||
|
||||
{% block content %}
|
||||
{# LOGO #}
|
||||
<div class="container" style="margin-top: 50px">
|
||||
|
||||
{# Display logo #}
|
||||
<div style="margin-bottom: 50px">
|
||||
<img
|
||||
src="{{ url_for('static', filename=resources.LOGO) }}"
|
||||
class="center-block img-responsive mx-auto d-block"
|
||||
alt="Logo"
|
||||
width="100"
|
||||
height="100"
|
||||
>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{# Key creation #}
|
||||
<div class="container">
|
||||
<div class="text-center">
|
||||
<h3>Key Creation</h3>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-3">
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
|
||||
{# If the error value is set, display the error in red text #}
|
||||
{% if error %}
|
||||
<div class="alert alert-danger">
|
||||
{{ error }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# If the message value is set, display the message in green text #}
|
||||
{% if message %}
|
||||
<div class="alert alert-success">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Form which takes in Admin Username, Admin Password, and the amount of keys to create. #}
|
||||
<form action="{{ url_for('dashboard') }}" method="post">
|
||||
{# Key count input #}
|
||||
<div class="form-group">
|
||||
<label for="key_count">Generate keys</label>
|
||||
<input type="number" class="form-control" name="key_count" placeholder="Enter number of keys...">
|
||||
<small class="form-text text-muted">Number of keys to create.</small>
|
||||
</div>
|
||||
|
||||
{# Submit button #}
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary">Generate Keys</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{# If the keys value is set, create a list for each key in keys #}
|
||||
{% if keys %}
|
||||
<div class="alert alert-success">
|
||||
<ul>
|
||||
{% for key in keys %}
|
||||
<li>{{ key }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Activity graphs #}
|
||||
<div class="container">
|
||||
|
||||
<div class="text-center">
|
||||
<h3>Activity</h3>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-3">
|
||||
</div>
|
||||
|
||||
<div class="col-lg-6">
|
||||
|
||||
<canvas id="sessions_graph" width="400" height="400"></canvas>
|
||||
<canvas id="play_time_graph" width="400" height="400"></canvas>
|
||||
<canvas id="zone_play_time_graph" width="400" height="400"></canvas>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-lg-3">
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.5.1/dist/chart.min.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
|
||||
|
||||
<script>
|
||||
// Make a get request to the server to load the activity data
|
||||
$.get("{{ url_for('load_activities') }}", function(data) {
|
||||
|
||||
});
|
||||
|
||||
// Make a get request to the server to get the activity data for "sessions"
|
||||
$.get("{{ url_for('activity_data', name='sessions') }}", function(data) {
|
||||
// Load data as a json object
|
||||
data = JSON.parse(data);
|
||||
var ctx = document.getElementById('sessions_graph').getContext('2d');
|
||||
var myChart = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: data.labels,
|
||||
datasets: data.datasets
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Make a get request to the server to get the activity data for "play_time"
|
||||
$.get("{{ url_for('activity_data', name='play_time') }}", function(data) {
|
||||
// Load data as a json object
|
||||
data = JSON.parse(data);
|
||||
var ctx = document.getElementById('play_time_graph').getContext('2d');
|
||||
var myChart = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: data.labels,
|
||||
datasets: data.datasets
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Make a get request to the server to get the activity data for "zone_play_time"
|
||||
$.get("{{ url_for('activity_data', name='zone_play_time') }}", function(data) {
|
||||
// Load data as a json object
|
||||
data = JSON.parse(data);
|
||||
var ctx = document.getElementById('zone_play_time_graph').getContext('2d');
|
||||
var myChart = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: data.labels,
|
||||
datasets: data.datasets
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock scripts %}}
|
100
app/templates/base.html.j2
Normal file
100
app/templates/base.html.j2
Normal file
@@ -0,0 +1,100 @@
|
||||
{% import "_formhelpers.jinja2" as helper %}
|
||||
<!doctype html>
|
||||
<html lang='en'>
|
||||
|
||||
<head>
|
||||
|
||||
{# Title #}
|
||||
<title>{% block title %}{% endblock %} - {{ config.APP_NAME }}</title>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
{% block css %}
|
||||
<style>
|
||||
.required:after {
|
||||
content:" *";
|
||||
color: red;
|
||||
}
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
|
||||
{# CSS Styling #}
|
||||
{% assets "scss_all" %}
|
||||
<link rel=stylesheet type=text/css href="{{ ASSET_URL }}">
|
||||
{% endassets %}
|
||||
|
||||
<link rel='stylesheet' href="{{ url_for('static', filename='font-awesome/css/all.min.css')}}">
|
||||
|
||||
{% endblock %}
|
||||
|
||||
</head>
|
||||
<body class="bg-dark text-white">
|
||||
|
||||
|
||||
{% block header %}
|
||||
{# Header / Navigation #}
|
||||
{% include 'header.html.j2' %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{# Content #}
|
||||
|
||||
<div class="container py-0">
|
||||
|
||||
{# Text #}
|
||||
<div class="text-center">
|
||||
<span class="h3 mb-0"><br/>{% block content_before %}{% endblock %}<br/><br/></span>
|
||||
</div>
|
||||
{# Show any errors #}
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div class="alert alert-{{category}}" role="alert">
|
||||
{{message}}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
|
||||
{% block content_override %}
|
||||
<div class='container mt-4'>
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
<div class='container mt-4'>
|
||||
{% block content_after %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
{# Footer #}
|
||||
{% block footer %}
|
||||
<hr class="my-5"/>
|
||||
|
||||
{% endblock %}
|
||||
</footer>
|
||||
|
||||
|
||||
{% block js %}
|
||||
{# JavaScript #}
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='bootstrap-4.2.1/js/jquery-3.3.1.min.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='bootstrap-4.2.1/js/bootstrap.bundle.min.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='datatables/datatables.min.js') }}"></script>
|
||||
<script type="sytylesheet" src="{{ url_for('static', filename='datatables/datatables.min.css') }}"></script>
|
||||
<script>
|
||||
// set the active nav-link item
|
||||
$(function () {
|
||||
let target_nav = '#{{request.endpoint}}'.replace('\.', '-');
|
||||
$(target_nav).addClass('active');
|
||||
});
|
||||
$(function () {
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
</body>
|
||||
</html>
|
40
app/templates/bug_reports/index.html.j2
Normal file
40
app/templates/bug_reports/index.html.j2
Normal file
@@ -0,0 +1,40 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
{{ status|capitalize }} Bug Reports
|
||||
{% endblock title %}
|
||||
|
||||
{% block content_before %}
|
||||
{{ status|capitalize }} Bug Reports
|
||||
{% endblock content_before %}
|
||||
|
||||
{% block content %}
|
||||
<table class="table" id="accounts_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Actions</th>
|
||||
<th>Body</th>
|
||||
<th>Client Version</th>
|
||||
<th>Other Player</th>
|
||||
<th>Type</th>
|
||||
<th>Submitted</th>
|
||||
<th>Resolved</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block js %}
|
||||
{{ super () }}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
let accounts_table = $('#accounts_table').DataTable({
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"ajax": "{{ url_for('bug_reports.get', status=status) }}",
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
78
app/templates/bug_reports/resolve.html.j2
Normal file
78
app/templates/bug_reports/resolve.html.j2
Normal file
@@ -0,0 +1,78 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
Resolve Report {{ report.id }}
|
||||
{% endblock title %}
|
||||
|
||||
{% block content_before %}
|
||||
Resolve Report {{ report.id }}
|
||||
{% endblock content_before %}
|
||||
|
||||
{% block content %}
|
||||
<form method=post>
|
||||
{{ form.csrf_token }}
|
||||
<div class="card shadow-sm mx-auto pb-3 bg-dark border-primary" style="width: 20rem;">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Message:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ report.body }}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Client Version:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ report.client_version }}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Other Player:
|
||||
</div>
|
||||
<div class="col">
|
||||
{% set other_char = report.other_player_id|parse_other_player_id %}
|
||||
{% if other_char %}
|
||||
<a role="button" class="btn btn-primary btn btn-block"
|
||||
href='{{url_for('characters.view', id=other_char[0])}}'>
|
||||
{{other_char[1]}}
|
||||
</a>
|
||||
{% else %}
|
||||
None
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Type:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ report.selection[2:-1]|lu_translate }}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Submitted:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ report.submitted }}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
{{ helper.render_field(form.resolution) }}
|
||||
{{ helper.render_submit_field(form.submit) }}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock content %}
|
105
app/templates/bug_reports/view.html.j2
Normal file
105
app/templates/bug_reports/view.html.j2
Normal file
@@ -0,0 +1,105 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
View Report {{ report.id }}
|
||||
{% endblock title %}
|
||||
|
||||
{% block content_before %}
|
||||
View Report {{ report.id }}
|
||||
{% endblock content_before %}
|
||||
|
||||
{% block content %}
|
||||
<div class="card shadow-sm mx-auto pb-3 bg-dark border-primary" style="width: 20rem;">
|
||||
<div class="card-body">
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Message:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ report.body }}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Client Version:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ report.client_version }}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Other Player:
|
||||
</div>
|
||||
<div class="col">
|
||||
{% set other_char = report.other_player_id|parse_other_player_id %}
|
||||
{% if other_char %}
|
||||
<a role="button" class="btn btn-primary btn btn-block"
|
||||
href='{{url_for('characters.view', id=other_char[0])}}'>
|
||||
{{other_char[1]}}
|
||||
</a>
|
||||
{% else %}
|
||||
None
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Type:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ report.selection[2:-1]|lu_translate }}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Submitted:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ report.submitted }}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Resolved:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ report.resolved_time }}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Resolved By:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ resolved_by }}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Resolution:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ report.resolution }}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
52
app/templates/character/index.html.j2
Normal file
52
app/templates/character/index.html.j2
Normal file
@@ -0,0 +1,52 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
Account Management
|
||||
{% endblock title %}
|
||||
|
||||
{% block content_before %}
|
||||
Account Management
|
||||
{% endblock content_before %}
|
||||
|
||||
{% block content %}
|
||||
{% if message %}
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<h3>{{ message }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
{% endif %}
|
||||
<table class="table" id="characters_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Actions</th>
|
||||
<th>Account</th>
|
||||
<th>Name</th>
|
||||
<th>Pending Name</th>
|
||||
<th>Needs Rename</th>
|
||||
<th>Last Login</th>
|
||||
<th>Permission Map</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block js %}
|
||||
{{ super () }}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
let characters_table = $('#characters_table').DataTable({
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"ajax": "{{ url_for('characters.get', status='all') }}",
|
||||
"columnDefs": [
|
||||
{ "searchable": false, "targets": [0,5] },
|
||||
{ "orderable": false, "targets": [0] }
|
||||
]
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
34
app/templates/character/view.html.j2
Normal file
34
app/templates/character/view.html.j2
Normal file
@@ -0,0 +1,34 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
Viewing {{ character_data.name }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content_before %}
|
||||
Viewing {{ character_data.name }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-sm">
|
||||
{% with character=character_data%}
|
||||
{% include 'partials/_character.html.j2' %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
{% include 'partials/_charxml.html.j2'%}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
||||
{% block content_after %}
|
||||
<br/>
|
||||
<br/>
|
||||
<h3 class="text-center">Properties</h3>
|
||||
<hr class="bg-primary"/>
|
||||
<div class="card-columns">
|
||||
{% for property in character_data.properties_owner %}
|
||||
{% include 'partials/_property.html.j2' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock content_after %}
|
14
app/templates/flask_user/_common_base.html
Normal file
14
app/templates/flask_user/_common_base.html
Normal file
@@ -0,0 +1,14 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block content_override %}
|
||||
<div class='container mt-4'>
|
||||
<div class="card shadow rounded border-0 h-100 my-5 bg-dark">
|
||||
<div class="card-body d-flex flex-column m-2">
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block footer %}{% endblock %}
|
42
app/templates/flask_user/_macros.html
Normal file
42
app/templates/flask_user/_macros.html
Normal file
@@ -0,0 +1,42 @@
|
||||
{% macro render_field(field, label=None, label_visible=true, right_url=None, right_label=None) -%}
|
||||
<div class="form-group {% if field.errors %}has-error{% endif %} {{ kwargs.pop('class_', '') }}">
|
||||
{% if field.type != 'HiddenField' and label_visible %}
|
||||
{% if not label %}{% set label=field.label.text %}{% endif %}
|
||||
<label for="{{ field.id }}" class="control-label">{{ label|safe }}</label>
|
||||
{% endif %}
|
||||
{{ field(class_='form-control', **kwargs) }}
|
||||
{% if field.errors %}
|
||||
{% for e in field.errors %}
|
||||
<p class=" text-danger help-block">{{ e }}</p>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro render_checkbox_field(field, label=None) -%}
|
||||
{% if not label %}{% set label=field.label.text %}{% endif %}
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
{{ field(type='checkbox', **kwargs) }} {{ label }}
|
||||
</label>
|
||||
</div>
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro render_radio_field(field) -%}
|
||||
{% for value, label, checked in field.iter_choices() %}
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" name="{{ field.id }}" id="{{ field.id }}" value="{{ value }}"{% if checked %} checked{% endif %}>
|
||||
{{ label }}
|
||||
</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro render_submit_field(field, label=None, tabindex=None) -%}
|
||||
{% if not label %}{% set label=field.label.text %}{% endif %}
|
||||
{#<button type="submit" class="form-control btn btn-default btn-primary">{{label}}</button>#}
|
||||
<input type="submit" class="btn btn-default btn-primary" value="{{label}}"
|
||||
{% if tabindex %}tabindex="{{ tabindex }}"{% endif %}
|
||||
>
|
||||
{%- endmacro %}
|
70
app/templates/flask_user/login.html
Normal file
70
app/templates/flask_user/login.html
Normal file
@@ -0,0 +1,70 @@
|
||||
{% extends 'flask_user/_public_base.html' %}
|
||||
|
||||
{% block title %}
|
||||
Login
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% from "flask_user/_macros.html" import render_field, render_checkbox_field, render_submit_field %}
|
||||
<h1>{%trans%}Sign in{%endtrans%}</h1>
|
||||
|
||||
|
||||
<form action="" method="POST" class="form" role="form">
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
{# Username or Email field #}
|
||||
{% set field = form.username if user_manager.USER_ENABLE_USERNAME else form.email %}
|
||||
<div class="form-group {% if field.errors %}has-error{% endif %}">
|
||||
{# Label on left, "New here? Register." on right #}
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<label for="{{ field.id }}" class="control-label">{{ field.label.text }}</label>
|
||||
</div>
|
||||
<div class="col text-right">
|
||||
{% if user_manager.USER_ENABLE_REGISTER and not user_manager.USER_REQUIRE_INVITATION %}
|
||||
<a href="{{ url_for('user.register') }}" tabindex='190'>
|
||||
{%trans%}New here? Register.{%endtrans%}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{{ field(class_='form-control', tabindex=110) }}
|
||||
{% if field.errors %}
|
||||
{% for e in field.errors %}
|
||||
<p class="help-block text-danger">{{ e }}</p>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{# Password field #}
|
||||
{% set field = form.password %}
|
||||
<div class="form-group {% if field.errors %}has-error{% endif %}">
|
||||
{# Label on left, "Forgot your Password?" on right #}
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<label for="{{ field.id }}" class="control-label">{{ field.label.text }}</label>
|
||||
</div>
|
||||
<div class="col text-right">
|
||||
{% if user_manager.USER_ENABLE_FORGOT_PASSWORD %}
|
||||
<a href="{{ url_for('user.forgot_password') }}" tabindex='195'>
|
||||
{%trans%}Forgot your Password?{%endtrans%}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{{ field(class_='form-control', tabindex=120) }}
|
||||
{% if field.errors %}
|
||||
{% for e in field.errors %}
|
||||
<p class="help-block text-danger">{{ e }}</p>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{# Remember me #}
|
||||
{% if user_manager.USER_ENABLE_REMEMBER_ME %}
|
||||
{{ render_checkbox_field(login_form.remember_me, tabindex=130) }}
|
||||
{% endif %}
|
||||
|
||||
{# Submit button #}
|
||||
{{ render_submit_field(form.submit, tabindex=180) }}
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
71
app/templates/flask_user/login_or_register.html
Normal file
71
app/templates/flask_user/login_or_register.html
Normal file
@@ -0,0 +1,71 @@
|
||||
{% extends 'flask_user/_public_base.html' %}
|
||||
|
||||
{% block title %}
|
||||
Login or Register
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% from "flask_user/_macros.html" import render_field, render_checkbox_field, render_submit_field %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
|
||||
<h1>{%trans%}Sign in{%endtrans%}</h1>
|
||||
|
||||
|
||||
{# ** Login form ** #}
|
||||
<form action="{{ url_for('user.login') }}" method="POST" class="form" role="form">
|
||||
{{ login_form.hidden_tag() }}
|
||||
|
||||
{# Username or Email #}
|
||||
{% set field = login_form.username if user_manager.USER_ENABLE_USERNAME else login_form.email %}
|
||||
{{ render_field(field, tabindex=110) }}
|
||||
|
||||
{# Password #}
|
||||
{{ render_field(login_form.password, tabindex=120) }}
|
||||
|
||||
{# Remember me #}
|
||||
{% if user_manager.USER_ENABLE_REMEMBER_ME %}
|
||||
{{ render_checkbox_field(login_form.remember_me, tabindex=130) }}
|
||||
{% endif %}
|
||||
|
||||
{# Submit button #}
|
||||
{{ render_submit_field(login_form.submit, tabindex=180) }}
|
||||
</form>
|
||||
{% if user_manager.USER_ENABLE_FORGOT_PASSWORD %}
|
||||
<p>
|
||||
<br/>
|
||||
<a href="{{ url_for('user.forgot_password') }}" tabindex='190'>
|
||||
{%trans%}Forgot your Password?{%endtrans%}</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
|
||||
<h1>{%trans%}Register{%endtrans%}</h1>
|
||||
|
||||
{# ** Register form ** #}
|
||||
<form action="{{ url_for('user.register') }}" method="POST" novalidate formnovalidate class="form" role="form">
|
||||
{{ register_form.hidden_tag() }}
|
||||
|
||||
{# Username or Email #}
|
||||
{% set field = register_form.username if user_manager.USER_ENABLE_USERNAME else register_form.email %}
|
||||
{{ render_field(field, tabindex=210) }}
|
||||
|
||||
{% if user_manager.USER_ENABLE_EMAIL and user_manager.USER_ENABLE_USERNAME %}
|
||||
{{ render_field(register_form.email, tabindex=220) }}
|
||||
{% endif %}
|
||||
|
||||
{{ render_field(register_form.password, tabindex=230) }}
|
||||
|
||||
{% if user_manager.USER_REQUIRE_RETYPE_PASSWORD %}
|
||||
{{ render_field(register_form.retype_password, tabindex=240) }}
|
||||
{% endif %}
|
||||
|
||||
{{ render_submit_field(register_form.submit, tabindex=280) }}
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
53
app/templates/flask_user/register.html
Normal file
53
app/templates/flask_user/register.html
Normal file
@@ -0,0 +1,53 @@
|
||||
{% extends 'flask_user/_public_base.html' %}
|
||||
|
||||
{% block title %}
|
||||
Register
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% from "flask_user/_macros.html" import render_field, render_submit_field %}
|
||||
<h1>{%trans%}Register{%endtrans%}</h1>
|
||||
|
||||
<form action="" method="POST" novalidate formnovalidate class="form" role="form">
|
||||
{{ form.hidden_tag() }}
|
||||
{# Username or Email #}
|
||||
{% set field = form.username if user_manager.USER_ENABLE_USERNAME else form.email %}
|
||||
<div class="form-group {% if field.errors %}has-error{% endif %}">
|
||||
{# Label on left, "Already registered? Sign in." on right #}
|
||||
<div class="row">
|
||||
<div class="col ml-1">
|
||||
<label for="{{ field.id }}" class="control-label">{{ field.label.text }}</label>
|
||||
</div>
|
||||
<div class="col-xs-6 text-right">
|
||||
{% if user_manager.USER_ENABLE_REGISTER %}
|
||||
<a href="{{ url_for('user.login') }}" tabindex='290'>
|
||||
{%trans%}Already registered? Sign in.{%endtrans%}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{{ field(class_='form-control', tabindex=210) }}
|
||||
{% if field.errors %}
|
||||
{% for e in field.errors %}
|
||||
<p class="help-block text-danger">{{ e }}</p>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if user_manager.USER_ENABLE_EMAIL and user_manager.USER_ENABLE_USERNAME %}
|
||||
{{ render_field(form.email, tabindex=220) }}
|
||||
{% endif %}
|
||||
|
||||
{% if config.REQUIRE_PLAY_KEY %}
|
||||
{{ render_field(form.play_key_id, tabindex=225) }}
|
||||
{% endif %}
|
||||
|
||||
{{ render_field(form.password, tabindex=230) }}
|
||||
|
||||
{% if user_manager.USER_REQUIRE_RETYPE_PASSWORD %}
|
||||
{{ render_field(form.retype_password, tabindex=240) }}
|
||||
{% endif %}
|
||||
|
||||
{{ render_submit_field(form.submit, tabindex=280) }}
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
94
app/templates/header.html.j2
Normal file
94
app/templates/header.html.j2
Normal file
@@ -0,0 +1,94 @@
|
||||
{# Navigation brand, nav toggle bar #}
|
||||
<nav class='navbar navbar-expand-sm navbar-dark bg-primary flex-row pb-3'>
|
||||
<div class='container md-0 flex-nowrap'>
|
||||
|
||||
{# Logo and App Name #}
|
||||
<nav class="navbar">
|
||||
<a class="navbar-brand" href="{{ url_for('main.index') }}">
|
||||
<img src="{{ url_for('static', filename='logo/logo.png') }}" width="30" height="30" class="d-inline-block align-top" alt="">
|
||||
{{ config.APP_NAME }}
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
|
||||
{# Visible only on large devices #}
|
||||
<nav class='navbar-nav'>
|
||||
<div class='collapse navbar-collapse'>
|
||||
{% if current_user.is_authenticated %}
|
||||
{% if config.USER_ENABLE_INVITE_USER %}
|
||||
<a class='btn-nav-dashboard mr-2' href='{{ url_for('user.invite_user') }}'>Invite</a>
|
||||
{% endif %}
|
||||
<a class='btn-nav-dashboard' href='{{ url_for('user.logout') }}'><i
|
||||
class='fas fa-sign-out-alt mr-1'></i>Logout</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<button class='navbar-toggler' type='button' data-toggle='collapse' data-target='#navbarSupportedContent'
|
||||
aria-controls='navbarSupportedContent' aria-expanded='false' aria-label='Toggle navigation'>
|
||||
<span class='navbar-toggler-icon'></span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{# Navigation menu / links bar #}
|
||||
<nav class='navbar navbar-expand-sm navbar-dark bg-primary p-sm-0 py-0 {% if navbar_shadow %}shadow-sm{% endif %}'>
|
||||
<div class='container mt-0 pt-0'>
|
||||
<div class='collapse navbar-collapse' id='navbarSupportedContent' style='margin-top: -16px;'>
|
||||
<nav class='navbar-nav mr-auto'>
|
||||
<a id='main-index' class='nav-link' href='{{ url_for('main.index') }}'>Home</a>
|
||||
|
||||
{% if current_user.is_authenticated and current_user.gm_level >= 3 %}
|
||||
{# General Moderation Links #}
|
||||
<a id='accounts-index' class='nav-link' href='{{ url_for('accounts.index') }}'>Accounts</a>
|
||||
<a id='character-index' class='nav-link' href='{{ url_for('characters.index') }}'>Characters</a>
|
||||
<a id='property-index' class='nav-link' href='{{ url_for('properties.index') }}'>Properties</a>
|
||||
{% endif %}
|
||||
|
||||
{% if current_user.is_authenticated and current_user.gm_level >= 2 %}
|
||||
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">Tools</a>
|
||||
<div class="dropdown-menu">
|
||||
|
||||
<a class="dropdown-item" href='{{ url_for('mail.send') }}'>Send Mail</a>
|
||||
<hr/>
|
||||
<h6 class="text-center">Moderation</h6>
|
||||
<a class="dropdown-item" href='{{ url_for('moderation.index', status='unapproved') }}'>View Unapproved Items</a>
|
||||
<a class="dropdown-item" href='{{ url_for('moderation.index', status='approved') }}'>View Approved Items</a>
|
||||
<a class="dropdown-item" href='{{ url_for('moderation.index', status='all') }}'>View All Items</a>
|
||||
<hr/>
|
||||
<h6 class="text-center">Bug Reports</h6>
|
||||
<a class="dropdown-item" href='{{ url_for('bug_reports.index', status='unresolved') }}'>View Unresolved Reports</a>
|
||||
<a class="dropdown-item" href='{{ url_for('bug_reports.index', status='resolved') }}'>View Resolved Reports</a>
|
||||
<a class="dropdown-item" href='{{ url_for('bug_reports.index', status='all') }}'>View All Reports</a>
|
||||
{% if current_user.is_authenticated and current_user.gm_level >= 8 %}
|
||||
<hr/>
|
||||
<h6 class="text-center">Logs</h6>
|
||||
<a class="dropdown-item" href='{{ url_for('log.activity') }}'>Command Log</a>
|
||||
<a class="dropdown-item" href='{{ url_for('log.command') }}'>Activity Log</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
||||
{% if current_user.is_authenticated and current_user.gm_level == 9 and config.REQUIRE_PLAY_KEY %}
|
||||
{# Play Keys #}
|
||||
<a id='play_keys-index' class='nav-link' href='{{ url_for('play_keys.index') }}'>Play Keys</a>
|
||||
{% endif %}
|
||||
|
||||
{# About always right most #}
|
||||
<a id='main-about' class='nav-link' href='{{ url_for('main.about') }}'>About</a>
|
||||
|
||||
{# Only show logout if unauthenticated #}
|
||||
{% if current_user.is_authenticated %}
|
||||
<a class='nav-link d-sm-none' href='{{ url_for('user.logout') }}'><i
|
||||
class='fas fa-sign-out-alt mr-1'></i>Logout</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
1190
app/templates/ldd/ldd.html.j2
Normal file
1190
app/templates/ldd/ldd.html.j2
Normal file
File diff suppressed because it is too large
Load Diff
45
app/templates/logs/activity.html.j2
Normal file
45
app/templates/logs/activity.html.j2
Normal file
@@ -0,0 +1,45 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
Activity Log
|
||||
{% endblock title %}
|
||||
|
||||
{% block content_before %}
|
||||
Activity Log
|
||||
{% endblock content_before %}
|
||||
|
||||
{% block content %}
|
||||
{% if message %}
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<h3>{{ message }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
{% endif %}
|
||||
<table class="table" id="command_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Account:Character</th>
|
||||
<th>Command</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block js %}
|
||||
{{ super () }}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
let command_table = $('#command_table').DataTable({
|
||||
"order": [[0, "desc"]],
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"ajax": "{{ url_for('log.get_commands') }}",
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
47
app/templates/logs/command.html.j2
Normal file
47
app/templates/logs/command.html.j2
Normal file
@@ -0,0 +1,47 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
Command Log
|
||||
{% endblock title %}
|
||||
|
||||
{% block content_before %}
|
||||
Command Log
|
||||
{% endblock content_before %}
|
||||
|
||||
{% block content %}
|
||||
{% if message %}
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<h3>{{ message }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
{% endif %}
|
||||
<table class="table" id="activity_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Account:Character</th>
|
||||
<th>Activity</th>
|
||||
<th>Time</th>
|
||||
<th>Map</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block js %}
|
||||
{{ super () }}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
let activity_table = $('#activity_table').DataTable({
|
||||
"order": [[0, "desc"]],
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"ajax": "{{ url_for('log.get_activities') }}",
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
46
app/templates/mail/send.html.j2
Normal file
46
app/templates/mail/send.html.j2
Normal file
@@ -0,0 +1,46 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
Send Mail
|
||||
{% endblock title %}
|
||||
|
||||
{% block content_before %}
|
||||
Send Mail
|
||||
{% endblock content_before %}
|
||||
|
||||
{% block content %}
|
||||
<form method=post>
|
||||
{{ form.csrf_token }}
|
||||
<div class="card shadow-sm mx-auto pb-3 bg-dark border-primary" style="width: 20rem;">
|
||||
<div class="card-body">
|
||||
{{ helper.render_field(form.recipient) }}
|
||||
{{ helper.render_field(form.subject) }}
|
||||
{{ helper.render_field(form.body) }}
|
||||
{{ helper.render_field(form.attachment) }}
|
||||
{{ helper.render_field(form.attachment_count) }}
|
||||
{{ helper.render_submit_field(form.submit) }}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock content %}
|
||||
|
||||
{% block js %}
|
||||
{{ super() }}
|
||||
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.10/css/select2.min.css" rel="stylesheet" />
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.10/js/select2.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#recipient').select2({ // init Select2 on form's name field
|
||||
placeholder: "{{ form.recipient.label.text }}",
|
||||
allowClear: true,
|
||||
});
|
||||
});
|
||||
$(document).ready(function() {
|
||||
$('#attachment').select2({ // init Select2 on form's name field
|
||||
placeholder: "{{ form.attachment.label.text }}",
|
||||
allowClear: true,
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock js %}
|
73
app/templates/main/about.html.j2
Normal file
73
app/templates/main/about.html.j2
Normal file
@@ -0,0 +1,73 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}About{% endblock %}
|
||||
|
||||
{% block content_before %}
|
||||
About {{ config.APP_NAME }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class='card mx-auto mt-5 shadow-sm bg-dark border-primary'>
|
||||
<div class="card-body">
|
||||
<h4 class="text-center">Contributors</h4>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Developer:
|
||||
</div>
|
||||
<div class="col">
|
||||
Aronwk (Aaron Kimbrell)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Developer:
|
||||
</div>
|
||||
<div class="col">
|
||||
Wincent
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Logo Designer:
|
||||
</div>
|
||||
<div class="col">
|
||||
BlasterBuilder
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
LDD/LXFML Rendering:
|
||||
</div>
|
||||
<div class="col">
|
||||
m2m/sttng
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
TODO: add more Contributors
|
||||
</div>
|
||||
<div class="col">
|
||||
Add more
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Source
|
||||
</div>
|
||||
<div class="col">
|
||||
<a href="https://github.com/DarkflameUniverse/AccountManager">
|
||||
Github
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
82
app/templates/main/account_creation.html.j2
Normal file
82
app/templates/main/account_creation.html.j2
Normal file
@@ -0,0 +1,82 @@
|
||||
{% extends "base.html.j2" %}
|
||||
{% block title %}Account Creation{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container" style="margin-top: 50px">
|
||||
|
||||
{# Display DLU.png #}
|
||||
<div style="margin-bottom: 50px">
|
||||
<img
|
||||
src="{{ url_for('static', filename=logo/logo.png) }}"
|
||||
class="center-block img-responsive mx-auto d-block"
|
||||
alt="DLU Logo"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-3">
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
|
||||
{# If the error value is set, display the error in red text #}
|
||||
{% if error %}
|
||||
<div class="alert alert-danger">
|
||||
{{ error }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# If the message value is set, display the message in green text #}
|
||||
{% if message %}
|
||||
<div class="alert alert-success">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Form which takes in Play Key, Account Name, and Account Password #}
|
||||
<form action="{{ url_for('account_creation') }}" method="post">
|
||||
{# Play Key input #}
|
||||
<div class="form-group">
|
||||
<label for="play_key">Play Key</label>
|
||||
<input type="text" class="form-control" name="play_key" aria-describedby="emailHelp" placeholder="AAAA-BBBB-CCCC-DDDD" value="{{ key }}">
|
||||
<small class="form-text text-muted">In the format: AAAA-BBBB-CCCC-DDDD</small>
|
||||
</div>
|
||||
|
||||
{# Account Name input #}
|
||||
<div class="form-group">
|
||||
<label for="account_name">Username</label>
|
||||
<input type="text" class="form-control" name="account_name" placeholder="Enter username...">
|
||||
<small class="form-text text-muted">Limited to a-z, A-Z, and 0-9. No spaces or special characters. Max 32 characters.</small>
|
||||
</div>
|
||||
|
||||
{# Account Password input #}
|
||||
<div class="form-group">
|
||||
<label for="account_password">Password</label>
|
||||
<input type="password" class="form-control" name="account_password" placeholder="Enter password...">
|
||||
<small class="form-text text-muted"></small>
|
||||
</div>
|
||||
|
||||
{# Account Repeat Password input #}
|
||||
<div class="form-group">
|
||||
<label for="account_repeat_password">Repeat Password</label>
|
||||
<input type="password" class="form-control" name="account_repeat_password" placeholder="Repeat password...">
|
||||
<small class="form-text text-muted"></small>
|
||||
</div>
|
||||
|
||||
{# Agree to the Privacy Policy and Terms of Service #}
|
||||
<div class="form-group">
|
||||
<label class="checkbox-inline">
|
||||
<input type="checkbox" name="agree">
|
||||
I agree to the <a href="{{ url_for('static', filename=resources.PRIVACY_POLICY) }}" target="_blank">Privacy Policy</a> and <a href="{{ url_for('static', filename=resources.TERMS_OF_USE) }}" target="_blank">Terms of Service</a>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{# Submit button #}
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary">Create Account</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
53
app/templates/main/data_download.html.j2
Normal file
53
app/templates/main/data_download.html.j2
Normal file
@@ -0,0 +1,53 @@
|
||||
{% extends "bootstrap/base.html" %}
|
||||
{% block title %}Data Download{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container" style="margin-top: 50px">
|
||||
|
||||
{# Display logo #}
|
||||
<div style="margin-bottom: 50px">
|
||||
<img
|
||||
src="{{ url_for('static', filename=resources.LOGO) }}"
|
||||
class="center-block img-responsive mx-auto d-block"
|
||||
alt="DLU Logo"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-3">
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
|
||||
{# If the error value is set, display the error in red text #}
|
||||
{% if error %}
|
||||
<div class="alert alert-danger">
|
||||
{{ error }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# If the message value is set, display the message in green text #}
|
||||
{% if message %}
|
||||
<div class="alert alert-success">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Form which takes in Character Name #}
|
||||
<form action="{{ url_for('data_download') }}" method="post">
|
||||
{# Account Name input #}
|
||||
<div class="form-group">
|
||||
<label for="character_name">Character Name</label>
|
||||
<input type="text" class="form-control" name="character_name" placeholder="Enter username...">
|
||||
<small class="form-text text-muted">Full character name.</small>
|
||||
</div>
|
||||
|
||||
{# Submit button #}
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary">Download</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
49
app/templates/main/index.html.j2
Normal file
49
app/templates/main/index.html.j2
Normal file
@@ -0,0 +1,49 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}Home{% endblock %}
|
||||
|
||||
{% block content_before %}
|
||||
{% if current_user.is_authenticated %}
|
||||
Welcome back {{ current_user.username }}!
|
||||
{% else %}
|
||||
Welcome Explorer!
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if current_user.is_authenticated %}
|
||||
{% include 'partials/_account.html.j2' %}
|
||||
{% else %}
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<a role="button" class="btn btn-primary btn-lg btn-block"
|
||||
href='{{ url_for('user.login') }}'>
|
||||
Login
|
||||
</a>
|
||||
</div>
|
||||
{% if config.USER_ENABLE_REGISTER %}
|
||||
<div class="col">
|
||||
<a role="button" class="btn btn-primary btn-lg btn-block"
|
||||
href='{{ url_for('user.register') }}'>
|
||||
Register
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
|
||||
{% block content_after %}
|
||||
{% if current_user.is_authenticated %}
|
||||
<br/>
|
||||
<br/>
|
||||
<h3 class="text-center">Characters</h3>
|
||||
<hr class="bg-primary"/>
|
||||
<div class="card-columns">
|
||||
{% for character in account_data.charinfo %}
|
||||
{% include 'partials/_character.html.j2' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock content_after %}
|
||||
|
92
app/templates/moderation/index.html.j2
Normal file
92
app/templates/moderation/index.html.j2
Normal file
@@ -0,0 +1,92 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
Moderation of {{ status|capitalize }} Items
|
||||
{% endblock title %}
|
||||
|
||||
{% block content_before %}
|
||||
Moderation of {{ status|capitalize }} Items
|
||||
{% endblock content_before %}
|
||||
|
||||
{% block content %}
|
||||
<h4> Characters </h4>
|
||||
<hr class="bg-primary"/>
|
||||
<table class="table" id="character_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Actions</th>
|
||||
<th>Account</th>
|
||||
<th>Name</th>
|
||||
<th>Pending Name</th>
|
||||
<th>Needs Rename</th>
|
||||
<th>Last Login</th>
|
||||
<th>Permission Map</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
<br/>
|
||||
<h4> Pets </h4>
|
||||
<hr class="bg-primary"/>
|
||||
<table class="table" id="pet_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Actions</th>
|
||||
<th>Name</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
<br/>
|
||||
<h4> Properties </h4>
|
||||
<hr class="bg-primary"/>
|
||||
<table class="table" id="property_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Actions</th>
|
||||
<th>Owner</th>
|
||||
<th>Template ID</th>
|
||||
<th>Clone ID</th>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>Privacy</th>
|
||||
<th>Approved</th>
|
||||
<th>Updated</th>
|
||||
<th>Claimed</th>
|
||||
<th>Rejection Reason</th>
|
||||
<th>Reputation</th>
|
||||
<th>Location</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
{{ super () }}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
let character_table = $('#character_table').DataTable({
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"ajax": "{{ url_for('characters.get', status=status) }}",
|
||||
});
|
||||
});
|
||||
|
||||
$(document).ready(function(){
|
||||
let pet_table = $('#pet_table').DataTable({
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"ajax": "{{ url_for('moderation.get_pets', status=status) }}",
|
||||
});
|
||||
});
|
||||
$(document).ready(function(){
|
||||
let property_table = $('#property_table').DataTable({
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"ajax": "{{ url_for('properties.get', status=status) }}",
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
196
app/templates/partials/_account.html.j2
Normal file
196
app/templates/partials/_account.html.j2
Normal file
@@ -0,0 +1,196 @@
|
||||
<div class="card shadow-sm bg-dark border-primary">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<h4>Account Info</h4>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Username:
|
||||
</div>
|
||||
<br/>
|
||||
<div class="col">
|
||||
{{ account_data.username}}
|
||||
</div>
|
||||
</div>
|
||||
{% if config.USER_ENABLE_EMAIL %}
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
E-mail:
|
||||
</div>
|
||||
<br/>
|
||||
<div class="col">
|
||||
{{ account_data.email }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Role:
|
||||
</div>
|
||||
<div class="col">
|
||||
{% with gm_level=account_data.gm_level %}
|
||||
{% include 'partials/_gm_level.html.j2' %}
|
||||
{% endwith %}
|
||||
{% if current_user.id != account_data.id %}
|
||||
{% if current_user.gm_level >= 8 and not(current_user.gm_level == 8 and account_data.gm_level == 8)%}
|
||||
<a role="button" class="btn btn-primary"
|
||||
href='{{ url_for('accounts.edit_gm_level', id=account_data.id) }}'>
|
||||
Edit
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Account Lock Status:
|
||||
</div>
|
||||
<br/>
|
||||
<div class="col">
|
||||
{% if account_data.locked %}
|
||||
<h5 class="far fa-times-circle text-danger"></h5> Locked
|
||||
{% else %}
|
||||
<h5 class="far fa-check-square text-success"></h5> Not Locked
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Ban Status:
|
||||
</div>
|
||||
<div class="col">
|
||||
{% if account_data.banned %}
|
||||
<h5 class="far fa-times-circle text-danger"></h5> Banned
|
||||
{% else %}
|
||||
<h5 class="far fa-check-square text-success"></h5> Not Banned
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Mute Status:
|
||||
</div>
|
||||
<div class="col">
|
||||
{% if account_data.mute_expire != 0 %}
|
||||
<h5 class="far fa-times-circle text-danger"></h5> Muted Until: <br/>
|
||||
{{ account_data.mute_expire|ctime }}
|
||||
{% else %}
|
||||
<h5 class="far fa-check-square text-success"></h5> Not Muted
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
{% if current_user.id == account_data.id %}
|
||||
<div class="row">
|
||||
{% if config.USER_ENABLE_CHANGE_PASSWORD %}
|
||||
<div class="col">
|
||||
<a role="button" class="btn btn-primary btn btn-block"
|
||||
href='{{ url_for('user.change_password') }}'>
|
||||
Change Password
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if config.USER_ENABLE_CHANGE_USERNAME%}
|
||||
<div class="col">
|
||||
<a role="button" class="btn btn-primary btn btn-block"
|
||||
href='{{ url_for('user.change_username') }}'>
|
||||
Change Username
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if account_data.play_key and current_user.gm_level > 3 and config.REQUIRE_PLAY_KEY %}
|
||||
<hr class="bg-primary"/>
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<h4>Key Info</h4>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Play Key:
|
||||
</div>
|
||||
<br/>
|
||||
<div class="col">
|
||||
{{ account_data.play_key.key_string }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Uses Left:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ account_data.play_key.key_uses }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Active:
|
||||
</div>
|
||||
<div class="col">
|
||||
{% if account_data.active %}
|
||||
<h5 class="far fa-check-square text-success"></h5>
|
||||
{% else %}
|
||||
<h5 class="far fa-times-circle text-danger"></h5>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if current_user.id != account_data.id and current_user.gm_level > 3 %}
|
||||
<hr class="bg-primary"/>
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<h4>Actions</h4>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<a role="button" class="btn btn-primary btn-block"
|
||||
href='{{ url_for('accounts.lock', id=account_data.id) }}'>
|
||||
{% if account_data.locked %}
|
||||
Unlock
|
||||
{% else %}
|
||||
Lock
|
||||
{% endif %}
|
||||
</a>
|
||||
<a role="button" class="btn btn-primary btn-block"
|
||||
href='{{ url_for('accounts.ban', id=account_data.id) }}'>
|
||||
{% if account_data.banned %}
|
||||
Unban
|
||||
{% else %}
|
||||
Ban
|
||||
{% endif %}
|
||||
</a>
|
||||
<br/>
|
||||
{% if account_data.mute_expire %}
|
||||
<a role="button" class="btn btn-primary btn-block"
|
||||
href='{{ url_for('accounts.mute', id=account_data.id, days=0) }}'>
|
||||
Unmute
|
||||
</a>
|
||||
{% else %}
|
||||
<a role="button" class="btn btn-primary btn-block"
|
||||
href='{{ url_for('accounts.mute', id=account_data.id, days=1) }}'>
|
||||
Mute for 1 days
|
||||
</a>
|
||||
<a role="button" class="btn btn-primary btn-block"
|
||||
href='{{ url_for('accounts.mute', id=account_data.id, days=7) }}'>
|
||||
Mute for 7 days
|
||||
</a>
|
||||
<a role="button" class="btn btn-primary btn-block"
|
||||
href='{{ url_for('accounts.mute', id=account_data.id, days=31) }}'>
|
||||
Mute for 1 month
|
||||
</a>
|
||||
<a role="button" class="btn btn-primary btn-block"
|
||||
href='{{ url_for('accounts.mute', id=account_data.id, days=365) }}'>
|
||||
Mute for 1 year
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
101
app/templates/partials/_character.html.j2
Normal file
101
app/templates/partials/_character.html.j2
Normal file
@@ -0,0 +1,101 @@
|
||||
<div class="card shadow-sm bg-dark border-primary">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<h4>
|
||||
{{ character.name }}
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
{% if character.pending_name %}
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Pending:
|
||||
</div>
|
||||
<br/>
|
||||
<div class="col">
|
||||
{{ character.pending_name }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Rename:
|
||||
</div>
|
||||
<br/>
|
||||
<div class="col">
|
||||
{% if character.needs_rename %}
|
||||
<h5 class="far fa-check-square text-danger"></h5>
|
||||
{% else %}
|
||||
<h5 class="far fa-times-circle text-success"></h5>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Last Login:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ character.last_login|ctime }}
|
||||
</div>
|
||||
</div>
|
||||
{% if request.endpoint != "characters.view" %}
|
||||
<br/>
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<a role="button" class="btn btn-primary btn-block"
|
||||
href='{{ url_for('characters.view', id=character.id) }}'>
|
||||
View Character
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<br/>
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<a role="button" class="btn btn-primary btn-block"
|
||||
href='{{ url_for('accounts.view', id=character.account_id) }}'>
|
||||
View Account: {{character.account.username}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if current_user.id != character.account_id and current_user.gm_level > 2 %}
|
||||
<hr class="bg-primary"/>
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<h4>Actions</h4>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
{% if not character.needs_rename %}
|
||||
<a role="button" class="btn btn-danger btn btn-block"
|
||||
href='{{url_for('characters.approve_name', id=character.id, action="rename")}}'>
|
||||
Needs Rename
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if character.pending_name or character.needs_rename %}
|
||||
<a role="button" class="btn btn-success btn btn-block"
|
||||
href='{{url_for('characters.approve_name', id=character.id, action="approve")}}'>
|
||||
Approve Name
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<a role="button" class="btn btn-primary btn-block"
|
||||
href='{{ url_for('characters.restrict', id=character.id, bit=4) }}'>
|
||||
{% if character.permission_map|check_perm_map(4) %}Unrestrict{% else %}Restrict{% endif %} Trade
|
||||
</a>
|
||||
<a role="button" class="btn btn-primary btn-block"
|
||||
href='{{ url_for('characters.restrict', id=character.id, bit=5) }}'>
|
||||
{% if character.permission_map|check_perm_map(5) %}Unrestrict{% else %}Restrict{% endif %} Mail
|
||||
</a>
|
||||
<a role="button" class="btn btn-primary btn-block"
|
||||
href='{{ url_for('characters.restrict', id=character.id, bit=6) }}'>
|
||||
{% if character.permission_map|check_perm_map(6) %}Unrestrict{% else %}Restrict{% endif %} Chat
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
221
app/templates/partials/_charxml.html.j2
Normal file
221
app/templates/partials/_charxml.html.j2
Normal file
@@ -0,0 +1,221 @@
|
||||
<div class="card shadow-sm bg-dark border-primary">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<h4>
|
||||
Chatacter Data
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
U-Score: {{ character_json.obj.char.attr_ls }}
|
||||
</div>
|
||||
<div class="col">
|
||||
Level: {{ character_json.obj.lvl.attr_l }}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
{% set parsed_lzid = character_json.obj.char.attr_lzid|parse_lzid %}
|
||||
Zone: {{ parsed_lzid[0]|get_zone_name }}<br>
|
||||
Zone Instance: {{ parsed_lzid[1] }}<br>
|
||||
Zone Clone: {{ parsed_lzid[2] }}<br>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
<img src="{{url_for('luclient.get_icon_iconid', id=4273)}}"
|
||||
alt="Coins: "
|
||||
width="32"
|
||||
height="32">
|
||||
{{ character_json.obj.char.attr_cc }}
|
||||
</div>
|
||||
<div class="col text-center">
|
||||
<img src="{{url_for('luclient.get_icon_iconid', id=3262)}}"
|
||||
alt="Health: "
|
||||
width="32"
|
||||
height="32">
|
||||
{{ character_json.obj.dest.attr_hc }}/{{ character_json.obj.dest.attr_hm }}
|
||||
</div>
|
||||
<div class="col text-center">
|
||||
<img src="{{url_for('luclient.get_icon_iconid', id=3263)}}"
|
||||
alt="Armor: "
|
||||
width="32"
|
||||
height="32">
|
||||
{{ character_json.obj.dest.attr_ac }}/{{ character_json.obj.dest.attr_am }}
|
||||
</div>
|
||||
<div class="col">
|
||||
<img src="{{url_for('luclient.get_icon_iconid', id=1032)}}"
|
||||
alt="Imagination: "
|
||||
width="32"
|
||||
height="32">
|
||||
{{ character_json.obj.dest.attr_ic }}/{{ character_json.obj.dest.attr_im }}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Play time:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ (character_json.obj.char.attr_time|int/60/60/24)|int }} Days
|
||||
{{ (character_json.obj.char.attr_time|int/60/60)|int - ((character_json.obj.char.attr_time|int/60/60/24)|int) * 24}} Hours
|
||||
{{ (character_json.obj.char.attr_time|int/60 - (character_json.obj.char.attr_time|int/60/60)|int*60)|int }} Minutes
|
||||
</div>
|
||||
</div>
|
||||
<hr class="bg-primary"/>
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#generalStatisticsModal">
|
||||
General Stats
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#zoneStatisticsModal">
|
||||
Zone Stats
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#inventoryModal">
|
||||
Inventory
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Inventory Modal #}
|
||||
<div class="modal fade" id="inventoryModal" tabindex="-1" role="dialog" aria-labelledby="inventoryModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content bg-dark">
|
||||
<div class="modal-header">
|
||||
<div class="modal-title" id="inventoryModalLabel">
|
||||
Inventories
|
||||
</div>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<nav>
|
||||
<div class="nav nav-tabs" id="inv-tab" role="tablist">
|
||||
<a class="nav-item nav-link active" id="nav-items-tab" data-toggle="tab" href="#nav-items" role="tab" aria-controls="nav-items" aria-selected="true">Items</a>
|
||||
<a class="nav-item nav-link" id="nav-vault-tab" data-toggle="tab" href="#nav-vault" role="tab" aria-controls="nav-vault" aria-selected="false">Vault Items</a>
|
||||
<a class="nav-item nav-link" id="nav-bricks-tab" data-toggle="tab" href="#nav-bricks" role="tab" aria-controls="nav-bricks" aria-selected="false">Bricks</a>
|
||||
<a class="nav-item nav-link" id="nav-models-tab" data-toggle="tab" href="#nav-models" role="tab" aria-controls="nav-models" aria-selected="false">Models</a>
|
||||
<a class="nav-item nav-link" id="nav-vault-models-tab" data-toggle="tab" href="#nav-vault-models" role="tab" aria-controls="nav-vault-models" aria-selected="false">Vault Models</a>
|
||||
<a class="nav-item nav-link" id="nav-behaviors-tab" data-toggle="tab" href="#nav-behaviors" role="tab" aria-controls="nav-behaviors" aria-selected="false">Behaviors</a>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="tab-content mt-3" id="nav-invContent">
|
||||
<div class="tab-pane fade show active" id="nav-items" role="tabpanel" aria-labelledby="nav-items-tab">
|
||||
{# Inv ID 0 - Index: 0 #}
|
||||
{% for item in character_json.obj.inv.holdings.in %}
|
||||
{% if item.attr_t == "0" %}
|
||||
{% for inv_item in item.i %}
|
||||
{% include 'partials/charxml/_inv_grid.html.j2' %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="tab-pane fade" id="nav-vault" role="tabpanel" aria-labelledby="nav-vault-tab">
|
||||
{# Inv ID 1 - Index: 1 #}
|
||||
{% for item in character_json.obj.inv.holdings.in %}
|
||||
{% if item.attr_t == "1" %}
|
||||
{% for inv_item in item.i %}
|
||||
{% include 'partials/charxml/_inv_grid.html.j2' %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="tab-pane fade" id="nav-vault-models" role="tabpanel" aria-labelledby="nav-vault-models-tab">
|
||||
{# Inv ID 14 - Index: 10 #}
|
||||
{% for item in character_json.obj.inv.holdings.in %}
|
||||
{% if item.attr_t == "14" %}
|
||||
{% for inv_item in item.i %}
|
||||
{% include 'partials/charxml/_inv_grid.html.j2' %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="tab-pane fade" id="nav-bricks" role="tabpanel" aria-labelledby="nav-bricks-tab">
|
||||
{# Inv ID 2 - Index: 2 #}
|
||||
{% for item in character_json.obj.inv.holdings.in %}
|
||||
{% if item.attr_t == "2" %}
|
||||
{% for inv_item in item.i %}
|
||||
{% include 'partials/charxml/_inv_grid.html.j2' %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="tab-pane fade" id="nav-models" role="tabpanel" aria-labelledby="nav-models-tab">
|
||||
{# Inv ID 5 - Index: 6 #}
|
||||
{% for item in character_json.obj.inv.holdings.in %}
|
||||
{% if item.attr_t == "5" %}
|
||||
{% for inv_item in item.i %}
|
||||
{% include 'partials/charxml/_inv_grid.html.j2' %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="tab-pane fade" id="nav-behaviors" role="tabpanel" aria-labelledby="nav-behaviors-tab">
|
||||
{# Inv ID 7 - Index: 8 #}
|
||||
{% for item in character_json.obj.inv.holdings.in %}
|
||||
{% if item.attr_t == "7" %}
|
||||
{% for inv_item in item.i %}
|
||||
{% include 'partials/charxml/_inv_grid.html.j2' %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{# Zone Statistics Modal #}
|
||||
<div class="modal fade" id="zoneStatisticsModal" tabindex="-1" role="dialog" aria-labelledby="zoneStatisticsModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content bg-dark">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="zoneStatisticsModalLabel">Zone Statistics</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
{% for zone in character_json.obj.char.zs.s %}
|
||||
{% include 'partials/charxml/_zone_stats.html.j2' %}
|
||||
{{ '<hr class="bg-primary"/>' if not loop.last else "" }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{# General Statistics Modal #}
|
||||
<div class="modal fade" id="generalStatisticsModal" tabindex="-1" role="dialog" aria-labelledby="generalStatisticsModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content bg-dark">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="generalStatisticsModalLabel">Statistics</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
{% include 'partials/charxml/_char_stats.html.j2' %}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
35
app/templates/partials/_gm_level.html.j2
Normal file
35
app/templates/partials/_gm_level.html.j2
Normal file
@@ -0,0 +1,35 @@
|
||||
{#
|
||||
GAME_MASTER_LEVEL_CIVILIAN = 0, // Normal player.
|
||||
GAME_MASTER_LEVEL_FORUM_MODERATOR = 1, // No permissions on live servers.
|
||||
GAME_MASTER_LEVEL_JUNIOR_MODERATOR = 2, // Can kick/mute and pull chat logs.
|
||||
GAME_MASTER_LEVEL_MODERATOR = 3, // Can return lost items.
|
||||
GAME_MASTER_LEVEL_SENIOR_MODERATOR = 4, // Can ban.
|
||||
GAME_MASTER_LEVEL_LEAD_MODERATOR = 5, // Can approve properties.
|
||||
GAME_MASTER_LEVEL_JUNIOR_DEVELOPER = 6, // Junior developer & future content team. Civilan on live.
|
||||
GAME_MASTER_LEVEL_INACTIVE_DEVELOPER = 7, // Inactive developer, limited permissions.
|
||||
GAME_MASTER_LEVEL_DEVELOPER = 8, // Active developer, full permissions on live.
|
||||
GAME_MASTER_LEVEL_OPERATOR = 9
|
||||
#}
|
||||
|
||||
{% if gm_level==0 %}
|
||||
Player
|
||||
{% elif gm_level==1 %}
|
||||
Key Distrubuter
|
||||
{% elif gm_level==2 %}
|
||||
Junior Moderator
|
||||
{% elif gm_level==3 %}
|
||||
Moderator
|
||||
{% elif gm_level==4 %}
|
||||
Senior Moderator
|
||||
{% elif gm_level==5 %}
|
||||
Lead Moderator
|
||||
{% elif gm_level==5 %}
|
||||
Junior Developer
|
||||
{% elif gm_level==7 %}
|
||||
Inactive Developer
|
||||
{% elif gm_level==8 %}
|
||||
Developer
|
||||
{% else %}
|
||||
Operator
|
||||
{% endif %}
|
||||
(GM Level: {{ gm_level }})
|
0
app/templates/partials/_mail.html.j2
Normal file
0
app/templates/partials/_mail.html.j2
Normal file
101
app/templates/partials/_property.html.j2
Normal file
101
app/templates/partials/_property.html.j2
Normal file
@@ -0,0 +1,101 @@
|
||||
<div class="card shadow-sm bg-dark border-primary">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<h4>
|
||||
{% if property.name %}
|
||||
{{ property.name }}
|
||||
{% else %}
|
||||
{{ property.zone_id|get_zone_name }}
|
||||
{% endif %}
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
{{ property.description }}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Approved:
|
||||
</div>
|
||||
<br/>
|
||||
<div class="col">
|
||||
{% if property.mod_approved %}
|
||||
<h5 class="far fa-check-square text-success"></h5>
|
||||
{% else %}
|
||||
<h5 class="far fa-times-circle text-danger"></h5>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{# Never get's updated currenlty #}
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Updated:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ property.last_updated|ctime }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Claimed:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ property.time_claimed|ctime }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Visibility:
|
||||
</div>
|
||||
<div class="col">
|
||||
{% if property.privacy_option == 0 %}
|
||||
Private
|
||||
{% elif property.privacy_option == 1 %}
|
||||
Best Friends
|
||||
{% else %}
|
||||
Public
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Reputation:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ property.reputation }}
|
||||
</div>
|
||||
</div>
|
||||
{% if request.endpoint != "properties.view" %}
|
||||
<br/>
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<a role="button" class="btn btn-primary btn-block"
|
||||
href='{{ url_for('properties.view', id=property.id) }}'>
|
||||
View Property
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<br/>
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<a role="button" class="btn btn-primary btn-block"
|
||||
href='{{ url_for('properties.view_models', id=property.id) }}'>
|
||||
Render Property
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if current_user.gm_level > 2 %}
|
||||
<br/>
|
||||
<a role="button" class="btn btn-{% if property.mod_approved %}danger{% else %}success{% endif %} btn-block"
|
||||
href='{{url_for('properties.approve', id=property.id)}}'>
|
||||
{% if property.mod_approved %} Unapprove {% else %} Approve {% endif %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
71
app/templates/partials/_property_content.html.j2
Normal file
71
app/templates/partials/_property_content.html.j2
Normal file
@@ -0,0 +1,71 @@
|
||||
<div class="card shadow-sm bg-dark border-primary">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<h4>
|
||||
{% if not item.ugc_id %}
|
||||
{{ item.lot|get_lot_name }}
|
||||
{% else %}
|
||||
UGC: {{ item.ugc.filename.split('.')[0] }}
|
||||
{% endif %}
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
{% if item.lot == 14 %}
|
||||
{# Do nothing for now#}
|
||||
{% else %}
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<img src="{{url_for('luclient.get_icon_lot', id=item.lot)}}" alt="{{ item.lot|get_lot_name }}" width="64" height="64">
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
LOT:
|
||||
</div>
|
||||
<br/>
|
||||
<div class="col">
|
||||
{{ item.lot }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Description:
|
||||
</div>
|
||||
<br/>
|
||||
<div class="col">
|
||||
{{ item.lot|get_lot_desc }}
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<a role="button" class="btn btn-primary btn-block"
|
||||
href='{{ url_for('properties.get_model', id=item.id, file_format="lxfml") }}'>
|
||||
View Model XML
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<a role="button" class="btn btn-primary btn-block"
|
||||
href='{{ url_for('properties.view_model', id=item.id) }}'>
|
||||
Render Model
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<a role="button" class="btn btn-primary btn-block"
|
||||
href='{{ url_for('properties.download_model', id=item.id) }}'>
|
||||
Download Model
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
242
app/templates/partials/charxml/_char_stats.html.j2
Normal file
242
app/templates/partials/charxml/_char_stats.html.j2
Normal file
@@ -0,0 +1,242 @@
|
||||
{% set stats = character_json.obj.char.attr_stt.split(';') %}
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Currency Collected:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[0] }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Bricks Collected:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[1] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Smashables Smashed:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[2] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Quick Builds Completed:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[3] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Enemies Smashed:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[4] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Rockets Used:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[5] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Missions Completed:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[6] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Pets Tamed:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[7] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Imagination Power Ups Collected:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[8] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Life Power Ups Collected:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[9] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Armor Power Ups Collected:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[10] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Meters Traveled:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[11] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Times Smashed:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[12] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Total Damage Taken:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[13] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Total Damage Healed:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[14] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Total Armor Repaired:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[15] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Total Imagination Restored:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[16] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Total Imagination Used:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[17] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Distance Driven:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[18] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Time Airborne in Car:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[19] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Racing Imagination Power Ups Collected:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[20] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Racing Imagination Crates Smashed:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[21] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Racing Car Boosts Activated:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[22] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Racing Times Wrecked:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[23] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Racing Smashables Smashed:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[24] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Races Finished:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[25] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
First Place Race Finishes:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ stats[26] }}
|
||||
</div>
|
||||
</div>
|
24
app/templates/partials/charxml/_inv_grid.html.j2
Normal file
24
app/templates/partials/charxml/_inv_grid.html.j2
Normal file
@@ -0,0 +1,24 @@
|
||||
<div class="inventory-item">
|
||||
<img
|
||||
src="{{url_for('luclient.get_icon_lot', id=inv_item.attr_l)}}"
|
||||
alt="{{ inv_item.attr_l|get_lot_name }}"
|
||||
class="border p-1 border-primary rounded m-1"
|
||||
width="60"
|
||||
{% if inv_item.attr_eq == "true" %}style="background-color:#d16f05;"{% endif %}
|
||||
height="60"
|
||||
data-html="true"
|
||||
data-toggle="tooltip"
|
||||
data-placement="left"
|
||||
title="{% include 'partials/charxml/_item_tooltip.html.j2' %}"
|
||||
>
|
||||
{% if inv_item.attr_c != "1" %}
|
||||
<span class="inventory-count text-bold">
|
||||
{{ inv_item.attr_c }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if inv_item.attr_b == "true" %}
|
||||
<span class="inventory-lock">
|
||||
<i class='fas fa-lock'></i>
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
67
app/templates/partials/charxml/_item_tooltip.html.j2
Normal file
67
app/templates/partials/charxml/_item_tooltip.html.j2
Normal file
@@ -0,0 +1,67 @@
|
||||
{% set base_stat = inv_item.attr_l|get_lot_stats %}
|
||||
{% set desc = inv_item.attr_l|get_lot_desc %}
|
||||
{% set item_set = inv_item.attr_l|get_item_set %}
|
||||
|
||||
{{ inv_item.attr_l|get_lot_name }}
|
||||
|
||||
{% if item_set and item_set[0 != 49]%}
|
||||
<br/>
|
||||
--------------------------------
|
||||
<br/>
|
||||
{{ ("ItemSets_" ~ item_set[0] ~ "_kitName")|lu_translate }}: Rank {{ item_set[4] }}<br/>
|
||||
{% if item_set[5] %}
|
||||
<img src='/luclient/get_icon_iconid/{{item_set[5]}}'
|
||||
alt='Kit Image'
|
||||
width='128'
|
||||
height='128'>
|
||||
<br/>
|
||||
Multi-Item Bonus:<br/>
|
||||
{% if item_set[6] %}
|
||||
<b>2 Items:</b><br/>
|
||||
{% with stat = item_set[6]|get_set_stats %}
|
||||
{% include 'partials/charxml/_stats.html.j2' %}
|
||||
{% endwith %}
|
||||
<br/><br/>
|
||||
{% endif %}
|
||||
{% if item_set[7] %}
|
||||
<b>3 Items:</b><br/>
|
||||
{% with stat = item_set[7]|get_set_stats %}
|
||||
{% include 'partials/charxml/_stats.html.j2' %}
|
||||
{% endwith %}
|
||||
<br/><br/>
|
||||
{% endif %}
|
||||
{% if item_set[8] %}
|
||||
<b>4 Items:</b><br/>
|
||||
{% with stat = item_set[8]|get_set_stats %}
|
||||
{% include 'partials/charxml/_stats.html.j2' %}
|
||||
{% endwith %}
|
||||
<br/><br/>
|
||||
{% endif %}
|
||||
{% if item_set[9] %}
|
||||
<b>5 Items:</b><br/>
|
||||
{% with stat = item_set[9]|get_set_stats %}
|
||||
{% include 'partials/charxml/_stats.html.j2' %}
|
||||
{% endwith %}
|
||||
<br/><br/>
|
||||
{% endif %}
|
||||
{% if item_set[10] %}
|
||||
<b>6 Items:</b><br/>
|
||||
{% with stat = item_set[10]|get_set_stats %}
|
||||
{% include 'partials/charxml/_stats.html.j2' %}
|
||||
{% endwith %}
|
||||
<br/><br/>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
--------------------------------
|
||||
{% endif %}
|
||||
|
||||
{% if desc %}
|
||||
<br/>{{ desc }}
|
||||
{% endif %}
|
||||
{% if base_stat %}
|
||||
<br/>
|
||||
{% with stat = base_stat %}
|
||||
{% include 'partials/charxml/_stats.html.j2' %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
38
app/templates/partials/charxml/_stats.html.j2
Normal file
38
app/templates/partials/charxml/_stats.html.j2
Normal file
@@ -0,0 +1,38 @@
|
||||
{% if stat.life > 0 %}
|
||||
+ {{ stat.life }}
|
||||
<img src='{{ url_for('luclient.get_icon_iconid', id=3262) }}'
|
||||
alt='Health: '
|
||||
width='20'
|
||||
height='20'>
|
||||
{% endif %}
|
||||
|
||||
{% if stat.armor > 0 %}
|
||||
+ {{ stat.armor }}
|
||||
<img src='{{ url_for('luclient.get_icon_iconid', id=3263) }}'
|
||||
alt='Armor: '
|
||||
width='20'
|
||||
height='20'>
|
||||
{% endif %}
|
||||
|
||||
{% if stat.im > 0 %}
|
||||
+ {{ stat.im }}
|
||||
<img src='{{ url_for('luclient.get_icon_iconid', id=1032) }}'
|
||||
alt='Imagination: '
|
||||
width='20'
|
||||
height='20'>
|
||||
{% endif %}
|
||||
|
||||
{% if stat.skill|length > 0 %}
|
||||
{% for skill in stat.skill %}
|
||||
{% set skill_desc = skill[0]|get_skill_desc %}
|
||||
{% if "IP" not in skill_desc and "AP" not in skill_desc and "LP" not in skill_desc and skill[0]|string not in skill_desc %}
|
||||
<br/>
|
||||
<img src='{{ url_for('luclient.get_icon_iconid', id=skill[1]) }}'
|
||||
alt='Skill: '
|
||||
width='32'
|
||||
height='32'>
|
||||
{{ skill[0]|get_skill_desc }}
|
||||
<br/>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
51
app/templates/partials/charxml/_zone_stats.html.j2
Normal file
51
app/templates/partials/charxml/_zone_stats.html.j2
Normal file
@@ -0,0 +1,51 @@
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
{{ zone.attr_map|get_zone_name }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Achievements Collected:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ zone.attr_ac }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Bricks Collected:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ zone.attr_bc }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Coins Collected:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ zone.attr_cc }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Enemies Smashed:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ zone.attr_es }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Quick Builds Collected:
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ zone.attr_qbc }}
|
||||
</div>
|
||||
</div>
|
||||
|
22
app/templates/play_keys/bulk.html.j2
Normal file
22
app/templates/play_keys/bulk.html.j2
Normal file
@@ -0,0 +1,22 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
Bulk Play Key Creation
|
||||
{% endblock title %}
|
||||
|
||||
{% block content_before %}
|
||||
Bulk Play Key Creation
|
||||
{% endblock content_before %}
|
||||
|
||||
{% block content %}
|
||||
<form method=post>
|
||||
{{ form.csrf_token }}
|
||||
<div class="card shadow-sm mx-auto pb-3 bg-dark border-primary" style="width: 20rem;">
|
||||
<div class="card-body">
|
||||
{{ helper.render_field(form.count) }}
|
||||
{{ helper.render_field(form.uses) }}
|
||||
{{ helper.render_submit_field(form.submit) }}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock content %}
|
23
app/templates/play_keys/edit.html.j2
Normal file
23
app/templates/play_keys/edit.html.j2
Normal file
@@ -0,0 +1,23 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
Edit Play Key {{ key.key_string }}
|
||||
{% endblock title %}
|
||||
|
||||
{% block content_before %}
|
||||
Edit Play Key {{ key.key_string }}
|
||||
{% endblock content_before %}
|
||||
|
||||
{% block content %}
|
||||
<form method=post>
|
||||
{{ form.csrf_token }}
|
||||
<div class="card shadow-sm mx-auto pb-3 bg-dark border-primary" style="width: 20rem;">
|
||||
<div class="card-body">
|
||||
{{ helper.render_field(form.uses) }}
|
||||
{{ helper.render_checkbox_field(form.active) }}
|
||||
{{ helper.render_field(form.notes) }}
|
||||
{{ helper.render_submit_field(form.submit) }}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock content %}
|
56
app/templates/play_keys/index.html.j2
Normal file
56
app/templates/play_keys/index.html.j2
Normal file
@@ -0,0 +1,56 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
Play Key Management
|
||||
{% endblock title %}
|
||||
|
||||
{% block content_before %}
|
||||
Play Key Management
|
||||
{% endblock content_before %}
|
||||
|
||||
{% block content %}
|
||||
{% if message %}
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<h3>{{ message }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
{% endif %}
|
||||
<a role="button" class="btn btn-primary btn btn-block"
|
||||
href='{{ url_for('play_keys.create') }}'>
|
||||
Create one Play Key with one use
|
||||
</a>
|
||||
<a role="button" class="btn btn-primary btn btn-block"
|
||||
href='{{ url_for('play_keys.bulk_create') }}'>
|
||||
Bulk Create Play Keys
|
||||
</a>
|
||||
<hr class="bg-primary"/>
|
||||
<table class="table" id="play_key_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Actions</th>
|
||||
<th>Key</th>
|
||||
<th>Uses Left</th>
|
||||
<th>Times Used</th>
|
||||
<th>Created</th>
|
||||
<th>Active</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block js %}
|
||||
{{ super () }}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
let play_key_table = $('#play_key_table').DataTable({
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"ajax": "{{ url_for('play_keys.get') }}",
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
96
app/templates/play_keys/view.html.j2
Normal file
96
app/templates/play_keys/view.html.j2
Normal file
@@ -0,0 +1,96 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
Play Key {{ key.key_string }}
|
||||
{% endblock title %}
|
||||
|
||||
{% block content_before %}
|
||||
Play Key {{ key.key_string }}
|
||||
{% endblock content_before %}
|
||||
|
||||
{% block content %}
|
||||
<div class="card shadow-sm mx-auto pb-3 bg-dark border-primary" style="width: 30em;">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<h4>Key Info</h4>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Uses Left:
|
||||
</div>
|
||||
<br/>
|
||||
<div class="col">
|
||||
{{ key.key_uses}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Uses Left:
|
||||
</div>
|
||||
<br/>
|
||||
<div class="col">
|
||||
{{ key.key_uses}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Created:
|
||||
</div>
|
||||
<br/>
|
||||
<div class="col">
|
||||
{{ key.created_at }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Active:
|
||||
</div>
|
||||
<div class="col">
|
||||
{% if key.active %}
|
||||
<h5 class="far fa-check-square text-success"></h5>
|
||||
{% else %}
|
||||
<h5 class="far fa-times-circle text-danger"></h5>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
Notes:
|
||||
</div>
|
||||
<br/>
|
||||
<div class="col">
|
||||
{{ key.notes }}
|
||||
</div>
|
||||
</div>
|
||||
<hr class="bg-primary"/>
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<h4>Associated Accounts</h4>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
{% if accounts %}
|
||||
{% for account in accounts %}
|
||||
<div class="row">
|
||||
<div class="col text-right">
|
||||
{{ account.username }}
|
||||
</div>
|
||||
<br/>
|
||||
<div class="col">
|
||||
<a role="button" class="btn btn-primary"
|
||||
href='{{ url_for('accounts.view', id=account.id) }}'>
|
||||
View Account
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
No accounts are using ths Play Key
|
||||
{% endif %}
|
||||
<br/>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
58
app/templates/properties/index.html.j2
Normal file
58
app/templates/properties/index.html.j2
Normal file
@@ -0,0 +1,58 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
Property Management
|
||||
{% endblock title %}
|
||||
|
||||
{% block content_before %}
|
||||
Property Management
|
||||
{% endblock content_before %}
|
||||
|
||||
{% block content %}
|
||||
{% if message %}
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<h3>{{ message }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
{% endif %}
|
||||
<table class="table" id="properties_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Actions</th>
|
||||
<th>Owner</th>
|
||||
<th>Template ID</th>
|
||||
<th>Clone ID</th>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>Privacy</th>
|
||||
<th>Approved</th>
|
||||
<th>Updated</th>
|
||||
<th>Claimed</th>
|
||||
<th>Rejection Reason</th>
|
||||
<th>Reputation</th>
|
||||
<th>Location</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block js %}
|
||||
{{ super () }}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
let properties_table = $('#properties_table').DataTable({
|
||||
"processing": true,
|
||||
"serverSide": true,
|
||||
"ajax": "{{ url_for('properties.get', status='all') }}",
|
||||
"columnDefs": [
|
||||
{ "searchable": false, "targets": [0] },
|
||||
{ "orderable": false, "targets": [0] }
|
||||
]
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
39
app/templates/properties/view.html.j2
Normal file
39
app/templates/properties/view.html.j2
Normal file
@@ -0,0 +1,39 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
Viewing {{property_data.owner.name}}'s
|
||||
{% if property_data.name %}
|
||||
{{ property_data.name }}
|
||||
{% else %}
|
||||
{{ property_data.zone_id|get_zone_name }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content_before %}
|
||||
Viewing {{property_data.owner.name}}'s
|
||||
{% if property_data.name %}
|
||||
{{ property_data.name }}
|
||||
{% else %}
|
||||
{{ property_data.zone_id|get_zone_name }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% with property=property_data%}
|
||||
{% include 'partials/_property.html.j2' %}
|
||||
{% endwith %}
|
||||
{% endblock content %}
|
||||
|
||||
{% block content_after %}
|
||||
<br/>
|
||||
<br/>
|
||||
<h3 class="text-center">Property Content</h3>
|
||||
<hr class="bg-primary"/>
|
||||
<div class="card-columns">
|
||||
{% for item in property_data.properties_contents %}
|
||||
{% include 'partials/_property_content.html.j2' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% endblock content_after %}
|
||||
|
33
app/templates/reports/index.html.j2
Normal file
33
app/templates/reports/index.html.j2
Normal file
@@ -0,0 +1,33 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
Reports
|
||||
{% endblock title %}
|
||||
|
||||
{% block content_before %}
|
||||
Reports
|
||||
{% endblock content_before %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
Items: <br/>
|
||||
{% for item in items %}
|
||||
<a role="button" class="btn btn-primary btn btn-block"
|
||||
href='{{url_for('reports.items_by_date', date=item.date)}}'>
|
||||
{{item.date}}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block js %}
|
||||
{{ super () }}
|
||||
|
||||
{% endblock %}
|
46
app/templates/reports/items/by_date.html.j2
Normal file
46
app/templates/reports/items/by_date.html.j2
Normal file
@@ -0,0 +1,46 @@
|
||||
{% extends 'base.html.j2' %}
|
||||
|
||||
{% block title %}
|
||||
Items on {{ date }}
|
||||
{% endblock title %}
|
||||
|
||||
{% block content_before %}
|
||||
Items on {{ date }}
|
||||
{% endblock content_before %}
|
||||
|
||||
{% block content %}
|
||||
<div class='table-responsive'>
|
||||
<table class="table table-dark table-striped table-bordered table-hover"
|
||||
id="two_weeks"
|
||||
data-order='[[ 1, "asc" ]]'
|
||||
data-page-length='25'>
|
||||
<thead>
|
||||
<th scope="col">
|
||||
Item
|
||||
</th>
|
||||
<th scope="col">
|
||||
Count
|
||||
</th>
|
||||
<th scope="col">
|
||||
Rarity
|
||||
</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in items %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ item.item|get_lot_name }}
|
||||
</td>
|
||||
<td>
|
||||
{{ item.count }}
|
||||
</td>
|
||||
<td>
|
||||
{{ item.item|get_lot_rarity }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
Reference in New Issue
Block a user