Add full SkinsPins application
- FastAPI + SQLite + Alpine.js + HTMX PWA for Bingo Bango Bongo golf scoring - Passwordless magic link auth with email (aiosmtplib) and admin invite system - Real-time score entry via WebSocket with drag-and-drop player ordering - Course management with per-hole par and stroke index - Scorecard with golf score markers (birdie, eagle, bogey, etc.) - Two-step new game form with tee selection per player - Dashboard with stats, live games social stream, and recent game history - Game summary view (read-only scorecard with leaderboard) - User profile pages with win stats - PWA install support with generated PNG icons - Admin panel for users, courses, games, and invitations Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Courses – Skins & Pins{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="page">
|
||||
<div class="page-header">
|
||||
<h1>⚙️ Admin</h1>
|
||||
</div>
|
||||
|
||||
<div class="admin-subnav">
|
||||
<a href="/admin" class="admin-subnav-item">Users</a>
|
||||
<a href="/admin/courses" class="admin-subnav-item active">Courses</a>
|
||||
<a href="/admin/games" class="admin-subnav-item">Games</a>
|
||||
</div>
|
||||
|
||||
{% if request.query_params.get('success') %}
|
||||
<div class="alert alert-success">{{ request.query_params.get('success') }}</div>
|
||||
{% endif %}
|
||||
|
||||
<div style="display:flex; justify-content:flex-end; margin-bottom:1rem;">
|
||||
<a href="/admin/courses/new" class="btn btn-primary" style="width:auto; padding:0.5rem 1rem;">+ New course</a>
|
||||
</div>
|
||||
|
||||
{% if courses %}
|
||||
<div class="card" style="padding:0;">
|
||||
<table class="data-table" style="margin:0;">
|
||||
<thead>
|
||||
<tr><th>Course</th><th>Holes</th><th>Location</th><th></th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for c in courses %}
|
||||
<tr>
|
||||
<td style="font-weight:500;">{{ c.name }}</td>
|
||||
<td style="color:var(--text-muted);">{{ c.holes }}</td>
|
||||
<td style="color:var(--text-muted);">{{ c.location or '—' }}</td>
|
||||
<td style="white-space:nowrap;">
|
||||
<a href="/admin/courses/{{ c.id }}/edit" class="btn-table-action">Edit</a>
|
||||
<form method="post" action="/admin/courses/{{ c.id }}/delete" style="display:inline;"
|
||||
onsubmit="return confirm('Delete {{ c.name }}? This cannot be undone.')">
|
||||
<button type="submit" class="btn-table-action danger">Delete</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="empty-state">
|
||||
<div class="empty-icon">⛳</div>
|
||||
<p>No courses yet.</p>
|
||||
<a href="/admin/courses/new" class="btn btn-primary" style="margin-top:1rem; max-width:200px;">Add a course</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user