diff --git a/Visor/Visor.sln b/Visor/Visor.sln new file mode 100644 index 0000000..08a9cf6 --- /dev/null +++ b/Visor/Visor.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.32916.344 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Visor", "Visor\Visor.csproj", "{A1073A31-9C1C-4B5F-8752-F4397F84E210}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A1073A31-9C1C-4B5F-8752-F4397F84E210}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1073A31-9C1C-4B5F-8752-F4397F84E210}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1073A31-9C1C-4B5F-8752-F4397F84E210}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1073A31-9C1C-4B5F-8752-F4397F84E210}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C59BEA9D-058E-406A-BE53-A3BC184DCF72} + EndGlobalSection +EndGlobal diff --git a/Visor/Visor/.mcp.json b/Visor/Visor/.mcp.json new file mode 100644 index 0000000..681a523 --- /dev/null +++ b/Visor/Visor/.mcp.json @@ -0,0 +1,8 @@ +{ + "servers": { + "blazorise-docs": { + "type": "http", + "url": "https://mcp.blazorise.com/mcp" + } + } +} diff --git a/Visor/Visor/App.razor b/Visor/Visor/App.razor new file mode 100644 index 0000000..033391a --- /dev/null +++ b/Visor/Visor/App.razor @@ -0,0 +1,47 @@ + + + + + + +

Sorry, there's nothing at this address.

