Merge branch 'dev' of https://git.immortal.host/clubesportsudes/team-tryouts into dev
This commit is contained in:
@@ -1,15 +1,15 @@
|
||||
{% extends "layouts/base.html" %}
|
||||
{% block title %}My Profile - TryoutPro{% endblock %}
|
||||
{% block page_title %}My Profile{% endblock %}
|
||||
{% block title %}{{ _('My Profile') }} - UdeS team manager{% endblock %}
|
||||
{% block page_title %}{{ _('My Profile') }}{% endblock %}
|
||||
{% block breadcrumb %}<span class="breadcrumb">Home / Profile</span>{% endblock %}
|
||||
|
||||
{% block header_actions %}
|
||||
<div class="header-actions">
|
||||
<a href="{{ url_for('users.list_contracts') }}" class="btn btn-sm btn-info">
|
||||
<i class="fas fa-file-contract"></i> Contracts
|
||||
<i class="fas fa-file-contract"></i> {{ _('Contracts') }}
|
||||
</a>
|
||||
<a href="{{ url_for('users.edit_profile') }}" class="btn btn-sm btn-primary">
|
||||
<i class="fas fa-edit"></i> Edit Profile
|
||||
<i class="fas fa-edit"></i> {{ _('Edit Profile') }}
|
||||
</a>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -18,7 +18,7 @@
|
||||
<div class="dashboard-grid">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-user-circle"></i> Account Information</h3>
|
||||
<h3><i class="fas fa-user-circle"></i> {{ _('Account Information') }}</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="profile-header">
|
||||
@@ -60,12 +60,12 @@
|
||||
<!-- E-Sports Profile Card -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-gamepad"></i> E-Sports Profile</h3>
|
||||
<h3><i class="fas fa-gamepad"></i> {{ _('E-Sports Profile') }}</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="detail-grid">
|
||||
<div class="detail-item">
|
||||
<span class="detail-label"><i class="fas fa-gamepad"></i> Gamertags</span>
|
||||
<span class="detail-label"><i class="fas fa-gamepad"></i> {{ _('Gamertags') }}</span>
|
||||
<span class="detail-value">
|
||||
{% set games_list = user.get_games_list() %}
|
||||
{% if games_list %}
|
||||
@@ -91,7 +91,7 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<span class="detail-label"><i class="fab fa-discord"></i> Discord</span>
|
||||
<span class="detail-label"><i class="fab fa-discord"></i> {{ _('Discord') }}</span>
|
||||
<span class="detail-value">
|
||||
{% if user.discord_username %}
|
||||
{{ user.discord_username }}
|
||||
@@ -101,7 +101,7 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<span class="detail-label"><i class="fas fa-link"></i> League OS</span>
|
||||
<span class="detail-label"><i class="fas fa-link"></i> {{ _('League OS') }}</span>
|
||||
<span class="detail-value">
|
||||
{% if user.league_os_profile %}
|
||||
<a href="{{ user.league_os_profile }}" target="_blank" rel="noopener noreferrer" class="trn-link">
|
||||
@@ -118,29 +118,29 @@
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-chart-bar"></i> My Statistics</h3>
|
||||
<h3><i class="fas fa-chart-bar"></i> {{ _('My Statistics') }}</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if user.role == 'player' %}
|
||||
<div class="profile-stats">
|
||||
<div class="stat-item">
|
||||
<h4>{{ user.tryout_registrations.count() }}</h4>
|
||||
<p>Tryouts Registered</p>
|
||||
<p>{{ _('Tryouts Registered') }}</p>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<h4>{{ user.team_assignments.count() }}</h4>
|
||||
<p>Team Assignments</p>
|
||||
<p>{{ _('Team Assignments') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% elif user.can_evaluate() %}
|
||||
<div class="profile-stats">
|
||||
<div class="stat-item">
|
||||
<h4>{{ user.evaluations_given.count() }}</h4>
|
||||
<p>Evaluations Given</p>
|
||||
<p>{{ _('Evaluations Given') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="text-muted">No statistics available for this role.</p>
|
||||
<p class="text-muted">{{ _('No statistics available for this role.') }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -192,7 +192,7 @@
|
||||
{% if user.role == 'player' %}
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-file-contract"></i> My Contracts</h3>
|
||||
<h3><i class="fas fa-file-contract"></i> {{ _('My Contracts') }}</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if contracts %}
|
||||
@@ -214,11 +214,11 @@
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<a href="{{ url_for('users.list_contracts') }}" class="btn btn-sm btn-primary">
|
||||
<i class="fas fa-folder-open"></i> View All Contracts
|
||||
<i class="fas fa-folder-open"></i> {{ _('View All Contracts') }}
|
||||
</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="text-muted">No contracts have been uploaded for you yet.</p>
|
||||
<p class="text-muted">{{ _('No contracts have been uploaded for you yet.') }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -228,19 +228,16 @@
|
||||
{% if user.role == 'player' %}
|
||||
<div class="card" style="grid-column: 1 / -1;">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-clock"></i> My Disponibilities</h3>
|
||||
<h3><i class="fas fa-clock"></i> {{ _('My Disponibilities') }}</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="text-muted small">Select your available time blocks for matches (5pm to 12am). Green = selected, Gray = available to select.</p>
|
||||
<p class="text-muted small">{{ _('Select your available time blocks for matches (5pm to 12am). Green = selected, Gray = available to select.') }}</p>
|
||||
<div id="disponibilities-grid">
|
||||
<p class="text-muted">Loading...</p>
|
||||
<p class="text-muted">{{ _('Loading...') }}</p>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="button" class="btn btn-primary" onclick="saveDisponibilities()">
|
||||
<i class="fas fa-save"></i> Save Disponibilities
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary" onclick="clearDisponibilities()">
|
||||
<i class="fas fa-trash"></i> Clear All
|
||||
<button type="button" class="btn btn-secondary" data-action="clear-disponibilities">
|
||||
<i class="fas fa-trash"></i> {{ _('Clear All') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -251,16 +248,16 @@
|
||||
{% if user.role == 'coach' %}
|
||||
<div class="card" style="grid-column: 1 / -1;">
|
||||
<div class="card-header">
|
||||
<h3><i class="fas fa-clock"></i> My Coaching Availability</h3>
|
||||
<p class="text-muted small">Select time slots when you're available for One on One sessions (8am to 10pm).</p>
|
||||
<h3><i class="fas fa-clock"></i> {{ _('My Coaching Availability') }}</h3>
|
||||
<p class="text-muted small">{{ _('Select time slots when you\'re available for One on One sessions (8am to 10pm).') }}</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="availability-grid" id="availability-grid">
|
||||
<p class="text-muted">Loading availability grid...</p>
|
||||
<p class="text-muted">{{ _('Loading availability grid...') }}</p>
|
||||
</div>
|
||||
<div class="form-actions mt-3">
|
||||
<button type="button" class="btn btn-secondary" onclick="clearAllAvailability()">
|
||||
<i class="fas fa-trash"></i> Clear All
|
||||
<button type="button" class="btn btn-secondary" data-action="clear-availability">
|
||||
<i class="fas fa-trash"></i> {{ _('Clear All') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -309,7 +306,7 @@
|
||||
@media (max-width: 768px) { .availability-grid { grid-template-columns: repeat(3, 1fr); } }
|
||||
@media (max-width: 480px) { .availability-grid { grid-template-columns: 1fr; } }
|
||||
</style>
|
||||
<script>
|
||||
<script nonce="{{ csp_nonce }}">
|
||||
const COACH_TIME_SLOTS = [];
|
||||
for (let h = 8; h <= 22; h++) {
|
||||
for (let m = 0; m < 60; m += 30) {
|
||||
@@ -400,7 +397,10 @@ function saveCoachAvailability() {
|
||||
}
|
||||
fetch('{{ url_for("users.manage_coach_availability") }}', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': '{{ csrf_token() }}'
|
||||
},
|
||||
body: JSON.stringify({ slots: slots })
|
||||
})
|
||||
.then(r => r.json())
|
||||
@@ -409,7 +409,7 @@ function saveCoachAvailability() {
|
||||
const msg = document.createElement('div');
|
||||
msg.className = 'alert alert-success';
|
||||
msg.style.marginTop = '10px';
|
||||
msg.innerHTML = '<i class="fas fa-check"></i> Availability saved!';
|
||||
msg.innerHTML = '<span><i class="fas fa-check"></i> Availability saved!</span>';
|
||||
document.getElementById('availability-grid').appendChild(msg);
|
||||
setTimeout(() => msg.remove(), 3000);
|
||||
}
|
||||
@@ -419,7 +419,10 @@ function saveCoachAvailability() {
|
||||
|
||||
function clearAllAvailability() {
|
||||
if (!confirm('Are you sure you want to clear all your availability slots?')) return;
|
||||
fetch('{{ url_for("users.clear_coach_availability") }}', { method: 'POST' })
|
||||
fetch('{{ url_for("users.clear_coach_availability") }}', {
|
||||
method: 'POST',
|
||||
headers: { 'X-CSRFToken': '{{ csrf_token() }}' }
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
@@ -437,7 +440,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
{% endif %}
|
||||
|
||||
{% if user.role == 'player' %}
|
||||
<script>
|
||||
<script nonce="{{ csp_nonce }}">
|
||||
// Generate time slots from 5pm (17:00) to 12am (24:00)
|
||||
var TIME_SLOTS = [];
|
||||
for (var h = 17; h <= 24; h++) {
|
||||
@@ -494,7 +497,7 @@ function applySlotAction(block, action) {
|
||||
|
||||
function renderDisponibilityGrid() {
|
||||
var grid = document.getElementById('disponibilities-grid');
|
||||
grid.innerHTML = '<div style="margin-bottom: 10px;"><strong>Click or click-and-drag to select your available hours</strong></div>';
|
||||
grid.innerHTML = '<div style="margin-bottom: 10px;"><strong>{{ _('Click or click-and-drag to select your available hours') }}</strong></div>';
|
||||
|
||||
var container = document.createElement('div');
|
||||
container.className = 'disponibility-grid';
|
||||
@@ -608,7 +611,7 @@ function saveDisponibilities() {
|
||||
var msg = document.createElement('div');
|
||||
msg.className = 'alert alert-success';
|
||||
msg.style.marginTop = '10px';
|
||||
msg.innerHTML = '<i class="fas fa-check"></i> Disponibilities saved successfully!';
|
||||
msg.innerHTML = '<span><i class="fas fa-check"></i> Disponibilities saved successfully!</span>';
|
||||
document.getElementById('disponibilities-grid').appendChild(msg);
|
||||
setTimeout(function() { msg.remove(); }, 3000);
|
||||
}
|
||||
@@ -642,6 +645,14 @@ function clearDisponibilities() {
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
renderDisponibilityGrid();
|
||||
});
|
||||
|
||||
// Behaviours are declared in the markup with data-action / data-change and
|
||||
// dispatched by the delegated listener in main.js. This replaces inline
|
||||
// onclick attributes, which no CSP nonce is able to authorise.
|
||||
registerActions({
|
||||
'clear-disponibilities': clearDisponibilities,
|
||||
'clear-availability': clearAllAvailability,
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user