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
{