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