From a0f18a886cc0114cd7b44d584650b5cdeeae0863 Mon Sep 17 00:00:00 2001 From: cedrick2711 Date: Tue, 28 Jul 2026 18:11:02 -0400 Subject: [PATCH 1/7] =?UTF-8?q?Correction=20des=20pr=C3=A9sences=20et=20co?= =?UTF-8?q?rrection=20de=20plusieurs=20erreurs=20mineur=20de=20d=C3=A9plac?= =?UTF-8?q?ement/parcours=20de=20l'utilisateur,=20harmonisation=20des=20pr?= =?UTF-8?q?ocessus?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- instance/team_tryouts.db | Bin 204800 -> 204800 bytes models.py | 18 ++--- routes/evaluations.py | 4 +- routes/main.py | 2 +- routes/matches.py | 10 ++- routes/team_matches.py | 6 +- routes/teams.py | 55 ++++++++++---- routes/tryouts.py | 20 ++++- routes/users.py | 26 +++---- seed.py | 6 +- static/css/style.css | 12 +-- templates/pages/contracts.html | 2 +- templates/pages/dashboard.html | 2 +- templates/pages/evaluations.html | 2 +- templates/pages/match_form.html | 7 +- templates/pages/team_matches.html | 9 +-- templates/pages/teams.html | 117 ++++++++++++++++++------------ templates/pages/view_tryout.html | 64 ++++++++++++++++ validators.py | 4 +- 19 files changed, 250 insertions(+), 116 deletions(-) diff --git a/instance/team_tryouts.db b/instance/team_tryouts.db index 7ecf4ca26e968718c77ee46174b151448d8b4365..79db22059e40646f6078fd66acf98f51737f1d5b 100644 GIT binary patch literal 204800 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 diff --git a/models.py b/models.py index 0371b34..55fb565 100644 --- a/models.py +++ b/models.py @@ -11,7 +11,7 @@ from urllib.parse import quote # Available user roles in the system -ROLES = ['president', 'manager', 'coach', 'player', 'scout'] +ROLES = ['admin', 'manager', 'coach', 'player', 'scout'] # Popular E-Sports games list for player profiles ESPORT_GAMES = [ @@ -123,7 +123,7 @@ class User(UserMixin, db.Model): Returns: bool: True if user is president, manager, or coach. """ - return self.role in ['president', 'manager', 'coach'] + return self.role in ['admin', 'manager', 'coach'] def can_manage_users(self): """Check if user can manage (create/delete) other users. @@ -131,7 +131,7 @@ class User(UserMixin, db.Model): Returns: bool: True if user is president. """ - return self.role == 'president' + return self.role == 'admin' def can_manage_tryouts(self): """Check if user can manage tryouts. @@ -139,7 +139,7 @@ class User(UserMixin, db.Model): Returns: bool: True if user is president, manager or coach. """ - return self.role in ['president', 'manager', 'coach'] + return self.role in ['admin', 'manager', 'coach'] def can_manage_teams(self): """Check if user can manage organization teams. @@ -147,7 +147,7 @@ class User(UserMixin, db.Model): Returns: bool: True if user is president or manager. """ - return self.role in ['president', 'manager'] + return self.role in ['admin', 'manager'] def can_schedule_matches(self): """Check if user can schedule matches. @@ -155,7 +155,7 @@ class User(UserMixin, db.Model): Returns: bool: True if user is president, manager, or coach. """ - return self.role in ['president', 'manager', 'coach'] + return self.role in ['admin', 'manager', 'coach'] def can_manage_this_tryout(self, tryout): """Check if user can manage a specific tryout. @@ -170,7 +170,7 @@ class User(UserMixin, db.Model): Returns: bool: True if user has permission to manage the tryout. """ - if self.role == 'president': + if self.role == 'admin': return True if self.role == 'manager' and (tryout.created_by == self.id or tryout.manager_id == self.id): return True @@ -203,7 +203,7 @@ class User(UserMixin, db.Model): Returns: bool: True if user has permission to manage the org team. """ - if self.role == 'president': + if self.role == 'admin': return True if self.role == 'manager': return True # Managers can manage all org teams (create/edit/delete) @@ -778,7 +778,7 @@ class Contract(db.Model): if user.id == self.player_id: return True # President can view all contracts - if user.role == 'president': + if user.role == 'admin': return True # Manager can view contracts for players on their teams if user.role == 'manager': diff --git a/routes/evaluations.py b/routes/evaluations.py index ceb619b..72a3fd3 100644 --- a/routes/evaluations.py +++ b/routes/evaluations.py @@ -89,7 +89,7 @@ def list_evaluations(): else: sort_expr = sort_expr.desc() - if user.role == 'president': + if user.role == 'admin': evaluations = Evaluation.query \ .outerjoin(Tryout, Evaluation.tryout_id == Tryout.id) \ .outerjoin(player_alias, Evaluation.player_id == player_alias.id) \ @@ -227,7 +227,7 @@ def evaluate_player(tryout_id, player_id): return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id)) evaluators = None - if current_user.role == 'president': + if current_user.role == 'admin': all_evaluations = Evaluation.query.filter_by(tryout_id=tryout_id, player_id=player_id).all() evaluators = [{'evaluator': User.query.get(e.evaluator_id), 'eval': e} for e in all_evaluations] diff --git a/routes/main.py b/routes/main.py index c160724..db2c91a 100644 --- a/routes/main.py +++ b/routes/main.py @@ -43,7 +43,7 @@ def dashboard(): user = current_user stats = {} - if user.role == 'president': + if user.role == 'admin': stats['total_users'] = User.query.count() stats['total_players'] = User.query.filter_by(role='player').count() stats['total_tryouts'] = Tryout.query.count() diff --git a/routes/matches.py b/routes/matches.py index 9a5947e..8c279c5 100644 --- a/routes/matches.py +++ b/routes/matches.py @@ -19,7 +19,7 @@ def can_schedule_match(): Returns: bool: True if user is president, manager, coach, or scout. """ - return current_user.role in ['president', 'manager', 'coach', 'scout'] + return current_user.role in ['admin', 'manager', 'coach', 'scout'] @matches_bp.route('/calendar') @@ -248,7 +248,7 @@ def get_visible_tryouts_for_user(): Returns: list: Query result of Tryout objects. """ - if current_user.role == 'president': + if current_user.role == 'admin': return Tryout.query.order_by(Tryout.date).all() elif current_user.role == 'manager': return Tryout.query.filter_by(created_by=current_user.id).order_by(Tryout.date).all() @@ -558,8 +558,10 @@ def edit_match(match_id): # Handle player vs player matches - update participants elif match.match_type == 'player_vs_player': MatchParticipant.query.filter_by(match_id=match.id).delete() - team1_player_ids = request.form.getlist('team1_player_ids') - team2_player_ids = request.form.getlist('team2_player_ids') + team1_str = request.form.get('team1_player_ids', '') + team2_str = request.form.get('team2_player_ids', '') + team1_player_ids = [p for p in team1_str.split(',') if p.strip()] if team1_str else [] + team2_player_ids = [p for p in team2_str.split(',') if p.strip()] if team2_str else [] notified_participant_ids = [] for pid in team1_player_ids: participant = MatchParticipant(match_id=match.id, player_id=int(pid), team_side=1) diff --git a/routes/team_matches.py b/routes/team_matches.py index bb7eaf1..f4f7130 100644 --- a/routes/team_matches.py +++ b/routes/team_matches.py @@ -20,7 +20,7 @@ def can_manage_team_match(team): Returns: bool: True if user is president, manager, or a coach of this team. """ - if current_user.role in ['president']: + if current_user.role in ['admin']: return True if current_user.role == 'manager': return True @@ -45,7 +45,7 @@ def list_matches(): # Optional pre-filter by team_id from query param filter_team_id = request.args.get('team_id', type=int) - if current_user.role == 'president': + if current_user.role == 'admin': teams = OrgTeam.query.order_by(OrgTeam.name).all() matches_query = TeamMatch.query elif current_user.role == 'manager': @@ -337,7 +337,7 @@ def api_manageable_teams(): if not current_user.can_schedule_matches(): return jsonify([]) - if current_user.role in ['president', 'manager']: + if current_user.role in ['admin', 'manager']: teams = OrgTeam.query.order_by(OrgTeam.name).all() elif current_user.role == 'coach': teams = OrgTeam.query.filter( diff --git a/routes/teams.py b/routes/teams.py index f427a15..6ba869e 100644 --- a/routes/teams.py +++ b/routes/teams.py @@ -24,7 +24,9 @@ def list_teams(): """ can_manage = current_user.can_manage_teams() - if current_user.role == 'coach': + if current_user.role == 'admin': + teams = OrgTeam.query.order_by(OrgTeam.name).all() + elif current_user.role == 'coach': teams = OrgTeam.query.filter( db.or_( OrgTeam.coaches.any(id=current_user.id), @@ -181,18 +183,45 @@ def edit_team(team_id): flash(f'Team "{name}" already exists.', 'danger') return redirect(url_for('teams.list_teams')) - team.name = name - team.coach_id = int(coach_id) if coach_id else None - team.manager_id = int(manager_id) if manager_id else None - - if coach_id: - coach_user = User.query.get(int(coach_id)) - if coach_user and not team.coaches.filter_by(id=coach_user.id).first(): - team.coaches.append(coach_user) - if manager_id: - manager_user = User.query.get(int(manager_id)) - if manager_user and not team.managers.filter_by(id=manager_user.id).first(): - team.managers.append(manager_user) + # Check if we're syncing staff (multi-select) or single legacy update + if request.form.get('sync_staff') == '1': + coach_ids = request.form.getlist('coach_ids') + manager_ids = request.form.getlist('manager_ids') + + # Sync coaches many-to-many + team.coaches = [] + for cid in coach_ids: + if cid and cid.strip(): + coach_user = User.query.get(int(cid)) + if coach_user and coach_user.role == 'coach': + team.coaches.append(coach_user) + # Update legacy coach_id with first coach + coach_list = team.coaches.all() + team.coach_id = coach_list[0].id if coach_list else None + + # Sync managers many-to-many + team.managers = [] + for mid in manager_ids: + if mid and mid.strip(): + manager_user = User.query.get(int(mid)) + if manager_user and manager_user.role == 'manager': + team.managers.append(manager_user) + # Update legacy manager_id with first manager + manager_list = team.managers.all() + team.manager_id = manager_list[0].id if manager_list else None + else: + # Legacy single dropdown update + team.coach_id = int(coach_id) if coach_id else None + team.manager_id = int(manager_id) if manager_id else None + + if coach_id: + coach_user = User.query.get(int(coach_id)) + if coach_user and not team.coaches.filter_by(id=coach_user.id).first(): + team.coaches.append(coach_user) + if manager_id: + manager_user = User.query.get(int(manager_id)) + if manager_user and not team.managers.filter_by(id=manager_user.id).first(): + team.managers.append(manager_user) db.session.commit() flash(f'Team "{name}" updated successfully!', 'success') diff --git a/routes/tryouts.py b/routes/tryouts.py index fa63f36..a4fac57 100644 --- a/routes/tryouts.py +++ b/routes/tryouts.py @@ -18,7 +18,7 @@ def can_manage(): Returns: bool: True if user is president or manager. """ - return current_user.role in ['president', 'manager'] + return current_user.role in ['admin', 'manager'] @tryouts_bp.route('') @@ -35,7 +35,7 @@ def list_tryouts(): Returns: Response: Rendered tryouts list template. """ - if current_user.role == 'president': + if current_user.role == 'admin': tryouts = Tryout.query.order_by(Tryout.date.desc()).all() elif current_user.role == 'manager': tryouts = Tryout.query.filter_by(created_by=current_user.id).order_by(Tryout.date.desc()).all() @@ -192,7 +192,7 @@ def view_tryout(tryout_id): # Check if user has permission to view this tryout can_view = False - if current_user.role == 'president': + if current_user.role == 'admin': can_view = True elif current_user.role == 'manager' and tryout.created_by == current_user.id: can_view = True @@ -276,6 +276,17 @@ def view_tryout(tryout_id): confirmed_count = sum(1 for p in all_participants if p.attendance_confirmed) total_count = len(all_participants) + # Build per-player presence data for toggle buttons + player_presence = [] + for p in all_participants: + if p.player: + player_presence.append({ + 'participant_id': p.id, + 'player_id': p.player_id, + 'player_name': p.player.username, + 'attendance_confirmed': p.attendance_confirmed + }) + if match.match_type == 'team_vs_team': participants = { 'team1': match.team1.name if match.team1 else 'TBD', @@ -299,7 +310,8 @@ def view_tryout(tryout_id): 'match': match, 'participants': participants, 'confirmed_count': confirmed_count, - 'total_count': total_count + 'total_count': total_count, + 'player_presence': player_presence }) return render_template('pages/view_tryout.html', diff --git a/routes/users.py b/routes/users.py index ecbb82d..cce8732 100644 --- a/routes/users.py +++ b/routes/users.py @@ -69,7 +69,7 @@ def list_users(): Returns: Response: Rendered users list template or redirect to dashboard. """ - if current_user.role != 'president': + if current_user.role != 'admin': flash('Only the president can manage users.', 'danger') return redirect(url_for('main.dashboard')) @@ -91,7 +91,7 @@ def edit_user(user_id): Returns: Response: Edit form or redirect to users list. """ - if current_user.role != 'president': + if current_user.role != 'admin': flash('Only the president can edit users.', 'danger') return redirect(url_for('main.dashboard')) @@ -149,7 +149,7 @@ def delete_user(user_id): Returns: Response: Redirect to users list with status message. """ - if current_user.role != 'president': + if current_user.role != 'admin': flash('Only the president can delete users.', 'danger') return redirect(url_for('main.dashboard')) @@ -229,7 +229,7 @@ def create_user(): Returns: Response: Create form or redirect to users list. """ - if current_user.role != 'president': + if current_user.role != 'admin': flash('Only the president can create users.', 'danger') return redirect(url_for('main.dashboard')) @@ -588,7 +588,7 @@ def can_manage_player_contract(user, player_id): bool: True if user has permission to manage the contract. """ # President can manage all contracts - if user.role == 'president': + if user.role == 'admin': return True # Manager can upload contracts for any player @@ -621,7 +621,7 @@ def list_contracts(): if current_user.role == 'player': # Players see their own contracts contracts = Contract.query.filter_by(player_id=current_user.id).order_by(Contract.uploaded_at.desc()).all() - elif current_user.role in ['president', 'manager', 'coach']: + elif current_user.role in ['admin', 'manager', 'coach']: # Superiors see contracts for players on their teams players = [] if current_user.role == 'coach': @@ -636,7 +636,7 @@ def list_contracts(): player_ids = [p.id for p in players] contracts = Contract.query.filter(Contract.player_id.in_(player_ids)).order_by(Contract.uploaded_at.desc()).all() - return render_template('pages/contracts.html', contracts=contracts, players=players if current_user.role in ['president', 'manager', 'coach'] else None) + return render_template('pages/contracts.html', contracts=contracts, players=players if current_user.role in ['admin', 'manager', 'coach'] else None) @users_bp.route('/contracts/upload', methods=['GET', 'POST']) @@ -650,7 +650,7 @@ def upload_contract(): Returns: Response: Upload form or redirect to contracts list. """ - if current_user.role not in ['president', 'manager', 'coach']: + if current_user.role not in ['admin', 'manager', 'coach']: flash('Only presidents, managers, and coaches can upload contracts.', 'danger') return redirect(url_for('users.list_contracts')) @@ -1395,7 +1395,7 @@ def add_personal_note(): Returns: Response: Create form or redirect to notes view. """ - if current_user.role not in ['coach', 'manager', 'president']: + if current_user.role not in ['coach', 'manager', 'admin']: flash('Only coaches and managers can add notes.', 'danger') return redirect(url_for('main.dashboard')) @@ -1407,7 +1407,7 @@ def add_personal_note(): if org_team: player_ids = [tp.player_id for tp in TeamPlayer.query.filter_by(org_team_id=org_team.id).all()] players = User.query.filter(User.id.in_(player_ids)).order_by(User.username).all() if player_ids else [] - elif current_user.role in ['president', 'manager']: + elif current_user.role in ['admin', 'manager']: players = User.query.filter_by(role='player').order_by(User.username).all() # Get available matches and tryouts for context @@ -1417,7 +1417,7 @@ def add_personal_note(): if current_user.role == 'coach' and org_team: tryouts = Tryout.query.filter_by(target_org_team_id=org_team.id).order_by(Tryout.date.desc()).all() matches = Match.query.join(Tryout).filter(Tryout.target_org_team_id == org_team.id).order_by(Match.date.desc()).all() - elif current_user.role in ['president', 'manager']: + elif current_user.role in ['admin', 'manager']: tryouts = Tryout.query.order_by(Tryout.date.desc()).all() matches = Match.query.order_by(Match.date.desc()).all() teams = Team.query.order_by(Team.name).all() @@ -1501,7 +1501,7 @@ def add_note_from_match(match_id): Returns: Response: Create form or redirect. """ - if current_user.role not in ['coach', 'manager', 'president']: + if current_user.role not in ['coach', 'manager', 'admin']: flash('Only coaches can add notes from matches.', 'danger') return redirect(url_for('main.dashboard')) @@ -1577,7 +1577,7 @@ def add_note_from_tryout(tryout_id): Returns: Response: Create form or redirect. """ - if current_user.role not in ['coach', 'manager', 'president']: + if current_user.role not in ['coach', 'manager', 'admin']: flash('Only coaches can add notes from tryouts.', 'danger') return redirect(url_for('main.dashboard')) diff --git a/seed.py b/seed.py index f5d1604..2d4ada2 100644 --- a/seed.py +++ b/seed.py @@ -43,7 +43,7 @@ def seed_database(): # Create users with different roles users_data = [ - {'username': 'president', 'password': 'password', 'role': 'president', 'full_name': 'Sarah Johnson', 'email': 'sarah@teampro.com', 'phone': '555-0101'}, + {'username': 'admin', 'password': 'password', 'role': 'admin', 'full_name': 'Sarah Johnson', 'email': 'sarah@teampro.com', 'phone': '555-0101'}, {'username': 'manager1', 'password': 'password', 'role': 'manager', 'full_name': 'Mike Williams', 'email': 'mike@teampro.com', 'phone': '555-0102'}, {'username': 'manager2', 'password': 'password', 'role': 'manager', 'full_name': 'Emily Davis', 'email': 'emily@teampro.com', 'phone': '555-0103'}, {'username': 'coach1', 'password': 'password', 'role': 'coach', 'full_name': 'Coach Thompson', 'email': 'coach.t@teampro.com', 'phone': '555-0104', 'discord_user_id': '484107446298738689'}, @@ -117,7 +117,7 @@ def seed_database(): # Map users for easy access user_map = {u.username: u for u in users} - president = user_map['president'] + president = user_map['admin'] manager1 = user_map['manager1'] manager2 = user_map['manager2'] coaches = [user_map['coach1'], user_map['coach2'], user_map['coach3']] @@ -507,7 +507,7 @@ def seed_database(): print("\n[SUCCESS] Database seeded successfully!") print("\n=== Login Credentials ===") - print("President: username='president', password='password'") + print("President: username='admin', password='password'") print("Manager: username='manager1', password='password'") print("Coach: username='coach1', password='password' (assigned to Varsity)") print("Coach: username='coach2', password='password' (assigned to Junior Varsity)") diff --git a/static/css/style.css b/static/css/style.css index 129747e..847abf1 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -1231,9 +1231,9 @@ a:hover { color: var(--primary-dark); } } .merged-disponibility-time-block.selected { - background: var(--success); - color: white; - border-color: var(--success); + background: #6366f1 !important; + color: white !important; + border-color: #4f46e5 !important; } .merged-disponibility-time-block.high-availability { @@ -1266,10 +1266,10 @@ a:hover { color: var(--primary-dark); } /* Then specific states override the generic rule */ [data-theme="dark"] .merged-disponibility-time-block.selected { - background: var(--success) !important; + background: #6366f1 !important; color: white !important; - border-color: var(--success) !important; - box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.5); + border-color: #818cf8 !important; + box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.5); } [data-theme="dark"] .merged-disponibility-time-block.high-availability { diff --git a/templates/pages/contracts.html b/templates/pages/contracts.html index 1202bd8..d275fcb 100644 --- a/templates/pages/contracts.html +++ b/templates/pages/contracts.html @@ -4,7 +4,7 @@ {% block breadcrumb %}Home / Profile / Contracts{% endblock %} {% block header_actions %} -{% if current_user.role in ['president', 'manager', 'coach'] %} +{% if current_user.role in ['admin', 'manager', 'coach'] %} Upload Contract diff --git a/templates/pages/dashboard.html b/templates/pages/dashboard.html index 6ae7e90..bf20877 100644 --- a/templates/pages/dashboard.html +++ b/templates/pages/dashboard.html @@ -5,7 +5,7 @@ {% block content %}
- {% if user.role == 'president' %} + {% if user.role == 'admin' %}
diff --git a/templates/pages/evaluations.html b/templates/pages/evaluations.html index bf9fccf..64541a3 100644 --- a/templates/pages/evaluations.html +++ b/templates/pages/evaluations.html @@ -21,7 +21,7 @@ {% endmacro %} -{% if current_user.role == 'president' and player_scores %} +{% if current_user.role == 'admin' and player_scores %}
{% for pid, data in player_scores.items() %}
diff --git a/templates/pages/match_form.html b/templates/pages/match_form.html index 797d37a..68f933d 100644 --- a/templates/pages/match_form.html +++ b/templates/pages/match_form.html @@ -75,7 +75,12 @@ {% if current_user.can_manage_teams() or current_user.can_schedule_matches() %}

