Files
SkinsPins/app/templates/admin/edit_course.html
T
Rolf 3a1da1482c 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>
2026-03-20 10:16:46 +01:00

150 lines
7.2 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}Edit Course Skins &amp; Pins{% endblock %}
{% block content %}
<div class="page">
<div class="page-header">
<a href="/admin/courses" style="color:var(--text-muted); font-size:0.9rem;">← Courses</a>
<h1 style="margin-top:0.25rem;">{{ course.name }}</h1>
</div>
{% if request.query_params.get('success') %}
<div class="alert alert-success">{{ request.query_params.get('success') }}</div>
{% endif %}
{# ── Course info + hole pars ── #}
<form method="post" action="/admin/courses/{{ course.id }}/edit">
<div class="card">
<h2 style="font-size:0.95rem; color:var(--text-muted); margin-bottom:1rem;">Course info</h2>
<div class="form-group">
<label for="name">Course name</label>
{% if errors and errors.name %}<div class="alert alert-error">{{ errors.name }}</div>{% endif %}
<input type="text" id="name" name="name" value="{{ course.name }}" required>
</div>
<div class="form-group">
<label for="location">Location <span style="color:var(--text-muted); font-size:0.8rem;">(optional)</span></label>
<input type="text" id="location" name="location" value="{{ course.location or '' }}"
placeholder="e.g. Augusta, Georgia">
</div>
<div class="form-group">
<label>Holes</label>
<div style="display:flex; gap:0.75rem;">
<label class="radio-card">
<input type="radio" name="holes" value="9" {% if course.holes == 9 %}checked{% endif %}>
<span>9 holes</span>
</label>
<label class="radio-card">
<input type="radio" name="holes" value="18" {% if course.holes == 18 %}checked{% endif %}>
<span>18 holes</span>
</label>
</div>
</div>
</div>
<div class="card">
{% set course_par = holes | sum(attribute='par') %}
<h2 style="font-size:0.95rem; color:var(--text-muted); margin-bottom:0.75rem;">
Hole details <span style="font-weight:400;">— Course par: <strong>{{ course_par }}</strong></span>
</h2>
<div class="hole-pars-grid">
{% for h in holes %}
<div class="hole-par-cell">
<div class="hole-par-label">{{ h.hole_number }}</div>
<select name="par_{{ h.hole_number }}" class="hole-par-select">
<option value="3" {% if h.par == 3 %}selected{% endif %}>3</option>
<option value="4" {% if h.par == 4 %}selected{% endif %}>4</option>
<option value="5" {% if h.par == 5 %}selected{% endif %}>5</option>
</select>
<select name="si_{{ h.hole_number }}" class="hole-par-select">
<option value=""></option>
{% for s in range(1, course.holes + 1) %}
<option value="{{ s }}" {% if h.stroke_index == s %}selected{% endif %}>{{ s }}</option>
{% endfor %}
</select>
</div>
{% endfor %}
</div>
</div>
<button type="submit" class="btn btn-primary" style="margin-bottom:1.5rem;">Save changes</button>
</form>
{# ── Tees ── #}
<div class="card">
<h2 style="font-size:0.95rem; color:var(--text-muted); margin-bottom:1rem;">Tees</h2>
{% if tees %}
<div style="margin-bottom:1.25rem;">
{% for t in tees %}
<div x-data="{ editing: false }" style="border-bottom:1px solid var(--border); padding:0.6rem 0;">
<div x-show="!editing" style="display:flex; align-items:center; gap:0.75rem; flex-wrap:wrap;">
<span style="font-weight:500; min-width:5rem;">{{ t.name }}</span>
<span style="color:var(--text-muted); font-size:0.85rem;">Slope {{ t.slope }}</span>
<span style="color:var(--text-muted); font-size:0.85rem;">Rating {{ t.rating }}</span>
<span style="margin-left:auto; display:flex; gap:0.4rem;">
<button type="button" @click="editing = true" class="btn-table-action">Edit</button>
<form method="post" action="/admin/courses/{{ course.id }}/tees/{{ t.id }}/delete"
style="display:inline;"
onsubmit="return confirm('Delete {{ t.name }} tee?')">
<button type="submit" class="btn-table-action danger">Delete</button>
</form>
</span>
</div>
<form x-show="editing" method="post"
action="/admin/courses/{{ course.id }}/tees/{{ t.id }}/edit"
style="display:flex; gap:0.5rem; align-items:flex-end; flex-wrap:wrap; padding-top:0.4rem;">
<div class="form-group" style="margin:0; flex:1; min-width:7rem;">
<label style="font-size:0.8rem;">Name</label>
<input type="text" name="name" value="{{ t.name }}" required style="padding:0.4rem 0.6rem;">
</div>
<div class="form-group" style="margin:0; width:6rem;">
<label style="font-size:0.8rem;">Slope</label>
<input type="number" name="slope" value="{{ t.slope }}" min="55" max="155" required style="padding:0.4rem 0.6rem;">
</div>
<div class="form-group" style="margin:0; width:7rem;">
<label style="font-size:0.8rem;">Rating</label>
<input type="number" step="0.1" name="rating" value="{{ t.rating }}" min="60" max="80" required style="padding:0.4rem 0.6rem;">
</div>
<div style="display:flex; gap:0.4rem; padding-bottom:0.1rem;">
<button type="submit" class="btn btn-primary" style="padding:0.4rem 0.75rem; font-size:0.85rem;">Save</button>
<button type="button" @click="editing = false"
style="padding:0.4rem 0.75rem; font-size:0.85rem; background:none; border:1px solid var(--border); border-radius:0.4rem; color:var(--text-muted); cursor:pointer;">Cancel</button>
</div>
</form>
</div>
{% endfor %}
</div>
{% else %}
<p style="color:var(--text-muted); font-size:0.9rem; margin-bottom:1rem;">No tees yet. Add at least one tee so players can start a game on this course.</p>
{% endif %}
{# Add tee form #}
<h3 style="font-size:0.85rem; color:var(--text-muted); margin-bottom:0.75rem; text-transform:uppercase; letter-spacing:0.05em;">Add tee</h3>
<form method="post" action="/admin/courses/{{ course.id }}/tees/new"
style="display:flex; gap:0.5rem; align-items:flex-end; flex-wrap:wrap;">
<div class="form-group" style="margin:0; flex:1; min-width:7rem;">
<label style="font-size:0.8rem;">Name</label>
<input type="text" name="name" placeholder="e.g. White" required style="padding:0.4rem 0.6rem;">
</div>
<div class="form-group" style="margin:0; width:6rem;">
<label style="font-size:0.8rem;">Slope</label>
<input type="number" name="slope" placeholder="113" min="55" max="155" required style="padding:0.4rem 0.6rem;">
</div>
<div class="form-group" style="margin:0; width:7rem;">
<label style="font-size:0.8rem;">Rating</label>
<input type="number" step="0.1" name="rating" placeholder="72.0" min="60" max="80" required style="padding:0.4rem 0.6rem;">
</div>
<div style="padding-bottom:0.1rem;">
<button type="submit" class="btn btn-primary" style="padding:0.4rem 0.75rem; font-size:0.85rem;">Add tee</button>
</div>
</form>
</div>
</div>
{% endblock %}