Compare commits
No commits in common. "5441bbed3f080d28c1002bcf4c3af3052019d02f" and "660d1433334fb38e429061862a7c535cbf6e0058" have entirely different histories.
5441bbed3f
...
660d143333
|
|
@ -5,8 +5,7 @@
|
||||||
"Bash(dotnet build:*)",
|
"Bash(dotnet build:*)",
|
||||||
"Bash(dotnet test:*)",
|
"Bash(dotnet test:*)",
|
||||||
"Bash(git checkout:*)",
|
"Bash(git checkout:*)",
|
||||||
"Bash(git add:*)",
|
"Bash(git add:*)"
|
||||||
"Bash(git commit:*)"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -337,7 +337,7 @@ NavMenu.razor:
|
||||||
| ✓ | B5 | User/Account | Admin Users Page | 1 Razor |
|
| ✓ | B5 | User/Account | Admin Users Page | 1 Razor |
|
||||||
| ✓ | C1 | Clubs | ClubState Fluxor | 4 State-Dateien |
|
| ✓ | C1 | Clubs | ClubState Fluxor | 4 State-Dateien |
|
||||||
| ✓ | C2 | Clubs | Club Pages - ERSTES TESTBARES MVP | 1 Razor |
|
| ✓ | C2 | Clubs | Club Pages - ERSTES TESTBARES MVP | 1 Razor |
|
||||||
| ✓ | D1 | Personen | PersonState Fluxor | 4 State-Dateien |
|
| ☐ | D1 | Personen | PersonState Fluxor | 4 State-Dateien |
|
||||||
| ☐ | D2 | Personen | Person Pages | 1 Razor |
|
| ☐ | D2 | Personen | Person Pages | 1 Razor |
|
||||||
| ☐ | D3 | Expenses | ExpenseState Fluxor | 4 State-Dateien |
|
| ☐ | D3 | Expenses | ExpenseState Fluxor | 4 State-Dateien |
|
||||||
| ☐ | D4 | Expenses | Expense Pages | 1 Razor |
|
| ☐ | D4 | Expenses | Expense Pages | 1 Razor |
|
||||||
|
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
using Koogle.Application.DTOs;
|
|
||||||
|
|
||||||
namespace Koogle.Web.Store.PersonState;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Action to load all persons for the current club.
|
|
||||||
/// </summary>
|
|
||||||
public record LoadPersonsAction;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Action dispatched when persons are loaded successfully.
|
|
||||||
/// </summary>
|
|
||||||
public record LoadPersonsSuccessAction(IReadOnlyList<PersonDto> Persons);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Action dispatched when loading persons fails.
|
|
||||||
/// </summary>
|
|
||||||
public record LoadPersonsFailureAction(string Error);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Action to create a new person.
|
|
||||||
/// </summary>
|
|
||||||
public record CreatePersonAction(CreatePersonDto Dto);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Action dispatched when person is created successfully.
|
|
||||||
/// </summary>
|
|
||||||
public record CreatePersonSuccessAction(PersonDto Person);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Action dispatched when creating person fails.
|
|
||||||
/// </summary>
|
|
||||||
public record CreatePersonFailureAction(string Error);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Action to update an existing person.
|
|
||||||
/// </summary>
|
|
||||||
public record UpdatePersonAction(UpdatePersonDto Dto);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Action dispatched when person is updated successfully.
|
|
||||||
/// </summary>
|
|
||||||
public record UpdatePersonSuccessAction(PersonDto Person);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Action dispatched when updating person fails.
|
|
||||||
/// </summary>
|
|
||||||
public record UpdatePersonFailureAction(string Error);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Action to delete a person.
|
|
||||||
/// </summary>
|
|
||||||
public record DeletePersonAction(Guid Id);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Action dispatched when person is deleted successfully.
|
|
||||||
/// </summary>
|
|
||||||
public record DeletePersonSuccessAction(Guid Id);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Action dispatched when deleting person fails.
|
|
||||||
/// </summary>
|
|
||||||
public record DeletePersonFailureAction(string Error);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Action to select a person for editing.
|
|
||||||
/// </summary>
|
|
||||||
public record SelectPersonAction(PersonDto? Person);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Action to clear person error state.
|
|
||||||
/// </summary>
|
|
||||||
public record ClearPersonErrorAction;
|
|
||||||
|
|
@ -1,112 +0,0 @@
|
||||||
using Fluxor;
|
|
||||||
using Koogle.Application.Interfaces;
|
|
||||||
|
|
||||||
namespace Koogle.Web.Store.PersonState;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Side effects for person state management.
|
|
||||||
/// Handles async operations like API calls.
|
|
||||||
/// </summary>
|
|
||||||
public class PersonEffects
|
|
||||||
{
|
|
||||||
private readonly IPersonService _personService;
|
|
||||||
private readonly ILogger<PersonEffects> _logger;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the PersonEffects class.
|
|
||||||
/// </summary>
|
|
||||||
public PersonEffects(IPersonService personService, ILogger<PersonEffects> logger)
|
|
||||||
{
|
|
||||||
_personService = personService;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles LoadPersonsAction - loads all persons from service.
|
|
||||||
/// </summary>
|
|
||||||
[EffectMethod]
|
|
||||||
public async Task HandleLoadPersons(LoadPersonsAction action, IDispatcher dispatcher)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_logger.LogDebug("Loading persons");
|
|
||||||
var persons = await _personService.GetAllAsync();
|
|
||||||
dispatcher.Dispatch(new LoadPersonsSuccessAction(persons));
|
|
||||||
_logger.LogInformation("Loaded {Count} persons", persons.Count);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Failed to load persons");
|
|
||||||
dispatcher.Dispatch(new LoadPersonsFailureAction(ex.Message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles CreatePersonAction - creates a new person.
|
|
||||||
/// </summary>
|
|
||||||
[EffectMethod]
|
|
||||||
public async Task HandleCreatePerson(CreatePersonAction action, IDispatcher dispatcher)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_logger.LogDebug("Creating person {Name}", action.Dto.Name);
|
|
||||||
var person = await _personService.CreateAsync(action.Dto);
|
|
||||||
dispatcher.Dispatch(new CreatePersonSuccessAction(person));
|
|
||||||
_logger.LogInformation("Created person {Name} with ID {Id}", person.Name, person.Id);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Failed to create person {Name}", action.Dto.Name);
|
|
||||||
dispatcher.Dispatch(new CreatePersonFailureAction(ex.Message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles UpdatePersonAction - updates an existing person.
|
|
||||||
/// </summary>
|
|
||||||
[EffectMethod]
|
|
||||||
public async Task HandleUpdatePerson(UpdatePersonAction action, IDispatcher dispatcher)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_logger.LogDebug("Updating person {Id}", action.Dto.Id);
|
|
||||||
var person = await _personService.UpdateAsync(action.Dto);
|
|
||||||
dispatcher.Dispatch(new UpdatePersonSuccessAction(person));
|
|
||||||
_logger.LogInformation("Updated person {Name}", person.Name);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Failed to update person {Id}", action.Dto.Id);
|
|
||||||
dispatcher.Dispatch(new UpdatePersonFailureAction(ex.Message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles DeletePersonAction - deletes a person.
|
|
||||||
/// </summary>
|
|
||||||
[EffectMethod]
|
|
||||||
public async Task HandleDeletePerson(DeletePersonAction action, IDispatcher dispatcher)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_logger.LogDebug("Deleting person {Id}", action.Id);
|
|
||||||
var success = await _personService.DeleteAsync(action.Id);
|
|
||||||
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
dispatcher.Dispatch(new DeletePersonSuccessAction(action.Id));
|
|
||||||
_logger.LogInformation("Deleted person {Id}", action.Id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dispatcher.Dispatch(new DeletePersonFailureAction("Person konnte nicht gelöscht werden."));
|
|
||||||
_logger.LogWarning("Failed to delete person {Id} - not found or already deleted", action.Id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Failed to delete person {Id}", action.Id);
|
|
||||||
dispatcher.Dispatch(new DeletePersonFailureAction(ex.Message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,163 +0,0 @@
|
||||||
using Fluxor;
|
|
||||||
|
|
||||||
namespace Koogle.Web.Store.PersonState;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Reducers for person state management.
|
|
||||||
/// </summary>
|
|
||||||
public static class PersonReducers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Handles LoadPersonsAction - sets loading state.
|
|
||||||
/// </summary>
|
|
||||||
[ReducerMethod(typeof(LoadPersonsAction))]
|
|
||||||
public static PersonState OnLoadPersons(PersonState state)
|
|
||||||
=> state with
|
|
||||||
{
|
|
||||||
IsLoading = true,
|
|
||||||
Error = null
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles LoadPersonsSuccessAction - updates persons list.
|
|
||||||
/// </summary>
|
|
||||||
[ReducerMethod]
|
|
||||||
public static PersonState OnLoadPersonsSuccess(PersonState state, LoadPersonsSuccessAction action)
|
|
||||||
=> state with
|
|
||||||
{
|
|
||||||
Persons = action.Persons,
|
|
||||||
IsLoading = false
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles LoadPersonsFailureAction - sets error state.
|
|
||||||
/// </summary>
|
|
||||||
[ReducerMethod]
|
|
||||||
public static PersonState OnLoadPersonsFailure(PersonState state, LoadPersonsFailureAction action)
|
|
||||||
=> state with
|
|
||||||
{
|
|
||||||
IsLoading = false,
|
|
||||||
Error = action.Error
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles CreatePersonAction - sets loading state.
|
|
||||||
/// </summary>
|
|
||||||
[ReducerMethod(typeof(CreatePersonAction))]
|
|
||||||
public static PersonState OnCreatePerson(PersonState state)
|
|
||||||
=> state with
|
|
||||||
{
|
|
||||||
IsLoading = true,
|
|
||||||
Error = null
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles CreatePersonSuccessAction - adds person to list.
|
|
||||||
/// </summary>
|
|
||||||
[ReducerMethod]
|
|
||||||
public static PersonState OnCreatePersonSuccess(PersonState state, CreatePersonSuccessAction action)
|
|
||||||
=> state with
|
|
||||||
{
|
|
||||||
Persons = [.. state.Persons, action.Person],
|
|
||||||
IsLoading = false
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles CreatePersonFailureAction - sets error state.
|
|
||||||
/// </summary>
|
|
||||||
[ReducerMethod]
|
|
||||||
public static PersonState OnCreatePersonFailure(PersonState state, CreatePersonFailureAction action)
|
|
||||||
=> state with
|
|
||||||
{
|
|
||||||
IsLoading = false,
|
|
||||||
Error = action.Error
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles UpdatePersonAction - sets loading state.
|
|
||||||
/// </summary>
|
|
||||||
[ReducerMethod(typeof(UpdatePersonAction))]
|
|
||||||
public static PersonState OnUpdatePerson(PersonState state)
|
|
||||||
=> state with
|
|
||||||
{
|
|
||||||
IsLoading = true,
|
|
||||||
Error = null
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles UpdatePersonSuccessAction - replaces person in list.
|
|
||||||
/// </summary>
|
|
||||||
[ReducerMethod]
|
|
||||||
public static PersonState OnUpdatePersonSuccess(PersonState state, UpdatePersonSuccessAction action)
|
|
||||||
=> state with
|
|
||||||
{
|
|
||||||
Persons = state.Persons.Select(p => p.Id == action.Person.Id ? action.Person : p).ToList(),
|
|
||||||
SelectedPerson = state.SelectedPerson?.Id == action.Person.Id ? action.Person : state.SelectedPerson,
|
|
||||||
IsLoading = false
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles UpdatePersonFailureAction - sets error state.
|
|
||||||
/// </summary>
|
|
||||||
[ReducerMethod]
|
|
||||||
public static PersonState OnUpdatePersonFailure(PersonState state, UpdatePersonFailureAction action)
|
|
||||||
=> state with
|
|
||||||
{
|
|
||||||
IsLoading = false,
|
|
||||||
Error = action.Error
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles DeletePersonAction - sets loading state.
|
|
||||||
/// </summary>
|
|
||||||
[ReducerMethod(typeof(DeletePersonAction))]
|
|
||||||
public static PersonState OnDeletePerson(PersonState state)
|
|
||||||
=> state with
|
|
||||||
{
|
|
||||||
IsLoading = true,
|
|
||||||
Error = null
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles DeletePersonSuccessAction - removes person from list.
|
|
||||||
/// </summary>
|
|
||||||
[ReducerMethod]
|
|
||||||
public static PersonState OnDeletePersonSuccess(PersonState state, DeletePersonSuccessAction action)
|
|
||||||
=> state with
|
|
||||||
{
|
|
||||||
Persons = state.Persons.Where(p => p.Id != action.Id).ToList(),
|
|
||||||
SelectedPerson = state.SelectedPerson?.Id == action.Id ? null : state.SelectedPerson,
|
|
||||||
IsLoading = false
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles DeletePersonFailureAction - sets error state.
|
|
||||||
/// </summary>
|
|
||||||
[ReducerMethod]
|
|
||||||
public static PersonState OnDeletePersonFailure(PersonState state, DeletePersonFailureAction action)
|
|
||||||
=> state with
|
|
||||||
{
|
|
||||||
IsLoading = false,
|
|
||||||
Error = action.Error
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles SelectPersonAction - sets selected person.
|
|
||||||
/// </summary>
|
|
||||||
[ReducerMethod]
|
|
||||||
public static PersonState OnSelectPerson(PersonState state, SelectPersonAction action)
|
|
||||||
=> state with
|
|
||||||
{
|
|
||||||
SelectedPerson = action.Person
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handles ClearPersonErrorAction - clears error state.
|
|
||||||
/// </summary>
|
|
||||||
[ReducerMethod(typeof(ClearPersonErrorAction))]
|
|
||||||
public static PersonState OnClearError(PersonState state)
|
|
||||||
=> state with
|
|
||||||
{
|
|
||||||
Error = null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
using Fluxor;
|
|
||||||
using Koogle.Application.DTOs;
|
|
||||||
|
|
||||||
namespace Koogle.Web.Store.PersonState;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Fluxor state for person management.
|
|
||||||
/// </summary>
|
|
||||||
[FeatureState]
|
|
||||||
public record PersonState
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// List of all persons for the current club.
|
|
||||||
/// </summary>
|
|
||||||
public IReadOnlyList<PersonDto> Persons { get; init; } = [];
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Currently selected person for editing.
|
|
||||||
/// </summary>
|
|
||||||
public PersonDto? SelectedPerson { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates whether a person operation is in progress.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsLoading { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Error message if operation failed.
|
|
||||||
/// </summary>
|
|
||||||
public string? Error { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Private constructor for Fluxor initialization.
|
|
||||||
/// </summary>
|
|
||||||
private PersonState() { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates the initial state.
|
|
||||||
/// </summary>
|
|
||||||
public static PersonState Initial => new()
|
|
||||||
{
|
|
||||||
Persons = [],
|
|
||||||
SelectedPerson = null,
|
|
||||||
IsLoading = false,
|
|
||||||
Error = null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue