Refactored pages
This commit is contained in:
parent
a08897c5c2
commit
d5350aa4cb
3
motm_app/=21.0.0
Normal file
3
motm_app/=21.0.0
Normal 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)
|
||||||
160
motm_app/PRODUCTION_DEPLOYMENT.md
Normal file
160
motm_app/PRODUCTION_DEPLOYMENT.md
Normal 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
52
motm_app/gunicorn.conf.py
Normal 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
18
motm_app/motm-app.service
Normal 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
|
||||||
@ -29,3 +29,6 @@ boto3>=1.34.0
|
|||||||
|
|
||||||
# Legacy support (can be removed after migration)
|
# Legacy support (can be removed after migration)
|
||||||
flask-mysql
|
flask-mysql
|
||||||
|
|
||||||
|
# Production WSGI server
|
||||||
|
gunicorn>=21.0.0
|
||||||
|
|||||||
12
motm_app/run_production.py
Normal file
12
motm_app/run_production.py
Normal 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
26
motm_app/start_production.sh
Executable 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
|
||||||
@ -1,219 +1,280 @@
|
|||||||
<!DOCTYPE html>
|
{% extends "base.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">
|
{% block title %}Admin Dashboard - HKFC Men's C Team MOTM System{% endblock %}
|
||||||
<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 -->
|
{% block content %}
|
||||||
<div class="admin-section">
|
<!-- Dashboard Header -->
|
||||||
<div class="section-header">
|
<div class="row mb-4">
|
||||||
<h3>Data Management</h3>
|
<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>
|
||||||
|
</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="row">
|
||||||
<div class="col-md-3">
|
<div class="col-md-3 mb-3">
|
||||||
<div class="list-group card-custom">
|
<a href="/admin/import" class="btn btn-outline-primary w-100">
|
||||||
<a href="/admin/players" class="list-group-item">
|
<i class="fas fa-download me-2"></i>
|
||||||
<h4 class="list-group-item-heading">Player Management</h4>
|
<div class="text-start">
|
||||||
<p class="list-group-item-text">Add, edit, and manage players</p>
|
<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>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
</div>
|
||||||
<div class="list-group card-custom">
|
</div>
|
||||||
<a href="/admin/clubs" class="list-group-item">
|
</div>
|
||||||
<h4 class="list-group-item-heading">Club Management</h4>
|
</div>
|
||||||
<p class="list-group-item-text">Manage hockey clubs</p>
|
|
||||||
|
<!-- 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>
|
||||||
</div>
|
<a href="/admin/clubs/add" class="btn btn-outline-success">
|
||||||
</div>
|
<i class="fas fa-plus me-2"></i>Add Club
|
||||||
<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>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Match Management Section -->
|
<div class="col-lg-4 mb-3">
|
||||||
<div class="admin-section">
|
<div class="card h-100 border-primary">
|
||||||
<div class="section-header">
|
<div class="card-header bg-light">
|
||||||
<h3>Match Management</h3>
|
<h6 class="card-title mb-0">
|
||||||
|
<i class="fas fa-user text-primary me-2"></i>Player Management
|
||||||
|
</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="card-body">
|
||||||
<div class="col-md-3">
|
<p class="card-text">Add, edit, and manage player information and squads.</p>
|
||||||
<div class="list-group card-custom">
|
<div class="d-grid gap-2">
|
||||||
<a href="/admin/squad" class="list-group-item">
|
<a href="/admin/players" class="btn btn-primary">
|
||||||
<h4 class="list-group-item-heading">Squad Selection</h4>
|
<i class="fas fa-eye me-2"></i>View Players
|
||||||
<p class="list-group-item-text">Select match squad</p>
|
|
||||||
</a>
|
</a>
|
||||||
</div>
|
<a href="/admin/players/add" class="btn btn-outline-primary">
|
||||||
</div>
|
<i class="fas fa-plus me-2"></i>Add Player
|
||||||
<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>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- MOTM Management Section -->
|
<div class="col-lg-4 mb-3">
|
||||||
<div class="admin-section">
|
<div class="card h-100 border-info">
|
||||||
<div class="section-header">
|
<div class="card-header bg-light">
|
||||||
<h3>MOTM Management</h3>
|
<h6 class="card-title mb-0">
|
||||||
|
<i class="fas fa-layer-group text-info me-2"></i>Team Management
|
||||||
|
</h6>
|
||||||
</div>
|
</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="row">
|
||||||
<div class="col-md-4">
|
<div class="col-lg-4 mb-3">
|
||||||
<div class="list-group card-custom">
|
<div class="card h-100 border-warning">
|
||||||
<a href="/admin/motm" class="list-group-item">
|
<div class="card-header bg-light">
|
||||||
<h4 class="list-group-item-heading">MOTM Admin</h4>
|
<h6 class="card-title mb-0">
|
||||||
<p class="list-group-item-text">Manage match settings and activate voting</p>
|
<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>
|
||||||
</div>
|
<a href="/admin/s3-status" class="btn btn-outline-warning">
|
||||||
</div>
|
<i class="fas fa-info-circle me-2"></i>View Status
|
||||||
<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>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- System Management Section -->
|
<div class="col-lg-4 mb-3">
|
||||||
<div class="admin-section">
|
<div class="card h-100 border-secondary">
|
||||||
<div class="section-header">
|
<div class="card-header bg-light">
|
||||||
<h3>System Management</h3>
|
<h6 class="card-title mb-0">
|
||||||
|
<i class="fas fa-database text-secondary me-2"></i>Database
|
||||||
|
</h6>
|
||||||
</div>
|
</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="row">
|
||||||
<div class="col-md-3">
|
<div class="col-md-3 text-center">
|
||||||
<div class="list-group card-custom">
|
<div class="mb-2">
|
||||||
<a href="/admin/database-setup" class="list-group-item">
|
<i class="fas fa-server text-success fs-1"></i>
|
||||||
<h4 class="list-group-item-heading">Database Setup</h4>
|
|
||||||
<p class="list-group-item-text">Configure and initialize database</p>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
<h6>Database</h6>
|
||||||
|
<span class="badge bg-success">
|
||||||
|
<span class="status-indicator status-online"></span>Online
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3 text-center">
|
||||||
<div class="list-group card-custom">
|
<div class="mb-2">
|
||||||
<a href="/admin/database-status" class="list-group-item">
|
<i class="fas fa-cloud text-info fs-1"></i>
|
||||||
<h4 class="list-group-item-heading">Database Status</h4>
|
|
||||||
<p class="list-group-item-text">View database configuration</p>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
<h6>S3 Storage</h6>
|
||||||
|
<span class="badge bg-info">
|
||||||
|
<span class="status-indicator status-online"></span>Configured
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3 text-center">
|
||||||
<div class="list-group card-custom">
|
<div class="mb-2">
|
||||||
<a href="/admin/s3-config" class="list-group-item">
|
<i class="fas fa-users text-primary fs-1"></i>
|
||||||
<h4 class="list-group-item-heading">S3 Configuration</h4>
|
|
||||||
<p class="list-group-item-text">Configure S3/MinIO storage</p>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
<h6>Active Users</h6>
|
||||||
|
<span class="badge bg-primary">1</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3 text-center">
|
||||||
<div class="list-group card-custom">
|
<div class="mb-2">
|
||||||
<a href="/admin/s3-status" class="list-group-item">
|
<i class="fas fa-calendar text-warning fs-1"></i>
|
||||||
<h4 class="list-group-item-heading">S3 Status</h4>
|
</div>
|
||||||
<p class="list-group-item-text">View S3/MinIO status</p>
|
<h6>Next Match</h6>
|
||||||
</a>
|
<span class="badge bg-warning">Pending</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% endblock %}
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|||||||
280
motm_app/templates/admin_dashboard_new.html
Normal file
280
motm_app/templates/admin_dashboard_new.html
Normal 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 %}
|
||||||
219
motm_app/templates/admin_dashboard_old.html
Normal file
219
motm_app/templates/admin_dashboard_old.html
Normal 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>
|
||||||
349
motm_app/templates/base.html
Normal file
349
motm_app/templates/base.html
Normal 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>
|
||||||
@ -1,19 +1,35 @@
|
|||||||
<html>
|
{% extends "base.html" %}
|
||||||
<head>
|
|
||||||
<title>Error - Invalid URL</title>
|
{% block title %}Error - HKFC MOTM System{% endblock %}
|
||||||
<link rel="stylesheet" media="screen" href ="/static/css/bootstrap.min.css">
|
|
||||||
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
|
{% block content %}
|
||||||
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
|
<div class="row justify-content-center">
|
||||||
</head>
|
<div class="col-lg-8">
|
||||||
<body>
|
<div class="card border-danger">
|
||||||
<div class="container">
|
<div class="card-body text-center">
|
||||||
<div class="row">
|
<div class="mb-4">
|
||||||
<div class="col-md-12">
|
<i class="fas fa-exclamation-triangle text-danger" style="font-size: 4rem;"></i>
|
||||||
<h1>Error</h1>
|
</div>
|
||||||
<p>{{ message or "Invalid voting URL. Please check the link and try again." }}</p>
|
|
||||||
<a class="btn btn-primary" href="/" role="button">Home</a>
|
<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>
|
</div>
|
||||||
</body>
|
</div>
|
||||||
</html>
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|||||||
35
motm_app/templates/error_new.html
Normal file
35
motm_app/templates/error_new.html
Normal 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 %}
|
||||||
19
motm_app/templates/error_old.html
Normal file
19
motm_app/templates/error_old.html
Normal 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>
|
||||||
@ -1,115 +1,237 @@
|
|||||||
<html>
|
{% extends "base.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>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
{% block title %}HKFC Men's C Team - MOTM System{% endblock %}
|
||||||
<div class="col-md-6">
|
|
||||||
<h3>Player Section</h3>
|
{% block content %}
|
||||||
<div class="list-group">
|
<div class="row">
|
||||||
<a href="/motm/comments" class="list-group-item">
|
<div class="col-12">
|
||||||
<h4 class="list-group-item-heading">Match Comments</h4>
|
<!-- Welcome Section -->
|
||||||
<p class="list-group-item-text">View comments from recent matches</p>
|
<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>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Admin Section -->
|
||||||
{% if is_admin %}
|
{% if is_admin %}
|
||||||
<div class="col-md-6">
|
<div class="col-lg-6 mb-4">
|
||||||
<h3>Admin Section</h3>
|
<div class="card h-100">
|
||||||
<div class="list-group">
|
<div class="card-header bg-success text-white">
|
||||||
<a href="/admin" class="list-group-item">
|
<h4 class="card-title mb-0">
|
||||||
<h4 class="list-group-item-heading">Admin Dashboard</h4>
|
<i class="fas fa-user-shield me-2"></i>Admin Section
|
||||||
<p class="list-group-item-text">Access all administrative functions</p>
|
</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>
|
||||||
<a href="/admin/players" class="list-group-item">
|
|
||||||
<h4 class="list-group-item-heading">Player Management</h4>
|
<a href="/admin/clubs" class="btn btn-outline-success">
|
||||||
<p class="list-group-item-text">Add, edit, and manage players in the database</p>
|
<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>
|
||||||
<a href="/admin/clubs" class="list-group-item">
|
|
||||||
<h4 class="list-group-item-heading">Club Management</h4>
|
<a href="/admin/players" class="btn btn-outline-success">
|
||||||
<p class="list-group-item-text">Add, edit, and manage hockey clubs</p>
|
<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>
|
||||||
<a href="/admin/teams" class="list-group-item">
|
|
||||||
<h4 class="list-group-item-heading">Team Management</h4>
|
<a href="/admin/teams" class="btn btn-outline-success">
|
||||||
<p class="list-group-item-text">Add, edit, and manage hockey teams</p>
|
<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>
|
||||||
<a href="/admin/import" class="list-group-item">
|
|
||||||
<h4 class="list-group-item-heading">Data Import</h4>
|
<a href="/admin/s3-config" class="btn btn-outline-info">
|
||||||
<p class="list-group-item-text">Import clubs and teams from Hong Kong Hockey Association</p>
|
<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>
|
||||||
<a href="/admin/squad" class="list-group-item">
|
|
||||||
<h4 class="list-group-item-heading">Match Squad Selection</h4>
|
<a href="/admin/s3-status" class="btn btn-outline-info">
|
||||||
<p class="list-group-item-text">Select players for the match squad</p>
|
<i class="fas fa-cloud-upload-alt me-2"></i>
|
||||||
</a>
|
<div class="text-start">
|
||||||
<a href="/admin/squad/list" class="list-group-item">
|
<div class="fw-bold">S3 Status</div>
|
||||||
<h4 class="list-group-item-heading">View Current Squad</h4>
|
<small class="text-muted">View current S3 configuration and connection status</small>
|
||||||
<p class="list-group-item-text">View current match squad</p>
|
</div>
|
||||||
</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>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="col-md-6">
|
<div class="col-lg-6 mb-4">
|
||||||
<h3>Admin Access</h3>
|
<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">
|
<div class="alert alert-info">
|
||||||
<h4 class="alert-heading">Authentication Required</h4>
|
<h5 class="alert-heading">
|
||||||
<p>Admin functions require authentication. Please contact the system administrator for access.</p>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% 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>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</div>
|
||||||
</html>
|
</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 %}
|
||||||
|
|||||||
237
motm_app/templates/index_new.html
Normal file
237
motm_app/templates/index_new.html
Normal 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 %}
|
||||||
117
motm_app/templates/index_old.html
Normal file
117
motm_app/templates/index_old.html
Normal 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>
|
||||||
@ -1,31 +1,76 @@
|
|||||||
<html>
|
{% extends "base.html" %}
|
||||||
<head>
|
|
||||||
<title>HKFC Men's C Team - Match Comments</title>
|
{% block title %}HKFC Men's C Team - Match Comments{% endblock %}
|
||||||
<link rel="stylesheet" media="screen" href ="/static/css/bootstrap.min.css">
|
|
||||||
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
|
{% block content %}
|
||||||
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
|
<!-- Match Header -->
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
<div class="row mb-4">
|
||||||
<script src="/static/js/bootstrap.min.js"></script>
|
<div class="col-12">
|
||||||
</head>
|
<div class="card">
|
||||||
<body>
|
<div class="card-body text-center">
|
||||||
<h3>Match Comments</h3>
|
<h2 class="card-title">
|
||||||
<div class="row">
|
<i class="fas fa-comments me-2"></i>Match Comments
|
||||||
<div class="col-sm-6">
|
</h2>
|
||||||
<img src="{{ hkfcLogo }}" height="100"></img>
|
|
||||||
<img src="{{ oppoLogo }}" height="100"></img>
|
<!-- 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>
|
</div>
|
||||||
<div class="row">
|
<div class="text-center mx-3">
|
||||||
<div class="col-sm-8">
|
<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 %}
|
{% for comment in comments %}
|
||||||
<div class="panel panel-default">
|
<div class="card mb-3">
|
||||||
<div class="panel-body">
|
<div class="card-body">
|
||||||
{{ comment.comment }}
|
<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>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% 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>
|
||||||
</div>
|
</div>
|
||||||
<a class="btn btn-primary" href="/" role="button">Home</a>
|
{% endif %}
|
||||||
</body>
|
</div>
|
||||||
</html>
|
</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 %}
|
||||||
|
|||||||
76
motm_app/templates/match_comments_new.html
Normal file
76
motm_app/templates/match_comments_new.html
Normal 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 %}
|
||||||
31
motm_app/templates/match_comments_old.html
Normal file
31
motm_app/templates/match_comments_old.html
Normal 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>
|
||||||
@ -1,83 +1,219 @@
|
|||||||
<html>
|
{% extends "base.html" %}
|
||||||
<head>
|
|
||||||
<title>HKFC Men's C Team - MotM and DotD online vote</title>
|
{% block title %}HKFC Men's C Team - MotM and DotD Vote{% endblock %}
|
||||||
<link rel="stylesheet" media="screen" href ="/static/css/bootstrap.min.css">
|
|
||||||
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
|
{% block content %}
|
||||||
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
|
<!-- Match Header -->
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
<div class="row mb-4">
|
||||||
<script src="/static/js/bootstrap.min.js"></script>
|
<div class="col-12">
|
||||||
</head>
|
<div class="card">
|
||||||
<h3>HKFC Men's C Team MotM and DotD online vote</h3>
|
<div class="card-body text-center">
|
||||||
<h5>{{ formatDate }}</h5>
|
<h2 class="card-title">
|
||||||
<h4><img src="{{ hkfcLogo }}" height="150"></img> <b> </b> <img src="{{ oppoLogo }}" height="140"></img></h4>
|
<i class="fas fa-trophy text-warning me-2"></i>
|
||||||
<body>
|
HKFC Men's C Team MotM and DotD Vote
|
||||||
<p><b>Randomly selected comment from the match:</b>
|
</h2>
|
||||||
<br/>
|
<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 %}
|
{% for item in comment %}
|
||||||
<i>{{ item.comment }}</i>
|
<blockquote class="blockquote text-center">
|
||||||
{% endfor %}
|
<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>
|
</p>
|
||||||
<dl>
|
</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 }}
|
{{ 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="matchNumber" name="matchNumber" value="{{ matchNumber }}">
|
||||||
<input type="hidden" id="oppo" name="oppo" value="{{ oppo }}">
|
<input type="hidden" id="oppo" name="oppo" value="{{ oppo }}">
|
||||||
<div class = "row">
|
|
||||||
<div class = "col-sm-6">
|
<div class="mb-3">
|
||||||
<div class="input-group">
|
<label for="motmSelect" class="form-label">Select Player:</label>
|
||||||
<span class="input-group-addon" id="basic-addon1">Man of the Match</span>
|
<select class="form-select" id="motmSelect" name="motmSelect" required>
|
||||||
<select class="form-control" name="motmVote" required>
|
<option value="">Choose a player...</option>
|
||||||
{% for item in data %}
|
{% for player in data %}
|
||||||
{% if item.playernickname != "" %}
|
<option value="{{ player.playernumber }}">{{ player.playerforenames }} {{ player.playersurname }}
|
||||||
<option value={{ item.playernumber }}>{{ item.playernickname }}</option>
|
{% if player.playernickname %}"{{ player.playernickname }}"{% endif %}
|
||||||
{% else %}
|
</option>
|
||||||
<option value={{ item.playernumber }}>{{ item.playersurname }}, {{ item.playerforenames }}</option>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</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>
|
</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>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</dl>
|
</div>
|
||||||
</body>
|
|
||||||
</html>
|
<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 %}
|
||||||
|
|||||||
219
motm_app/templates/motm_vote_new.html
Normal file
219
motm_app/templates/motm_vote_new.html
Normal 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 %}
|
||||||
83
motm_app/templates/motm_vote_old.html
Normal file
83
motm_app/templates/motm_vote_old.html
Normal 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>
|
||||||
@ -1,11 +1,9 @@
|
|||||||
<!DOCTYPE html>
|
{% extends "base.html" %}
|
||||||
<html lang="en">
|
|
||||||
<head>
|
{% block title %}S3 Configuration - HKFC Men's C Team{% endblock %}
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
{% block extra_head %}
|
||||||
<title>S3 Configuration - HKFC Men's C Team</title>
|
<style>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
||||||
<style>
|
|
||||||
.config-section {
|
.config-section {
|
||||||
background-color: #f8f9fa;
|
background-color: #f8f9fa;
|
||||||
border-radius: 0.375rem;
|
border-radius: 0.375rem;
|
||||||
@ -16,18 +14,10 @@
|
|||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
color: #6c757d;
|
color: #6c757d;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
{% endblock %}
|
||||||
<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">
|
{% block content %}
|
||||||
<a href="/admin" class="btn btn-secondary">Back to Admin</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||||
{% if messages %}
|
{% if messages %}
|
||||||
@ -251,5 +241,4 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
{% endblock %}
|
||||||
</html>
|
|
||||||
|
|||||||
@ -1,22 +1,26 @@
|
|||||||
<!DOCTYPE html>
|
{% extends "base.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">
|
{% block title %}S3 Status - HKFC Men's C Team{% endblock %}
|
||||||
<a href="/admin/s3-config" class="btn btn-primary">Configure S3</a>
|
|
||||||
<a href="/admin" class="btn btn-secondary">Back to Admin</a>
|
{% 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>
|
||||||
|
<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">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
@ -149,6 +153,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
{% endblock %}
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|||||||
@ -1,19 +1,44 @@
|
|||||||
<html>
|
{% extends "base.html" %}
|
||||||
<head>
|
|
||||||
<title>HKFC Men's C Team - MotM and DotD vote</title>
|
{% block title %}Vote Submitted - HKFC MOTM System{% endblock %}
|
||||||
<link rel="stylesheet" media="screen" href ="/static/css/bootstrap.min.css">
|
|
||||||
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
|
{% block content %}
|
||||||
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
|
<div class="row justify-content-center">
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
<div class="col-lg-8">
|
||||||
<script src="/static/js/bootstrap.min.js"></script>
|
<div class="card border-success">
|
||||||
</head>
|
<div class="card-body text-center">
|
||||||
<h2>Thanks for submitting the MotM and DotD votes</h2>
|
<div class="mb-4">
|
||||||
<body>
|
<i class="fas fa-check-circle text-success" style="font-size: 4rem;"></i>
|
||||||
Smithers' army of Internet monkeys will now go about adding up the votes ...
|
</div>
|
||||||
<p>
|
|
||||||
<img src="http://icarus.ipa.champion:9000/hockey-app/assets/simpsons-monkeys.jpg"></img>
|
<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>
|
</p>
|
||||||
<a class="btn btn-primary" href="/" role="button">Home</a>
|
</div>
|
||||||
<a class="btn btn-info" href="/motm/comments" role="button">Comments</a>
|
|
||||||
</body>
|
<div class="mb-4">
|
||||||
</html>
|
<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 %}
|
||||||
|
|||||||
44
motm_app/templates/vote_thanks_new.html
Normal file
44
motm_app/templates/vote_thanks_new.html
Normal 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 %}
|
||||||
19
motm_app/templates/vote_thanks_old.html
Normal file
19
motm_app/templates/vote_thanks_old.html
Normal 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>
|
||||||
Loading…
Reference in New Issue
Block a user