Select Match Time

-

Click time slots consecutively to set match duration. Players available in all selected time blocks are shown below.

+
+

Click time slots consecutively to set match duration. Players available in all selected time blocks are shown below.

+ +

Loading...

diff --git a/templates/pages/team_matches.html b/templates/pages/team_matches.html index 3c9fba9..07c2266 100644 --- a/templates/pages/team_matches.html +++ b/templates/pages/team_matches.html @@ -77,12 +77,11 @@ {% else %} @@ -93,7 +92,7 @@ {{ m.status }} - {% set can_manage_this = (current_user.role in ['president', 'manager']) or (current_user.role == 'coach' and m.org_team.coaches.filter_by(id=current_user.id).first()) or (current_user.role == 'coach' and m.org_team.coach_id == current_user.id) %} + {% set can_manage_this = (current_user.role in ['admin', 'manager']) or (current_user.role == 'coach' and m.org_team.coaches.filter_by(id=current_user.id).first()) or (current_user.role == 'coach' and m.org_team.coach_id == current_user.id) %} {% if can_manage_this %} diff --git a/templates/pages/teams.html b/templates/pages/teams.html index 7348b1c..27de3d9 100644 --- a/templates/pages/teams.html +++ b/templates/pages/teams.html @@ -124,36 +124,10 @@ {% endif %}
- {% if can_manage %} -
-
- - -
-
- - -
-
- {% endif %}
Matches - {% if current_user.can_schedule_matches() and (current_user.role in ['president', 'manager'] or (current_user.role == 'coach' and team.coaches.filter_by(id=current_user.id).first()) or (current_user.role == 'coach' and team.coach_id == current_user.id)) %} + {% if current_user.can_schedule_matches() and (current_user.role in ['admin', 'manager'] or (current_user.role == 'coach' and team.coaches.filter_by(id=current_user.id).first()) or (current_user.role == 'coach' and team.coach_id == current_user.id)) %} Match @@ -286,28 +260,37 @@