From ad7b932c0a6dd3e48531db4a1c0d67bee6cb66c8 Mon Sep 17 00:00:00 2001 From: cedrick2711 Date: Wed, 29 Jul 2026 17:01:28 -0400 Subject: [PATCH] =?UTF-8?q?r=C3=A9gler=20les=20probl=C3=A8mes=20de=20route?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/routes/users.py | 349 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 348 insertions(+), 1 deletion(-) diff --git a/app/routes/users.py b/app/routes/users.py index b22bfdd..a2dfd33 100644 --- a/app/routes/users.py +++ b/app/routes/users.py @@ -767,4 +767,351 @@ def one_on_one(): return render_template('pages/one_on_one.html', org_team=org_team, coach=coach, team_notes=team_notes, personal_notes=personal_notes, - coach_availability=coach_availability) \ No newline at end of file + coach_availability=coach_availability) + + +# --------------------------------------------------------------------------- +# My Notes (Player) +# --------------------------------------------------------------------------- + +@users_bp.route('/my-notes') +@login_required +def my_notes(): + """View personal and team notes for the current player.""" + if not isinstance(current_user, Player): + flash('This page is for players only.', 'info') + return redirect(url_for('main.dashboard')) + + org_teams = current_user.get_org_teams() + org_team = org_teams[0] if org_teams else None + + personal_notes = PersonalNote.query.filter_by( + player_id=current_user.id, + ).order_by(PersonalNote.created_at.desc()).all() + + team_notes = [] + if org_team: + team_notes = TeamNote.query.filter_by( + org_team_id=org_team.id, + ).order_by(TeamNote.created_at.desc()).all() + + return render_template('pages/player_personal_notes.html', + org_team=org_team, + personal_notes=personal_notes, + team_notes=team_notes) + + +# --------------------------------------------------------------------------- +# Coach Availability +# --------------------------------------------------------------------------- + +@users_bp.route('/coach-availability', methods=['GET', 'POST']) +@login_required +def manage_coach_availability(): + """Manage coach availability for One on One sessions.""" + if not isinstance(current_user, Coach): + flash('Only coaches can manage availability.', 'danger') + return redirect(url_for('main.dashboard')) + + if request.method == 'POST': + data = request.get_json() + slots = data.get('slots', []) if data else [] + + # Clear existing availability + CoachAvailability.query.filter_by(coach_id=current_user.id).delete() + + # Add new slots + for slot in slots: + day_of_week = slot.get('day_of_week') + start_time_str = slot.get('start_time') + if day_of_week is None or day_of_week < 0 or day_of_week > 6: + continue + try: + start_time = datetime.strptime(start_time_str, '%H:%M').time() + end_time = (datetime.combine(datetime.today(), start_time) + timedelta(minutes=30)).time() + except (ValueError, TypeError): + continue + + availability = CoachAvailability( + coach_id=current_user.id, + day_of_week=day_of_week, + start_time=start_time, + end_time=end_time, + ) + db.session.add(availability) + + db.session.commit() + return jsonify({'success': True}) + + existing_availability = CoachAvailability.query.filter_by( + coach_id=current_user.id, + ).all() + + return render_template('pages/coach_availability.html', + existing_availability=existing_availability) + + +@users_bp.route('/coach-availability/clear', methods=['POST']) +@login_required +def clear_coach_availability(): + """Clear all coach availability slots.""" + if not isinstance(current_user, Coach): + return jsonify({'error': 'Unauthorized'}), 403 + + CoachAvailability.query.filter_by(coach_id=current_user.id).delete() + db.session.commit() + return jsonify({'success': True}) + + +# --------------------------------------------------------------------------- +# Notes Dashboard (Coach) +# --------------------------------------------------------------------------- + +@users_bp.route('/notes-dashboard') +@login_required +def notes_dashboard(): + """Notes and One on One dashboard for coaches.""" + if not isinstance(current_user, Coach): + flash('Only coaches can access the notes dashboard.', 'danger') + return redirect(url_for('main.dashboard')) + + org_team = OrgTeam.query.filter_by(coach_id=current_user.id).first() + + players = [] + 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)).all() if player_ids else [] + + team_notes = [] + personal_notes = [] + latest_team_note = None + if org_team: + team_notes = TeamNote.query.filter_by( + org_team_id=org_team.id, + ).order_by(TeamNote.created_at.desc()).all() + latest_team_note = team_notes[0] if team_notes else None + + personal_notes = PersonalNote.query.filter_by( + coach_id=current_user.id, + ).order_by(PersonalNote.created_at.desc()).all() + + # For context selectors in the form + from app.models import Team as MatchTeam + matches = Match.query.filter( + db.or_(Match.created_by == current_user.id, Match.status == 'scheduled'), + ).order_by(Match.date.desc()).limit(20).all() + tryouts = Tryout.query.filter_by( + created_by=current_user.id, + ).order_by(Tryout.date.desc()).limit(20).all() + teams = OrgTeam.query.order_by(OrgTeam.name).all() + + return render_template('pages/notes.html', + org_team=org_team, + players=players, + team_notes=team_notes, + latest_team_note=latest_team_note, + personal_notes=personal_notes, + matches=matches, + tryouts=tryouts, + teams=teams) + + +# --------------------------------------------------------------------------- +# Manage Team Notes (POST) +# --------------------------------------------------------------------------- + +@users_bp.route('/team-notes/manage', methods=['POST']) +@login_required +def manage_team_notes(): + """Create or update team notes for the coach's org team.""" + if not isinstance(current_user, Coach): + flash('Only coaches can manage team notes.', 'danger') + return redirect(url_for('main.dashboard')) + + org_team = OrgTeam.query.filter_by(coach_id=current_user.id).first() + if not org_team: + flash('You are not assigned to a team.', 'danger') + return redirect(url_for('users.notes_dashboard')) + + content = request.form.get('content', '').strip() + if content: + note = TeamNote( + org_team_id=org_team.id, + coach_id=current_user.id, + content=content, + ) + db.session.add(note) + db.session.commit() + flash('Team notes saved successfully!', 'success') + + return redirect(url_for('users.notes_dashboard')) + + +# --------------------------------------------------------------------------- +# Manage Personal Notes (POST, simple form) +# --------------------------------------------------------------------------- + +@users_bp.route('/personal-notes/manage', methods=['POST']) +@login_required +def manage_personal_notes(): + """Create a personal note for a player (coach only, simple form).""" + if not isinstance(current_user, Coach): + flash('Only coaches can manage personal notes.', 'danger') + return redirect(url_for('main.dashboard')) + + player_id = request.form.get('player_id', type=int) + content = request.form.get('content', '').strip() + + if not player_id or not content: + flash('Player and content are required.', 'danger') + return redirect(url_for('users.notes_dashboard')) + + player = User.query.get_or_404(player_id) + if not isinstance(player, Player): + flash('Can only add notes for players.', 'danger') + return redirect(url_for('users.notes_dashboard')) + + note = PersonalNote( + player_id=player_id, + coach_id=current_user.id, + content=content, + ) + db.session.add(note) + db.session.commit() + flash(f'Note added for {player.username}.', 'success') + return redirect(url_for('users.notes_dashboard')) + + +# --------------------------------------------------------------------------- +# Add Personal Note (POST, full form with context) +# --------------------------------------------------------------------------- + +@users_bp.route('/personal-notes/add', methods=['POST']) +@login_required +def add_personal_note(): + """Create a personal note for a player with optional context (coach only).""" + if not isinstance(current_user, Coach): + flash('Only coaches can add personal notes.', 'danger') + return redirect(url_for('main.dashboard')) + + player_id = request.form.get('player_id', type=int) + content = request.form.get('content', '').strip() + match_id = request.form.get('match_id', type=int) + tryout_id = request.form.get('tryout_id', type=int) + team_id_str = request.form.get('team_id') + + if not player_id or not content: + flash('Player and content are required.', 'danger') + return redirect(url_for('users.notes_dashboard')) + + player = User.query.get_or_404(player_id) + if not isinstance(player, Player): + flash('Can only add notes for players.', 'danger') + return redirect(url_for('users.notes_dashboard')) + + note = PersonalNote( + player_id=player_id, + coach_id=current_user.id, + content=content, + match_id=match_id if match_id else None, + tryout_id=tryout_id if tryout_id else None, + team_id=int(team_id_str) if team_id_str and team_id_str.isdigit() else None, + ) + db.session.add(note) + db.session.commit() + flash(f'Note added for {player.username}.', 'success') + return redirect(url_for('users.notes_dashboard')) + + +# --------------------------------------------------------------------------- +# Add Note from Tryout context (GET + POST) +# --------------------------------------------------------------------------- + +@users_bp.route('/personal-notes/tryout/', methods=['GET', 'POST']) +@login_required +def add_note_from_tryout(tryout_id): + """Add a personal note for a player in the context of a tryout.""" + if not isinstance(current_user, Coach): + flash('Only coaches can add personal notes.', 'danger') + return redirect(url_for('main.dashboard')) + + tryout = Tryout.query.get_or_404(tryout_id) + preselected_player_id = request.args.get('player_id', type=int) + + # Get registrations as players for the select list + registrations = TryoutRegistration.query.filter_by(tryout_id=tryout_id).all() + players = [r.player for r in registrations if r.player] + + if request.method == 'POST': + player_id = request.form.get('player_id', type=int) + content = request.form.get('content', '').strip() + + if not player_id or not content: + flash('Player and content are required.', 'danger') + return redirect(url_for('users.add_note_from_tryout', tryout_id=tryout_id)) + + note = PersonalNote( + player_id=player_id, + coach_id=current_user.id, + content=content, + tryout_id=tryout_id, + ) + db.session.add(note) + db.session.commit() + flash('Note added successfully.', 'success') + return redirect(url_for('tryouts.view_tryout', tryout_id=tryout_id)) + + return render_template('pages/add_note.html', + context_type='tryout', + tryout=tryout, + players=players, + preselected_player_id=preselected_player_id, + team_notes=[]) + + +# --------------------------------------------------------------------------- +# Add Note from Match context (GET + POST) +# --------------------------------------------------------------------------- + +@users_bp.route('/personal-notes/match/', methods=['GET', 'POST']) +@login_required +def add_note_from_match(match_id): + """Add a personal note for a player in the context of a match.""" + if not isinstance(current_user, Coach): + flash('Only coaches can add personal notes.', 'danger') + return redirect(url_for('main.dashboard')) + + match_obj = Match.query.get_or_404(match_id) + + # Get participants as players for the select list + participants = MatchParticipant.query.filter_by(match_id=match_id).all() + players = [p.player for p in participants if p.player] + + preselected_player_id = request.args.get('player_id', type=int) + + if request.method == 'POST': + player_id = request.form.get('player_id', type=int) + content = request.form.get('content', '').strip() + + if not player_id or not content: + flash('Player and content are required.', 'danger') + return redirect(url_for('users.add_note_from_match', match_id=match_id)) + + note = PersonalNote( + player_id=player_id, + coach_id=current_user.id, + content=content, + match_id=match_id, + ) + db.session.add(note) + db.session.commit() + flash('Note added successfully.', 'success') + return redirect(url_for('tryouts.view_tryout', tryout_id=match_obj.tryout_id)) + + return render_template('pages/add_note.html', + context_type='match', + tryout=match_obj, + match=match_obj, + players=players, + preselected_player_id=preselected_player_id, + team_notes=[])