Start implementing settings page

This commit is contained in:
Samuele Lorefice
2025-07-16 17:10:32 +02:00
parent c8f0bfe85b
commit 07741f4129
6 changed files with 59 additions and 13 deletions

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectTasksOptions">
<TaskOptions isEnabled="false">
<TaskOptions isEnabled="true">
<option name="arguments" value="$FileName$:$FileNameWithoutExtension$.css" />
<option name="checkSyntaxErrors" value="true" />
<option name="description" />

View File

@@ -2,6 +2,7 @@
<configuration default="false" name="MilkStream HotReload" type="RunDotNetWatch" factoryName="RunDotNetWatch">
<option name="envs">
<map>
<entry key="ASPNETCORE_ENVIRONMENT" value="Development" />
<entry key="DOTNET_ENVIRONMENT" value="Hotreload" />
</map>
</option>
@@ -9,6 +10,7 @@
<option name="programParameters" value="" />
<option name="projectFilePath" value="$PROJECT_DIR$/MilkStream/MilkStream.csproj" />
<option name="projectTfm" value="net8.0" />
<option name="suppressBrowserLaunch" value="true" />
<option name="watchParameters" value="" />
<option name="workingDirectory" value="$PROJECT_DIR$/MilkStream" />
<method v="2" />

View File

@@ -44,7 +44,7 @@
</div>
@if (admin) {
<button class="btn btn-outline-info mx-1">
<button class="btn btn-outline-info mx-1" @onclick="OnSettingsClick">
<i class="bi bi-gear-wide-connected"></i>
Settings
</button>
@@ -74,7 +74,6 @@
}
username = userInfo.Username;
admin = userInfo.AccessLevel == EAccessLevel.Admin;
StateHasChanged();
}
async Task OnLoginClick() {
@@ -90,4 +89,6 @@
}
void OnRegisterClick() => navigation.NavigateTo("/register");
void OnSettingsClick() => navigation.NavigateTo("/settings");
}

View File

@@ -0,0 +1,41 @@
@page "/Settings"
@using Butter.Dtos.Settings
@using MilkStream.Services
@inject SettingsService SettingsService
<PageTitle>Settings</PageTitle>
<div>
@if (settings.Settings.Any()) {
foreach (var setting in settings.Settings) {
<div class="card mb-3">
<div class="card-header">
@setting.Name
</div>
<div class="card-body">
<p class="card-text"><strong>Value:</strong> @setting.Value</p>
</div>
</div>
}
} else {
<div class="alert alert-danger my-2 my-sm-5 mx-auto" style="max-width: fit-content" role="alert">
No settings available.
</div>
}
</div>
@code {
SettingsDto settings = new SettingsDto {
Settings = new List<SettingDto>()
};
protected async override Task OnInitializedAsync() {
var response = await SettingsService.GetAllSettings();
settings = response ??
new SettingsDto() {
Settings = (List<SettingDto>)[]
};
}
}

View File

@@ -9,21 +9,22 @@ public class SettingsServiceOptions {
public class SettingsService {
HttpClient client;
public SettingsService(IOptions<SettingsServiceOptions> options) {
client = new();
LoginService loginService;
public SettingsService(IOptions<SettingsServiceOptions> options, LoginService loginService, IHttpClientFactory httpClientFactory) {
client = httpClientFactory.CreateClient("MilkstreamClient");
this.loginService = loginService;
client.BaseAddress = new(options.Value.BaseUrl);
}
public async Task<List<SettingsDto>> GetAllSettings(string accessToken) {
client.DefaultRequestHeaders.Authorization = new("Bearer", accessToken);
public async Task<SettingsDto?> GetAllSettings() {
if (!loginService.IsLoggedIn) return null;
client.DefaultRequestHeaders.Authorization = new("Bearer", loginService.authInfo!.Token);
var response = await client.GetAsync("api/settings/get-all");
if (response.IsSuccessStatusCode) {
return await response.Content.ReadFromJsonAsync<List<SettingsDto>>() ?? new List<SettingsDto>();
}
return new List<SettingsDto>();
if (response.IsSuccessStatusCode) return await response.Content.ReadFromJsonAsync<SettingsDto>();
return null;
}
}

View File

@@ -50,5 +50,6 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASessionStorageService_002Eg_002Ecs_002Fl_003AC_0021_003FUsers_003FREDCODE_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fc5abb9d0ed5bcffd706887e8cabcd2f1947e67c_003FSessionStorageService_002Eg_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThreadPoolWorkQueue_002Ecs_002Fl_003AC_0021_003FUsers_003FREDCODE_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fac24a7c2e0f296e231c484b3fd930268f76c06dc75f4aad1df7aaf09f2c1227_003FThreadPoolWorkQueue_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThrowHelper_002Ecs_002Fl_003AC_0021_003FUsers_003FREDCODE_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003F2c8e7ca976f350cba9836d5565dac56b11e0b56656fa786460eb1395857a6fa_003FThrowHelper_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThrowHelper_002Ecs_002Fl_003AC_0021_003FUsers_003FREDCODE_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fc7da56581ee7b20208f09e80b735961e4d5d7b9e5562bfdec94a75c57b391_003FThrowHelper_002Ecs_002Fz_003A2_002D1/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AUtf8JsonWriterCache_002Ecs_002Fl_003AC_0021_003FUsers_003FREDCODE_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003F96d87fca98b4167c66ffae61c9ee88dc182d6e7dbc7eb8dbf41297e660eb_003FUtf8JsonWriterCache_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AWriteStackFrame_002Ecs_002Fl_003AC_0021_003FUsers_003FREDCODE_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fcfb06811acbbb25f4c1f3ae4eee74f65da5b2e9bd1bdc01ad979ac9b6745e9_003FWriteStackFrame_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>