diff --git a/testFrontend/SafeNSound.Demo/Pages/Admin.razor b/testFrontend/SafeNSound.Demo/Pages/Admin.razor
index 0dcb1a3..952910d 100644
--- a/testFrontend/SafeNSound.Demo/Pages/Admin.razor
+++ b/testFrontend/SafeNSound.Demo/Pages/Admin.razor
@@ -5,8 +5,24 @@
return Task.CompletedTask;
})">Manage devices
</LinkButton>
+<LinkButton OnClick="@GetUserList">Get all users</LinkButton>
+
+<pre>
+ @foreach (var user in Enumerable.Reverse(UserList)) {
+ @(user + "\n")
+ }
+</pre>
@code {
-
-
+
+ List<string> UserList { get; set; } = [];
+
+ private async Task GetUserList() {
+ UserList.Clear();
+ await foreach (var userId in App.AdminClient.GetAllUserIdsEnumerable()) {
+ UserList.Add(userId);
+ StateHasChanged();
+ }
+ }
+
}
\ No newline at end of file
diff --git a/testFrontend/SafeNSound.Demo/Pages/Devices.razor b/testFrontend/SafeNSound.Demo/Pages/Devices.razor
index 5f90132..695c138 100644
--- a/testFrontend/SafeNSound.Demo/Pages/Devices.razor
+++ b/testFrontend/SafeNSound.Demo/Pages/Devices.razor
@@ -5,6 +5,7 @@
<hr/>
<LinkButton OnClick="@CreateDevice">Create new device</LinkButton>
<LinkButton OnClick="@ReloadDevices">Reload Devices</LinkButton>
+ <LinkButton OnClick="@Logout">Log out</LinkButton>
<LinkButton OnClick="@DeleteAccount">Delete account</LinkButton>
@foreach (var device in CurrentDevices) {
<div class="device-card">
@@ -77,5 +78,9 @@
private async Task DeleteAccount() {
await Client.DeleteAccount(Auth);
}
+
+ private async Task Logout() {
+ await Client.LogOut();
+ }
}
\ No newline at end of file
diff --git a/testFrontend/SafeNSound.Demo/Pages/Monitor.razor b/testFrontend/SafeNSound.Demo/Pages/Monitor.razor
index d78d60a..f948b69 100644
--- a/testFrontend/SafeNSound.Demo/Pages/Monitor.razor
+++ b/testFrontend/SafeNSound.Demo/Pages/Monitor.razor
@@ -6,16 +6,44 @@
return Task.CompletedTask;
})">Manage devices
</LinkButton>
-
+
@foreach (var user in AssignedUsers) {
- <p>Assigned user @user
+ <p>
+ <span>Assigned user @user</span>
@if (Alarms.ContainsKey(user)) {
- <pre>@Alarms[user].ToJson(indent: false)</pre>
+ <span>🔔</span>
+ <br/>
+ <i>@Alarms[user].Reason (@Alarms[user].CreatedAt)</i>
+ }
+ else {
+ <span>🔕</span>
}
- </p>
+ </p>
+ <LinkButton OnClick="() => { _ = ManageUser(user); return Task.CompletedTask; }">Manage</LinkButton>
}
}
+@if (!string.IsNullOrWhiteSpace(manageUserId)) {
+ <ModalWindow Title="Manage user">
+ <span>ID: @manageUserId</span><br/>
+ @if (Alarms.ContainsKey(manageUserId)) {
+ <span><b>User has alarm!</b></span>
+ <br/>
+ <i>@Alarms[manageUserId].Reason at @Alarms[manageUserId].CreatedAt.ToLocalTime()</i>
+ <LinkButton>Clear</LinkButton>
+ <br/>
+ }
+ <span>Budget: @manageUserBudget?.Amount EUR</span><br/>
+ <span>Add money: </span>
+ <FancyTextBox Value="@manageUserNewBudget?.Amount.ToString()"
+ ValueChanged="s => manageUserNewBudget.Amount = double.Parse(s)"/>
+ <span>, reason:</span>
+ <FancyTextBox @bind-Value="@manageUserNewBudget.Reason"/>
+ <LinkButton OnClick="@UpdateUserBudget">Add budget
+ </LinkButton>
+ </ModalWindow>
+}
+
@code {
bool _isInitialized = false;
@@ -28,4 +56,27 @@
_isInitialized = true;
}
+ string? manageUserId { get; set; }
+ BudgetWithHistory? manageUserBudget { get; set; }
+ BudgetHistoryEntry manageUserNewBudget { get; set; }
+
+ private async Task ManageUser(string user) {
+ manageUserId = user;
+ manageUserBudget = await App.MonitorClient.GetBudget(manageUserId);
+ manageUserBudget ??= new BudgetWithHistory {
+ Amount = 0,
+ History = []
+ };
+ manageUserNewBudget = new() {
+ Venue = App.MonitorAuth.Username
+ };
+
+ StateHasChanged();
+ }
+
+ private async Task UpdateUserBudget() {
+ await App.MonitorClient.AddBudget(manageUserId, manageUserNewBudget);
+ await ManageUser(manageUserId);
+ }
+
}
\ No newline at end of file
diff --git a/testFrontend/SafeNSound.Demo/Pages/Tools.razor b/testFrontend/SafeNSound.Demo/Pages/Tools.razor
new file mode 100644
index 0000000..f67f7ef
--- /dev/null
+++ b/testFrontend/SafeNSound.Demo/Pages/Tools.razor
@@ -0,0 +1,18 @@
+@page "/Tools"
+<h3>Tools</h3>
+<LinkButton OnClick="@MakeSuperAdmin">Assign more users to monitor</LinkButton>
+
+@code {
+
+ private async Task MakeSuperAdmin() {
+ await foreach (var user in App.AdminClient.GetAllUserIdsEnumerable()) {
+ try {
+ await App.MonitorClient.AddAssignedUser(user);
+ }
+ catch (Exception ex) {
+ Console.WriteLine($"Failed to assign user {user}: {ex.Message}");
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/testFrontend/SafeNSound.Demo/Pages/User.razor b/testFrontend/SafeNSound.Demo/Pages/User.razor
index cdffbe3..cfbfa53 100644
--- a/testFrontend/SafeNSound.Demo/Pages/User.razor
+++ b/testFrontend/SafeNSound.Demo/Pages/User.razor
@@ -16,6 +16,30 @@
<LinkButton Color="#FF0000" OnClick="@(() => RaiseAlarm(null))">Clear</LinkButton>
</span>
<br/>
+
+ <span>Budget: @Math.Round(Budget.Amount, 2)</span><br/>
+
+ <span>
+ Spend
+ <FancyTextBox Value="@ToSpend.Amount.ToString()" ValueChanged="s => ToSpend.Amount = double.Parse(s)"/>
+ EUR at
+ <FancyTextBox @bind-Value="@ToSpend.Venue"/>
+ for
+ <FancyTextBox @bind-Value="@ToSpend.Reason"/>
+ <LinkButton OnClick="@(() => SpendBudget(ToSpend))">Spend</LinkButton>
+ </span><br/>
+
+ <i>Spend history is comming soon!</i>
+ @* oops, forgot to use the DTO for getting own budget... *@
+ @* @foreach(var history in Budget.History) { *@
+ @* <div> *@
+ @* <span>@history.CreatedAt!.Value.ToLocalTime()</span> - *@
+ @* <span>@history.Amount EUR</span> - *@
+ @* <span>@history.Reason</span> - *@
+ @* <span>@history.Venue</span> *@
+ @* </div> *@
+ @* } *@
+
}
@if (Alarm != null) {
@@ -38,16 +62,22 @@
private WhoAmI WhoAmI { get; set; } = null!;
private AlarmDto? Alarm { get; set; } = null!;
+ private BudgetHistoryEntry ToSpend { get; set; } = new() {
+ Amount = 0,
+ Reason = string.Empty,
+ Venue = string.Empty
+ };
protected override async Task OnInitializedAsync() {
WhoAmI = await App.UserClient.WhoAmI();
- _isInitialized = true;
_ = PollAlarm();
+ Budget = await App.UserClient.GetBudget();
NavigationManager.LocationChanged += (sender, args) => {
if (args.Location != NavigationManager.Uri) {
- _running = false; // Stop polling when navigating away
+ _running = false;
}
};
+ _isInitialized = true;
}
private async Task PollAlarm() {
@@ -57,11 +87,19 @@
Alarm = newAlarm;
StateHasChanged();
}
+
+ var newBudget = await App.UserClient.GetBudget();
+ if (Math.Abs(Budget.Amount - newBudget.Amount) > 0.01) {
+ Budget = newBudget;
+ StateHasChanged();
+ }
await Task.Delay(1000);
}
}
+ public CurrentBalance Budget { get; set; }
+
private async Task RaiseAlarm(string? reason) {
if (string.IsNullOrWhiteSpace(reason))
await App.UserClient.DeleteAlarm();
@@ -80,4 +118,8 @@
~User() => ReleaseUnmanagedResources();
+ private async Task SpendBudget(BudgetHistoryEntry toSpend) {
+ await App.UserClient.SpendBudget(toSpend);
+ }
+
}
\ No newline at end of file
|