régler problème avec les liens TRN

This commit is contained in:
cedrick2711
2026-07-15 16:29:58 -04:00
parent 073543fc48
commit ca60f001e2
13 changed files with 368 additions and 47 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
+86 -1
View File
@@ -1,6 +1,7 @@
from extensions import db, login_manager from extensions import db, login_manager
from flask_login import UserMixin from flask_login import UserMixin
from datetime import datetime from datetime import datetime
from urllib.parse import quote
ROLES = ['president', 'manager', 'coach', 'player', 'scout'] ROLES = ['president', 'manager', 'coach', 'player', 'scout']
@@ -35,7 +36,6 @@ class User(UserMixin, db.Model):
# E-Sports specific fields # E-Sports specific fields
games = db.Column(db.Text, nullable=True) # Comma-separated list of games games = db.Column(db.Text, nullable=True) # Comma-separated list of games
trn_username = db.Column(db.String(120), nullable=True) # Tracker Network username
discord_username = db.Column(db.String(100), nullable=True) # Discord handle discord_username = db.Column(db.String(100), nullable=True) # Discord handle
league_os_profile = db.Column(db.String(255), nullable=True) # League OS profile URL or ID league_os_profile = db.Column(db.String(255), nullable=True) # League OS profile URL or ID
@@ -90,12 +90,97 @@ class User(UserMixin, db.Model):
return True return True
return False return False
def get_gamertags(self):
"""Return gamertags as a dict keyed by game."""
return {gt.game: {'gamertag': gt.gamertag, 'platform': gt.platform} for gt in self.gamertags}
@login_manager.user_loader @login_manager.user_loader
def load_user(user_id): def load_user(user_id):
return User.query.get(int(user_id)) return User.query.get(int(user_id))
# Platform options for games that require platform specification
GAME_PLATFORMS = {
'Valorant': [], # No platform needed
'League of Legends': [],
'Counter-Strike 2': [],
'Apex Legends': ['PC', 'PlayStation', 'Xbox', 'Nintendo Switch'],
'Overwatch 2': ['PC', 'PlayStation', 'Xbox', 'Nintendo Switch'],
'Rainbow Six Siege': ['Ubisoft', 'PlayStation', 'Xbox'], # Ubisoft = Uplay/Steam
'Fortnite': ['PC', 'PlayStation', 'Xbox', 'Nintendo Switch', 'Mobile'],
'Rocket League': ['Epic', 'PlayStation', 'Xbox', 'Nintendo Switch'], # Epic uses EpicID, others use username
'Call of Duty': ['PC', 'PlayStation', 'Xbox'],
'Dota 2': [],
'Super Smash Bros.': ['Nintendo Switch'],
'Street Fighter 6': ['PC', 'PlayStation', 'Xbox'],
}
# Platform code mapping for TRN URLs (platform -> TRN code)
PLATFORM_CODES = {
'Ubisoft': 'ubi',
'PlayStation': 'psn',
'Xbox': 'xbl',
'Nintendo Switch': 'switch',
'PC': 'pc',
'Mobile': 'mobile',
'Steam': 'steam',
'Epic': 'epic',
}
# TRN URL mapping for each game
TRN_URLS = {
'Valorant': 'https://tracker.gg/valorant/profile/riot/{username}',
'League of Legends': 'https://tracker.gg/lol/profile/{username}',
'Counter-Strike 2': 'https://tracker.gg/cs2/profile/steam/{username}',
'Apex Legends': 'https://tracker.gg/apex/profile/{platform}/{username}',
'Overwatch 2': 'https://tracker.gg/overwatch/profile/{platform}/{username}',
'Rainbow Six Siege': 'https://r6.tracker.network/r6siege/profile/{platform_code}/{username}',
'Fortnite': 'https://tracker.gg/fortnite/profile/{platform}/{username}',
'Rocket League': 'https://rocketleague.tracker.network/rocket-league/profile/{platform_code}/{username}',
'Call of Duty': 'https://tracker.gg/call-of-duty/profile/{platform}/{username}',
'Dota 2': 'https://tracker.gg/dota2/profile/steam/{username}',
'Super Smash Bros.': 'https://tracker.gg/smash/profile/{username}',
'Street Fighter 6': 'https://tracker.gg/streetfighter/profile/{username}',
}
class UserGamertag(db.Model):
"""Store gamertag per game for each user."""
__tablename__ = 'user_gamertags'
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
game = db.Column(db.String(50), nullable=False)
gamertag = db.Column(db.String(120), nullable=False)
platform = db.Column(db.String(30), nullable=True) # For games that need platform (e.g., PSN, Xbox Live)
user = db.relationship('User', backref='gamertags')
__table_args__ = (
db.UniqueConstraint('user_id', 'game', name='unique_user_game'),
)
def get_trn_url(self):
"""Generate the TRN URL for this gamertag."""
if self.game not in TRN_URLS:
return None
url = TRN_URLS[self.game]
# URL-encode the gamertag to handle special characters like #, spaces, etc.
encoded_gamertag = quote(self.gamertag, safe='')
# Check for platform_code placeholder (used for R6 and Rocket League)
if '{platform_code}' in url and '{username}' in url:
platform_code = PLATFORM_CODES.get(self.platform, self.platform.lower().replace(' ', '-')) if self.platform else ''
return url.format(platform_code=platform_code, username=encoded_gamertag)
elif '{platform}' in url and '{username}' in url:
return url.format(platform=self.platform.lower().replace(' ', '-'), username=encoded_gamertag)
elif '{username}' in url:
return url.format(username=encoded_gamertag)
return url
class OrgTeam(db.Model): class OrgTeam(db.Model):
"""Persistent organization teams (e.g., Varsity, JV) that exist across tryouts.""" """Persistent organization teams (e.g., Varsity, JV) that exist across tryouts."""
__tablename__ = 'org_teams' __tablename__ = 'org_teams'
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+55 -9
View File
@@ -1,7 +1,7 @@
from flask import Blueprint, render_template, redirect, url_for, flash, request, jsonify from flask import Blueprint, render_template, redirect, url_for, flash, request, jsonify
from flask_login import login_required, current_user from flask_login import login_required, current_user
from extensions import db, hash_password from extensions import db, hash_password
from models import User, ROLES, ESPORT_GAMES, PlayerDisponibility from models import User, ROLES, ESPORT_GAMES, PlayerDisponibility, UserGamertag, GAME_PLATFORMS
from datetime import datetime, timedelta from datetime import datetime, timedelta
users_bp = Blueprint('users', __name__, url_prefix='/users') users_bp = Blueprint('users', __name__, url_prefix='/users')
@@ -34,10 +34,9 @@ def edit_user(user_id):
if role not in ROLES: if role not in ROLES:
flash('Invalid role selected.', 'danger') flash('Invalid role selected.', 'danger')
return render_template('pages/edit_user.html', user=user, roles=ROLES, esport_games=ESPORT_GAMES) return render_template('pages/edit_user.html', user=user, roles=ROLES, esport_games=ESPORT_GAMES, game_platforms=GAME_PLATFORMS)
selected_games = request.form.getlist('games') selected_games = request.form.getlist('games')
trn_username = request.form.get('trn_username', '').strip()
discord_username = request.form.get('discord_username', '').strip() discord_username = request.form.get('discord_username', '').strip()
league_os_profile = request.form.get('league_os_profile', '').strip() league_os_profile = request.form.get('league_os_profile', '').strip()
@@ -47,10 +46,33 @@ def edit_user(user_id):
user.role = role user.role = role
user.is_active_account = is_active user.is_active_account = is_active
user.games = ','.join(selected_games) if selected_games else None user.games = ','.join(selected_games) if selected_games else None
user.trn_username = trn_username or None
user.discord_username = discord_username or None user.discord_username = discord_username or None
user.league_os_profile = league_os_profile or None user.league_os_profile = league_os_profile or None
# Handle gamertags - save or delete based on form input
# First, get all existing gamertags for this user
existing_gamertags = {gt.game: gt for gt in user.gamertags}
for game in selected_games:
gamertag = request.form.get(f'gamertag_{game}', '').strip()
platform = request.form.get(f'platform_{game}', '').strip() if GAME_PLATFORMS.get(game) else None
existing = existing_gamertags.get(game)
if gamertag:
if existing:
existing.gamertag = gamertag
existing.platform = platform
else:
gt = UserGamertag(user_id=user.id, game=game, gamertag=gamertag, platform=platform)
db.session.add(gt)
elif existing:
db.session.delete(existing)
# Remove gamertags for games that are no longer selected
for game in existing_gamertags:
if game not in selected_games:
db.session.delete(existing_gamertags[game])
password = request.form.get('password') password = request.form.get('password')
if password: if password:
user.password_hash = hash_password(password) user.password_hash = hash_password(password)
@@ -59,7 +81,8 @@ def edit_user(user_id):
flash(f'User {user.full_name} updated successfully!', 'success') flash(f'User {user.full_name} updated successfully!', 'success')
return redirect(url_for('users.list_users')) return redirect(url_for('users.list_users'))
return render_template('pages/edit_user.html', user=user, roles=ROLES, esport_games=ESPORT_GAMES) user_gamertags = {gt.game: {'gamertag': gt.gamertag, 'platform': gt.platform} for gt in user.gamertags}
return render_template('pages/edit_user.html', user=user, roles=ROLES, esport_games=ESPORT_GAMES, game_platforms=GAME_PLATFORMS, user_gamertags=user_gamertags)
@users_bp.route('/<int:user_id>/delete', methods=['POST']) @users_bp.route('/<int:user_id>/delete', methods=['POST'])
@login_required @login_required
@@ -135,22 +158,44 @@ def edit_profile():
phone = request.form.get('phone') phone = request.form.get('phone')
selected_games = request.form.getlist('games') selected_games = request.form.getlist('games')
trn_username = request.form.get('trn_username', '').strip()
discord_username = request.form.get('discord_username', '').strip() discord_username = request.form.get('discord_username', '').strip()
league_os_profile = request.form.get('league_os_profile', '').strip() league_os_profile = request.form.get('league_os_profile', '').strip()
if email != current_user.email and User.query.filter_by(email=email).first(): if email != current_user.email and User.query.filter_by(email=email).first():
flash('Email already in use.', 'danger') flash('Email already in use.', 'danger')
return render_template('pages/edit_profile.html', user=current_user, esport_games=ESPORT_GAMES) return render_template('pages/edit_profile.html', user=current_user, esport_games=ESPORT_GAMES, game_platforms=GAME_PLATFORMS)
current_user.full_name = full_name current_user.full_name = full_name
current_user.email = email current_user.email = email
current_user.phone = phone current_user.phone = phone
current_user.games = ','.join(selected_games) if selected_games else None current_user.games = ','.join(selected_games) if selected_games else None
current_user.trn_username = trn_username or None
current_user.discord_username = discord_username or None current_user.discord_username = discord_username or None
current_user.league_os_profile = league_os_profile or None current_user.league_os_profile = league_os_profile or None
# Handle gamertags - save or delete based on form input
# First, get all existing gamertags for this user
existing_gamertags = {gt.game: gt for gt in current_user.gamertags}
for game in selected_games:
gamertag = request.form.get(f'gamertag_{game}', '').strip()
platform = request.form.get(f'platform_{game}', '').strip() if GAME_PLATFORMS.get(game) else None
existing = existing_gamertags.get(game)
if gamertag:
if existing:
existing.gamertag = gamertag
existing.platform = platform
else:
gt = UserGamertag(user_id=current_user.id, game=game, gamertag=gamertag, platform=platform)
db.session.add(gt)
elif existing:
db.session.delete(existing)
# Remove gamertags for games that are no longer selected
for game in existing_gamertags:
if game not in selected_games:
db.session.delete(existing_gamertags[game])
password = request.form.get('password') password = request.form.get('password')
if password: if password:
current_user.password_hash = hash_password(password) current_user.password_hash = hash_password(password)
@@ -159,7 +204,8 @@ def edit_profile():
flash('Profile updated successfully!', 'success') flash('Profile updated successfully!', 'success')
return redirect(url_for('users.profile')) return redirect(url_for('users.profile'))
return render_template('pages/edit_profile.html', user=current_user, esport_games=ESPORT_GAMES) user_gamertags = {gt.game: {'gamertag': gt.gamertag, 'platform': gt.platform} for gt in current_user.gamertags}
return render_template('pages/edit_profile.html', user=current_user, esport_games=ESPORT_GAMES, game_platforms=GAME_PLATFORMS, user_gamertags=user_gamertags)
# Day names for disponibility # Day names for disponibility
+69 -14
View File
@@ -1,6 +1,6 @@
from sqlalchemy import text from sqlalchemy import text
from extensions import db, hash_password from extensions import db, hash_password
from models import User, Tryout, TryoutRegistration, Evaluation, Team, TeamMember, OrgTeam, PlayerDisponibility from models import User, Tryout, TryoutRegistration, Evaluation, Team, TeamMember, OrgTeam, PlayerDisponibility, UserGamertag
from datetime import datetime, timedelta, time from datetime import datetime, timedelta, time
import random import random
@@ -16,6 +16,7 @@ def seed_database():
db.session.execute(text('DELETE FROM tryout_registrations')) db.session.execute(text('DELETE FROM tryout_registrations'))
db.session.execute(text('DELETE FROM tryouts')) db.session.execute(text('DELETE FROM tryouts'))
db.session.execute(text('DELETE FROM org_teams')) db.session.execute(text('DELETE FROM org_teams'))
db.session.execute(text('DELETE FROM user_gamertags'))
db.session.execute(text('DELETE FROM users')) db.session.execute(text('DELETE FROM users'))
db.session.commit() db.session.commit()
@@ -30,25 +31,45 @@ def seed_database():
{'username': 'scout1', 'password': 'password', 'role': 'scout', 'full_name': 'Alex Rivera', 'email': '[email protected]', 'phone': '555-0107'}, {'username': 'scout1', 'password': 'password', 'role': 'scout', 'full_name': 'Alex Rivera', 'email': '[email protected]', 'phone': '555-0107'},
] ]
# Create players with E-Sports profile data # Create players with E-Sports profile data (gamertags per game)
player_data = [ player_data = [
{'username': 'jplayer1', 'full_name': 'James Wilson', 'email': '[email protected]', 'games': 'Valorant,Counter-Strike 2', 'trn': 'jameswilson_tr', 'discord': 'JamesW#7291', 'league_os': 'https://leagueos.gg/player/jameswilson'}, {'username': 'jplayer1', 'full_name': 'James Wilson', 'email': '[email protected]', 'games': 'Valorant,Counter-Strike 2',
{'username': 'jplayer2', 'full_name': 'Emma Garcia', 'email': '[email protected]', 'games': 'League of Legends,Valorant', 'trn': 'emmagarcia_gg', 'discord': 'EmmaG#4452', 'league_os': 'https://leagueos.gg/player/emmagarcia'}, 'gamertags': {'Valorant': 'jameswilson_val', 'Counter-Strike 2': 'jameswilson_cs'},
{'username': 'jplayer3', 'full_name': 'Liam Brown', 'email': '[email protected]', 'games': 'Apex Legends,Fortnite', 'trn': 'liambrown_fn', 'discord': 'LiamB#8103', 'league_os': 'https://leagueos.gg/player/liambrown'}, 'discord': 'JamesW#7291', 'league_os': 'https://leagueos.gg/player/jameswilson'},
{'username': 'jplayer4', 'full_name': 'Sophia Lee', 'email': 'sophi[email protected]', 'games': 'Overwatch 2,Valorant', 'trn': 'sophialee_ow', 'discord': 'SophiaL#3327', 'league_os': 'https://leagueos.gg/player/sophialee'}, {'username': 'jplayer2', 'full_name': 'Emma Garcia', 'email': 'emm[email protected]', 'games': 'League of Legends,Valorant',
{'username': 'jplayer5', 'full_name': 'Noah Taylor', 'email': '[email protected]', 'games': 'Counter-Strike 2,Rainbow Six Siege', 'trn': 'noahtaylor_r6', 'discord': 'NoahT#6614', 'league_os': 'https://leagueos.gg/player/noahtaylor'}, 'gamertags': {'League of Legends': 'emmagarcia_lol', 'Valorant': 'emmagarcia_val'},
{'username': 'jplayer6', 'full_name': 'Olivia Martin', 'email': '[email protected]', 'games': 'Rocket League,Fortnite', 'trn': 'oliviamartin_rl', 'discord': 'OliviaM#2298', 'league_os': 'https://leagueos.gg/player/oliviamartin'}, 'discord': 'EmmaG#4452', 'league_os': 'https://leagueos.gg/player/emmagarcia'},
{'username': 'jplayer7', 'full_name': 'Ethan Clark', 'email': 'ethan@email.com', 'games': 'Valorant,Apex Legends', 'trn': 'ethanclark_val', 'discord': 'EthanC#7743', 'league_os': 'https://leagueos.gg/player/ethanclark'}, {'username': 'jplayer3', 'full_name': 'Liam Brown', 'email': 'liam@email.com', 'games': 'Apex Legends,Fortnite',
{'username': 'jplayer8', 'full_name': 'Ava White', 'email': '[email protected]', 'games': 'League of Legends,Counter-Strike 2', 'trn': 'avawhite_lol', 'discord': 'AvaW#5561', 'league_os': 'https://leagueos.gg/player/avawhite'}, 'gamertags': {'Apex Legends': 'liambrown_apex', 'platform': 'PC', 'Fortnite': 'liambrown_fn', 'platform_fn': 'PC'},
{'username': 'jplayer9', 'full_name': 'Mason Hall', 'email': '[email protected]', 'games': 'Call of Duty,Rocket League', 'trn': 'masonhall_cod', 'discord': 'MasonH#1189', 'league_os': 'https://leagueos.gg/player/masonhall'}, 'discord': 'LiamB#8103', 'league_os': 'https://leagueos.gg/player/liambrown'},
{'username': 'jplayer10', 'full_name': 'Isabella Adams', 'email': 'isabell[email protected]', 'games': 'Overwatch 2,Dota 2', 'trn': 'isabellaadams_ow', 'discord': 'IsabellaA#4437', 'league_os': 'https://leagueos.gg/player/isabellaadams'}, {'username': 'jplayer4', 'full_name': 'Sophia Lee', 'email': 'sophi[email protected]', 'games': 'Overwatch 2,Valorant',
'gamertags': {'Overwatch 2': 'sophialee_ow', 'platform_ow': 'PC', 'Valorant': 'sophialee_val'},
'discord': 'SophiaL#3327', 'league_os': 'https://leagueos.gg/player/sophialee'},
{'username': 'jplayer5', 'full_name': 'Noah Taylor', 'email': '[email protected]', 'games': 'Counter-Strike 2,Rainbow Six Siege',
'gamertags': {'Counter-Strike 2': 'noahtaylor_cs', 'Rainbow Six Siege': 'noahtaylor_r6', 'platform_r6': 'PC'},
'discord': 'NoahT#6614', 'league_os': 'https://leagueos.gg/player/noahtaylor'},
{'username': 'jplayer6', 'full_name': 'Olivia Martin', 'email': '[email protected]', 'games': 'Rocket League,Fortnite',
'gamertags': {'Rocket League': 'oliviamartin_rl', 'platform_rl': 'PC', 'Fortnite': 'oliviamartin_fn', 'platform_fn': 'PC'},
'discord': 'OliviaM#2298', 'league_os': 'https://leagueos.gg/player/oliviamartin'},
{'username': 'jplayer7', 'full_name': 'Ethan Clark', 'email': '[email protected]', 'games': 'Valorant,Apex Legends',
'gamertags': {'Valorant': 'ethanclark_val', 'Apex Legends': 'ethanclark_apex', 'platform_apex': 'PC'},
'discord': 'EthanC#7743', 'league_os': 'https://leagueos.gg/player/ethanclark'},
{'username': 'jplayer8', 'full_name': 'Ava White', 'email': '[email protected]', 'games': 'League of Legends,Counter-Strike 2',
'gamertags': {'League of Legends': 'avawhite_lol', 'Counter-Strike 2': 'avawhite_cs'},
'discord': 'AvaW#5561', 'league_os': 'https://leagueos.gg/player/avawhite'},
{'username': 'jplayer9', 'full_name': 'Mason Hall', 'email': '[email protected]', 'games': 'Call of Duty,Rocket League',
'gamertags': {'Call of Duty': 'masonhall_cod', 'platform_cod': 'PC', 'Rocket League': 'masonhall_rl', 'platform_rl': 'PC'},
'discord': 'MasonH#1189', 'league_os': 'https://leagueos.gg/player/masonhall'},
{'username': 'jplayer10', 'full_name': 'Isabella Adams', 'email': '[email protected]', 'games': 'Overwatch 2,Dota 2',
'gamertags': {'Overwatch 2': 'isabellaadams_ow', 'platform_ow': 'PC', 'Dota 2': 'isabellaadams_dota'},
'discord': 'IsabellaA#4437', 'league_os': 'https://leagueos.gg/player/isabellaadams'},
] ]
for i, data in enumerate(player_data, start=10): for i, data in enumerate(player_data, start=10):
users_data.append({ users_data.append({
'username': data['username'], 'password': 'password', 'role': 'player', 'username': data['username'], 'password': 'password', 'role': 'player',
'full_name': data['full_name'], 'email': data['email'], 'phone': f'555-01{i:02d}', 'full_name': data['full_name'], 'email': data['email'], 'phone': f'555-01{i:02d}',
'games': data['games'], 'trn_username': data['trn'], 'games': data['games'], 'gamertags': data.get('gamertags', {}),
'discord_username': data['discord'], 'league_os_profile': data['league_os'] 'discord_username': data['discord'], 'league_os_profile': data['league_os']
}) })
@@ -63,7 +84,6 @@ def seed_database():
email=data['email'], email=data['email'],
phone=data.get('phone', ''), phone=data.get('phone', ''),
games=data.get('games'), games=data.get('games'),
trn_username=data.get('trn_username'),
discord_username=data.get('discord_username'), discord_username=data.get('discord_username'),
league_os_profile=data.get('league_os_profile') league_os_profile=data.get('league_os_profile')
) )
@@ -82,6 +102,41 @@ def seed_database():
scout = user_map['scout1'] scout = user_map['scout1']
players = [user_map[f'jplayer{i}'] for i in range(1, 11)] players = [user_map[f'jplayer{i}'] for i in range(1, 11)]
# Create gamertags for players
gamertag_data = [
{'user': users[7], 'game': 'Valorant', 'gamertag': 'jameswilson_val'},
{'user': users[7], 'game': 'Counter-Strike 2', 'gamertag': 'jameswilson_cs'},
{'user': users[8], 'game': 'League of Legends', 'gamertag': 'emmagarcia_lol'},
{'user': users[8], 'game': 'Valorant', 'gamertag': 'emmagarcia_val'},
{'user': users[9], 'game': 'Apex Legends', 'gamertag': 'liambrown_apex', 'platform': 'PC'},
{'user': users[9], 'game': 'Fortnite', 'gamertag': 'liambrown_fn', 'platform': 'PC'},
{'user': users[10], 'game': 'Overwatch 2', 'gamertag': 'sophialee_ow', 'platform': 'PC'},
{'user': users[10], 'game': 'Valorant', 'gamertag': 'sophialee_val'},
{'user': users[11], 'game': 'Counter-Strike 2', 'gamertag': 'noahtaylor_cs'},
{'user': users[11], 'game': 'Rainbow Six Siege', 'gamertag': 'noahtaylor_r6', 'platform': 'Ubisoft'},
{'user': users[12], 'game': 'Rocket League', 'gamertag': 'oliviamartin_rl', 'platform': 'Epic'},
{'user': users[12], 'game': 'Fortnite', 'gamertag': 'oliviamartin_fn', 'platform': 'PC'},
{'user': users[13], 'game': 'Valorant', 'gamertag': 'ethanclark_val'},
{'user': users[13], 'game': 'Apex Legends', 'gamertag': 'ethanclark_apex', 'platform': 'PC'},
{'user': users[14], 'game': 'League of Legends', 'gamertag': 'avawhite_lol'},
{'user': users[14], 'game': 'Counter-Strike 2', 'gamertag': 'avawhite_cs'},
{'user': users[15], 'game': 'Call of Duty', 'gamertag': 'masonhall_cod', 'platform': 'PC'},
{'user': users[15], 'game': 'Rocket League', 'gamertag': 'masonhall_rl', 'platform': 'Epic'},
{'user': users[16], 'game': 'Overwatch 2', 'gamertag': 'isabellaadams_ow', 'platform': 'PC'},
{'user': users[16], 'game': 'Dota 2', 'gamertag': 'isabellaadams_dota'},
]
for gt in gamertag_data:
gamertag = UserGamertag(
user_id=gt['user'].id,
game=gt['game'],
gamertag=gt['gamertag'],
platform=gt.get('platform')
)
db.session.add(gamertag)
db.session.commit()
print(f"[OK] Created {len(gamertag_data)} user gamertags")
# Create Organization Teams (OrgTeams) # Create Organization Teams (OrgTeams)
org_teams_data = [ org_teams_data = [
{'name': 'Varsity', 'coach': coaches[0], 'creator': president}, {'name': 'Varsity', 'coach': coaches[0], 'creator': president},
+73 -9
View File
@@ -42,17 +42,44 @@
</div> </div>
<small class="form-text text-muted">Select all games you're signing in for.</small> <small class="form-text text-muted">Select all games you're signing in for.</small>
</div> </div>
<div class="form-row">
<div class="form-group col-4"> <!-- Gamertag inputs - will be shown when game is selected -->
<label for="trn_username"><i class="fas fa-chart-line"></i> TRN Username</label> <div id="gamertag-section" style="display: none;">
<input type="text" id="trn_username" name="trn_username" value="{{ user.trn_username or '' }}" placeholder="Your Tracker Network username"> <hr class="section-divider">
<small class="form-text text-muted">Others can click your TRN to view your stats on tracker.gg.</small> <h4 class="section-title"><i class="fas fa-chart-line"></i> Gamertags for TRN</h4>
<p class="text-muted small">Enter your gamertag for each selected game to link to your Tracker Network profile.</p>
{% for game in esport_games %}
{% set gamertag_data = user_gamertags.get(game) %}
<div class="gamertag-input-row" data-game="{{ game }}" style="display: none; margin-bottom: 15px; padding: 15px; background: #f9fafb; border-radius: 8px;">
<h5 style="margin-top: 0; margin-bottom: 10px;">{{ game }}</h5>
<div class="form-row">
<div class="form-group col-6">
<label for="gamertag_{{ game }}">Gamertag</label>
<input type="text" id="gamertag_{{ game }}" name="gamertag_{{ game }}" value="{{ gamertag_data.gamertag if gamertag_data else '' }}" placeholder="Your {{ game }} gamertag">
</div>
{% if game_platforms.get(game) %}
<div class="form-group col-6">
<label for="platform_{{ game }}">Platform</label>
<select id="platform_{{ game }}" name="platform_{{ game }}">
<option value="">Select Platform</option>
{% for platform in game_platforms[game] %}
<option value="{{ platform }}" {% if gamertag_data and gamertag_data.platform == platform %}selected{% endif %}>{{ platform }}</option>
{% endfor %}
</select>
</div>
{% endif %}
</div>
</div> </div>
<div class="form-group col-4"> {% endfor %}
</div>
<div class="form-row">
<div class="form-group col-6">
<label for="discord_username"><i class="fab fa-discord"></i> Discord Username</label> <label for="discord_username"><i class="fab fa-discord"></i> Discord Username</label>
<input type="text" id="discord_username" name="discord_username" value="{{ user.discord_username or '' }}" placeholder="e.g. Name#1234"> <input type="text" id="discord_username" name="discord_username" value="{{ user.discord_username or '' }}" placeholder="e.g. Name#1234">
</div> </div>
<div class="form-group col-4"> <div class="form-group col-6">
<label for="league_os_profile"><i class="fas fa-link"></i> League OS Connection</label> <label for="league_os_profile"><i class="fas fa-link"></i> League OS Connection</label>
<input type="text" id="league_os_profile" name="league_os_profile" value="{{ user.league_os_profile or '' }}" placeholder="League OS profile link or ID"> <input type="text" id="league_os_profile" name="league_os_profile" value="{{ user.league_os_profile or '' }}" placeholder="League OS profile link or ID">
</div> </div>
@@ -137,6 +164,45 @@
</style> </style>
<script> <script>
var GAME_PLATFORMS = {{ game_platforms|tojson }};
// Show/hide gamertag inputs when games are checked
function toggleGamertagInputs() {
var selectedGames = [];
document.querySelectorAll('input[name="games"]:checked').forEach(function(cb) {
selectedGames.push(cb.value);
});
if (selectedGames.length > 0) {
document.getElementById('gamertag-section').style.display = 'block';
} else {
document.getElementById('gamertag-section').style.display = 'none';
}
document.querySelectorAll('.gamertag-input-row').forEach(function(row) {
if (selectedGames.includes(row.dataset.game)) {
row.style.display = 'block';
} else {
row.style.display = 'none';
}
});
}
// Initialize on page load
document.addEventListener('DOMContentLoaded', function() {
// Set up event listeners for game checkboxes
document.querySelectorAll('input[name="games"]').forEach(function(cb) {
cb.addEventListener('change', toggleGamertagInputs);
});
// Show gamertag inputs for already selected games
toggleGamertagInputs();
{% if user.role == 'player' %}
renderDisponibilityGrid();
{% endif %}
});
{% if user.role == 'player' %} {% if user.role == 'player' %}
// Generate time slots from 5pm (17:00) to 12am (24:00) // Generate time slots from 5pm (17:00) to 12am (24:00)
var TIME_SLOTS = []; var TIME_SLOTS = [];
@@ -302,8 +368,6 @@ function clearDisponibilities() {
} }
}); });
} }
document.addEventListener('DOMContentLoaded', renderDisponibilityGrid);
{% endif %} {% endif %}
</script> </script>
{% endblock %} {% endblock %}
+71 -8
View File
@@ -54,17 +54,45 @@
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
<div class="form-row">
<div class="form-group col-4"> <!-- Gamertag inputs - will be shown when game is selected -->
<label for="trn_username">TRN (Tracker Network) Username</label> <div id="gamertag-section" style="display: none;">
<input type="text" id="trn_username" name="trn_username" value="{{ user.trn_username or '' }}" placeholder="Tracker Network username"> <hr class="section-divider">
<h4 class="section-title"><i class="fas fa-chart-line"></i> Gamertags for TRN</h4>
<p class="text-muted small">Enter gamertag for each selected game to link to Tracker Network.</p>
{% for game in esport_games %}
{% set gamertag_data = user_gamertags.get(game) %}
<div class="gamertag-input-row" data-game="{{ game }}" style="display: none; margin-bottom: 15px; padding: 15px; background: #f9fafb; border-radius: 8px;">
<h5 style="margin-top: 0; margin-bottom: 10px;">{{ game }}</h5>
<div class="form-row">
<div class="form-group col-6">
<label for="gamertag_{{ game }}">Gamertag</label>
<input type="text" id="gamertag_{{ game }}" name="gamertag_{{ game }}" value="{{ gamertag_data.gamertag if gamertag_data else '' }}" placeholder="Gamertag">
</div>
{% if game_platforms.get(game) %}
<div class="form-group col-6">
<label for="platform_{{ game }}">Platform</label>
<select id="platform_{{ game }}" name="platform_{{ game }}">
<option value="">Select Platform</option>
{% for platform in game_platforms[game] %}
<option value="{{ platform }}" {% if gamertag_data and gamertag_data.platform == platform %}selected{% endif %}>{{ platform }}</option>
{% endfor %}
</select>
</div>
{% endif %}
</div>
</div> </div>
<div class="form-group col-4"> {% endfor %}
<label for="discord_username">Discord Username</label> </div>
<div class="form-row">
<div class="form-group col-6">
<label for="discord_username"><i class="fab fa-discord"></i> Discord Username</label>
<input type="text" id="discord_username" name="discord_username" value="{{ user.discord_username or '' }}" placeholder="e.g. Name#1234"> <input type="text" id="discord_username" name="discord_username" value="{{ user.discord_username or '' }}" placeholder="e.g. Name#1234">
</div> </div>
<div class="form-group col-4"> <div class="form-group col-6">
<label for="league_os_profile">League OS Connection</label> <label for="league_os_profile"><i class="fas fa-link"></i> League OS Connection</label>
<input type="text" id="league_os_profile" name="league_os_profile" value="{{ user.league_os_profile or '' }}" placeholder="League OS profile link or ID"> <input type="text" id="league_os_profile" name="league_os_profile" value="{{ user.league_os_profile or '' }}" placeholder="League OS profile link or ID">
</div> </div>
</div> </div>
@@ -80,4 +108,39 @@
</form> </form>
</div> </div>
</div> </div>
<script>
// Show/hide gamertag inputs when games are checked
function toggleGamertagInputs() {
var selectedGames = [];
document.querySelectorAll('input[name="games"]:checked').forEach(function(cb) {
selectedGames.push(cb.value);
});
if (selectedGames.length > 0) {
document.getElementById('gamertag-section').style.display = 'block';
} else {
document.getElementById('gamertag-section').style.display = 'none';
}
document.querySelectorAll('.gamertag-input-row').forEach(function(row) {
if (selectedGames.includes(row.dataset.game)) {
row.style.display = 'block';
} else {
row.style.display = 'none';
}
});
}
// Initialize on page load
document.addEventListener('DOMContentLoaded', function() {
// Set up event listeners for game checkboxes
document.querySelectorAll('input[name="games"]').forEach(function(cb) {
cb.addEventListener('change', toggleGamertagInputs);
});
// Show gamertag inputs for already selected games
toggleGamertagInputs();
});
</script>
{% endblock %} {% endblock %}
+13 -5
View File
@@ -76,12 +76,20 @@
<div class="detail-item"> <div class="detail-item">
<span class="detail-label"><i class="fas fa-chart-line"></i> TRN (Tracker Network)</span> <span class="detail-label"><i class="fas fa-chart-line"></i> TRN (Tracker Network)</span>
<span class="detail-value"> <span class="detail-value">
{% if user.trn_username %} {% if user.gamertags %}
<a href="https://tracker.gg" target="_blank" rel="noopener noreferrer" class="trn-link"> <div style="display: flex; flex-direction: column; gap: 8px;">
<i class="fas fa-external-link-alt"></i> {{ user.trn_username }} {% for gamertag in user.gamertags %}
</a> <div>
<span class="badge badge-esport" style="margin-right: 8px;">{{ gamertag.game }}</span>
<a href="{{ gamertag.get_trn_url() }}" target="_blank" rel="noopener noreferrer" class="trn-link">
<i class="fas fa-external-link-alt"></i> {{ gamertag.gamertag }}
{% if gamertag.platform %}<small>({{ gamertag.platform }})</small>{% endif %}
</a>
</div>
{% endfor %}
</div>
{% else %} {% else %}
<span class="text-muted">Not connected</span> <span class="text-muted">Not connected</span>
{% endif %} {% endif %}
</span> </span>
</div> </div>