Files
Tabletop/Tabletop/Components/PlayerOrder.razor
2025-12-30 02:22:44 +01:00

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);
}
}