diff --git a/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Components/App.razor b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Components/App.razor
new file mode 100644
index 0000000..ee23fea
--- /dev/null
+++ b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Components/App.razor
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Components/Layout/MainLayout.razor b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Components/Layout/MainLayout.razor
new file mode 100644
index 0000000..111dfdb
--- /dev/null
+++ b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Components/Layout/MainLayout.razor
@@ -0,0 +1,18 @@
+@inherits LayoutComponentBase
+
+
+
+
+
+
+
+
+ Akka.NET SqlServer CQRS Demo
+
+
+ @Body
+
+
+
+@code {
+}
\ No newline at end of file
diff --git a/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Components/Pages/Error.razor b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Components/Pages/Error.razor
new file mode 100644
index 0000000..576cc2d
--- /dev/null
+++ b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Components/Pages/Error.razor
@@ -0,0 +1,36 @@
+@page "/Error"
+@using System.Diagnostics
+
+Error
+
+Error.
+An error occurred while processing your request.
+
+@if (ShowRequestId)
+{
+
+ Request ID: @RequestId
+
+}
+
+Development Mode
+
+ Swapping to Development environment will display more detailed information about the error that occurred.
+
+
+ The Development environment shouldn't be enabled for deployed applications.
+ It can result in displaying sensitive information from exceptions to end users.
+ For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development
+ and restarting the app.
+
+
+@code{
+ [CascadingParameter]
+ private HttpContext? HttpContext { get; set; }
+
+ private string? RequestId { get; set; }
+ private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
+
+ protected override void OnInitialized() =>
+ RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
+}
diff --git a/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Components/Pages/Home.razor b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Components/Pages/Home.razor
new file mode 100644
index 0000000..2299380
--- /dev/null
+++ b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Components/Pages/Home.razor
@@ -0,0 +1,58 @@
+@page "/"
+@using CqrsSqlServer.DataModel.Entities
+@using CqrsSqlServer.DataModel
+@using Microsoft.EntityFrameworkCore
+@inject CqrsSqlServerContext DbContext
+
+Product Data
+
+ Product Data
+
+
+
+
+
+ Id
+ Name
+ Price
+ Inventory
+ Sold
+ Revenue
+ Created
+ Updated
+
+
+ @context.ProductId
+ @context.ProductName
+ @context.Price
+ @context.AllInventory
+ @context.SoldUnits
+ @context.TotalRevenue
+ @context.Created
+ @context.LastModified
+
+
+
+
+
+
+@code {
+ private ProductListing[] _products = Array.Empty();
+ private bool _loading = true;
+
+ protected override async Task OnInitializedAsync()
+ {
+ _products = await DbContext.Products.ToArrayAsync();
+ _loading = false;
+ }
+
+ private async Task RefreshCallback()
+ {
+ _loading = true;
+ StateHasChanged();
+ _products = await DbContext.Products.ToArrayAsync();
+ _loading = false;
+ StateHasChanged();
+ }
+
+}
diff --git a/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Components/Routes.razor b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Components/Routes.razor
new file mode 100644
index 0000000..d0df781
--- /dev/null
+++ b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Components/Routes.razor
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Components/_Imports.razor b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Components/_Imports.razor
new file mode 100644
index 0000000..a202814
--- /dev/null
+++ b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Components/_Imports.razor
@@ -0,0 +1,12 @@
+@using System.Net.Http
+@using System.Net.Http.Json
+@using Microsoft.AspNetCore.Components.Forms
+@using Microsoft.AspNetCore.Components.Routing
+@using Microsoft.AspNetCore.Components.Web
+@using static Microsoft.AspNetCore.Components.Web.RenderMode
+@using Microsoft.AspNetCore.Components.Web.Virtualization
+@using Microsoft.JSInterop
+@using CqrsSqlServer.Frontend
+@using CqrsSqlServer.Frontend.Components
+@using MudBlazor
+@using MudBlazor.Services
\ No newline at end of file
diff --git a/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/CqrsSqlServer.Frontend.csproj b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/CqrsSqlServer.Frontend.csproj
new file mode 100644
index 0000000..a903c9f
--- /dev/null
+++ b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/CqrsSqlServer.Frontend.csproj
@@ -0,0 +1,19 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Program.cs b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Program.cs
new file mode 100644
index 0000000..2e96bf4
--- /dev/null
+++ b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/Program.cs
@@ -0,0 +1,51 @@
+using CqrsSqlServer.DataModel;
+using CqrsSqlServer.Frontend.Components;
+using Microsoft.EntityFrameworkCore;
+using MudBlazor.Services;
+
+namespace CqrsSqlServer.Frontend;
+
+public class Program
+{
+ public static void Main(string[] args)
+ {
+ var builder = WebApplication.CreateBuilder(args);
+
+ // Add services to the container.
+ builder.Services.AddRazorComponents()
+ .AddInteractiveServerComponents();
+
+ builder.Services.AddMudServices();
+
+ var connectionString = builder.Configuration.GetConnectionString("AkkaSqlConnection");
+ if (connectionString is null)
+ throw new Exception("AkkaSqlConnection setting is missing");
+
+ builder.Services.AddDbContext(options =>
+ {
+ // disable change tracking for all implementations of this context
+ options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
+ options.UseSqlServer(connectionString);
+ });
+
+ var app = builder.Build();
+
+ // Configure the HTTP request pipeline.
+ if (!app.Environment.IsDevelopment())
+ {
+ app.UseExceptionHandler("/Error");
+ // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
+ app.UseHsts();
+ }
+
+ app.UseHttpsRedirection();
+
+ app.UseStaticFiles();
+ app.UseAntiforgery();
+
+ app.MapRazorComponents()
+ .AddInteractiveServerRenderMode();
+
+ app.Run();
+ }
+}
diff --git a/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/appsettings.Development.json b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/appsettings.Development.json
new file mode 100644
index 0000000..0c208ae
--- /dev/null
+++ b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/appsettings.json b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/appsettings.json
new file mode 100644
index 0000000..df096e7
--- /dev/null
+++ b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/appsettings.json
@@ -0,0 +1,12 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*",
+ "ConnectionStrings": {
+ "AkkaSqlConnection": "Server=localhost,1533; Database=Akka; User Id=sa; Password=yourStrong(!)Password; TrustServerCertificate=true;"
+ }
+}
diff --git a/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/wwwroot/app.css b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/wwwroot/app.css
new file mode 100644
index 0000000..2238114
--- /dev/null
+++ b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/wwwroot/app.css
@@ -0,0 +1,20 @@
+/*
+ This CSS file matches the color scheme from MudBlazor to Bootstrap when utilized for authentication.
+ The file remains available at all times for demonstration purposes,
+ but it is exclusively employed in the 'App.razor' component when authentication is enabled.
+*/
+
+.btn-primary {
+ text-transform: uppercase;
+ --bs-btn-bg: var(--mud-palette-primary) !important;
+ --bs-btn-hover-bg: var(--mud-palette-primary-darken) !important;
+}
+
+.nav-pills {
+ --bs-nav-pills-link-active-bg: var(--mud-palette-primary) !important;
+}
+
+.nav {
+ --bs-nav-link-color: var(--mud-palette-primary) !important;
+ --bs-nav-link-hover-color: var(--mud-palette-primary-darken) !important;
+}
\ No newline at end of file
diff --git a/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/wwwroot/favicon.ico b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/wwwroot/favicon.ico
new file mode 100644
index 0000000..1239223
Binary files /dev/null and b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.Frontend/wwwroot/favicon.ico differ
diff --git a/src/cqrs/cqrs-sqlserver/CqrsSqlServer.sln b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.sln
index b4d1cfe..4f7a13c 100644
--- a/src/cqrs/cqrs-sqlserver/CqrsSqlServer.sln
+++ b/src/cqrs/cqrs-sqlserver/CqrsSqlServer.sln
@@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CqrsSqlServer.Backend", "Cq
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CqrsSqlServer.DataModel", "CqrsSqlServer.DataModel\CqrsSqlServer.DataModel.csproj", "{A1B9790C-AC65-46C0-8BC5-2C4013F5245D}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CqrsSqlServer.Frontend", "CqrsSqlServer.Frontend\CqrsSqlServer.Frontend.csproj", "{D291AA52-B8AA-4A8C-A5F2-9323259DAACF}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -30,5 +32,11 @@ Global
{A1B9790C-AC65-46C0-8BC5-2C4013F5245D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A1B9790C-AC65-46C0-8BC5-2C4013F5245D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A1B9790C-AC65-46C0-8BC5-2C4013F5245D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D291AA52-B8AA-4A8C-A5F2-9323259DAACF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D291AA52-B8AA-4A8C-A5F2-9323259DAACF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D291AA52-B8AA-4A8C-A5F2-9323259DAACF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D291AA52-B8AA-4A8C-A5F2-9323259DAACF}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
EndGlobalSection
EndGlobal