Refactored pages

This commit is contained in:
Jonny Ervine 2025-10-06 23:32:53 +08:00
parent a08897c5c2
commit d5350aa4cb
28 changed files with 2917 additions and 519 deletions

3
motm_app/=21.0.0 Normal file
View File

@ -0,0 +1,3 @@
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: gunicorn in /home/jonny/.local/lib/python3.13/site-packages (21.2.0)
Requirement already satisfied: packaging in /usr/lib/python3.13/site-packages (from gunicorn) (24.2)

View File

@ -0,0 +1,160 @@
# Production Deployment Guide
## WSGI Server Setup
Your Flask application now uses **Gunicorn** as the production WSGI server instead of the Flask development server.
### Files Added:
- `gunicorn.conf.py` - Gunicorn configuration file
- `run_production.py` - WSGI entry point
- `start_production.sh` - Production startup script
- `motm-app.service` - Systemd service file (optional)
## Quick Start (Recommended)
### 1. Install Dependencies
```bash
pip install -r requirements.txt
```
### 2. Start Production Server
```bash
# Option A: Use the startup script (easiest)
./start_production.sh
# Option B: Start manually
gunicorn -c gunicorn.conf.py run_production:app
# Option C: Quick start with default settings
gunicorn --bind 0.0.0.0:5000 --workers 4 run_production:app
```
## Configuration Details
### Gunicorn Configuration (`gunicorn.conf.py`)
- **Workers**: `CPU_COUNT * 2 + 1` (automatically calculated)
- **Worker Class**: `sync` (good for Flask applications)
- **Timeout**: 30 seconds
- **Max Requests**: 1000 per worker (prevents memory leaks)
- **Logging**: Standard output (can be redirected)
- **Preload**: Enabled for better performance
### Environment Variables
- `FLASK_ENV=production` (automatically set)
## Alternative WSGI Servers
If you prefer different WSGI servers:
### 1. uWSGI
```bash
pip install uwsgi
uwsgi --http 0.0.0.0:5000 --module run_production:app --processes 4 --threads 2
```
### 2. Waitress (Windows-friendly)
```bash
pip install waitress
waitress-serve --host=0.0.0.0 --port=5000 run_production:app
```
### 3. Gevent (for async workloads)
```bash
pip install gunicorn[gevent]
gunicorn -c gunicorn.conf.py --worker-class gevent run_production:app
```
## Production Recommendations
### 1. Use a Reverse Proxy
Place Nginx or Apache in front of Gunicorn:
**Nginx Example:**
```nginx
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
### 2. SSL/HTTPS
For production, always use HTTPS:
- Use Let's Encrypt for free SSL certificates
- Configure SSL in your reverse proxy
- Update Gunicorn config with SSL settings if needed
### 3. Process Management
Use systemd or supervisor to manage the Gunicorn process:
**Systemd (Linux):**
```bash
sudo cp motm-app.service /etc/systemd/system/
sudo systemctl enable motm-app
sudo systemctl start motm-app
sudo systemctl status motm-app
```
### 4. Monitoring
- Monitor worker processes and memory usage
- Set up log rotation
- Use tools like Prometheus + Grafana for metrics
## Performance Tuning
### Worker Count
- **CPU-bound**: `workers = CPU_COUNT * 2`
- **I/O-bound**: `workers = CPU_COUNT * 2 + 1` (current setting)
- **High concurrency**: Consider async workers (gevent/eventlet)
### Memory Management
- Current: `max_requests = 1000` (restarts workers periodically)
- Adjust based on your memory constraints
### Timeout Settings
- Current: `timeout = 30` seconds
- Increase if you have long-running requests
## Troubleshooting
### Common Issues:
1. **Permission denied**: Check file permissions and user/group settings
2. **Port already in use**: Change port in `gunicorn.conf.py` or kill existing process
3. **Memory issues**: Reduce worker count or increase `max_requests`
4. **Slow responses**: Increase timeout or worker count
### Logs:
- Gunicorn logs to stdout/stderr by default
- Check systemd logs: `journalctl -u motm-app`
- Redirect logs to files if needed
## Security Notes
1. **Never run as root** in production
2. **Use HTTPS** for all production traffic
3. **Set proper file permissions** on your application files
4. **Keep dependencies updated** regularly
5. **Use environment variables** for sensitive configuration
## Migration from Development
Your application is now ready for production! The key changes:
- ✅ Gunicorn WSGI server instead of Flask dev server
- ✅ Production-optimized configuration
- ✅ Proper worker management
- ✅ Security improvements
- ✅ Performance optimizations
**Next Steps:**
1. Test the production setup locally
2. Deploy to your production server
3. Set up reverse proxy (Nginx/Apache)
4. Configure SSL certificates
5. Set up monitoring and logging

52
motm_app/gunicorn.conf.py Normal file
View File

@ -0,0 +1,52 @@
# Gunicorn configuration file for production deployment
import multiprocessing
import os
# Server socket
bind = "0.0.0.0:5000"
backlog = 2048
# Worker processes
workers = multiprocessing.cpu_count() * 2 + 1
worker_class = "sync"
worker_connections = 1000
timeout = 30
keepalive = 2
# Restart workers after this many requests, to prevent memory leaks
max_requests = 1000
max_requests_jitter = 50
# Logging
accesslog = "-"
errorlog = "-"
loglevel = "info"
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %(D)s'
# Process naming
proc_name = "motm_app"
# Server mechanics
daemon = False
pidfile = "/tmp/motm_app.pid"
user = None
group = None
tmp_upload_dir = None
# SSL (uncomment and configure if using HTTPS)
# keyfile = "/path/to/keyfile"
# certfile = "/path/to/certfile"
# Preload app for better performance
preload_app = True
# Environment variables
raw_env = [
'FLASK_ENV=production',
]
# Security
limit_request_line = 4094
limit_request_fields = 100
limit_request_field_size = 8190

18
motm_app/motm-app.service Normal file
View File

@ -0,0 +1,18 @@
[Unit]
Description=MOTM App - Man of the Match Voting System
After=network.target
[Service]
Type=exec
User=www-data
Group=www-data
WorkingDirectory=/home/jonny/Projects/gcp-hockey-results/motm_app
Environment=PATH=/home/jonny/Projects/gcp-hockey-results/motm_app/venv/bin
Environment=FLASK_ENV=production
ExecStart=/home/jonny/Projects/gcp-hockey-results/motm_app/venv/bin/gunicorn -c gunicorn.conf.py run_production:app
ExecReload=/bin/kill -s HUP $MAINPID
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target

View File

@ -29,3 +29,6 @@ boto3>=1.34.0
# Legacy support (can be removed after migration)
flask-mysql
# Production WSGI server
gunicorn>=21.0.0

View File

@ -0,0 +1,12 @@
#!/usr/bin/env python3
"""
Production WSGI entry point for MOTM App
This file is used by Gunicorn to run the application in production
"""
from main import app
if __name__ == "__main__":
# This should not be called directly in production
# Use: gunicorn -c gunicorn.conf.py run_production:app
app.run(host='0.0.0.0', port=5000, debug=False)

26
motm_app/start_production.sh Executable file
View File

@ -0,0 +1,26 @@
#!/bin/bash
# Production startup script for MOTM App
echo "Starting MOTM App in production mode..."
# Check if virtual environment exists
if [ ! -d "venv" ]; then
echo "Creating virtual environment..."
python3 -m venv venv
fi
# Activate virtual environment
echo "Activating virtual environment..."
source venv/bin/activate
# Install/upgrade dependencies
echo "Installing dependencies..."
pip install --upgrade pip
pip install -r requirements.txt
# Set production environment
export FLASK_ENV=production
# Start Gunicorn
echo "Starting Gunicorn WSGI server..."
gunicorn -c gunicorn.conf.py run_production:app

View File

@ -1,219 +1,280 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Dashboard - 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">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
<style>
.admin-section {
margin-bottom: 30px;
}
.section-header {
background-color: #f5f5f5;
padding: 15px;
border-left: 4px solid #337ab7;
margin-bottom: 15px;
}
.card-custom {
transition: transform 0.2s;
}
.card-custom:hover {
transform: translateY(-5px);
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="page-header">
<h1>HKFC Men's C Team - Admin Dashboard</h1>
<p class="lead">Central hub for all administrative functions</p>
</div>
<div class="mb-3">
<a href="/" class="btn btn-default">Back to Main Page</a>
<a href="/admin/profile" class="btn btn-outline-secondary">Admin Profile</a>
</div>
<!-- Data Management Section -->
<div class="admin-section">
<div class="section-header">
<h3>Data Management</h3>
</div>
<div class="row">
<div class="col-md-3">
<div class="list-group card-custom">
<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</p>
</a>
</div>
</div>
<div class="col-md-3">
<div class="list-group card-custom">
<a href="/admin/clubs" class="list-group-item">
<h4 class="list-group-item-heading">Club Management</h4>
<p class="list-group-item-text">Manage hockey clubs</p>
</a>
</div>
</div>
<div class="col-md-3">
<div class="list-group card-custom">
<a href="/admin/teams" class="list-group-item">
<h4 class="list-group-item-heading">Team Management</h4>
<p class="list-group-item-text">Manage hockey teams</p>
</a>
</div>
</div>
<div class="col-md-3">
<div class="list-group card-custom">
<a href="/admin/import" class="list-group-item">
<h4 class="list-group-item-heading">Data Import</h4>
<p class="list-group-item-text">Import clubs and teams</p>
</a>
</div>
</div>
</div>
</div>
<!-- Match Management Section -->
<div class="admin-section">
<div class="section-header">
<h3>Match Management</h3>
</div>
<div class="row">
<div class="col-md-3">
<div class="list-group card-custom">
<a href="/admin/squad" class="list-group-item">
<h4 class="list-group-item-heading">Squad Selection</h4>
<p class="list-group-item-text">Select match squad</p>
</a>
</div>
</div>
<div class="col-md-3">
<div class="list-group card-custom">
<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 squad</p>
</a>
</div>
</div>
<div class="col-md-3">
<div class="list-group card-custom">
<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 for new match</p>
</a>
</div>
</div>
<div class="col-md-3">
<div class="list-group card-custom">
<a href="/admin/stats" class="list-group-item">
<h4 class="list-group-item-heading">Goals & Assists</h4>
<p class="list-group-item-text">Record statistics</p>
</a>
</div>
</div>
</div>
</div>
<!-- MOTM Management Section -->
<div class="admin-section">
<div class="section-header">
<h3>MOTM Management</h3>
</div>
<div class="row">
<div class="col-md-4">
<div class="list-group card-custom">
<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>
</div>
</div>
<div class="col-md-4">
<div class="list-group card-custom">
<a href="/admin/voting" class="list-group-item">
<h4 class="list-group-item-heading">Voting Results</h4>
<p class="list-group-item-text">View current match results</p>
</a>
</div>
</div>
<div class="col-md-4">
<div class="list-group card-custom">
<a href="/admin/motm/manage" class="list-group-item">
<h4 class="list-group-item-heading">MOTM Management</h4>
<p class="list-group-item-text">Reset MOTM/DotD counts for specific fixtures</p>
</a>
</div>
</div>
<div class="col-md-4">
<div class="list-group card-custom">
<a href="/admin/device-tracking" class="list-group-item">
<h4 class="list-group-item-heading">Device Tracking</h4>
<p class="list-group-item-text">Monitor voting patterns and detect duplicate votes</p>
</a>
</div>
</div>
<div class="col-md-4">
<div class="list-group card-custom">
<a href="/admin/poty" class="list-group-item">
<h4 class="list-group-item-heading">Player of the Year</h4>
<p class="list-group-item-text">View season standings</p>
</a>
</div>
</div>
</div>
</div>
<!-- System Management Section -->
<div class="admin-section">
<div class="section-header">
<h3>System Management</h3>
</div>
<div class="row">
<div class="col-md-3">
<div class="list-group card-custom">
<a href="/admin/database-setup" class="list-group-item">
<h4 class="list-group-item-heading">Database Setup</h4>
<p class="list-group-item-text">Configure and initialize database</p>
</a>
</div>
</div>
<div class="col-md-3">
<div class="list-group card-custom">
<a href="/admin/database-status" class="list-group-item">
<h4 class="list-group-item-heading">Database Status</h4>
<p class="list-group-item-text">View database configuration</p>
</a>
</div>
</div>
<div class="col-md-3">
<div class="list-group card-custom">
<a href="/admin/s3-config" class="list-group-item">
<h4 class="list-group-item-heading">S3 Configuration</h4>
<p class="list-group-item-text">Configure S3/MinIO storage</p>
</a>
</div>
</div>
<div class="col-md-3">
<div class="list-group card-custom">
<a href="/admin/s3-status" class="list-group-item">
<h4 class="list-group-item-heading">S3 Status</h4>
<p class="list-group-item-text">View S3/MinIO status</p>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
{% extends "base.html" %}
{% block title %}Admin Dashboard - HKFC Men's C Team MOTM System{% endblock %}
{% block content %}
<!-- Dashboard Header -->
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-body text-center">
<h1 class="card-title">
<i class="fas fa-tachometer-alt text-primary me-2"></i>
Admin Dashboard
</h1>
<p class="lead text-muted">Central hub for all administrative functions</p>
</div>
</div>
</body>
</html>
</div>
</div>
<!-- Quick Actions -->
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-header bg-primary text-white">
<h5 class="card-title mb-0">
<i class="fas fa-bolt me-2"></i>Quick Actions
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3 mb-3">
<a href="/admin/import" class="btn btn-outline-primary w-100">
<i class="fas fa-download me-2"></i>
<div class="text-start">
<div class="fw-bold">Import Data</div>
<small class="text-muted">Import from HKHA</small>
</div>
</a>
</div>
<div class="col-md-3 mb-3">
<a href="/admin/squad" class="btn btn-outline-success w-100">
<i class="fas fa-list-check me-2"></i>
<div class="text-start">
<div class="fw-bold">Select Squad</div>
<small class="text-muted">Choose match squad</small>
</div>
</a>
</div>
<div class="col-md-3 mb-3">
<a href="/admin/motm" class="btn btn-outline-warning w-100">
<i class="fas fa-trophy me-2"></i>
<div class="text-start">
<div class="fw-bold">MOTM Settings</div>
<small class="text-muted">Manage voting</small>
</div>
</a>
</div>
<div class="col-md-3 mb-3">
<a href="/admin/profile" class="btn btn-outline-secondary w-100">
<i class="fas fa-user-cog me-2"></i>
<div class="text-start">
<div class="fw-bold">Admin Profile</div>
<small class="text-muted">Account settings</small>
</div>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Data Management Section -->
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-header bg-success text-white">
<h5 class="card-title mb-0">
<i class="fas fa-database me-2"></i>Data Management
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-lg-4 mb-3">
<div class="card h-100 border-success">
<div class="card-header bg-light">
<h6 class="card-title mb-0">
<i class="fas fa-users text-success me-2"></i>Club Management
</h6>
</div>
<div class="card-body">
<p class="card-text">Manage hockey clubs, logos, and club information.</p>
<div class="d-grid gap-2">
<a href="/admin/clubs" class="btn btn-success">
<i class="fas fa-eye me-2"></i>View Clubs
</a>
<a href="/admin/clubs/add" class="btn btn-outline-success">
<i class="fas fa-plus me-2"></i>Add Club
</a>
</div>
</div>
</div>
</div>
<div class="col-lg-4 mb-3">
<div class="card h-100 border-primary">
<div class="card-header bg-light">
<h6 class="card-title mb-0">
<i class="fas fa-user text-primary me-2"></i>Player Management
</h6>
</div>
<div class="card-body">
<p class="card-text">Add, edit, and manage player information and squads.</p>
<div class="d-grid gap-2">
<a href="/admin/players" class="btn btn-primary">
<i class="fas fa-eye me-2"></i>View Players
</a>
<a href="/admin/players/add" class="btn btn-outline-primary">
<i class="fas fa-plus me-2"></i>Add Player
</a>
</div>
</div>
</div>
</div>
<div class="col-lg-4 mb-3">
<div class="card h-100 border-info">
<div class="card-header bg-light">
<h6 class="card-title mb-0">
<i class="fas fa-layer-group text-info me-2"></i>Team Management
</h6>
</div>
<div class="card-body">
<p class="card-text">Manage hockey teams and their associations with clubs.</p>
<div class="d-grid gap-2">
<a href="/admin/teams" class="btn btn-info">
<i class="fas fa-eye me-2"></i>View Teams
</a>
<a href="/admin/teams/add" class="btn btn-outline-info">
<i class="fas fa-plus me-2"></i>Add Team
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- System Management Section -->
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-header bg-warning text-dark">
<h5 class="card-title mb-0">
<i class="fas fa-cogs me-2"></i>System Management
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-lg-4 mb-3">
<div class="card h-100 border-warning">
<div class="card-header bg-light">
<h6 class="card-title mb-0">
<i class="fas fa-cloud text-warning me-2"></i>S3 Storage
</h6>
</div>
<div class="card-body">
<p class="card-text">Configure and manage S3 storage for assets and logos.</p>
<div class="d-grid gap-2">
<a href="/admin/s3-config" class="btn btn-warning">
<i class="fas fa-cog me-2"></i>Configure S3
</a>
<a href="/admin/s3-status" class="btn btn-outline-warning">
<i class="fas fa-info-circle me-2"></i>View Status
</a>
</div>
</div>
</div>
</div>
<div class="col-lg-4 mb-3">
<div class="card h-100 border-secondary">
<div class="card-header bg-light">
<h6 class="card-title mb-0">
<i class="fas fa-database text-secondary me-2"></i>Database
</h6>
</div>
<div class="card-body">
<p class="card-text">Manage database configuration and status.</p>
<div class="d-grid gap-2">
<a href="/admin/database-status" class="btn btn-secondary">
<i class="fas fa-info-circle me-2"></i>Database Status
</a>
<a href="/admin/database-setup" class="btn btn-outline-secondary">
<i class="fas fa-wrench me-2"></i>Database Setup
</a>
</div>
</div>
</div>
</div>
<div class="col-lg-4 mb-3">
<div class="card h-100 border-dark">
<div class="card-header bg-light">
<h6 class="card-title mb-0">
<i class="fas fa-list-check text-dark me-2"></i>Squad Management
</h6>
</div>
<div class="card-body">
<p class="card-text">Manage match squads and player selections.</p>
<div class="d-grid gap-2">
<a href="/admin/squad/list" class="btn btn-dark">
<i class="fas fa-eye me-2"></i>View Squad
</a>
<a href="/admin/squad/reset" class="btn btn-outline-dark">
<i class="fas fa-refresh me-2"></i>Reset Squad
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- System Status -->
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header bg-info text-white">
<h5 class="card-title mb-0">
<i class="fas fa-heartbeat me-2"></i>System Status
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3 text-center">
<div class="mb-2">
<i class="fas fa-server text-success fs-1"></i>
</div>
<h6>Database</h6>
<span class="badge bg-success">
<span class="status-indicator status-online"></span>Online
</span>
</div>
<div class="col-md-3 text-center">
<div class="mb-2">
<i class="fas fa-cloud text-info fs-1"></i>
</div>
<h6>S3 Storage</h6>
<span class="badge bg-info">
<span class="status-indicator status-online"></span>Configured
</span>
</div>
<div class="col-md-3 text-center">
<div class="mb-2">
<i class="fas fa-users text-primary fs-1"></i>
</div>
<h6>Active Users</h6>
<span class="badge bg-primary">1</span>
</div>
<div class="col-md-3 text-center">
<div class="mb-2">
<i class="fas fa-calendar text-warning fs-1"></i>
</div>
<h6>Next Match</h6>
<span class="badge bg-warning">Pending</span>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,280 @@
{% extends "base.html" %}
{% block title %}Admin Dashboard - HKFC Men's C Team MOTM System{% endblock %}
{% block content %}
<!-- Dashboard Header -->
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-body text-center">
<h1 class="card-title">
<i class="fas fa-tachometer-alt text-primary me-2"></i>
Admin Dashboard
</h1>
<p class="lead text-muted">Central hub for all administrative functions</p>
</div>
</div>
</div>
</div>
<!-- Quick Actions -->
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-header bg-primary text-white">
<h5 class="card-title mb-0">
<i class="fas fa-bolt me-2"></i>Quick Actions
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3 mb-3">
<a href="/admin/import" class="btn btn-outline-primary w-100">
<i class="fas fa-download me-2"></i>
<div class="text-start">
<div class="fw-bold">Import Data</div>
<small class="text-muted">Import from HKHA</small>
</div>
</a>
</div>
<div class="col-md-3 mb-3">
<a href="/admin/squad" class="btn btn-outline-success w-100">
<i class="fas fa-list-check me-2"></i>
<div class="text-start">
<div class="fw-bold">Select Squad</div>
<small class="text-muted">Choose match squad</small>
</div>
</a>
</div>
<div class="col-md-3 mb-3">
<a href="/admin/motm" class="btn btn-outline-warning w-100">
<i class="fas fa-trophy me-2"></i>
<div class="text-start">
<div class="fw-bold">MOTM Settings</div>
<small class="text-muted">Manage voting</small>
</div>
</a>
</div>
<div class="col-md-3 mb-3">
<a href="/admin/profile" class="btn btn-outline-secondary w-100">
<i class="fas fa-user-cog me-2"></i>
<div class="text-start">
<div class="fw-bold">Admin Profile</div>
<small class="text-muted">Account settings</small>
</div>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Data Management Section -->
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-header bg-success text-white">
<h5 class="card-title mb-0">
<i class="fas fa-database me-2"></i>Data Management
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-lg-4 mb-3">
<div class="card h-100 border-success">
<div class="card-header bg-light">
<h6 class="card-title mb-0">
<i class="fas fa-users text-success me-2"></i>Club Management
</h6>
</div>
<div class="card-body">
<p class="card-text">Manage hockey clubs, logos, and club information.</p>
<div class="d-grid gap-2">
<a href="/admin/clubs" class="btn btn-success">
<i class="fas fa-eye me-2"></i>View Clubs
</a>
<a href="/admin/clubs/add" class="btn btn-outline-success">
<i class="fas fa-plus me-2"></i>Add Club
</a>
</div>
</div>
</div>
</div>
<div class="col-lg-4 mb-3">
<div class="card h-100 border-primary">
<div class="card-header bg-light">
<h6 class="card-title mb-0">
<i class="fas fa-user text-primary me-2"></i>Player Management
</h6>
</div>
<div class="card-body">
<p class="card-text">Add, edit, and manage player information and squads.</p>
<div class="d-grid gap-2">
<a href="/admin/players" class="btn btn-primary">
<i class="fas fa-eye me-2"></i>View Players
</a>
<a href="/admin/players/add" class="btn btn-outline-primary">
<i class="fas fa-plus me-2"></i>Add Player
</a>
</div>
</div>
</div>
</div>
<div class="col-lg-4 mb-3">
<div class="card h-100 border-info">
<div class="card-header bg-light">
<h6 class="card-title mb-0">
<i class="fas fa-layer-group text-info me-2"></i>Team Management
</h6>
</div>
<div class="card-body">
<p class="card-text">Manage hockey teams and their associations with clubs.</p>
<div class="d-grid gap-2">
<a href="/admin/teams" class="btn btn-info">
<i class="fas fa-eye me-2"></i>View Teams
</a>
<a href="/admin/teams/add" class="btn btn-outline-info">
<i class="fas fa-plus me-2"></i>Add Team
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- System Management Section -->
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-header bg-warning text-dark">
<h5 class="card-title mb-0">
<i class="fas fa-cogs me-2"></i>System Management
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-lg-4 mb-3">
<div class="card h-100 border-warning">
<div class="card-header bg-light">
<h6 class="card-title mb-0">
<i class="fas fa-cloud text-warning me-2"></i>S3 Storage
</h6>
</div>
<div class="card-body">
<p class="card-text">Configure and manage S3 storage for assets and logos.</p>
<div class="d-grid gap-2">
<a href="/admin/s3-config" class="btn btn-warning">
<i class="fas fa-cog me-2"></i>Configure S3
</a>
<a href="/admin/s3-status" class="btn btn-outline-warning">
<i class="fas fa-info-circle me-2"></i>View Status
</a>
</div>
</div>
</div>
</div>
<div class="col-lg-4 mb-3">
<div class="card h-100 border-secondary">
<div class="card-header bg-light">
<h6 class="card-title mb-0">
<i class="fas fa-database text-secondary me-2"></i>Database
</h6>
</div>
<div class="card-body">
<p class="card-text">Manage database configuration and status.</p>
<div class="d-grid gap-2">
<a href="/admin/database-status" class="btn btn-secondary">
<i class="fas fa-info-circle me-2"></i>Database Status
</a>
<a href="/admin/database-setup" class="btn btn-outline-secondary">
<i class="fas fa-wrench me-2"></i>Database Setup
</a>
</div>
</div>
</div>
</div>
<div class="col-lg-4 mb-3">
<div class="card h-100 border-dark">
<div class="card-header bg-light">
<h6 class="card-title mb-0">
<i class="fas fa-list-check text-dark me-2"></i>Squad Management
</h6>
</div>
<div class="card-body">
<p class="card-text">Manage match squads and player selections.</p>
<div class="d-grid gap-2">
<a href="/admin/squad/list" class="btn btn-dark">
<i class="fas fa-eye me-2"></i>View Squad
</a>
<a href="/admin/squad/reset" class="btn btn-outline-dark">
<i class="fas fa-refresh me-2"></i>Reset Squad
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- System Status -->
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header bg-info text-white">
<h5 class="card-title mb-0">
<i class="fas fa-heartbeat me-2"></i>System Status
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3 text-center">
<div class="mb-2">
<i class="fas fa-server text-success fs-1"></i>
</div>
<h6>Database</h6>
<span class="badge bg-success">
<span class="status-indicator status-online"></span>Online
</span>
</div>
<div class="col-md-3 text-center">
<div class="mb-2">
<i class="fas fa-cloud text-info fs-1"></i>
</div>
<h6>S3 Storage</h6>
<span class="badge bg-info">
<span class="status-indicator status-online"></span>Configured
</span>
</div>
<div class="col-md-3 text-center">
<div class="mb-2">
<i class="fas fa-users text-primary fs-1"></i>
</div>
<h6>Active Users</h6>
<span class="badge bg-primary">1</span>
</div>
<div class="col-md-3 text-center">
<div class="mb-2">
<i class="fas fa-calendar text-warning fs-1"></i>
</div>
<h6>Next Match</h6>
<span class="badge bg-warning">Pending</span>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,219 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Dashboard - 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">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
<style>
.admin-section {
margin-bottom: 30px;
}
.section-header {
background-color: #f5f5f5;
padding: 15px;
border-left: 4px solid #337ab7;
margin-bottom: 15px;
}
.card-custom {
transition: transform 0.2s;
}
.card-custom:hover {
transform: translateY(-5px);
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="page-header">
<h1>HKFC Men's C Team - Admin Dashboard</h1>
<p class="lead">Central hub for all administrative functions</p>
</div>
<div class="mb-3">
<a href="/" class="btn btn-default">Back to Main Page</a>
<a href="/admin/profile" class="btn btn-outline-secondary">Admin Profile</a>
</div>
<!-- Data Management Section -->
<div class="admin-section">
<div class="section-header">
<h3>Data Management</h3>
</div>
<div class="row">
<div class="col-md-3">
<div class="list-group card-custom">
<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</p>
</a>
</div>
</div>
<div class="col-md-3">
<div class="list-group card-custom">
<a href="/admin/clubs" class="list-group-item">
<h4 class="list-group-item-heading">Club Management</h4>
<p class="list-group-item-text">Manage hockey clubs</p>
</a>
</div>
</div>
<div class="col-md-3">
<div class="list-group card-custom">
<a href="/admin/teams" class="list-group-item">
<h4 class="list-group-item-heading">Team Management</h4>
<p class="list-group-item-text">Manage hockey teams</p>
</a>
</div>
</div>
<div class="col-md-3">
<div class="list-group card-custom">
<a href="/admin/import" class="list-group-item">
<h4 class="list-group-item-heading">Data Import</h4>
<p class="list-group-item-text">Import clubs and teams</p>
</a>
</div>
</div>
</div>
</div>
<!-- Match Management Section -->
<div class="admin-section">
<div class="section-header">
<h3>Match Management</h3>
</div>
<div class="row">
<div class="col-md-3">
<div class="list-group card-custom">
<a href="/admin/squad" class="list-group-item">
<h4 class="list-group-item-heading">Squad Selection</h4>
<p class="list-group-item-text">Select match squad</p>
</a>
</div>
</div>
<div class="col-md-3">
<div class="list-group card-custom">
<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 squad</p>
</a>
</div>
</div>
<div class="col-md-3">
<div class="list-group card-custom">
<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 for new match</p>
</a>
</div>
</div>
<div class="col-md-3">
<div class="list-group card-custom">
<a href="/admin/stats" class="list-group-item">
<h4 class="list-group-item-heading">Goals & Assists</h4>
<p class="list-group-item-text">Record statistics</p>
</a>
</div>
</div>
</div>
</div>
<!-- MOTM Management Section -->
<div class="admin-section">
<div class="section-header">
<h3>MOTM Management</h3>
</div>
<div class="row">
<div class="col-md-4">
<div class="list-group card-custom">
<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>
</div>
</div>
<div class="col-md-4">
<div class="list-group card-custom">
<a href="/admin/voting" class="list-group-item">
<h4 class="list-group-item-heading">Voting Results</h4>
<p class="list-group-item-text">View current match results</p>
</a>
</div>
</div>
<div class="col-md-4">
<div class="list-group card-custom">
<a href="/admin/motm/manage" class="list-group-item">
<h4 class="list-group-item-heading">MOTM Management</h4>
<p class="list-group-item-text">Reset MOTM/DotD counts for specific fixtures</p>
</a>
</div>
</div>
<div class="col-md-4">
<div class="list-group card-custom">
<a href="/admin/device-tracking" class="list-group-item">
<h4 class="list-group-item-heading">Device Tracking</h4>
<p class="list-group-item-text">Monitor voting patterns and detect duplicate votes</p>
</a>
</div>
</div>
<div class="col-md-4">
<div class="list-group card-custom">
<a href="/admin/poty" class="list-group-item">
<h4 class="list-group-item-heading">Player of the Year</h4>
<p class="list-group-item-text">View season standings</p>
</a>
</div>
</div>
</div>
</div>
<!-- System Management Section -->
<div class="admin-section">
<div class="section-header">
<h3>System Management</h3>
</div>
<div class="row">
<div class="col-md-3">
<div class="list-group card-custom">
<a href="/admin/database-setup" class="list-group-item">
<h4 class="list-group-item-heading">Database Setup</h4>
<p class="list-group-item-text">Configure and initialize database</p>
</a>
</div>
</div>
<div class="col-md-3">
<div class="list-group card-custom">
<a href="/admin/database-status" class="list-group-item">
<h4 class="list-group-item-heading">Database Status</h4>
<p class="list-group-item-text">View database configuration</p>
</a>
</div>
</div>
<div class="col-md-3">
<div class="list-group card-custom">
<a href="/admin/s3-config" class="list-group-item">
<h4 class="list-group-item-heading">S3 Configuration</h4>
<p class="list-group-item-text">Configure S3/MinIO storage</p>
</a>
</div>
</div>
<div class="col-md-3">
<div class="list-group card-custom">
<a href="/admin/s3-status" class="list-group-item">
<h4 class="list-group-item-heading">S3 Status</h4>
<p class="list-group-item-text">View S3/MinIO status</p>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,349 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}HKFC Men's C Team - MOTM System{% endblock %}</title>
<!-- Bootstrap 5 CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Font Awesome Icons -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<!-- Custom Styles -->
<style>
:root {
--primary-color: #0d6efd;
--secondary-color: #6c757d;
--success-color: #198754;
--danger-color: #dc3545;
--warning-color: #ffc107;
--info-color: #0dcaf0;
--light-color: #f8f9fa;
--dark-color: #212529;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f8f9fa;
}
.navbar-brand {
font-weight: bold;
font-size: 1.5rem;
}
.page-header {
background: linear-gradient(135deg, var(--primary-color) 0%, #0056b3 100%);
color: white;
padding: 2rem 0;
margin-bottom: 2rem;
}
.page-header h1 {
margin: 0;
font-size: 2.5rem;
font-weight: 300;
}
.page-header p {
margin: 0.5rem 0 0 0;
opacity: 0.9;
font-size: 1.1rem;
}
.card {
border: none;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
}
.card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 20px rgba(0,0,0,0.15);
}
.card-header {
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
border-bottom: 1px solid #dee2e6;
border-radius: 10px 10px 0 0 !important;
font-weight: 600;
}
.btn {
border-radius: 6px;
font-weight: 500;
transition: all 0.2s ease-in-out;
}
.btn:hover {
transform: translateY(-1px);
}
.alert {
border: none;
border-radius: 8px;
border-left: 4px solid;
}
.alert-success {
border-left-color: var(--success-color);
background-color: #d1e7dd;
}
.alert-danger {
border-left-color: var(--danger-color);
background-color: #f8d7da;
}
.alert-warning {
border-left-color: var(--warning-color);
background-color: #fff3cd;
}
.alert-info {
border-left-color: var(--info-color);
background-color: #cff4fc;
}
.table {
border-radius: 8px;
overflow: hidden;
}
.table thead th {
background-color: #f8f9fa;
border-bottom: 2px solid #dee2e6;
font-weight: 600;
}
.form-control, .form-select {
border-radius: 6px;
border: 1px solid #ced4da;
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}
.form-control:focus, .form-select:focus {
border-color: var(--primary-color);
box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25);
}
.footer {
background-color: var(--dark-color);
color: white;
padding: 2rem 0;
margin-top: 4rem;
}
.loading-spinner {
display: inline-block;
width: 1rem;
height: 1rem;
border: 0.125em solid currentColor;
border-right-color: transparent;
border-radius: 50%;
animation: spinner-border 0.75s linear infinite;
}
@keyframes spinner-border {
to { transform: rotate(360deg); }
}
.breadcrumb {
background-color: transparent;
padding: 0;
margin-bottom: 1rem;
}
.breadcrumb-item + .breadcrumb-item::before {
content: "";
color: #6c757d;
}
.status-indicator {
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
margin-right: 0.5rem;
}
.status-online { background-color: var(--success-color); }
.status-offline { background-color: var(--danger-color); }
.status-warning { background-color: var(--warning-color); }
</style>
{% block extra_head %}{% endblock %}
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container">
<a class="navbar-brand" href="/">
<i class="fas fa-trophy me-2"></i>HKFC MOTM System
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link" href="/">
<i class="fas fa-home me-1"></i>Home
</a>
</li>
{% if is_admin %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="adminDropdown" role="button" data-bs-toggle="dropdown">
<i class="fas fa-cog me-1"></i>Admin
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="/admin">
<i class="fas fa-tachometer-alt me-2"></i>Dashboard
</a></li>
<li><a class="dropdown-item" href="/admin/clubs">
<i class="fas fa-users me-2"></i>Club Management
</a></li>
<li><a class="dropdown-item" href="/admin/players">
<i class="fas fa-user me-2"></i>Player Management
</a></li>
<li><a class="dropdown-item" href="/admin/teams">
<i class="fas fa-layer-group me-2"></i>Team Management
</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="/admin/s3-config">
<i class="fas fa-cloud me-2"></i>S3 Configuration
</a></li>
<li><a class="dropdown-item" href="/admin/profile">
<i class="fas fa-user-cog me-2"></i>Profile
</a></li>
</ul>
</li>
{% endif %}
</ul>
<ul class="navbar-nav">
{% if is_admin %}
<li class="nav-item">
<span class="navbar-text">
<i class="fas fa-user-shield me-1"></i>Admin
</span>
</li>
{% endif %}
</ul>
</div>
</div>
</nav>
<!-- Page Header -->
{% if page_title or page_subtitle %}
<div class="page-header">
<div class="container">
<div class="row">
<div class="col-12">
{% if breadcrumbs %}
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
{% for breadcrumb in breadcrumbs %}
<li class="breadcrumb-item {% if loop.last %}active{% endif %}">
{% if not loop.last and breadcrumb.url %}
<a href="{{ breadcrumb.url }}">{{ breadcrumb.title }}</a>
{% else %}
{{ breadcrumb.title }}
{% endif %}
</li>
{% endfor %}
</ol>
</nav>
{% endif %}
{% if page_title %}
<h1>{{ page_title }}</h1>
{% endif %}
{% if page_subtitle %}
<p>{{ page_subtitle }}</p>
{% endif %}
</div>
</div>
</div>
</div>
{% endif %}
<!-- Main Content -->
<div class="container">
<!-- Flash Messages -->
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<div class="row">
<div class="col-12">
{% for category, message in messages %}
<div class="alert alert-{{ 'danger' if category == 'error' else category }} alert-dismissible fade show" role="alert">
<i class="fas fa-{{ 'exclamation-triangle' if category == 'error' else 'info-circle' if category == 'info' else 'check-circle' if category == 'success' else 'exclamation-triangle' }} me-2"></i>
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% endwith %}
<!-- Page Content -->
{% block content %}{% endblock %}
</div>
<!-- Footer -->
<footer class="footer">
<div class="container">
<div class="row">
<div class="col-md-6">
<h5>HKFC Men's C Team MOTM System</h5>
<p class="mb-0">Man of the Match and Dick of the Day voting system</p>
</div>
<div class="col-md-6 text-md-end">
<p class="mb-0">
<i class="fas fa-calendar-alt me-1"></i>
{% if current_year %}{{ current_year }}{% else %}2024{% endif %}
</p>
</div>
</div>
</div>
</footer>
<!-- Bootstrap 5 JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<!-- jQuery (for compatibility with existing scripts) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!-- Common JavaScript -->
<script>
// Common utility functions
function showLoading(element) {
element.html('<span class="loading-spinner"></span> Loading...');
}
function hideLoading(element, originalText) {
element.html(originalText);
}
// Auto-dismiss alerts after 5 seconds
$(document).ready(function() {
setTimeout(function() {
$('.alert:not(.alert-permanent)').fadeOut();
}, 5000);
});
// Confirm dialogs for destructive actions
$('[data-confirm]').on('click', function(e) {
if (!confirm($(this).data('confirm'))) {
e.preventDefault();
}
});
</script>
{% block extra_scripts %}{% endblock %}
</body>
</html>

View File

@ -1,19 +1,35 @@
<html>
<head>
<title>Error - Invalid URL</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">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-12">
<h1>Error</h1>
<p>{{ message or "Invalid voting URL. Please check the link and try again." }}</p>
<a class="btn btn-primary" href="/" role="button">Home</a>
{% extends "base.html" %}
{% block title %}Error - HKFC MOTM System{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="card border-danger">
<div class="card-body text-center">
<div class="mb-4">
<i class="fas fa-exclamation-triangle text-danger" style="font-size: 4rem;"></i>
</div>
<h1 class="card-title text-danger">Error</h1>
<div class="alert alert-danger">
<h5 class="alert-heading">
<i class="fas fa-info-circle me-2"></i>Something went wrong
</h5>
<p class="mb-0">{{ message or "Invalid voting URL. Please check the link and try again." }}</p>
</div>
<div class="d-grid gap-2 d-md-flex justify-content-md-center">
<a href="/" class="btn btn-primary">
<i class="fas fa-home me-2"></i>Back to Home
</a>
<button onclick="history.back()" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Go Back
</button>
</div>
</div>
</div>
</body>
</html>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,35 @@
{% extends "base.html" %}
{% block title %}Error - HKFC MOTM System{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="card border-danger">
<div class="card-body text-center">
<div class="mb-4">
<i class="fas fa-exclamation-triangle text-danger" style="font-size: 4rem;"></i>
</div>
<h1 class="card-title text-danger">Error</h1>
<div class="alert alert-danger">
<h5 class="alert-heading">
<i class="fas fa-info-circle me-2"></i>Something went wrong
</h5>
<p class="mb-0">{{ message or "Invalid voting URL. Please check the link and try again." }}</p>
</div>
<div class="d-grid gap-2 d-md-flex justify-content-md-center">
<a href="/" class="btn btn-primary">
<i class="fas fa-home me-2"></i>Back to Home
</a>
<button onclick="history.back()" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Go Back
</button>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,19 @@
<html>
<head>
<title>Error - Invalid URL</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">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-12">
<h1>Error</h1>
<p>{{ message or "Invalid voting URL. Please check the link and try again." }}</p>
<a class="btn btn-primary" href="/" role="button">Home</a>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,115 +1,237 @@
<html>
<head>
<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">
<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>
<body>
<div class="container">
<div class="row">
<div class="col-md-12">
<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>
{% extends "base.html" %}
{% block title %}HKFC Men's C Team - MOTM System{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<!-- Welcome Section -->
<div class="card mb-4">
<div class="card-body text-center">
<h2 class="card-title">
<i class="fas fa-trophy text-warning me-2"></i>
Welcome to the MOTM Voting System
</h2>
<p class="card-text lead">
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>
</div>
</div>
</div>
</div>
<div class="row">
<!-- Player Section -->
<div class="col-lg-6 mb-4">
<div class="card h-100">
<div class="card-header bg-primary text-white">
<h4 class="card-title mb-0">
<i class="fas fa-users me-2"></i>Player Section
</h4>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<a href="/motm/comments" class="btn btn-outline-primary btn-lg">
<i class="fas fa-comments me-2"></i>
<div class="text-start">
<div class="fw-bold">Match Comments</div>
<small class="text-muted">View comments from recent matches</small>
</div>
</a>
</div>
</div>
</div>
</div>
<!-- Admin Section -->
{% if is_admin %}
<div class="col-lg-6 mb-4">
<div class="card h-100">
<div class="card-header bg-success text-white">
<h4 class="card-title mb-0">
<i class="fas fa-user-shield me-2"></i>Admin Section
</h4>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<a href="/admin" class="btn btn-outline-success">
<i class="fas fa-tachometer-alt me-2"></i>
<div class="text-start">
<div class="fw-bold">Admin Dashboard</div>
<small class="text-muted">Access all administrative functions</small>
</div>
</a>
<a href="/admin/clubs" class="btn btn-outline-success">
<i class="fas fa-users me-2"></i>
<div class="text-start">
<div class="fw-bold">Club Management</div>
<small class="text-muted">Add, edit, and manage hockey clubs</small>
</div>
</a>
<a href="/admin/players" class="btn btn-outline-success">
<i class="fas fa-user me-2"></i>
<div class="text-start">
<div class="fw-bold">Player Management</div>
<small class="text-muted">Add, edit, and manage players</small>
</div>
</a>
<a href="/admin/teams" class="btn btn-outline-success">
<i class="fas fa-layer-group me-2"></i>
<div class="text-start">
<div class="fw-bold">Team Management</div>
<small class="text-muted">Add, edit, and manage hockey teams</small>
</div>
</a>
<a href="/admin/s3-config" class="btn btn-outline-info">
<i class="fas fa-cloud me-2"></i>
<div class="text-start">
<div class="fw-bold">S3 Configuration</div>
<small class="text-muted">Configure AWS S3 storage for logos and assets</small>
</div>
</a>
<a href="/admin/s3-status" class="btn btn-outline-info">
<i class="fas fa-cloud-upload-alt me-2"></i>
<div class="text-start">
<div class="fw-bold">S3 Status</div>
<small class="text-muted">View current S3 configuration and connection status</small>
</div>
</a>
</div>
</div>
</div>
</div>
{% else %}
<div class="col-lg-6 mb-4">
<div class="card h-100">
<div class="card-header bg-secondary text-white">
<h4 class="card-title mb-0">
<i class="fas fa-lock me-2"></i>Admin Access
</h4>
</div>
<div class="card-body">
<div class="alert alert-info">
<h5 class="alert-heading">
<i class="fas fa-info-circle me-2"></i>Authentication Required
</h5>
<p class="mb-0">Admin functions require authentication. Please contact the system administrator for access.</p>
</div>
</div>
</div>
</div>
{% endif %}
</div>
<!-- Additional Admin Functions (if admin) -->
{% if is_admin %}
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header bg-warning text-dark">
<h4 class="card-title mb-0">
<i class="fas fa-cogs me-2"></i>System Management
</h4>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-4 mb-3">
<a href="/admin/import" class="btn btn-outline-warning w-100">
<i class="fas fa-download me-2"></i>
<div class="text-start">
<div class="fw-bold">Data Import</div>
<small class="text-muted">Import clubs and teams from HKHA</small>
</div>
</a>
</div>
<div class="row">
<div class="col-md-6">
<h3>Player Section</h3>
<div class="list-group">
<a href="/motm/comments" class="list-group-item">
<h4 class="list-group-item-heading">Match Comments</h4>
<p class="list-group-item-text">View comments from recent matches</p>
</a>
<div class="col-md-4 mb-3">
<a href="/admin/squad" class="btn btn-outline-warning w-100">
<i class="fas fa-list-check me-2"></i>
<div class="text-start">
<div class="fw-bold">Squad Selection</div>
<small class="text-muted">Select players for match squad</small>
</div>
</div>
{% if is_admin %}
<div class="col-md-6">
<h3>Admin Section</h3>
<div class="list-group">
<a href="/admin" class="list-group-item">
<h4 class="list-group-item-heading">Admin Dashboard</h4>
<p class="list-group-item-text">Access all administrative functions</p>
</a>
<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/import" class="list-group-item">
<h4 class="list-group-item-heading">Data Import</h4>
<p class="list-group-item-text">Import clubs and teams from Hong Kong Hockey Association</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/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>
</a>
<a href="/admin/voting" class="list-group-item">
<h4 class="list-group-item-heading">Voting Results</h4>
<p class="list-group-item-text">View current match voting results</p>
</a>
<a href="/admin/poty" class="list-group-item">
<h4 class="list-group-item-heading">Player of the Year</h4>
<p class="list-group-item-text">View season totals and Player of the Year standings</p>
</a>
<a href="/admin/database-setup" class="list-group-item">
<h4 class="list-group-item-heading">Database Setup</h4>
<p class="list-group-item-text">Configure and initialize the database</p>
</a>
<a href="/admin/database-status" class="list-group-item">
<h4 class="list-group-item-heading">Database Status</h4>
<p class="list-group-item-text">View current database configuration and status</p>
</a>
<a href="/admin/s3-config" class="list-group-item">
<h4 class="list-group-item-heading">S3 Configuration</h4>
<p class="list-group-item-text">Configure AWS S3 storage for logos and assets</p>
</a>
<a href="/admin/s3-status" class="list-group-item">
<h4 class="list-group-item-heading">S3 Status</h4>
<p class="list-group-item-text">View current S3 configuration and connection status</p>
</a>
</a>
</div>
<div class="col-md-4 mb-3">
<a href="/admin/motm" class="btn btn-outline-warning w-100">
<i class="fas fa-trophy me-2"></i>
<div class="text-start">
<div class="fw-bold">MOTM Management</div>
<small class="text-muted">Manage Man of the Match settings</small>
</div>
</div>
{% else %}
<div class="col-md-6">
<h3>Admin Access</h3>
<div class="alert alert-info">
<h4 class="alert-heading">Authentication Required</h4>
<p>Admin functions require authentication. Please contact the system administrator for access.</p>
</a>
</div>
</div>
<div class="row">
<div class="col-md-4 mb-3">
<a href="/admin/squad/list" class="btn btn-outline-secondary w-100">
<i class="fas fa-eye me-2"></i>
<div class="text-start">
<div class="fw-bold">View Current Squad</div>
<small class="text-muted">View current match squad</small>
</div>
</div>
{% endif %}
</a>
</div>
<div class="col-md-4 mb-3">
<a href="/admin/squad/reset" class="btn btn-outline-danger w-100">
<i class="fas fa-refresh me-2"></i>
<div class="text-start">
<div class="fw-bold">Reset Squad</div>
<small class="text-muted">Reset squad for new match</small>
</div>
</a>
</div>
<div class="col-md-4 mb-3">
<a href="/admin/profile" class="btn btn-outline-secondary w-100">
<i class="fas fa-user-cog me-2"></i>
<div class="text-start">
<div class="fw-bold">Admin Profile</div>
<small class="text-muted">Manage admin settings</small>
</div>
</a>
</div>
</div>
</div>
</div>
</body>
</html>
</div>
</div>
{% endif %}
<!-- System Status Card -->
<div class="row mt-4">
<div class="col-12">
<div class="card">
<div class="card-header bg-info text-white">
<h4 class="card-title mb-0">
<i class="fas fa-info-circle me-2"></i>System Information
</h4>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h6><i class="fas fa-server me-2"></i>System Status</h6>
<p class="text-muted">
<span class="status-indicator status-online"></span>
System Online
</p>
</div>
<div class="col-md-6">
<h6><i class="fas fa-calendar-alt me-2"></i>Current Season</h6>
<p class="text-muted">2024-2025 Hockey Season</p>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,237 @@
{% extends "base.html" %}
{% block title %}HKFC Men's C Team - MOTM System{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<!-- Welcome Section -->
<div class="card mb-4">
<div class="card-body text-center">
<h2 class="card-title">
<i class="fas fa-trophy text-warning me-2"></i>
Welcome to the MOTM Voting System
</h2>
<p class="card-text lead">
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>
</div>
</div>
</div>
</div>
<div class="row">
<!-- Player Section -->
<div class="col-lg-6 mb-4">
<div class="card h-100">
<div class="card-header bg-primary text-white">
<h4 class="card-title mb-0">
<i class="fas fa-users me-2"></i>Player Section
</h4>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<a href="/motm/comments" class="btn btn-outline-primary btn-lg">
<i class="fas fa-comments me-2"></i>
<div class="text-start">
<div class="fw-bold">Match Comments</div>
<small class="text-muted">View comments from recent matches</small>
</div>
</a>
</div>
</div>
</div>
</div>
<!-- Admin Section -->
{% if is_admin %}
<div class="col-lg-6 mb-4">
<div class="card h-100">
<div class="card-header bg-success text-white">
<h4 class="card-title mb-0">
<i class="fas fa-user-shield me-2"></i>Admin Section
</h4>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<a href="/admin" class="btn btn-outline-success">
<i class="fas fa-tachometer-alt me-2"></i>
<div class="text-start">
<div class="fw-bold">Admin Dashboard</div>
<small class="text-muted">Access all administrative functions</small>
</div>
</a>
<a href="/admin/clubs" class="btn btn-outline-success">
<i class="fas fa-users me-2"></i>
<div class="text-start">
<div class="fw-bold">Club Management</div>
<small class="text-muted">Add, edit, and manage hockey clubs</small>
</div>
</a>
<a href="/admin/players" class="btn btn-outline-success">
<i class="fas fa-user me-2"></i>
<div class="text-start">
<div class="fw-bold">Player Management</div>
<small class="text-muted">Add, edit, and manage players</small>
</div>
</a>
<a href="/admin/teams" class="btn btn-outline-success">
<i class="fas fa-layer-group me-2"></i>
<div class="text-start">
<div class="fw-bold">Team Management</div>
<small class="text-muted">Add, edit, and manage hockey teams</small>
</div>
</a>
<a href="/admin/s3-config" class="btn btn-outline-info">
<i class="fas fa-cloud me-2"></i>
<div class="text-start">
<div class="fw-bold">S3 Configuration</div>
<small class="text-muted">Configure AWS S3 storage for logos and assets</small>
</div>
</a>
<a href="/admin/s3-status" class="btn btn-outline-info">
<i class="fas fa-cloud-upload-alt me-2"></i>
<div class="text-start">
<div class="fw-bold">S3 Status</div>
<small class="text-muted">View current S3 configuration and connection status</small>
</div>
</a>
</div>
</div>
</div>
</div>
{% else %}
<div class="col-lg-6 mb-4">
<div class="card h-100">
<div class="card-header bg-secondary text-white">
<h4 class="card-title mb-0">
<i class="fas fa-lock me-2"></i>Admin Access
</h4>
</div>
<div class="card-body">
<div class="alert alert-info">
<h5 class="alert-heading">
<i class="fas fa-info-circle me-2"></i>Authentication Required
</h5>
<p class="mb-0">Admin functions require authentication. Please contact the system administrator for access.</p>
</div>
</div>
</div>
</div>
{% endif %}
</div>
<!-- Additional Admin Functions (if admin) -->
{% if is_admin %}
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header bg-warning text-dark">
<h4 class="card-title mb-0">
<i class="fas fa-cogs me-2"></i>System Management
</h4>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-4 mb-3">
<a href="/admin/import" class="btn btn-outline-warning w-100">
<i class="fas fa-download me-2"></i>
<div class="text-start">
<div class="fw-bold">Data Import</div>
<small class="text-muted">Import clubs and teams from HKHA</small>
</div>
</a>
</div>
<div class="col-md-4 mb-3">
<a href="/admin/squad" class="btn btn-outline-warning w-100">
<i class="fas fa-list-check me-2"></i>
<div class="text-start">
<div class="fw-bold">Squad Selection</div>
<small class="text-muted">Select players for match squad</small>
</div>
</a>
</div>
<div class="col-md-4 mb-3">
<a href="/admin/motm" class="btn btn-outline-warning w-100">
<i class="fas fa-trophy me-2"></i>
<div class="text-start">
<div class="fw-bold">MOTM Management</div>
<small class="text-muted">Manage Man of the Match settings</small>
</div>
</a>
</div>
</div>
<div class="row">
<div class="col-md-4 mb-3">
<a href="/admin/squad/list" class="btn btn-outline-secondary w-100">
<i class="fas fa-eye me-2"></i>
<div class="text-start">
<div class="fw-bold">View Current Squad</div>
<small class="text-muted">View current match squad</small>
</div>
</a>
</div>
<div class="col-md-4 mb-3">
<a href="/admin/squad/reset" class="btn btn-outline-danger w-100">
<i class="fas fa-refresh me-2"></i>
<div class="text-start">
<div class="fw-bold">Reset Squad</div>
<small class="text-muted">Reset squad for new match</small>
</div>
</a>
</div>
<div class="col-md-4 mb-3">
<a href="/admin/profile" class="btn btn-outline-secondary w-100">
<i class="fas fa-user-cog me-2"></i>
<div class="text-start">
<div class="fw-bold">Admin Profile</div>
<small class="text-muted">Manage admin settings</small>
</div>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
{% endif %}
<!-- System Status Card -->
<div class="row mt-4">
<div class="col-12">
<div class="card">
<div class="card-header bg-info text-white">
<h4 class="card-title mb-0">
<i class="fas fa-info-circle me-2"></i>System Information
</h4>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h6><i class="fas fa-server me-2"></i>System Status</h6>
<p class="text-muted">
<span class="status-indicator status-online"></span>
System Online
</p>
</div>
<div class="col-md-6">
<h6><i class="fas fa-calendar-alt me-2"></i>Current Season</h6>
<p class="text-muted">2024-2025 Hockey Season</p>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,117 @@
{% extends "base.html" %}
{% block title %}HKFC Men's C Team - MOTM System{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<!-- Welcome Section -->
<div class="card mb-4">
<div class="card-body text-center">
<h2 class="card-title">
<i class="fas fa-trophy text-warning me-2"></i>
Welcome to the MOTM Voting System
</h2>
<p class="card-text lead">
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>
</div>
</div>
<div class="row">
<div class="col-md-6">
<h3>Player Section</h3>
<div class="list-group">
<a href="/motm/comments" class="list-group-item">
<h4 class="list-group-item-heading">Match Comments</h4>
<p class="list-group-item-text">View comments from recent matches</p>
</a>
</div>
</div>
{% if is_admin %}
<div class="col-md-6">
<h3>Admin Section</h3>
<div class="list-group">
<a href="/admin" class="list-group-item">
<h4 class="list-group-item-heading">Admin Dashboard</h4>
<p class="list-group-item-text">Access all administrative functions</p>
</a>
<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/import" class="list-group-item">
<h4 class="list-group-item-heading">Data Import</h4>
<p class="list-group-item-text">Import clubs and teams from Hong Kong Hockey Association</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/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>
</a>
<a href="/admin/voting" class="list-group-item">
<h4 class="list-group-item-heading">Voting Results</h4>
<p class="list-group-item-text">View current match voting results</p>
</a>
<a href="/admin/poty" class="list-group-item">
<h4 class="list-group-item-heading">Player of the Year</h4>
<p class="list-group-item-text">View season totals and Player of the Year standings</p>
</a>
<a href="/admin/database-setup" class="list-group-item">
<h4 class="list-group-item-heading">Database Setup</h4>
<p class="list-group-item-text">Configure and initialize the database</p>
</a>
<a href="/admin/database-status" class="list-group-item">
<h4 class="list-group-item-heading">Database Status</h4>
<p class="list-group-item-text">View current database configuration and status</p>
</a>
<a href="/admin/s3-config" class="list-group-item">
<h4 class="list-group-item-heading">S3 Configuration</h4>
<p class="list-group-item-text">Configure AWS S3 storage for logos and assets</p>
</a>
<a href="/admin/s3-status" class="list-group-item">
<h4 class="list-group-item-heading">S3 Status</h4>
<p class="list-group-item-text">View current S3 configuration and connection status</p>
</a>
</div>
</div>
{% else %}
<div class="col-md-6">
<h3>Admin Access</h3>
<div class="alert alert-info">
<h4 class="alert-heading">Authentication Required</h4>
<p>Admin functions require authentication. Please contact the system administrator for access.</p>
</div>
</div>
{% endif %}
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,31 +1,76 @@
<html>
<head>
<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">
<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>
<body>
<h3>Match Comments</h3>
<div class="row">
<div class="col-sm-6">
<img src="{{ hkfcLogo }}" height="100"></img>
<img src="{{ oppoLogo }}" height="100"></img>
</div>
</div>
<div class="row">
<div class="col-sm-8">
{% for comment in comments %}
<div class="panel panel-default">
<div class="panel-body">
{{ comment.comment }}
{% extends "base.html" %}
{% block title %}HKFC Men's C Team - Match Comments{% endblock %}
{% block content %}
<!-- Match Header -->
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-body text-center">
<h2 class="card-title">
<i class="fas fa-comments me-2"></i>Match Comments
</h2>
<!-- Team Logos -->
<div class="d-flex justify-content-center align-items-center mt-3">
<div class="text-center me-4">
<img src="{{ hkfcLogo }}" alt="HKFC Logo" class="img-fluid" style="max-height: 100px;">
<div class="mt-2">
<strong>HKFC</strong>
</div>
</div>
{% endfor %}
<div class="text-center mx-3">
<h4 class="text-primary">VS</h4>
</div>
<div class="text-center ms-4">
<img src="{{ oppoLogo }}" alt="Opponent Logo" class="img-fluid" style="max-height: 100px;">
<div class="mt-2">
<strong>Opponent</strong>
</div>
</div>
</div>
</div>
</div>
<a class="btn btn-primary" href="/" role="button">Home</a>
</body>
</html>
</div>
</div>
<!-- Comments Section -->
<div class="row">
<div class="col-lg-8 mx-auto">
{% if comments %}
{% for comment in comments %}
<div class="card mb-3">
<div class="card-body">
<div class="d-flex align-items-start">
<div class="flex-shrink-0">
<i class="fas fa-comment-dots text-primary fs-4"></i>
</div>
<div class="flex-grow-1 ms-3">
<p class="mb-0">{{ comment.comment }}</p>
</div>
</div>
</div>
</div>
{% endfor %}
{% else %}
<div class="card">
<div class="card-body text-center">
<i class="fas fa-comment-slash text-muted fs-1 mb-3"></i>
<h5 class="text-muted">No comments yet</h5>
<p class="text-muted">Comments for this match will appear here once they are added.</p>
</div>
</div>
{% endif %}
</div>
</div>
<!-- Navigation -->
<div class="row mt-4">
<div class="col-12 text-center">
<a href="/" class="btn btn-primary">
<i class="fas fa-home me-2"></i>Back to Home
</a>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,76 @@
{% extends "base.html" %}
{% block title %}HKFC Men's C Team - Match Comments{% endblock %}
{% block content %}
<!-- Match Header -->
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-body text-center">
<h2 class="card-title">
<i class="fas fa-comments me-2"></i>Match Comments
</h2>
<!-- Team Logos -->
<div class="d-flex justify-content-center align-items-center mt-3">
<div class="text-center me-4">
<img src="{{ hkfcLogo }}" alt="HKFC Logo" class="img-fluid" style="max-height: 100px;">
<div class="mt-2">
<strong>HKFC</strong>
</div>
</div>
<div class="text-center mx-3">
<h4 class="text-primary">VS</h4>
</div>
<div class="text-center ms-4">
<img src="{{ oppoLogo }}" alt="Opponent Logo" class="img-fluid" style="max-height: 100px;">
<div class="mt-2">
<strong>Opponent</strong>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Comments Section -->
<div class="row">
<div class="col-lg-8 mx-auto">
{% if comments %}
{% for comment in comments %}
<div class="card mb-3">
<div class="card-body">
<div class="d-flex align-items-start">
<div class="flex-shrink-0">
<i class="fas fa-comment-dots text-primary fs-4"></i>
</div>
<div class="flex-grow-1 ms-3">
<p class="mb-0">{{ comment.comment }}</p>
</div>
</div>
</div>
</div>
{% endfor %}
{% else %}
<div class="card">
<div class="card-body text-center">
<i class="fas fa-comment-slash text-muted fs-1 mb-3"></i>
<h5 class="text-muted">No comments yet</h5>
<p class="text-muted">Comments for this match will appear here once they are added.</p>
</div>
</div>
{% endif %}
</div>
</div>
<!-- Navigation -->
<div class="row mt-4">
<div class="col-12 text-center">
<a href="/" class="btn btn-primary">
<i class="fas fa-home me-2"></i>Back to Home
</a>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,31 @@
<html>
<head>
<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">
<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>
<body>
<h3>Match Comments</h3>
<div class="row">
<div class="col-sm-6">
<img src="{{ hkfcLogo }}" height="100"></img>
<img src="{{ oppoLogo }}" height="100"></img>
</div>
</div>
<div class="row">
<div class="col-sm-8">
{% for comment in comments %}
<div class="panel panel-default">
<div class="panel-body">
{{ comment.comment }}
</div>
</div>
{% endfor %}
</div>
</div>
<a class="btn btn-primary" href="/" role="button">Home</a>
</body>
</html>

View File

@ -1,83 +1,219 @@
<html>
<head>
<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 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>
<p><b>Randomly selected comment from the match:</b>
<br/>
{% for item in comment %}
<i>{{ item.comment }}</i>
{% endfor %}
</p>
<dl>
{{ form.csrf_token }}
<div class="row">
<div class="col-xs-12">
<form class="col-sm-6" method="post" action="/motm/vote-thanks" id="motmForm" accept-charset="utf-8">
<input type="hidden" id="matchNumber" name="matchNumber" value="{{ matchNumber }}">
<input type="hidden" id="oppo" name="oppo" value="{{ oppo }}">
<div class = "row">
<div class = "col-sm-6">
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">Man of the Match</span>
<select class="form-control" name="motmVote" required>
{% for item in data %}
{% if item.playernickname != "" %}
<option value={{ item.playernumber }}>{{ item.playernickname }}</option>
{% else %}
<option value={{ item.playernumber }}>{{ item.playersurname }}, {{ item.playerforenames }}</option>
{% endif %}
{% endfor %}
</select>
</div>
</div>
<div class = "col-sm-6">
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">Dick of the Day</span>
<select class="form-control" name="dotdVote" required>
{% for item in data %}
{% if item.playernickname != "" %}
<option value={{ item.playernumber }}>{{ item.playernickname }}</option>
{% else %}
<option value={{ item.playernumber }}>{{ item.playersurname }}, {{ item.playerforenames }}</option>
{% endif %}
{% endfor %}
</select>
</div>
</div>
{% extends "base.html" %}
{% block title %}HKFC Men's C Team - MotM and DotD Vote{% endblock %}
{% block content %}
<!-- Match Header -->
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-body text-center">
<h2 class="card-title">
<i class="fas fa-trophy text-warning me-2"></i>
HKFC Men's C Team MotM and DotD Vote
</h2>
<h5 class="text-muted">{{ formatDate }}</h5>
<!-- Team Logos -->
<div class="d-flex justify-content-center align-items-center mt-3">
<div class="text-center me-4">
<img src="{{ hkfcLogo }}" alt="HKFC Logo" class="img-fluid" style="max-height: 120px;">
<div class="mt-2">
<strong>HKFC</strong>
</div>
<div class = "row">
<div class = "col-sm-6">
<div class = "input-group">
<span class = "input-group-addon" id = "basic-addon1">Match comments</span>
<textarea rows = "4" cols = "80" name = "motmComment" form = "motmForm">Optional comments added here</textarea>
</div>
</div>
</div>
<div class="text-center mx-3">
<h3 class="text-primary">VS</h3>
</div>
<div class="text-center ms-4">
<img src="{{ oppoLogo }}" alt="Opponent Logo" class="img-fluid" style="max-height: 120px;">
<div class="mt-2">
<strong>{{ oppo }}</strong>
</div>
<div class = "row">
<h3>Rogues Gallery</h3>
<div class = "col-sm-4">
<h4>Current Man of the Match</h4>
<img src="{{ motmURL }}" height="200"></img>
</div>
<div class = "col-sm-4">
<h4>Current Dick of the Day</h4>
<img src="{{ dotdURL }}" height="200"></img>
</div>
</div>
<button type="submit" class="btn btn-success">Submit</button>
<a class="btn btn-danger" href="/" role="button">Cancel</a>
</form>
</div>
</div>
</div>
</dl>
</body>
</html>
</div>
</div>
</div>
<!-- Random Comment -->
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-header bg-info text-white">
<h5 class="card-title mb-0">
<i class="fas fa-comment-dots me-2"></i>Random Match Comment
</h5>
</div>
<div class="card-body">
{% for item in comment %}
<blockquote class="blockquote text-center">
<p class="mb-0">
<i class="fas fa-quote-left text-muted me-2"></i>
<em>{{ item.comment }}</em>
<i class="fas fa-quote-right text-muted ms-2"></i>
</p>
</blockquote>
{% endfor %}
</div>
</div>
</div>
</div>
<!-- Voting Forms -->
<div class="row">
<div class="col-lg-6 mb-4">
<!-- Man of the Match -->
<div class="card h-100">
<div class="card-header bg-success text-white">
<h5 class="card-title mb-0">
<i class="fas fa-trophy me-2"></i>Man of the Match
</h5>
</div>
<div class="card-body">
<form method="post" action="/motm/vote-thanks" id="motmForm">
{{ form.csrf_token }}
<input type="hidden" id="matchNumber" name="matchNumber" value="{{ matchNumber }}">
<input type="hidden" id="oppo" name="oppo" value="{{ oppo }}">
<div class="mb-3">
<label for="motmSelect" class="form-label">Select Player:</label>
<select class="form-select" id="motmSelect" name="motmSelect" required>
<option value="">Choose a player...</option>
{% for player in data %}
<option value="{{ player.playernumber }}">{{ player.playerforenames }} {{ player.playersurname }}
{% if player.playernickname %}"{{ player.playernickname }}"{% endif %}
</option>
{% endfor %}
</select>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-success btn-lg">
<i class="fas fa-vote-yea me-2"></i>Submit MOTM Vote
</button>
</div>
</form>
</div>
</div>
</div>
<div class="col-lg-6 mb-4">
<!-- Dick of the Day -->
<div class="card h-100">
<div class="card-header bg-warning text-dark">
<h5 class="card-title mb-0">
<i class="fas fa-award me-2"></i>Dick of the Day
</h5>
</div>
<div class="card-body">
<form method="post" action="/motm/dotd-thanks" id="dotdForm">
{{ form.csrf_token }}
<input type="hidden" id="matchNumber" name="matchNumber" value="{{ matchNumber }}">
<input type="hidden" id="oppo" name="oppo" value="{{ oppo }}">
<div class="mb-3">
<label for="dotdSelect" class="form-label">Select Player:</label>
<select class="form-select" id="dotdSelect" name="dotdSelect" required>
<option value="">Choose a player...</option>
{% for player in data %}
<option value="{{ player.playernumber }}">{{ player.playerforenames }} {{ player.playersurname }}
{% if player.playernickname %}"{{ player.playernickname }}"{% endif %}
</option>
{% endfor %}
</select>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-warning btn-lg">
<i class="fas fa-vote-yea me-2"></i>Submit DotD Vote
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- Current Results (if available) -->
{% if currMotM or currDotD %}
<div class="row mt-4">
<div class="col-12">
<div class="card">
<div class="card-header bg-secondary text-white">
<h5 class="card-title mb-0">
<i class="fas fa-chart-bar me-2"></i>Current Results
</h5>
</div>
<div class="card-body">
<div class="row">
{% if currMotM %}
<div class="col-md-6">
<div class="alert alert-success">
<h6 class="alert-heading">
<i class="fas fa-trophy me-2"></i>Current Man of the Match
</h6>
<p class="mb-0">{{ currMotM }}</p>
</div>
</div>
{% endif %}
{% if currDotD %}
<div class="col-md-6">
<div class="alert alert-warning">
<h6 class="alert-heading">
<i class="fas fa-award me-2"></i>Current Dick of the Day
</h6>
<p class="mb-0">{{ currDotD }}</p>
</div>
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
{% endif %}
<!-- Instructions -->
<div class="row mt-4">
<div class="col-12">
<div class="card">
<div class="card-body">
<h6><i class="fas fa-info-circle me-2"></i>Voting Instructions</h6>
<ul class="list-unstyled">
<li><i class="fas fa-check text-success me-2"></i>Select one player for Man of the Match</li>
<li><i class="fas fa-check text-success me-2"></i>Select one player for Dick of the Day</li>
<li><i class="fas fa-check text-success me-2"></i>You can vote for the same player for both categories</li>
<li><i class="fas fa-check text-success me-2"></i>Votes are submitted independently</li>
</ul>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_scripts %}
<script>
$(document).ready(function() {
// Form validation
$('#motmForm, #dotdForm').on('submit', function(e) {
const selectElement = $(this).find('select');
if (!selectElement.val()) {
e.preventDefault();
alert('Please select a player before submitting your vote.');
selectElement.focus();
return false;
}
});
// Add loading state to buttons
$('#motmForm, #dotdForm').on('submit', function() {
const button = $(this).find('button[type="submit"]');
const originalText = button.html();
button.html('<span class="loading-spinner"></span> Submitting...').prop('disabled', true);
});
});
</script>
{% endblock %}

View File

@ -0,0 +1,219 @@
{% extends "base.html" %}
{% block title %}HKFC Men's C Team - MotM and DotD Vote{% endblock %}
{% block content %}
<!-- Match Header -->
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-body text-center">
<h2 class="card-title">
<i class="fas fa-trophy text-warning me-2"></i>
HKFC Men's C Team MotM and DotD Vote
</h2>
<h5 class="text-muted">{{ formatDate }}</h5>
<!-- Team Logos -->
<div class="d-flex justify-content-center align-items-center mt-3">
<div class="text-center me-4">
<img src="{{ hkfcLogo }}" alt="HKFC Logo" class="img-fluid" style="max-height: 120px;">
<div class="mt-2">
<strong>HKFC</strong>
</div>
</div>
<div class="text-center mx-3">
<h3 class="text-primary">VS</h3>
</div>
<div class="text-center ms-4">
<img src="{{ oppoLogo }}" alt="Opponent Logo" class="img-fluid" style="max-height: 120px;">
<div class="mt-2">
<strong>{{ oppo }}</strong>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Random Comment -->
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-header bg-info text-white">
<h5 class="card-title mb-0">
<i class="fas fa-comment-dots me-2"></i>Random Match Comment
</h5>
</div>
<div class="card-body">
{% for item in comment %}
<blockquote class="blockquote text-center">
<p class="mb-0">
<i class="fas fa-quote-left text-muted me-2"></i>
<em>{{ item.comment }}</em>
<i class="fas fa-quote-right text-muted ms-2"></i>
</p>
</blockquote>
{% endfor %}
</div>
</div>
</div>
</div>
<!-- Voting Forms -->
<div class="row">
<div class="col-lg-6 mb-4">
<!-- Man of the Match -->
<div class="card h-100">
<div class="card-header bg-success text-white">
<h5 class="card-title mb-0">
<i class="fas fa-trophy me-2"></i>Man of the Match
</h5>
</div>
<div class="card-body">
<form method="post" action="/motm/vote-thanks" id="motmForm">
{{ form.csrf_token }}
<input type="hidden" id="matchNumber" name="matchNumber" value="{{ matchNumber }}">
<input type="hidden" id="oppo" name="oppo" value="{{ oppo }}">
<div class="mb-3">
<label for="motmSelect" class="form-label">Select Player:</label>
<select class="form-select" id="motmSelect" name="motmSelect" required>
<option value="">Choose a player...</option>
{% for player in data %}
<option value="{{ player.playernumber }}">{{ player.playerforenames }} {{ player.playersurname }}
{% if player.playernickname %}"{{ player.playernickname }}"{% endif %}
</option>
{% endfor %}
</select>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-success btn-lg">
<i class="fas fa-vote-yea me-2"></i>Submit MOTM Vote
</button>
</div>
</form>
</div>
</div>
</div>
<div class="col-lg-6 mb-4">
<!-- Dick of the Day -->
<div class="card h-100">
<div class="card-header bg-warning text-dark">
<h5 class="card-title mb-0">
<i class="fas fa-award me-2"></i>Dick of the Day
</h5>
</div>
<div class="card-body">
<form method="post" action="/motm/dotd-thanks" id="dotdForm">
{{ form.csrf_token }}
<input type="hidden" id="matchNumber" name="matchNumber" value="{{ matchNumber }}">
<input type="hidden" id="oppo" name="oppo" value="{{ oppo }}">
<div class="mb-3">
<label for="dotdSelect" class="form-label">Select Player:</label>
<select class="form-select" id="dotdSelect" name="dotdSelect" required>
<option value="">Choose a player...</option>
{% for player in data %}
<option value="{{ player.playernumber }}">{{ player.playerforenames }} {{ player.playersurname }}
{% if player.playernickname %}"{{ player.playernickname }}"{% endif %}
</option>
{% endfor %}
</select>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-warning btn-lg">
<i class="fas fa-vote-yea me-2"></i>Submit DotD Vote
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- Current Results (if available) -->
{% if currMotM or currDotD %}
<div class="row mt-4">
<div class="col-12">
<div class="card">
<div class="card-header bg-secondary text-white">
<h5 class="card-title mb-0">
<i class="fas fa-chart-bar me-2"></i>Current Results
</h5>
</div>
<div class="card-body">
<div class="row">
{% if currMotM %}
<div class="col-md-6">
<div class="alert alert-success">
<h6 class="alert-heading">
<i class="fas fa-trophy me-2"></i>Current Man of the Match
</h6>
<p class="mb-0">{{ currMotM }}</p>
</div>
</div>
{% endif %}
{% if currDotD %}
<div class="col-md-6">
<div class="alert alert-warning">
<h6 class="alert-heading">
<i class="fas fa-award me-2"></i>Current Dick of the Day
</h6>
<p class="mb-0">{{ currDotD }}</p>
</div>
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
{% endif %}
<!-- Instructions -->
<div class="row mt-4">
<div class="col-12">
<div class="card">
<div class="card-body">
<h6><i class="fas fa-info-circle me-2"></i>Voting Instructions</h6>
<ul class="list-unstyled">
<li><i class="fas fa-check text-success me-2"></i>Select one player for Man of the Match</li>
<li><i class="fas fa-check text-success me-2"></i>Select one player for Dick of the Day</li>
<li><i class="fas fa-check text-success me-2"></i>You can vote for the same player for both categories</li>
<li><i class="fas fa-check text-success me-2"></i>Votes are submitted independently</li>
</ul>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_scripts %}
<script>
$(document).ready(function() {
// Form validation
$('#motmForm, #dotdForm').on('submit', function(e) {
const selectElement = $(this).find('select');
if (!selectElement.val()) {
e.preventDefault();
alert('Please select a player before submitting your vote.');
selectElement.focus();
return false;
}
});
// Add loading state to buttons
$('#motmForm, #dotdForm').on('submit', function() {
const button = $(this).find('button[type="submit"]');
const originalText = button.html();
button.html('<span class="loading-spinner"></span> Submitting...').prop('disabled', true);
});
});
</script>
{% endblock %}

View File

@ -0,0 +1,83 @@
<html>
<head>
<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 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>
<p><b>Randomly selected comment from the match:</b>
<br/>
{% for item in comment %}
<i>{{ item.comment }}</i>
{% endfor %}
</p>
<dl>
{{ form.csrf_token }}
<div class="row">
<div class="col-xs-12">
<form class="col-sm-6" method="post" action="/motm/vote-thanks" id="motmForm" accept-charset="utf-8">
<input type="hidden" id="matchNumber" name="matchNumber" value="{{ matchNumber }}">
<input type="hidden" id="oppo" name="oppo" value="{{ oppo }}">
<div class = "row">
<div class = "col-sm-6">
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">Man of the Match</span>
<select class="form-control" name="motmVote" required>
{% for item in data %}
{% if item.playernickname != "" %}
<option value={{ item.playernumber }}>{{ item.playernickname }}</option>
{% else %}
<option value={{ item.playernumber }}>{{ item.playersurname }}, {{ item.playerforenames }}</option>
{% endif %}
{% endfor %}
</select>
</div>
</div>
<div class = "col-sm-6">
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">Dick of the Day</span>
<select class="form-control" name="dotdVote" required>
{% for item in data %}
{% if item.playernickname != "" %}
<option value={{ item.playernumber }}>{{ item.playernickname }}</option>
{% else %}
<option value={{ item.playernumber }}>{{ item.playersurname }}, {{ item.playerforenames }}</option>
{% endif %}
{% endfor %}
</select>
</div>
</div>
</div>
<div class = "row">
<div class = "col-sm-6">
<div class = "input-group">
<span class = "input-group-addon" id = "basic-addon1">Match comments</span>
<textarea rows = "4" cols = "80" name = "motmComment" form = "motmForm">Optional comments added here</textarea>
</div>
</div>
</div>
<div class = "row">
<h3>Rogues Gallery</h3>
<div class = "col-sm-4">
<h4>Current Man of the Match</h4>
<img src="{{ motmURL }}" height="200"></img>
</div>
<div class = "col-sm-4">
<h4>Current Dick of the Day</h4>
<img src="{{ dotdURL }}" height="200"></img>
</div>
</div>
<button type="submit" class="btn btn-success">Submit</button>
<a class="btn btn-danger" href="/" role="button">Cancel</a>
</form>
</div>
</div>
</dl>
</body>
</html>

View File

@ -1,33 +1,23 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>S3 Configuration - HKFC Men's C Team</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
.config-section {
background-color: #f8f9fa;
border-radius: 0.375rem;
padding: 1rem;
margin-bottom: 1rem;
}
.help-text {
font-size: 0.875rem;
color: #6c757d;
}
</style>
</head>
<body>
<div class="container mt-4">
<div class="row">
<div class="col-md-12">
<h1>S3 Configuration</h1>
<p class="lead">Configure AWS S3 storage for logos and assets</p>
<div class="mb-3">
<a href="/admin" class="btn btn-secondary">Back to Admin</a>
</div>
{% extends "base.html" %}
{% block title %}S3 Configuration - HKFC Men's C Team{% endblock %}
{% block extra_head %}
<style>
.config-section {
background-color: #f8f9fa;
border-radius: 0.375rem;
padding: 1rem;
margin-bottom: 1rem;
}
.help-text {
font-size: 0.875rem;
color: #6c757d;
}
</style>
{% endblock %}
{% block content %}
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
@ -251,5 +241,4 @@
}
});
</script>
</body>
</html>
{% endblock %}

View File

@ -1,22 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>S3 Status - 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>S3 Storage Status</h1>
<p class="lead">Current S3 configuration and connection status</p>
<div class="mb-3">
<a href="/admin/s3-config" class="btn btn-primary">Configure S3</a>
<a href="/admin" class="btn btn-secondary">Back to Admin</a>
</div>
{% extends "base.html" %}
{% block title %}S3 Status - HKFC Men's C Team{% endblock %}
{% block content %}
<div class="row mb-4">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center">
<div>
<h1><i class="fas fa-cloud text-info me-2"></i>S3 Storage Status</h1>
<p class="lead text-muted">Current S3 configuration and connection status</p>
</div>
<div>
<a href="/admin/s3-config" class="btn btn-primary me-2">
<i class="fas fa-cog me-1"></i>Configure S3
</a>
<a href="/admin" class="btn btn-secondary">
<i class="fas fa-arrow-left me-1"></i>Back to Admin
</a>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
@ -149,6 +153,4 @@
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
{% endblock %}

View File

@ -1,19 +1,44 @@
<html>
<head>
<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">
<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>Thanks for submitting the MotM and DotD votes</h2>
<body>
Smithers' army of Internet monkeys will now go about adding up the votes ...
<p>
<img src="http://icarus.ipa.champion:9000/hockey-app/assets/simpsons-monkeys.jpg"></img>
</p>
<a class="btn btn-primary" href="/" role="button">Home</a>
<a class="btn btn-info" href="/motm/comments" role="button">Comments</a>
</body>
</html>
{% extends "base.html" %}
{% block title %}Vote Submitted - HKFC MOTM System{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="card border-success">
<div class="card-body text-center">
<div class="mb-4">
<i class="fas fa-check-circle text-success" style="font-size: 4rem;"></i>
</div>
<h1 class="card-title text-success">Vote Submitted Successfully!</h1>
<div class="alert alert-success">
<h5 class="alert-heading">
<i class="fas fa-thumbs-up me-2"></i>Thank you for voting
</h5>
<p class="mb-0">
Smithers' army of Internet monkeys will now go about adding up the votes...
</p>
</div>
<div class="mb-4">
<img src="http://icarus.ipa.champion:9000/hockey-app/assets/simpsons-monkeys.jpg"
alt="Counting votes"
class="img-fluid rounded"
style="max-height: 300px;">
</div>
<div class="d-grid gap-2 d-md-flex justify-content-md-center">
<a href="/" class="btn btn-primary">
<i class="fas fa-home me-2"></i>Back to Home
</a>
<a href="/motm/comments" class="btn btn-info">
<i class="fas fa-comments me-2"></i>View Comments
</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,44 @@
{% extends "base.html" %}
{% block title %}Vote Submitted - HKFC MOTM System{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="card border-success">
<div class="card-body text-center">
<div class="mb-4">
<i class="fas fa-check-circle text-success" style="font-size: 4rem;"></i>
</div>
<h1 class="card-title text-success">Vote Submitted Successfully!</h1>
<div class="alert alert-success">
<h5 class="alert-heading">
<i class="fas fa-thumbs-up me-2"></i>Thank you for voting
</h5>
<p class="mb-0">
Smithers' army of Internet monkeys will now go about adding up the votes...
</p>
</div>
<div class="mb-4">
<img src="http://icarus.ipa.champion:9000/hockey-app/assets/simpsons-monkeys.jpg"
alt="Counting votes"
class="img-fluid rounded"
style="max-height: 300px;">
</div>
<div class="d-grid gap-2 d-md-flex justify-content-md-center">
<a href="/" class="btn btn-primary">
<i class="fas fa-home me-2"></i>Back to Home
</a>
<a href="/motm/comments" class="btn btn-info">
<i class="fas fa-comments me-2"></i>View Comments
</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,19 @@
<html>
<head>
<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">
<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>Thanks for submitting the MotM and DotD votes</h2>
<body>
Smithers' army of Internet monkeys will now go about adding up the votes ...
<p>
<img src="http://icarus.ipa.champion:9000/hockey-app/assets/simpsons-monkeys.jpg"></img>
</p>
<a class="btn btn-primary" href="/" role="button">Home</a>
<a class="btn btn-info" href="/motm/comments" role="button">Comments</a>
</body>
</html>