+
+
+ + +
+@code { + private Theme theme = new() + { + BarOptions = new() + { + HorizontalHeight = "72px" + }, + ColorOptions = new() + { + Primary = "#0288D1", + Secondary = "#A65529", + Success = "#23C02E", + Info = "#9BD8FE", + Warning = "#F8B86C", + Danger = "#F95741", + Light = "#F0F0F0", + Dark = "#535353", + }, + BackgroundOptions = new() + { + Primary = "#0288D1", + Secondary = "#A65529", + Success = "#23C02E", + Info = "#9BD8FE", + Warning = "#F8B86C", + Danger = "#F95741", + Light = "#F0F0F0", + Dark = "#535353", + }, + InputOptions = new() + { + CheckColor = "#0288D1", + } + }; +} \ No newline at end of file diff --git a/Visor/Visor/Components/Layout/FooterMenu.razor b/Visor/Visor/Components/Layout/FooterMenu.razor new file mode 100644 index 0000000..231121f --- /dev/null +++ b/Visor/Visor/Components/Layout/FooterMenu.razor @@ -0,0 +1,4 @@ +@using System.Reflection + + @($"{Assembly.GetExecutingAssembly().GetName().Name} v{Assembly.GetExecutingAssembly().GetName().Version}") + \ No newline at end of file diff --git a/Visor/Visor/Components/Layout/SideMenu.razor b/Visor/Visor/Components/Layout/SideMenu.razor new file mode 100644 index 0000000..a0fde1c --- /dev/null +++ b/Visor/Visor/Components/Layout/SideMenu.razor @@ -0,0 +1,56 @@ + + + + + + + Visor + + + + + + + + + Dashboard + + + + + + + Pages + + + Simple Form + + + Simple DataGrid + + + + + + + + + + Apps + + + + Todo + + + + + + + +@code { + private bool pagesBarVisible = true; + + RenderFragment customIcon =@; +} \ No newline at end of file diff --git a/Visor/Visor/Components/Layout/ThemeColorSelector.razor b/Visor/Visor/Components/Layout/ThemeColorSelector.razor new file mode 100644 index 0000000..b23b351 --- /dev/null +++ b/Visor/Visor/Components/Layout/ThemeColorSelector.razor @@ -0,0 +1,26 @@ +
+ @foreach ( var color in ThemeColors.Items.Values ) + { +
+ @foreach ( var shade in color.Shades.Values ) + { + var temp = shade.Value; + +
+ } +
+ } +
+@code{ + [Parameter] + public string? Value { get; set; } + + [Parameter] + public EventCallback ValueChanged { get; set; } + + Task OnThemeColorSelect( string value ) + { + Value = value; + return ValueChanged.InvokeAsync(value); + } +} \ No newline at end of file diff --git a/Visor/Visor/Components/Layout/ThemeColorSelector.razor.css b/Visor/Visor/Components/Layout/ThemeColorSelector.razor.css new file mode 100644 index 0000000..0d2ad7b --- /dev/null +++ b/Visor/Visor/Components/Layout/ThemeColorSelector.razor.css @@ -0,0 +1,16 @@ +.demo-theme-color-item { + display: table-cell; + width: 36px; + height: 36px; + vertical-align: top; + text-align: center; + color: white; + cursor: pointer; +} + + .demo-theme-color-item .material-icons { + display: flex; + height: 100%; + align-items: center; + justify-content: center; + } diff --git a/Visor/Visor/Components/Layout/TopMenu.razor b/Visor/Visor/Components/Layout/TopMenu.razor new file mode 100644 index 0000000..6dd6782 --- /dev/null +++ b/Visor/Visor/Components/Layout/TopMenu.razor @@ -0,0 +1,163 @@ +@using Blazorise.Localization + + + + + + + Visor + + + + + + + + Home + + + Documentation + + + + More + + + Quick-Start Guide + + + + Usage + + + + + + + Layout + + + @if ( LayoutType == "fixed-header" ) + { + + } + Fixed Header + + + @if ( LayoutType == "fixed-header-footer-only" ) + { + + } + Fixed Header and Footer only + + + @if ( LayoutType == "sider-with-header-on-top" ) + { + + } + Sider with Header on top + + + + + + + + + + + + + @foreach ( var cultureInfo in LocalizationService!.AvailableCultures ) + { + + @if ( cultureInfo.IsNeutralCulture ) + { + @cultureInfo.EnglishName + } + else + { + @cultureInfo.Parent.EnglishName + } + + } + + + + + + Theme + + + + + Theme enabled + + + + + + + Gradient colors + + + Rounded elements + + + + + + + + + + + + + + + GitHub + + + + +@code { + protected override async Task OnInitializedAsync() + { + await SelectCulture( "en-US" ); + + await base.OnInitializedAsync(); + } + + Task SelectCulture( string name ) + { + LocalizationService!.ChangeLanguage( name ); + + return Task.CompletedTask; + } + + private bool topbarVisible = false; + + Task OnLayoutTypeChecked( string layoutType ) + { + LayoutType = layoutType; + + return LayoutTypeChanged.InvokeAsync( layoutType ); + } + + [Parameter] public EventCallback ThemeEnabledChanged { get; set; } + + [Parameter] public EventCallback ThemeGradientChanged { get; set; } + + [Parameter] public EventCallback ThemeRoundedChanged { get; set; } + + [Parameter] public EventCallback ThemeColorChanged { get; set; } + + [Parameter] public string? LayoutType { get; set; } + + [Parameter] public EventCallback LayoutTypeChanged { get; set; } + + [Inject] protected ITextLocalizerService? LocalizationService { get; set; } + + [CascadingParameter] protected Theme? Theme { get; set; } +} \ No newline at end of file diff --git a/Visor/Visor/Components/TodoApp/BaseTodoItems.cs b/Visor/Visor/Components/TodoApp/BaseTodoItems.cs new file mode 100644 index 0000000..16b2d41 --- /dev/null +++ b/Visor/Visor/Components/TodoApp/BaseTodoItems.cs @@ -0,0 +1,68 @@ +using Microsoft.AspNetCore.Components; + +namespace Visor.Components.TodoApp +{ + public abstract class BaseTodoItems : ComponentBase + { + protected Validations? validations; + + protected string? description; + + protected Filter filter = Filter.All; + + protected List todos = new() + { + new() { Description = "Buy milk" }, + new() { Description = "Call John regarding the meeting" }, + new() { Description = "Walk a dog" }, + }; + + protected IEnumerable Todos + { + get + { + var query = from t in todos select t; + + if (filter == Filter.Active) + query = from q in query where !q.Completed select q; + + if (filter == Filter.Completed) + query = from q in query where q.Completed select q; + + return query; + } + } + + protected void SetFilter(Filter filter) + { + this.filter = filter; + } + + protected void OnCheckAll(bool isChecked) + { + todos.ForEach(x => x.Completed = isChecked); + } + + protected async Task OnAddTodo() + { + if (await validations!.ValidateAll()) + { + todos.Add(new() { Description = description }); + description = null; + + await validations.ClearAll(); + } + } + + protected void OnClearCompleted() + { + todos.RemoveAll(x => x.Completed); + filter = Filter.All; + } + + protected Task OnTodoStatusChanged(bool isChecked) + { + return InvokeAsync(StateHasChanged); + } + } +} diff --git a/Visor/Visor/Components/TodoApp/Filter.cs b/Visor/Visor/Components/TodoApp/Filter.cs new file mode 100644 index 0000000..e4d2542 --- /dev/null +++ b/Visor/Visor/Components/TodoApp/Filter.cs @@ -0,0 +1,9 @@ +namespace Visor.Components.TodoApp +{ + public enum Filter + { + All, + Active, + Completed, + } +} diff --git a/Visor/Visor/Components/TodoApp/Todo.cs b/Visor/Visor/Components/TodoApp/Todo.cs new file mode 100644 index 0000000..8f28939 --- /dev/null +++ b/Visor/Visor/Components/TodoApp/Todo.cs @@ -0,0 +1,9 @@ +namespace Visor.Components.TodoApp +{ + public class Todo + { + public bool Completed { get; set; } + + public string? Description { get; set; } + } +} diff --git a/Visor/Visor/Components/TodoApp/TodoItem.razor b/Visor/Visor/Components/TodoApp/TodoItem.razor new file mode 100644 index 0000000..a1b9356 --- /dev/null +++ b/Visor/Visor/Components/TodoApp/TodoItem.razor @@ -0,0 +1,25 @@ +@if (Todo is not null) +{ + + + + + + + @Todo.Description + + + +} +@code { + Task OnCheckedChanged(bool isChecked) + { + Todo!.Completed = isChecked; + + return StatusChanged?.Invoke(isChecked) ?? Task.CompletedTask; + } + + [Parameter] public Todo? Todo { get; set; } + + [Parameter] public Func? StatusChanged { get; set; } +} \ No newline at end of file diff --git a/Visor/Visor/Components/TodoApp/TodoItems.razor b/Visor/Visor/Components/TodoApp/TodoItems.razor new file mode 100644 index 0000000..934e33e --- /dev/null +++ b/Visor/Visor/Components/TodoApp/TodoItems.razor @@ -0,0 +1,57 @@ +@inherits BaseTodoItems + + + + + + Todo List + + + + + All + + + + + + + + + + + + + + + + + + + + @foreach ( var todo in Todos ) + { + + } + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Visor/Visor/GlobalUsings.cs b/Visor/Visor/GlobalUsings.cs new file mode 100644 index 0000000..be71087 --- /dev/null +++ b/Visor/Visor/GlobalUsings.cs @@ -0,0 +1,2 @@ +global using Blazorise; +global using Blazorise.DataGrid; diff --git a/Visor/Visor/Layouts/MainLayout.razor b/Visor/Visor/Layouts/MainLayout.razor new file mode 100644 index 0000000..b0e5a37 --- /dev/null +++ b/Visor/Visor/Layouts/MainLayout.razor @@ -0,0 +1,69 @@ +@using Visor.Components.Layout + +@inherits LayoutComponentBase + + +@if ( layoutType == "fixed-header" ) +{ + + + + + + + + + + + + @Body + + + +} +else if ( layoutType == "fixed-header-footer-only" ) +{ + + + + + + @Body + + + + + +} +else if ( layoutType == "sider-with-header-on-top" ) +{ + + + + + + + + + + + + + @Body + + + + +} \ No newline at end of file diff --git a/Visor/Visor/Layouts/MainLayout.razor.cs b/Visor/Visor/Layouts/MainLayout.razor.cs new file mode 100644 index 0000000..4b2de2e --- /dev/null +++ b/Visor/Visor/Layouts/MainLayout.razor.cs @@ -0,0 +1,89 @@ +using Blazorise; +using Blazorise.Localization; + +using Microsoft.AspNetCore.Components; + +namespace Visor.Layouts +{ + public partial class MainLayout + { + [Inject] protected ITextLocalizerService? LocalizationService { get; set; } + + [CascadingParameter] protected Theme? Theme { get; set; } + + protected string layoutType = "fixed-header"; + + protected override async Task OnInitializedAsync() + { + await SelectCulture("en-US"); + + await base.OnInitializedAsync(); + } + + private Task SelectCulture(string name) + { + LocalizationService!.ChangeLanguage(name); + + return Task.CompletedTask; + } + + Task OnThemeEnabledChanged(bool value) + { + if (Theme is null) + return Task.CompletedTask; + + Theme.Enabled = value; + + return InvokeAsync(Theme.ThemeHasChanged); + } + + Task OnThemeGradientChanged(bool value) + { + if (Theme is null) + return Task.CompletedTask; + + Theme.IsGradient = value; + + return InvokeAsync(Theme.ThemeHasChanged); + } + + Task OnThemeRoundedChanged(bool value) + { + if (Theme is null) + return Task.CompletedTask; + + Theme.IsRounded = value; + + return InvokeAsync(Theme.ThemeHasChanged); + } + + Task OnThemeColorChanged(string value) + { + if (Theme is null) + return Task.CompletedTask; + + Theme.ColorOptions ??= new(); + + Theme.BackgroundOptions ??= new(); + + Theme.TextColorOptions ??= new(); + + Theme.ColorOptions.Primary = value; + Theme.BackgroundOptions.Primary = value; + Theme.TextColorOptions.Primary = value; + + Theme.InputOptions ??= new(); + + Theme.InputOptions.CheckColor = value; + Theme.InputOptions.SliderColor = value; + + Theme.SpinKitOptions ??= new(); + + Theme.SpinKitOptions.Color = value; + + return InvokeAsync(Theme.ThemeHasChanged); + } + + + } +} \ No newline at end of file diff --git a/Visor/Visor/Pages/Dashboard.razor b/Visor/Visor/Pages/Dashboard.razor new file mode 100644 index 0000000..b735c21 --- /dev/null +++ b/Visor/Visor/Pages/Dashboard.razor @@ -0,0 +1,36 @@ +@page "/" +@inject IVersionProvider VersionProvider +Blazorise + + + Blazorise is a component library built on top of Blazor and CSS frameworks like Bootstrap, FluentUI2, Tailwind, Bulma, Ant Design, and Material. It can be used to build responsive, single-page web applications. + + + + + This is a Blazorise Starting Template allowing you to quickly get started building your project! + + + + The following Blazorise packages have been installed for you: + + + + Blazorise @($"v{VersionProvider.MilestoneVersion}") + The Blazorise Bootstrap5 Provider + The Blazorise FontAwesome Icon Provider + The Blazorise DataGrid extension + + + + However Blazorise has many more extensions at your disposal. + You can find them here. + + + + Please visit the official Blazorise Demo for component examples. + + + Please visit the official Blazorise Documentation to learn more about the available components. + + diff --git a/Visor/Visor/Pages/Error.cshtml b/Visor/Visor/Pages/Error.cshtml new file mode 100644 index 0000000..91c9f5d --- /dev/null +++ b/Visor/Visor/Pages/Error.cshtml @@ -0,0 +1,37 @@ +@page +@model Visor.Pages.ErrorModel + + + + + + + + Error + + + +

