diff --git a/EstateManagementUI.BlazorServer/Components/Pages/Operators/New.razor b/EstateManagementUI.BlazorServer/Components/Pages/Operators/New.razor index 71223bc5..b71350bc 100644 --- a/EstateManagementUI.BlazorServer/Components/Pages/Operators/New.razor +++ b/EstateManagementUI.BlazorServer/Components/Pages/Operators/New.razor @@ -29,6 +29,14 @@

@errorMessage

} + + @if (!string.IsNullOrWhiteSpace(successMessage)) + { +
+

Success

+

@successMessage

+
+ }
@@ -84,72 +92,4 @@
- - -@code { - private CreateOperatorModel model = new(); - private bool isSaving = false; - private string? errorMessage; - - protected override async Task OnInitializedAsync() - { - await RequirePermission(PermissionSection.Operator, PermissionFunction.Create); - } - - private async Task HandleSubmit() - { - isSaving = true; - errorMessage = null; - - try - { - var correlationId = new CorrelationId(Guid.NewGuid()); - var estateId = Guid.Parse("11111111-1111-1111-1111-111111111111"); - var accessToken = "stubbed-token"; - - // Create operator - var createCommand = new Commands.CreateOperatorCommand( - correlationId, - accessToken, - estateId, - model.OperatorName!, - model.RequireCustomMerchantNumber, - model.RequireCustomTerminalNumber - ); - - var createResult = await Mediator.Send(createCommand); - - if (!createResult.IsSuccess) - { - errorMessage = createResult.Message ?? "Failed to create operator"; - return; - } - - // Navigate to operators list with success - NavigationManager.NavigateTo("/operators"); - } - catch (Exception ex) - { - errorMessage = $"An error occurred: {ex.Message}"; - } - finally - { - isSaving = false; - } - } - - private void Cancel() - { - NavigationManager.NavigateTo("/operators"); - } - - public class CreateOperatorModel - { - [Required(ErrorMessage = "Operator name is required")] - public string? OperatorName { get; set; } - - public bool RequireCustomMerchantNumber { get; set; } - - public bool RequireCustomTerminalNumber { get; set; } - } -} + \ No newline at end of file diff --git a/EstateManagementUI.BlazorServer/Components/Pages/Operators/New.razor.cs b/EstateManagementUI.BlazorServer/Components/Pages/Operators/New.razor.cs new file mode 100644 index 00000000..7f531872 --- /dev/null +++ b/EstateManagementUI.BlazorServer/Components/Pages/Operators/New.razor.cs @@ -0,0 +1,88 @@ +using EstateManagementUI.BlazorServer.Permissions; +using EstateManagementUI.BusinessLogic.Requests; +using System.ComponentModel.DataAnnotations; + +namespace EstateManagementUI.BlazorServer.Components.Pages.Operators +{ + public partial class New + { + private CreateOperatorModel model = new(); + private bool isSaving = false; + private string? errorMessage; + private string? successMessage; + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (!firstRender) + { + await base.OnAfterRenderAsync(firstRender); + return; + } + + await RequirePermission(PermissionSection.Operator, PermissionFunction.Create); + } + + private async Task HandleSubmit() + { + isSaving = true; + errorMessage = null; + + try + { + var correlationId = new CorrelationId(Guid.NewGuid()); + var estateId = await this.GetEstateId(); + + // Create operator + var createCommand = new OperatorCommands.CreateOperatorCommand( + correlationId, + estateId, + model.OperatorName!, + model.RequireCustomMerchantNumber, + model.RequireCustomTerminalNumber + ); + + var createResult = await Mediator.Send(createCommand); + + if (!createResult.IsSuccess) + { + errorMessage = createResult.Message ?? "Failed to create operator"; + return; + } + + // Show success message briefly before navigating away + successMessage = "Operator created successfully."; + StateHasChanged(); + + // Small delay so user sees confirmation (adjust duration as needed) + await Task.Delay(2500); + + + // Navigate to operators list with success + NavigationManager.NavigateTo("/operators"); + } + catch (Exception ex) + { + errorMessage = $"An error occurred: {ex.Message}"; + } + finally + { + isSaving = false; + } + } + + private void Cancel() + { + NavigationManager.NavigateTo("/operators"); + } + + public class CreateOperatorModel + { + [Required(ErrorMessage = "Operator name is required")] + public string? OperatorName { get; set; } + + public bool RequireCustomMerchantNumber { get; set; } + + public bool RequireCustomTerminalNumber { get; set; } + } + } +} diff --git a/EstateManagmentUI.BusinessLogic/Client/OperatorMethods.cs b/EstateManagmentUI.BusinessLogic/Client/OperatorMethods.cs index 0179fee2..e07881a0 100644 --- a/EstateManagmentUI.BusinessLogic/Client/OperatorMethods.cs +++ b/EstateManagmentUI.BusinessLogic/Client/OperatorMethods.cs @@ -19,6 +19,9 @@ Task> GetOperator(OperatorQueries.GetOperatorQuery request Task UpdateOperator(OperatorCommands.UpdateOperatorCommand request, CancellationToken cancellationToken); + + Task CreateOperator(OperatorCommands.CreateOperatorCommand request, + CancellationToken cancellationToken); } public partial class ApiClient : IApiClient { @@ -71,5 +74,21 @@ public async Task UpdateOperator(OperatorCommands.UpdateOperatorCommand return Result.Success(); } + + public async Task CreateOperator(OperatorCommands.CreateOperatorCommand request, + CancellationToken cancellationToken) + { + var token = await this.GetToken(cancellationToken); + if (token.IsFailed) + return ResultHelpers.CreateFailure(token); + + var apiRequest = new CreateOperatorRequest() { Name = request.Name, RequireCustomMerchantNumber = request.RequireCustomMerchantNumber, RequireCustomTerminalNumber = request.RequireCustomTerminalNumber }; + + var apiResult = await this.TransactionProcessorClient.CreateOperator(token.Data, request.EstateId, apiRequest, cancellationToken); + if (apiResult.IsFailed) + return ResultHelpers.CreateFailure(apiResult); + + return Result.Success(); + } } } diff --git a/EstateManagmentUI.BusinessLogic/RequestHandlers/DateRequestHandler.cs b/EstateManagmentUI.BusinessLogic/RequestHandlers/DateRequestHandler.cs index d80c4f40..d43b3ea1 100644 --- a/EstateManagmentUI.BusinessLogic/RequestHandlers/DateRequestHandler.cs +++ b/EstateManagmentUI.BusinessLogic/RequestHandlers/DateRequestHandler.cs @@ -224,7 +224,7 @@ public async Task>> Handle(ContractQueries.Ge public class OperatorRequestHandler : IRequestHandler>>, IRequestHandler>, - IRequestHandler, + IRequestHandler, IRequestHandler { private readonly IApiClient ApiClient; @@ -242,9 +242,9 @@ public async Task> Handle(OperatorQueries.GetOperatorQuery CancellationToken cancellationToken) { return await this.ApiClient.GetOperator(request, cancellationToken); } - public async Task Handle(Commands.CreateOperatorCommand request, + public async Task Handle(OperatorCommands.CreateOperatorCommand request, CancellationToken cancellationToken) { - return Result.Success(); + return await this.ApiClient.CreateOperator(request, cancellationToken); } public async Task Handle(OperatorCommands.UpdateOperatorCommand request, CancellationToken cancellationToken) { diff --git a/EstateManagmentUI.BusinessLogic/Requests/Requests.cs b/EstateManagmentUI.BusinessLogic/Requests/Requests.cs index e77e0074..10d7c41c 100644 --- a/EstateManagmentUI.BusinessLogic/Requests/Requests.cs +++ b/EstateManagmentUI.BusinessLogic/Requests/Requests.cs @@ -90,6 +90,8 @@ public record CreateMerchantCommand(CorrelationId CorrelationId, Guid EstateId, public static class OperatorCommands { public record UpdateOperatorCommand(CorrelationId CorrelationId,Guid EstateId, Guid OperatorId, string Name, bool RequireCustomMerchantNumber, bool RequireCustomTerminalNumber) : IRequest; + + public record CreateOperatorCommand(CorrelationId CorrelationId, Guid EstateId, string Name, bool RequireCustomMerchantNumber, bool RequireCustomTerminalNumber) : IRequest; } public static class Commands @@ -97,7 +99,6 @@ public static class Commands public record CreateContractCommand(CorrelationId CorrelationId, string AccessToken, Guid EstateId, string Description, Guid OperatorId) : IRequest; public record CreateMerchantUserCommand(CorrelationId CorrelationId, string AccessToken, Guid EstateId, Guid MerchantId, string EmailAddress, string Password) : IRequest; - public record CreateOperatorCommand(CorrelationId CorrelationId, string AccessToken, Guid EstateId, string Name, bool RequireCustomMerchantNumber, bool RequireCustomTerminalNumber) : IRequest; diff --git a/EstateManagmentUI.BusinessLogic/Services/TestMediatorService.cs b/EstateManagmentUI.BusinessLogic/Services/TestMediatorService.cs index a063e4f3..c90d0514 100644 --- a/EstateManagmentUI.BusinessLogic/Services/TestMediatorService.cs +++ b/EstateManagmentUI.BusinessLogic/Services/TestMediatorService.cs @@ -69,7 +69,7 @@ public Task Send(IRequest request, Cancellation // Commands - execute against test data store MerchantCommands.CreateMerchantCommand cmd => Task.FromResult((TResponse)(object)this.ExecuteCreateMerchant(cmd)), MerchantCommands.UpdateMerchantCommand cmd => Task.FromResult((TResponse)(object)this.ExecuteUpdateMerchant(cmd)), - Commands.CreateOperatorCommand cmd => Task.FromResult((TResponse)(object)this.ExecuteCreateOperator(cmd)), + OperatorCommands.CreateOperatorCommand cmd => Task.FromResult((TResponse)(object)this.ExecuteCreateOperator(cmd)), OperatorCommands.UpdateOperatorCommand cmd => Task.FromResult((TResponse)(object)this.ExecuteUpdateOperator(cmd)), Commands.CreateContractCommand cmd => Task.FromResult((TResponse)(object)this.ExecuteCreateContract(cmd)), Commands.AddProductToContractCommand cmd => Task.FromResult((TResponse)(object)this.ExecuteAddProductToContract(cmd)), @@ -170,7 +170,7 @@ private Result ExecuteUpdateMerchant(MerchantCommands.UpdateMerchantCommand cmd) return Result.Success(); } - private Result ExecuteCreateOperator(Commands.CreateOperatorCommand cmd) + private Result ExecuteCreateOperator(OperatorCommands.CreateOperatorCommand cmd) { var operatorModel = new OperatorModel {