Ajout d'une extension

This commit is contained in:
Gauvain Boiché
2020-04-04 18:27:27 +02:00
parent c3ed8cc1c1
commit 3a964fe237
387 changed files with 58921 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
{% extends '@phpbbstudio_aps/aps_main.html' %}
{% block nav %}
{% for page in aps_navbar %}
<li>
<a class="aps-list-item{{ page.S_ACTIVE ? ' aps-list-active' }}" href="{{ page.U_VIEW }}">
{{ page.TITLE }}
</a>
</li>
{% endfor %}
{% endblock %}
{% block nav_right %}
{% if S_REGISTERED_USER %}
<li class="aps-list-item aps-panel-add dropdown-container dropdown-container-left">
<span class="dropdown-trigger dropdown-select{{ aps_blocks|length ? '' : ' aps-panel-add-pulse' }}">
<i class="icon fa-th-large fa-fw" aria-hidden="true"></i>
</span>
<div class="dropdown hidden">
<div class="pointer"><div class="pointer-inner"></div></div>
<ul class="dropdown-contents">
{% for block in aps_blocks_add %}
{{ block.item }}
{% endfor %}
<li class="aps-panel-empty"><span class="aps-button-red">{{ lang('APS_POINTS_BLOCK_NO') }}</span></li>
</ul>
</div>
</li>
{% endif %}
{% endblock %}
{% block main %}
<div class="aps-row" data-aps-sort="{{ U_APS_ACTION_SORT }}">
{% for block in aps_blocks %}
{{ include('@phpbbstudio_aps/blocks/base.html', {'block': block}) }}
{% endfor %}
<div class="aps-panel-empty aps-col s12" data-aps-empty-panel="true">
<div class="aps-panel">
<div class="aps-panel-content aps-center">
<p class="error aps-no-mar-bot">{{ lang('APS_POINTS_BLOCK_NONE') }}</p>
</div>
</div>
</div>
</div>
{% endblock %}
{% INCLUDEJS '@phpbbstudio_aps/js/chart.bundle.min.js' %}
{% INCLUDEJS '@phpbbstudio_aps/js/jquery-ui-sortable.min.js' %}
{% INCLUDEJS '@phpbbstudio_aps/js/palette.js' %}
{% INCLUDEJS '@phpbbstudio_aps/js/aps_display.js' %}

View File

@@ -0,0 +1,36 @@
<div class="dropdown-container dropdown-container-left dropdown-button-control sort-tools">
<span title="{{ lang('SEARCH') }}" class="aps-button-blue dropdown-trigger dropdown-select">
<i class="icon fa-search fa-fw" aria-hidden="true"></i>
<span class="caret"><i class="icon fa-sort-down fa-fw" aria-hidden="true"></i></span>
</span>
<div class="dropdown hidden">
<div class="pointer"><div class="pointer-inner"></div></div>
<div class="dropdown-contents">
<fieldset class="display-options">
<label>
{{ lang('FORUM') ~ lang('COLON') }}
<select name="f">
<option value="0">{{ lang('SELECT_FORUM') }}</option>
{{ S_SELECT_FORUM }}
</select>
</label>
<label>
{{ lang('TOPIC_TITLE') ~ lang('COLON') }}
<input class="inputbox autowidth" name="t" type="text" value="{{ S_SEARCH_TOPIC }}">
</label>
{% if S_AUTH_USER %}
<label>
{{ lang('SORT_USERNAME') ~ lang('COLON') }}
<input class="inputbox autowidth" name="u" type="text" value="{{ S_SEARCH_USER }}">
</label>
{% endif %}
{% if S_AUTH_FROM %}
<label>
{{ lang('FROM')|capitalize ~ lang('COLON') }}
<input class="inputbox autowidth" name="r" type="text" value="{{ S_SEARCH_FROM }}">
</label>
{% endif %}
</fieldset>
</div>
</div>
</div>

View File

@@ -0,0 +1,16 @@
<div class="dropdown-container dropdown-container-left dropdown-button-control sort-tools">
<span title="{{ lang('SORT_OPTIONS') }}" class="aps-button-blue dropdown-trigger dropdown-select">
<i class="icon fa-sort-amount-asc fa-fw" aria-hidden="true"></i>
<span class="caret"><i class="icon fa-sort-down fa-fw" aria-hidden="true"></i></span>
</span>
<div class="dropdown hidden">
<div class="pointer"><div class="pointer-inner"></div></div>
<div class="dropdown-contents">
<fieldset class="display-options">
<label>{{ lang('DISPLAY') ~ lang('COLON') }} {{ S_SELECT_SORT_DAYS }}</label>
<label>{{ lang('SORT_BY') ~ lang('COLON') }} {{ S_SELECT_SORT_KEY }}</label>
<label>{{ lang('SORT_DIRECTION') ~ lang('COLON') }} {{ S_SELECT_SORT_DIR }}</label>
</fieldset>
</div>
</div>
</div>

View File

