Skip to content

Commit cc4e3ee

Browse files
committed
Update layout styling and refactor API clients for the ClientPortal and Admin web apps
1 parent 91bef64 commit cc4e3ee

7 files changed

Lines changed: 100 additions & 169 deletions

File tree

‎src/Admin.Web/Pages/Index.razor‎

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -65,48 +65,4 @@
6565
</FluentCard>
6666
</FluentGridItem>
6767
</FluentGrid>
68-
69-
<FluentCard Style="padding: 32px; background-color: #f3f2f1;">
70-
<FluentStack Orientation="Microsoft.FluentUI.AspNetCore.Components.Orientation.Vertical" Style="gap: 16px;">
71-
<h2 style="margin: 0;">CRA Compliance Features</h2>
72-
<FluentGrid Spacing="2">
73-
<FluentGridItem xs="12" md="6">
74-
<FluentStack Orientation="Microsoft.FluentUI.AspNetCore.Components.Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center" Style="gap: 12px;">
75-
<FluentIcon Value="@(new Icons.Regular.Size24.Checkmark())" Color="Color.Success" />
76-
<div>
77-
<strong>Automatic Security Updates</strong>
78-
<p style="margin: 4px 0 0 0; color: #605e5c;">Enabled by default for all registered devices</p>
79-
</div>
80-
</FluentStack>
81-
</FluentGridItem>
82-
<FluentGridItem xs="12" md="6">
83-
<FluentStack Orientation="Microsoft.FluentUI.AspNetCore.Components.Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center" Style="gap: 12px;">
84-
<FluentIcon Value="@(new Icons.Regular.Size24.Checkmark())" Color="Color.Success" />
85-
<div>
86-
<strong>Digital Signatures</strong>
87-
<p style="margin: 4px 0 0 0; color: #605e5c;">RSA-4096 signatures ensure update authenticity</p>
88-
</div>
89-
</FluentStack>
90-
</FluentGridItem>
91-
<FluentGridItem xs="12" md="6">
92-
<FluentStack Orientation="Microsoft.FluentUI.AspNetCore.Components.Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center" Style="gap: 12px;">
93-
<FluentIcon Value="@(new Icons.Regular.Size24.Checkmark())" Color="Color.Success" />
94-
<div>
95-
<strong>Integrity Verification</strong>
96-
<p style="margin: 4px 0 0 0; color: #605e5c;">SHA-256 hashing prevents file corruption</p>
97-
</div>
98-
</FluentStack>
99-
</FluentGridItem>
100-
<FluentGridItem xs="12" md="6">
101-
<FluentStack Orientation="Microsoft.FluentUI.AspNetCore.Components.Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center" Style="gap: 12px;">
102-
<FluentIcon Value="@(new Icons.Regular.Size24.Checkmark())" Color="Color.Success" />
103-
<div>
104-
<strong>Deployment Tracking</strong>
105-
<p style="margin: 4px 0 0 0; color: #605e5c;">Monitor status across all customer devices</p>
106-
</div>
107-
</FluentStack>
108-
</FluentGridItem>
109-
</FluentGrid>
110-
</FluentStack>
111-
</FluentCard>
11268
</FluentStack>

‎src/Admin.Web/Shared/Layout/MainLayout.razor‎

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,45 +4,47 @@
44

