many bug fixes
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
using SportsDivision.Application.DTOs;
|
using SportsDivision.Application.DTOs;
|
||||||
namespace SportsDivision.Application.Interfaces;
|
namespace SportsDivision.Application.Interfaces;
|
||||||
public interface IHighJumpService { Task<IEnumerable<HighJumpHeightDto>> GetHeightsAsync(int tournamentEventLevelId); Task<HighJumpHeightDto> AddHeightAsync(HighJumpHeightCreateDto dto); Task RemoveHeightAsync(int heightId); Task RecordAttemptAsync(HighJumpAttemptUpdateDto dto); Task<bool> IsEliminatedAsync(int tournamentEventLevelId, int eventRegistrationId); Task CalculateResultsAsync(int tournamentEventLevelId, string recordedBy); }
|
public interface IHighJumpService { Task<IEnumerable<HighJumpHeightDto>> GetHeightsAsync(int tournamentEventLevelId); Task<HighJumpHeightDto> AddHeightAsync(HighJumpHeightCreateDto dto); Task RemoveHeightAsync(int heightId); Task RecordAttemptAsync(HighJumpAttemptUpdateDto dto); Task<bool> IsEliminatedAsync(int tournamentEventLevelId, int eventRegistrationId); Task<string?> CalculateResultsAsync(int tournamentEventLevelId, string recordedBy); }
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ public class HighJumpService : IHighJumpService
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CalculateResultsAsync(int tournamentEventLevelId, string recordedBy)
|
public async Task<string?> CalculateResultsAsync(int tournamentEventLevelId, string recordedBy)
|
||||||
{
|
{
|
||||||
var heights = (await _uow.HighJumpHeights.GetByTournamentEventLevelAsync(tournamentEventLevelId))
|
var heights = (await _uow.HighJumpHeights.GetByTournamentEventLevelAsync(tournamentEventLevelId))
|
||||||
.OrderBy(h => h.SortOrder).ToList();
|
.OrderBy(h => h.SortOrder).ToList();
|
||||||
@@ -139,34 +139,74 @@ public class HighJumpService : IHighJumpService
|
|||||||
results.Add((reg.EventRegistrationId, highestCleared, totalFails, failsAtHighest));
|
results.Add((reg.EventRegistrationId, highestCleared, totalFails, failsAtHighest));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort: highest cleared DESC, then fewest fails at that height, then fewest total fails
|
// Rank by World Athletics high-jump countback:
|
||||||
|
// 1. highest bar cleared (desc)
|
||||||
|
// 2. fewest misses at that bar
|
||||||
|
// 3. fewest total misses in the competition
|
||||||
var sorted = results
|
var sorted = results
|
||||||
.OrderByDescending(r => r.HighestCleared)
|
.OrderByDescending(r => r.HighestCleared)
|
||||||
.ThenBy(r => r.FailsAtHighest)
|
.ThenBy(r => r.FailsAtHighest)
|
||||||
.ThenBy(r => r.TotalFails)
|
.ThenBy(r => r.TotalFails)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// Record scores: cleared height, placement, placement points, and World-Athletics points.
|
|
||||||
var placementPoints = (await _uow.PlacementPointConfigs.GetAllAsync())
|
var placementPoints = (await _uow.PlacementPointConfigs.GetAllAsync())
|
||||||
.ToDictionary(p => p.Placement, p => p.Points);
|
.ToDictionary(p => p.Placement, p => p.Points);
|
||||||
var constant = await _uow.ScoringConstants.GetByEventAsync(tel.EventId);
|
var constant = await _uow.ScoringConstants.GetByEventAsync(tel.EventId);
|
||||||
|
|
||||||
for (int i = 0; i < sorted.Count; i++)
|
// Assign placements with proper tie handling. Athletes identical on all three
|
||||||
|
// countback keys are a genuine tie: they share one placement (standard competition
|
||||||
|
// ranking, e.g. 1, 2, 3, 3, 5) and share placement points — the points for the
|
||||||
|
// positions the tie-group occupies are pooled and divided equally.
|
||||||
|
static bool SameRank(
|
||||||
|
(int RegId, decimal HighestCleared, int TotalFails, int FailsAtHighest) a,
|
||||||
|
(int RegId, decimal HighestCleared, int TotalFails, int FailsAtHighest) b)
|
||||||
|
=> a.HighestCleared == b.HighestCleared
|
||||||
|
&& a.FailsAtHighest == b.FailsAtHighest
|
||||||
|
&& a.TotalFails == b.TotalFails;
|
||||||
|
|
||||||
|
var placeByIndex = new int[sorted.Count];
|
||||||
|
var pointsByIndex = new int[sorted.Count];
|
||||||
|
var firstPlaceTie = new List<int>(); // RegIds sharing 1st place
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (i < sorted.Count)
|
||||||
{
|
{
|
||||||
int place = i + 1;
|
int start = i;
|
||||||
decimal cleared = sorted[i].HighestCleared;
|
int place = start + 1;
|
||||||
|
while (i + 1 < sorted.Count && SameRank(sorted[i + 1], sorted[start])) i++;
|
||||||
|
int size = i - start + 1;
|
||||||
|
|
||||||
|
// Pool the points for the positions this tie-group occupies, then split equally.
|
||||||
|
int pooled = 0;
|
||||||
|
for (int p = place; p < place + size; p++)
|
||||||
|
pooled += placementPoints.TryGetValue(p, out var pp) ? pp : 0;
|
||||||
|
int shared = (int)Math.Round((double)pooled / size, MidpointRounding.AwayFromZero);
|
||||||
|
|
||||||
|
for (int k = start; k <= i; k++)
|
||||||
|
{
|
||||||
|
placeByIndex[k] = place;
|
||||||
|
pointsByIndex[k] = shared;
|
||||||
|
}
|
||||||
|
if (place == 1 && size > 1)
|
||||||
|
firstPlaceTie.AddRange(sorted.GetRange(start, size).Select(r => r.RegId));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < sorted.Count; j++)
|
||||||
|
{
|
||||||
|
decimal cleared = sorted[j].HighestCleared;
|
||||||
int calc = (constant != null && cleared > constant.B)
|
int calc = (constant != null && cleared > constant.B)
|
||||||
? (int)Math.Floor((double)constant.A * Math.Pow((double)(cleared - constant.B), (double)constant.C))
|
? (int)Math.Floor((double)constant.A * Math.Pow((double)(cleared - constant.B), (double)constant.C))
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
var score = await _uow.Scores.GetByRegistrationAsync(sorted[i].RegId);
|
var score = await _uow.Scores.GetByRegistrationAsync(sorted[j].RegId);
|
||||||
var isNew = score == null;
|
var isNew = score == null;
|
||||||
score ??= new Score { EventRegistrationId = sorted[i].RegId };
|
score ??= new Score { EventRegistrationId = sorted[j].RegId };
|
||||||
|
|
||||||
score.RawPerformance = cleared;
|
score.RawPerformance = cleared;
|
||||||
score.CalculatedPoints = calc;
|
score.CalculatedPoints = calc;
|
||||||
score.Placement = place;
|
score.Placement = placeByIndex[j];
|
||||||
score.PlacementPoints = placementPoints.TryGetValue(place, out var pts) ? pts : 0;
|
score.PlacementPoints = pointsByIndex[j];
|
||||||
score.RecordedBy = recordedBy;
|
score.RecordedBy = recordedBy;
|
||||||
score.RecordedAt = DateTime.UtcNow;
|
score.RecordedAt = DateTime.UtcNow;
|
||||||
|
|
||||||
@@ -174,5 +214,19 @@ public class HighJumpService : IHighJumpService
|
|||||||
else _uow.Scores.Update(score);
|
else _uow.Scores.Update(score);
|
||||||
}
|
}
|
||||||
await _uow.SaveChangesAsync();
|
await _uow.SaveChangesAsync();
|
||||||
|
|
||||||
|
// A tie for 1st cannot be settled by countback — World Athletics requires a jump-off.
|
||||||
|
// Flag it so an official can arrange one; the tied athletes currently share 1st place.
|
||||||
|
if (firstPlaceTie.Count > 1)
|
||||||
|
{
|
||||||
|
var names = tel.Registrations
|
||||||
|
.Where(r => firstPlaceTie.Contains(r.EventRegistrationId))
|
||||||
|
.Select(r => r.Student?.FullName ?? "Unknown")
|
||||||
|
.OrderBy(n => n);
|
||||||
|
return $"Tie for 1st place between {string.Join(" and ", names)}. "
|
||||||
|
+ "Countback cannot separate them — a jump-off is required to decide the winner. "
|
||||||
|
+ "They currently share 1st place.";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ public class TournamentService : ITournamentService
|
|||||||
{
|
{
|
||||||
var tournament = await _uow.Tournaments.GetByIdAsync(id)
|
var tournament = await _uow.Tournaments.GetByIdAsync(id)
|
||||||
?? throw new KeyNotFoundException("Tournament not found.");
|
?? throw new KeyNotFoundException("Tournament not found.");
|
||||||
|
if (tournament.Status != TournamentStatus.Completed)
|
||||||
|
throw new InvalidOperationException("Only tournaments marked as Completed can be archived.");
|
||||||
tournament.IsArchived = true;
|
tournament.IsArchived = true;
|
||||||
_uow.Tournaments.Update(tournament);
|
_uow.Tournaments.Update(tournament);
|
||||||
await _uow.SaveChangesAsync();
|
await _uow.SaveChangesAsync();
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using SportsDivision.Application.DTOs;
|
using SportsDivision.Application.DTOs;
|
||||||
using SportsDivision.Application.Interfaces;
|
using SportsDivision.Application.Interfaces;
|
||||||
using SportsDivision.Domain.Enums;
|
using SportsDivision.Domain.Enums;
|
||||||
using SportsDivision.Web.Helpers;
|
|
||||||
|
|
||||||
namespace SportsDivision.Web.Controllers;
|
namespace SportsDivision.Web.Controllers;
|
||||||
|
|
||||||
@@ -17,7 +16,7 @@ public class EventController : Controller
|
|||||||
_eventService = eventService;
|
_eventService = eventService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IActionResult> Index(EventCategory? category, int page = 1, int pageSize = PaginationHelper.PageSize)
|
public async Task<IActionResult> Index(EventCategory? category)
|
||||||
{
|
{
|
||||||
IEnumerable<EventDto> events;
|
IEnumerable<EventDto> events;
|
||||||
|
|
||||||
@@ -32,7 +31,7 @@ public class EventController : Controller
|
|||||||
|
|
||||||
ViewBag.SelectedCategory = category;
|
ViewBag.SelectedCategory = category;
|
||||||
|
|
||||||
return View(this.Page(events, page, pageSize));
|
return View(events);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
|
|||||||
@@ -77,7 +77,11 @@ public class HighJumpController : Controller
|
|||||||
public async Task<IActionResult> CalculateResults(int tournamentEventLevelId)
|
public async Task<IActionResult> CalculateResults(int tournamentEventLevelId)
|
||||||
{
|
{
|
||||||
var recordedBy = User.Identity?.Name ?? "Unknown";
|
var recordedBy = User.Identity?.Name ?? "Unknown";
|
||||||
await _highJumpService.CalculateResultsAsync(tournamentEventLevelId, recordedBy);
|
var warning = await _highJumpService.CalculateResultsAsync(tournamentEventLevelId, recordedBy);
|
||||||
|
if (warning != null)
|
||||||
|
TempData["WarningMessage"] = warning;
|
||||||
|
else
|
||||||
|
TempData["SuccessMessage"] = "High jump results calculated.";
|
||||||
return RedirectToAction(nameof(Index), new { tournamentEventLevelId });
|
return RedirectToAction(nameof(Index), new { tournamentEventLevelId });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,10 @@ public class TournamentController : Controller
|
|||||||
|
|
||||||
public async Task<IActionResult> Index(TournamentStatus? status, bool showArchived = false, int page = 1, int pageSize = PaginationHelper.PageSize)
|
public async Task<IActionResult> Index(TournamentStatus? status, bool showArchived = false, int page = 1, int pageSize = PaginationHelper.PageSize)
|
||||||
{
|
{
|
||||||
var tournaments = await _tournamentService.GetAllAsync(includeArchived: showArchived);
|
var all = await _tournamentService.GetAllAsync(includeArchived: true);
|
||||||
|
var archivedCount = all.Count(t => t.IsArchived);
|
||||||
|
|
||||||
|
var tournaments = showArchived ? all : all.Where(t => !t.IsArchived);
|
||||||
|
|
||||||
if (status.HasValue)
|
if (status.HasValue)
|
||||||
{
|
{
|
||||||
@@ -30,6 +33,7 @@ public class TournamentController : Controller
|
|||||||
|
|
||||||
ViewBag.SelectedStatus = status;
|
ViewBag.SelectedStatus = status;
|
||||||
ViewBag.ShowArchived = showArchived;
|
ViewBag.ShowArchived = showArchived;
|
||||||
|
ViewBag.ArchivedCount = archivedCount;
|
||||||
|
|
||||||
return View(this.Page(tournaments, page, pageSize));
|
return View(this.Page(tournaments, page, pageSize));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,5 +35,3 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<partial name="_Pagination" />
|
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
var eventName = ViewBag.EventName as string;
|
var eventName = ViewBag.EventName as string;
|
||||||
var levelName = ViewBag.LevelName as string;
|
var levelName = ViewBag.LevelName as string;
|
||||||
var registrations = ViewBag.Registrations as IEnumerable<EventRegistrationDto>;
|
var registrations = ViewBag.Registrations as IEnumerable<EventRegistrationDto>;
|
||||||
|
var results = registrations?.Where(r => r.Score != null && r.Score.Placement != null)
|
||||||
|
.OrderBy(r => r.Score!.Placement)
|
||||||
|
.ToList() ?? new List<EventRegistrationDto>();
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||||
@@ -95,3 +98,44 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="card shadow-sm mt-4">
|
||||||
|
<div class="card-header d-flex justify-content-between align-items-center" style="background-color:#003366; color:white;">
|
||||||
|
<h5 class="mb-0">Results</h5>
|
||||||
|
<span class="small">Best cleared height ranks athletes; points use the World Athletics formula.</span>
|
||||||
|
</div>
|
||||||
|
<div class="card-body p-0">
|
||||||
|
@if (results.Any())
|
||||||
|
{
|
||||||
|
<table class="table table-hover mb-0">
|
||||||
|
<thead class="table-dark">
|
||||||
|
<tr>
|
||||||
|
<th>Place</th>
|
||||||
|
<th>Student</th>
|
||||||
|
<th>School</th>
|
||||||
|
<th>Best Height</th>
|
||||||
|
<th>Points</th>
|
||||||
|
<th>Placement Pts</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach (var r in results)
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<td><span class="badge bg-warning text-dark">#@r.Score!.Placement</span></td>
|
||||||
|
<td>@r.StudentName</td>
|
||||||
|
<td>@r.SchoolName</td>
|
||||||
|
<td>@r.Score.RawPerformance.ToString("0.00")m</td>
|
||||||
|
<td>@r.Score.CalculatedPoints</td>
|
||||||
|
<td>@r.Score.PlacementPoints</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<p class="text-muted p-3 mb-0">No results yet. Record clearances above, then click <strong>Calculate Results</strong> to rank athletes and award points.</p>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -14,10 +14,19 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@if (TempData["WarningMessage"] != null)
|
||||||
|
{
|
||||||
|
<div class="alert alert-warning alert-dismissible fade show" role="alert" data-no-autodismiss="true">
|
||||||
|
@TempData["WarningMessage"]
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
var alerts = document.querySelectorAll('.alert');
|
// Auto-dismiss transient alerts, but keep ones that need the user's attention.
|
||||||
|
var alerts = document.querySelectorAll('.alert:not([data-no-autodismiss])');
|
||||||
alerts.forEach(function (alert) {
|
alerts.forEach(function (alert) {
|
||||||
var bsAlert = new bootstrap.Alert(alert);
|
var bsAlert = new bootstrap.Alert(alert);
|
||||||
bsAlert.close();
|
bsAlert.close();
|
||||||
|
|||||||
@@ -72,7 +72,14 @@
|
|||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
<a asp-action="Edit" asp-route-id="@Model.TournamentId" class="btn btn-outline-primary">Edit</a>
|
<a asp-action="Edit" asp-route-id="@Model.TournamentId" class="btn btn-outline-primary">Edit</a>
|
||||||
@if (!Model.IsArchived)
|
@if (Model.IsArchived)
|
||||||
|
{
|
||||||
|
<form asp-action="Unarchive" method="post">
|
||||||
|
<input type="hidden" name="id" value="@Model.TournamentId" />
|
||||||
|
<button type="submit" class="btn btn-outline-dark">Unarchive</button>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
else if (Model.Status == TournamentStatus.Completed)
|
||||||
{
|
{
|
||||||
<form asp-action="Archive" method="post">
|
<form asp-action="Archive" method="post">
|
||||||
<input type="hidden" name="id" value="@Model.TournamentId" />
|
<input type="hidden" name="id" value="@Model.TournamentId" />
|
||||||
@@ -80,13 +87,6 @@
|
|||||||
onclick="return confirm('Archive this tournament? It will be hidden from the default list but not deleted, and can be restored later.')">Archive</button>
|
onclick="return confirm('Archive this tournament? It will be hidden from the default list but not deleted, and can be restored later.')">Archive</button>
|
||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
<form asp-action="Unarchive" method="post">
|
|
||||||
<input type="hidden" name="id" value="@Model.TournamentId" />
|
|
||||||
<button type="submit" class="btn btn-outline-dark">Unarchive</button>
|
|
||||||
</form>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
ViewData["Title"] = "Tournaments";
|
ViewData["Title"] = "Tournaments";
|
||||||
var selectedStatus = ViewBag.SelectedStatus as TournamentStatus?;
|
var selectedStatus = ViewBag.SelectedStatus as TournamentStatus?;
|
||||||
var showArchived = ViewBag.ShowArchived as bool? ?? false;
|
var showArchived = ViewBag.ShowArchived as bool? ?? false;
|
||||||
|
var archivedCount = ViewBag.ArchivedCount as int? ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||||
@@ -24,14 +25,30 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<div class="form-check">
|
<label class="form-label mb-0 small text-muted d-block">Archived</label>
|
||||||
<input class="form-check-input" type="checkbox" name="showArchived" value="true"
|
<div class="form-check form-switch d-inline-flex align-items-center gap-2 border rounded px-2 py-1 @(showArchived ? "border-primary bg-light" : (archivedCount > 0 ? "border-warning" : ""))" style="min-height:31px">
|
||||||
|
<input class="form-check-input m-0" type="checkbox" role="switch" name="showArchived" value="true"
|
||||||
id="showArchived" @(showArchived ? "checked" : "") onchange="this.form.submit()" />
|
id="showArchived" @(showArchived ? "checked" : "") onchange="this.form.submit()" />
|
||||||
<label class="form-check-label" for="showArchived">Show archived</label>
|
<label class="form-check-label fw-semibold" for="showArchived" style="cursor:pointer">
|
||||||
|
Show archived
|
||||||
|
@if (archivedCount > 0)
|
||||||
|
{
|
||||||
|
<span class="badge rounded-pill bg-warning text-dark" title="@archivedCount archived tournament(s) hidden">@archivedCount</span>
|
||||||
|
}
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
@if (!showArchived && archivedCount > 0)
|
||||||
|
{
|
||||||
|
<p class="text-muted small mb-3">
|
||||||
|
<i class="bi bi-archive"></i>
|
||||||
|
@archivedCount archived tournament@(archivedCount == 1 ? "" : "s") @(archivedCount == 1 ? "is" : "are") hidden.
|
||||||
|
Flip <strong>Show archived</strong> above to view @(archivedCount == 1 ? "it" : "them").
|
||||||
|
</p>
|
||||||
|
}
|
||||||
|
|
||||||
<table class="table table-striped table-hover">
|
<table class="table table-striped table-hover">
|
||||||
<thead class="table-dark">
|
<thead class="table-dark">
|
||||||
<tr>
|
<tr>
|
||||||
@@ -67,7 +84,14 @@
|
|||||||
<td>
|
<td>
|
||||||
<a asp-action="Edit" asp-route-id="@t.TournamentId" class="btn btn-sm btn-outline-primary">Edit</a>
|
<a asp-action="Edit" asp-route-id="@t.TournamentId" class="btn btn-sm btn-outline-primary">Edit</a>
|
||||||
<a asp-action="Details" asp-route-id="@t.TournamentId" class="btn btn-sm btn-outline-info">Details</a>
|
<a asp-action="Details" asp-route-id="@t.TournamentId" class="btn btn-sm btn-outline-info">Details</a>
|
||||||
@if (!t.IsArchived)
|
@if (t.IsArchived)
|
||||||
|
{
|
||||||
|
<form asp-action="Unarchive" method="post" class="d-inline">
|
||||||
|
<input type="hidden" name="id" value="@t.TournamentId" />
|
||||||
|
<button type="submit" class="btn btn-sm btn-outline-dark">Unarchive</button>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
else if (t.Status == TournamentStatus.Completed)
|
||||||
{
|
{
|
||||||
<form asp-action="Archive" method="post" class="d-inline">
|
<form asp-action="Archive" method="post" class="d-inline">
|
||||||
<input type="hidden" name="id" value="@t.TournamentId" />
|
<input type="hidden" name="id" value="@t.TournamentId" />
|
||||||
@@ -75,13 +99,6 @@
|
|||||||
onclick="return confirm('Archive "@t.Name"? It will be hidden from the default list but can be restored.')">Archive</button>
|
onclick="return confirm('Archive "@t.Name"? It will be hidden from the default list but can be restored.')">Archive</button>
|
||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
<form asp-action="Unarchive" method="post" class="d-inline">
|
|
||||||
<input type="hidden" name="id" value="@t.TournamentId" />
|
|
||||||
<button type="submit" class="btn btn-sm btn-outline-dark">Unarchive</button>
|
|
||||||
</form>
|
|
||||||
}
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ INSERT INTO _ev (ename, base, step, is_track) VALUES
|
|||||||
('3000m', 560.00, 6.00, true),
|
('3000m', 560.00, 6.00, true),
|
||||||
('5000m', 980.00, 10.0, true),
|
('5000m', 980.00, 10.0, true),
|
||||||
('80mH', 13.00, 0.25, true),
|
('80mH', 13.00, 0.25, true),
|
||||||
('QC 60m Sprint', 7.50, 0.12, true),
|
|
||||||
-- Field (metres)
|
-- Field (metres)
|
||||||
('Long Jump', 6.40, 0.15, false),
|
('Long Jump', 6.40, 0.15, false),
|
||||||
('Triple Jump', 13.00, 0.30, false),
|
('Triple Jump', 13.00, 0.30, false),
|
||||||
@@ -70,10 +69,8 @@ INSERT INTO _ev (ename, base, step, is_track) VALUES
|
|||||||
('Javelin 700g', 40.00, 1.40, false),
|
('Javelin 700g', 40.00, 1.40, false),
|
||||||
('Javelin 800g', 38.00, 1.30, false),
|
('Javelin 800g', 38.00, 1.30, false),
|
||||||
('Throwing the Cricket Ball', 65.00, 2.00, false),
|
('Throwing the Cricket Ball', 65.00, 2.00, false),
|
||||||
('QC Javelin Throw', 40.00, 1.40, false),
|
|
||||||
-- High jump (metres)
|
-- High jump (metres)
|
||||||
('High Jump', 1.85, 0.04, false),
|
('High Jump', 1.85, 0.04, false);
|
||||||
('QC High Jump Open', 1.80, 0.04, false);
|
|
||||||
|
|
||||||
-- ---------------------------------------------------------------------------
|
-- ---------------------------------------------------------------------------
|
||||||
-- 1. STUDENTS (60: TD-0001 .. TD-0060; first 30 Male, next 30 Female)
|
-- 1. STUDENTS (60: TD-0001 .. TD-0060; first 30 Male, next 30 Female)
|
||||||
|
|||||||
Reference in New Issue
Block a user