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)
|
||||
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>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Admin Dashboard - HKFC Men's C Team MOTM System</title>
|
||||
<link rel="stylesheet" media="screen" href="/static/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="/static/js/bootstrap.min.js"></script>
|
||||
<style>
|
||||
.admin-section {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.section-header {
|
||||
background-color: #f5f5f5;
|
||||
padding: 15px;
|
||||
border-left: 4px solid #337ab7;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.card-custom {
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
.card-custom:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="page-header">
|
||||
<h1>HKFC Men's C Team - Admin Dashboard</h1>
|
||||
<p class="lead">Central hub for all administrative functions</p>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<a href="/" class="btn btn-default">Back to Main Page</a>
|
||||
<a href="/admin/profile" class="btn btn-outline-secondary">Admin Profile</a>
|
||||
</div>
|
||||
|
||||
<!-- Data Management Section -->
|
||||
<div class="admin-section">
|
||||
<div class="section-header">
|
||||
<h3>Data Management</h3>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<div class="list-group card-custom">
|
||||
<a href="/admin/players" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Player Management</h4>
|
||||
<p class="list-group-item-text">Add, edit, and manage players</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="list-group card-custom">
|
||||
<a href="/admin/clubs" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Club Management</h4>
|
||||
<p class="list-group-item-text">Manage hockey clubs</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="list-group card-custom">
|
||||
<a href="/admin/teams" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Team Management</h4>
|
||||
<p class="list-group-item-text">Manage hockey teams</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="list-group card-custom">
|
||||
<a href="/admin/import" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Data Import</h4>
|
||||
<p class="list-group-item-text">Import clubs and teams</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Match Management Section -->
|
||||
<div class="admin-section">
|
||||
<div class="section-header">
|
||||
<h3>Match Management</h3>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<div class="list-group card-custom">
|
||||
<a href="/admin/squad" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Squad Selection</h4>
|
||||
<p class="list-group-item-text">Select match squad</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="list-group card-custom">
|
||||
<a href="/admin/squad/list" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">View Squad</h4>
|
||||
<p class="list-group-item-text">View current squad</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="list-group card-custom">
|
||||
<a href="/admin/squad/reset" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Reset Squad</h4>
|
||||
<p class="list-group-item-text">Reset for new match</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="list-group card-custom">
|
||||
<a href="/admin/stats" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Goals & Assists</h4>
|
||||
<p class="list-group-item-text">Record statistics</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- MOTM Management Section -->
|
||||
<div class="admin-section">
|
||||
<div class="section-header">
|
||||
<h3>MOTM Management</h3>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="list-group card-custom">
|
||||
<a href="/admin/motm" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">MOTM Admin</h4>
|
||||
<p class="list-group-item-text">Manage match settings and activate voting</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="list-group card-custom">
|
||||
<a href="/admin/voting" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Voting Results</h4>
|
||||
<p class="list-group-item-text">View current match results</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="list-group card-custom">
|
||||
<a href="/admin/motm/manage" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">MOTM Management</h4>
|
||||
<p class="list-group-item-text">Reset MOTM/DotD counts for specific fixtures</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="list-group card-custom">
|
||||
<a href="/admin/device-tracking" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Device Tracking</h4>
|
||||
<p class="list-group-item-text">Monitor voting patterns and detect duplicate votes</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="list-group card-custom">
|
||||
<a href="/admin/poty" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Player of the Year</h4>
|
||||
<p class="list-group-item-text">View season standings</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- System Management Section -->
|
||||
<div class="admin-section">
|
||||
<div class="section-header">
|
||||
<h3>System Management</h3>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<div class="list-group card-custom">
|
||||
<a href="/admin/database-setup" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Database Setup</h4>
|
||||
<p class="list-group-item-text">Configure and initialize database</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="list-group card-custom">
|
||||
<a href="/admin/database-status" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Database Status</h4>
|
||||
<p class="list-group-item-text">View database configuration</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="list-group card-custom">
|
||||
<a href="/admin/s3-config" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">S3 Configuration</h4>
|
||||
<p class="list-group-item-text">Configure S3/MinIO storage</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="list-group card-custom">
|
||||
<a href="/admin/s3-status" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">S3 Status</h4>
|
||||
<p class="list-group-item-text">View S3/MinIO status</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Admin Dashboard - HKFC Men's C Team MOTM System{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Dashboard Header -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body text-center">
|
||||
<h1 class="card-title">
|
||||
<i class="fas fa-tachometer-alt text-primary me-2"></i>
|
||||
Admin Dashboard
|
||||
</h1>
|
||||
<p class="lead text-muted">Central hub for all administrative functions</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quick Actions -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h5 class="card-title mb-0">
|
||||
<i class="fas fa-bolt me-2"></i>Quick Actions
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-3 mb-3">
|
||||
<a href="/admin/import" class="btn btn-outline-primary w-100">
|
||||
<i class="fas fa-download me-2"></i>
|
||||
<div class="text-start">
|
||||
<div class="fw-bold">Import Data</div>
|
||||
<small class="text-muted">Import from HKHA</small>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<a href="/admin/squad" class="btn btn-outline-success w-100">
|
||||
<i class="fas fa-list-check me-2"></i>
|
||||
<div class="text-start">
|
||||
<div class="fw-bold">Select Squad</div>
|
||||
<small class="text-muted">Choose match squad</small>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<a href="/admin/motm" class="btn btn-outline-warning w-100">
|
||||
<i class="fas fa-trophy me-2"></i>
|
||||
<div class="text-start">
|
||||
<div class="fw-bold">MOTM Settings</div>
|
||||
<small class="text-muted">Manage voting</small>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-3 mb-3">
|
||||
<a href="/admin/profile" class="btn btn-outline-secondary w-100">
|
||||
<i class="fas fa-user-cog me-2"></i>
|
||||
<div class="text-start">
|
||||
<div class="fw-bold">Admin Profile</div>
|
||||
<small class="text-muted">Account settings</small>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Data Management Section -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-success text-white">
|
||||
<h5 class="card-title mb-0">
|
||||
<i class="fas fa-database me-2"></i>Data Management
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-lg-4 mb-3">
|
||||
<div class="card h-100 border-success">
|
||||
<div class="card-header bg-light">
|
||||
<h6 class="card-title mb-0">
|
||||
<i class="fas fa-users text-success me-2"></i>Club Management
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="card-text">Manage hockey clubs, logos, and club information.</p>
|
||||
<div class="d-grid gap-2">
|
||||
<a href="/admin/clubs" class="btn btn-success">
|
||||
<i class="fas fa-eye me-2"></i>View Clubs
|
||||
</a>
|
||||
<a href="/admin/clubs/add" class="btn btn-outline-success">
|
||||
<i class="fas fa-plus me-2"></i>Add Club
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 mb-3">
|
||||
<div class="card h-100 border-primary">
|
||||
<div class="card-header bg-light">
|
||||
<h6 class="card-title mb-0">
|
||||
<i class="fas fa-user text-primary me-2"></i>Player Management
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="card-text">Add, edit, and manage player information and squads.</p>
|
||||
<div class="d-grid gap-2">
|
||||
<a href="/admin/players" class="btn btn-primary">
|
||||
<i class="fas fa-eye me-2"></i>View Players
|
||||
</a>
|
||||
<a href="/admin/players/add" class="btn btn-outline-primary">
|
||||
<i class="fas fa-plus me-2"></i>Add Player
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 mb-3">
|
||||
<div class="card h-100 border-info">
|
||||
<div class="card-header bg-light">
|
||||
<h6 class="card-title mb-0">
|
||||
<i class="fas fa-layer-group text-info me-2"></i>Team Management
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="card-text">Manage hockey teams and their associations with clubs.</p>
|
||||
<div class="d-grid gap-2">
|
||||
<a href="/admin/teams" class="btn btn-info">
|
||||
<i class="fas fa-eye me-2"></i>View Teams
|
||||
</a>
|
||||
<a href="/admin/teams/add" class="btn btn-outline-info">
|
||||
<i class="fas fa-plus me-2"></i>Add Team
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- System Management Section -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-warning text-dark">
|
||||
<h5 class="card-title mb-0">
|
||||
<i class="fas fa-cogs me-2"></i>System Management
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-lg-4 mb-3">
|
||||
<div class="card h-100 border-warning">
|
||||
<div class="card-header bg-light">
|
||||
<h6 class="card-title mb-0">
|
||||
<i class="fas fa-cloud text-warning me-2"></i>S3 Storage
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="card-text">Configure and manage S3 storage for assets and logos.</p>
|
||||
<div class="d-grid gap-2">
|
||||
<a href="/admin/s3-config" class="btn btn-warning">
|
||||
<i class="fas fa-cog me-2"></i>Configure S3
|
||||
</a>
|
||||
<a href="/admin/s3-status" class="btn btn-outline-warning">
|
||||
<i class="fas fa-info-circle me-2"></i>View Status
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 mb-3">
|
||||
<div class="card h-100 border-secondary">
|
||||
<div class="card-header bg-light">
|
||||
<h6 class="card-title mb-0">
|
||||
<i class="fas fa-database text-secondary me-2"></i>Database
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="card-text">Manage database configuration and status.</p>
|
||||
<div class="d-grid gap-2">
|
||||
<a href="/admin/database-status" class="btn btn-secondary">
|
||||
<i class="fas fa-info-circle me-2"></i>Database Status
|
||||
</a>
|
||||
<a href="/admin/database-setup" class="btn btn-outline-secondary">
|
||||
<i class="fas fa-wrench me-2"></i>Database Setup
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4 mb-3">
|
||||
<div class="card h-100 border-dark">
|
||||
<div class="card-header bg-light">
|
||||
<h6 class="card-title mb-0">
|
||||
<i class="fas fa-list-check text-dark me-2"></i>Squad Management
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="card-text">Manage match squads and player selections.</p>
|
||||
<div class="d-grid gap-2">
|
||||
<a href="/admin/squad/list" class="btn btn-dark">
|
||||
<i class="fas fa-eye me-2"></i>View Squad
|
||||
</a>
|
||||
<a href="/admin/squad/reset" class="btn btn-outline-dark">
|
||||
<i class="fas fa-refresh me-2"></i>Reset Squad
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- System Status -->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-info text-white">
|
||||
<h5 class="card-title mb-0">
|
||||
<i class="fas fa-heartbeat me-2"></i>System Status
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-3 text-center">
|
||||
<div class="mb-2">
|
||||
<i class="fas fa-server text-success fs-1"></i>
|
||||
</div>
|
||||
<h6>Database</h6>
|
||||
<span class="badge bg-success">
|
||||
<span class="status-indicator status-online"></span>Online
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-md-3 text-center">
|
||||
<div class="mb-2">
|
||||
<i class="fas fa-cloud text-info fs-1"></i>
|
||||
</div>
|
||||
<h6>S3 Storage</h6>
|
||||
<span class="badge bg-info">
|
||||
<span class="status-indicator status-online"></span>Configured
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-md-3 text-center">
|
||||
<div class="mb-2">
|
||||
<i class="fas fa-users text-primary fs-1"></i>
|
||||
</div>
|
||||
<h6>Active Users</h6>
|
||||
<span class="badge bg-primary">1</span>
|
||||
</div>
|
||||
<div class="col-md-3 text-center">
|
||||
<div class="mb-2">
|
||||
<i class="fas fa-calendar text-warning fs-1"></i>
|
||||
</div>
|
||||
<h6>Next Match</h6>
|
||||
<span class="badge bg-warning">Pending</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
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>
|
||||
<head>
|
||||
<title>Error - Invalid URL</title>
|
||||
<link rel="stylesheet" media="screen" href ="/static/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
|
||||
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1>Error</h1>
|
||||
<p>{{ message or "Invalid voting URL. Please check the link and try again." }}</p>
|
||||
<a class="btn btn-primary" href="/" role="button">Home</a>
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Error - HKFC MOTM System{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<div class="card border-danger">
|
||||
<div class="card-body text-center">
|
||||
<div class="mb-4">
|
||||
<i class="fas fa-exclamation-triangle text-danger" style="font-size: 4rem;"></i>
|
||||
</div>
|
||||
|
||||
<h1 class="card-title text-danger">Error</h1>
|
||||
|
||||
<div class="alert alert-danger">
|
||||
<h5 class="alert-heading">
|
||||
<i class="fas fa-info-circle me-2"></i>Something went wrong
|
||||
</h5>
|
||||
<p class="mb-0">{{ message or "Invalid voting URL. Please check the link and try again." }}</p>
|
||||
</div>
|
||||
|
||||
<div class="d-grid gap-2 d-md-flex justify-content-md-center">
|
||||
<a href="/" class="btn btn-primary">
|
||||
<i class="fas fa-home me-2"></i>Back to Home
|
||||
</a>
|
||||
<button onclick="history.back()" class="btn btn-outline-secondary">
|
||||
<i class="fas fa-arrow-left me-2"></i>Go Back
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
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>
|
||||
<head>
|
||||
<title>HKFC Men's C Team - MOTM System</title>
|
||||
<link rel="stylesheet" media="screen" href ="/static/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
|
||||
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="/static/js/bootstrap.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1>HKFC Men's C Team - Man of the Match System</h1>
|
||||
<div class="jumbotron">
|
||||
<h2>Welcome to the MOTM Voting System</h2>
|
||||
<p>This system allows players to vote for Man of the Match and Dick of the Day, while providing admin tools for managing matches and squads.</p>
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}HKFC Men's C Team - MOTM System{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<!-- Welcome Section -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-body text-center">
|
||||
<h2 class="card-title">
|
||||
<i class="fas fa-trophy text-warning me-2"></i>
|
||||
Welcome to the MOTM Voting System
|
||||
</h2>
|
||||
<p class="card-text lead">
|
||||
This system allows players to vote for Man of the Match and Dick of the Day,
|
||||
while providing admin tools for managing matches and squads.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<!-- Player Section -->
|
||||
<div class="col-lg-6 mb-4">
|
||||
<div class="card h-100">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h4 class="card-title mb-0">
|
||||
<i class="fas fa-users me-2"></i>Player Section
|
||||
</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-grid gap-2">
|
||||
<a href="/motm/comments" class="btn btn-outline-primary btn-lg">
|
||||
<i class="fas fa-comments me-2"></i>
|
||||
<div class="text-start">
|
||||
<div class="fw-bold">Match Comments</div>
|
||||
<small class="text-muted">View comments from recent matches</small>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Admin Section -->
|
||||
{% if is_admin %}
|
||||
<div class="col-lg-6 mb-4">
|
||||
<div class="card h-100">
|
||||
<div class="card-header bg-success text-white">
|
||||
<h4 class="card-title mb-0">
|
||||
<i class="fas fa-user-shield me-2"></i>Admin Section
|
||||
</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-grid gap-2">
|
||||
<a href="/admin" class="btn btn-outline-success">
|
||||
<i class="fas fa-tachometer-alt me-2"></i>
|
||||
<div class="text-start">
|
||||
<div class="fw-bold">Admin Dashboard</div>
|
||||
<small class="text-muted">Access all administrative functions</small>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="/admin/clubs" class="btn btn-outline-success">
|
||||
<i class="fas fa-users me-2"></i>
|
||||
<div class="text-start">
|
||||
<div class="fw-bold">Club Management</div>
|
||||
<small class="text-muted">Add, edit, and manage hockey clubs</small>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="/admin/players" class="btn btn-outline-success">
|
||||
<i class="fas fa-user me-2"></i>
|
||||
<div class="text-start">
|
||||
<div class="fw-bold">Player Management</div>
|
||||
<small class="text-muted">Add, edit, and manage players</small>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="/admin/teams" class="btn btn-outline-success">
|
||||
<i class="fas fa-layer-group me-2"></i>
|
||||
<div class="text-start">
|
||||
<div class="fw-bold">Team Management</div>
|
||||
<small class="text-muted">Add, edit, and manage hockey teams</small>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="/admin/s3-config" class="btn btn-outline-info">
|
||||
<i class="fas fa-cloud me-2"></i>
|
||||
<div class="text-start">
|
||||
<div class="fw-bold">S3 Configuration</div>
|
||||
<small class="text-muted">Configure AWS S3 storage for logos and assets</small>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a href="/admin/s3-status" class="btn btn-outline-info">
|
||||
<i class="fas fa-cloud-upload-alt me-2"></i>
|
||||
<div class="text-start">
|
||||
<div class="fw-bold">S3 Status</div>
|
||||
<small class="text-muted">View current S3 configuration and connection status</small>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-lg-6 mb-4">
|
||||
<div class="card h-100">
|
||||
<div class="card-header bg-secondary text-white">
|
||||
<h4 class="card-title mb-0">
|
||||
<i class="fas fa-lock me-2"></i>Admin Access
|
||||
</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="alert alert-info">
|
||||
<h5 class="alert-heading">
|
||||
<i class="fas fa-info-circle me-2"></i>Authentication Required
|
||||
</h5>
|
||||
<p class="mb-0">Admin functions require authentication. Please contact the system administrator for access.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Additional Admin Functions (if admin) -->
|
||||
{% if is_admin %}
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-warning text-dark">
|
||||
<h4 class="card-title mb-0">
|
||||
<i class="fas fa-cogs me-2"></i>System Management
|
||||
</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<a href="/admin/import" class="btn btn-outline-warning w-100">
|
||||
<i class="fas fa-download me-2"></i>
|
||||
<div class="text-start">
|
||||
<div class="fw-bold">Data Import</div>
|
||||
<small class="text-muted">Import clubs and teams from HKHA</small>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3>Player Section</h3>
|
||||
<div class="list-group">
|
||||
<a href="/motm/comments" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Match Comments</h4>
|
||||
<p class="list-group-item-text">View comments from recent matches</p>
|
||||
</a>
|
||||
<div class="col-md-4 mb-3">
|
||||
<a href="/admin/squad" class="btn btn-outline-warning w-100">
|
||||
<i class="fas fa-list-check me-2"></i>
|
||||
<div class="text-start">
|
||||
<div class="fw-bold">Squad Selection</div>
|
||||
<small class="text-muted">Select players for match squad</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if is_admin %}
|
||||
<div class="col-md-6">
|
||||
<h3>Admin Section</h3>
|
||||
<div class="list-group">
|
||||
<a href="/admin" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Admin Dashboard</h4>
|
||||
<p class="list-group-item-text">Access all administrative functions</p>
|
||||
</a>
|
||||
<a href="/admin/players" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Player Management</h4>
|
||||
<p class="list-group-item-text">Add, edit, and manage players in the database</p>
|
||||
</a>
|
||||
<a href="/admin/clubs" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Club Management</h4>
|
||||
<p class="list-group-item-text">Add, edit, and manage hockey clubs</p>
|
||||
</a>
|
||||
<a href="/admin/teams" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Team Management</h4>
|
||||
<p class="list-group-item-text">Add, edit, and manage hockey teams</p>
|
||||
</a>
|
||||
<a href="/admin/import" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Data Import</h4>
|
||||
<p class="list-group-item-text">Import clubs and teams from Hong Kong Hockey Association</p>
|
||||
</a>
|
||||
<a href="/admin/squad" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Match Squad Selection</h4>
|
||||
<p class="list-group-item-text">Select players for the match squad</p>
|
||||
</a>
|
||||
<a href="/admin/squad/list" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">View Current Squad</h4>
|
||||
<p class="list-group-item-text">View current match squad</p>
|
||||
</a>
|
||||
<a href="/admin/squad/reset" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Reset Squad</h4>
|
||||
<p class="list-group-item-text">Reset squad for new match</p>
|
||||
</a>
|
||||
<a href="/admin/motm" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">MOTM Admin</h4>
|
||||
<p class="list-group-item-text">Manage match settings and activate voting</p>
|
||||
</a>
|
||||
<a href="/admin/stats" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Goals & Assists</h4>
|
||||
<p class="list-group-item-text">Record goals and assists statistics</p>
|
||||
</a>
|
||||
<a href="/admin/voting" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Voting Results</h4>
|
||||
<p class="list-group-item-text">View current match voting results</p>
|
||||
</a>
|
||||
<a href="/admin/poty" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Player of the Year</h4>
|
||||
<p class="list-group-item-text">View season totals and Player of the Year standings</p>
|
||||
</a>
|
||||
<a href="/admin/database-setup" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Database Setup</h4>
|
||||
<p class="list-group-item-text">Configure and initialize the database</p>
|
||||
</a>
|
||||
<a href="/admin/database-status" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">Database Status</h4>
|
||||
<p class="list-group-item-text">View current database configuration and status</p>
|
||||
</a>
|
||||
<a href="/admin/s3-config" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">S3 Configuration</h4>
|
||||
<p class="list-group-item-text">Configure AWS S3 storage for logos and assets</p>
|
||||
</a>
|
||||
<a href="/admin/s3-status" class="list-group-item">
|
||||
<h4 class="list-group-item-heading">S3 Status</h4>
|
||||
<p class="list-group-item-text">View current S3 configuration and connection status</p>
|
||||
</a>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 mb-3">
|
||||
<a href="/admin/motm" class="btn btn-outline-warning w-100">
|
||||
<i class="fas fa-trophy me-2"></i>
|
||||
<div class="text-start">
|
||||
<div class="fw-bold">MOTM Management</div>
|
||||
<small class="text-muted">Manage Man of the Match settings</small>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-md-6">
|
||||
<h3>Admin Access</h3>
|
||||
<div class="alert alert-info">
|
||||
<h4 class="alert-heading">Authentication Required</h4>
|
||||
<p>Admin functions require authentication. Please contact the system administrator for access.</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4 mb-3">
|
||||
<a href="/admin/squad/list" class="btn btn-outline-secondary w-100">
|
||||
<i class="fas fa-eye me-2"></i>
|
||||
<div class="text-start">
|
||||
<div class="fw-bold">View Current Squad</div>
|
||||
<small class="text-muted">View current match squad</small>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 mb-3">
|
||||
<a href="/admin/squad/reset" class="btn btn-outline-danger w-100">
|
||||
<i class="fas fa-refresh me-2"></i>
|
||||
<div class="text-start">
|
||||
<div class="fw-bold">Reset Squad</div>
|
||||
<small class="text-muted">Reset squad for new match</small>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 mb-3">
|
||||
<a href="/admin/profile" class="btn btn-outline-secondary w-100">
|
||||
<i class="fas fa-user-cog me-2"></i>
|
||||
<div class="text-start">
|
||||
<div class="fw-bold">Admin Profile</div>
|
||||
<small class="text-muted">Manage admin settings</small>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- System Status Card -->
|
||||
<div class="row mt-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-info text-white">
|
||||
<h4 class="card-title mb-0">
|
||||
<i class="fas fa-info-circle me-2"></i>System Information
|
||||
</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h6><i class="fas fa-server me-2"></i>System Status</h6>
|
||||
<p class="text-muted">
|
||||
<span class="status-indicator status-online"></span>
|
||||
System Online
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h6><i class="fas fa-calendar-alt me-2"></i>Current Season</h6>
|
||||
<p class="text-muted">2024-2025 Hockey Season</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
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>
|
||||
<head>
|
||||
<title>HKFC Men's C Team - Match Comments</title>
|
||||
<link rel="stylesheet" media="screen" href ="/static/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
|
||||
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="/static/js/bootstrap.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h3>Match Comments</h3>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<img src="{{ hkfcLogo }}" height="100"></img>
|
||||
<img src="{{ oppoLogo }}" height="100"></img>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-8">
|
||||
{% for comment in comments %}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
{{ comment.comment }}
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}HKFC Men's C Team - Match Comments{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Match Header -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body text-center">
|
||||
<h2 class="card-title">
|
||||
<i class="fas fa-comments me-2"></i>Match Comments
|
||||
</h2>
|
||||
|
||||
<!-- Team Logos -->
|
||||
<div class="d-flex justify-content-center align-items-center mt-3">
|
||||
<div class="text-center me-4">
|
||||
<img src="{{ hkfcLogo }}" alt="HKFC Logo" class="img-fluid" style="max-height: 100px;">
|
||||
<div class="mt-2">
|
||||
<strong>HKFC</strong>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="text-center mx-3">
|
||||
<h4 class="text-primary">VS</h4>
|
||||
</div>
|
||||
<div class="text-center ms-4">
|
||||
<img src="{{ oppoLogo }}" alt="Opponent Logo" class="img-fluid" style="max-height: 100px;">
|
||||
<div class="mt-2">
|
||||
<strong>Opponent</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-primary" href="/" role="button">Home</a>
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Comments Section -->
|
||||
<div class="row">
|
||||
<div class="col-lg-8 mx-auto">
|
||||
{% if comments %}
|
||||
{% for comment in comments %}
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-start">
|
||||
<div class="flex-shrink-0">
|
||||
<i class="fas fa-comment-dots text-primary fs-4"></i>
|
||||
</div>
|
||||
<div class="flex-grow-1 ms-3">
|
||||
<p class="mb-0">{{ comment.comment }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="card">
|
||||
<div class="card-body text-center">
|
||||
<i class="fas fa-comment-slash text-muted fs-1 mb-3"></i>
|
||||
<h5 class="text-muted">No comments yet</h5>
|
||||
<p class="text-muted">Comments for this match will appear here once they are added.</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Navigation -->
|
||||
<div class="row mt-4">
|
||||
<div class="col-12 text-center">
|
||||
<a href="/" class="btn btn-primary">
|
||||
<i class="fas fa-home me-2"></i>Back to Home
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
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>
|
||||
<head>
|
||||
<title>HKFC Men's C Team - MotM and DotD online vote</title>
|
||||
<link rel="stylesheet" media="screen" href ="/static/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
|
||||
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="/static/js/bootstrap.min.js"></script>
|
||||
</head>
|
||||
<h3>HKFC Men's C Team MotM and DotD online vote</h3>
|
||||
<h5>{{ formatDate }}</h5>
|
||||
<h4><img src="{{ hkfcLogo }}" height="150"></img> <b> </b> <img src="{{ oppoLogo }}" height="140"></img></h4>
|
||||
<body>
|
||||
<p><b>Randomly selected comment from the match:</b>
|
||||
<br/>
|
||||
{% for item in comment %}
|
||||
<i>{{ item.comment }}</i>
|
||||
{% endfor %}
|
||||
</p>
|
||||
<dl>
|
||||
{{ form.csrf_token }}
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<form class="col-sm-6" method="post" action="/motm/vote-thanks" id="motmForm" accept-charset="utf-8">
|
||||
<input type="hidden" id="matchNumber" name="matchNumber" value="{{ matchNumber }}">
|
||||
<input type="hidden" id="oppo" name="oppo" value="{{ oppo }}">
|
||||
<div class = "row">
|
||||
<div class = "col-sm-6">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon" id="basic-addon1">Man of the Match</span>
|
||||
<select class="form-control" name="motmVote" required>
|
||||
{% for item in data %}
|
||||
{% if item.playernickname != "" %}
|
||||
<option value={{ item.playernumber }}>{{ item.playernickname }}</option>
|
||||
{% else %}
|
||||
<option value={{ item.playernumber }}>{{ item.playersurname }}, {{ item.playerforenames }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class = "col-sm-6">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon" id="basic-addon1">Dick of the Day</span>
|
||||
<select class="form-control" name="dotdVote" required>
|
||||
{% for item in data %}
|
||||
{% if item.playernickname != "" %}
|
||||
<option value={{ item.playernumber }}>{{ item.playernickname }}</option>
|
||||
{% else %}
|
||||
<option value={{ item.playernumber }}>{{ item.playersurname }}, {{ item.playerforenames }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}HKFC Men's C Team - MotM and DotD Vote{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Match Header -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body text-center">
|
||||
<h2 class="card-title">
|
||||
<i class="fas fa-trophy text-warning me-2"></i>
|
||||
HKFC Men's C Team MotM and DotD Vote
|
||||
</h2>
|
||||
<h5 class="text-muted">{{ formatDate }}</h5>
|
||||
|
||||
<!-- Team Logos -->
|
||||
<div class="d-flex justify-content-center align-items-center mt-3">
|
||||
<div class="text-center me-4">
|
||||
<img src="{{ hkfcLogo }}" alt="HKFC Logo" class="img-fluid" style="max-height: 120px;">
|
||||
<div class="mt-2">
|
||||
<strong>HKFC</strong>
|
||||
</div>
|
||||
<div class = "row">
|
||||
<div class = "col-sm-6">
|
||||
<div class = "input-group">
|
||||
<span class = "input-group-addon" id = "basic-addon1">Match comments</span>
|
||||
<textarea rows = "4" cols = "80" name = "motmComment" form = "motmForm">Optional comments added here</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center mx-3">
|
||||
<h3 class="text-primary">VS</h3>
|
||||
</div>
|
||||
<div class="text-center ms-4">
|
||||
<img src="{{ oppoLogo }}" alt="Opponent Logo" class="img-fluid" style="max-height: 120px;">
|
||||
<div class="mt-2">
|
||||
<strong>{{ oppo }}</strong>
|
||||
</div>
|
||||
<div class = "row">
|
||||
<h3>Rogues Gallery</h3>
|
||||
<div class = "col-sm-4">
|
||||
<h4>Current Man of the Match</h4>
|
||||
<img src="{{ motmURL }}" height="200"></img>
|
||||
</div>
|
||||
<div class = "col-sm-4">
|
||||
<h4>Current Dick of the Day</h4>
|
||||
<img src="{{ dotdURL }}" height="200"></img>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success">Submit</button>
|
||||
<a class="btn btn-danger" href="/" role="button">Cancel</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</dl>
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Random Comment -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-info text-white">
|
||||
<h5 class="card-title mb-0">
|
||||
<i class="fas fa-comment-dots me-2"></i>Random Match Comment
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% for item in comment %}
|
||||
<blockquote class="blockquote text-center">
|
||||
<p class="mb-0">
|
||||
<i class="fas fa-quote-left text-muted me-2"></i>
|
||||
<em>{{ item.comment }}</em>
|
||||
<i class="fas fa-quote-right text-muted ms-2"></i>
|
||||
</p>
|
||||
</blockquote>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Voting Forms -->
|
||||
<div class="row">
|
||||
<div class="col-lg-6 mb-4">
|
||||
<!-- Man of the Match -->
|
||||
<div class="card h-100">
|
||||
<div class="card-header bg-success text-white">
|
||||
<h5 class="card-title mb-0">
|
||||
<i class="fas fa-trophy me-2"></i>Man of the Match
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="post" action="/motm/vote-thanks" id="motmForm">
|
||||
{{ form.csrf_token }}
|
||||
<input type="hidden" id="matchNumber" name="matchNumber" value="{{ matchNumber }}">
|
||||
<input type="hidden" id="oppo" name="oppo" value="{{ oppo }}">
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="motmSelect" class="form-label">Select Player:</label>
|
||||
<select class="form-select" id="motmSelect" name="motmSelect" required>
|
||||
<option value="">Choose a player...</option>
|
||||
{% for player in data %}
|
||||
<option value="{{ player.playernumber }}">{{ player.playerforenames }} {{ player.playersurname }}
|
||||
{% if player.playernickname %}"{{ player.playernickname }}"{% endif %}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="d-grid">
|
||||
<button type="submit" class="btn btn-success btn-lg">
|
||||
<i class="fas fa-vote-yea me-2"></i>Submit MOTM Vote
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-6 mb-4">
|
||||
<!-- Dick of the Day -->
|
||||
<div class="card h-100">
|
||||
<div class="card-header bg-warning text-dark">
|
||||
<h5 class="card-title mb-0">
|
||||
<i class="fas fa-award me-2"></i>Dick of the Day
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="post" action="/motm/dotd-thanks" id="dotdForm">
|
||||
{{ form.csrf_token }}
|
||||
<input type="hidden" id="matchNumber" name="matchNumber" value="{{ matchNumber }}">
|
||||
<input type="hidden" id="oppo" name="oppo" value="{{ oppo }}">
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="dotdSelect" class="form-label">Select Player:</label>
|
||||
<select class="form-select" id="dotdSelect" name="dotdSelect" required>
|
||||
<option value="">Choose a player...</option>
|
||||
{% for player in data %}
|
||||
<option value="{{ player.playernumber }}">{{ player.playerforenames }} {{ player.playersurname }}
|
||||
{% if player.playernickname %}"{{ player.playernickname }}"{% endif %}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="d-grid">
|
||||
<button type="submit" class="btn btn-warning btn-lg">
|
||||
<i class="fas fa-vote-yea me-2"></i>Submit DotD Vote
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Current Results (if available) -->
|
||||
{% if currMotM or currDotD %}
|
||||
<div class="row mt-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-secondary text-white">
|
||||
<h5 class="card-title mb-0">
|
||||
<i class="fas fa-chart-bar me-2"></i>Current Results
|
||||
</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
{% if currMotM %}
|
||||
<div class="col-md-6">
|
||||
<div class="alert alert-success">
|
||||
<h6 class="alert-heading">
|
||||
<i class="fas fa-trophy me-2"></i>Current Man of the Match
|
||||
</h6>
|
||||
<p class="mb-0">{{ currMotM }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if currDotD %}
|
||||
<div class="col-md-6">
|
||||
<div class="alert alert-warning">
|
||||
<h6 class="alert-heading">
|
||||
<i class="fas fa-award me-2"></i>Current Dick of the Day
|
||||
</h6>
|
||||
<p class="mb-0">{{ currDotD }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Instructions -->
|
||||
<div class="row mt-4">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h6><i class="fas fa-info-circle me-2"></i>Voting Instructions</h6>
|
||||
<ul class="list-unstyled">
|
||||
<li><i class="fas fa-check text-success me-2"></i>Select one player for Man of the Match</li>
|
||||
<li><i class="fas fa-check text-success me-2"></i>Select one player for Dick of the Day</li>
|
||||
<li><i class="fas fa-check text-success me-2"></i>You can vote for the same player for both categories</li>
|
||||
<li><i class="fas fa-check text-success me-2"></i>Votes are submitted independently</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_scripts %}
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// Form validation
|
||||
$('#motmForm, #dotdForm').on('submit', function(e) {
|
||||
const selectElement = $(this).find('select');
|
||||
if (!selectElement.val()) {
|
||||
e.preventDefault();
|
||||
alert('Please select a player before submitting your vote.');
|
||||
selectElement.focus();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// Add loading state to buttons
|
||||
$('#motmForm, #dotdForm').on('submit', function() {
|
||||
const button = $(this).find('button[type="submit"]');
|
||||
const originalText = button.html();
|
||||
button.html('<span class="loading-spinner"></span> Submitting...').prop('disabled', true);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
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,33 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>S3 Configuration - HKFC Men's C Team</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<style>
|
||||
.config-section {
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 0.375rem;
|
||||
padding: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.help-text {
|
||||
font-size: 0.875rem;
|
||||
color: #6c757d;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-4">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1>S3 Configuration</h1>
|
||||
<p class="lead">Configure AWS S3 storage for logos and assets</p>
|
||||
|
||||
<div class="mb-3">
|
||||
<a href="/admin" class="btn btn-secondary">Back to Admin</a>
|
||||
</div>
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}S3 Configuration - HKFC Men's C Team{% endblock %}
|
||||
|
||||
{% block extra_head %}
|
||||
<style>
|
||||
.config-section {
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 0.375rem;
|
||||
padding: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.help-text {
|
||||
font-size: 0.875rem;
|
||||
color: #6c757d;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
@ -251,5 +241,4 @@
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
{% endblock %}
|
||||
|
||||
@ -1,22 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>S3 Status - HKFC Men's C Team</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-4">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1>S3 Storage Status</h1>
|
||||
<p class="lead">Current S3 configuration and connection status</p>
|
||||
|
||||
<div class="mb-3">
|
||||
<a href="/admin/s3-config" class="btn btn-primary">Configure S3</a>
|
||||
<a href="/admin" class="btn btn-secondary">Back to Admin</a>
|
||||
</div>
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}S3 Status - HKFC Men's C Team{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<h1><i class="fas fa-cloud text-info me-2"></i>S3 Storage Status</h1>
|
||||
<p class="lead text-muted">Current S3 configuration and connection status</p>
|
||||
</div>
|
||||
<div>
|
||||
<a href="/admin/s3-config" class="btn btn-primary me-2">
|
||||
<i class="fas fa-cog me-1"></i>Configure S3
|
||||
</a>
|
||||
<a href="/admin" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left me-1"></i>Back to Admin
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
@ -149,6 +153,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
{% endblock %}
|
||||
|
||||
@ -1,19 +1,44 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>HKFC Men's C Team - MotM and DotD vote</title>
|
||||
<link rel="stylesheet" media="screen" href ="/static/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
|
||||
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||
<script src="/static/js/bootstrap.min.js"></script>
|
||||
</head>
|
||||
<h2>Thanks for submitting the MotM and DotD votes</h2>
|
||||
<body>
|
||||
Smithers' army of Internet monkeys will now go about adding up the votes ...
|
||||
<p>
|
||||
<img src="http://icarus.ipa.champion:9000/hockey-app/assets/simpsons-monkeys.jpg"></img>
|
||||
</p>
|
||||
<a class="btn btn-primary" href="/" role="button">Home</a>
|
||||
<a class="btn btn-info" href="/motm/comments" role="button">Comments</a>
|
||||
</body>
|
||||
</html>
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Vote Submitted - HKFC MOTM System{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<div class="card border-success">
|
||||
<div class="card-body text-center">
|
||||
<div class="mb-4">
|
||||
<i class="fas fa-check-circle text-success" style="font-size: 4rem;"></i>
|
||||
</div>
|
||||
|
||||
<h1 class="card-title text-success">Vote Submitted Successfully!</h1>
|
||||
|
||||
<div class="alert alert-success">
|
||||
<h5 class="alert-heading">
|
||||
<i class="fas fa-thumbs-up me-2"></i>Thank you for voting
|
||||
</h5>
|
||||
<p class="mb-0">
|
||||
Smithers' army of Internet monkeys will now go about adding up the votes...
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<img src="http://icarus.ipa.champion:9000/hockey-app/assets/simpsons-monkeys.jpg"
|
||||
alt="Counting votes"
|
||||
class="img-fluid rounded"
|
||||
style="max-height: 300px;">
|
||||
</div>
|
||||
|
||||
<div class="d-grid gap-2 d-md-flex justify-content-md-center">
|
||||
<a href="/" class="btn btn-primary">
|
||||
<i class="fas fa-home me-2"></i>Back to Home
|
||||
</a>
|
||||
<a href="/motm/comments" class="btn btn-info">
|
||||
<i class="fas fa-comments me-2"></i>View Comments
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
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