Merge branch 'dev' of https://github.com/cedrick2711/team-tryouts into dev
This commit is contained in:
@@ -10,6 +10,7 @@ from app.models import (
|
||||
Admin, Manager, Coach, Player, Scout,
|
||||
User, Tryout, Match, MatchParticipant, Team, TeamMember,
|
||||
OrgTeam, TryoutRegistration, PlayerDisponibility,
|
||||
OneOnOneRequest,
|
||||
)
|
||||
from datetime import datetime, time, timedelta
|
||||
from app.discord_bot import send_schedule_notification
|
||||
@@ -101,6 +102,37 @@ def api_events():
|
||||
},
|
||||
})
|
||||
|
||||
# Add approved One on One sessions for the current user (player or coach)
|
||||
if isinstance(current_user, Player):
|
||||
one_on_ones = OneOnOneRequest.query.filter_by(
|
||||
player_id=current_user.id,
|
||||
status='approved'
|
||||
).all()
|
||||
elif isinstance(current_user, Coach):
|
||||
one_on_ones = OneOnOneRequest.query.filter_by(
|
||||
coach_id=current_user.id,
|
||||
status='approved'
|
||||
).all()
|
||||
else:
|
||||
one_on_ones = []
|
||||
|
||||
for ooo in one_on_ones:
|
||||
events.append({
|
||||
'id': f'one_on_one_{ooo.id}',
|
||||
'title': f'1:1 - {ooo.player.full_name} & {ooo.coach.full_name}',
|
||||
'date': ooo.date.strftime('%Y-%m-%d'),
|
||||
'type': 'one_on_one',
|
||||
'color': '#8b5cf6',
|
||||
'extendedProps': {
|
||||
'location': 'Discord / Voice Chat',
|
||||
'status': 'approved',
|
||||
'description': ooo.points or 'One on One session',
|
||||
'start_time': ooo.start_time.strftime('%H:%M') if ooo.start_time else None,
|
||||
'end_time': ooo.end_time.strftime('%H:%M') if ooo.end_time else None,
|
||||
'participants': f"{ooo.player.full_name} with {ooo.coach.full_name}",
|
||||
},
|
||||
})
|
||||
|
||||
return jsonify(events)
|
||||
|
||||
|
||||
|
||||
+103
-1
@@ -788,11 +788,104 @@ def one_on_one():
|
||||
'display': d.strftime('%B %d, %Y (%A)'),
|
||||
})
|
||||
|
||||
# Player's own One on One request history
|
||||
my_requests = OneOnOneRequest.query.filter_by(
|
||||
player_id=current_user.id
|
||||
).order_by(OneOnOneRequest.created_at.desc()).all()
|
||||
|
||||
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,
|
||||
dates=dates)
|
||||
dates=dates,
|
||||
my_requests=my_requests)
|
||||
|
||||
|
||||
@users_bp.route('/one-on-one/<int:request_id>/accept', methods=['POST'])
|
||||
@login_required
|
||||
def accept_one_on_one(request_id):
|
||||
"""Coach accepts a One on One request."""
|
||||
if not isinstance(current_user, Coach):
|
||||
flash('Only coaches can accept One on One requests.', 'danger')
|
||||
return redirect(url_for('main.dashboard'))
|
||||
|
||||
request_obj = OneOnOneRequest.query.get_or_404(request_id)
|
||||
|
||||
if request_obj.coach_id != current_user.id:
|
||||
flash('This request is not for you.', 'danger')
|
||||
return redirect(url_for('users.notes_dashboard'))
|
||||
|
||||
if request_obj.status != 'pending':
|
||||
flash('This request has already been processed.', 'info')
|
||||
return redirect(url_for('users.notes_dashboard'))
|
||||
|
||||
player = request_obj.player
|
||||
request_obj.status = 'approved'
|
||||
request_obj.responded_at = datetime.utcnow()
|
||||
db.session.commit()
|
||||
|
||||
# Notify player via Discord (same message as if approved through Discord reactions)
|
||||
if player and player.discord_user_id:
|
||||
from app.discord_bot import send_one_on_one_response
|
||||
send_one_on_one_response(
|
||||
player_discord_id=player.discord_user_id,
|
||||
player_full_name=player.full_name,
|
||||
coach_full_name=current_user.full_name,
|
||||
date_str=request_obj.date.strftime('%A, %B %d, %Y'),
|
||||
start_time=request_obj.start_time.strftime('%I:%M %p') if request_obj.start_time else 'TBD',
|
||||
end_time=request_obj.end_time.strftime('%I:%M %p') if request_obj.end_time else 'TBD',
|
||||
points=request_obj.points or 'No specific points provided',
|
||||
approved=True,
|
||||
)
|
||||
|
||||
flash(f'One on One request from {player.username if player else "Unknown"} has been approved!', 'success')
|
||||
return redirect(url_for('users.notes_dashboard'))
|
||||
|
||||
|
||||
@users_bp.route('/one-on-one/<int:request_id>/reject', methods=['POST'])
|
||||
@login_required
|
||||
def reject_one_on_one(request_id):
|
||||
"""Coach rejects a One on One request."""
|
||||
if not isinstance(current_user, Coach):
|
||||
flash('Only coaches can reject One on One requests.', 'danger')
|
||||
return redirect(url_for('main.dashboard'))
|
||||
|
||||
request_obj = OneOnOneRequest.query.get_or_404(request_id)
|
||||
|
||||
if request_obj.coach_id != current_user.id:
|
||||
flash('This request is not for you.', 'danger')
|
||||
return redirect(url_for('users.notes_dashboard'))
|
||||
|
||||
if request_obj.status != 'pending':
|
||||
flash('This request has already been processed.', 'info')
|
||||
return redirect(url_for('users.notes_dashboard'))
|
||||
|
||||
rejection_reason = request.form.get('rejection_reason', '').strip()
|
||||
player = request_obj.player
|
||||
|
||||
request_obj.status = 'rejected'
|
||||
request_obj.responded_at = datetime.utcnow()
|
||||
if rejection_reason:
|
||||
request_obj.coach_rejection_message = rejection_reason
|
||||
db.session.commit()
|
||||
|
||||
# Notify player via Discord (same message as if rejected through Discord reactions)
|
||||
if player and player.discord_user_id:
|
||||
from app.discord_bot import send_one_on_one_response
|
||||
send_one_on_one_response(
|
||||
player_discord_id=player.discord_user_id,
|
||||
player_full_name=player.full_name,
|
||||
coach_full_name=current_user.full_name,
|
||||
date_str=request_obj.date.strftime('%A, %B %d, %Y'),
|
||||
start_time=request_obj.start_time.strftime('%I:%M %p') if request_obj.start_time else 'TBD',
|
||||
end_time=request_obj.end_time.strftime('%I:%M %p') if request_obj.end_time else 'TBD',
|
||||
points=request_obj.points or 'No specific points provided',
|
||||
approved=False,
|
||||
refusal_note=rejection_reason or None,
|
||||
)
|
||||
|
||||
flash(f'One on One request from {player.username if player else "Unknown"} has been rejected.', 'info')
|
||||
return redirect(url_for('users.notes_dashboard'))
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -920,6 +1013,14 @@ def notes_dashboard():
|
||||
coach_id=current_user.id,
|
||||
).order_by(PersonalNote.created_at.desc()).all()
|
||||
|
||||
# One on One requests from team players
|
||||
one_on_one_requests = []
|
||||
if org_team and players:
|
||||
player_ids_list = [p.id for p in players]
|
||||
one_on_one_requests = OneOnOneRequest.query.filter(
|
||||
OneOnOneRequest.player_id.in_(player_ids_list)
|
||||
).order_by(OneOnOneRequest.created_at.desc()).all()
|
||||
|
||||
# For context selectors in the form
|
||||
from app.models import Team as MatchTeam
|
||||
matches = Match.query.filter(
|
||||
@@ -936,6 +1037,7 @@ def notes_dashboard():
|
||||
team_notes=team_notes,
|
||||
latest_team_note=latest_team_note,
|
||||
personal_notes=personal_notes,
|
||||
one_on_one_requests=one_on_one_requests,
|
||||
matches=matches,
|
||||
tryouts=tryouts,
|
||||
teams=teams)
|
||||
|
||||
Reference in New Issue
Block a user