diff --git a/.idea/.idea.ProjectPiston/.idea/.gitignore b/.idea/.idea.ProjectPiston/.idea/.gitignore new file mode 100644 index 0000000..646eeec --- /dev/null +++ b/.idea/.idea.ProjectPiston/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/contentModel.xml +/projectSettingsUpdater.xml +/.idea.ProjectPiston.iml +/modules.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.ProjectPiston/.idea/encodings.xml b/.idea/.idea.ProjectPiston/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/.idea/.idea.ProjectPiston/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/.idea.ProjectPiston/.idea/indexLayout.xml b/.idea/.idea.ProjectPiston/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/.idea/.idea.ProjectPiston/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.ProjectPiston/.idea/vcs.xml b/.idea/.idea.ProjectPiston/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/.idea.ProjectPiston/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..c796a76 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,28 @@ + + + + net9.0 + + latest + Mathijs Nabbe + 2025 + https://github.com/MathijsNabbe/ProjectPiston + git + + enable + enable + + true + + true + Default + latest + latest + + + true + snupkg + false + + + diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 0000000..5bf0ae3 --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,11 @@ + + + + true + false + + + + + + \ No newline at end of file diff --git a/ProjectPiston.sln b/ProjectPiston.sln new file mode 100644 index 0000000..5da0001 --- /dev/null +++ b/ProjectPiston.sln @@ -0,0 +1,45 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "solution", "solution", "{D00066FA-CC5C-49D6-B980-ECD1DC2A6708}" + ProjectSection(SolutionItems) = preProject + .gitignore = .gitignore + Directory.Build.props = Directory.Build.props + Directory.Packages.props = Directory.Packages.props + README.md = README.md + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{BD135F67-D69C-499A-9610-B09689B86F53}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "bundles", "bundles", "{58BAB8E5-8400-4920-8B82-1720F38DDDD4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectPiston.Server", "src\bundles\ProjectPiston.Server\ProjectPiston.Server.csproj", "{D0399D68-8120-4128-815C-157E05146182}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectPiston.Client", "src\bundles\ProjectPiston.Client\ProjectPiston.Client.csproj", "{A25DD5CE-BECB-4275-A499-F60309FDCF6E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {58BAB8E5-8400-4920-8B82-1720F38DDDD4} = {BD135F67-D69C-499A-9610-B09689B86F53} + {D0399D68-8120-4128-815C-157E05146182} = {58BAB8E5-8400-4920-8B82-1720F38DDDD4} + {A25DD5CE-BECB-4275-A499-F60309FDCF6E} = {58BAB8E5-8400-4920-8B82-1720F38DDDD4} + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D0399D68-8120-4128-815C-157E05146182}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D0399D68-8120-4128-815C-157E05146182}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D0399D68-8120-4128-815C-157E05146182}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D0399D68-8120-4128-815C-157E05146182}.Release|Any CPU.Build.0 = Release|Any CPU + {A25DD5CE-BECB-4275-A499-F60309FDCF6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A25DD5CE-BECB-4275-A499-F60309FDCF6E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A25DD5CE-BECB-4275-A499-F60309FDCF6E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A25DD5CE-BECB-4275-A499-F60309FDCF6E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/src/bundles/ProjectPiston.Client/Components/App.razor b/src/bundles/ProjectPiston.Client/Components/App.razor new file mode 100644 index 0000000..c3ab106 --- /dev/null +++ b/src/bundles/ProjectPiston.Client/Components/App.razor @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/bundles/ProjectPiston.Client/Components/Layout/MainLayout.razor b/src/bundles/ProjectPiston.Client/Components/Layout/MainLayout.razor new file mode 100644 index 0000000..119dfac --- /dev/null +++ b/src/bundles/ProjectPiston.Client/Components/Layout/MainLayout.razor @@ -0,0 +1,103 @@ +@inherits LayoutComponentBase + + + + + + + + + Application + + + + + + + + + @Body + + + + +
+ An unhandled error has occurred. + Reload + 🗙 +
+ +@code { + private bool _drawerOpen = true; + private bool _isDarkMode = true; + private MudTheme? _theme = null; + + protected override void OnInitialized() + { + base.OnInitialized(); + + _theme = new() + { + PaletteLight = _lightPalette, + PaletteDark = _darkPalette, + LayoutProperties = new LayoutProperties() + }; + } + + private void DrawerToggle() + { + _drawerOpen = !_drawerOpen; + } + + private void DarkModeToggle() + { + _isDarkMode = !_isDarkMode; + } + + private readonly PaletteLight _lightPalette = new() + { + Black = "#110e2d", + AppbarText = "#424242", + AppbarBackground = "rgba(255,255,255,0.8)", + DrawerBackground = "#ffffff", + GrayLight = "#e8e8e8", + GrayLighter = "#f9f9f9", + }; + + private readonly PaletteDark _darkPalette = new() + { + Primary = "#7e6fff", + Surface = "#1e1e2d", + Background = "#1a1a27", + BackgroundGray = "#151521", + AppbarText = "#92929f", + AppbarBackground = "rgba(26,26,39,0.8)", + DrawerBackground = "#1a1a27", + ActionDefault = "#74718e", + ActionDisabled = "#9999994d", + ActionDisabledBackground = "#605f6d4d", + TextPrimary = "#b2b0bf", + TextSecondary = "#92929f", + TextDisabled = "#ffffff33", + DrawerIcon = "#92929f", + DrawerText = "#92929f", + GrayLight = "#2a2833", + GrayLighter = "#1e1e2d", + Info = "#4a86ff", + Success = "#3dcb6c", + Warning = "#ffb545", + Error = "#ff3f5f", + LinesDefault = "#33323e", + TableLines = "#33323e", + Divider = "#292838", + OverlayLight = "#1e1e2d80", + }; + + public string DarkLightModeButtonIcon => _isDarkMode switch + { + true => Icons.Material.Rounded.AutoMode, + false => Icons.Material.Outlined.DarkMode, + }; +} + + diff --git a/src/bundles/ProjectPiston.Client/Components/Layout/NavMenu.razor b/src/bundles/ProjectPiston.Client/Components/Layout/NavMenu.razor new file mode 100644 index 0000000..3f08809 --- /dev/null +++ b/src/bundles/ProjectPiston.Client/Components/Layout/NavMenu.razor @@ -0,0 +1,10 @@ + + + Home + Counter + + Weather + + + + diff --git a/src/bundles/ProjectPiston.Client/Components/Pages/Counter.razor b/src/bundles/ProjectPiston.Client/Components/Pages/Counter.razor new file mode 100644 index 0000000..db95bf3 --- /dev/null +++ b/src/bundles/ProjectPiston.Client/Components/Pages/Counter.razor @@ -0,0 +1,18 @@ +@page "/counter" + +Counter + +Counter + +Current count: @currentCount + +Click me + +@code { + private int currentCount = 0; + + private void IncrementCount() + { + currentCount++; + } +} diff --git a/src/bundles/ProjectPiston.Client/Components/Pages/Error.razor b/src/bundles/ProjectPiston.Client/Components/Pages/Error.razor new file mode 100644 index 0000000..576cc2d --- /dev/null +++ b/src/bundles/ProjectPiston.Client/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/bundles/ProjectPiston.Client/Components/Pages/Home.razor b/src/bundles/ProjectPiston.Client/Components/Pages/Home.razor new file mode 100644 index 0000000..6aaa2a4 --- /dev/null +++ b/src/bundles/ProjectPiston.Client/Components/Pages/Home.razor @@ -0,0 +1,59 @@ +@page "/" + +Home + +Hello, world! +Welcome to your new app, powered by MudBlazor and the .NET 9 Template! + + + You can find documentation and examples on our website here: + + www.mudblazor.com + + + +
+Interactivity in this Template +
+ + When you opt for the "Global" Interactivity Location,
+ the render modes are defined in App.razor and consequently apply to all child components.
+ In this case, providers are globally set in the MainLayout.
+
+ On the other hand, if you choose the "Per page/component" Interactivity Location,
+ it is necessary to include the
+
+ <MudPopoverProvider />
+ <MudDialogProvider />
+ <MudSnackbarProvider />
+
+ components on every interactive page.
+
+ If a render mode is not specified for a page, it defaults to Server-Side Rendering (SSR),
+ similar to this page. While MudBlazor allows pages to be rendered in SSR,
+ please note that interactive features, such as buttons and dropdown menus, will not be functional. +
+ +
+What's New in Blazor with the Release of .NET 9 +
+ +Prerendering + + If you're exploring the features of .NET 9 Blazor,
you might be pleasantly surprised to learn that each page is prerendered on the server,
regardless of the selected render mode.

