Game management
This commit is contained in:
@@ -0,0 +1,275 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using TournamentOrganizer.Models;
|
||||
|
||||
namespace TournamentOrganizer.ViewModels;
|
||||
|
||||
public partial class GamesViewModel : ViewModelBase
|
||||
{
|
||||
private readonly TournamentContext _context;
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<GameDisplay> _games = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private GameDisplay? _selectedGame;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _gameName = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _gameDescription = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private RuleSetOption? _selectedS1RuleSet;
|
||||
|
||||
[ObservableProperty]
|
||||
private int? _s1Groups;
|
||||
|
||||
[ObservableProperty]
|
||||
private int? _s1GroupAdvances;
|
||||
|
||||
[ObservableProperty]
|
||||
private RuleSetOption? _selectedS2RuleSet;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _filterGameName = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isEditing;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _statusMessage = string.Empty;
|
||||
|
||||
public ObservableCollection<RuleSetOption> S1RuleSetOptions { get; } = [];
|
||||
|
||||
public ObservableCollection<RuleSetOption> S2RuleSetOptions { get; } = [new RuleSetOption(null, "(None)")];
|
||||
|
||||
public bool ShowStage1GroupSettings => SelectedS2RuleSet?.Value != null;
|
||||
|
||||
public GamesViewModel()
|
||||
{
|
||||
_context = new TournamentContext();
|
||||
foreach (var rs in Enum.GetValues<RuleSet>())
|
||||
{
|
||||
S1RuleSetOptions.Add(new RuleSetOption(rs, rs.ToDisplayName()));
|
||||
S2RuleSetOptions.Add(new RuleSetOption(rs, rs.ToDisplayName()));
|
||||
}
|
||||
SelectedS1RuleSet = S1RuleSetOptions.First();
|
||||
SelectedS2RuleSet = S2RuleSetOptions.First();
|
||||
}
|
||||
|
||||
partial void OnSelectedS2RuleSetChanged(RuleSetOption? value)
|
||||
{
|
||||
OnPropertyChanged(nameof(ShowStage1GroupSettings));
|
||||
if (value?.Value == null)
|
||||
{
|
||||
S1Groups = null;
|
||||
S1GroupAdvances = null;
|
||||
}
|
||||
}
|
||||
|
||||
partial void OnFilterGameNameChanged(string value) => ApplyFilters();
|
||||
|
||||
private async void ApplyFilters()
|
||||
{
|
||||
await LoadGames();
|
||||
}
|
||||
|
||||
public async Task LoadGames()
|
||||
{
|
||||
var allGames = await _context.Games
|
||||
.Include(g => g.Tournaments)
|
||||
.ThenInclude(t => t.Event)
|
||||
.ToListAsync();
|
||||
|
||||
var filtered = allGames.AsEnumerable();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(FilterGameName))
|
||||
{
|
||||
var filter = FilterGameName.ToLower();
|
||||
filtered = filtered.Where(g => g.Name.ToLower().Contains(filter));
|
||||
}
|
||||
|
||||
Games.Clear();
|
||||
foreach (var game in filtered)
|
||||
{
|
||||
Games.Add(new GameDisplay(game));
|
||||
}
|
||||
|
||||
SelectedGame = null;
|
||||
IsEditing = false;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task RefreshGames()
|
||||
{
|
||||
await LoadGames();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void CreateNewGame()
|
||||
{
|
||||
GameName = "New Game";
|
||||
GameDescription = string.Empty;
|
||||
SelectedS1RuleSet = S1RuleSetOptions.FirstOrDefault(o => o.Value == RuleSet.SingleElimination);
|
||||
S1Groups = null;
|
||||
S1GroupAdvances = null;
|
||||
SelectedS2RuleSet = S2RuleSetOptions.First();
|
||||
IsEditing = true;
|
||||
SelectedGame = null;
|
||||
StatusMessage = "Creating new game";
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task SaveGame()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(GameName))
|
||||
{
|
||||
StatusMessage = "Game name is required";
|
||||
return;
|
||||
}
|
||||
|
||||
Game? game;
|
||||
if (SelectedGame != null && SelectedGame.Id > 0)
|
||||
{
|
||||
game = await _context.Games.FirstOrDefaultAsync(g => g.Id == SelectedGame.Id);
|
||||
|
||||
if (game == null)
|
||||
{
|
||||
StatusMessage = "Game not found";
|
||||
return;
|
||||
}
|
||||
|
||||
game.Name = GameName;
|
||||
game.Description = GameDescription;
|
||||
game.S1RuleSet = SelectedS1RuleSet!.Value!.Value;
|
||||
game.S1Groups = ShowStage1GroupSettings ? S1Groups : null;
|
||||
game.S1GroupAdvances = ShowStage1GroupSettings ? S1GroupAdvances : null;
|
||||
game.S2RuleSet = SelectedS2RuleSet?.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
game = new Game
|
||||
{
|
||||
Name = GameName,
|
||||
Description = GameDescription,
|
||||
S1RuleSet = SelectedS1RuleSet!.Value!.Value,
|
||||
S1Groups = ShowStage1GroupSettings ? S1Groups : null,
|
||||
S1GroupAdvances = ShowStage1GroupSettings ? S1GroupAdvances : null,
|
||||
S2RuleSet = SelectedS2RuleSet?.Value,
|
||||
Tournaments = []
|
||||
};
|
||||
|
||||
_context.Games.Add(game);
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
StatusMessage = $"Game '{GameName}' saved successfully";
|
||||
await LoadGames();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task DeleteGame()
|
||||
{
|
||||
if (SelectedGame == null || SelectedGame.Id == 0)
|
||||
{
|
||||
StatusMessage = "Select a game to delete";
|
||||
return;
|
||||
}
|
||||
|
||||
var game = await _context.Games.FirstOrDefaultAsync(g => g.Id == SelectedGame.Id);
|
||||
|
||||
if (game == null)
|
||||
{
|
||||
StatusMessage = "Game not found";
|
||||
return;
|
||||
}
|
||||
|
||||
_context.Games.Remove(game);
|
||||
await _context.SaveChangesAsync();
|
||||
StatusMessage = $"Game '{game.Name}' deleted";
|
||||
await LoadGames();
|
||||
}
|
||||
|
||||
partial void OnSelectedGameChanged(GameDisplay? value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
IsEditing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
GameName = value.Name;
|
||||
GameDescription = value.Description;
|
||||
SelectedS1RuleSet = S1RuleSetOptions.FirstOrDefault(o => o.Value == value.S1RuleSet) ?? S1RuleSetOptions.First();
|
||||
S1Groups = value.S1Groups;
|
||||
S1GroupAdvances = value.S1GroupAdvances;
|
||||
SelectedS2RuleSet = S2RuleSetOptions.FirstOrDefault(o => o.Value == value.S2RuleSet) ?? S2RuleSetOptions.First();
|
||||
IsEditing = true;
|
||||
StatusMessage = $"Editing game '{value.Name}'";
|
||||
}
|
||||
}
|
||||
|
||||
public class GameDisplay
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public RuleSet S1RuleSet { get; set; }
|
||||
public string S1RuleSetName => S1RuleSet.ToDisplayName();
|
||||
public int? S1Groups { get; set; }
|
||||
public int? S1GroupAdvances { get; set; }
|
||||
public RuleSet? S2RuleSet { get; set; }
|
||||
public string? S2RuleSetName => S2RuleSet?.ToDisplayName();
|
||||
public List<string> AssociatedEvents { get; set; } = [];
|
||||
|
||||
public GameDisplay() { }
|
||||
|
||||
public GameDisplay(Game game)
|
||||
{
|
||||
Id = game.Id;
|
||||
Name = game.Name;
|
||||
Description = game.Description;
|
||||
S1RuleSet = game.S1RuleSet;
|
||||
S1Groups = game.S1Groups;
|
||||
S1GroupAdvances = game.S1GroupAdvances;
|
||||
S2RuleSet = game.S2RuleSet;
|
||||
|
||||
var events = new HashSet<string>();
|
||||
if (game.Tournaments != null)
|
||||
{
|
||||
foreach (var t in game.Tournaments)
|
||||
{
|
||||
if (t.Event != null)
|
||||
{
|
||||
events.Add(t.Event.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AssociatedEvents = events.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public class RuleSetOption
|
||||
{
|
||||
public RuleSet? Value { get; set; }
|
||||
public string Label { get; set; } = string.Empty;
|
||||
|
||||
public RuleSetOption() { }
|
||||
|
||||
public RuleSetOption(RuleSet? value, string label)
|
||||
{
|
||||
Value = value;
|
||||
Label = label;
|
||||
}
|
||||
|
||||
public override string ToString() => Label;
|
||||
}
|
||||
Reference in New Issue
Block a user