Updated code to populate database
This commit is contained in:
parent
1b36a283d5
commit
aabc01382c
@ -1,6 +1,6 @@
|
||||
# HKFC Men's D Team - MOTM (Man of the Match) System
|
||||
# HKFC Men's C Team - MOTM (Man of the Match) System
|
||||
|
||||
This is a standalone Flask application for managing Man of the Match and Dick of the Day voting for the HKFC Men's D Team hockey club.
|
||||
This is a standalone Flask application for managing Man of the Match and Dick of the Day voting for the HKFC Men's C Team hockey club.
|
||||
|
||||
## Features
|
||||
|
||||
@ -113,11 +113,11 @@ The application will be available at `http://localhost:5000`
|
||||
## Database Requirements
|
||||
|
||||
The application requires access to the following database tables:
|
||||
- `_hkfcD_matchSquad` - Current match squad
|
||||
- `_hkfcC_matchSquad` - Current match squad
|
||||
- `_HKFC_players` - Player database
|
||||
- `hkfcDAdminSettings` - Admin configuration
|
||||
- `hkfcCAdminSettings` - Admin configuration
|
||||
- `hockeyFixtures` - Match fixtures
|
||||
- `_hkfc_d_motm` - MOTM/DotD voting results
|
||||
- `_hkfc_c_motm` - MOTM/DotD voting results
|
||||
- `_motmComments` - Match comments
|
||||
- `_clubTeams` - Club and team information
|
||||
- `mensHockeyClubs` - Club logos and information
|
||||
|
||||
@ -231,7 +231,9 @@ def fetch_all(sql_command, params=None):
|
||||
result = session.execute(sql_command, params)
|
||||
else:
|
||||
result = session.execute(sql_command)
|
||||
return result.fetchall()
|
||||
rows = result.fetchall()
|
||||
# Convert to list of dictionaries for compatibility
|
||||
return [dict(row._mapping) for row in rows] if rows else []
|
||||
except Exception as e:
|
||||
print(f"SQL Error: {e}")
|
||||
return []
|
||||
@ -246,7 +248,8 @@ def fetch_one(sql_command, params=None):
|
||||
result = session.execute(sql_command, params)
|
||||
else:
|
||||
result = session.execute(sql_command)
|
||||
return result.fetchone()
|
||||
row = result.fetchone()
|
||||
return dict(row._mapping) if row else None
|
||||
except Exception as e:
|
||||
print(f"SQL Error: {e}")
|
||||
return None
|
||||
@ -254,32 +257,31 @@ def fetch_one(sql_command, params=None):
|
||||
session.close()
|
||||
|
||||
# Legacy compatibility functions
|
||||
def sql_write(sql_cmd):
|
||||
def sql_write(sql_cmd, params=None):
|
||||
"""Legacy compatibility function for sql_write."""
|
||||
try:
|
||||
execute_sql(sql_cmd)
|
||||
execute_sql(sql_cmd, params)
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Write Error: {e}")
|
||||
return False
|
||||
|
||||
def sql_write_static(sql_cmd):
|
||||
def sql_write_static(sql_cmd, params=None):
|
||||
"""Legacy compatibility function for sql_write_static."""
|
||||
return sql_write(sql_cmd)
|
||||
return sql_write(sql_cmd, params)
|
||||
|
||||
def sql_read(sql_cmd):
|
||||
def sql_read(sql_cmd, params=None):
|
||||
"""Legacy compatibility function for sql_read."""
|
||||
try:
|
||||
result = fetch_all(sql_cmd)
|
||||
# Convert to list of dictionaries for compatibility
|
||||
return [dict(row) for row in result] if result else []
|
||||
result = fetch_all(sql_cmd, params)
|
||||
return result
|
||||
except Exception as e:
|
||||
print(f"Read Error: {e}")
|
||||
return []
|
||||
|
||||
def sql_read_static(sql_cmd):
|
||||
def sql_read_static(sql_cmd, params=None):
|
||||
"""Legacy compatibility function for sql_read_static."""
|
||||
return sql_read(sql_cmd)
|
||||
return sql_read(sql_cmd, params)
|
||||
|
||||
# Initialize database tables
|
||||
def init_database():
|
||||
|
||||
19
motm_app/database_config.ini
Normal file
19
motm_app/database_config.ini
Normal file
@ -0,0 +1,19 @@
|
||||
[DATABASE]
|
||||
type = postgresql
|
||||
sqlite_database_path = hockey_results.db
|
||||
|
||||
[MYSQL]
|
||||
host = localhost
|
||||
port = 3306
|
||||
database = hockey_results
|
||||
username = root
|
||||
password =
|
||||
charset = utf8mb4
|
||||
|
||||
[POSTGRESQL]
|
||||
host = icarus.ipa.champion
|
||||
port = 5432
|
||||
database = motm
|
||||
username = motm_user
|
||||
password = q7y7f7Lv*sODJZ2wGiv0Wq5a
|
||||
|
||||
@ -20,6 +20,9 @@ class DatabaseConfigManager:
|
||||
"""Manages database configuration and setup."""
|
||||
|
||||
def __init__(self, config_file='database_config.ini'):
|
||||
# Use absolute path to ensure we save in the right location
|
||||
if not os.path.isabs(config_file):
|
||||
config_file = os.path.join(os.path.dirname(__file__), config_file)
|
||||
self.config_file = config_file
|
||||
self.config = configparser.ConfigParser()
|
||||
self.load_config()
|
||||
@ -49,6 +52,8 @@ class DatabaseConfigManager:
|
||||
'username': 'postgres',
|
||||
'password': ''
|
||||
}
|
||||
# Save the default configuration to file
|
||||
self._save_config_file()
|
||||
|
||||
def save_config(self, form_data):
|
||||
"""Save configuration from form data."""
|
||||
@ -60,38 +65,42 @@ class DatabaseConfigManager:
|
||||
self.config['DATABASE']['sqlite_database_path'] = form_data['sqlite_database_path']
|
||||
|
||||
# Update MySQL settings
|
||||
if 'mysql_host' in form_data:
|
||||
self.config['MYSQL']['host'] = form_data['mysql_host']
|
||||
if 'mysql_port' in form_data:
|
||||
if 'mysql_host' in form_data and form_data['mysql_host'] is not None:
|
||||
self.config['MYSQL']['host'] = str(form_data['mysql_host'])
|
||||
if 'mysql_port' in form_data and form_data['mysql_port'] is not None:
|
||||
self.config['MYSQL']['port'] = str(form_data['mysql_port'])
|
||||
if 'mysql_database' in form_data:
|
||||
self.config['MYSQL']['database'] = form_data['mysql_database']
|
||||
if 'mysql_username' in form_data:
|
||||
self.config['MYSQL']['username'] = form_data['mysql_username']
|
||||
if 'mysql_password' in form_data:
|
||||
self.config['MYSQL']['password'] = form_data['mysql_password']
|
||||
if 'mysql_charset' in form_data:
|
||||
self.config['MYSQL']['charset'] = form_data['mysql_charset']
|
||||
if 'mysql_database' in form_data and form_data['mysql_database'] is not None:
|
||||
self.config['MYSQL']['database'] = str(form_data['mysql_database'])
|
||||
if 'mysql_username' in form_data and form_data['mysql_username'] is not None:
|
||||
self.config['MYSQL']['username'] = str(form_data['mysql_username'])
|
||||
if 'mysql_password' in form_data and form_data['mysql_password'] is not None:
|
||||
self.config['MYSQL']['password'] = str(form_data['mysql_password'])
|
||||
if 'mysql_charset' in form_data and form_data['mysql_charset'] is not None:
|
||||
self.config['MYSQL']['charset'] = str(form_data['mysql_charset'])
|
||||
|
||||
# Update PostgreSQL settings
|
||||
if 'postgres_host' in form_data:
|
||||
self.config['POSTGRESQL']['host'] = form_data['postgres_host']
|
||||
if 'postgres_port' in form_data:
|
||||
if 'postgres_host' in form_data and form_data['postgres_host'] is not None:
|
||||
self.config['POSTGRESQL']['host'] = str(form_data['postgres_host'])
|
||||
if 'postgres_port' in form_data and form_data['postgres_port'] is not None:
|
||||
self.config['POSTGRESQL']['port'] = str(form_data['postgres_port'])
|
||||
if 'postgres_database' in form_data:
|
||||
self.config['POSTGRESQL']['database'] = form_data['postgres_database']
|
||||
if 'postgres_username' in form_data:
|
||||
self.config['POSTGRESQL']['username'] = form_data['postgres_username']
|
||||
if 'postgres_password' in form_data:
|
||||
self.config['POSTGRESQL']['password'] = form_data['postgres_password']
|
||||
if 'postgres_database' in form_data and form_data['postgres_database'] is not None:
|
||||
self.config['POSTGRESQL']['database'] = str(form_data['postgres_database'])
|
||||
if 'postgres_username' in form_data and form_data['postgres_username'] is not None:
|
||||
self.config['POSTGRESQL']['username'] = str(form_data['postgres_username'])
|
||||
if 'postgres_password' in form_data and form_data['postgres_password'] is not None:
|
||||
self.config['POSTGRESQL']['password'] = str(form_data['postgres_password'])
|
||||
|
||||
# Save to file
|
||||
with open(self.config_file, 'w') as f:
|
||||
self.config.write(f)
|
||||
self._save_config_file()
|
||||
|
||||
# Update environment variables
|
||||
self._update_environment_variables()
|
||||
|
||||
def _save_config_file(self):
|
||||
"""Save configuration to file."""
|
||||
with open(self.config_file, 'w') as f:
|
||||
self.config.write(f)
|
||||
|
||||
def _update_environment_variables(self):
|
||||
"""Update environment variables based on configuration."""
|
||||
db_type = self.config['DATABASE']['type']
|
||||
@ -188,7 +197,7 @@ class DatabaseConfigManager:
|
||||
|
||||
session = get_db_session()
|
||||
try:
|
||||
# Create sample clubs
|
||||
# Create sample clubs (only if they don't exist)
|
||||
clubs_data = [
|
||||
{'hockey_club': 'HKFC', 'logo_url': '/static/images/hkfc_logo.png'},
|
||||
{'hockey_club': 'KCC', 'logo_url': '/static/images/kcc_logo.png'},
|
||||
@ -197,59 +206,72 @@ class DatabaseConfigManager:
|
||||
]
|
||||
|
||||
for club_data in clubs_data:
|
||||
club = Club(**club_data)
|
||||
session.add(club)
|
||||
# Check if club already exists
|
||||
existing_club = session.query(Club).filter_by(hockey_club=club_data['hockey_club']).first()
|
||||
if not existing_club:
|
||||
club = Club(**club_data)
|
||||
session.add(club)
|
||||
|
||||
# Create sample teams
|
||||
# Create sample teams (only if they don't exist)
|
||||
teams_data = [
|
||||
{'club': 'HKFC', 'team': 'A', 'display_name': 'HKFC A', 'league': 'Premier Division'},
|
||||
{'club': 'HKFC', 'team': 'B', 'display_name': 'HKFC B', 'league': 'Division 1'},
|
||||
{'club': 'HKFC', 'team': 'C', 'display_name': 'HKFC C', 'league': 'Division 2'},
|
||||
{'club': 'HKFC', 'team': 'D', 'display_name': 'HKFC D', 'league': 'Division 3'},
|
||||
]
|
||||
|
||||
for team_data in teams_data:
|
||||
team = Team(**team_data)
|
||||
session.add(team)
|
||||
# Check if team already exists
|
||||
existing_team = session.query(Team).filter_by(club=team_data['club'], team=team_data['team']).first()
|
||||
if not existing_team:
|
||||
team = Team(**team_data)
|
||||
session.add(team)
|
||||
|
||||
# Create sample players
|
||||
# Create sample players (only if they don't exist)
|
||||
players_data = [
|
||||
{'player_number': 1, 'player_forenames': 'John', 'player_surname': 'Smith', 'player_nickname': 'Smithers', 'player_team': 'HKFC D'},
|
||||
{'player_number': 2, 'player_forenames': 'Mike', 'player_surname': 'Jones', 'player_nickname': 'Jonesy', 'player_team': 'HKFC D'},
|
||||
{'player_number': 3, 'player_forenames': 'David', 'player_surname': 'Brown', 'player_nickname': 'Brownie', 'player_team': 'HKFC D'},
|
||||
{'player_number': 4, 'player_forenames': 'Chris', 'player_surname': 'Wilson', 'player_nickname': 'Willy', 'player_team': 'HKFC D'},
|
||||
{'player_number': 5, 'player_forenames': 'Tom', 'player_surname': 'Taylor', 'player_nickname': 'Tayls', 'player_team': 'HKFC D'},
|
||||
{'player_number': 1, 'player_forenames': 'John', 'player_surname': 'Smith', 'player_nickname': 'Smithers', 'player_team': 'HKFC C'},
|
||||
{'player_number': 2, 'player_forenames': 'Mike', 'player_surname': 'Jones', 'player_nickname': 'Jonesy', 'player_team': 'HKFC C'},
|
||||
{'player_number': 3, 'player_forenames': 'David', 'player_surname': 'Brown', 'player_nickname': 'Brownie', 'player_team': 'HKFC C'},
|
||||
{'player_number': 4, 'player_forenames': 'Chris', 'player_surname': 'Wilson', 'player_nickname': 'Willy', 'player_team': 'HKFC C'},
|
||||
{'player_number': 5, 'player_forenames': 'Tom', 'player_surname': 'Taylor', 'player_nickname': 'Tayls', 'player_team': 'HKFC C'},
|
||||
]
|
||||
|
||||
for player_data in players_data:
|
||||
player = Player(**player_data)
|
||||
session.add(player)
|
||||
# Check if player already exists
|
||||
existing_player = session.query(Player).filter_by(player_number=player_data['player_number']).first()
|
||||
if not existing_player:
|
||||
player = Player(**player_data)
|
||||
session.add(player)
|
||||
|
||||
# Create sample admin settings
|
||||
admin_settings = AdminSettings(
|
||||
userid='admin',
|
||||
next_fixture=1,
|
||||
next_club='KCC',
|
||||
next_team='KCC A',
|
||||
curr_motm=1,
|
||||
curr_dotd=2,
|
||||
oppo_logo='/static/images/kcc_logo.png',
|
||||
hkfc_logo='/static/images/hkfc_logo.png',
|
||||
motm_url_suffix='abc123',
|
||||
prev_fixture=0
|
||||
)
|
||||
session.add(admin_settings)
|
||||
# Create sample admin settings (only if they don't exist)
|
||||
existing_admin = session.query(AdminSettings).filter_by(userid='admin').first()
|
||||
if not existing_admin:
|
||||
admin_settings = AdminSettings(
|
||||
userid='admin',
|
||||
next_fixture=1,
|
||||
next_club='KCC',
|
||||
next_team='KCC A',
|
||||
curr_motm=1,
|
||||
curr_dotd=2,
|
||||
oppo_logo='/static/images/kcc_logo.png',
|
||||
hkfc_logo='/static/images/hkfc_logo.png',
|
||||
motm_url_suffix='abc123',
|
||||
prev_fixture=0
|
||||
)
|
||||
session.add(admin_settings)
|
||||
|
||||
# Create sample fixtures
|
||||
# Create sample fixtures (only if they don't exist)
|
||||
fixtures_data = [
|
||||
{'fixture_number': 1, 'date': datetime(2024, 1, 15), 'home_team': 'HKFC D', 'away_team': 'KCC A', 'venue': 'HKFC'},
|
||||
{'fixture_number': 2, 'date': datetime(2024, 1, 22), 'home_team': 'USRC A', 'away_team': 'HKFC D', 'venue': 'USRC'},
|
||||
{'fixture_number': 3, 'date': datetime(2024, 1, 29), 'home_team': 'HKFC D', 'away_team': 'Valley A', 'venue': 'HKFC'},
|
||||
{'fixture_number': 1, 'date': datetime(2024, 1, 15), 'home_team': 'HKFC C', 'away_team': 'KCC A', 'venue': 'HKFC'},
|
||||
{'fixture_number': 2, 'date': datetime(2024, 1, 22), 'home_team': 'USRC A', 'away_team': 'HKFC C', 'venue': 'USRC'},
|
||||
{'fixture_number': 3, 'date': datetime(2024, 1, 29), 'home_team': 'HKFC C', 'away_team': 'Valley A', 'venue': 'HKFC'},
|
||||
]
|
||||
|
||||
for fixture_data in fixtures_data:
|
||||
fixture = HockeyFixture(**fixture_data)
|
||||
session.add(fixture)
|
||||
# Check if fixture already exists
|
||||
existing_fixture = session.query(HockeyFixture).filter_by(fixture_number=fixture_data['fixture_number']).first()
|
||||
if not existing_fixture:
|
||||
fixture = HockeyFixture(**fixture_data)
|
||||
session.add(fixture)
|
||||
|
||||
session.commit()
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ class motmAdminForm(FlaskForm):
|
||||
|
||||
|
||||
class adminSettingsForm2(FlaskForm):
|
||||
nextMatch = SelectField('Fixture', choices=[])
|
||||
nextMatchDate = DateField('Match Date', format='%Y-%m-%d')
|
||||
nextOppoClub = StringField('Next Opposition Club:')
|
||||
nextOppoTeam = StringField("Next Opposition Team:")
|
||||
currMotM = SelectField('Current Man of the Match:', choices=[])
|
||||
@ -47,8 +47,7 @@ class DatabaseSetupForm(FlaskForm):
|
||||
|
||||
# SQLite fields
|
||||
sqlite_database_path = StringField('Database File Path',
|
||||
default='hockey_results.db',
|
||||
validators=[InputRequired()])
|
||||
default='hockey_results.db')
|
||||
|
||||
# MySQL/MariaDB fields
|
||||
mysql_host = StringField('Host', default='localhost')
|
||||
@ -73,3 +72,57 @@ class DatabaseSetupForm(FlaskForm):
|
||||
test_connection = SubmitField('Test Connection')
|
||||
save_config = SubmitField('Save Configuration')
|
||||
initialize_database = SubmitField('Initialize Database')
|
||||
|
||||
|
||||
class PlayerForm(FlaskForm):
|
||||
"""Form for adding/editing players."""
|
||||
|
||||
player_number = IntegerField('Player Number', validators=[InputRequired()])
|
||||
player_forenames = StringField('First Names', validators=[InputRequired()])
|
||||
player_surname = StringField('Surname', validators=[InputRequired()])
|
||||
player_nickname = StringField('Nickname', validators=[InputRequired()])
|
||||
player_team = SelectField('Team',
|
||||
choices=[('HKFC A', 'HKFC A'),
|
||||
('HKFC B', 'HKFC B'),
|
||||
('HKFC C', 'HKFC C')],
|
||||
default='HKFC C')
|
||||
|
||||
# Action buttons
|
||||
save_player = SubmitField('Save Player')
|
||||
cancel = SubmitField('Cancel')
|
||||
|
||||
|
||||
class ClubForm(FlaskForm):
|
||||
"""Form for adding/editing clubs."""
|
||||
|
||||
hockey_club = StringField('Club Name', validators=[InputRequired()])
|
||||
logo_url = StringField('Logo URL', validators=[InputRequired()])
|
||||
|
||||
# Action buttons
|
||||
save_club = SubmitField('Save Club')
|
||||
cancel = SubmitField('Cancel')
|
||||
|
||||
|
||||
class TeamForm(FlaskForm):
|
||||
"""Form for adding/editing teams."""
|
||||
|
||||
club = StringField('Club', validators=[InputRequired()])
|
||||
team = StringField('Team', validators=[InputRequired()])
|
||||
display_name = StringField('Display Name', validators=[InputRequired()])
|
||||
league = StringField('League', validators=[InputRequired()])
|
||||
|
||||
# Action buttons
|
||||
save_team = SubmitField('Save Team')
|
||||
cancel = SubmitField('Cancel')
|
||||
|
||||
|
||||
class DataImportForm(FlaskForm):
|
||||
"""Form for importing data from Hong Kong Hockey Association."""
|
||||
|
||||
import_clubs = BooleanField('Import Clubs', default=True)
|
||||
import_teams = BooleanField('Import Teams', default=True)
|
||||
import_players = BooleanField('Import Sample Players', default=False)
|
||||
|
||||
# Action buttons
|
||||
import_data = SubmitField('Import Data')
|
||||
cancel = SubmitField('Cancel')
|
||||
|
||||
425
motm_app/main.py
425
motm_app/main.py
@ -15,8 +15,9 @@ from flask_basicauth import BasicAuth
|
||||
from wtforms import StringField, PasswordField, BooleanField
|
||||
from wtforms import DateField
|
||||
from wtforms.validators import InputRequired, Email, Length
|
||||
from forms import motmForm, adminSettingsForm2, goalsAssistsForm, DatabaseSetupForm
|
||||
from forms import motmForm, adminSettingsForm2, goalsAssistsForm, DatabaseSetupForm, PlayerForm, ClubForm, TeamForm, DataImportForm
|
||||
from db_config import sql_write, sql_write_static, sql_read, sql_read_static
|
||||
from sqlalchemy import text
|
||||
from tables import matchSquadTable
|
||||
from readSettings import mySettings
|
||||
from db_setup import db_config_manager
|
||||
@ -37,10 +38,15 @@ def index():
|
||||
@app.route('/motm/<randomUrlSuffix>')
|
||||
def motm_vote(randomUrlSuffix):
|
||||
"""Public voting page for Man of the Match and Dick of the Day"""
|
||||
sql = "SELECT playerNumber, playerForenames, playerSurname, playerNickname FROM _hkfcD_matchSquad ORDER BY RAND()"
|
||||
sql2 = "SELECT nextClub, nextTeam, nextDate, oppoLogo, hkfcLogo, currMotM, currDotD, nextFixture FROM hkfcDAdminSettings"
|
||||
sql = "SELECT playerNumber, playerForenames, playerSurname, playerNickname FROM _hkfcC_matchSquad ORDER BY RAND()"
|
||||
sql2 = "SELECT nextClub, nextTeam, nextDate, oppoLogo, hkfcLogo, currMotM, currDotD, nextFixture FROM motmAdminSettings"
|
||||
rows = sql_read(sql)
|
||||
nextInfo = sql_read_static(sql2)
|
||||
|
||||
# Handle empty results
|
||||
if not nextInfo:
|
||||
return render_template('error.html', message="Database not initialized. Please go to Database Setup to initialize the database.")
|
||||
|
||||
nextClub = nextInfo[0]['nextClub']
|
||||
nextTeam = nextInfo[0]['nextTeam']
|
||||
nextFixture = nextInfo[0]['nextFixture']
|
||||
@ -49,25 +55,34 @@ def motm_vote(randomUrlSuffix):
|
||||
currMotM = nextInfo[0]['currMotM']
|
||||
currDotD = nextInfo[0]['currDotD']
|
||||
oppo = nextTeam
|
||||
sql3 = "SELECT hockeyResults2021.hockeyFixtures.date, hockeyResults.hkfcDAdminSettings.nextFixture FROM hockeyResults2021.hockeyFixtures INNER JOIN hockeyResults.hkfcDAdminSettings ON hockeyResults2021.hockeyFixtures.fixtureNumber = hockeyResults.hkfcDAdminSettings.nextFixture"
|
||||
sql3 = "SELECT hockeyResults2021.hockeyFixtures.date, hockeyResults.motmAdminSettings.nextFixture FROM hockeyResults2021.hockeyFixtures INNER JOIN hockeyResults.motmAdminSettings ON hockeyResults2021.hockeyFixtures.fixtureNumber = hockeyResults.motmAdminSettings.nextFixture"
|
||||
nextMatchDate = sql_read(sql3)
|
||||
if not nextMatchDate:
|
||||
return render_template('error.html', message="No fixtures found. Please initialize the database with sample data.")
|
||||
nextDate = nextMatchDate[0]['date']
|
||||
formatDate = datetime.strftime(nextDate, '%A, %d %B %Y')
|
||||
|
||||
sql3 = "SELECT playerPictureURL FROM _HKFC_players INNER JOIN hockeyResults.hkfcDAdminSettings ON _HKFC_players.playerNumber=hockeyResults.hkfcDAdminSettings.currMotM"
|
||||
sql4 = "SELECT playerPictureURL FROM _HKFC_players INNER JOIN hockeyResults.hkfcDAdminSettings ON _HKFC_players.playerNumber=hockeyResults.hkfcDAdminSettings.currDotD"
|
||||
sql3 = "SELECT playerPictureURL FROM _HKFC_players INNER JOIN hockeyResults.motmAdminSettings ON _HKFC_players.playerNumber=hockeyResults.motmAdminSettings.currMotM"
|
||||
sql4 = "SELECT playerPictureURL FROM _HKFC_players INNER JOIN hockeyResults.motmAdminSettings ON _HKFC_players.playerNumber=hockeyResults.motmAdminSettings.currDotD"
|
||||
motm = sql_read(sql3)
|
||||
dotd = sql_read(sql4)
|
||||
|
||||
# Handle empty results
|
||||
if not motm or not dotd:
|
||||
return render_template('error.html', message="Player data not found. Please initialize the database with sample data.")
|
||||
|
||||
motmURL = motm[0]['playerPictureURL']
|
||||
dotdURL = dotd[0]['playerPictureURL']
|
||||
|
||||
sql5 = "SELECT comment FROM _motmComments INNER JOIN hockeyResults.hkfcDAdminSettings ON _motmComments.matchDate=hockeyResults.hkfcDAdminSettings.nextDate ORDER BY RAND() LIMIT 1"
|
||||
sql5 = "SELECT comment FROM _motmComments INNER JOIN hockeyResults.motmAdminSettings ON _motmComments.matchDate=hockeyResults.motmAdminSettings.nextDate ORDER BY RAND() LIMIT 1"
|
||||
comment = sql_read(sql5)
|
||||
if comment == "":
|
||||
comment = "No comments added yet"
|
||||
form = motmForm()
|
||||
sql6 = "SELECT motmUrlSuffix FROM hockeyResults.hkfcDAdminSettings WHERE userid='admin'"
|
||||
sql6 = "SELECT motmUrlSuffix FROM hockeyResults.motmAdminSettings WHERE userid='admin'"
|
||||
urlSuff = sql_read_static(sql6)
|
||||
if not urlSuff:
|
||||
return render_template('error.html', message="Admin settings not found. Please initialize the database.")
|
||||
randomSuff = urlSuff[0]['motmUrlSuffix']
|
||||
print(randomSuff)
|
||||
if randomSuff == randomUrlSuffix:
|
||||
@ -79,8 +94,11 @@ def motm_vote(randomUrlSuffix):
|
||||
@app.route('/motm/comments', methods=['GET', 'POST'])
|
||||
def match_comments():
|
||||
"""Display and allow adding match comments"""
|
||||
sql = "SELECT nextClub, nextTeam, nextDate, oppoLogo, hkfcLogo FROM hkfcDAdminSettings"
|
||||
sql = "SELECT nextClub, nextTeam, nextDate, oppoLogo, hkfcLogo FROM motmAdminSettings"
|
||||
row = sql_read_static(sql)
|
||||
if not row:
|
||||
return render_template('error.html', message="Database not initialized. Please go to Database Setup to initialize the database.")
|
||||
|
||||
_oppo = row[0]['nextClub']
|
||||
commentDate = row[0]['nextDate'].strftime('%Y-%m-%d')
|
||||
_matchDate = row[0]['nextDate'].strftime('%Y_%m_%d')
|
||||
@ -109,8 +127,8 @@ def vote_thanks():
|
||||
_oppo = request.form['oppo']
|
||||
|
||||
if _motm and _dotd and request.method == 'POST':
|
||||
sql = "INSERT INTO _hkfc_d_motm (playerNumber, playerName, motmTotal, motm_" + _matchDate + ") SELECT playerNumber, playerNickname, '1', '1' FROM _HKFC_players WHERE playerNumber='" + _motm + "' ON DUPLICATE KEY UPDATE motmTotal = motmTotal + 1, motm_" + _matchDate + " = motm_" + _matchDate + " + 1"
|
||||
sql2 = "INSERT INTO _hkfc_d_motm (playerNumber, playerName, dotdTotal, dotd_" + _matchDate + ") SELECT playerNumber, playerNickname, '1', '1' FROM _HKFC_players WHERE playerNumber='" + _dotd + "' ON DUPLICATE KEY UPDATE dotdTotal = dotdTotal + 1, dotd_" + _matchDate + " = dotd_" + _matchDate + " + 1"
|
||||
sql = "INSERT INTO _hkfc_c_motm (playerNumber, playerName, motmTotal, motm_" + _matchDate + ") SELECT playerNumber, playerNickname, '1', '1' FROM _HKFC_players WHERE playerNumber='" + _motm + "' ON DUPLICATE KEY UPDATE motmTotal = motmTotal + 1, motm_" + _matchDate + " = motm_" + _matchDate + " + 1"
|
||||
sql2 = "INSERT INTO _hkfc_c_motm (playerNumber, playerName, dotdTotal, dotd_" + _matchDate + ") SELECT playerNumber, playerNickname, '1', '1' FROM _HKFC_players WHERE playerNumber='" + _dotd + "' ON DUPLICATE KEY UPDATE dotdTotal = dotdTotal + 1, dotd_" + _matchDate + " = dotd_" + _matchDate + " + 1"
|
||||
if _comments == "":
|
||||
print("No comment")
|
||||
elif _comments == "Optional comments added here":
|
||||
@ -147,28 +165,36 @@ def motm_admin():
|
||||
else:
|
||||
print('Activated')
|
||||
_nextTeam = request.form['nextOppoTeam']
|
||||
_nextFixture = request.form['nextMatch']
|
||||
_nextMatchDate = request.form['nextMatchDate']
|
||||
_currMotM = request.form['currMotM']
|
||||
_currDotD = request.form['currDotD']
|
||||
sql1 = "SELECT club FROM _clubTeams WHERE displayName='" + _nextTeam + "'"
|
||||
_nextClubName = sql_read_static(sql1)
|
||||
if not _nextClubName:
|
||||
flash('Error: Club not found for team ' + _nextTeam, 'error')
|
||||
return redirect(url_for('motm_admin'))
|
||||
_nextClub = _nextClubName[0]['club']
|
||||
sql = "UPDATE hkfcDAdminSettings SET nextFixture='" + _nextFixture + "', nextClub='" + _nextClub + "', nextTeam='" + _nextTeam + "', currMotM=" + _currMotM + ", currDotD=" + _currDotD + ""
|
||||
sql = "UPDATE motmAdminSettings SET nextDate='" + _nextMatchDate + "', nextClub='" + _nextClub + "', nextTeam='" + _nextTeam + "', currMotM=" + _currMotM + ", currDotD=" + _currDotD + ""
|
||||
sql_write_static(sql)
|
||||
sql2 = "UPDATE hkfcDAdminSettings INNER JOIN mensHockeyClubs ON hkfcDAdminSettings.nextClub = mensHockeyClubs.hockeyClub SET hkfcDAdminSettings.oppoLogo = mensHockeyClubs.logoURL WHERE mensHockeyClubs.hockeyClub='" + _nextClub + "'"
|
||||
sql2 = "UPDATE motmAdminSettings INNER JOIN mensHockeyClubs ON motmAdminSettings.nextClub = mensHockeyClubs.hockeyClub SET motmAdminSettings.oppoLogo = mensHockeyClubs.logoURL WHERE mensHockeyClubs.hockeyClub='" + _nextClub + "'"
|
||||
sql_write_static(sql2)
|
||||
if form.saveButton.data:
|
||||
flash('Settings saved!')
|
||||
urlSuffix = randomUrlSuffix(8)
|
||||
print(urlSuffix)
|
||||
sql3 = "UPDATE hkfcDAdminSettings SET motmUrlSuffix='" + urlSuffix + "' WHERE userid='admin'"
|
||||
sql3 = "UPDATE motmAdminSettings SET motmUrlSuffix='" + urlSuffix + "' WHERE userid='admin'"
|
||||
sql_write_static(sql3)
|
||||
flash('MotM URL https://hockey.ervine.cloud/motm/'+urlSuffix)
|
||||
elif form.activateButton.data:
|
||||
sql4 = "ALTER TABLE _hkfc_d_motm ADD COLUMN motm_" + _nextFixture + " smallint DEFAULT 0, ADD COLUMN dotd_" + _nextFixture + " smallint DEFAULT 0, ADD COLUMN assists_" + _nextFixture + " smallint DEFAULT 0, ADD COLUMN goals_" + _nextFixture + " smallint DEFAULT 0 "
|
||||
# Generate a fixture number based on the date
|
||||
_nextFixture = _nextMatchDate.replace('-', '')
|
||||
sql4 = "ALTER TABLE _hkfc_c_motm ADD COLUMN motm_" + _nextFixture + " smallint DEFAULT 0, ADD COLUMN dotd_" + _nextFixture + " smallint DEFAULT 0, ADD COLUMN assists_" + _nextFixture + " smallint DEFAULT 0, ADD COLUMN goals_" + _nextFixture + " smallint DEFAULT 0 "
|
||||
sql_write(sql4)
|
||||
sql5 = "SELECT motmUrlSuffix FROM hkfcDAdminSettings WHERE userid='admin'"
|
||||
sql5 = "SELECT motmUrlSuffix FROM motmAdminSettings WHERE userid='admin'"
|
||||
tempSuffix = sql_read_static(sql5)
|
||||
if not tempSuffix:
|
||||
flash('Error: Admin settings not found', 'error')
|
||||
return redirect(url_for('motm_admin'))
|
||||
currSuffix = tempSuffix[0]['motmUrlSuffix']
|
||||
print(currSuffix)
|
||||
flash('Man of the Match vote is now activated')
|
||||
@ -176,15 +202,31 @@ def motm_admin():
|
||||
else:
|
||||
flash('Something went wrong - check with Smithers')
|
||||
|
||||
sql7 = "SELECT date, homeTeam, awayTeam, venue, fixtureNumber FROM hockeyFixtures WHERE homeTeam='HKFC D' OR awayTeam='HKFC D'"
|
||||
matches = sql_read(sql7)
|
||||
form.nextMatch.choices = [(match['fixtureNumber'], match['date']) for match in matches]
|
||||
# Load current settings to populate the form
|
||||
sql_current = "SELECT nextDate FROM motmAdminSettings WHERE userid='admin'"
|
||||
current_settings = sql_read_static(sql_current)
|
||||
if current_settings:
|
||||
from datetime import datetime
|
||||
try:
|
||||
current_date = datetime.strptime(current_settings[0]['nextDate'], '%Y-%m-%d').date()
|
||||
form.nextMatchDate.data = current_date
|
||||
except:
|
||||
pass
|
||||
sql4 = "SELECT hockeyClub FROM mensHockeyClubs ORDER BY hockeyClub"
|
||||
sql5 = "SELECT nextClub, oppoLogo FROM hkfcDAdminSettings"
|
||||
sql6 = "SELECT playerNumber, playerForenames, playerSurname FROM _hkfcD_matchSquad_" + prevFixture + " ORDER BY playerForenames"
|
||||
sql5 = "SELECT nextClub, oppoLogo FROM motmAdminSettings"
|
||||
sql6 = "SELECT playerNumber, playerForenames, playerSurname FROM _hkfcC_matchSquad_" + prevFixture + " ORDER BY playerForenames"
|
||||
clubs = sql_read_static(sql4)
|
||||
settings = sql_read_static(sql5)
|
||||
players = sql_read(sql6)
|
||||
|
||||
# Handle empty results gracefully
|
||||
if not clubs:
|
||||
clubs = []
|
||||
if not settings:
|
||||
settings = [{'nextClub': 'Unknown', 'oppoLogo': '/static/images/default_logo.png'}]
|
||||
if not players:
|
||||
players = []
|
||||
|
||||
form.nextOppoClub.choices = [(oppo['hockeyClub'], oppo['hockeyClub']) for oppo in clubs]
|
||||
form.currMotM.choices = [(player['playerNumber'], player['playerForenames'] + " " + player['playerSurname']) for player in players]
|
||||
form.currDotD.choices = [(player['playerNumber'], player['playerForenames'] + " " + player['playerSurname']) for player in players]
|
||||
@ -193,15 +235,286 @@ def motm_admin():
|
||||
return render_template('motm_admin.html', form=form, nextOppoLogo=clubLogo)
|
||||
|
||||
|
||||
@app.route('/admin/players', methods=['GET'])
|
||||
@basic_auth.required
|
||||
def player_management():
|
||||
"""Admin page for managing players"""
|
||||
sql = text("SELECT playerNumber, playerForenames, playerSurname, playerNickname, playerTeam FROM _HKFC_players ORDER BY playerNumber")
|
||||
players = sql_read(sql)
|
||||
return render_template('player_management.html', players=players)
|
||||
|
||||
|
||||
@app.route('/admin/players/add', methods=['GET', 'POST'])
|
||||
@basic_auth.required
|
||||
def add_player():
|
||||
"""Add a new player"""
|
||||
form = PlayerForm()
|
||||
|
||||
if form.validate_on_submit():
|
||||
if form.save_player.data:
|
||||
# Check if player number already exists
|
||||
sql_check = text("SELECT playerNumber FROM _HKFC_players WHERE playerNumber = :player_number")
|
||||
existing = sql_read(sql_check, {'player_number': form.player_number.data})
|
||||
|
||||
if existing:
|
||||
flash('Player number already exists!', 'error')
|
||||
return render_template('add_player.html', form=form)
|
||||
|
||||
# Insert new player
|
||||
sql = text("INSERT INTO _HKFC_players (playerNumber, playerForenames, playerSurname, playerNickname, playerTeam) VALUES (:player_number, :forenames, :surname, :nickname, :team)")
|
||||
sql_write(sql, {
|
||||
'player_number': form.player_number.data,
|
||||
'forenames': form.player_forenames.data,
|
||||
'surname': form.player_surname.data,
|
||||
'nickname': form.player_nickname.data,
|
||||
'team': form.player_team.data
|
||||
})
|
||||
flash('Player added successfully!', 'success')
|
||||
return redirect(url_for('player_management'))
|
||||
elif form.cancel.data:
|
||||
return redirect(url_for('player_management'))
|
||||
|
||||
return render_template('add_player.html', form=form)
|
||||
|
||||
|
||||
@app.route('/admin/players/edit/<int:player_number>', methods=['GET', 'POST'])
|
||||
@basic_auth.required
|
||||
def edit_player(player_number):
|
||||
"""Edit an existing player"""
|
||||
form = PlayerForm()
|
||||
|
||||
if request.method == 'GET':
|
||||
# Load player data
|
||||
sql = text("SELECT playerNumber, playerForenames, playerSurname, playerNickname, playerTeam FROM _HKFC_players WHERE playerNumber = :player_number")
|
||||
player_data = sql_read(sql, {'player_number': player_number})
|
||||
|
||||
if not player_data:
|
||||
flash('Player not found!', 'error')
|
||||
return redirect(url_for('player_management'))
|
||||
|
||||
player = player_data[0]
|
||||
form.player_number.data = player['playerNumber']
|
||||
form.player_forenames.data = player['playerForenames']
|
||||
form.player_surname.data = player['playerSurname']
|
||||
form.player_nickname.data = player['playerNickname']
|
||||
form.player_team.data = player['playerTeam']
|
||||
|
||||
if form.validate_on_submit():
|
||||
if form.save_player.data:
|
||||
# Update player
|
||||
sql = text("UPDATE _HKFC_players SET playerForenames = :forenames, playerSurname = :surname, playerNickname = :nickname, playerTeam = :team WHERE playerNumber = :player_number")
|
||||
sql_write(sql, {
|
||||
'forenames': form.player_forenames.data,
|
||||
'surname': form.player_surname.data,
|
||||
'nickname': form.player_nickname.data,
|
||||
'team': form.player_team.data,
|
||||
'player_number': player_number
|
||||
})
|
||||
flash('Player updated successfully!', 'success')
|
||||
return redirect(url_for('player_management'))
|
||||
elif form.cancel.data:
|
||||
return redirect(url_for('player_management'))
|
||||
|
||||
return render_template('edit_player.html', form=form, player_number=player_number)
|
||||
|
||||
|
||||
@app.route('/admin/players/delete/<int:player_number>', methods=['POST'])
|
||||
@basic_auth.required
|
||||
def delete_player(player_number):
|
||||
"""Delete a player"""
|
||||
sql = text("DELETE FROM _HKFC_players WHERE playerNumber = :player_number")
|
||||
sql_write(sql, {'player_number': player_number})
|
||||
flash('Player deleted successfully!', 'success')
|
||||
return redirect(url_for('player_management'))
|
||||
|
||||
|
||||
@app.route('/admin/squad', methods=['GET'])
|
||||
@basic_auth.required
|
||||
def match_squad():
|
||||
"""Admin page for managing match squad"""
|
||||
sql1 = "SELECT team from _clubTeams WHERE club='HKFC' ORDER BY team"
|
||||
sql2 = "SELECT playerTeam, playerForenames, playerSurname, playerNickname, playerNumber FROM _HKFC_players"
|
||||
teams = sql_read(sql1)
|
||||
players = sql_read(sql2)
|
||||
return render_template('match_squad.html', teams=teams, players=players)
|
||||
sql = text("SELECT playerNumber, playerForenames, playerSurname, playerNickname, playerTeam FROM _HKFC_players ORDER BY playerTeam, playerNumber")
|
||||
players = sql_read(sql)
|
||||
return render_template('match_squad.html', players=players)
|
||||
|
||||
|
||||
# ==================== CLUB MANAGEMENT ====================
|
||||
|
||||
@app.route('/admin/clubs', methods=['GET'])
|
||||
@basic_auth.required
|
||||
def club_management():
|
||||
"""Admin page for managing clubs"""
|
||||
sql = text("SELECT id, hockey_club, logo_url FROM clubs ORDER BY hockey_club")
|
||||
clubs = sql_read(sql)
|
||||
return render_template('club_management.html', clubs=clubs)
|
||||
|
||||
|
||||
@app.route('/admin/clubs/add', methods=['GET', 'POST'])
|
||||
@basic_auth.required
|
||||
def add_club():
|
||||
"""Add a new club"""
|
||||
form = ClubForm()
|
||||
|
||||
if form.validate_on_submit():
|
||||
if form.save_club.data:
|
||||
# Check if club already exists
|
||||
sql_check = text("SELECT hockey_club FROM clubs WHERE hockey_club = :club_name")
|
||||
existing = sql_read(sql_check, {'club_name': form.hockey_club.data})
|
||||
|
||||
if existing:
|
||||
flash('Club already exists!', 'error')
|
||||
return render_template('add_club.html', form=form)
|
||||
|
||||
# Insert new club
|
||||
sql = text("INSERT INTO clubs (hockey_club, logo_url) VALUES (:club_name, :logo_url)")
|
||||
sql_write(sql, {
|
||||
'club_name': form.hockey_club.data,
|
||||
'logo_url': form.logo_url.data
|
||||
})
|
||||
flash('Club added successfully!', 'success')
|
||||
return redirect(url_for('club_management'))
|
||||
elif form.cancel.data:
|
||||
return redirect(url_for('club_management'))
|
||||
|
||||
return render_template('add_club.html', form=form)
|
||||
|
||||
|
||||
@app.route('/admin/clubs/edit/<int:club_id>', methods=['GET', 'POST'])
|
||||
@basic_auth.required
|
||||
def edit_club(club_id):
|
||||
"""Edit an existing club"""
|
||||
form = ClubForm()
|
||||
|
||||
if request.method == 'GET':
|
||||
# Load club data
|
||||
sql = text("SELECT id, hockey_club, logo_url FROM clubs WHERE id = :club_id")
|
||||
club_data = sql_read(sql, {'club_id': club_id})
|
||||
|
||||
if not club_data:
|
||||
flash('Club not found!', 'error')
|
||||
return redirect(url_for('club_management'))
|
||||
|
||||
club = club_data[0]
|
||||
form.hockey_club.data = club['hockey_club']
|
||||
form.logo_url.data = club['logo_url']
|
||||
|
||||
if form.validate_on_submit():
|
||||
if form.save_club.data:
|
||||
# Update club
|
||||
sql = text("UPDATE clubs SET hockey_club = :club_name, logo_url = :logo_url WHERE id = :club_id")
|
||||
sql_write(sql, {
|
||||
'club_name': form.hockey_club.data,
|
||||
'logo_url': form.logo_url.data,
|
||||
'club_id': club_id
|
||||
})
|
||||
flash('Club updated successfully!', 'success')
|
||||
return redirect(url_for('club_management'))
|
||||
elif form.cancel.data:
|
||||
return redirect(url_for('club_management'))
|
||||
|
||||
return render_template('edit_club.html', form=form, club_id=club_id)
|
||||
|
||||
|
||||
@app.route('/admin/clubs/delete/<int:club_id>', methods=['POST'])
|
||||
@basic_auth.required
|
||||
def delete_club(club_id):
|
||||
"""Delete a club"""
|
||||
sql = text("DELETE FROM clubs WHERE id = :club_id")
|
||||
sql_write(sql, {'club_id': club_id})
|
||||
flash('Club deleted successfully!', 'success')
|
||||
return redirect(url_for('club_management'))
|
||||
|
||||
|
||||
# ==================== TEAM MANAGEMENT ====================
|
||||
|
||||
@app.route('/admin/teams', methods=['GET'])
|
||||
@basic_auth.required
|
||||
def team_management():
|
||||
"""Admin page for managing teams"""
|
||||
sql = text("SELECT id, club, team, display_name, league FROM teams ORDER BY club, team")
|
||||
teams = sql_read(sql)
|
||||
return render_template('team_management.html', teams=teams)
|
||||
|
||||
|
||||
@app.route('/admin/teams/add', methods=['GET', 'POST'])
|
||||
@basic_auth.required
|
||||
def add_team():
|
||||
"""Add a new team"""
|
||||
form = TeamForm()
|
||||
|
||||
if form.validate_on_submit():
|
||||
if form.save_team.data:
|
||||
# Check if team already exists
|
||||
sql_check = text("SELECT club, team FROM teams WHERE club = :club AND team = :team")
|
||||
existing = sql_read(sql_check, {'club': form.club.data, 'team': form.team.data})
|
||||
|
||||
if existing:
|
||||
flash('Team already exists!', 'error')
|
||||
return render_template('add_team.html', form=form)
|
||||
|
||||
# Insert new team
|
||||
sql = text("INSERT INTO teams (club, team, display_name, league) VALUES (:club, :team, :display_name, :league)")
|
||||
sql_write(sql, {
|
||||
'club': form.club.data,
|
||||
'team': form.team.data,
|
||||
'display_name': form.display_name.data,
|
||||
'league': form.league.data
|
||||
})
|
||||
flash('Team added successfully!', 'success')
|
||||
return redirect(url_for('team_management'))
|
||||
elif form.cancel.data:
|
||||
return redirect(url_for('team_management'))
|
||||
|
||||
return render_template('add_team.html', form=form)
|
||||
|
||||
|
||||
@app.route('/admin/teams/edit/<int:team_id>', methods=['GET', 'POST'])
|
||||
@basic_auth.required
|
||||
def edit_team(team_id):
|
||||
"""Edit an existing team"""
|
||||
form = TeamForm()
|
||||
|
||||
if request.method == 'GET':
|
||||
# Load team data
|
||||
sql = text("SELECT id, club, team, display_name, league FROM teams WHERE id = :team_id")
|
||||
team_data = sql_read(sql, {'team_id': team_id})
|
||||
|
||||
if not team_data:
|
||||
flash('Team not found!', 'error')
|
||||
return redirect(url_for('team_management'))
|
||||
|
||||
team = team_data[0]
|
||||
form.club.data = team['club']
|
||||
form.team.data = team['team']
|
||||
form.display_name.data = team['display_name']
|
||||
form.league.data = team['league']
|
||||
|
||||
if form.validate_on_submit():
|
||||
if form.save_team.data:
|
||||
# Update team
|
||||
sql = text("UPDATE teams SET club = :club, team = :team, display_name = :display_name, league = :league WHERE id = :team_id")
|
||||
sql_write(sql, {
|
||||
'club': form.club.data,
|
||||
'team': form.team.data,
|
||||
'display_name': form.display_name.data,
|
||||
'league': form.league.data,
|
||||
'team_id': team_id
|
||||
})
|
||||
flash('Team updated successfully!', 'success')
|
||||
return redirect(url_for('team_management'))
|
||||
elif form.cancel.data:
|
||||
return redirect(url_for('team_management'))
|
||||
|
||||
return render_template('edit_team.html', form=form, team_id=team_id)
|
||||
|
||||
|
||||
@app.route('/admin/teams/delete/<int:team_id>', methods=['POST'])
|
||||
@basic_auth.required
|
||||
def delete_team(team_id):
|
||||
"""Delete a team"""
|
||||
sql = text("DELETE FROM teams WHERE id = :team_id")
|
||||
sql_write(sql, {'team_id': team_id})
|
||||
flash('Team deleted successfully!', 'success')
|
||||
return redirect(url_for('team_management'))
|
||||
|
||||
|
||||
@app.route('/admin/squad/submit', methods=['POST'])
|
||||
@ -210,9 +523,9 @@ def match_squad_submit():
|
||||
"""Process squad selection"""
|
||||
_playerNumbers = request.form.getlist('playerNumber')
|
||||
for _playerNumber in _playerNumbers:
|
||||
sql = "INSERT INTO _hkfcD_matchSquad (playerNumber, playerForenames, playerSurname, playerNickname) SELECT playerNumber, playerForenames, playerSurname, playerNickname FROM _HKFC_players WHERE playerNumber='" + _playerNumber + "'"
|
||||
sql = "INSERT INTO _hkfcC_matchSquad (playerNumber, playerForenames, playerSurname, playerNickname) SELECT playerNumber, playerForenames, playerSurname, playerNickname FROM _HKFC_players WHERE playerNumber='" + _playerNumber + "'"
|
||||
sql_write(sql)
|
||||
sql2 = "SELECT playerNumber, playerForenames, playerSurname, playerNickname FROM _hkfcD_matchSquad"
|
||||
sql2 = "SELECT playerNumber, playerForenames, playerSurname, playerNickname FROM _hkfcC_matchSquad"
|
||||
players = sql_read(sql2)
|
||||
table = matchSquadTable(players)
|
||||
table.border = True
|
||||
@ -224,7 +537,7 @@ def match_squad_submit():
|
||||
@basic_auth.required
|
||||
def match_squad_list():
|
||||
"""Display current squad list"""
|
||||
sql = "SELECT playerNumber, playerForenames, playerSurname, playerNickname FROM _hkfcD_matchSquad"
|
||||
sql = "SELECT playerNumber, playerForenames, playerSurname, playerNickname FROM _hkfcC_matchSquad"
|
||||
players = sql_read(sql)
|
||||
table = matchSquadTable(players)
|
||||
table.border = True
|
||||
@ -237,7 +550,7 @@ def match_squad_list():
|
||||
def delPlayerFromSquad():
|
||||
"""Remove player from squad"""
|
||||
_playerNumber = request.args['playerNumber']
|
||||
sql = "DELETE FROM _hkfcD_matchSquad WHERE playerNumber=" + _playerNumber + ""
|
||||
sql = "DELETE FROM _hkfcC_matchSquad WHERE playerNumber=" + _playerNumber + ""
|
||||
sql_write(sql)
|
||||
return render_template('player_removed.html', number=_playerNumber)
|
||||
|
||||
@ -248,9 +561,9 @@ def matchSquadReset():
|
||||
"""Reset squad for new match"""
|
||||
_matchNumber = str(mySettings('fixture'))
|
||||
print(_matchNumber)
|
||||
sql1 = "RENAME TABLE _hkfcD_matchSquad TO _hkfcD_matchSquad_" + _matchNumber + ""
|
||||
sql2 = "CREATE TABLE _hkfcD_matchSquad (playerNumber smallint UNIQUE, playerForenames varchar(50), playerSurname varchar(30), playerNickname varchar(30) NOT NULL, PRIMARY KEY (playerNumber))"
|
||||
sql3 = "UPDATE hkfcDAdminSettings SET prevFixture='" + _matchNumber + "'"
|
||||
sql1 = "RENAME TABLE _hkfcC_matchSquad TO _hkfcC_matchSquad_" + _matchNumber + ""
|
||||
sql2 = "CREATE TABLE _hkfcC_matchSquad (playerNumber smallint UNIQUE, playerForenames varchar(50), playerSurname varchar(30), playerNickname varchar(30) NOT NULL, PRIMARY KEY (playerNumber))"
|
||||
sql3 = "UPDATE motmAdminSettings SET prevFixture='" + _matchNumber + "'"
|
||||
sql_write(sql1)
|
||||
sql_write(sql2)
|
||||
sql_write_static(sql3)
|
||||
@ -262,10 +575,10 @@ def matchSquadReset():
|
||||
def stats_admin():
|
||||
"""Admin page for managing goals and assists statistics"""
|
||||
form = goalsAssistsForm()
|
||||
sql = "SELECT date, homeTeam, awayTeam, venue, fixtureNumber FROM hockeyFixtures WHERE homeTeam='HKFC D' OR awayTeam='HKFC D'"
|
||||
sql = "SELECT date, homeTeam, awayTeam, venue, fixtureNumber FROM hockeyFixtures WHERE homeTeam='HKFC C' OR awayTeam='HKFC C'"
|
||||
matches = sql_read(sql)
|
||||
form.match.choices = [(match['fixtureNumber'], match['date']) for match in matches]
|
||||
sql2 = "SELECT playerNumber, playerNickname FROM _hkfcD_matchSquad"
|
||||
sql2 = "SELECT playerNumber, playerNickname FROM _hkfcC_matchSquad"
|
||||
players = sql_read(sql2)
|
||||
return render_template('goals_assists_admin.html', data=players, form=form)
|
||||
|
||||
@ -282,7 +595,7 @@ def goalsAssistsSubmit():
|
||||
goals = request.form.getlist('goals')
|
||||
match = request.form['match']
|
||||
for idx, player in enumerate(playerNumber):
|
||||
sql = "INSERT INTO _hkfc_d_motm (playerNumber, playerName, assistsTotal, goalsTotal, assists_" + match + ", goals_" + match + ") SELECT playerNumber, playerNickname, '" + assists[idx] + "', '" + goals[idx] + "', '" + assists[idx] + "', '" + goals[idx] + "' FROM _HKFC_players WHERE playerNumber='" + player + "' ON DUPLICATE KEY UPDATE assistsTotal = assistsTotal + " + assists[idx] + ", goalsTotal = goalsTotal + " + goals[idx] + ", assists_" + match + " = " + assists[idx] + ", goals_" + match + " = " + goals[idx] + ""
|
||||
sql = "INSERT INTO _hkfc_c_motm (playerNumber, playerName, assistsTotal, goalsTotal, assists_" + match + ", goals_" + match + ") SELECT playerNumber, playerNickname, '" + assists[idx] + "', '" + goals[idx] + "', '" + assists[idx] + "', '" + goals[idx] + "' FROM _HKFC_players WHERE playerNumber='" + player + "' ON DUPLICATE KEY UPDATE assistsTotal = assistsTotal + " + assists[idx] + ", goalsTotal = goalsTotal + " + goals[idx] + ", assists_" + match + " = " + assists[idx] + ", goals_" + match + " = " + goals[idx] + ""
|
||||
sql_write(sql)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
@ -313,6 +626,8 @@ def admin_fixture_lookup(fixture):
|
||||
"""API endpoint for fixture team lookup"""
|
||||
sql = "SELECT homeTeam, awayTeam FROM hockeyFixtures WHERE fixtureNumber='" + fixture + "'"
|
||||
myteams = sql_read(sql)
|
||||
if not myteams:
|
||||
return jsonify({'error': 'Fixture not found'})
|
||||
if myteams[0]['homeTeam'].startswith("HKFC"):
|
||||
nextOppo = myteams[0]['awayTeam']
|
||||
else:
|
||||
@ -325,15 +640,21 @@ def admin_fixture_logo_lookup(fixture):
|
||||
"""API endpoint for fixture logo lookup"""
|
||||
sql = "SELECT homeTeam, awayTeam FROM hockeyFixtures WHERE fixtureNumber='" + fixture + "'"
|
||||
myteams = sql_read(sql)
|
||||
if myteams[0]['homeTeam'].startswith("HKFC D"):
|
||||
if not myteams:
|
||||
return jsonify({'error': 'Fixture not found'})
|
||||
if myteams[0]['homeTeam'].startswith("HKFC C"):
|
||||
nextOppo = myteams[0]['awayTeam']
|
||||
else:
|
||||
nextOppo = myteams[0]['homeTeam']
|
||||
sql2 = "SELECT club FROM _clubTeams WHERE displayName ='" + nextOppo + "'"
|
||||
clubs = sql_read_static(sql2)
|
||||
if not clubs:
|
||||
return jsonify({'error': 'Club not found'})
|
||||
clubName = clubs[0]['club']
|
||||
sql3 = "SELECT logoUrl FROM mensHockeyClubs WHERE hockeyClub ='" + clubName + "'"
|
||||
logo = sql_read_static(sql3)
|
||||
if not logo:
|
||||
return jsonify({'error': 'Logo not found'})
|
||||
clubLogo = logo[0]['logoUrl']
|
||||
return jsonify(clubLogo)
|
||||
|
||||
@ -343,7 +664,7 @@ def vote_results():
|
||||
"""API endpoint for voting results"""
|
||||
_matchDate = str(mySettings('fixture'))
|
||||
print(_matchDate)
|
||||
sql = "SELECT playerName, motm_" + _matchDate + ", dotd_" + _matchDate + " FROM _hkfc_d_motm WHERE (motm_" + _matchDate + " > '0') OR (dotd_" + _matchDate + " > '0')"
|
||||
sql = "SELECT playerName, motm_" + _matchDate + ", dotd_" + _matchDate + " FROM _hkfc_c_motm WHERE (motm_" + _matchDate + " > '0') OR (dotd_" + _matchDate + " > '0')"
|
||||
print(sql)
|
||||
rows = sql_read(sql)
|
||||
print(rows)
|
||||
@ -353,7 +674,7 @@ def vote_results():
|
||||
@app.route('/api/poty-results')
|
||||
def poty_results():
|
||||
"""API endpoint for Player of the Year results"""
|
||||
sql = "SELECT playerName, motmTotal, dotdTotal FROM _hkfc_d_motm WHERE (motmTotal > '0') OR (dotdTotal > '0')"
|
||||
sql = "SELECT playerName, motmTotal, dotdTotal FROM _hkfc_c_motm WHERE (motmTotal > '0') OR (dotdTotal > '0')"
|
||||
print(sql)
|
||||
rows = sql_read(sql)
|
||||
return json.dumps(rows)
|
||||
@ -382,14 +703,6 @@ def database_setup():
|
||||
"""Admin page for database setup and configuration"""
|
||||
form = DatabaseSetupForm()
|
||||
|
||||
# Load current configuration
|
||||
current_config = db_config_manager.get_config_dict()
|
||||
|
||||
# Populate form with current configuration
|
||||
for field_name, value in current_config.items():
|
||||
if hasattr(form, field_name):
|
||||
getattr(form, field_name).data = value
|
||||
|
||||
if request.method == 'POST':
|
||||
if form.test_connection.data:
|
||||
# Test database connection
|
||||
@ -452,6 +765,14 @@ def database_setup():
|
||||
except Exception as e:
|
||||
flash(f'❌ Database initialization failed: {str(e)}', 'error')
|
||||
|
||||
# Load current configuration for display
|
||||
current_config = db_config_manager.get_config_dict()
|
||||
|
||||
# Populate form with current configuration (only for GET requests or after POST processing)
|
||||
for field_name, value in current_config.items():
|
||||
if hasattr(form, field_name):
|
||||
getattr(form, field_name).data = value
|
||||
|
||||
return render_template('database_setup.html', form=form, current_config=current_config)
|
||||
|
||||
|
||||
@ -460,8 +781,10 @@ def database_setup():
|
||||
def database_status():
|
||||
"""Admin page showing current database status and configuration"""
|
||||
try:
|
||||
from database import db_config
|
||||
engine = db_config.engine
|
||||
# Reload database configuration to get latest settings
|
||||
from database import DatabaseConfig
|
||||
current_db_config = DatabaseConfig()
|
||||
engine = current_db_config.engine
|
||||
|
||||
# Test connection
|
||||
with engine.connect() as conn:
|
||||
@ -472,7 +795,7 @@ def database_status():
|
||||
|
||||
# Get database info
|
||||
db_info = {
|
||||
'database_url': str(db_config.database_url),
|
||||
'database_url': str(current_db_config.database_url),
|
||||
'database_type': os.getenv('DATABASE_TYPE', 'unknown'),
|
||||
'connection_status': connection_status
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ from db_config import sql_read_static
|
||||
|
||||
def mySettings(setting):
|
||||
try:
|
||||
sql = "SELECT " + setting + " FROM hkfcDAdminSettings WHERE userid='admin'"
|
||||
sql = "SELECT " + setting + " FROM motmAdminSettings WHERE userid='admin'"
|
||||
rows = sql_read_static(sql)
|
||||
if rows:
|
||||
return rows[0][setting]
|
||||
|
||||
74
motm_app/templates/add_club.html
Normal file
74
motm_app/templates/add_club.html
Normal file
@ -0,0 +1,74 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Add Club - HKFC Men's C Team</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Add New Club</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div class="alert alert-{{ 'danger' if category == 'error' else 'success' }} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<form method="POST">
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.hockey_club.label(class="form-label") }}
|
||||
{{ form.hockey_club(class="form-control") }}
|
||||
{% if form.hockey_club.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.hockey_club.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.logo_url.label(class="form-label") }}
|
||||
{{ form.logo_url(class="form-control") }}
|
||||
{% if form.logo_url.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.logo_url.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<small class="form-text text-muted">Enter the full URL to the club's logo image</small>
|
||||
</div>
|
||||
|
||||
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
|
||||
{{ form.cancel(class="btn btn-secondary me-md-2") }}
|
||||
{{ form.save_club(class="btn btn-primary") }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="/admin/clubs" class="btn btn-outline-secondary">Back to Club Management</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
109
motm_app/templates/add_player.html
Normal file
109
motm_app/templates/add_player.html
Normal file
@ -0,0 +1,109 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Add Player - HKFC Men's C Team</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Add New Player</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div class="alert alert-{{ 'danger' if category == 'error' else 'success' }} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<form method="POST">
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.player_number.label(class="form-label") }}
|
||||
{{ form.player_number(class="form-control") }}
|
||||
{% if form.player_number.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.player_number.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.player_forenames.label(class="form-label") }}
|
||||
{{ form.player_forenames(class="form-control") }}
|
||||
{% if form.player_forenames.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.player_forenames.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.player_surname.label(class="form-label") }}
|
||||
{{ form.player_surname(class="form-control") }}
|
||||
{% if form.player_surname.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.player_surname.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.player_nickname.label(class="form-label") }}
|
||||
{{ form.player_nickname(class="form-control") }}
|
||||
{% if form.player_nickname.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.player_nickname.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.player_team.label(class="form-label") }}
|
||||
{{ form.player_team(class="form-select") }}
|
||||
{% if form.player_team.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.player_team.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
|
||||
{{ form.cancel(class="btn btn-secondary me-md-2") }}
|
||||
{{ form.save_player(class="btn btn-primary") }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="/admin/players" class="btn btn-outline-secondary">Back to Player Management</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
101
motm_app/templates/add_team.html
Normal file
101
motm_app/templates/add_team.html
Normal file
@ -0,0 +1,101 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Add Team - HKFC Men's C Team</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Add New Team</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div class="alert alert-{{ 'danger' if category == 'error' else 'success' }} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<form method="POST">
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.club.label(class="form-label") }}
|
||||
{{ form.club(class="form-control") }}
|
||||
{% if form.club.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.club.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<small class="form-text text-muted">Enter the club name (e.g., HKFC, KCC, USRC)</small>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.team.label(class="form-label") }}
|
||||
{{ form.team(class="form-control") }}
|
||||
{% if form.team.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.team.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<small class="form-text text-muted">Enter the team identifier (e.g., A, B, C, 1st, 2nd)</small>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.display_name.label(class="form-label") }}
|
||||
{{ form.display_name(class="form-control") }}
|
||||
{% if form.display_name.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.display_name.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<small class="form-text text-muted">Enter the full display name (e.g., HKFC A, KCC 1st Team)</small>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.league.label(class="form-label") }}
|
||||
{{ form.league(class="form-control") }}
|
||||
{% if form.league.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.league.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<small class="form-text text-muted">Enter the league/division (e.g., Premier Division, Division 1)</small>
|
||||
</div>
|
||||
|
||||
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
|
||||
{{ form.cancel(class="btn btn-secondary me-md-2") }}
|
||||
{{ form.save_team(class="btn btn-primary") }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="/admin/teams" class="btn btn-outline-secondary">Back to Team Management</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
83
motm_app/templates/club_management.html
Normal file
83
motm_app/templates/club_management.html
Normal file
@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Club Management - HKFC Men's C Team</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-4">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1>Club Management</h1>
|
||||
<p class="lead">Manage hockey clubs in the database</p>
|
||||
|
||||
<div class="mb-3">
|
||||
<a href="/admin/clubs/add" class="btn btn-primary">Add New Club</a>
|
||||
<a href="/admin" class="btn btn-secondary">Back to Admin</a>
|
||||
</div>
|
||||
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div class="alert alert-{{ 'danger' if category == 'error' else 'success' }} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5>All Clubs</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if clubs %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Club Name</th>
|
||||
<th>Logo URL</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for club in clubs %}
|
||||
<tr>
|
||||
<td>{{ club.id }}</td>
|
||||
<td>{{ club.hockey_club }}</td>
|
||||
<td>
|
||||
<a href="{{ club.logo_url }}" target="_blank" class="text-decoration-none">
|
||||
{{ club.logo_url }}
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="/admin/clubs/edit/{{ club.id }}" class="btn btn-sm btn-outline-primary">Edit</a>
|
||||
<form method="POST" action="/admin/clubs/delete/{{ club.id }}" style="display: inline;" onsubmit="return confirm('Are you sure you want to delete this club?')">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger">Delete</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-info">
|
||||
<h5>No clubs found</h5>
|
||||
<p>There are no clubs in the database. <a href="/admin/clubs/add">Add the first club</a> to get started.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
74
motm_app/templates/edit_club.html
Normal file
74
motm_app/templates/edit_club.html
Normal file
@ -0,0 +1,74 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Edit Club - HKFC Men's C Team</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Edit Club #{{ club_id }}</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div class="alert alert-{{ 'danger' if category == 'error' else 'success' }} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<form method="POST">
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.hockey_club.label(class="form-label") }}
|
||||
{{ form.hockey_club(class="form-control") }}
|
||||
{% if form.hockey_club.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.hockey_club.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.logo_url.label(class="form-label") }}
|
||||
{{ form.logo_url(class="form-control") }}
|
||||
{% if form.logo_url.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.logo_url.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<small class="form-text text-muted">Enter the full URL to the club's logo image</small>
|
||||
</div>
|
||||
|
||||
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
|
||||
{{ form.cancel(class="btn btn-secondary me-md-2") }}
|
||||
{{ form.save_club(class="btn btn-primary") }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="/admin/clubs" class="btn btn-outline-secondary">Back to Club Management</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
103
motm_app/templates/edit_player.html
Normal file
103
motm_app/templates/edit_player.html
Normal file
@ -0,0 +1,103 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Edit Player - HKFC Men's C Team</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Edit Player #{{ player_number }}</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div class="alert alert-{{ 'danger' if category == 'error' else 'success' }} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<form method="POST">
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.player_number.label(class="form-label") }}
|
||||
{{ form.player_number(class="form-control", readonly=true) }}
|
||||
<small class="form-text text-muted">Player number cannot be changed</small>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.player_forenames.label(class="form-label") }}
|
||||
{{ form.player_forenames(class="form-control") }}
|
||||
{% if form.player_forenames.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.player_forenames.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.player_surname.label(class="form-label") }}
|
||||
{{ form.player_surname(class="form-control") }}
|
||||
{% if form.player_surname.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.player_surname.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.player_nickname.label(class="form-label") }}
|
||||
{{ form.player_nickname(class="form-control") }}
|
||||
{% if form.player_nickname.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.player_nickname.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.player_team.label(class="form-label") }}
|
||||
{{ form.player_team(class="form-select") }}
|
||||
{% if form.player_team.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.player_team.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
|
||||
{{ form.cancel(class="btn btn-secondary me-md-2") }}
|
||||
{{ form.save_player(class="btn btn-primary") }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="/admin/players" class="btn btn-outline-secondary">Back to Player Management</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
101
motm_app/templates/edit_team.html
Normal file
101
motm_app/templates/edit_team.html
Normal file
@ -0,0 +1,101 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Edit Team - HKFC Men's C Team</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Edit Team #{{ team_id }}</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div class="alert alert-{{ 'danger' if category == 'error' else 'success' }} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<form method="POST">
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.club.label(class="form-label") }}
|
||||
{{ form.club(class="form-control") }}
|
||||
{% if form.club.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.club.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<small class="form-text text-muted">Enter the club name (e.g., HKFC, KCC, USRC)</small>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.team.label(class="form-label") }}
|
||||
{{ form.team(class="form-control") }}
|
||||
{% if form.team.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.team.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<small class="form-text text-muted">Enter the team identifier (e.g., A, B, C, 1st, 2nd)</small>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.display_name.label(class="form-label") }}
|
||||
{{ form.display_name(class="form-control") }}
|
||||
{% if form.display_name.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.display_name.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<small class="form-text text-muted">Enter the full display name (e.g., HKFC A, KCC 1st Team)</small>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
{{ form.league.label(class="form-label") }}
|
||||
{{ form.league(class="form-control") }}
|
||||
{% if form.league.errors %}
|
||||
<div class="text-danger">
|
||||
{% for error in form.league.errors %}
|
||||
<small>{{ error }}</small>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<small class="form-text text-muted">Enter the league/division (e.g., Premier Division, Division 1)</small>
|
||||
</div>
|
||||
|
||||
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
|
||||
{{ form.cancel(class="btn btn-secondary me-md-2") }}
|
||||
{{ form.save_team(class="btn btn-primary") }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="/admin/teams" class="btn btn-outline-secondary">Back to Team Management</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,6 +1,6 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>HKFC Men's D Team - MOTM System</title>
|
||||
<title>HKFC Men's C Team - MOTM System</title>
|
||||
<link rel="stylesheet" media="screen" href ="/static/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
|
||||
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
|
||||
@ -11,7 +11,7 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1>HKFC Men's D Team - Man of the Match System</h1>
|
||||
<h1>HKFC Men's C Team - Man of the Match System</h1>
|
||||
<div class="jumbotron">
|
||||
<h2>Welcome to the MOTM Voting System</h2>
|
||||
<p>This system allows players to vote for Man of the Match and Dick of the Day, while providing admin tools for managing matches and squads.</p>
|
||||
@ -31,18 +31,34 @@
|
||||
<div class="col-md-6">
|
||||
<h3>Admin Section</h3>
|
||||
<div class="list-group">
|
||||
<a href="/admin/players" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Player Management</h4>
|
||||
<p class="list-group-item-text">Add, edit, and manage players in the database</p>
|
||||
</a>
|
||||
<a href="/admin/clubs" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Club Management</h4>
|
||||
<p class="list-group-item-text">Add, edit, and manage hockey clubs</p>
|
||||
</a>
|
||||
<a href="/admin/teams" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Team Management</h4>
|
||||
<p class="list-group-item-text">Add, edit, and manage hockey teams</p>
|
||||
</a>
|
||||
<a href="/admin/squad" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Match Squad Selection</h4>
|
||||
<p class="list-group-item-text">Select players for the match squad</p>
|
||||
</a>
|
||||
<a href="/admin/squad/list" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">View Current Squad</h4>
|
||||
<p class="list-group-item-text">View current match squad</p>
|
||||
</a>
|
||||
<a href="/admin/squad/reset" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Reset Squad</h4>
|
||||
<p class="list-group-item-text">Reset squad for new match</p>
|
||||
</a>
|
||||
<a href="/admin/motm" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">MOTM Admin</h4>
|
||||
<p class="list-group-item-text">Manage match settings and activate voting</p>
|
||||
</a>
|
||||
<a href="/admin/squad" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Squad Management</h4>
|
||||
<p class="list-group-item-text">Add players to match squads</p>
|
||||
</a>
|
||||
<a href="/admin/squad/list" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">View Squad</h4>
|
||||
<p class="list-group-item-text">View current match squad</p>
|
||||
</a>
|
||||
<a href="/admin/stats" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Goals & Assists</h4>
|
||||
<p class="list-group-item-text">Record goals and assists statistics</p>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>HKFC Men's D Team - Match Comments</title>
|
||||
<title>HKFC Men's C Team - Match Comments</title>
|
||||
<link rel="stylesheet" media="screen" href ="/static/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
|
||||
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
|
||||
|
||||
@ -1,200 +1,73 @@
|
||||
<html>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet">
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
#squadForm {
|
||||
background-color: #ffffff;
|
||||
margin: 100px auto;
|
||||
font-family: Raleway;
|
||||
padding: 40px;
|
||||
width: 40%;
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
input {
|
||||
padding: 10px;
|
||||
width: 10%;
|
||||
font-size: 17px;
|
||||
font-family: Raleway;
|
||||
border: 1px solid #aaaaaa;
|
||||
}
|
||||
|
||||
/* Mark input boxes that gets an error on validation: */
|
||||
input.invalid {
|
||||
background-color: #ffdddd;
|
||||
}
|
||||
|
||||
/* Hide all steps by default: */
|
||||
.tab {
|
||||
display: none;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: #4CAF50;
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
font-size: 17px;
|
||||
font-family: Raleway;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
#prevBtn {
|
||||
background-color: #bbbbbb;
|
||||
}
|
||||
|
||||
/* Make circles that indicate the steps of the form: */
|
||||
.step {
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
margin: 0 2px;
|
||||
background-color: #bbbbbb;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.step.active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Mark the steps that are finished and valid: */
|
||||
.step.finish {
|
||||
background-color: #4CAF50;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Match Squad Selection - HKFC Men's C Team</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<form id="squadForm" action="/admin/squad/submit" method="post">
|
||||
|
||||
<h1>Add Players to Squad</h1>
|
||||
|
||||
<!-- One "tab" for each step in the form: -->
|
||||
{% for team in teams %}
|
||||
<div class="tab">{{ team.team }} Team Players
|
||||
<p>
|
||||
{% for item in players %}
|
||||
{% if item.playerTeam == team.team %}
|
||||
<label><input type="checkbox" name="playerNumber" value="{{ item.playerNumber }}">{{ item.playerNumber }} {{ item.playerForenames }} {{ item.playerSurname }}</label>
|
||||
<br/>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<div style="overflow:auto;">
|
||||
<div style="float:right;">
|
||||
<button type="button" id="prevBtn" onclick="nextPrev(-1)">Previous</button>
|
||||
<button type="button" id="nextBtn" onclick="nextPrev(1)">Next</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Circles which indicates the steps of the form: -->
|
||||
<div style="text-align:center;margin-top:40px;">
|
||||
<span class="step"></span>
|
||||
<span class="step"></span>
|
||||
<span class="step"></span>
|
||||
<span class="step"></span>
|
||||
<span class="step"></span>
|
||||
<span class="step"></span>
|
||||
<span class="step"></span>
|
||||
<span class="step"></span>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<script>
|
||||
var currentTab = 0; // Current tab is set to be the first tab (0)
|
||||
showTab(currentTab); // Display the crurrent tab
|
||||
|
||||
function showTab(n) {
|
||||
// This function will display the specified tab of the form...
|
||||
var x = document.getElementsByClassName("tab");
|
||||
x[n].style.display = "block";
|
||||
//... and fix the Previous/Next buttons:
|
||||
if (n == 0) {
|
||||
document.getElementById("prevBtn").style.display = "none";
|
||||
} else {
|
||||
document.getElementById("prevBtn").style.display = "inline";
|
||||
}
|
||||
if (n == (x.length - 1)) {
|
||||
document.getElementById("nextBtn").innerHTML = "Submit";
|
||||
} else {
|
||||
document.getElementById("nextBtn").innerHTML = "Next";
|
||||
}
|
||||
//... and run a function that will display the correct step indicator:
|
||||
fixStepIndicator(n)
|
||||
}
|
||||
|
||||
function nextPrev(n) {
|
||||
// This function will figure out which tab to display
|
||||
var x = document.getElementsByClassName("tab");
|
||||
// Exit the function if any field in the current tab is invalid:
|
||||
// JDE ** Need to validate for this to work? ** if (n == 1 && !validateForm()) return false;
|
||||
// Hide the current tab:
|
||||
x[currentTab].style.display = "none";
|
||||
// Increase or decrease the current tab by 1:
|
||||
currentTab = currentTab + n;
|
||||
// if you have reached the end of the form...
|
||||
if (currentTab >= x.length) {
|
||||
// ... the form gets submitted:
|
||||
document.getElementById("squadForm").submit();
|
||||
return false;
|
||||
}
|
||||
// Otherwise, display the correct tab:
|
||||
showTab(currentTab);
|
||||
}
|
||||
|
||||
function validateForm() {
|
||||
// This function deals with validation of the form fields
|
||||
var x, y, i, valid = true;
|
||||
x = document.getElementsByClassName("tab");
|
||||
y = x[currentTab].getElementsByTagName("input");
|
||||
// A loop that checks every input field in the current tab:
|
||||
for (i = 0; i < y.length; i++) {
|
||||
// If a field is empty...
|
||||
if (y[i].value == "") {
|
||||
// add an "invalid" class to the field:
|
||||
y[i].className += " invalid";
|
||||
// and set the current valid status to false
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
// If the valid status is true, mark the step as finished and valid:
|
||||
if (valid) {
|
||||
document.getElementsByClassName("step")[currentTab].className += " finish";
|
||||
}
|
||||
return valid; // return the valid status
|
||||
}
|
||||
|
||||
function fixStepIndicator(n) {
|
||||
// This function removes the "active" class of all steps...
|
||||
var i, x = document.getElementsByClassName("step");
|
||||
for (i = 0; i < x.length; i++) {
|
||||
x[i].className = x[i].className.replace(" active", "");
|
||||
}
|
||||
//... and adds the "active" class on the current step:
|
||||
x[n].className += " active";
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="container mt-4">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1>Match Squad Selection</h1>
|
||||
<p class="lead">Select players for the match squad from the available players</p>
|
||||
|
||||
<div class="mb-3">
|
||||
<a href="/admin/players" class="btn btn-outline-primary">Manage Players</a>
|
||||
<a href="/admin" class="btn btn-secondary">Back to Admin</a>
|
||||
</div>
|
||||
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div class="alert alert-{{ 'danger' if category == 'error' else 'success' }} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
{% if players %}
|
||||
<form action="/admin/squad/submit" method="post">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5>Available Players</h5>
|
||||
<small class="text-muted">Select players to add to the match squad</small>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
{% for player in players %}
|
||||
<div class="col-md-4 mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="playerNumber" value="{{ player.playerNumber }}" id="player{{ player.playerNumber }}">
|
||||
<label class="form-check-label" for="player{{ player.playerNumber }}">
|
||||
<strong>#{{ player.playerNumber }}</strong> {{ player.playerForenames }} {{ player.playerSurname }}
|
||||
<br>
|
||||
<small class="text-muted">{{ player.playerNickname }} - {{ player.playerTeam }}</small>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="submit" class="btn btn-primary">Add Selected Players to Squad</button>
|
||||
<a href="/admin/squad/list" class="btn btn-outline-secondary">View Current Squad</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% else %}
|
||||
<div class="alert alert-warning">
|
||||
<h5>No players available</h5>
|
||||
<p>There are no players in the database. <a href="/admin/players/add">Add some players</a> before selecting a squad.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>HKFC Men's D Team - Match Squad Selected</title>
|
||||
<title>HKFC Men's C Team - Match Squad Selected</title>
|
||||
<link rel="stylesheet" media="screen" href ="/static/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
|
||||
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>HKFC Men's D Team - MotM and DotD vote admin</title>
|
||||
<title>HKFC Men's C Team - MotM and DotD vote admin</title>
|
||||
<link rel="stylesheet" media="screen" href ="/static/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
|
||||
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="/static/js/bootstrap.min.js"></script>
|
||||
</head>
|
||||
<h2>HKFC Men's D Team MotM and DotD online vote admin page</h2>
|
||||
<h2>HKFC Men's C Team MotM and DotD online vote admin page</h2>
|
||||
{% with messages = get_flashed_messages() %}
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
@ -23,7 +23,7 @@
|
||||
<dl>
|
||||
<p>
|
||||
{{ form.csrf_token }}
|
||||
<b>HKFC D Next Opponent:</b>
|
||||
<b>HKFC C Next Opponent:</b>
|
||||
<br/>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
@ -32,7 +32,7 @@
|
||||
<div class = "col-sm-6">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon" id="basic-addon1">Date:</span>
|
||||
{{ form.nextMatch(class_="form-control") }}
|
||||
{{ form.nextMatchDate(class_="form-control") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -74,32 +74,8 @@
|
||||
</dl>
|
||||
|
||||
<script>
|
||||
var match_select = document.getElementById("nextMatch");
|
||||
var club_logo = document.getElementById("nextOppoLogo");
|
||||
var team_select = document.getElementById("nextOppoTeam");
|
||||
|
||||
match_select.onchange = function() {myFunction()};
|
||||
|
||||
function myFunction() {
|
||||
|
||||
match = match_select.value;
|
||||
|
||||
fetch('/admin/api/fixture/' + match).then(function(response) {
|
||||
response.json().then(function(team) {
|
||||
var optionHTML = '';
|
||||
optionHTML += team;
|
||||
team_select.value = optionHTML;
|
||||
})
|
||||
|
||||
});
|
||||
fetch('/admin/api/fixture/' + match + '/logo').then(function(response) {
|
||||
response.json().then(function(logo) {
|
||||
var HTML = '';
|
||||
HTML += logo;
|
||||
club_logo.src = HTML;
|
||||
})
|
||||
});
|
||||
}
|
||||
// Date input functionality - no longer needed to fetch fixture data
|
||||
// The date input will be handled by the browser's native date picker
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>HKFC Men's D Team - MotM and DotD online vote</title>
|
||||
<title>HKFC Men's C Team - MotM and DotD online vote</title>
|
||||
<link rel="stylesheet" media="screen" href ="/static/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
|
||||
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="/static/js/bootstrap.min.js"></script>
|
||||
</head>
|
||||
<h3>HKFC Men's D Team MotM and DotD online vote</h3>
|
||||
<h3>HKFC Men's C Team MotM and DotD online vote</h3>
|
||||
<h5>{{ formatDate }}</h5>
|
||||
<h4><img src="{{ hkfcLogo }}" height="150"></img> <b> </b> <img src="{{ oppoLogo }}" height="140"></img></h4>
|
||||
<body>
|
||||
|
||||
87
motm_app/templates/player_management.html
Normal file
87
motm_app/templates/player_management.html
Normal file
@ -0,0 +1,87 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Player Management - HKFC Men's C Team</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-4">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1>Player Management</h1>
|
||||
<p class="lead">Manage players in the HKFC Men's C Team database</p>
|
||||
|
||||
<div class="mb-3">
|
||||
<a href="/admin/players/add" class="btn btn-primary">Add New Player</a>
|
||||
<a href="/admin" class="btn btn-secondary">Back to Admin</a>
|
||||
</div>
|
||||
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div class="alert alert-{{ 'danger' if category == 'error' else 'success' }} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5>All Players</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if players %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th>Number</th>
|
||||
<th>First Names</th>
|
||||
<th>Surname</th>
|
||||
<th>Nickname</th>
|
||||
<th>Team</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for player in players %}
|
||||
<tr>
|
||||
<td>{{ player.playerNumber }}</td>
|
||||
<td>{{ player.playerForenames }}</td>
|
||||
<td>{{ player.playerSurname }}</td>
|
||||
<td>{{ player.playerNickname }}</td>
|
||||
<td>
|
||||
<span class="badge bg-{{ 'primary' if player.playerTeam == 'HKFC C' else 'secondary' }}">
|
||||
{{ player.playerTeam }}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<a href="/admin/players/edit/{{ player.playerNumber }}" class="btn btn-sm btn-outline-primary">Edit</a>
|
||||
<form method="POST" action="/admin/players/delete/{{ player.playerNumber }}" style="display: inline;" onsubmit="return confirm('Are you sure you want to delete this player?')">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger">Delete</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-info">
|
||||
<h5>No players found</h5>
|
||||
<p>There are no players in the database. <a href="/admin/players/add">Add the first player</a> to get started.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
83
motm_app/templates/team_management.html
Normal file
83
motm_app/templates/team_management.html
Normal file
@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Team Management - HKFC Men's C Team</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-4">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1>Team Management</h1>
|
||||
<p class="lead">Manage hockey teams in the database</p>
|
||||
|
||||
<div class="mb-3">
|
||||
<a href="/admin/teams/add" class="btn btn-primary">Add New Team</a>
|
||||
<a href="/admin" class="btn btn-secondary">Back to Admin</a>
|
||||
</div>
|
||||
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div class="alert alert-{{ 'danger' if category == 'error' else 'success' }} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5>All Teams</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if teams %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Club</th>
|
||||
<th>Team</th>
|
||||
<th>Display Name</th>
|
||||
<th>League</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for team in teams %}
|
||||
<tr>
|
||||
<td>{{ team.id }}</td>
|
||||
<td>{{ team.club }}</td>
|
||||
<td>{{ team.team }}</td>
|
||||
<td>{{ team.display_name }}</td>
|
||||
<td>{{ team.league }}</td>
|
||||
<td>
|
||||
<a href="/admin/teams/edit/{{ team.id }}" class="btn btn-sm btn-outline-primary">Edit</a>
|
||||
<form method="POST" action="/admin/teams/delete/{{ team.id }}" style="display: inline;" onsubmit="return confirm('Are you sure you want to delete this team?')">
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger">Delete</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-info">
|
||||
<h5>No teams found</h5>
|
||||
<p>There are no teams in the database. <a href="/admin/teams/add">Add the first team</a> to get started.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,6 +1,6 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>HKFC Men's D Team - MotM and DotD vote</title>
|
||||
<title>HKFC Men's C Team - MotM and DotD vote</title>
|
||||
<link rel="stylesheet" media="screen" href ="/static/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
|
||||
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user