Error.

+

An error occurred while processing your request.

+ + @if (Model.ShowRequestId) + { +

+ Request ID: @Model.RequestId +

+ } + +

Development Mode

+

+ Swapping to the Development environment displays 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. +

+ + + + diff --git a/Visor/Visor/Pages/Error.cshtml.cs b/Visor/Visor/Pages/Error.cshtml.cs new file mode 100644 index 0000000..35f5504 --- /dev/null +++ b/Visor/Visor/Pages/Error.cshtml.cs @@ -0,0 +1,27 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using System.Diagnostics; + +namespace Visor.Pages +{ + [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] + [IgnoreAntiforgeryToken] + public class ErrorModel : PageModel + { + public string? RequestId { get; set; } + + public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + + private readonly ILogger _logger; + + public ErrorModel(ILogger logger) + { + _logger = logger; + } + + public void OnGet() + { + RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; + } + } +} diff --git a/Visor/Visor/Pages/SimpleDataGridPage.razor b/Visor/Visor/Pages/SimpleDataGridPage.razor new file mode 100644 index 0000000..f6d6082 --- /dev/null +++ b/Visor/Visor/Pages/SimpleDataGridPage.razor @@ -0,0 +1,75 @@ +@page "/simple-datagrid" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@code { + private List data = new() + { + new("Harry Potter and the Sorcerer's Stone", "J.K. Rowling","9780590353427", new(1997,6,26), "Scholastic Press" ), + new("To Kill a Mockingbird", "Harper Lee", "9780061120084", new(1960,7,11), "J.B. Lippincott & Co." ), + new("The Catcher in the Rye", "J.D. Salinger","9780316769488", new(1951,7,16), "Little, Brown and Company" ), + new("The Great Gatsby", "F. Scott Fitzgerald","9780743273565", new(1925,4,10), "Charles Scribner's Sons" ), + new("The Lord of the Rings", "J.R.R. Tolkien", "9780544003415", new(1954,7,29), "George Allen & Unwin"), + new("The Hobbit", "J.R.R. Tolkien", "9780547928227", new(1937,9,21), "George Allen & Unwin"), + new("The Chronicles of Narnia: The Lion, the Witch, and the Wardrobe", "C.S. Lewis", "9780064471073", new(1950,10,16), "Geoffrey Bles"), + new("Animal Farm", "George Orwell", "978451219811", new(1945,8,17), "Secker & Warburg"), + new("The Adventures of Huckleberry Finn", "Mark Twain", "9780142437254", new(1884,12,10), "Chatto & Windus"), + new("The Diary of a Young Girl", "Anne Frank", "9780385473788", new(1947,6,25), "Doubleday"), + new("The Hunger Games", "Suzanne Collins", "9780439023481", new(2008,9,14), "Scholastic Press"), + new("The Maze Runner", "James Dashner", "9780385737965", new(2009,10,6), "Delacorte Press"), + new("The Secret Life of Bees", "Sue Monk Kidd", "9780670034852", new(2002,5,5), "Viking Press"), + new("The Strange Case of Dr. Jekyll and Mr. Hyde", "Robert Louis Stevenson", "9781593080171", new(1886,1,5), "Longmans, Green and Co"), + new("Harry Potter and the Chamber of Secrets", "J.K. Rowling", "9780439064866", new(1998,7,2), "Scholastic Press"), + new("Harry Potter and the Prisoner of Azkaban", "J.K. Rowling", "9780439136365", new(1999,7,8), "Scholastic Press"), + new("Catching Fire", "Suzanne Collins", "9780439023498", new(2009,9,1), "Scholastic Press"), + new("Mockingjay", "Suzanne Collins", "9780439023528", new(2010,8,24), "Scholastic Press"), + new("The Children of Hurin", "J.R.R. Tolkien", "9780544003422", new(2007,4,17), "Houghton Mifflin Harcourt"), + new("Beren and Luthien", "J.R.R. Tolkien", "9780544116813", new(2017,5,23), "Houghton Mifflin Harcourt") + }; + + private record Book( string Title, string Author, string Isbn, DateOnly PublicationDate, string Publisher ); + + +} \ No newline at end of file diff --git a/Visor/Visor/Pages/SimpleFormPage.razor b/Visor/Visor/Pages/SimpleFormPage.razor new file mode 100644 index 0000000..8a607bc --- /dev/null +++ b/Visor/Visor/Pages/SimpleFormPage.razor @@ -0,0 +1,124 @@ +@page "/simple-form" + + + + + Basic Example + + + + + + Email address + + We'll never share your email with anyone else. + + + + + Password + + + + + + Remember me? + + + + + + + + + + Horizontal Form + + + + + + Email address + + + + + + + + Password + + + + + + + + Re Password + + + + + + + + Remember me? + + + + + + + + + + + + +@code { + Validations? validationsBasicExampleRef; + Validations? validationsHorizontalFormRef; + string? password; + + void ValidatePassword( ValidatorEventArgs e ) + { + e.Status = Convert.ToString( e.Value )?.Length >= 6 ? ValidationStatus.Success : ValidationStatus.Error; + } + + void ValidatePassword2( ValidatorEventArgs e ) + { + var password2 = Convert.ToString( e.Value ); + + if ( password2?.Length < 6 ) + { + e.Status = ValidationStatus.Error; + e.ErrorText = "Password must be at least 6 characters long!"; + } + else if ( password2 != password ) + { + e.Status = ValidationStatus.Error; + } + else + { + e.Status = ValidationStatus.Success; + } + } + + async Task SubmitBasicExample() + { + if ( await validationsBasicExampleRef!.ValidateAll() ) + { + await validationsBasicExampleRef.ClearAll(); + } + } + + async Task SubmitHorizontalForm() + { + if ( await validationsHorizontalFormRef!.ValidateAll() ) + { + await validationsHorizontalFormRef.ClearAll(); + } + } + + +} \ No newline at end of file diff --git a/Visor/Visor/Pages/TodoAppPage.razor b/Visor/Visor/Pages/TodoAppPage.razor new file mode 100644 index 0000000..9a9ab4f --- /dev/null +++ b/Visor/Visor/Pages/TodoAppPage.razor @@ -0,0 +1,3 @@ +@using Visor.Components.TodoApp +@page "/apps/todo" + \ No newline at end of file diff --git a/Visor/Visor/Pages/_Host.cshtml b/Visor/Visor/Pages/_Host.cshtml new file mode 100644 index 0000000..0156356 --- /dev/null +++ b/Visor/Visor/Pages/_Host.cshtml @@ -0,0 +1,8 @@ +@page "/" +@namespace Visor.Pages +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@{ + Layout = "_Layout"; +} + + diff --git a/Visor/Visor/Pages/_Layout.cshtml b/Visor/Visor/Pages/_Layout.cshtml new file mode 100644 index 0000000..3aeec43 --- /dev/null +++ b/Visor/Visor/Pages/_Layout.cshtml @@ -0,0 +1,41 @@ +@using Microsoft.AspNetCore.Components.Web +@namespace Visor.Pages +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers + + + + + + + Visor + + + + + + + + + + + + + + + + @RenderBody() + +
+ + An error has occurred. This application may no longer respond until reloaded. + + + An unhandled exception has occurred. See browser dev tools for details. + + Reload + 🗙 +
+ + + + diff --git a/Visor/Visor/Program.cs b/Visor/Visor/Program.cs new file mode 100644 index 0000000..093540f --- /dev/null +++ b/Visor/Visor/Program.cs @@ -0,0 +1,41 @@ +using Blazorise.Bootstrap5; +using Blazorise.Icons.FontAwesome; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +builder.Services.AddRazorPages(); +builder.Services.AddServerSideBlazor(); + +AddBlazorise(builder.Services); + +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.UseRouting(); + +app.MapBlazorHub(); +app.MapFallbackToPage("/_Host"); + +app.Run(); + + +void AddBlazorise(IServiceCollection services) +{ + services + .AddBlazorise(); + services + .AddBootstrap5Providers() + .AddFontAwesomeIcons(); +} diff --git a/Visor/Visor/Properties/launchSettings.json b/Visor/Visor/Properties/launchSettings.json new file mode 100644 index 0000000..a59427d --- /dev/null +++ b/Visor/Visor/Properties/launchSettings.json @@ -0,0 +1,28 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:61646", + "sslPort": 44332 + } + }, + "profiles": { + "Visor": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7297;http://localhost:5255", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/Visor/Visor/Visor.csproj b/Visor/Visor/Visor.csproj new file mode 100644 index 0000000..8cab721 --- /dev/null +++ b/Visor/Visor/Visor.csproj @@ -0,0 +1,29 @@ + + + + net8.0 + enable + enable + 2.2.1 + Megabit + Megabit + + This is a Blazorise Template for a Blazor Server Application. + Blazorise is a component library built on top of Blazor and CSS frameworks like Bootstrap, FluentUI2, Tailwind, Bulma and Material. + + Copyright 2018-2026 Megabit + + + + + + + + + + + + + + + diff --git a/Visor/Visor/_Imports.razor b/Visor/Visor/_Imports.razor new file mode 100644 index 0000000..e467b30 --- /dev/null +++ b/Visor/Visor/_Imports.razor @@ -0,0 +1,12 @@ +@using System.Net.Http +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components.Authorization +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.Web.Virtualization +@using Microsoft.JSInterop + +@using Visor +@using Blazorise +@using Blazorise.DataGrid diff --git a/Visor/Visor/appsettings.Development.json b/Visor/Visor/appsettings.Development.json new file mode 100644 index 0000000..770d3e9 --- /dev/null +++ b/Visor/Visor/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "DetailedErrors": true, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/Visor/Visor/appsettings.json b/Visor/Visor/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/Visor/Visor/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/Visor/Visor/wwwroot/brand-logo.png b/Visor/Visor/wwwroot/brand-logo.png new file mode 100644 index 0000000..3746003 Binary files /dev/null and b/Visor/Visor/wwwroot/brand-logo.png differ diff --git a/Visor/Visor/wwwroot/css/blazor-ui.css b/Visor/Visor/wwwroot/css/blazor-ui.css new file mode 100644 index 0000000..db706f5 --- /dev/null +++ b/Visor/Visor/wwwroot/css/blazor-ui.css @@ -0,0 +1,28 @@ +#blazor-error-ui { + background: #ffffe0; + bottom: 0; + box-shadow: 0 -1px 2px rgba(0, 0, 0, .2); + display: none; + left: 0; + padding: .6rem 1.25rem .7rem 1.25rem; + position: fixed; + right: 0; + z-index: 1000 +} + +#blazor-error-ui .dismiss { + cursor: pointer; + position: absolute; + right: .75rem; + top: .5rem +} + +.blazor-error-boundary { + background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; + padding: 1rem 1rem 1rem 3.7rem; + color: white; +} + +.blazor-error-boundary::after { + content: "An error has occurred." +} \ No newline at end of file diff --git a/Visor/Visor/wwwroot/favicon.ico b/Visor/Visor/wwwroot/favicon.ico new file mode 100644 index 0000000..f47a486 Binary files /dev/null and b/Visor/Visor/wwwroot/favicon.ico differ diff --git a/lsSoft.slnx b/lsSoft.slnx index 7413f25..3d55c97 100644 --- a/lsSoft.slnx +++ b/lsSoft.slnx @@ -5,6 +5,7 @@ +