@@ -0,0 +1,79 @@
{% include 'overall_header.html' %}
{% if not definition.INCLUDED_APS_DISPLAYCSS %}
{% INCLUDECSS '@phpbbstudio_aps/aps_display.css' %}
{% DEFINE INCLUDED_APS_DISPLAYCSS = true %}
{% endif %}
{% if not definition.INCLUDED_APS_FORMCSS %}
{% INCLUDECSS '@phpbbstudio_aps/aps_form.css' %}
{% DEFINE INCLUDED_APS_FORMCSS = true %}
{% endif %}
{% block includes %}{% endblock %}
<main class="aps-main">
<header>
<div class="aps-menu aps-lists-container">
<div class="aps-menu-before">
{# Reserved: Please do not use this event #}
{% EVENT phpbbstudio_aps_menu_before %}
</div>
<div class="aps-menu-icon">
<div>
<i class="headerbar icon {{ aps_config('aps_points_icon') }} fa-fw"></i>
</div>
</div>
<ul class="aps-list">
<li>
<a class="aps-list-item{{ S_APS_OVERVIEW ? ' aps-list-active' }}" href="{{ path('phpbbstudio_aps_display') }}" title="{{ lang('APS_OVERVIEW') }}">
<i class="icon fa-newspaper-o fa-fw"></i>
<span>{{ lang('APS_OVERVIEW') }}</span>
</a>
</li>
{% EVENT phpbbstudio_aps_menu_append %}
</ul>
<ul class="aps-list aps-list-right">
{% EVENT phpbbstudio_aps_menu_right_prepend %}
<li>
<span class="aps-list-item aps-menu-points">
{{ aps_display(user.data.user_points, false) }}
</span>
</li>
</ul>
</div>
{% set nav = block('nav') is defined ? block('nav')|trim : '' %}
{% set nav_right = block('nav_right') is defined ? block('nav_right')|trim : '' %}
{% if nav != '' or nav_right != '' %}
<div class="aps-nav aps-lists-container headerbar">
{% if nav != '' %}
<ul class="aps-list">
{{ nav }}
</ul>
{% endif %}
{% if nav_right != '' %}
<ul class="aps-list aps-list-right">
{{ nav_right }}
</ul>
{% endif %}
</div>
{% endif %}
</header>
<div class="aps-body">
{% block main %}{% endblock %}
</div>
<footer class="aps-footer">
<a href="https://phpbbstudio.com/extensions/advanced-points-system" target="_blank" rel="noopener">Advanced Points System</a> <i class="icon fa-copyright fa-fw" aria-hidden="true"></i> <a href="https://phpbbstudio.com" target="_blank" rel="noopener">phpBB Studio</a>
</footer>
</main>
{% if not definition.INCLUDED_SWEETALERT2ALLMINJS %}
{% INCLUDEJS '@phpbbstudio_aps/js/sweetalert2.all.min.js' %}
{% DEFINE INCLUDED_SWEETALERT2ALLMINJS = true %}
{% endif %}
{% include 'overall_footer.html' %}

View File

@@ -0,0 +1,28 @@
{% set width = block('width', block.TEMPLATE) is defined ? block('width', block.TEMPLATE) : 's12' %}
<div class="aps-col {{ width }}" id="aps_{{ block.ID }}" data-aps-id="{{ block.ID }}">
<div class="aps-panel">
<div class="aps-panel-header">
<h3>{{ block.TITLE }}</h3>
{% if S_USER_LOGGED_IN and not S_IS_BOT %}
{% if not block.S_REQUIRED %}
<a class="aps-panel-action aps-panel-delete" href="{{ block.U_DELETE }}" data-ajax="aps_remove">
<i class="icon fa-times fa-fw"></i>
</a>
{% endif %}
<span class="aps-panel-action aps-panel-move aps-js"><i class="icon fa-ellipsis-h fa-fw"></i></span>
{% endif %}
</div>
<div class="aps-panel-content">
{% if block('content', block.TEMPLATE) is defined %}
{{ block('content', block.TEMPLATE) }}
{% else %}
<p class="error">{{ lang('APS_POINTS_BLOCK_NO_CONTENT') }}</p>
{% endif %}
</div>
{% if block('footer', block.TEMPLATE) is defined %}
<div class="aps-panel-footer">
{{ block('footer', block.TEMPLATE) }}
</div>
{% endif %}
</div>
</div>

View File

@@ -0,0 +1,104 @@
{% block width %}s12{% endblock %}
{% block content %}
{% if aps_actions %}
<div class="aps-collection">
{% for action in aps_actions %}
<div class="aps-collection-item aps-avatar">
{{ APS_ACTIONS_AVATARS[action.USER_ID] is not empty ? APS_ACTIONS_AVATARS[action.USER_ID] : (S_APS_DAE_ENABLED ? '' : APS_ACTIONS_NO_AVATAR) }}
<div class="aps-row">
<div class="aps-col s12 m{{ action.S_AUTH_BUILD ? 4 : 6 }} l2 aps-no-mar-bot">
{{ action.USER }}
</div>
<div class="aps-col {{ action.S_AUTH_BUILD ? 's9 m6 l2' : 's12 m6 l3' }} aps-no-mar-bot aps-no-padding">
<strong>{{ lang(action.ACTION) }}</strong>
{% if not action.S_SELF %}
<br>{{ lang('POST_BY_AUTHOR') }}
{% if action.S_MOD and not action.S_AUTH_MOD %}
{{ lang('MODERATOR') }}
{% else %}
{{ action.REPORTEE }}
{% endif %}
{% endif %}
</div>
{% if action.S_AUTH_BUILD %}
<div class="aps-col s1 m1 l1 aps-no-mar-bot">
{% if action.S_AUTH_BUILD_OTHER %}
<div class="aps-button-blue aps-inline aps-js" data-aps-augmentation="true">
<i class="icon fa-list fa-fw"></i>
</div>
<div class="hidden">
<dl class="details">
{% for key, value in action.ACTIONS %}
<dt>{{ aps_display(value, false) }}</dt>
<dd>{{ lang(key, aps_name()) }}</dd>
{% endfor %}
</dl>
</div>
{% endif %}
</div>
{% endif %}
<div class="aps-row aps-col s12 l3 aps-no-mar-bot">
<div class="aps-col s4 aps-no-mar-bot aps-no-padding">
{{ aps_display(action.POINTS_OLD, false) }}
</div>
<div class="aps-col s4 aps-no-mar-bot aps-no-padding {{ action.POINTS_SUM < 0 ? 'aps-negative' : 'aps-positive' }}">
{{ aps_display(action.POINTS_SUM, false) }}
</div>
<div class="aps-col s4 aps-no-mar-bot aps-no-padding">
{{ aps_display(action.POINTS_NEW, false) }}
</div>
</div>
<div class="aps-col s6 l2 aps-no-mar-bot aps-hide-s">
{{ user.format_date(action.TIME) }}
</div>
<div class="aps-col s6 l2 aps-no-mar-bot aps-ellipsis aps-hide-s">
{% if action.FORUM_NAME or action.TOPIC_TITLE or action.POST_SUBJECT %}
<ul class="fa-ul aps-no-mar">
{% if action.FORUM_NAME %}
<li><a href="{{ action.U_FORUM }}" title="{{ action.FORUM_NAME }}">{{ action.FORUM_NAME }}</a></li>
{% endif %}
{% if action.TOPIC_TITLE %}
<li><a href="{{ action.U_TOPIC }}" title="{{ action.TOPIC_TITLE }}">{{ action.TOPIC_TITLE }}</a></li>
{% endif %}
{% if action.POST_SUBJECT %}
<li><a href="{{ action.U_POST }}" title="{{ action.POST_SUBJECT }}">{{ action.POST_SUBJECT }}</a></li>
{% endif %}
</ul>
{% else %}
<div class="aps-center">{{ lang('NA') }}</div>
{% endif %}
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="error">{{ lang('APS_POINTS_ACTIONS_NONE', aps_name()) }}</div>
{% endif %}
{% endblock %}
{% block footer %}
{# Pagination #}
<div class="pagination top-pagination">
{{ TOTAL_LOGS }}
{% if pagination %}
{% include 'pagination.html' %}
{% else %}
&bull; {{ PAGE_NUMBER }}
{% endif %}
</div>
{# Search and sort #}
<form class="aps-form" method="post" action="{{ U_APS_ACTION_LOGS }}" data-ajax="aps_replace">
{# Sort options #}
{% include '@phpbbstudio_aps/aps_display_sort.html' %}
{# Search options #}
{% include '@phpbbstudio_aps/aps_display_search.html' %}
{# Search keywords #}
<input id="keywords" name="keywords" type="search" size="20" placeholder="{{ lang('APS_POINTS_ACTION_SEARCH', aps_name()) }}" />
<input id="submit" name="submit" type="submit" value="{{ lang('SEARCH') }}">
</form>
{% endblock %}

View File

@@ -0,0 +1,79 @@
{% block width %}s12{% endblock %}
{% block content %}
{% if aps_adjustments %}
<div class="aps-collection">
{% for action in aps_adjustments %}
<div class="aps-collection-item aps-avatar">
{{ APS_ADJUSTMENTS_AVATARS[action.USER_ID] is not empty ? APS_ADJUSTMENTS_AVATARS[action.USER_ID] : (S_APS_DAE_ENABLED ? '' : APS_ADJUSTMENTS_NO_AVATAR) }}
<div class="aps-row">
<div class="aps-col s12 m{{ action.S_AUTH_BUILD ? 4 : 6 }} l2 aps-no-mar-bot">
{{ action.USER }}
</div>
<div class="aps-col {{ action.S_AUTH_BUILD ? 's9 m6 l2' : 's12 m6 l3' }} aps-no-mar-bot">
<strong>{{ lang(action.ACTION) }}</strong>
</div>
{% if action.S_AUTH_BUILD %}
<div class="aps-col s1 m1 l1 aps-no-mar-bot">
{% if action.S_AUTH_BUILD_OTHER %}
<div class="aps-button-blue aps-inline aps-js" data-aps-augmentation="true">
<i class="icon fa-list fa-fw"></i>
</div>
<div class="hidden">
<dl class="details">
{% for key, value in action.ACTIONS %}
<dt>{{ aps_display(value, false) }}</dt>
<dd>{{ lang(key, aps_name()) }}</dd>
{% endfor %}
</dl>
</div>
{% endif %}
</div>
{% endif %}
<div class="aps-row aps-col s12 l3 aps-no-mar-bot">
<div class="aps-col s4 aps-no-mar-bot">
{{ aps_display(action.POINTS_OLD, false) }}
</div>
<div class="aps-col s4 aps-no-mar-bot">
{{ aps_display(action.POINTS_SUM, false) }}
</div>
<div class="aps-col s4 aps-no-mar-bot">
{{ aps_display(action.POINTS_NEW, false) }}
</div>
</div>
<div class="aps-col s6 l2 aps-no-mar-bot aps-hide-s">
{{ user.format_date(action.TIME) }}
{% if not action.S_SELF %}
{{ lang('POST_BY_AUTHOR') }}
{% if action.S_MOD and not action.S_AUTH_MOD %}
{{ lang('MODERATOR') }}
{% else %}
{{ action.REPORTEE }}
{% endif %}
{% endif %}
</div>
<div class="aps-col s6 l2 aps-no-mar-bot aps-ellipsis aps-hide-s">
{% if action.FORUM_NAME or action.TOPIC_TITLE or action.POST_SUBJECT %}
<ul class="fa-ul aps-no-mar">
{% if action.FORUM_NAME %}
<li><a href="{{ action.U_FORUM }}" title="{{ action.FORUM_NAME }}">{{ action.FORUM_NAME }}</a></li>
{% endif %}
{% if action.TOPIC_TITLE %}
<li><a href="{{ action.U_TOPIC }}" title="{{ action.TOPIC_TITLE }}">{{ action.TOPIC_TITLE }}</a></li>
{% endif %}
{% if action.POST_SUBJECT %}
<li><a href="{{ action.U_POST }}" title="{{ action.POST_SUBJECT }}">{{ action.POST_SUBJECT }}</a></li>
{% endif %}
</ul>
{% else %}
<div class="aps-center">{{ lang('NA') }}</div>
{% endif %}
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="error">{{ lang('APS_POINTS_ACTIONS_NONE', aps_name()) }}</div>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,18 @@
{% block width %}s12 m6 aps-js{% endblock %}
{% block content %}
<canvas data-aps-chart="pie"
data-aps-time="{{ aps_config('aps_display_graph_time') }}"
data-aps-empty="{{ lang('APS_POINTS_DATA_EMPTY', aps_name()) }}"
aria-label="{{ lang('APS_POINTS_PER_FORUM', aps_name()) }}"
role="img">
<p>{{ lang('APS_POINTS_PER_FORUM', aps_name()) }}</p>
</canvas>
<div class="hidden">
{% for forum in aps_forums %}
<div data-aps-labels="{{ forum.NAME|e }}"
data-aps-value="{{ aps_format(forum.POINTS) }}">
</div>
{% endfor %}
</div>
{% endblock %}

View File

@@ -0,0 +1,16 @@
{% block width %}s12 m6 aps-js{% endblock %}
{% block content %}
<canvas data-aps-chart="polarArea"
data-aps-time="{{ aps_config('aps_display_graph_time') }}"
data-aps-empty="{{ lang('APS_POINTS_DATA_EMPTY', aps_name()) }}"
aria-label="{{ lang('APS_POINTS_PER_GROUP', aps_name()) }}"
role="img">
<p>{{ lang('APS_POINTS_PER_GROUP', aps_name()) }}</p>
</canvas>
<div class="hidden">
{% for group in aps_groups %}
<div data-aps-labels="{{ group.NAME|e }}" data-aps-colour="#{{ group.COLOUR }}" data-aps-value="{{ aps_format(group.POINTS) }}"></div>
{% endfor %}
</div>
{% endblock %}

View File

@@ -0,0 +1,22 @@
{% block width %}s12 m6 aps-js{% endblock %}
{% block content %}
<canvas data-aps-chart="line"
data-aps-time="{{ aps_config('aps_display_graph_time') }}"
data-aps-empty="{{ lang('APS_POINTS_DATA_EMPTY', aps_name()) }}"
aria-label="{{ lang('APS_POINTS_GROWTH', aps_name()) }}"
role="img">
<p>{{ lang('APS_POINTS_GROWTH', aps_name()) }}</p>
</canvas>
<div class="hidden">
{% for growth in aps_period %}
<div data-aps-labels="{{ growth.DATE|e }}"
data-aps-label="{{ aps_name()|e }}"
data-aps-colour="transparent"
data-aps-colour-border="#12a3eb"
data-aps-colour-point="#0076b1"
data-aps-value="{{ aps_format(growth.TOTAL) }}">
</div>
{% endfor %}
</div>
{% endblock %}

View File

@@ -0,0 +1,13 @@
{% block width %}s12 m6{% endblock %}
{% block content %}
<div class="aps-row">
<div class="aps-col s6 aps-center">
{{ APS_RANDOM_USER_AVATAR ? APS_RANDOM_USER_AVATAR : (S_APS_DAE_ENABLED ? '' : APS_RANDOM_NO_AVATAR) }}
</div>
<div class="aps-col s6">
{{ APS_RANDOM_USER_FULL }}<br />
{{ aps_display(APS_RANDOM_USER_POINTS) }}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,29 @@
{% block width %}s12 m6{% endblock %}
{% block content %}
<div class="aps-row">
<div class="aps-col s6 aps-center">
{{ APS_SEARCH_USER_AVATAR ? APS_SEARCH_USER_AVATAR : (S_APS_DAE_ENABLED ? '' : APS_NO_AVATAR) }}
</div>
<div class="aps-col s6">
{{ APS_SEARCH_USER_FULL }}<br />
{{ aps_display(APS_SEARCH_USER_POINTS) }}<br />
{% set podium = APS_SEARCH_USER_RANK in 1..3 ? APS_SEARCH_USER_RANK : 0 %}
<span title="{{ lang('RANK') }}"><i class="icon fa-trophy fa-fw aps-podium-{{ podium }}" aria-hidden="true"></i> {{ APS_SEARCH_USER_RANK }}</span>
{% if S_APS_USER_ADJUST and U_APS_SEARCH_USER_ADJUST %}
<br />
<a class="aps-secondary-content" href="{{ U_APS_SEARCH_USER_ADJUST }}" title="{{ lang('APS_ADJUST_USER_POINTS', aps_name()) }}">
<i class="icon fa-pencil fa-fw"></i>
</a>
{% endif %}
</div>
</div>
{% endblock %}
{% block footer %}
<form class="aps-form" method="post" action="{{ U_APS_ACTION_SEARCH }}" data-ajax="aps_replace">
<label for="aps_user_search">{{ lang('FIND_USERNAME') ~ lang('COLON') }}</label>
<input id="aps_user_search" name="aps_user_search" type="text" value="{{ APS_SEARCH_USERNAME }}" />
<input name="submit" type="submit" value="{{ lang('SEARCH') }}" />
</form>
{% endblock %}

View File

@@ -0,0 +1,18 @@
{% block width %}s12 m6{% endblock %}
{% block content %}
{% set min = aps_config('aps_points_min') %}
{% set max = aps_config('aps_points_max') %}
{% set def = aps_config('default_lang') %}
{% set name = aps_config('aps_points_name_' ~ def) %}
{% set name = user.lang_name != def and name != aps_name() ? name : '' %}
<dl class="details">
<dt>{{ lang('APS_POINTS_NAME') ~ lang('COLON') }}</dt><dd>{{ aps_name() }}{% if name %} <em>({{ name }})</em>{% endif %}</dd>
<dt>{{ lang('APS_POINTS_FORMAT', aps_name()) ~ lang('COLON') }}</dt><dd>{{ aps_display(12345.00) }}</dd>
<dt>{{ lang('APS_POINTS_MIN', aps_name()) ~ lang('COLON') }}</dt><dd>{{ min ? min : lang('NA') }}</dd>
<dt>{{ lang('APS_POINTS_MAX', aps_name()) ~ lang('COLON') }}</dt><dd>{{ max ? max : lang('NA') }}</dd>
<dt>{{ lang('APS_POINTS_ACTIONS_PAGE') ~ lang('COLON') }}</dt><dd>{{ aps_config('aps_actions_per_page') }}</dd>
{% EVENT phpbbstudio_aps_display_settings_append %}
</dl>
{% endblock %}

View File

@@ -0,0 +1,36 @@
{% block width %}s12 m6{% endblock %}
{% block content %}
<div class="aps-collection">
{% set last_place = 0 %}
{% set last_points = 0 %}
{% for user in top_users %}
{% set same_points = last_points == user.POINTS %}
{% set last_place = same_points ? last_place : loop.index %}
{% set last_points = same_points ? last_points : user.POINTS %}
<div class="aps-collection-item aps-avatar">
{{ user.AVATAR ? user.AVATAR : (S_APS_DAE_ENABLED ? '' : APS_NO_AVATAR) }}
<span class="title">{{ user.NAME }}</span>
<p>{{ aps_display(user.POINTS) }}</p>
{% if S_APS_USER_ADJUST %}
<a class="aps-secondary-content" href="{{ user.U_ADJUST }}" title="{{ lang('APS_ADJUST_USER_POINTS', aps_name()) }}">
<i class="icon fa-pencil fa-fw"></i>
</a>
{% elseif last_place < 4 %}
<i class="aps-secondary-content icon fa-trophy fa-fw aps-podium-{{ last_place }}" aria-hidden="true"></i>
{% else %}
<span class="aps-secondary-content fa-fw">{{ last_place }}</span>
{% endif %}
</div>
{% endfor %}
</div>
{% endblock %}
{% block footer %}
<form class="aps-form" method="post" action="{{ U_APS_ACTION_TOP }}" data-ajax="aps_replace">
<label for="aps_user_top_count">{{ lang('USERS') ~ lang('COLON') }}</label>
<input id="aps_user_top_count" name="aps_user_top_count" type="number" min="{{ aps_config('aps_display_top_count') }}" max="50" value="{{ APS_TOP_USERS_COUNT }}"{% if not aps_config('aps_display_top_change') %} disabled{% endif %} />
{% if aps_config('aps_display_top_change') %}<input name="submit" type="submit" value="{{ lang('GO') }}" />{% endif %}
</form>
{% endblock %}

View File

@@ -0,0 +1,28 @@
{% block width %}s12 m6 aps-js{% endblock %}
{% block content %}
<canvas data-aps-chart="bar"
data-aps-time="{{ aps_config('aps_display_graph_time') }}"
data-aps-empty="{{ lang('APS_POINTS_DATA_EMPTY', aps_name()) }}"
aria-label="{{ lang('APS_POINTS_TRADE_OFF', aps_name()) }}"
role="img">
<p>{{ lang('APS_POINTS_TRADE_OFF', aps_name()) }}</p>
</canvas>
<div class="hidden">
{% for trade in aps_period %}
<div data-aps-labels="{{ trade.DATE|e }}"
data-aps-label="{{ lang('APS_POINTS_LOST', aps_name())|e }}"
data-aps-colour="#d31141"
data-aps-value="{{ aps_format(trade.NEGATIVE) }}">
</div>
{% endfor %}
</div>
<div class="hidden">
{% for trade in aps_period %}
<div data-aps-label="{{ lang('APS_POINTS_GAINED', aps_name())|e }}"
data-aps-colour="#28a745"
data-aps-value="{{ aps_format(trade.POSITIVE) }}">
</div>
{% endfor %}
</div>
{% endblock %}

View File

@@ -0,0 +1,2 @@
{% if aps_config('aps_points_display_profile') %}<dt>{{ aps_name() ~ lang('COLON') }}</dt> <dd>{{ aps_display(USER_POINTS) }}</dd>{% endif %}
{% EVENT phpbbstudio_aps_profile_append %}

View File

@@ -0,0 +1,7 @@
{% if S_APS_NAVBAR_HEADER_PROFILE_LIST_AFTER %}
<li>
<a href="{{ path('phpbbstudio_aps_display') }}" title="{{ aps_name() }}" role="menuitem">
{{ aps_icon() }}<span>{{ aps_display(user.data.user_points, false) }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_APS_NAVBAR_HEADER_PROFILE_LIST_BEFORE %}
<li>
<a href="{{ path('phpbbstudio_aps_display') }}" title="{{ aps_name() }}" role="menuitem">
{{ aps_icon() }}<span>{{ aps_display(user.data.user_points, false) }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_APS_NAVBAR_HEADER_QUICK_LINKS_AFTER %}
<li>
<a href="{{ path('phpbbstudio_aps_display') }}" title="{{ aps_name() }}" role="menuitem">
{{ aps_icon() }}<span>{{ aps_display(user.data.user_points, false) }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_APS_NAVBAR_HEADER_QUICK_LINKS_BEFORE %}
<li>
<a href="{{ path('phpbbstudio_aps_display') }}" title="{{ aps_name() }}" role="menuitem">
{{ aps_icon() }}<span>{{ aps_display(user.data.user_points, false) }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_APS_NAVBAR_HEADER_USER_PROFILE_APPEND %}
<li class="rightside">
<a href="{{ path('phpbbstudio_aps_display') }}" title="{{ aps_name() }}" role="menuitem">
{{ aps_icon() }}<span>{{ aps_display(user.data.user_points, false) }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_APS_NAVBAR_HEADER_USER_PROFILE_PREPEND %}
<li class="rightside">
<a href="{{ path('phpbbstudio_aps_display') }}" title="{{ aps_name() }}" role="menuitem">
{{ aps_icon() }}<span>{{ aps_display(user.data.user_points, false) }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_APS_OVERALL_FOOTER_BREADCRUMB_APPEND %}
<li>
<a href="{{ path('phpbbstudio_aps_display') }}" title="{{ aps_name() }}">
{{ aps_icon() }}<span>{{ aps_display(user.data.user_points, false) }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_APS_OVERALL_FOOTER_TEAMLINK_AFTER %}
<li class="rightside">
<a href="{{ path('phpbbstudio_aps_display') }}" title="{{ aps_name() }}" role="menuitem">
{{ aps_icon() }}<span>{{ aps_display(user.data.user_points, false) }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_APS_OVERALL_FOOTER_TEAMLINK_BEFORE %}
<li class="rightside">
<a href="{{ path('phpbbstudio_aps_display') }}" title="{{ aps_name() }}" role="menuitem">
{{ aps_icon() }}<span>{{ aps_display(user.data.user_points, false) }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_APS_OVERALL_FOOTER_TIMEZONE_AFTER %}
<li class="rightside">
<a href="{{ path('phpbbstudio_aps_display') }}" title="{{ aps_name() }}" role="menuitem">
{{ aps_icon() }}<span>{{ aps_display(user.data.user_points, false) }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_APS_OVERALL_FOOTER_TIMEZONE_BEFORE %}
<li class="rightside">
<a href="{{ path('phpbbstudio_aps_display') }}" title="{{ aps_name() }}" role="menuitem">
{{ aps_icon() }}<span>{{ aps_display(user.data.user_points, false) }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_APS_OVERALL_HEADER_NAVIGATION_APPEND %}
<li>
<a href="{{ path('phpbbstudio_aps_display') }}" title="{{ aps_name() }}" role="menuitem">
{{ aps_icon() }}<span>{{ aps_display(user.data.user_points, false) }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,7 @@
{% if S_APS_OVERALL_HEADER_NAVIGATION_PREPEND %}
<li>
<a href="{{ path('phpbbstudio_aps_display') }}" title="{{ aps_name() }}" role="menuitem">
{{ aps_icon() }}<span>{{ aps_display(user.data.user_points, false) }}</span>
</a>
</li>
{% endif %}

View File

@@ -0,0 +1,2 @@
{% if aps_config('aps_points_display_pm') %}<dd><strong>{{ aps_name() ~ lang('COLON') }}</strong> {{ aps_display(AUTHOR_POINTS) }}</dd>{% endif %}
{% EVENT phpbbstudio_aps_pm_append %}

View File

@@ -0,0 +1,2 @@
{% if aps_config('aps_points_display_post') %}<dd><strong>{{ aps_name() ~ lang('COLON') }}</strong> {{ aps_display(postrow.POSTER_POINTS) }}</dd>{% endif %}
{% EVENT phpbbstudio_aps_post_append %}

View File

@@ -0,0 +1,255 @@
/** @function jQuery */
jQuery(function($) {
let aps = {
body: $('.aps-body'),
empty: $('[data-aps-empty-panel]'),
darken: $('#darkenwrapper'),
classes: {
column: '.aps-col',
content: '.aps-panel-content',
panel: '.aps-panel',
pagination: '.aps-panel-footer .pagination'
},
add: {
el: $('.aps-panel-add'),
class: 'aps-panel-add-pulse',
content: '.dropdown-contents',
trigger: '.dropdown-trigger'
},
sortable: {
el: $('[data-aps-sort]'),
url: 'aps-sort',
attr: 'data-aps-id',
data: {
delay: 150,
cursor: 'grabbing',
tolerance: 'pointer',
handle: '.aps-panel-move',
placeholder: 'aps-panel-placeholder',
forcePlaceholderSize: true
}
},
augmentation: {
selector: '[data-aps-augmentation]'
},
charts: {
selector: '[data-aps-chart]',
data: {
chart: 'aps-chart',
colour: 'aps-colour',
border: 'aps-colour-border',
point: 'aps-colour-point',
label: 'aps-label',
labels: 'aps-labels',
time: 'aps-time',
value: 'aps-value'
}
}
};
aps.add.pulse = function() {
this.el.children(this.trigger).toggleClass(this.class, !aps.empty.is(':hidden'));
};
aps.ajaxify = function(context) {
$('[data-ajax]', context).each(function() {
let $this = $(this),
ajax = $this.data('ajax'),
filter = $this.data('filter');
if (ajax !== 'false') {
phpbb.ajaxify({
selector: this,
callback: ajax !== 'true' ? ajax : null,
refresh: aps.defined($this.data('refresh')),
filter: aps.defined(filter) ? phpbb.getFunctionByName(filter) : null
})
}
});
};
aps.defined = function(operand) {
return typeof operand !== 'undefined';
};
aps.message = function(title, text, type, time) {
swal({
title: title,
text: text,
type: type || 'success',
timer: aps.defined(time) ? time : 1500,
showConfirmButton: false
});
};
aps.sortable.el.each(function() {
$(this).sortable($.extend(aps.sortable.data, {
containment: $(this),
update: function() {
$.ajax({
url: $(this).data(aps.sortable.url),
type: 'POST',
data: {
order: $(this).sortable('toArray', { attribute: aps.sortable.attr }),
},
error: function() {
aps.message(aps.darken.data('ajax-error-title'), aps.darken.data('ajax-error-text'), 'error', null);
},
success: function(r) {
aps.message(r.APS_TITLE, r.APS_TEXT);
}
});
}
}));
});
aps.augmentation.register = function(context) {
$(aps.augmentation.selector, context).each(function() {
$(this).on('click', function() {
let $parent = $(this).parent(),
$avatar = $parent.parent().siblings('img');
swal({
title: $parent.siblings().first().html(),
html: $(this).next('.hidden').html(),
imageUrl: $avatar.attr('src'),
imageAlt: $avatar.attr('alt'),
imageWidth: $avatar.attr('width'),
imageHeight: $avatar.attr('height')
});
});
});
};
aps.augmentation.register(null);
aps.charts.draw = function() {
$(aps.charts.selector).each(function() {
let data = {
datasets: [],
labels: []
};
$(this).siblings('.hidden').each(function(i) {
data.datasets[i] = {
backgroundColor: [],
data: []
};
$(this).children().each(function() {
data.datasets[i].data.push($(this).data(aps.charts.data.value));
let colour = $(this).data(aps.charts.data.colour),
border = $(this).data(aps.charts.data.border),
point = $(this).data(aps.charts.data.point),
label = $(this).data(aps.charts.data.label),
labels = $(this).data(aps.charts.data.labels);
if (aps.defined(colour)) {
data.datasets[i].backgroundColor.push(colour);
data.datasets[i].fill = colour;
}
if (aps.defined(border)) {
data.datasets[i].borderColor = colour;
data.datasets[i].pointBorderColor = colour;
}
if (aps.defined(point)) {
data.datasets[i].pointBackgroundColor = point;
}
if (aps.defined(label)) {
data.datasets[i].label = label;
}
if (aps.defined(labels)) {
data.labels.push(labels);
}
});
if (!data.datasets[i].backgroundColor.length) {
data.datasets[i].backgroundColor = palette('tol', data.datasets[i].data.length).map(function(hex) {
return '#' + hex;
});
}
});
new Chart($(this), {
type: $(this).data(aps.charts.data.chart),
data: data,
responsive: true,
maintainAspectRatio: false,
options: {
animation: { duration: $(this).data(aps.charts.data.time) },
legend: { position: 'bottom' }
}
});
});
};
/**
* Register a chart plugin.
* This plugin checks for empty charts.
* If the chart is empty, the canvas' data-aps-empty is displayed instead.
*/
Chart.plugins.register({
afterDraw: function(chart) {
if (!chart.config.data.datasets[0].data.length) {
let ctx = chart.chart.ctx,
width = chart.chart.width,
height = chart.chart.height;
chart.clear();
ctx.save();
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(chart.canvas.dataset.apsEmpty, width / 2, height / 2);
ctx.restore();
}
}
});
/**
* Add a "fake" timeout to the Chart drawing animation,
* otherwise the animation does not show up.
*/
setTimeout(aps.charts.draw, 0);
phpbb.addAjaxCallback('aps_add', function(r) {
if (r.success) {
$(this).parent('li').remove();
let panel = $(r.success).insertBefore(aps.empty, null);
aps.ajaxify(panel);
aps.add.pulse();
aps.charts.draw();
aps.body.trigger('click');
aps.message(r.APS_TITLE, r.APS_TEXT);
}
});
phpbb.addAjaxCallback('aps_remove', function(r) {
if (r.success) {
$(this).parents(aps.classes.column).remove();
let item = aps.add.el.find(aps.add.content).append(r.success);
aps.ajaxify(item);
aps.add.pulse();
aps.message(r.APS_TITLE, r.APS_TEXT);
}
});
phpbb.addAjaxCallback('aps_replace', function(r) {
let $old = $(this).parents(aps.classes.panel),
$new = $(r.body);
$old.find(aps.classes.content).html($new.find(aps.classes.content));
$old.find(aps.classes.pagination).html($new.find(aps.classes.pagination));
aps.augmentation.register($old);
});
});

View File

@@ -0,0 +1,23 @@
jQuery(function($) {
let $action = $('#action'),
$points = $('#points'),
$reason = $('#reason');
let apsChangeAction = function() {
let $selected = $(this).find(':selected'),
points = $selected.data('points'),
reason = $selected.data('reason');
if (points || $selected.context === undefined) {
$points.prop('disabled', 'disabled').val(points);
$reason.prop('disabled', 'disabled').val(reason);
} else {
$points.prop('disabled', false).val('');
$reason.prop('disabled', false).val('');
}
};
apsChangeAction();
$action.on('change', apsChangeAction);
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,81 @@
{% include 'mcp_header.html' %}
<h2>{{ lang('MCP_APS_POINTS_CHANGE', aps_name()) }}</h2>
<form id="mcp_aps_change" name="mcp_aps_change" method="post" action="{{ U_APS_ACTION }}">
{% if S_APS_SEARCH %}
{% include '@phpbbstudio_aps/mcp/mcp_aps_find_username.html' %}
{% else %}
{% INCLUDEJS '@phpbbstudio_aps/js/aps_mcp.js' %}
{% if S_APS_LOGS %}
<div class="panel">
<div class="inner">
{% include '@phpbbstudio_aps/mcp/mcp_aps_logs_list.html' with {'logs_array': logs} %}
</div>
</div>
{% endif %}
<div class="panel">
<div class="inner">
<fieldset>
{% if APS_USERNAME %}
<dl>
<dt><strong>{{ lang('USERNAME') ~ lang('COLON') }}</strong></dt>
<dd>{{ APS_USERNAME }}</dd>
</dl>
<dl>
<dt><strong>{{ aps_name() ~ lang('COLON') }}</strong></dt>
<dd>{{ APS_POINTS }}</dd>
</dl>
{% else %}
<dl>
<dt><strong>{{ lang('GROUP') ~ lang('COLON') }}</strong></dt>
<dd>{{ APS_GROUP }}</dd>
</dl>
{% endif %}
<dl>
<dt>
<label for="action">
{{ lang('MCP_APS_POINTS_CHANGE', aps_name()) ~ lang('COLON') }}
</label>
</dt>
<dd>
<select id="action" name="action">
<option value="" data-points="true">{{ lang('SELECT_OPTION') }}</option>
{% if S_APS_REASON %}
{% for reason in APS_REASONS %}
{% if loop.first and S_APS_CUSTOM %}<optgroup label="{{ lang('REASON') }}">{% endif %}
<option value="{{ reason.reason_id }}" data-points="{{ aps_format(reason.reason_points) }}" data-reason="{{ reason.reason_desc|e }}">
{{ reason.reason_title }}
</option>
{% if loop.last and S_APS_CUSTOM %}</optgroup>{% endif %}
{% endfor %}
{% endif %}
{% if S_APS_CUSTOM %}
{% if S_APS_REASON %}<optgroup label="{{ lang('ACTION') }}">{% endif %}
{% for action, title in APS_ACTIONS %}
<option value="{{ action }}" data-points="false">{{ title }}</option>
{% endfor %}
{% if S_APS_REASON %}</optgroup>{% endif %}
{% endif %}
</select>
<input id="points" name="points" type="number" step="{{ aps_step() }}" class="tiny" placeholder="{{ aps_format(0.00) }}"><br>
<input id="reason" name="reason" type="text" class="full" placeholder="{{ lang('REASON') }}">
</dd>
</dl>
</fieldset>
</div>
</div>
<fieldset class="submit-buttons">
<input class="button1" id="submit" name="submit" type="submit" value="{{ lang('SUBMIT') }}" />
&nbsp;
<input class="button2" id="reset" name="reset" type="reset" value="{{ lang('RESET') }}" />
{{ S_FORM_TOKEN }}
</fieldset>
{% endif %}
</form>
{% include 'mcp_footer.html' %}

View File

@@ -0,0 +1,42 @@
{% INCLUDECSS '@phpbbstudio_aps/aps_display.css' %}
<div class="panel">
<div class="inner">
{% if S_ERROR %}
<fieldset>
<p class="error">{{ ERROR_MSG }}</p>
</fieldset>
{% endif %}
<fieldset>
<dl>
<dt><label for="username">{{ lang('SELECT_USER') ~ lang('COLON') }}</label></dt>
<dd><input class="inputbox" id="username" name="username" type="text" value="{{ APS_USERNAME }}" /></dd>
<dd>[ <a href="{{ U_APS_SEARCH }}" onclick="find_username(this.href); return false;">{{ lang('FIND_USERNAME') }}</a> ]</dd>
</dl>
</fieldset>
<fieldset class="submit-buttons">
<input class="button1" id="submit_user" name="submit_user" type="submit" value="{{ lang('SUBMIT') }}" />
&nbsp;
<input class="button2" id="reset_user" type="reset" value="{{ lang('RESET') }}" />
</fieldset>
<hr class="aps-mar-top aps-mar-bot">
<fieldset>
<dl>
<dt><label for="group_id">{{ lang('SELECT_GROUP') ~ lang('COLON') }}</label></dt>
<dd><select class="inputbox" id="group_id" name="group_id">{{ APS_GROUPS }}</select></dd>
</dl>
</fieldset>
<fieldset class="submit-buttons">
<input class="button1" id="submit_group" name="submit_group" type="submit" value="{{ lang('SUBMIT') }}" />
&nbsp;
<input class="button2" id="reset_group" type="reset" value="{{ lang('RESET') }}" />
</fieldset>
{{ S_FORM_TOKEN }}
</div>
</div>

View File

@@ -0,0 +1,56 @@
{% include 'mcp_header.html' %}
<h2>{{ lang('MAIN') }}</h2>
{% EVENT phpbbstudio_aps_mcp_front_before %}
{% if S_APS_LOGS %}
<div class="panel">
<div class="inner">
<h3>{{ lang('LATEST_LOGS') }}</h3>
{% include '@phpbbstudio_aps/mcp/mcp_aps_logs_list.html' with {'logs_array': logs} %}
</div>
</div>
{% EVENT phpbbstudio_aps_mcp_front_between_logs %}
<div class="panel">
<div class="inner">
<h3>{{ lang('MCP_APS_LATEST_ADJUSTED', 5) }}</h3>
{% include '@phpbbstudio_aps/mcp/mcp_aps_logs_list.html' with {'logs_array': moderated} %}
</div>
</div>
{% endif %}
{% EVENT phpbbstudio_aps_mcp_front_between %}
<div class="panel">
<div class="inner">
<div class="column1">
<h3>{{ lang('MCP_APS_USERS_TOP', 5) }}</h3>
<ul class="fa-ul">
{% for user in aps_users_top %}
<li><em class="small">{{ loop.index }}.</em> {{ aps_display(user.POINTS) }} {{ user.NAME }}</li>
{% else %}
<li><strong>{{ lang('NO_ONLINE_USERS') }}</strong></li>
{% endfor %}
</ul>
</div>
<div class="column2">
<h3>{{ lang('MCP_APS_USERS_BOTTOM', 5) }}</h3>
<ul class="fa-ul">
{% for user in aps_users_bottom %}
<li><em class="small">{{ loop.index }}.</em> {{ aps_display(user.POINTS) }} {{ user.NAME }}</li>
{% else %}
<li><strong>{{ lang('NO_ONLINE_USERS') }}</strong></li>
{% endfor %}
</ul>
</div>
</div>
</div>
{% EVENT phpbbstudio_aps_mcp_front_after %}
{% include 'mcp_footer.html' %}

View File

@@ -0,0 +1,40 @@
{% include 'mcp_header.html' %}
<h2>{{ lang('MCP_APS_LOGS') }}</h2>
<div class="panel">
<div class="inner">
<form id="aps_logs" name="aps_logs" action="{{ U_ACTION }}" method="post">
<fieldset class="display-options search-box">
<label for="keywords">
{{ lang('SEARCH_KEYWORDS') ~ lang('COLON') }}
</label>
<input type="text" id="keywords" name="keywords" value="{{ S_KEYWORDS }}" />&nbsp;
<input type="submit" class="button2" name="filter" value="{{ lang('SEARCH') }}" />
</fieldset>
{% if pagination %}
<div class="pagination top-pagination">
{% include 'pagination.html' %}
</div>
{% endif %}
{% include '@phpbbstudio_aps/mcp/mcp_aps_logs_list.html' with {'logs_array': logs} %}
{% if pagination %}
<div class="pagination">
{% include 'pagination.html' %}
</div>
{% endif %}
<fieldset class="display-options">
{{ lang('DISPLAY_LOG') ~ lang('COLON') }} {{ S_LIMIT_DAYS }} &nbsp;
{{ lang('SORT_BY') ~ lang('COLON') }} {{ S_SORT_KEY }} {{ S_SORT_DIR }}
<input class="button2" type="submit" value="{{ lang('GO') }}" name="sort" />
{{ S_FORM_TOKEN }}
</fieldset>
</form>
</div>
</div>
{% include 'mcp_footer.html' %}

View File

@@ -0,0 +1,38 @@
<table class="table1">
<thead>
<tr>
<th class="name"><i class="icon fa-user fa-fw"></i></th>
<th class="name">{{ lang('REASON') }}</th>
<th class="name"><i class="icon fa-clock-o fa-fw"></i></th>
<th class="name"><i class="icon fa-sign-out fa-fw"></i></th>
<th class="name"><i class="icon fa-arrow-right fa-fw"></i></th>
<th class="name"><i class="icon fa-sign-in fa-fw"></i></th>
<th class="name"><i class="icon fa-comments fa-fw"></i></th>
</tr>
</thead>
<tbody>
{% for log in logs_array %}
<tr class="bg{{ loop.index is odd ? 1 : 2 }}">
<td>{{ log.USER }}</td>
<td>
<strong>{{ lang(log.ACTION, aps_name()) }}</strong>
{% if not log.S_SELF and log.REPORTEE %}<br>&raquo; {{ lang('FROM') ~ ' ' ~ log.REPORTEE }}{% endif %}
</td>
<td>{{ user.format_date(log.TIME) }}</td>
<td>{{ aps_display(log.POINTS_OLD, false) }}</td>
<td>{{ aps_display(log.POINTS_SUM, false) }}</td>
<td>{{ aps_display(log.POINTS_NEW, false) }}</td>
<td>
{% if log.FORUM_NAME %}&raquo; <a href="{{ log.U_FORUM }}" title="{{ lang('FORUM') }}">{{ log.FORUM_NAME }}</a><br />{% endif %}
{% if log.TOPIC_TITLE %}&raquo; <a href="{{ log.U_TOPIC }}" title="{{ lang('TOPIC') }}">{{ log.TOPIC_TITLE }}</a><br />{% endif %}
{% if log.POST_SUBJECT %}&raquo; <a href="{{ log.U_POST }}" title="{{ lang('POST') }}">{{ log.POST_SUBJECT }}</a><br />{% endif %}
{% if not log.FORUM_NAME and not log.TOPIC_TITLE and not log.POST_SUBJECT %}{{ lang('NA') }}{% endif %}
</td>
</tr>
{% else %}
<tr>
<td class="center" colspan="7"><span class="error">{{ lang('NO_ENTRIES') }}</span></td>
</tr>
{% endfor %}
</tbody>
</table>

View File

@@ -0,0 +1,738 @@
/* Colours and border radius */
:root {
--white: #ffffff;
--white-darken-1: #f9f9f9;
--white-darken-2: #fefefe;
--white-darken-3: #ebedf2;
--white-darken-4: #ececec;
--white-darken-5: #e0e0e0;
--white-darken-6: #c9c9c9;
--blue: #12a3eb;
--blue-darken-1: #0076b1;
--border-radius-style: 7px;
--border-radius-aps-panels: 4px;
}
/* Helpers */
.nojs .aps-js { display: none; }
.aps-block { display: block; }
.aps-inline { display: inline-block; }
.aps-relative { position: relative; }
.aps-center { text-align: center; }
.aps-bold { font-weight: bold; }
.aps-italic { font-style: italic; }
.aps-cursor-normal { cursor: auto; }
.aps-cursor-banned { cursor: not-allowed; }
.aps-cursor-pointer { cursor: pointer; }
.aps-cursor-help { cursor: help; }
.aps-mar-top { margin-top: 16px; }
.aps-mar-bot { margin-bottom: 16px; }
.aps-mar-left { margin-left: 16px; }
.aps-mar-right { margin-right: 16px; }
.aps-no-mar { margin: 0 !important; }
.aps-no-mar-bot { margin-bottom: 0 !important; }
.aps-no-mar-top { margin-top: 0 !important; }
.aps-no-mar-left { margin-left: 0 !important; }
.aps-no-mar-right { margin-right: 0 !important; }
.aps-no-mar-edge {
margin-top: 0;
margin-bottom: 0;
}
.aps-no-mar-side {
margin-right: 0;
margin-left: 0;
}
.aps-no-padding { padding: 0 !important; }
.aps-padding { padding: 8px 16px; }
.aps-padding-edge {
padding-top: 8px;
padding-bottom: 8px;
}
.aps-padding-side {
padding-right: 16px;
padding-left: 16px;
}
.aps-ellipsis,
.aps-ellipsis * {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.aps-positive,
.aps-negative { font-weight: bold; }
.aps-positive { color: #28a745; }
.aps-negative { color: #d31141; }
.aps-podium-0 { color: #313131; }
.aps-podium-1 { color: #d6af36; }
.aps-podium-2 { color: #a7a7ad; }
.aps-podium-3 { color: #824a02; }
.aps-main,
.aps-main *,
.aps-main *:after,
.aps-main *:before {
box-sizing: border-box;
}
.aps-main {
font-size: 13px;
font-weight: 300;
line-height: 1.5;
background: var(--white-darken-1);
border-radius: var(--border-radius-style);
color: #212529;
position: relative;
z-index: 0;
margin: 10px 0;
}
.aps-footer {
font-size: 0.9em;
text-align: right;
background: var(--white);
border-bottom-right-radius: var(--border-radius-style);
border-bottom-left-radius: var(--border-radius-style);
-webkit-box-shadow: 0 1px 15px 1px rgba(69, 65, 78, 0.1);
box-shadow: 0 1px 15px 1px rgba(69, 65, 78, 0.1);
color: #999999;
padding: 8px 16px;
}
.aps-footer i {
font-size: 0.9em;
color: var(--blue);
}
.aps-footer a {
color: #999999;
}
.aps-footer a:hover {
color: #313131;
text-decoration-color: var(--blue);
}
.aps-nav {
border-bottom: 1px solid var(--blue-darken-1);
border-radius: 0;
margin: 0;
padding: 0;
}
.aps-menu {
background: var(--white);
border-top-left-radius: var(--border-radius-style);
border-top-right-radius: var(--border-radius-style);
-webkit-box-shadow: 0 1px 15px 1px rgba(69, 65, 78, 0.1);
box-shadow: 0 1px 15px 1px rgba(69, 65, 78, 0.1);
position: relative;
z-index: 1;
}
.aps-menu-before {
line-height: 48px;
text-align: center;
width: 32px;
height: 48px;
margin-left: 8px;
}
.aps-menu-icon {
line-height: 56px;
text-align: center;
background: linear-gradient(var(--white-darken-2), var(--white) 75%);
position: absolute;
z-index: 2;
top: 0;
left: 56px;
display: inline-block;
width: 64px;
height: 56px;
}
.aps-menu-icon > div {
width: 48px;
margin: 0 8px;
}
.aps-menu-icon > div:after,
.aps-menu-icon > div:before,
.aps-menu-icon:after,
.aps-menu-icon:before {
background: inherit;
position: absolute;
z-index: -2;
top: 0;
right: -12px;
width: 100%;
height: 56px;
content: "";
-webkit-transform: skewX(-10deg);
-moz-transform: skewX(-10deg);
-ms-transform: skewX(-10deg);
transform: skewX(-10deg);
}
.aps-menu-icon:after {
border-right: 1px solid var(--white-darken-1);
-webkit-box-shadow: 1px 0 0 rgba(69, 65, 78, 0.1);
box-shadow: 1px 0 0 rgba(69, 65, 78, 0.1);
}
.aps-menu-icon:before {
border-left: 1px solid var(--white-darken-1);
-webkit-box-shadow: -1px 0 0 rgba(69, 65, 78, 0.1);
box-shadow: -1px 0 0 rgba(69, 65, 78, 0.1);
right: unset;
left: -12px;
-webkit-transform: skewX(10deg);
-moz-transform: skewX(10deg);
-ms-transform: skewX(10deg);
transform: skewX(10deg);
}
.aps-menu-icon > div:after {
border-right: 1px solid var(--white-darken-4);
-webkit-box-shadow: 2px 0 0 rgba(69, 65, 78, 0.05);
box-shadow: 2px 0 0 rgba(69, 65, 78, 0.05);
z-index: -1;
right: -4px;
-webkit-transform: skewX(-7deg);
-moz-transform: skewX(-7deg);
-ms-transform: skewX(-7deg);
transform: skewX(-7deg);
}
.aps-menu-icon > div:before {
border-left: 1px solid var(--white-darken-4);
-webkit-box-shadow: -2px 0 0 rgba(69, 65, 78, 0.05);
box-shadow: -2px 0 0 rgba(69, 65, 78, 0.05);
z-index: -1;
right: unset;
left: -4px;
-webkit-transform: skewX(7deg);
-moz-transform: skewX(7deg);
-ms-transform: skewX(7deg);
transform: skewX(7deg);
}
.aps-menu-icon:after,
.aps-menu-icon:before {
height: 52px;
}
.aps-menu-icon i {
font-size: 32px;
vertical-align: -6px;
-webkit-background-clip: text;
-moz-background-clip: text;
background-clip: text;
border: none;
text-shadow: 2px 2px 3px rgba(255, 255, 255, 0.5);
color: transparent;
}
.aps-lists-container {
display: flex;
flex-flow: row nowrap;
}
.aps-lists-container > .aps-list {
flex: 1 1 auto;
}
.aps-lists-container > .aps-list-right {
flex-basis: 0;
}
.aps-list {
display: flex;
justify-content: flex-start;
align-items: stretch;
list-style: none;
align-content: flex-start;
flex-flow: row wrap;
}
.aps-list-right {
justify-content: flex-end;
}
.aps-list > li {
flex: 0 1 auto;
}
.aps-list-item {
line-height: 48px;
text-align: center;
white-space: nowrap;
text-decoration: none;
display: block;
min-width: 64px;
height: 48px;
padding: 0 16px;
}
.aps-menu > .aps-list:not(.aps-list-right) > :first-child {
margin-left: 89px;
}
.aps-menu .aps-list-item {
font-weight: bold;
text-decoration: none;
color: var(--blue-darken-1);
position: relative;
padding: 0 16px 0 24px;
}
.aps-menu .aps-list-item:hover {
text-decoration: none;
color: var(--blue);
}
.aps-menu .aps-list-item:not(.aps-list-active) i {
transition: all 0.2s ease-in-out;
}
.aps-menu .aps-list-item:not(.aps-list-active):hover i {
font-size: 1.2em;
}
.aps-menu .aps-list-item:after {
border-right: 1px solid var(--white-darken-4);
border-left: 1px solid var(--white-darken-4);
-webkit-box-shadow: 0 1px 15px 1px rgba(69, 65, 78, 0.08);
box-shadow: 0 1px 15px 1px rgba(69, 65, 78, 0.08);
position: absolute;
z-index: -1;
top: 0;
right: -4px;
width: 100%;
height: 100%;
content: "";
-webkit-transform: skewX(-10deg);
-moz-transform: skewX(-10deg);
-ms-transform: skewX(-10deg);
transform: skewX(-10deg);
}
.aps-menu .aps-list-active {
margin-right: 2px;
}
.aps-menu .aps-list-active:after {
border-color: var(--blue-darken-1);
-webkit-box-shadow: 5px 1px 8px 1px rgba(69, 65, 78, 0.08), -5px 1px 8px 1px rgba(69, 65, 78, 0.08);
box-shadow: 5px 1px 8px 1px rgba(69, 65, 78, 0.08), -5px 1px 8px 1px rgba(69, 65, 78, 0.08);
}
.aps-menu .aps-list-item > span {
display: none;
}
@media only screen and (min-width: 601px) {
.aps-menu .aps-list-active > span {
display: inline-block;
}
}
@media only screen and (max-width: 600px) {
.aps-menu {
flex-flow: row wrap;
}
.aps-menu .aps-list:not(.aps-list-right) {
flex-basis: 100%;
order: 1;
}
.aps-menu > .aps-list:not(.aps-list-right) > :first-child {
margin-left: 0;
}
}
.aps-menu .aps-list-right > li:last-child .aps-list-item {
background: var(--white);
border-top-right-radius: var(--border-radius-style);
}
.aps-menu .aps-list-right > li:last-child .aps-list-item:after {
border-right: none;
border-left-color: var(--blue-darken-1);
right: unset;
left: -5px;
}
.aps-nav .aps-list-item {
text-decoration: none;
color: #ececec;
}
.aps-nav .aps-list-item:hover {
text-decoration: none;
color: #ffffff;
}
.aps-nav .aps-list-active {
font-weight: bold;
text-shadow: 1px 1px 1px var(--blue);
color: #ffffff;
}
.aps-body {
margin: 6px;
padding: 15px;
}
.aps-panel-placeholder,
.aps-panel {
background-color: var(--white);
border: 1px solid var(--white-darken-4);
border-radius: var(--border-radius-aps-panels);
-webkit-box-shadow: 0 1px 15px 1px rgba(69, 65, 78, 0.08);
box-shadow: 0 1px 15px 1px rgba(69, 65, 78, 0.08);
position: relative;
}
.aps-panel-header,
.aps-panel-content,
.aps-panel-footer {
position: relative;
padding: 8px 10px;
}
.aps-panel-header,
.aps-panel-footer {
background: var(--white-darken-2);
}
.aps-panel-header {
border-bottom: 1px solid var(--white-darken-3);
border-top-left-radius: inherit;
border-top-right-radius: inherit;
}
.aps-panel-header > h3 {
font-weight: bold;
letter-spacing: 0.05rem;
text-transform: none;
border: none;
color: #333333;
display: inline-block;
margin: 0;
padding: 0;
}
.aps-panel-footer {
border-top: 1px solid var(--white-darken-3);
border-bottom-right-radius: inherit;
border-bottom-left-radius: inherit;
}
.aps-panel-footer,
.aps-panel-footer label {
color: #999999;
}
.aps-panel-content {
color: #7b7e8a;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
max-height: 500px;
-ms-overflow-style: -ms-autohiding-scrollbar;
scrollbar-color: rgba(0, 0, 0, 0.4) transparent;
scrollbar-width: 4px;
}
.aps-panel-action,
a.aps-panel-action {
color: #999999;
float: right;
margin-right: 5px;
cursor: pointer;
}
.aps-panel-delete:hover {
color: #d31141;
}
.aps-panel-move:hover {
color: var(--blue);
cursor: grab;
}
.aps-panel-add {
padding: 0 12px;
}
.aps-panel-add-pulse,
.aps-panel-add .aps-panel-action:hover {
color: #28a745;
}
.aps-panel-add .aps-button-red {
display: inline-block;
margin: 5px;
cursor: not-allowed;
}
.aps-panel-add li {
margin: 5px;
}
.aps-body > .aps-row > .aps-panel-empty,
.aps-panel-add .aps-panel-empty {
display: none;
}
.aps-panel-add .aps-panel-empty:only-child {
display: list-item;
}
.aps-panel-add > .dropdown {
margin-top: 16px;
}
.aps-panel-add > .dropdown > .pointer {
right: 22px;
}
.aps-body > .aps-row > .aps-panel-empty:only-child {
display: block;
}
.aps-panel-placeholder {
background: var(--white-darken-5);
border: 1px dashed var(--white-darken-6);
}
.aps-panel-content::-webkit-scrollbar { width: 6px; }
.aps-panel-content::-webkit-scrollbar-track { background: transparent; }
.aps-panel-content::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.4);
border-radius: 4px;
}
.aps-panel-add-pulse {
box-shadow: 0 0 0 #28a745; /* same as rgba(40, 167, 69) below */
animation: pulse 1.5s infinite;
}
.aps-panel-add-pulse:hover {
animation: none;
}
.aps-panel-add-pulse i {
padding-left: 3px;
}
@keyframes pulse {
0% {
-moz-box-shadow: 0 0 0 0 rgba(40, 167, 69, 0.4);
box-shadow: 0 0 0 0 rgba(40, 167, 69, 0.4);
}
70% {
-moz-box-shadow: 0 0 0 10px rgba(40, 167, 69, 0);
box-shadow: 0 0 0 10px rgba(40, 167, 69, 0);
}
100% {
-moz-box-shadow: 0 0 0 0 rgba(40, 167, 69, 0);
box-shadow: 0 0 0 0 rgba(40, 167, 69, 0);
}
}
/**
* Materialize collections
*/
.aps-collection {
border: 1px solid var(--white-darken-5);
border-radius: var(--border-radius-aps-panels);
position: relative;
overflow: hidden;
margin: 0.5rem 0 1rem;
}
.aps-collection .aps-collection-item {
line-height: 1.5rem;
background-color: var(--white);
border-bottom: 1px solid var(--white-darken-5);
margin: 0;
padding: 10px 20px;
}
.aps-collection .aps-collection-item.aps-avatar {
position: relative;
min-height: 64px;
padding-left: 72px;
}
.aps-collection .aps-collection-item.aps-avatar .avatar {
vertical-align: middle;
position: absolute;
left: 15px;
display: inline-block;
overflow: hidden;
width: 42px;
height: 42px;
}
.aps-collection .aps-collection-item.aps-avatar i.circle {
font-size: 18px;
line-height: 42px;
text-align: center;
background-color: #999999;
color: #ffffff;
}
.aps-collection .aps-collection-item.aps-avatar .title {
font-size: 16px;
}
.aps-collection .aps-collection-item.aps-avatar p {
margin: 0;
}
.aps-collection .aps-collection-item.aps-avatar .aps-secondary-content {
position: absolute;
top: 16px;
right: 16px;
}
.aps-collection .aps-collection-item:last-child {
border-bottom: none;
}
.aps-collection .aps-collection-item.active {
background-color: #26a69a;
color: #eafaf9;
}
.aps-collection .aps-collection-item.active .secondary-content {
color: #ffffff;
}
.aps-collection a.aps-collection-item {
display: block;
-webkit-transition: 0.25s;
transition: 0.25s;
}
.aps-collection a.aps-collection-item:not(.active):hover {
background-color: #dddddd;
}
.aps-collection.aps-with-header .aps-collection-header {
background-color: #ffffff;
border-bottom: 1px solid #e0e0e0;
padding: 10px 20px;
}
.aps-collection.aps-with-header .aps-collection-item {
padding-left: 30px;
}
.aps-collection.aps-with-header .aps-collection-item.aps-avatar {
padding-left: 72px;
}
.aps-row {
display: flex;
justify-content: space-between;
align-items: flex-start;
align-content: flex-start;
flex-flow: row wrap;
}
.aps-col {
flex: 0 auto;
min-height: 1px;
margin-bottom: 1.25rem;
padding: 0 0.75rem;
}
.aps-col.s1 { flex-basis: calc(100% / 12); }
.aps-col.s2 { flex-basis: calc(100% / 12 * 2); }
.aps-col.s3 { flex-basis: 25%; }
.aps-col.s4 { flex-basis: calc(100% / 12 * 4); }
.aps-col.s5 { flex-basis: calc(100% / 12 * 5); }
.aps-col.s6 { flex-basis: 50%; }
.aps-col.s7 { flex-basis: calc(100% / 12 * 7); }
.aps-col.s8 { flex-basis: calc(100% / 12 * 8); }
.aps-col.s9 { flex-basis: 75%; }
.aps-col.s10 { flex-basis: calc(100% / 12 * 10); }
.aps-col.s11 { flex-basis: calc(100% / 12 * 11); }
.aps-col.s12 { flex-basis: 100%; }
.aps-hide-s { display: none; }
@media only screen and (min-width: 601px) {
.aps-col.m1 { flex-basis: calc(100% / 12); }
.aps-col.m2 { flex-basis: calc(100% / 12 * 2); }
.aps-col.m3 { flex-basis: 25%; }
.aps-col.m4 { flex-basis: calc(100% / 12 * 4); }
.aps-col.m5 { flex-basis: calc(100% / 12 * 5); }
.aps-col.m6 { flex-basis: 50%; }
.aps-col.m7 { flex-basis: calc(100% / 12 * 7); }
.aps-col.m8 { flex-basis: calc(100% / 12 * 8); }
.aps-col.m9 { flex-basis: 75%; }
.aps-col.m10 { flex-basis: calc(100% / 12 * 10); }
.aps-col.m11 { flex-basis: calc(100% / 12 * 11); }
.aps-col.m12 { flex-basis: 100%; }
.aps-hide-s { display: block; }
.aps-hide-m { display: none; }
}
@media only screen and (min-width: 993px) {
.aps-col.l1 { flex-basis: calc(100% / 12); }
.aps-col.l2 { flex-basis: calc(100% / 12 * 2); }
.aps-col.l3 { flex-basis: 25%; }
.aps-col.l4 { flex-basis: calc(100% / 12 * 4); }
.aps-col.l5 { flex-basis: calc(100% / 12 * 5); }
.aps-col.l6 { flex-basis: 50%; }
.aps-col.l7 { flex-basis: calc(100% / 12 * 7); }
.aps-col.l8 { flex-basis: calc(100% / 12 * 8); }
.aps-col.l9 { flex-basis: 75%; }
.aps-col.l10 { flex-basis: calc(100% / 12 * 10); }
.aps-col.l11 { flex-basis: calc(100% / 12 * 11); }
.aps-col.l12 { flex-basis: 100%; }
.aps-hide-m { display: block; }
.aps-hide-l { display: none; }
}
@media only screen and (min-width: 1201px) {
.aps-col.xl1 { flex-basis: calc(100% / 12); }
.aps-col.xl2 { flex-basis: calc(100% / 12 * 2); }
.aps-col.xl3 { flex-basis: 25%; }
.aps-col.xl4 { flex-basis: calc(100% / 12 * 4); }
.aps-col.xl5 { flex-basis: calc(100% / 12 * 5); }
.aps-col.xl6 { flex-basis: 50%; }
.aps-col.xl7 { flex-basis: calc(100% / 12 * 7); }
.aps-col.xl8 { flex-basis: calc(100% / 12 * 8); }
.aps-col.xl9 { flex-basis: 75%; }
.aps-col.xl10 { flex-basis: calc(100% / 12 * 10); }
.aps-col.xl11 { flex-basis: calc(100% / 12 * 11); }
.aps-col.xl12 { flex-basis: 100%; }
.aps-hide-l { display: block; }
.aps-hide-xl { display: none; }
}

View File

@@ -0,0 +1,184 @@
.aps-form *,
.aps-form *:before,
.aps-form *:after {
box-sizing: border-box;
}
.aps-radio { display: none; }
.aps-radio:checked + .aps-button-blue {
background: #12a3eb;
border-color: #12a3eb;
color: #ffffff;
}
/* Fix for double borders due to border-box */
.aps-form dt {
border-right: none;
}
.aps-form dd,
.aps-form dd label {
font-size: 14px;
line-height: 1.42857143;
}
.aps-form dd label {
display: inline-block;
height: 34px;
padding: 6px;
}
.aps-form dd label input[type="radio"] {
height: initial;
margin-right: 3px;
}
.aps-button-red,
.aps-button-blue,
.aps-button-green,
.aps-form input:not(.iconpicker-search),
.aps-form select,
.aps-form textarea {
font-size: 14px;
line-height: 1.42857143;
color: #555555;
height: 34px;
padding: 6px 12px;
}
.aps-button-red,
.aps-button-blue,
.aps-button-green,
.aps-form input[type="text"],
.aps-form input[type="number"],
.aps-form input[type="search"],
.aps-form input[type="submit"],
.aps-form input[type="reset"],
.aps-form select,
.aps-form textarea {
background-color: #ffffff;
background-image: none;
border: 1px solid #cccccc;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-sizing: border-box;
-webkit-transition: border-color ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s;
-o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
}
.aps-form input:not([type="checkbox"]):not([type="radio"]):focus,
.aps-form select:focus,
.aps-form textarea:focus {
border-color: #66afe9;
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
}
.aps-form select:focus {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.aps-form select[multiple] {
height: auto;
min-height: 170px;
}
.has-js select[multiple] {
max-height: 340px;
}
.aps-form textarea {
height: auto;
resize: vertical;
}
/* Buttons */
.aps-button-green,
a.aps-button-green,
.aps-form input[type="submit"] {
border-color: #28a745;
color: #28a745;
}
.aps-button-green:hover,
a.aps-button-green:hover,
.aps-button-green.aps-button-active,
.aps-form input[type="submit"]:hover {
background-color: #28a745;
color: #ffffff;
}
.aps-button-red,
a.aps-button-red,
.aps-form input[type="reset"],
.aps-form input[name="cancel"] {
border-color: #d31141;
color: #d31141;
}
.aps-button-red:hover,
a.aps-button-red:hover,
.aps-button-red.aps-button-active,
.aps-form input[type="reset"]:hover,
.aps-form input[name="cancel"]:hover {
background-color: #d31141;
color: #ffffff;
}
.aps-button-blue {
border-color: #12a3eb;
color: #12a3eb;
}
.aps-button-blue:hover,
.aps-button-blue.aps-button-active {
background-color: #12a3eb;
color: #ffffff;
}
[class*="aps-button-"] .caret {
padding-left: 6px;
}
[class*="aps-button-"]:hover .caret {
border-color: #ffffff;
}
.aps-button-red,
.aps-button-blue,
.aps-button-green {
text-decoration: none !important;
cursor: pointer;
}
/* Form dropdown(s) */
.aps-form .dropdown-container {
vertical-align: -2px;
display: inline-block;
float: none;
}
/* Multiple select scrollbar */
.aps-form select[multiple] {
scrollbar-color: #666666 #cccccc;
scrollbar-width: 10px;
}
.aps-form select[multiple]::-webkit-scrollbar {
width: 10px;
}
.aps-form select[multiple]::-webkit-scrollbar-thumb {
background: #666666;
border-radius: 0 4px 4px 0;
}
.aps-form select[multiple]::-webkit-scrollbar-track {
background: #cccccc;
border-radius: 0 4px 4px 0;
}