This commit is contained in:
cedrick2711
2026-08-25 14:03:07 -04:00
191 changed files with 28790 additions and 5066 deletions
+49 -38
View File
@@ -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 %}