modification des permissions de coach: Voit uniquement les tryouts de ses équipes.
Evaluer un joueur retourne à la page précédente au lieu de la page des evaluations
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -65,6 +65,28 @@ class User(UserMixin, db.Model):
|
|||||||
def can_manage_teams(self):
|
def can_manage_teams(self):
|
||||||
return self.role in ['president', 'manager']
|
return self.role in ['president', 'manager']
|
||||||
|
|
||||||
|
def can_manage_this_tryout(self, tryout):
|
||||||
|
"""Check if user can manage a specific tryout (president, or manager/coach in charge of it)."""
|
||||||
|
if self.role == 'president':
|
||||||
|
return True
|
||||||
|
if self.role == 'manager' and tryout.created_by == self.id:
|
||||||
|
return True
|
||||||
|
if self.role == 'coach':
|
||||||
|
org_team = OrgTeam.query.filter_by(coach_id=self.id).first()
|
||||||
|
if org_team and tryout.target_org_team_id == org_team.id:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def can_manage_this_org_team(self, org_team):
|
||||||
|
"""Check if user can manage a specific org team (president, or manager/coach in charge of it)."""
|
||||||
|
if self.role == 'president':
|
||||||
|
return True
|
||||||
|
if self.role == 'manager':
|
||||||
|
return True # Managers can manage all org teams (create/edit/delete)
|
||||||
|
if self.role == 'coach' and org_team.coach_id == self.id:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
@login_manager.user_loader
|
@login_manager.user_loader
|
||||||
def load_user(user_id):
|
def load_user(user_id):
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -99,7 +99,7 @@ def evaluate_player(tryout_id, player_id):
|
|||||||
flash('Evaluation submitted successfully!', 'success')
|
flash('Evaluation submitted successfully!', 'success')
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return redirect(url_for('evaluations.list_evaluations'))
|
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||||
|
|
||||||
evaluators = None
|
evaluators = None
|
||||||
if current_user.role == 'president':
|
if current_user.role == 'president':
|
||||||
|
|||||||
+7
-8
@@ -56,11 +56,11 @@ def create_team():
|
|||||||
@teams_bp.route('/<int:team_id>/edit', methods=['POST'])
|
@teams_bp.route('/<int:team_id>/edit', methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def edit_team(team_id):
|
def edit_team(team_id):
|
||||||
if not current_user.can_manage_teams():
|
team = OrgTeam.query.get_or_404(team_id)
|
||||||
flash('You do not have permission to edit teams.', 'danger')
|
if not current_user.can_manage_this_org_team(team):
|
||||||
|
flash('You do not have permission to edit this team.', 'danger')
|
||||||
return redirect(url_for('teams.list_teams'))
|
return redirect(url_for('teams.list_teams'))
|
||||||
|
|
||||||
team = OrgTeam.query.get_or_404(team_id)
|
|
||||||
name = request.form.get('name')
|
name = request.form.get('name')
|
||||||
coach_id = request.form.get('coach_id')
|
coach_id = request.form.get('coach_id')
|
||||||
|
|
||||||
@@ -105,11 +105,10 @@ def delete_team(team_id):
|
|||||||
@teams_bp.route('/<int:team_id>/add_player', methods=['POST'])
|
@teams_bp.route('/<int:team_id>/add_player', methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def add_player(team_id):
|
def add_player(team_id):
|
||||||
if not current_user.can_manage_teams():
|
team = OrgTeam.query.get_or_404(team_id)
|
||||||
|
if not current_user.can_manage_this_org_team(team):
|
||||||
flash('Permission denied.', 'danger')
|
flash('Permission denied.', 'danger')
|
||||||
return redirect(url_for('teams.list_teams'))
|
return redirect(url_for('teams.list_teams'))
|
||||||
|
|
||||||
team = OrgTeam.query.get_or_404(team_id)
|
|
||||||
player_id = request.form.get('player_id')
|
player_id = request.form.get('player_id')
|
||||||
position = request.form.get('position', '')
|
position = request.form.get('position', '')
|
||||||
|
|
||||||
@@ -138,11 +137,11 @@ def add_player(team_id):
|
|||||||
@teams_bp.route('/<int:team_id>/remove_player/<int:player_id>', methods=['POST'])
|
@teams_bp.route('/<int:team_id>/remove_player/<int:player_id>', methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def remove_player(team_id, player_id):
|
def remove_player(team_id, player_id):
|
||||||
if not current_user.can_manage_teams():
|
team = OrgTeam.query.get_or_404(team_id)
|
||||||
|
if not current_user.can_manage_this_org_team(team):
|
||||||
flash('Permission denied.', 'danger')
|
flash('Permission denied.', 'danger')
|
||||||
return redirect(url_for('teams.list_teams'))
|
return redirect(url_for('teams.list_teams'))
|
||||||
|
|
||||||
team = OrgTeam.query.get_or_404(team_id)
|
|
||||||
player = User.query.get_or_404(player_id)
|
player = User.query.get_or_404(player_id)
|
||||||
|
|
||||||
if player.team_id != team_id:
|
if player.team_id != team_id:
|
||||||
|
|||||||
+14
-30
@@ -74,17 +74,8 @@ def create_tryout():
|
|||||||
def edit_tryout(tryout_id):
|
def edit_tryout(tryout_id):
|
||||||
tryout = Tryout.query.get_or_404(tryout_id)
|
tryout = Tryout.query.get_or_404(tryout_id)
|
||||||
|
|
||||||
# Permission: president can edit any; manager can edit own; coach can edit if it targets their team
|
# Permission: president, manager (own tryouts), or coach (targets their team)
|
||||||
if current_user.role == 'president':
|
if not current_user.can_manage_this_tryout(tryout):
|
||||||
pass # allowed
|
|
||||||
elif current_user.role == 'manager' and tryout.created_by == current_user.id:
|
|
||||||
pass # allowed
|
|
||||||
elif current_user.role == 'coach':
|
|
||||||
org_team = OrgTeam.query.filter_by(coach_id=current_user.id).first()
|
|
||||||
if not org_team or tryout.target_org_team_id != org_team.id:
|
|
||||||
flash('You do not have permission to edit this tryout.', 'danger')
|
|
||||||
return redirect(url_for('tryouts.list_tryouts'))
|
|
||||||
else:
|
|
||||||
flash('You do not have permission to edit this tryout.', 'danger')
|
flash('You do not have permission to edit this tryout.', 'danger')
|
||||||
return redirect(url_for('tryouts.list_tryouts'))
|
return redirect(url_for('tryouts.list_tryouts'))
|
||||||
|
|
||||||
@@ -152,15 +143,7 @@ def view_tryout(tryout_id):
|
|||||||
})
|
})
|
||||||
|
|
||||||
# Determine if current user can edit this tryout
|
# Determine if current user can edit this tryout
|
||||||
can_edit = False
|
can_edit = current_user.can_manage_this_tryout(tryout)
|
||||||
if current_user.role == 'president':
|
|
||||||
can_edit = True
|
|
||||||
elif current_user.role == 'manager' and tryout.created_by == current_user.id:
|
|
||||||
can_edit = True
|
|
||||||
elif current_user.role == 'coach':
|
|
||||||
org_team = OrgTeam.query.filter_by(coach_id=current_user.id).first()
|
|
||||||
if org_team and tryout.target_org_team_id == org_team.id:
|
|
||||||
can_edit = True
|
|
||||||
|
|
||||||
# Get all players (for manager registration dropdown)
|
# Get all players (for manager registration dropdown)
|
||||||
all_players = User.query.filter_by(role='player').order_by(User.full_name).all()
|
all_players = User.query.filter_by(role='player').order_by(User.full_name).all()
|
||||||
@@ -209,11 +192,10 @@ def register_for_tryout(tryout_id):
|
|||||||
@tryouts_bp.route('/<int:tryout_id>/status', methods=['POST'])
|
@tryouts_bp.route('/<int:tryout_id>/status', methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def update_status(tryout_id):
|
def update_status(tryout_id):
|
||||||
if not can_manage():
|
tryout = Tryout.query.get_or_404(tryout_id)
|
||||||
|
if not current_user.can_manage_this_tryout(tryout):
|
||||||
flash('Permission denied.', 'danger')
|
flash('Permission denied.', 'danger')
|
||||||
return redirect(url_for('tryouts.list_tryouts'))
|
return redirect(url_for('tryouts.list_tryouts'))
|
||||||
|
|
||||||
tryout = Tryout.query.get_or_404(tryout_id)
|
|
||||||
new_status = request.form.get('status')
|
new_status = request.form.get('status')
|
||||||
if new_status in ['upcoming', 'in_progress', 'completed']:
|
if new_status in ['upcoming', 'in_progress', 'completed']:
|
||||||
tryout.status = new_status
|
tryout.status = new_status
|
||||||
@@ -224,7 +206,8 @@ def update_status(tryout_id):
|
|||||||
@tryouts_bp.route('/<int:tryout_id>/registration/<int:player_id>/status', methods=['POST'])
|
@tryouts_bp.route('/<int:tryout_id>/registration/<int:player_id>/status', methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def update_registration_status(tryout_id, player_id):
|
def update_registration_status(tryout_id, player_id):
|
||||||
if not can_manage():
|
tryout = Tryout.query.get_or_404(tryout_id)
|
||||||
|
if not current_user.can_manage_this_tryout(tryout):
|
||||||
flash('Permission denied.', 'danger')
|
flash('Permission denied.', 'danger')
|
||||||
return redirect(url_for('tryouts.list_tryouts'))
|
return redirect(url_for('tryouts.list_tryouts'))
|
||||||
|
|
||||||
@@ -239,11 +222,10 @@ def update_registration_status(tryout_id, player_id):
|
|||||||
@tryouts_bp.route('/<int:tryout_id>/register_player', methods=['POST'])
|
@tryouts_bp.route('/<int:tryout_id>/register_player', methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def register_player(tryout_id):
|
def register_player(tryout_id):
|
||||||
if not can_manage():
|
tryout = Tryout.query.get_or_404(tryout_id)
|
||||||
|
if not current_user.can_manage_this_tryout(tryout):
|
||||||
flash('Permission denied.', 'danger')
|
flash('Permission denied.', 'danger')
|
||||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||||
|
|
||||||
tryout = Tryout.query.get_or_404(tryout_id)
|
|
||||||
player_id = request.form.get('player_id')
|
player_id = request.form.get('player_id')
|
||||||
|
|
||||||
if not player_id:
|
if not player_id:
|
||||||
@@ -275,7 +257,8 @@ def register_player(tryout_id):
|
|||||||
@tryouts_bp.route('/<int:tryout_id>/team/create', methods=['POST'])
|
@tryouts_bp.route('/<int:tryout_id>/team/create', methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def create_team(tryout_id):
|
def create_team(tryout_id):
|
||||||
if not can_manage():
|
tryout = Tryout.query.get_or_404(tryout_id)
|
||||||
|
if not current_user.can_manage_this_tryout(tryout):
|
||||||
flash('Permission denied.', 'danger')
|
flash('Permission denied.', 'danger')
|
||||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||||
|
|
||||||
@@ -290,13 +273,14 @@ def create_team(tryout_id):
|
|||||||
@tryouts_bp.route('/<int:tryout_id>/team/<int:team_id>/add', methods=['POST'])
|
@tryouts_bp.route('/<int:tryout_id>/team/<int:team_id>/add', methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def add_to_team(tryout_id, team_id):
|
def add_to_team(tryout_id, team_id):
|
||||||
if not can_manage():
|
team = Team.query.get_or_404(team_id)
|
||||||
|
tryout = Tryout.query.get_or_404(tryout_id)
|
||||||
|
if not current_user.can_manage_this_tryout(tryout):
|
||||||
flash('Permission denied.', 'danger')
|
flash('Permission denied.', 'danger')
|
||||||
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id))
|
||||||
|
|
||||||
player_id = request.form.get('player_id')
|
player_id = request.form.get('player_id')
|
||||||
position = request.form.get('position', '')
|
position = request.form.get('position', '')
|
||||||
team = Team.query.get_or_404(team_id)
|
|
||||||
|
|
||||||
existing = TeamMember.query.filter_by(team_id=team_id, player_id=player_id).first()
|
existing = TeamMember.query.filter_by(team_id=team_id, player_id=player_id).first()
|
||||||
if existing:
|
if existing:
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% for team in teams %}
|
{% for team in teams %}
|
||||||
|
{% set can_manage_team = can_manage or (current_user.role == 'coach' and team.coach_id == current_user.id) %}
|
||||||
<div class="card mb-4">
|
<div class="card mb-4">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h3><i class="fas fa-users-cog"></i> {{ team.name }}</h3>
|
<h3><i class="fas fa-users-cog"></i> {{ team.name }}</h3>
|
||||||
@@ -76,7 +77,7 @@
|
|||||||
<th>Position / Role</th>
|
<th>Position / Role</th>
|
||||||
<th>Email</th>
|
<th>Email</th>
|
||||||
<th>Phone</th>
|
<th>Phone</th>
|
||||||
{% if can_manage %}
|
{% if can_manage_team %}
|
||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
@@ -93,7 +94,7 @@
|
|||||||
<td>{{ player.role | capitalize }}</td>
|
<td>{{ player.role | capitalize }}</td>
|
||||||
<td>{{ player.email }}</td>
|
<td>{{ player.email }}</td>
|
||||||
<td>{{ player.phone or '-' }}</td>
|
<td>{{ player.phone or '-' }}</td>
|
||||||
{% if can_manage %}
|
{% if can_manage_team %}
|
||||||
<td>
|
<td>
|
||||||
<form method="POST" action="{{ url_for('teams.remove_player', team_id=team.id, player_id=player.id) }}" class="inline-form" onsubmit="return confirm('Remove {{ player.full_name }} from {{ team.name }}?')">
|
<form method="POST" action="{{ url_for('teams.remove_player', team_id=team.id, player_id=player.id) }}" class="inline-form" onsubmit="return confirm('Remove {{ player.full_name }} from {{ team.name }}?')">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||||
@@ -106,11 +107,11 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{% else %}
|
{% else %}
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="{% if can_manage %}5{% else %}4{% endif %}" class="text-center">
|
<td colspan="{% if can_manage_team %}5{% else %}4{% endif %}" class="text-center">
|
||||||
<div class="empty-state">
|
<div class="empty-state">
|
||||||
<i class="fas fa-users-slash"></i>
|
<i class="fas fa-users-slash"></i>
|
||||||
<h4>No players assigned</h4>
|
<h4>No players assigned</h4>
|
||||||
{% if can_manage %}
|
{% if can_manage_team %}
|
||||||
<p>Add players to this team using the form below.</p>
|
<p>Add players to this team using the form below.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
@@ -121,7 +122,7 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if can_manage %}
|
{% if can_manage_team %}
|
||||||
<hr class="my-3">
|
<hr class="my-3">
|
||||||
<div class="add-player-section">
|
<div class="add-player-section">
|
||||||
<h5 class="mb-2"><i class="fas fa-user-plus"></i> Add Player to {{ team.name }}</h5>
|
<h5 class="mb-2"><i class="fas fa-user-plus"></i> Add Player to {{ team.name }}</h5>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h3>Tryout Details</h3>
|
<h3>Tryout Details</h3>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
{% if current_user.can_manage_tryouts() %}
|
{% if can_edit %}
|
||||||
<form method="POST" action="{{ url_for('tryouts.update_status', tryout_id=tryout.id) }}" class="inline-form">
|
<form method="POST" action="{{ url_for('tryouts.update_status', tryout_id=tryout.id) }}" class="inline-form">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||||
<select name="status" onchange="this.form.submit()" class="form-select">
|
<select name="status" onchange="this.form.submit()" class="form-select">
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if current_user.can_manage_tryouts() %}
|
{% if can_edit %}
|
||||||
<div class="card mb-4">
|
<div class="card mb-4">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h3><i class="fas fa-user-plus"></i> Add Player to Tryout</h3>
|
<h3><i class="fas fa-user-plus"></i> Add Player to Tryout</h3>
|
||||||
@@ -125,7 +125,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% if current_user.can_manage_tryouts() %}
|
{% if can_edit %}
|
||||||
<form method="POST" action="{{ url_for('tryouts.update_registration_status', tryout_id=tryout.id, player_id=p.id) }}" class="inline-form">
|
<form method="POST" action="{{ url_for('tryouts.update_registration_status', tryout_id=tryout.id, player_id=p.id) }}" class="inline-form">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||||
<select name="status" onchange="this.form.submit()" class="form-select form-select-sm">
|
<select name="status" onchange="this.form.submit()" class="form-select form-select-sm">
|
||||||
@@ -169,14 +169,14 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h3><i class="fas fa-users-cog"></i> Teams</h3>
|
<h3><i class="fas fa-users-cog"></i> Teams</h3>
|
||||||
{% if current_user.can_manage_tryouts() %}
|
{% if can_edit %}
|
||||||
<button class="btn btn-sm btn-primary" onclick="showCreateTeam()">
|
<button class="btn btn-sm btn-primary" onclick="showCreateTeam()">
|
||||||
<i class="fas fa-plus"></i> New Team
|
<i class="fas fa-plus"></i> New Team
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
{% if current_user.can_manage_tryouts() %}
|
{% if can_edit %}
|
||||||
<div id="createTeamForm" class="hidden mb-3">
|
<div id="createTeamForm" class="hidden mb-3">
|
||||||
<form method="POST" action="{{ url_for('tryouts.create_team', tryout_id=tryout.id) }}" class="form-inline">
|
<form method="POST" action="{{ url_for('tryouts.create_team', tryout_id=tryout.id) }}" class="form-inline">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||||
@@ -203,7 +203,7 @@
|
|||||||
<li class="text-muted">No players assigned yet.</li>
|
<li class="text-muted">No players assigned yet.</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% if current_user.can_manage_tryouts() and registered_players %}
|
{% if can_edit and registered_players %}
|
||||||
<form method="POST" action="{{ url_for('tryouts.add_to_team', tryout_id=tryout.id, team_id=team.team.id) }}" class="form-inline mt-2">
|
<form method="POST" action="{{ url_for('tryouts.add_to_team', tryout_id=tryout.id, team_id=team.team.id) }}" class="form-inline mt-2">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||||
<select name="player_id" class="form-select" required>
|
<select name="player_id" class="form-select" required>
|
||||||
|
|||||||
Reference in New Issue
Block a user