mirror of
https://github.com/aljazceru/CTFd.git
synced 2026-02-11 01:04:30 +01:00
Squashed 'CTFd/themes/core-beta/' changes from 9126d77d..5ce3003b
5ce3003b Merge pull request #47 from aCursedComrade/patch-1 c9887cb1 Fix team template git-subtree-dir: CTFd/themes/core-beta git-subtree-split: 5ce3003b4d68352e629ee2d390bc999e7d6b071e
This commit is contained in:
213
templates/users/private.html
Normal file
213
templates/users/private.html
Normal file
@@ -0,0 +1,213 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="jumbotron">
|
||||
<div class="container">
|
||||
<h1>{{ user.name }}</h1>
|
||||
|
||||
{% if user.team_id %}
|
||||
<h2>
|
||||
<a href="{{ url_for('teams.public', team_id=user.team_id) }}">
|
||||
<span class="badge bg-secondary">
|
||||
{{ user.team.name }}
|
||||
</span>
|
||||
</a>
|
||||
</h2>
|
||||
{% endif %}
|
||||
|
||||
<div class="pt-2">
|
||||
{% if user.oauth_id %}
|
||||
<a href="https://majorleaguecyber.org/u/{{ user.name }}">
|
||||
<h3 class="d-inline-block mx-1"><span class="badge rounded-pill bg-primary">{% trans %}Official{% endtrans %}</span></h3>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if user.affiliation %}
|
||||
<h3 class="d-inline-block mx-1">
|
||||
<span class="badge rounded-pill bg-primary">{{ user.affiliation }}</span>
|
||||
</h3>
|
||||
{% endif %}
|
||||
|
||||
{% if user.country %}
|
||||
<h3 class="d-inline-block mx-1">
|
||||
<span class="badge rounded-pill bg-primary">
|
||||
<i class="flag-{{ user.country.lower() }}"></i>
|
||||
{{ lookup_country_code(user.country) }}
|
||||
</span>
|
||||
</h3>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="pt-2">
|
||||
{% for field in user.fields %}
|
||||
<h3 class="d-block">
|
||||
{{ field.name }}: {{ field.value }}
|
||||
</h3>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if user.fields %}
|
||||
<hr class="w-50 mx-auto">
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
<h2 class="text-center">
|
||||
{% if account.place %}
|
||||
{{ account.place }} <small>place</small>
|
||||
{% endif %}
|
||||
</h2>
|
||||
<h2 class="text-center">
|
||||
{% if account.place %}
|
||||
{{ account.score }} <small>points</small>
|
||||
{% endif %}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="pt-3">
|
||||
{% if user.website %}
|
||||
<a href="{{ user.website }}" target="_blank" style="color: inherit;" rel="noopener">
|
||||
<i
|
||||
class="fas fa-external-link-alt fa-2x px-2" data-toggle="tooltip" data-placement="top"
|
||||
title="{{ user.website }}"
|
||||
></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
{% include "components/errors.html" %}
|
||||
|
||||
{% set solves = user.solves %}
|
||||
{% set awards = user.awards %}
|
||||
|
||||
{% if solves or awards %}
|
||||
{% if awards %}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h3>{% trans %}Awards{% endtrans %}</h3>
|
||||
|
||||
</div>
|
||||
{% for award in awards %}
|
||||
<div class="col-md-3 col-sm-6">
|
||||
<p class="text-center">
|
||||
<i class="award-icon award-{{ award.icon }} fa-2x"></i>
|
||||
<br>
|
||||
<strong>{{ award.name }}</strong>
|
||||
</p>
|
||||
<p class="text-center">{{ award.category or "" }}</p>
|
||||
<p class="text-center">{{ award.description or "" }}</p>
|
||||
<p class="text-center">{{ award.value }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<br>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h3>{% trans %}Solves{% endtrans %}</h3>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<td><b>{% trans %}Challenge{% endtrans %}</b></td>
|
||||
<td class="d-none d-md-block d-lg-block"><b>{% trans %}Category{% endtrans %}</b></td>
|
||||
<td><b>{% trans %}Value{% endtrans %}</b></td>
|
||||
<td><b>{% trans %}Time{% endtrans %}</b></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for solve in solves %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{ url_for('challenges.listing') }}#{{ solve.challenge.name }}-{{ solve.challenge.id }}">
|
||||
{{ solve.challenge.name }}
|
||||
</a>
|
||||
</td>
|
||||
<td class="d-none d-md-block d-lg-block">{{ solve.challenge.category }}</td>
|
||||
<td>{{ solve.challenge.value }}</td>
|
||||
<td class="solve-time">
|
||||
<span data-time="{{ solve.date | isoformat }}"></span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div class="row" x-data="UserGraphs">
|
||||
<div class="col-md-6 d-none d-md-block d-lg-block py-4">
|
||||
<div class="progress">
|
||||
<div
|
||||
class="progress-bar"
|
||||
role="progressbar"
|
||||
:style="{ width: `${getSolvePercentage()}%`, 'background-color': 'rgb(0, 209, 64)' }"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="progress-bar"
|
||||
role="progressbar"
|
||||
:style="{ width: `${getFailPercentage()}%`, 'background-color': 'rgb(207, 38, 0)' }"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ps-2 float-start">
|
||||
<svg height="16" width="16">
|
||||
<circle cx="8" cy="8" r="5" fill="rgb(0, 209, 64)" />
|
||||
</svg>
|
||||
<small x-text="`Solves (${getSolvePercentage()}%)`"></small>
|
||||
</div>
|
||||
<div class="ps-2 float-start">
|
||||
<svg height="16" width="16">
|
||||
<circle cx="8" cy="8" r="5" fill="rgb(207, 38, 0)" />
|
||||
</svg>
|
||||
<small x-text="`Fails (${getFailPercentage()}%)`"></small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 d-none d-md-block d-lg-block py-4">
|
||||
<div class="progress">
|
||||
<template x-for="category in getCategoryBreakdown()" :key="category.name">
|
||||
<div
|
||||
class="progress-bar"
|
||||
role="progressbar"
|
||||
:style="{ width: `${category.percent}%`, 'background-color': category.color }"
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<template x-for="category in getCategoryBreakdown()" :key="category.name">
|
||||
<div class="ps-2 float-start">
|
||||
<svg height="16" width="16">
|
||||
<circle cx="8" cy="8" r="5" :fill="category.color" />
|
||||
</svg>
|
||||
<small x-text="`${category.name} (${category.percent}%)`"></small>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<br class="clearfix">
|
||||
<div class="col-md-12 d-none d-md-block d-lg-block py-4">
|
||||
<div id="score-graph" x-ref="scoregraph" class="w-100 d-flex align-items-center">
|
||||
<div class="text-center w-100">
|
||||
<i class="fas fa-circle-notch fa-spin fa-3x fa-fw spinner"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="row min-vh-25">
|
||||
<h3 class="opacity-50 text-center w-100 justify-content-center align-self-center">
|
||||
{% trans %}No solves yet{% endtrans %}
|
||||
</h3>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
{{ Assets.js("assets/js/users/private.js") }}
|
||||
{% endblock %}
|
||||
|
||||
222
templates/users/public.html
Normal file
222
templates/users/public.html
Normal file
@@ -0,0 +1,222 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="jumbotron">
|
||||
<div class="container">
|
||||
<h1>{{ user.name }}</h1>
|
||||
|
||||
{% if user.team_id %}
|
||||
<h2>
|
||||
<a href="{{ url_for('teams.public', team_id=user.team_id) }}">
|
||||
<span class="badge bg-secondary">
|
||||
{{ user.team.name }}
|
||||
</span>
|
||||
</a>
|
||||
</h2>
|
||||
{% endif %}
|
||||
|
||||
<div class="pt-2">
|
||||
{% if user.oauth_id %}
|
||||
<a href="https://majorleaguecyber.org/u/{{ user.name }}">
|
||||
<h3 class="d-inline-block mx-1"><span class="badge rounded-pill bg-primary">{% trans %}Official{% endtrans %}</span></h3>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if user.affiliation %}
|
||||
<h3 class="d-inline-block mx-1">
|
||||
<span class="badge rounded-pill bg-primary">{{ user.affiliation }}</span>
|
||||
</h3>
|
||||
{% endif %}
|
||||
|
||||
{% if user.country %}
|
||||
<h3 class="d-inline-block mx-1">
|
||||
<span class="badge rounded-pill bg-primary">
|
||||
<i class="flag-{{ user.country.lower() }}"></i>
|
||||
{{ lookup_country_code(user.country) }}
|
||||
</span>
|
||||
</h3>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="pt-2">
|
||||
{% for field in user.fields %}
|
||||
<h3 class="d-block">
|
||||
{{ field.name }}: {{ field.value }}
|
||||
</h3>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if user.fields %}
|
||||
<hr class="w-50 mx-auto">
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
<h2 class="text-center">
|
||||
{% if account.place %}
|
||||
{{ account.place }} <small>place</small>
|
||||
{% endif %}
|
||||
</h2>
|
||||
<h2 class="text-center">
|
||||
{% if account.place %}
|
||||
{{ account.score }} <small>points</small>
|
||||
{% endif %}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="pt-3">
|
||||
{% if user.website %}
|
||||
<a href="{{ user.website }}" target="_blank" style="color: inherit;" rel="noopener">
|
||||
<i
|
||||
class="fas fa-external-link-alt fa-2x px-2" data-toggle="tooltip" data-placement="top"
|
||||
title="{{ user.website }}"
|
||||
></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
{% include "components/errors.html" %}
|
||||
|
||||
{% set solves = user.solves %}
|
||||
{% set awards = user.awards %}
|
||||
{% if solves or awards %}
|
||||
|
||||
{% if awards %}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h3>{% trans %}Awards{% endtrans %}</h3>
|
||||
</div>
|
||||
{% for award in awards %}
|
||||
<div class="col-md-3 col-sm-6">
|
||||
<p class="text-center">
|
||||
<i class="award-icon award-{{ award.icon }} fa-2x"></i>
|
||||
<br>
|
||||
<strong>{{ award.name }}</strong>
|
||||
</p>
|
||||
<p class="text-center">{{ award.category or "" }}</p>
|
||||
<p class="text-center">{{ award.description or "" }}</p>
|
||||
<p class="text-center">{{ award.value }}</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<br>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h3>Solves</h3>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<td><b>{% trans %}Challenge{% endtrans %}</b></td>
|
||||
<td class="d-none d-md-block d-lg-block"><b>{% trans %}Category{% endtrans %}</b></td>
|
||||
<td><b>{% trans %}Value{% endtrans %}</b></td>
|
||||
<td><b>{% trans %}Time{% endtrans %}</b></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for solve in solves %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{ url_for('challenges.listing') }}#{{ solve.challenge.name }}-{{ solve.challenge.id }}">
|
||||
{{ solve.challenge.name }}
|
||||
</a>
|
||||
</td>
|
||||
<td class="d-none d-md-block d-lg-block">{{ solve.challenge.category }}</td>
|
||||
<td>{{ solve.challenge.value }}</td>
|
||||
<td class="solve-time">
|
||||
<span data-time="{{ solve.date | isoformat }}"></span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div class="row" x-data="UserGraphs">
|
||||
<div class="col-md-6 d-none d-md-block d-lg-block py-4">
|
||||
<div class="progress">
|
||||
<div
|
||||
class="progress-bar"
|
||||
role="progressbar"
|
||||
:style="{ width: `${getSolvePercentage()}%`, 'background-color': 'rgb(0, 209, 64)' }"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="progress-bar"
|
||||
role="progressbar"
|
||||
:style="{ width: `${getFailPercentage()}%`, 'background-color': 'rgb(207, 38, 0)' }"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ps-2 float-start">
|
||||
<svg height="16" width="16">
|
||||
<circle cx="8" cy="8" r="5" fill="rgb(0, 209, 64)" />
|
||||
</svg>
|
||||
<small x-text="`Solves (${getSolvePercentage()}%)`"></small>
|
||||
</div>
|
||||
<div class="ps-2 float-start">
|
||||
<svg height="16" width="16">
|
||||
<circle cx="8" cy="8" r="5" fill="rgb(207, 38, 0)" />
|
||||
</svg>
|
||||
<small x-text="`Fails (${getFailPercentage()}%)`"></small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 d-none d-md-block d-lg-block py-4">
|
||||
<div class="progress">
|
||||
<template x-for="category in getCategoryBreakdown()" :key="category.name">
|
||||
<div
|
||||
class="progress-bar"
|
||||
role="progressbar"
|
||||
:style="{ width: `${category.percent}%`, 'background-color': category.color }"
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<template x-for="category in getCategoryBreakdown()" :key="category.name">
|
||||
<div class="ps-2 float-start">
|
||||
<svg height="16" width="16">
|
||||
<circle cx="8" cy="8" r="5" :fill="category.color" />
|
||||
</svg>
|
||||
<small x-text="`${category.name} (${category.percent}%)`"></small>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<br class="clearfix">
|
||||
|
||||
<div class="col-md-12 d-none d-md-block d-lg-block py-4">
|
||||
<div id="score-graph" x-ref="scoregraph" class="w-100 d-flex align-items-center">
|
||||
<div class="text-center w-100">
|
||||
<i class="fas fa-circle-notch fa-spin fa-3x fa-fw spinner"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="row min-vh-25">
|
||||
<h3 class="opacity-50 text-center w-100 justify-content-center align-self-center">
|
||||
{% trans %}No solves yet{% endtrans %}
|
||||
</h3>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
window.USER = {{ {
|
||||
'type': 'user',
|
||||
'id': user.id,
|
||||
'name': user.name,
|
||||
'account_id': user.id,
|
||||
} | tojson }};
|
||||
</script>
|
||||
|
||||
{{ Assets.js("assets/js/users/public.js") }}
|
||||
{% endblock %}
|
||||
138
templates/users/users.html
Normal file
138
templates/users/users.html
Normal file
@@ -0,0 +1,138 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="jumbotron">
|
||||
<div class="container">
|
||||
<h1>{% trans %}Users{% endtrans %}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
{% if q and field %}
|
||||
<h5 class="text-muted text-center">
|
||||
Searching for users with <strong>{{ field }}</strong> matching <strong>{{ q }}</strong>
|
||||
</h5>
|
||||
<h6 class="text-muted text-center pb-3">
|
||||
Page {{ users.page }} of {{ users.total }} results
|
||||
</h6>
|
||||
{% endif %}
|
||||
|
||||
{% with form = Forms.users.PublicUserSearchForm(field=field, q=q) %}
|
||||
<form method="GET" class="row justify-content-around align-items-center">
|
||||
<div class="mb-3 col-md-2">
|
||||
{{ form.field(class="form-control form-select w-100") }}
|
||||
</div>
|
||||
<div class="mb-3 col-md-8">
|
||||
{{ form.q(class="form-control w-100", placeholder=form.q.description) }}
|
||||
</div>
|
||||
<div class="mb-3 col-md-2">
|
||||
<button type="submit" class="btn btn-primary w-100">
|
||||
<i class="fas fa-search" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endwith %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<td><b>{% trans %}User{% endtrans %}</b></td>
|
||||
<td><b>{% trans %}Website{% endtrans %}</b></td>
|
||||
<td class="d-none d-md-table-cell"><b>{% trans %}Affiliation{% endtrans %}</b></td>
|
||||
<td class="d-none d-md-table-cell"><b>{% trans %}Country{% endtrans %}</b></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in users.items %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if scores_visible() %}
|
||||
<a href="{{ url_for('users.public', user_id=user.id) }}">
|
||||
{{ user.name | truncate(50) }}
|
||||
</a>
|
||||
{% else %}
|
||||
<span>{{ user.name | truncate(50) }}</span>
|
||||
{% endif %}
|
||||
|
||||
{% if user.oauth_id %}
|
||||
<a href="https://majorleaguecyber.org/u/{{ user.name }}">
|
||||
<span class="badge bg-primary ms-2">{% trans %}Official{% endtrans %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<td class="text-center" style="width: 10px;">
|
||||
{% if user.website and (user.website.startswith('http://') or user.website.startswith('https://')) %}
|
||||
<a href="{{ user.website }}" target="_blank" rel="noopener">
|
||||
<i
|
||||
class="fas fa-external-link-alt" data-toggle="tooltip" data-placement="top"
|
||||
title="{{ user.website }}"
|
||||
></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<td class="d-none d-md-table-cell d-lg-table-cell">
|
||||
{% if user.affiliation %}
|
||||
{% if user.affiliation | length > 50 %}
|
||||
<span data-toggle="tooltip" data-placement="top" title="{{ user.affiliation }}">
|
||||
{% if user.affiliation %}{{ user.affiliation | truncate(50) }}{% endif %}
|
||||
</span>
|
||||
{% else %}
|
||||
<span>
|
||||
{% if user.affiliation %}{{ user.affiliation | truncate(50) }}{% endif %}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="d-none d-md-table-cell d-lg-table-cell">
|
||||
<span>
|
||||
{% if user.country %}
|
||||
<i class="flag-{{ user.country.lower() }}"></i>
|
||||
{{ lookup_country_code(user.country) }}
|
||||
{% endif %}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if users.pages > 1 %}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="text-center">
|
||||
{% trans %}Page{% endtrans %} <br>
|
||||
|
||||
{% if users.page != 1 %}
|
||||
<a href="{{ prev_page }}"><<<</a>
|
||||
{% endif %}
|
||||
|
||||
<select class="page-select">
|
||||
{% for page in range(1, users.pages + 1) %}
|
||||
<option {% if users.page == page %}selected{% endif %}>{{ page }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
{% if users.next_num %}
|
||||
<a href="{{ next_page }}">>>></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
{{ Assets.js("assets/js/users/list.js") }}
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user