55
<FluentLayout>
66
<FluentHeader Style="background-color: #0078d4; color: white; padding: 16px 24px;">
7-
<FluentStack Orientation="Microsoft.FluentUI.AspNetCore.Components.Orientation.Horizontal"
8-
VerticalAlignment="VerticalAlignment.Center"
9-
Style="width: 100%;">
10-
<FluentLabel Typo="Typography.H4" Style="color: white; margin: 0;">
11-
<FluentIcon Value="@(new Icons.Regular.Size24.CloudArrowUp())" Style="color: white; margin-right: 8px;" />
12-
Admin Portal - CRA Update Management
13-
</FluentLabel>
14-
<FluentSpacer />
15-
<FluentNavMenu>
16-
<FluentNavLink Href="/" Icon="@(new Icons.Regular.Size20.Home())" Style="color: white;">
17-
Home
18-
</FluentNavLink>
19-
<FluentNavLink Href="/upload-update" Icon="@(new Icons.Regular.Size20.CloudArrowUp())" Style="color: white;">
20-
Upload Updates
21-
</FluentNavLink>
22-
<FluentNavLink Href="/manage-releases" Icon="@(new Icons.Regular.Size20.Document())" Style="color: white;">
23-
Manage Releases
24-
</FluentNavLink>
25-
<FluentNavLink Href="/dashboard" Icon="@(new Icons.Regular.Size20.DataBarVertical())" Style="color: white;">
26-
Dashboard
27-
</FluentNavLink>
28-
</FluentNavMenu>
29-
</FluentStack>
7+
<FluentLabel Typo="Typography.H4" Style="color: white; margin: 0;">
8+
<FluentIcon Value="@(new Icons.Regular.Size24.CloudArrowUp())" Style="color: white; margin-right: 8px;" />
9+
Admin Portal - CRA Update Management
10+
</FluentLabel>
3011
</FluentHeader>
3112

32-
<FluentStack Class="main-content" Style="padding: 24px; min-height: calc(100vh - 120px);">
33-
<ErrorBoundary @ref="errorBoundary">
34-
<ChildContent>
35-
@Body
36-
</ChildContent>
37-
<ErrorContent>
38-
<FluentMessageBar Intent="MessageIntent.Error">
39-
<p>Something went wrong: @context.Message</p>
40-
</FluentMessageBar>
41-
@{ ToastService.ShowError(@context.Message); }
42-
</ErrorContent>
43-
</ErrorBoundary>
44-
<FluentDialogProvider />
45-
</FluentStack>
13+
<div class="container-fluid" style="min-height: calc(100vh - 120px);">
14+
<div class="row h-100">
15+
<div class="col-md-2 col-lg-2" style="background-color: #f3f2f1; padding: 16px;">
16+
<FluentNavMenu>
17+
<FluentNavLink Href="/" Icon="@(new Icons.Regular.Size20.Home())" Match="NavLinkMatch.All">
18+
Home
19+
</FluentNavLink>
20+
<FluentNavLink Href="/upload-update" Icon="@(new Icons.Regular.Size20.CloudArrowUp())">
21+
Upload Updates
22+
</FluentNavLink>
23+
<FluentNavLink Href="/manage-releases" Icon="@(new Icons.Regular.Size20.Document())">
24+
Manage Releases
25+
</FluentNavLink>
26+
<FluentNavLink Href="/dashboard" Icon="@(new Icons.Regular.Size20.DataBarVertical())">
27+
Dashboard
28+
</FluentNavLink>
29+
</FluentNavMenu>
30+
</div>
31+
32+
<div class="col-md-10 col-lg-10" style="padding: 24px;">
33+
<ErrorBoundary @ref="errorBoundary">
34+
<ChildContent>
35+
@Body
36+
</ChildContent>
37+
<ErrorContent>
38+
<FluentMessageBar Intent="MessageIntent.Error">
39+
<p>Something went wrong: @context.Message</p>
40+
</FluentMessageBar>
41+
@{ ToastService.ShowError(@context.Message); }
42+
</ErrorContent>
43+
</ErrorBoundary>
44+
<FluentDialogProvider />
45+
</div>
46+
</div>
47+
</div>
4648

4749
<FluentFooter Style="background-color: #f3f2f1; padding: 16px 24px; text-align: center;">
4850
<p style="margin: 0; color: #605e5c;">

‎src/ClientPortal.UpdateAgent/Program.cs‎

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,45 @@
1212
// Configure configuration
1313
builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
1414

