You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

359 lines
13 KiB

package templates
import (
"fmt"
"track-gopher/models"
)
templ Admin(groups []models.Group, racers []models.Racer) {
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Derby Race Admin</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="/static/js/htmx.min.js"></script>
<!-- Bootstrap JS Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body class="bg-light">
<div class="container py-4">
<header class="mb-4">
<h1 class="text-center">Derby Race Admin</h1>
<nav class="nav nav-pills nav-fill mt-3">
<a class="nav-link active" data-bs-toggle="tab" href="#groups">Groups</a>
<a class="nav-link" data-bs-toggle="tab" href="#racers">Racers</a>
<a class="nav-link" href="/">Race Timer</a>
<a class="nav-link" href="/register">Racer Registration</a>
<a class="nav-link" href="/heats">Race Heats</a>
</nav>
</header>
<div class="tab-content">
<div class="tab-pane fade show active" id="groups">
<div class="card mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">Groups</h5>
<button class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#addGroupModal">
Add Group
</button>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
for _, group := range groups {
<tr>
<td>{ group.Name }</td>
<td>{ group.Description }</td>
<td>
<button class="btn btn-sm btn-outline-primary me-1"
data-bs-toggle="modal"
data-bs-target="#editGroupModal"
data-id={ fmt.Sprint(group.ID) }
data-name={ group.Name }
data-description={ group.Description }>
Edit
</button>
<button class="btn btn-sm btn-outline-danger"
data-bs-toggle="modal"
data-bs-target="#deleteGroupModal"
data-id={ fmt.Sprint(group.ID) }
data-name={ group.Name }>
Delete
</button>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="racers">
<div class="card mb-4">
<div class="card-header">
<h5 class="mb-0">Racers</h5>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Car #</th>
<th>Weight</th>
<th>Group</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
for _, racer := range racers {
<tr>
<td>{ racer.FirstName } { racer.LastName }</td>
<td>{ racer.CarNumber }</td>
<td>{ fmt.Sprintf("%.1f", racer.CarWeight) } oz</td>
<td>{ racer.GroupName }</td>
<td>
<button class="btn btn-sm btn-outline-primary me-1"
data-bs-toggle="modal"
data-bs-target="#editRacerModal"
data-id={ fmt.Sprint(racer.ID) }
data-firstname={ racer.FirstName }
data-lastname={ racer.LastName }
data-carnumber={ racer.CarNumber }
data-carweight={ fmt.Sprintf("%.1f", racer.CarWeight) }
data-groupid={ fmt.Sprint(racer.GroupID) }>
Edit
</button>
<button class="btn btn-sm btn-outline-danger"
data-bs-toggle="modal"
data-bs-target="#deleteRacerModal"
data-id={ fmt.Sprint(racer.ID) }
data-name={ racer.FirstName + " " + racer.LastName }>
Delete
</button>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Add Group Modal -->
<div class="modal fade" id="addGroupModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add Group</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form hx-post="/api/groups" hx-swap="none" hx-on::after-request="location.reload()">
<div class="modal-body">
<div class="mb-3">
<label for="groupName" class="form-label">Name</label>
<input type="text" class="form-control" id="groupName" name="name" required/>
</div>
<div class="mb-3">
<label for="groupDescription" class="form-label">Description</label>
<textarea class="form-control" id="groupDescription" name="description" rows="3"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Save</button>
</div>
</form>
</div>
</div>
</div>
<!-- Edit Group Modal -->
<div class="modal fade" id="editGroupModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Edit Group</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form id="editGroupForm" hx-put="/api/groups/0" hx-swap="none" hx-on::after-request="location.reload()">
<div class="modal-body">
<div class="mb-3">
<label for="editGroupName" class="form-label">Name</label>
<input type="text" class="form-control" id="editGroupName" name="name" required/>
</div>
<div class="mb-3">
<label for="editGroupDescription" class="form-label">Description</label>
<textarea class="form-control" id="editGroupDescription" name="description" rows="3"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Save</button>
</div>
</form>
</div>
</div>
</div>
<!-- Delete Group Modal -->
<div class="modal fade" id="deleteGroupModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Delete Group</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Are you sure you want to delete the group "<span id="deleteGroupName"></span>"?</p>
<p class="text-danger">This will also delete all racers in this group!</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" id="confirmDeleteGroup" class="btn btn-danger">Delete</button>
</div>
</div>
</div>
</div>
<!-- Edit Racer Modal -->
<div class="modal fade" id="editRacerModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Edit Racer</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form id="editRacerForm" hx-put="/api/racers/0" hx-swap="none" hx-on::after-request="location.reload()">
<div class="modal-body">
<div class="row">
<div class="col-md-6 mb-3">
<label for="editFirstName" class="form-label">First Name</label>
<input type="text" class="form-control" id="editFirstName" name="first_name" required/>
</div>
<div class="col-md-6 mb-3">
<label for="editLastName" class="form-label">Last Name</label>
<input type="text" class="form-control" id="editLastName" name="last_name" required/>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="editCarNumber" class="form-label">Car Number</label>
<input type="text" class="form-control" id="editCarNumber" name="car_number" required/>
</div>
<div class="col-md-6 mb-3">
<label for="editCarWeight" class="form-label">Car Weight (oz)</label>
<input type="number" step="0.1" class="form-control" id="editCarWeight" name="car_weight" required/>
</div>
</div>
<div class="mb-3">
<label for="editGroupID" class="form-label">Group</label>
<select class="form-select" id="editGroupID" name="group_id" required>
for _, group := range groups {
<option value={ fmt.Sprint(group.ID) }>{ group.Name }</option>
}
</select>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Save</button>
</div>
</form>
</div>
</div>
</div>
<!-- Delete Racer Modal -->
<div class="modal fade" id="deleteRacerModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Delete Racer</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Are you sure you want to delete the racer "<span id="deleteRacerName"></span>"?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" id="confirmDeleteRacer" class="btn btn-danger">Delete</button>
</div>
</div>
</div>
</div>
<script>
// Handle edit group modal
document.getElementById('editGroupModal').addEventListener('show.bs.modal', function (event) {
const button = event.relatedTarget;
const id = button.getAttribute('data-id');
const name = button.getAttribute('data-name');
const description = button.getAttribute('data-description');
const form = document.getElementById('editGroupForm');
form.setAttribute('hx-put', `/api/groups/${id}`);
document.getElementById('editGroupName').value = name;
document.getElementById('editGroupDescription').value = description;
});
// Handle delete group modal
document.getElementById('deleteGroupModal').addEventListener('show.bs.modal', function (event) {
const button = event.relatedTarget;
const id = button.getAttribute('data-id');
const name = button.getAttribute('data-name');
document.getElementById('deleteGroupName').textContent = name;
document.getElementById('confirmDeleteGroup').onclick = function() {
fetch(`/api/groups/${id}`, { method: 'DELETE' })
.then(response => {
if (response.ok) {
location.reload();
} else {
alert('Failed to delete group');
}
});
};
});
// Handle edit racer modal
document.getElementById('editRacerModal').addEventListener('show.bs.modal', function (event) {
const button = event.relatedTarget;
const id = button.getAttribute('data-id');
const firstName = button.getAttribute('data-firstname');
const lastName = button.getAttribute('data-lastname');
const carNumber = button.getAttribute('data-carnumber');
const carWeight = button.getAttribute('data-carweight');
const groupId = button.getAttribute('data-groupid');
const form = document.getElementById('editRacerForm');
form.setAttribute('hx-put', `/api/racers/${id}`);
document.getElementById('editFirstName').value = firstName;
document.getElementById('editLastName').value = lastName;
document.getElementById('editCarNumber').value = carNumber;
document.getElementById('editCarWeight').value = carWeight;
document.getElementById('editGroupID').value = groupId;
});
// Handle delete racer modal
document.getElementById('deleteRacerModal').addEventListener('show.bs.modal', function (event) {
const button = event.relatedTarget;
const id = button.getAttribute('data-id');
const name = button.getAttribute('data-name');
document.getElementById('deleteRacerName').textContent = name;
document.getElementById('confirmDeleteRacer').onclick = function() {
fetch(`/api/racers/${id}`, { method: 'DELETE' })
.then(response => {
if (response.ok) {
location.reload();
} else {
alert('Failed to delete racer');
}
});
};
});
</script>
</body>
</html>
}