diff --git a/Server/Components/App.razor b/Server/Components/App.razor index 1fc4de1..8565904 100644 --- a/Server/Components/App.razor +++ b/Server/Components/App.razor @@ -9,6 +9,11 @@ + + + + + diff --git a/Server/Components/Dialogs/AddressSelector.razor b/Server/Components/Dialogs/AddressSelector.razor new file mode 100644 index 0000000..fda9d62 --- /dev/null +++ b/Server/Components/Dialogs/AddressSelector.razor @@ -0,0 +1,22 @@ +@using Server.Data +@using Server.Model +@using Address = Server.Model.Address + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Server/Components/Dialogs/AddressSelector.razor.cs b/Server/Components/Dialogs/AddressSelector.razor.cs new file mode 100644 index 0000000..0b318ca --- /dev/null +++ b/Server/Components/Dialogs/AddressSelector.razor.cs @@ -0,0 +1,85 @@ +using Blazorise; +using Microsoft.AspNetCore.Components; +using Server.Data; +using Address = Server.Model.Address; + +namespace Server.Components.Dialogs +{ + public partial class AddressSelector : ComponentBase + { + #region Dependencies + + [Inject] + private IModalService ModalService { get; set; } = null!; + + #endregion + + #region Parameters + + /// + /// Gets or sets the delegate that will be invoked when an address is selected. + /// + /// + /// This property expects a delegate where the input parameter is an + /// and the return type is a . It allows customization of what should happen when a user selects an address + /// from the AddressSelector component. + /// + [Parameter] + public Func? OnSelected { get; set; } + + #endregion + + #region Private Properties + + private Address? SelectedCustomer { get; set; } + + #endregion + + #region Override SetParametersAsync + + //// + public override async Task SetParametersAsync(ParameterView parameters) + { + parameters.SetParameterProperties(this); + await CustomerData.LoadAsync(); + await base.SetParametersAsync(ParameterView.Empty); + } + + #endregion + + #region Public Method ShowAsync + + /// + /// Displays the AddressSelector component as a modal dialog asynchronously. + /// + /// The service used to show the modal dialog. + /// The callback to invoke when an address is selected. + /// + /// A Task that represents the asynchronous operation of showing the modal dialog. + /// + public static Task ShowAsync(IModalService modalService, Func onSelected) + { + return modalService.Show(builder => { builder.Add(x => x.OnSelected, onSelected); }); + } + + #endregion + + #region Private Method SelectedAsync + + /// + /// Handles the selection of an address asynchronously. + /// Invokes the OnSelected callback with the selected address + /// and hides the modal service upon completion. + /// + /// + /// A Task that represents the asynchronous operation. + /// + private async Task SelectedAsync() + { + if (SelectedCustomer != null && OnSelected != null) await OnSelected.Invoke(SelectedCustomer); + await ModalService.Hide(); + } + + #endregion + } +} \ No newline at end of file diff --git a/Server/Components/Pages/InvoicePage.razor b/Server/Components/Pages/InvoicePage.razor index ad49087..985ba9c 100644 --- a/Server/Components/Pages/InvoicePage.razor +++ b/Server/Components/Pages/InvoicePage.razor @@ -1,4 +1,5 @@ @page "/edit/{InvoiceId}" +@using Server.Data @using Server.Model @rendermode InteractiveServer @@ -33,6 +34,27 @@ +
+ +@if (Invoice.Customer != null) +{ +
+
+
@Invoice.Customer.Name
+

+ @Invoice.Customer.Name2
+ @Invoice.Customer.Street
+ @Invoice.Customer.Zip - @Invoice.Customer.City
+ @Invoice.Customer.Phone +

+
+
+} + + + +
+
@@ -83,4 +105,6 @@
-} \ No newline at end of file +} + + \ No newline at end of file diff --git a/Server/Components/Pages/InvoicePage.razor.cs b/Server/Components/Pages/InvoicePage.razor.cs index 542eb2f..1268239 100644 --- a/Server/Components/Pages/InvoicePage.razor.cs +++ b/Server/Components/Pages/InvoicePage.razor.cs @@ -1,7 +1,9 @@ -using Microsoft.AspNetCore.Components; +using Blazorise; +using Microsoft.AspNetCore.Components; using QuestPDF; using QuestPDF.Fluent; using QuestPDF.Infrastructure; +using Server.Components.Dialogs; using Server.Data; using Server.Model; @@ -11,6 +13,9 @@ namespace Server.Components.Pages { #region Dependencies + [Inject] + private IModalService ModalService { get; set; } = null!; + [Inject] private NavigationManager NavigationManager { get; set; } = null!; @@ -18,6 +23,13 @@ namespace Server.Components.Pages #region Parameters + /// + /// Gets or sets the identifier for the invoice. + /// + /// + /// This property is used to uniquely identify an invoice. + /// It is a nullable string which allows handling cases where no invoice ID is provided. + /// [Parameter] public string? InvoiceId { get; set; } @@ -25,10 +37,10 @@ namespace Server.Components.Pages #region Private Properties - private InvoiceModel Invoice { get; set; } = new(); - private string? AlertMessage { get; set; } + private InvoiceModel Invoice { get; set; } = new(); + #endregion #region Override SetParametersAsync @@ -44,7 +56,7 @@ namespace Server.Components.Pages NavigationManager.NavigateTo("/"); return; } - + // Existing var invoice = await InvoiceData.LoadAsync(InvoiceId); if (invoice == null) @@ -143,11 +155,24 @@ namespace Server.Components.Pages private async Task SaveInvoiceAsync() { AlertMessage = null; - + await InvoiceData.SaveAsync(Invoice); NavigationManager.NavigateTo("/invoices"); } #endregion + + #region Private Method SelectCustomerAsync + + private async Task SelectCustomerAsync() + { + await AddressSelector.ShowAsync(ModalService, async address => + { + Invoice.Customer = address; + await InvokeAsync(StateHasChanged); + }); + } + + #endregion } } \ No newline at end of file diff --git a/Server/Components/_Imports.razor b/Server/Components/_Imports.razor index da10e9f..a898ccd 100644 --- a/Server/Components/_Imports.razor +++ b/Server/Components/_Imports.razor @@ -7,4 +7,6 @@ @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.JSInterop @using Server -@using Server.Components \ No newline at end of file +@using Server.Components + @using Blazorise +@using Blazorise.DataGrid \ No newline at end of file diff --git a/Server/Program.cs b/Server/Program.cs index 66da67e..bc364b5 100644 --- a/Server/Program.cs +++ b/Server/Program.cs @@ -1,3 +1,6 @@ +using Blazorise; +using Blazorise.Bootstrap5; +using Blazorise.Icons.FontAwesome; using Server.Components; var builder = WebApplication.CreateBuilder(args); @@ -6,12 +9,16 @@ var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); +builder.Services.AddBlazorise(options => { options.Immediate = true; }) + .AddBootstrap5Providers() + .AddFontAwesomeIcons(); + var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { - app.UseExceptionHandler("/Error", createScopeForErrors: true); + app.UseExceptionHandler("/Error", 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(); } diff --git a/Server/Server.csproj b/Server/Server.csproj index fcd1e15..c70aaf6 100644 --- a/Server/Server.csproj +++ b/Server/Server.csproj @@ -7,6 +7,9 @@ + + +