155 lines
5.1 KiB
Plaintext
155 lines
5.1 KiB
Plaintext
@using System.Linq
|
|
|
|
@inject IStringLocalizer<App> localizer
|
|
|
|
<div class="card p-4">
|
|
@if (SelectionMode is null)
|
|
{
|
|
<h5>Wie soll die Reihenfolge vergeben werden?</h5>
|
|
<button class="btn btn-primary me-2" @onclick="UseManual">🔢 Manuell</button>
|
|
<button class="btn btn-secondary" @onclick="UseRandom">🎲 Randomized</button>
|
|
}
|
|
else if (SelectionMode == "manual")
|
|
{
|
|
<h5>Manuelle Spielerreihenfolge</h5>
|
|
|
|
<table class="table table-sm">
|
|
<thead>
|
|
<tr>
|
|
<th>Spieler</th>
|
|
<th>Reihenfolge</th>
|
|
<th>Startposition</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach (var player in Players)
|
|
{
|
|
<tr>
|
|
<td>@player.User.Username</td>
|
|
<td>
|
|
<div class="d-inline-block">
|
|
<InputSelect class="form-select" @bind-Value="player.OrderNr">
|
|
<option value="0">@localizer["SELECT_CHOOSE"]</option>
|
|
@foreach (var number in Enumerable.Range(1, Players.Count))
|
|
{
|
|
bool isUsed = Players.Any(p => p.PlayerId != player.PlayerId && p.OrderNr == number);
|
|
<option value="@number" disabled="@(isUsed && player.OrderNr != number)">
|
|
@number
|
|
</option>
|
|
}
|
|
</InputSelect>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<div class="d-inline-block">
|
|
<InputSelect class="form-select" @bind-Value="player.StartZone">
|
|
<option value="0">@localizer["SELECT_CHOOSE"]</option>
|
|
@foreach (var number in Enumerable.Range(1, Players.Count))
|
|
{
|
|
bool isUsed = Players.Any(p => p.PlayerId != player.PlayerId && p.StartZone == number);
|
|
<option value="@number" disabled="@(isUsed && player.StartZone != number)">
|
|
@number
|
|
</option>
|
|
}
|
|
</InputSelect>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
|
|
@if (!string.IsNullOrEmpty(ValidationMessage))
|
|
{
|
|
<div class="alert alert-danger">@ValidationMessage</div>
|
|
}
|
|
|
|
<button class="btn btn-success" @onclick="FinishManual">✅ Bestätigen</button>
|
|
}
|
|
else if (SelectionMode == "random")
|
|
{
|
|
<div class="alert alert-info">🎲 Die Reihenfolge wurde zufällig vergeben.</div>
|
|
}
|
|
</div>
|
|
|
|
@code {
|
|
[Parameter]
|
|
public List<Player> Players { get; set; } = new();
|
|
|
|
[Parameter]
|
|
public EventCallback<List<Player>> OnOrderChanged { get; set; }
|
|
|
|
private string? SelectionMode = null;
|
|
private string? ValidationMessage;
|
|
|
|
private void UseManual()
|
|
{
|
|
SelectionMode = "manual";
|
|
foreach (var p in Players)
|
|
{
|
|
p.OrderNr = 0; // zurücksetzen
|
|
}
|
|
}
|
|
|
|
private async void UseRandom()
|
|
{
|
|
var rnd = new Random();
|
|
|
|
// Zufällige Reihenfolge vergeben
|
|
Players = Players.OrderBy(_ => rnd.Next()).ToList();
|
|
for (int i = 0; i < Players.Count; i++)
|
|
{
|
|
Players[i].OrderNr = i + 1;
|
|
}
|
|
|
|
// Startzonen zufällig verteilen
|
|
var availableZones = Enumerable.Range(1, Players.Count).OrderBy(_ => rnd.Next()).ToList();
|
|
for (int i = 0; i < Players.Count; i++)
|
|
{
|
|
Players[i].StartZone = availableZones[i];
|
|
}
|
|
|
|
SelectionMode = "random";
|
|
await OnOrderChanged.InvokeAsync(Players);
|
|
}
|
|
|
|
private void SetOrder(Player player, string? value)
|
|
{
|
|
if (int.TryParse(value, out var number))
|
|
{
|
|
player.OrderNr = number;
|
|
}
|
|
else
|
|
{
|
|
player.OrderNr = 0;
|
|
}
|
|
}
|
|
|
|
private bool IsNumberUsed(int number)
|
|
{
|
|
return Players.Any(p => p.OrderNr == number);
|
|
}
|
|
|
|
private async void FinishManual()
|
|
{
|
|
ValidationMessage = null;
|
|
|
|
var usedOrders = Players.Select(p => p.OrderNr).Where(o => o > 0).ToList();
|
|
|
|
if (usedOrders.Count != Players.Count)
|
|
{
|
|
ValidationMessage = "⚠️ Es wurden noch nicht allen Spielern Nummern zugewiesen.";
|
|
return;
|
|
}
|
|
|
|
if (usedOrders.Distinct().Count() != Players.Count)
|
|
{
|
|
ValidationMessage = "⚠️ Jede Nummer darf nur einmal vergeben werden.";
|
|
return;
|
|
}
|
|
|
|
Players = Players.OrderBy(p => p.OrderNr).ToList();
|
|
await OnOrderChanged.InvokeAsync(Players);
|
|
}
|
|
}
|