gcp-hockey-results/motm_app/templates/club_management.html

319 lines
14 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Club Management - HKFC Men's C Team</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-4">
<div class="row">
<div class="col-md-12">
<h1>Club Management</h1>
<p class="lead">Manage hockey clubs in the database</p>
<div class="mb-3">
<a href="/admin/clubs/add" class="btn btn-primary">Add New Club</a>
<button type="button" class="btn btn-info" id="importClubsBtn" onclick="importClubs()">
<span class="spinner-border spinner-border-sm d-none" id="importSpinner"></span>
Import from Hockey HK
</button>
<button type="button" class="btn btn-outline-info" id="previewClubsBtn" onclick="previewClubs()">
Preview Clubs
</button>
<a href="/admin" class="btn btn-secondary">Back to Admin</a>
</div>
<!-- Import Status -->
<div id="importStatus" class="alert d-none" role="alert"></div>
<!-- Preview Modal -->
<div class="modal fade" id="previewModal" tabindex="-1" aria-labelledby="previewModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="previewModalLabel">Clubs from Hockey Hong Kong</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div id="previewContent">
<div class="text-center">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<p>Loading clubs...</p>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" id="confirmImportBtn" onclick="confirmImport()">Import All</button>
</div>
</div>
</div>
</div>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ 'danger' if category == 'error' else 'success' }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endfor %}
{% endif %}
{% endwith %}
<div class="card">
<div class="card-header">
<h5>All Clubs</h5>
</div>
<div class="card-body">
{% if clubs %}
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead class="table-dark">
<tr>
<th>ID</th>
<th>Club Name</th>
<th>Logo</th>
<th>Logo URL</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for club in clubs %}
<tr>
<td>{{ club.id }}</td>
<td>{{ club.hockey_club }}</td>
<td>
{% if club.logo_url %}
<img src="{{ club.logo_url }}" alt="{{ club.hockey_club }} logo" style="max-height: 40px; max-width: 60px;" onerror="this.style.display='none'">
{% else %}
<span class="text-muted">No logo</span>
{% endif %}
</td>
<td>
{% if club.logo_url %}
<a href="{{ club.logo_url }}" target="_blank" class="text-decoration-none small">
{{ club.logo_url[:50] }}{% if club.logo_url|length > 50 %}...{% endif %}
</a>
{% else %}
<span class="text-muted">No URL</span>
{% endif %}
</td>
<td>
<a href="/admin/clubs/edit/{{ club.id }}" class="btn btn-sm btn-outline-primary">Edit</a>
<form method="POST" action="/admin/clubs/delete/{{ club.id }}" style="display: inline;" onsubmit="return confirm('Are you sure you want to delete this club?')">
<button type="submit" class="btn btn-sm btn-outline-danger">Delete</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="alert alert-info">
<h5>No clubs found</h5>
<p>There are no clubs in the database. <a href="/admin/clubs/add">Add the first club</a> to get started.</p>
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script>
let previewClubs = [];
function showStatus(message, type = 'info') {
const statusDiv = document.getElementById('importStatus');
statusDiv.className = `alert alert-${type}`;
statusDiv.textContent = message;
statusDiv.classList.remove('d-none');
// Auto-hide after 5 seconds
setTimeout(() => {
statusDiv.classList.add('d-none');
}, 5000);
}
function previewClubs() {
const modal = new bootstrap.Modal(document.getElementById('previewModal'));
const content = document.getElementById('previewContent');
// Show loading state
content.innerHTML = `
<div class="text-center">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<p>Loading clubs from Hockey Hong Kong...</p>
</div>
`;
modal.show();
// Fetch clubs
fetch('/admin/api/clubs')
.then(response => response.json())
.then(data => {
if (data.success) {
previewClubs = data.clubs;
displayPreviewClubs(data.clubs);
} else {
content.innerHTML = `
<div class="alert alert-warning">
<h6>Unable to fetch clubs</h6>
<p>${data.message}</p>
<p><small>This might be due to website structure changes or network issues.</small></p>
</div>
`;
}
})
.catch(error => {
console.error('Error:', error);
content.innerHTML = `
<div class="alert alert-danger">
<h6>Error loading clubs</h6>
<p>There was an error fetching clubs from the Hockey Hong Kong website.</p>
</div>
`;
});
}
function displayPreviewClubs(clubs) {
const content = document.getElementById('previewContent');
if (clubs.length === 0) {
content.innerHTML = `
<div class="alert alert-info">
<h6>No clubs found</h6>
<p>The website structure may have changed or no clubs are currently listed.</p>
</div>
`;
return;
}
let html = `
<div class="alert alert-info">
<h6>Found ${clubs.length} clubs</h6>
<p>These clubs will be imported with their full names and abbreviations.</p>
</div>
<div class="table-responsive">
<table class="table table-sm table-striped">
<thead>
<tr>
<th>Club Name</th>
<th>Abbreviation</th>
<th>Teams</th>
</tr>
</thead>
<tbody>
`;
clubs.forEach(club => {
const teams = club.teams ? club.teams.join(', ') : 'N/A';
html += `
<tr>
<td>${club.name}</td>
<td><span class="badge bg-secondary">${club.abbreviation || 'N/A'}</span></td>
<td>${teams}</td>
</tr>
`;
});
html += `
</tbody>
</table>
</div>
`;
content.innerHTML = html;
}
function confirmImport() {
const importBtn = document.getElementById('confirmImportBtn');
const spinner = document.getElementById('importSpinner');
// Show loading state
importBtn.disabled = true;
importBtn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> Importing...';
// Import clubs
fetch('/admin/api/import-clubs', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
showStatus(data.message, 'success');
// Close modal
const modal = bootstrap.Modal.getInstance(document.getElementById('previewModal'));
modal.hide();
// Reload page to show updated clubs
setTimeout(() => {
window.location.reload();
}, 1000);
} else {
showStatus(data.message, 'danger');
}
})
.catch(error => {
console.error('Error:', error);
showStatus('Error importing clubs', 'danger');
})
.finally(() => {
importBtn.disabled = false;
importBtn.innerHTML = 'Import All';
});
}
function importClubs() {
const importBtn = document.getElementById('importClubsBtn');
const spinner = document.getElementById('importSpinner');
// Show loading state
importBtn.disabled = true;
spinner.classList.remove('d-none');
// Import clubs directly
fetch('/admin/api/import-clubs', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
showStatus(data.message, 'success');
// Reload page to show updated clubs
setTimeout(() => {
window.location.reload();
}, 1000);
} else {
showStatus(data.message, 'danger');
}
})
.catch(error => {
console.error('Error:', error);
showStatus('Error importing clubs', 'danger');
})
.finally(() => {
importBtn.disabled = false;
spinner.classList.add('d-none');
});
}
</script>
</body>
</html>