15-
// Add HTTP client
16-
builder.Services.AddHttpClient("UpdateService", (sp, client) =>
15+
// Add HTTP client for ClientPortal.Api (releases list)
16+
builder.Services.AddHttpClient("ClientPortalApi", (sp, client) =>
1717
{
1818
var config = sp.GetRequiredService<IConfiguration>();
19-
var baseUrl = config["UpdateAgent:ApiBaseUrl"] ?? throw new Exception("ApiBaseUrl not configured");
19+
var baseUrl = config["UpdateAgent:ClientPortalApiUrl"] ?? throw new Exception("ClientPortalApiUrl not configured");
2020
var apiKey = config["UpdateAgent:DeviceApiKey"] ?? throw new Exception("DeviceApiKey not configured");
2121

2222
client.BaseAddress = new Uri(baseUrl);
2323
client.DefaultRequestHeaders.Add("X-API-Key", apiKey);
24-
client.Timeout = TimeSpan.FromMinutes(10); // Long timeout for large file downloads
24+
client.Timeout = TimeSpan.FromMinutes(1);
2525
})
2626
.ConfigurePrimaryHttpMessageHandler(() =>
2727
{
2828
var handler = new HttpClientHandler();
29-
30-
// In development, allow untrusted certificates (self-signed certs)
3129
if (builder.Environment.IsDevelopment())
3230
{
3331
handler.ServerCertificateCustomValidationCallback =
3432
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
3533
}
34+
return handler;
35+
});
3636

37+
// Add HTTP client for Admin.Api (file downloads)
38+
builder.Services.AddHttpClient("AdminApi", (sp, client) =>
39+
{
40+
var config = sp.GetRequiredService<IConfiguration>();
41+
var baseUrl = config["UpdateAgent:AdminApiUrl"] ?? throw new Exception("AdminApiUrl not configured");
42+
43+
client.BaseAddress = new Uri(baseUrl);
44+
client.Timeout = TimeSpan.FromMinutes(10); // Long timeout for large file downloads
45+
})
46+
.ConfigurePrimaryHttpMessageHandler(() =>
47+
{
48+
var handler = new HttpClientHandler();
49+
if (builder.Environment.IsDevelopment())
50+
{
51+
handler.ServerCertificateCustomValidationCallback =
52+
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
53+
}
3754
return handler;
3855
});
3956

@@ -86,9 +103,9 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
86103

87104
private async Task CheckForUpdatesAsync(CancellationToken cancellationToken)
88105
{
89-
var client = _httpClientFactory.CreateClient("UpdateService");
106+
var client = _httpClientFactory.CreateClient("ClientPortalApi");
90107

91-
// Get active releases (no leading slash - BaseAddress already includes /api)
108+
// Get active releases from ClientPortal.Api
92109
var releases = await client.GetFromJsonAsync<List<ReleaseDto>>("releases/active", cancellationToken);
93110

94111
if (releases == null || releases.Count == 0)
@@ -143,17 +160,17 @@ private async Task DownloadAndInstallAsync(ReleaseDto release, CancellationToken
143160

144161
try
145162
{
146-
var client = _httpClientFactory.CreateClient("UpdateService");
163+
var adminClient = _httpClientFactory.CreateClient("AdminApi");
147164

148165
// Create download directory
149166
var downloadDir = _config["UpdateAgent:DownloadDirectory"] ?? "./downloads";
150167
Directory.CreateDirectory(downloadDir);
151168

152169
var filePath = Path.Combine(downloadDir, $"update-{version}.bin");
153170

154-
// Download file
171+
// Download file from Admin.Api
155172
_logger.LogInformation("Downloading to {FilePath}...", filePath);
156-
var response = await client.GetAsync($"updates/{updateId}/download", cancellationToken);
173+
var response = await adminClient.GetAsync($"updates/{updateId}/download", cancellationToken);
157174
response.EnsureSuccessStatusCode();
158175

159176
await using (var fileStream = File.Create(filePath))

‎src/ClientPortal.UpdateAgent/appsettings.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"UpdateAgent": {
3-
"ApiBaseUrl": "https://localhost:7100/api",
3+
"ClientPortalApiUrl": "https://localhost:7200/api",
4+
"AdminApiUrl": "https://localhost:7100/api",
45
"DeviceApiKey": "dev1-api-key-12345678-secure-token",
56
"DeviceId": "77777777-7777-7777-7777-777777777777",
67
"CheckIntervalMinutes": 1,

‎src/ClientPortal.Web/Pages/Index.razor‎

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -63,48 +63,4 @@
6363
</FluentCard>
6464
</FluentGridItem>
6565
</FluentGrid>
66-
67-
<FluentCard Style="padding: 32px; background-color: #f3f2f1;">
68-
<FluentStack Orientation="Orientation.Vertical" Style="gap: 16px;">
69-
<h2 style="margin: 0;">CRA Compliance Features</h2>
70-
<FluentGrid Spacing="2">
71-
<FluentGridItem xs="12" md="6">
72-
<FluentStack Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center" Style="gap: 12px;">
73-
<FluentIcon Value="@(new Icons.Regular.Size24.Checkmark())" Color="Color.Success" />
74-
<div>
75-
<strong>Automatic Security Updates</strong>
76-
<p style="margin: 4px 0 0 0; color: #605e5c;">Enabled by default for all registered devices</p>
77-
</div>
78-
</FluentStack>
79-
</FluentGridItem>
80-
<FluentGridItem xs="12" md="6">
81-
<FluentStack Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center" Style="gap: 12px;">
82-
<FluentIcon Value="@(new Icons.Regular.Size24.Checkmark())" Color="Color.Success" />
83-
<div>
84-
<strong>Clear Opt-Out Mechanism</strong>
85-
<p style="margin: 4px 0 0 0; color: #605e5c;">Easy device settings to control updates</p>
86-
</div>
87-
</FluentStack>
88-
</FluentGridItem>
89-
<FluentGridItem xs="12" md="6">
90-
<FluentStack Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center" Style="gap: 12px;">
91-
<FluentIcon Value="@(new Icons.Regular.Size24.Checkmark())" Color="Color.Success" />
92-
<div>
93-
<strong>Postpone Capability</strong>
94-
<p style="margin: 4px 0 0 0; color: #605e5c;">Temporarily postpone non-critical updates</p>
95-
</div>
96-
</FluentStack>
97-
</FluentGridItem>
98-
<FluentGridItem xs="12" md="6">
99-
<FluentStack Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center" Style="gap: 12px;">
100-
<FluentIcon Value="@(new Icons.Regular.Size24.Checkmark())" Color="Color.Success" />
101-
<div>
102-
<strong>Security Transparency</strong>
103-
<p style="margin: 4px 0 0 0; color: #605e5c;">CVE lists and detailed security information</p>
104-
</div>
105-
</FluentStack>
106-
</FluentGridItem>
107-
</FluentGrid>
108-
</FluentStack>
109-
</FluentCard>
11066
</FluentStack>

‎src/ClientPortal.Web/Shared/MainLayout.razor‎

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,40 @@
22

33
<FluentLayout>
44
<FluentHeader Style="background-color: #0078d4; color: white; padding: 16px 24px;">
5-
<FluentStack Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center" Style="width: 100%;">
6-
<FluentLabel Typo="Typography.H4" Style="color: white; margin: 0;">
7-
<FluentIcon Value="@(new Icons.Regular.Size24.CloudCheckmark())" Style="color: white; margin-right: 8px;" />
8-
Customer Portal - CRA Update Management
9-
</FluentLabel>
10-
<FluentSpacer />
11-
<FluentNavMenu>
12-
<FluentNavLink Href="/" Match="NavLinkMatch.All" Icon="@(new Icons.Regular.Size20.Home())" Style="color: white;">
13-
Home
14-
</FluentNavLink>
15-
<FluentNavLink Href="/updates" Icon="@(new Icons.Regular.Size20.CloudArrowUp())" Style="color: white;">
16-
Updates
17-
</FluentNavLink>
18-
<FluentNavLink Href="/devices" Icon="@(new Icons.Regular.Size20.Phone())" Style="color: white;">
19-
Devices
20-
</FluentNavLink>
21-
<FluentNavLink Href="/deployments" Icon="@(new Icons.Regular.Size20.Rocket())" Style="color: white;">
22-
Deployments
23-
</FluentNavLink>
24-
</FluentNavMenu>
25-
</FluentStack>
5+
<FluentLabel Typo="Typography.H4" Style="color: white; margin: 0;">
6+
<FluentIcon Value="@(new Icons.Regular.Size24.CloudCheckmark())" Style="color: white; margin-right: 8px;" />
7+
Customer Portal - CRA Update Management
8+
</FluentLabel>
269
</FluentHeader>
2710

28-
<FluentStack Class="main-content" Orientation="Orientation.Vertical" Style="padding: 24px; min-height: calc(100vh - 120px);">
29-
@Body
30-
</FluentStack>
11+
<div class="container-fluid p-0" style="min-height: calc(100vh - 120px);">
12+
<div class="row g-0 h-100">
13+
<div class="col-md-2 col-lg-2" style="background-color: #f3f2f1; padding: 16px; min-height: calc(100vh - 120px);">
14+
<FluentNavMenu>
15+
<FluentNavLink Href="/" Match="NavLinkMatch.All" Icon="@(new Icons.Regular.Size20.Home())">
16+
Home
17+
</FluentNavLink>
18+
<FluentNavLink Href="/updates" Icon="@(new Icons.Regular.Size20.CloudArrowUp())">
19+
Updates
20+
</FluentNavLink>
21+
<FluentNavLink Href="/devices" Icon="@(new Icons.Regular.Size20.Phone())">
22+
Devices
23+
</FluentNavLink>
24+
<FluentNavLink Href="/deployments" Icon="@(new Icons.Regular.Size20.Rocket())">
25+
Deployments
26+
</FluentNavLink>
27+
</FluentNavMenu>
28+
</div>
29+
30+
<div class="col-md-10 col-lg-10" style="padding: 24px;">
31+
@Body
32+
</div>
33+
</div>
34+
</div>
3135

3236
<FluentFooter Style="background-color: #f3f2f1; padding: 16px 24px; text-align: center;">
3337
<p style="margin: 0; color: #605e5c;">
3438
&copy; 2025 Vendor Update Management System - CRA Compliant
3539
</p>
3640
</FluentFooter>
3741
</FluentLayout>
38-
39-
<style>
40-
.main-content {
41-
flex: 1;
42-
overflow-y: auto;
43-
}
44-
</style>

‎src/ClientPortal.Web/wwwroot/index.html‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>Vendor Client Portal</title>
77
<base href="/" />
8+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
89
<link href="_content/Microsoft.FluentUI.AspNetCore.Components/css/reboot.css" rel="stylesheet" />
910
<link href="_content/Blazored.Toast/blazored-toast.min.css" rel="stylesheet" />
1011
<link href="Vendor.Client.Web.styles.css" rel="stylesheet" />
1112
</head>
1213

13-
<body>
14+
<body style="background-color: var(--neutral-layer-1);">
1415
<div id="app">
1516
<div style="display: flex; align-items: center; justify-content: center; height: 100vh;">
1617
<p>Loading Vendor Client Portal...</p>
@@ -19,5 +20,6 @@
1920

2021
<script src="_framework/blazor.webassembly.js"></script>
2122
<script src="_content/Microsoft.FluentUI.AspNetCore.Components/Microsoft.FluentUI.AspNetCore.Components.lib.module.js" type="module" async></script>
23+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
2224
</body>
2325
</html>

0 commit comments

Comments
 (0)