+ This means that you'll need to inject all necessary services on the server,
even when opting for the wasm (WebAssembly) render mode.

+ This prerendering functionality is crucial to ensuring that WebAssembly mode feels fast and responsive,
especially when it comes to initial page load times.

+ For more information on how to detect prerendering and leverage the RenderContext, you can refer to the following link: + + More details + +
+ +
+InteractiveAuto + + A discussion on how to achieve this can be found here: + + More details + + diff --git a/src/bundles/ProjectPiston.Client/Components/Pages/Weather.razor b/src/bundles/ProjectPiston.Client/Components/Pages/Weather.razor new file mode 100644 index 0000000..3ffd7d8 --- /dev/null +++ b/src/bundles/ProjectPiston.Client/Components/Pages/Weather.razor @@ -0,0 +1,60 @@ +@page "/weather" + + + +Weather + +Weather forecast +This component demonstrates fetching data from the server. + +@if (forecasts == null) +{ + +} +else +{ + + + Date + Temp. (C) + Temp. (F) + Summary + + + @context.Date + @context.TemperatureC + @context.TemperatureF + @context.Summary + + + + + +} + +@code { + private WeatherForecast[]? forecasts; + + protected override async Task OnInitializedAsync() + { + // Simulate asynchronous loading to demonstrate a loading indicator + await Task.Delay(500); + + var startDate = DateOnly.FromDateTime(DateTime.Now); + var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; + forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = startDate.AddDays(index), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = summaries[Random.Shared.Next(summaries.Length)] + }).ToArray(); + } + + private class WeatherForecast + { + public DateOnly Date { get; set; } + public int TemperatureC { get; set; } + public string? Summary { get; set; } + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + } +} diff --git a/src/bundles/ProjectPiston.Client/Components/Routes.razor b/src/bundles/ProjectPiston.Client/Components/Routes.razor new file mode 100644 index 0000000..77738f4 --- /dev/null +++ b/src/bundles/ProjectPiston.Client/Components/Routes.razor @@ -0,0 +1,7 @@ +@using ProjectPiston.Client.Components.Layout + + + + + + diff --git a/src/bundles/ProjectPiston.Client/Components/_Imports.razor b/src/bundles/ProjectPiston.Client/Components/_Imports.razor new file mode 100644 index 0000000..76005b2 --- /dev/null +++ b/src/bundles/ProjectPiston.Client/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 MudBlazor +@using MudBlazor.Services +@using ProjectPiston.Client +@using ProjectPiston.Client.Components diff --git a/src/bundles/ProjectPiston.Client/Program.cs b/src/bundles/ProjectPiston.Client/Program.cs new file mode 100644 index 0000000..5232932 --- /dev/null +++ b/src/bundles/ProjectPiston.Client/Program.cs @@ -0,0 +1,32 @@ +using MudBlazor.Services; +using ProjectPiston.Client.Components; + +var builder = WebApplication.CreateBuilder(args); + +// Add MudBlazor services +builder.Services.AddMudServices(); + +// Add services to the container. +builder.Services.AddRazorComponents() + .AddInteractiveServerComponents(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (!app.Environment.IsDevelopment()) +{ + app.UseExceptionHandler("/Error", createScopeForErrors: true); + // 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.UseAntiforgery(); + +app.MapStaticAssets(); +app.MapRazorComponents() + .AddInteractiveServerRenderMode(); + +app.Run(); diff --git a/src/bundles/ProjectPiston.Client/ProjectPiston.Client.csproj b/src/bundles/ProjectPiston.Client/ProjectPiston.Client.csproj new file mode 100644 index 0000000..4849ee5 --- /dev/null +++ b/src/bundles/ProjectPiston.Client/ProjectPiston.Client.csproj @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/bundles/ProjectPiston.Client/Properties/launchSettings.json b/src/bundles/ProjectPiston.Client/Properties/launchSettings.json new file mode 100644 index 0000000..cb60b44 --- /dev/null +++ b/src/bundles/ProjectPiston.Client/Properties/launchSettings.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5153", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7017;http://localhost:5153", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/bundles/ProjectPiston.Client/appsettings.Development.json b/src/bundles/ProjectPiston.Client/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/src/bundles/ProjectPiston.Client/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/bundles/ProjectPiston.Client/appsettings.json b/src/bundles/ProjectPiston.Client/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/src/bundles/ProjectPiston.Client/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/src/bundles/ProjectPiston.Client/wwwroot/favicon.ico b/src/bundles/ProjectPiston.Client/wwwroot/favicon.ico new file mode 100644 index 0000000..1239223 Binary files /dev/null and b/src/bundles/ProjectPiston.Client/wwwroot/favicon.ico differ diff --git a/src/bundles/ProjectPiston.Server/Program.cs b/src/bundles/ProjectPiston.Server/Program.cs new file mode 100644 index 0000000..d5e0ef3 --- /dev/null +++ b/src/bundles/ProjectPiston.Server/Program.cs @@ -0,0 +1,41 @@ +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi +builder.Services.AddOpenApi(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.MapOpenApi(); +} + +app.UseHttpsRedirection(); + +var summaries = new[] +{ + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" +}; + +app.MapGet("/weatherforecast", () => + { + var forecast = Enumerable.Range(1, 5).Select(index => + new WeatherForecast + ( + DateOnly.FromDateTime(DateTime.Now.AddDays(index)), + Random.Shared.Next(-20, 55), + summaries[Random.Shared.Next(summaries.Length)] + )) + .ToArray(); + return forecast; + }) + .WithName("GetWeatherForecast"); + +app.Run(); + +record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) +{ + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); +} \ No newline at end of file diff --git a/src/bundles/ProjectPiston.Server/ProjectPiston.Server.csproj b/src/bundles/ProjectPiston.Server/ProjectPiston.Server.csproj new file mode 100644 index 0000000..94b8de3 --- /dev/null +++ b/src/bundles/ProjectPiston.Server/ProjectPiston.Server.csproj @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/bundles/ProjectPiston.Server/ProjectPiston.Server.http b/src/bundles/ProjectPiston.Server/ProjectPiston.Server.http new file mode 100644 index 0000000..78543c3 --- /dev/null +++ b/src/bundles/ProjectPiston.Server/ProjectPiston.Server.http @@ -0,0 +1,6 @@ +@ProjectPiston.Server_HostAddress = http://localhost:5256 + +GET {{ProjectPiston.Server_HostAddress}}/weatherforecast/ +Accept: application/json + +### diff --git a/src/bundles/ProjectPiston.Server/Properties/launchSettings.json b/src/bundles/ProjectPiston.Server/Properties/launchSettings.json new file mode 100644 index 0000000..1b8ded4 --- /dev/null +++ b/src/bundles/ProjectPiston.Server/Properties/launchSettings.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://localhost:5256", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "https://localhost:7075;http://localhost:5256", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/bundles/ProjectPiston.Server/appsettings.Development.json b/src/bundles/ProjectPiston.Server/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/src/bundles/ProjectPiston.Server/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/bundles/ProjectPiston.Server/appsettings.json b/src/bundles/ProjectPiston.Server/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/src/bundles/ProjectPiston.Server/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +}