diff --git a/.gitignore b/.gitignore index af2c4680..0f91c8d7 100644 --- a/.gitignore +++ b/.gitignore @@ -337,3 +337,5 @@ ASALocalRun/ # Visual Studio Code folder .vscode/ +*.db-wal +*.db-shm diff --git a/Directory.Build.props b/Directory.Build.props index bb2df7b9..33a62618 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,8 +1,8 @@ - 5.0.0 - 5.0.0 - 5.0.0 - 5.0.0 + 6.0.0-rc.1 + 6.0.0-rc.1 + 6.0.0-rc.1 + 6.0.0-rc.1 diff --git a/src/BlazingComponents/BlazingComponents.csproj b/src/BlazingComponents/BlazingComponents.csproj index 6325ad64..cd034c1a 100644 --- a/src/BlazingComponents/BlazingComponents.csproj +++ b/src/BlazingComponents/BlazingComponents.csproj @@ -1,7 +1,7 @@  - net5.0 + net6.0 diff --git a/src/BlazingPizza.Client/BlazingPizza.Client.csproj b/src/BlazingPizza.Client/BlazingPizza.Client.csproj index 5014247d..18b55749 100644 --- a/src/BlazingPizza.Client/BlazingPizza.Client.csproj +++ b/src/BlazingPizza.Client/BlazingPizza.Client.csproj @@ -1,12 +1,13 @@  - net5.0 + net6.0 + enable - + diff --git a/src/BlazingPizza.Client/JSRuntimeExtensions.cs b/src/BlazingPizza.Client/JSRuntimeExtensions.cs index 89da520c..ecd4067d 100644 --- a/src/BlazingPizza.Client/JSRuntimeExtensions.cs +++ b/src/BlazingPizza.Client/JSRuntimeExtensions.cs @@ -1,13 +1,12 @@ using Microsoft.JSInterop; using System.Threading.Tasks; -namespace BlazingPizza.Client +namespace BlazingPizza.Client; + +public static class JSRuntimeExtensions { - public static class JSRuntimeExtensions + public static ValueTask Confirm(this IJSRuntime jsRuntime, string message) { - public static ValueTask Confirm(this IJSRuntime jsRuntime, string message) - { - return jsRuntime.InvokeAsync("confirm", message); - } + return jsRuntime.InvokeAsync("confirm", message); } } diff --git a/src/BlazingPizza.Client/OrderState.cs b/src/BlazingPizza.Client/OrderState.cs index 5265ae39..cd8c6530 100644 --- a/src/BlazingPizza.Client/OrderState.cs +++ b/src/BlazingPizza.Client/OrderState.cs @@ -1,55 +1,54 @@ using System.Collections.Generic; -namespace BlazingPizza.Client +namespace BlazingPizza.Client; + +public class OrderState { - public class OrderState - { - public bool ShowingConfigureDialog { get; private set; } + public bool ShowingConfigureDialog { get; private set; } - public Pizza ConfiguringPizza { get; private set; } + public Pizza ConfiguringPizza { get; private set; } - public Order Order { get; private set; } = new Order(); + public Order Order { get; private set; } = new Order(); - public void ShowConfigurePizzaDialog(PizzaSpecial special) - { - ConfiguringPizza = new Pizza() - { - Special = special, - SpecialId = special.Id, - Size = Pizza.DefaultSize, - Toppings = new List(), - }; - - ShowingConfigureDialog = true; - } - - public void CancelConfigurePizzaDialog() + public void ShowConfigurePizzaDialog(PizzaSpecial special) + { + ConfiguringPizza = new Pizza() { - ConfiguringPizza = null; - ShowingConfigureDialog = false; - } + Special = special, + SpecialId = special.Id, + Size = Pizza.DefaultSize, + Toppings = new List(), + }; - public void ConfirmConfigurePizzaDialog() - { - Order.Pizzas.Add(ConfiguringPizza); - ConfiguringPizza = null; + ShowingConfigureDialog = true; + } - ShowingConfigureDialog = false; - } + public void CancelConfigurePizzaDialog() + { + ConfiguringPizza = null; + ShowingConfigureDialog = false; + } - public void RemoveConfiguredPizza(Pizza pizza) - { - Order.Pizzas.Remove(pizza); - } + public void ConfirmConfigurePizzaDialog() + { + Order.Pizzas.Add(ConfiguringPizza); + ConfiguringPizza = null; - public void ResetOrder() - { - Order = new Order(); - } + ShowingConfigureDialog = false; + } - public void ReplaceOrder(Order order) - { - Order = order; - } + public void RemoveConfiguredPizza(Pizza pizza) + { + Order.Pizzas.Remove(pizza); + } + + public void ResetOrder() + { + Order = new Order(); + } + + public void ReplaceOrder(Order order) + { + Order = order; } } diff --git a/src/BlazingPizza.Client/OrdersClient.cs b/src/BlazingPizza.Client/OrdersClient.cs index 01c63572..da99414a 100644 --- a/src/BlazingPizza.Client/OrdersClient.cs +++ b/src/BlazingPizza.Client/OrdersClient.cs @@ -1,41 +1,38 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Json; using System.Threading.Tasks; -namespace BlazingPizza.Client +namespace BlazingPizza.Client; + +public class OrdersClient { - public class OrdersClient - { - private readonly HttpClient httpClient; + private readonly HttpClient httpClient; - public OrdersClient(HttpClient httpClient) - { - this.httpClient = httpClient; - } + public OrdersClient(HttpClient httpClient) + { + this.httpClient = httpClient; + } - public async Task> GetOrders() => - await httpClient.GetFromJsonAsync>("orders"); + public async Task> GetOrders() => + await httpClient.GetFromJsonAsync>("orders"); - public async Task GetOrder(int orderId) => - await httpClient.GetFromJsonAsync($"orders/{orderId}"); + public async Task GetOrder(int orderId) => + await httpClient.GetFromJsonAsync($"orders/{orderId}"); - public async Task PlaceOrder(Order order) - { - var response = await httpClient.PostAsJsonAsync("orders", order); - response.EnsureSuccessStatusCode(); - var orderId = await response.Content.ReadFromJsonAsync(); - return orderId; - } + public async Task PlaceOrder(Order order) + { + var response = await httpClient.PostAsJsonAsync("orders", order); + response.EnsureSuccessStatusCode(); + var orderId = await response.Content.ReadFromJsonAsync(); + return orderId; + } - public async Task SubscribeToNotifications(NotificationSubscription subscription) - { - var response = await httpClient.PutAsJsonAsync("notifications/subscribe", subscription); - response.EnsureSuccessStatusCode(); - } + public async Task SubscribeToNotifications(NotificationSubscription subscription) + { + var response = await httpClient.PutAsJsonAsync("notifications/subscribe", subscription); + response.EnsureSuccessStatusCode(); } } diff --git a/src/BlazingPizza.Client/PizzaAuthenticationState.cs b/src/BlazingPizza.Client/PizzaAuthenticationState.cs index 3f295928..78627625 100644 --- a/src/BlazingPizza.Client/PizzaAuthenticationState.cs +++ b/src/BlazingPizza.Client/PizzaAuthenticationState.cs @@ -1,9 +1,8 @@ using Microsoft.AspNetCore.Components.WebAssembly.Authentication; -namespace BlazingPizza.Client +namespace BlazingPizza.Client; + +public class PizzaAuthenticationState : RemoteAuthenticationState { - public class PizzaAuthenticationState : RemoteAuthenticationState - { - public Order Order { get; set; } - } + public Order Order { get; set; } } diff --git a/src/BlazingPizza.Client/Program.cs b/src/BlazingPizza.Client/Program.cs index afeee128..98d9fd55 100644 --- a/src/BlazingPizza.Client/Program.cs +++ b/src/BlazingPizza.Client/Program.cs @@ -1,31 +1,19 @@ -using Microsoft.AspNetCore.Components.WebAssembly.Authentication; +using BlazingPizza.Client; +using Microsoft.AspNetCore.Components.WebAssembly.Authentication; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Net.Http; -using System.Threading.Tasks; -namespace BlazingPizza.Client -{ - public class Program - { - public static async Task Main(string[] args) - { - var builder = WebAssemblyHostBuilder.CreateDefault(args); - builder.RootComponents.Add("#app"); +var builder = WebAssemblyHostBuilder.CreateDefault(args); +builder.RootComponents.Add("#app"); - builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); - builder.Services.AddHttpClient(client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)) - .AddHttpMessageHandler(); - builder.Services.AddScoped(); +builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); +builder.Services.AddHttpClient(client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)) + .AddHttpMessageHandler(); +builder.Services.AddScoped(); - // Add auth services - builder.Services.AddApiAuthorization(options => - { - options.AuthenticationPaths.LogOutSucceededPath = ""; - }); +// Add auth services +builder.Services.AddApiAuthorization(options => +{ + options.AuthenticationPaths.LogOutSucceededPath = ""; +}); - await builder.Build().RunAsync(); - } - } -} +await builder.Build().RunAsync(); \ No newline at end of file diff --git a/src/BlazingPizza.ComponentsLibrary/BlazingPizza.ComponentsLibrary.csproj b/src/BlazingPizza.ComponentsLibrary/BlazingPizza.ComponentsLibrary.csproj index 5f51ee3c..32150e78 100644 --- a/src/BlazingPizza.ComponentsLibrary/BlazingPizza.ComponentsLibrary.csproj +++ b/src/BlazingPizza.ComponentsLibrary/BlazingPizza.ComponentsLibrary.csproj @@ -1,7 +1,7 @@  - net5.0 + net6.0 diff --git a/src/BlazingPizza.ComponentsLibrary/LocalStorage.cs b/src/BlazingPizza.ComponentsLibrary/LocalStorage.cs index f36b098e..e166bd5b 100644 --- a/src/BlazingPizza.ComponentsLibrary/LocalStorage.cs +++ b/src/BlazingPizza.ComponentsLibrary/LocalStorage.cs @@ -1,17 +1,16 @@ using Microsoft.JSInterop; using System.Threading.Tasks; -namespace BlazingPizza.ComponentsLibrary +namespace BlazingPizza.ComponentsLibrary; + +public static class LocalStorage { - public static class LocalStorage - { - public static ValueTask GetAsync(IJSRuntime jsRuntime, string key) - => jsRuntime.InvokeAsync("blazorLocalStorage.get", key); + public static ValueTask GetAsync(IJSRuntime jsRuntime, string key) + => jsRuntime.InvokeAsync("blazorLocalStorage.get", key); - public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) - => jsRuntime.InvokeVoidAsync("blazorLocalStorage.set", key, value); + public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.set", key, value); - public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) - => jsRuntime.InvokeVoidAsync("blazorLocalStorage.delete", key); - } + public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key) + => jsRuntime.InvokeVoidAsync("blazorLocalStorage.delete", key); } diff --git a/src/BlazingPizza.ComponentsLibrary/Map/Marker.cs b/src/BlazingPizza.ComponentsLibrary/Map/Marker.cs index 63006067..b067719c 100644 --- a/src/BlazingPizza.ComponentsLibrary/Map/Marker.cs +++ b/src/BlazingPizza.ComponentsLibrary/Map/Marker.cs @@ -1,13 +1,12 @@ -namespace BlazingPizza.ComponentsLibrary.Map +namespace BlazingPizza.ComponentsLibrary.Map; + +public class Marker { - public class Marker - { - public string Description { get; set; } + public string Description { get; set; } - public double X { get; set; } + public double X { get; set; } - public double Y { get; set; } + public double Y { get; set; } - public bool ShowPopup { get; set; } - } + public bool ShowPopup { get; set; } } diff --git a/src/BlazingPizza.ComponentsLibrary/Map/Point.cs b/src/BlazingPizza.ComponentsLibrary/Map/Point.cs index 03841826..7314fc6d 100644 --- a/src/BlazingPizza.ComponentsLibrary/Map/Point.cs +++ b/src/BlazingPizza.ComponentsLibrary/Map/Point.cs @@ -1,9 +1,8 @@ -namespace BlazingPizza.ComponentsLibrary.Map +namespace BlazingPizza.ComponentsLibrary.Map; + +public class Point { - public class Point - { - public double X { get; set; } + public double X { get; set; } - public double Y { get; set; } - } + public double Y { get; set; } } diff --git a/src/BlazingPizza.Server/BlazingPizza.Server.csproj b/src/BlazingPizza.Server/BlazingPizza.Server.csproj index 6391d520..0a113091 100644 --- a/src/BlazingPizza.Server/BlazingPizza.Server.csproj +++ b/src/BlazingPizza.Server/BlazingPizza.Server.csproj @@ -1,7 +1,8 @@  - net5.0 + net6.0 + enable diff --git a/src/BlazingPizza.Server/OidcConfigurationController.cs b/src/BlazingPizza.Server/OidcConfigurationController.cs index c074debf..1431697e 100644 --- a/src/BlazingPizza.Server/OidcConfigurationController.cs +++ b/src/BlazingPizza.Server/OidcConfigurationController.cs @@ -1,26 +1,21 @@ using Microsoft.AspNetCore.ApiAuthorization.IdentityServer; using Microsoft.AspNetCore.Mvc; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -namespace BlazingPizza.Server +namespace BlazingPizza.Server; + +public class OidcConfigurationController : Controller { - public class OidcConfigurationController : Controller + public OidcConfigurationController(IClientRequestParametersProvider clientRequestParametersProvider) { - public OidcConfigurationController(IClientRequestParametersProvider clientRequestParametersProvider) - { - ClientRequestParametersProvider = clientRequestParametersProvider; - } + ClientRequestParametersProvider = clientRequestParametersProvider; + } - public IClientRequestParametersProvider ClientRequestParametersProvider { get; } + public IClientRequestParametersProvider ClientRequestParametersProvider { get; } - [HttpGet("_configuration/{clientId}")] - public IActionResult GetClientRequestParameters([FromRoute]string clientId) - { - var parameters = ClientRequestParametersProvider.GetClientParameters(HttpContext, clientId); - return Ok(parameters); - } + [HttpGet("_configuration/{clientId}")] + public IActionResult GetClientRequestParameters([FromRoute] string clientId) + { + var parameters = ClientRequestParametersProvider.GetClientParameters(HttpContext, clientId); + return Ok(parameters); } } diff --git a/src/BlazingPizza.Server/OrdersController.cs b/src/BlazingPizza.Server/OrdersController.cs index bab775e4..f2f12ed2 100644 --- a/src/BlazingPizza.Server/OrdersController.cs +++ b/src/BlazingPizza.Server/OrdersController.cs @@ -1,135 +1,130 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Claims; +using System.Security.Claims; using System.Text.Json; -using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using WebPush; -namespace BlazingPizza.Server +namespace BlazingPizza.Server; + +[Route("orders")] +[ApiController] +[Authorize] +public class OrdersController : Controller { - [Route("orders")] - [ApiController] - [Authorize] - public class OrdersController : Controller + private readonly PizzaStoreContext _db; + + public OrdersController(PizzaStoreContext db) { - private readonly PizzaStoreContext _db; + _db = db; + } - public OrdersController(PizzaStoreContext db) - { - _db = db; - } + [HttpGet] + public async Task>> GetOrders() + { + var orders = await _db.Orders + .Where(o => o.UserId == GetUserId()) + .Include(o => o.DeliveryLocation) + .Include(o => o.Pizzas).ThenInclude(p => p.Special) + .Include(o => o.Pizzas).ThenInclude(p => p.Toppings).ThenInclude(t => t.Topping) + .OrderByDescending(o => o.CreatedTime) + .ToListAsync(); + + return orders.Select(o => OrderWithStatus.FromOrder(o)).ToList(); + } - [HttpGet] - public async Task>> GetOrders() + [HttpGet("{orderId}")] + public async Task> GetOrderWithStatus(int orderId) + { + var order = await _db.Orders + .Where(o => o.OrderId == orderId) + .Where(o => o.UserId == GetUserId()) + .Include(o => o.DeliveryLocation) + .Include(o => o.Pizzas).ThenInclude(p => p.Special) + .Include(o => o.Pizzas).ThenInclude(p => p.Toppings).ThenInclude(t => t.Topping) + .SingleOrDefaultAsync(); + + if (order == null) { - var orders = await _db.Orders - .Where(o => o.UserId == GetUserId()) - .Include(o => o.DeliveryLocation) - .Include(o => o.Pizzas).ThenInclude(p => p.Special) - .Include(o => o.Pizzas).ThenInclude(p => p.Toppings).ThenInclude(t => t.Topping) - .OrderByDescending(o => o.CreatedTime) - .ToListAsync(); - - return orders.Select(o => OrderWithStatus.FromOrder(o)).ToList(); + return NotFound(); } - [HttpGet("{orderId}")] - public async Task> GetOrderWithStatus(int orderId) - { - var order = await _db.Orders - .Where(o => o.OrderId == orderId) - .Where(o => o.UserId == GetUserId()) - .Include(o => o.DeliveryLocation) - .Include(o => o.Pizzas).ThenInclude(p => p.Special) - .Include(o => o.Pizzas).ThenInclude(p => p.Toppings).ThenInclude(t => t.Topping) - .SingleOrDefaultAsync(); - - if (order == null) - { - return NotFound(); - } - - return OrderWithStatus.FromOrder(order); - } + return OrderWithStatus.FromOrder(order); + } - [HttpPost] - public async Task> PlaceOrder(Order order) + [HttpPost] + public async Task> PlaceOrder(Order order) + { + order.CreatedTime = DateTime.Now; + order.DeliveryLocation = new LatLong(51.5001, -0.1239); + order.UserId = GetUserId(); + + // Enforce existence of Pizza.SpecialId and Topping.ToppingId + // in the database - prevent the submitter from making up + // new specials and toppings + foreach (var pizza in order.Pizzas) { - order.CreatedTime = DateTime.Now; - order.DeliveryLocation = new LatLong(51.5001, -0.1239); - order.UserId = GetUserId(); - - // Enforce existence of Pizza.SpecialId and Topping.ToppingId - // in the database - prevent the submitter from making up - // new specials and toppings - foreach (var pizza in order.Pizzas) - { - pizza.SpecialId = pizza.Special.Id; - pizza.Special = null; - - foreach (var topping in pizza.Toppings) - { - topping.ToppingId = topping.Topping.Id; - topping.Topping = null; - } - } - - _db.Orders.Attach(order); - await _db.SaveChangesAsync(); + pizza.SpecialId = pizza.Special.Id; + pizza.Special = null; - // In the background, send push notifications if possible - var subscription = await _db.NotificationSubscriptions.Where(e => e.UserId == GetUserId()).SingleOrDefaultAsync(); - if (subscription != null) + foreach (var topping in pizza.Toppings) { - _ = TrackAndSendNotificationsAsync(order, subscription); + topping.ToppingId = topping.Topping.Id; + topping.Topping = null; } - - return order.OrderId; } - private string GetUserId() - { - return HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier); - } + _db.Orders.Attach(order); + await _db.SaveChangesAsync(); - private static async Task TrackAndSendNotificationsAsync(Order order, NotificationSubscription subscription) + // In the background, send push notifications if possible + var subscription = await _db.NotificationSubscriptions.Where(e => e.UserId == GetUserId()).SingleOrDefaultAsync(); + if (subscription != null) { - // In a realistic case, some other backend process would track - // order delivery progress and send us notifications when it - // changes. Since we don't have any such process here, fake it. - await Task.Delay(OrderWithStatus.PreparationDuration); - await SendNotificationAsync(order, subscription, "Your order has been dispatched!"); - - await Task.Delay(OrderWithStatus.DeliveryDuration); - await SendNotificationAsync(order, subscription, "Your order is now delivered. Enjoy!"); + _ = TrackAndSendNotificationsAsync(order, subscription); } - private static async Task SendNotificationAsync(Order order, NotificationSubscription subscription, string message) + return order.OrderId; + } + + private string GetUserId() + { + return HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier); + } + + private static async Task TrackAndSendNotificationsAsync(Order order, NotificationSubscription subscription) + { + // In a realistic case, some other backend process would track + // order delivery progress and send us notifications when it + // changes. Since we don't have any such process here, fake it. + await Task.Delay(OrderWithStatus.PreparationDuration); + await SendNotificationAsync(order, subscription, "Your order has been dispatched!"); + + await Task.Delay(OrderWithStatus.DeliveryDuration); + await SendNotificationAsync(order, subscription, "Your order is now delivered. Enjoy!"); + } + + private static async Task SendNotificationAsync(Order order, NotificationSubscription subscription, string message) + { + // For a real application, generate your own + var publicKey = "BLC8GOevpcpjQiLkO7JmVClQjycvTCYWm6Cq_a7wJZlstGTVZvwGFFHMYfXt6Njyvgx_GlXJeo5cSiZ1y4JOx1o"; + var privateKey = "OrubzSz3yWACscZXjFQrrtDwCKg-TGFuWhluQ2wLXDo"; + + var pushSubscription = new PushSubscription(subscription.Url, subscription.P256dh, subscription.Auth); + var vapidDetails = new VapidDetails("mailto:", publicKey, privateKey); + var webPushClient = new WebPushClient(); + try { - // For a real application, generate your own - var publicKey = "BLC8GOevpcpjQiLkO7JmVClQjycvTCYWm6Cq_a7wJZlstGTVZvwGFFHMYfXt6Njyvgx_GlXJeo5cSiZ1y4JOx1o"; - var privateKey = "OrubzSz3yWACscZXjFQrrtDwCKg-TGFuWhluQ2wLXDo"; - - var pushSubscription = new PushSubscription(subscription.Url, subscription.P256dh, subscription.Auth); - var vapidDetails = new VapidDetails("mailto:", publicKey, privateKey); - var webPushClient = new WebPushClient(); - try - { - var payload = JsonSerializer.Serialize(new - { - message, - url = $"myorders/{order.OrderId}", - }); - await webPushClient.SendNotificationAsync(pushSubscription, payload, vapidDetails); - } - catch (Exception ex) + var payload = JsonSerializer.Serialize(new { - Console.Error.WriteLine("Error sending push notification: " + ex.Message); - } + message, + url = $"myorders/{order.OrderId}", + }); + await webPushClient.SendNotificationAsync(pushSubscription, payload, vapidDetails); + } + catch (Exception ex) + { + Console.Error.WriteLine("Error sending push notification: " + ex.Message); } } } diff --git a/src/BlazingPizza.Server/PizzaStoreContext.cs b/src/BlazingPizza.Server/PizzaStoreContext.cs index 51e96e1e..31269647 100644 --- a/src/BlazingPizza.Server/PizzaStoreContext.cs +++ b/src/BlazingPizza.Server/PizzaStoreContext.cs @@ -1,39 +1,38 @@ -using IdentityServer4.EntityFramework.Options; +using Duende.IdentityServer.EntityFramework.Options; using Microsoft.AspNetCore.ApiAuthorization.IdentityServer; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; -namespace BlazingPizza.Server +namespace BlazingPizza.Server; + +public class PizzaStoreContext : ApiAuthorizationDbContext { - public class PizzaStoreContext : ApiAuthorizationDbContext + public PizzaStoreContext( + DbContextOptions options, + IOptions operationalStoreOptions) : base(options, operationalStoreOptions) { - public PizzaStoreContext( - DbContextOptions options, - IOptions operationalStoreOptions) : base(options, operationalStoreOptions) - { - } + } - public DbSet Orders { get; set; } + public DbSet Orders { get; set; } - public DbSet Pizzas { get; set; } + public DbSet Pizzas { get; set; } - public DbSet Specials { get; set; } + public DbSet Specials { get; set; } - public DbSet Toppings { get; set; } + public DbSet Toppings { get; set; } - public DbSet NotificationSubscriptions { get; set; } + public DbSet NotificationSubscriptions { get; set; } - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - base.OnModelCreating(modelBuilder); + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); - // Configuring a many-to-many special -> topping relationship that is friendly for serialization - modelBuilder.Entity().HasKey(pst => new { pst.PizzaId, pst.ToppingId }); - modelBuilder.Entity().HasOne().WithMany(ps => ps.Toppings); - modelBuilder.Entity().HasOne(pst => pst.Topping).WithMany(); + // Configuring a many-to-many special -> topping relationship that is friendly for serialization + modelBuilder.Entity().HasKey(pst => new { pst.PizzaId, pst.ToppingId }); + modelBuilder.Entity().HasOne().WithMany(ps => ps.Toppings); + modelBuilder.Entity().HasOne(pst => pst.Topping).WithMany(); - // Inline the Lat-Long pairs in Order rather than having a FK to another table - modelBuilder.Entity().OwnsOne(o => o.DeliveryLocation); - } + // Inline the Lat-Long pairs in Order rather than having a FK to another table + modelBuilder.Entity().OwnsOne(o => o.DeliveryLocation); } } diff --git a/src/BlazingPizza.Server/PizzaStoreUser.cs b/src/BlazingPizza.Server/PizzaStoreUser.cs index 171ce83d..6d096921 100644 --- a/src/BlazingPizza.Server/PizzaStoreUser.cs +++ b/src/BlazingPizza.Server/PizzaStoreUser.cs @@ -1,8 +1,7 @@ using Microsoft.AspNetCore.Identity; -namespace BlazingPizza.Server +namespace BlazingPizza.Server; + +public class PizzaStoreUser : IdentityUser { - public class PizzaStoreUser : IdentityUser - { - } -} \ No newline at end of file +} diff --git a/src/BlazingPizza.Server/PizzasController.cs b/src/BlazingPizza.Server/PizzasController.cs index c082552c..f6336de3 100644 --- a/src/BlazingPizza.Server/PizzasController.cs +++ b/src/BlazingPizza.Server/PizzasController.cs @@ -1,16 +1,15 @@ using Microsoft.AspNetCore.Mvc; -namespace BlazingPizza.Server +namespace BlazingPizza.Server; + +[Route("pizzas")] +[ApiController] +public class PizzasController : Controller { - [Route("pizzas")] - [ApiController] - public class PizzasController : Controller - { - private readonly PizzaStoreContext _db; + private readonly PizzaStoreContext _db; - public PizzasController(PizzaStoreContext db) - { - _db = db; - } + public PizzasController(PizzaStoreContext db) + { + _db = db; } } diff --git a/src/BlazingPizza.Server/Program.cs b/src/BlazingPizza.Server/Program.cs index 40a47641..d7af5caf 100644 --- a/src/BlazingPizza.Server/Program.cs +++ b/src/BlazingPizza.Server/Program.cs @@ -1,33 +1,59 @@ -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; +using BlazingPizza.Server; +using Microsoft.AspNetCore.Authentication; +using Microsoft.EntityFrameworkCore; -namespace BlazingPizza.Server +var builder = WebApplication.CreateBuilder(args); + +var services = builder.Services; + +services.AddControllersWithViews(); +services.AddRazorPages(); + +services.AddDbContext(options => + options.UseSqlite("Data Source=pizza.db")); + +services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) + .AddEntityFrameworkStores(); + +services.AddIdentityServer() + .AddApiAuthorization(); + +services.AddAuthentication() + .AddIdentityServerJwt(); + +var app = builder.Build(); + +// Initialize the database +var scopeFactory = app.Services.GetRequiredService(); +using (var scope = scopeFactory.CreateScope()) { - public class Program + var db = scope.ServiceProvider.GetRequiredService(); + if (db.Database.EnsureCreated()) { - public static void Main(string[] args) - { - var host = CreateHostBuilder(args).Build(); - - // Initialize the database - var scopeFactory = host.Services.GetRequiredService(); - using (var scope = scopeFactory.CreateScope()) - { - var db = scope.ServiceProvider.GetRequiredService(); - if (db.Database.EnsureCreated()) - { - SeedData.Initialize(db); - } - } - - host.Run(); - } - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }); + SeedData.Initialize(db); } } + +if (app.Environment.IsDevelopment()) +{ + app.UseDeveloperExceptionPage(); + app.UseWebAssemblyDebugging(); +} +else +{ + app.UseExceptionHandler("/Error"); + app.UseHsts(); +} + +app.UseHttpsRedirection(); +app.UseBlazorFrameworkFiles(); +app.UseStaticFiles(); +app.UseRouting(); +app.UseAuthentication(); +app.UseIdentityServer(); +app.UseAuthorization(); +app.MapRazorPages(); +app.MapControllers(); +app.MapFallbackToFile("index.html"); + +await app.RunAsync(); diff --git a/src/BlazingPizza.Server/SeedData.cs b/src/BlazingPizza.Server/SeedData.cs index 7c86a5b2..fb0446d1 100644 --- a/src/BlazingPizza.Server/SeedData.cs +++ b/src/BlazingPizza.Server/SeedData.cs @@ -1,11 +1,11 @@ -namespace BlazingPizza.Server +namespace BlazingPizza.Server; + +public static class SeedData { - public static class SeedData + public static void Initialize(PizzaStoreContext db) { - public static void Initialize(PizzaStoreContext db) + var toppings = new Topping[] { - var toppings = new Topping[] - { new Topping() { Name = "Extra cheese", @@ -116,10 +116,10 @@ public static void Initialize(PizzaStoreContext db) Name = "Blue cheese", Price = 2.50m, }, - }; + }; - var specials = new PizzaSpecial[] - { + var specials = new PizzaSpecial[] + { new PizzaSpecial() { Name = "Basic Cheese Pizza", @@ -183,11 +183,10 @@ public static void Initialize(PizzaStoreContext db) BasePrice = 9.99m, ImageUrl = "img/pizzas/margherita.jpg", }, - }; + }; - db.Toppings.AddRange(toppings); - db.Specials.AddRange(specials); - db.SaveChanges(); - } + db.Toppings.AddRange(toppings); + db.Specials.AddRange(specials); + db.SaveChanges(); } } diff --git a/src/BlazingPizza.Server/SpecialsController.cs b/src/BlazingPizza.Server/SpecialsController.cs index a176844c..72cec2ff 100644 --- a/src/BlazingPizza.Server/SpecialsController.cs +++ b/src/BlazingPizza.Server/SpecialsController.cs @@ -1,26 +1,22 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -namespace BlazingPizza.Server +namespace BlazingPizza.Server; + +[Route("specials")] +[ApiController] +public class SpecialsController : Controller { - [Route("specials")] - [ApiController] - public class SpecialsController : Controller - { - private readonly PizzaStoreContext _db; + private readonly PizzaStoreContext _db; - public SpecialsController(PizzaStoreContext db) - { - _db = db; - } + public SpecialsController(PizzaStoreContext db) + { + _db = db; + } - [HttpGet] - public async Task>> GetSpecials() - { - return (await _db.Specials.ToListAsync()).OrderByDescending(s => s.BasePrice).ToList(); - } + [HttpGet] + public async Task>> GetSpecials() + { + return (await _db.Specials.ToListAsync()).OrderByDescending(s => s.BasePrice).ToList(); } } diff --git a/src/BlazingPizza.Server/Startup.cs b/src/BlazingPizza.Server/Startup.cs deleted file mode 100644 index 053acade..00000000 --- a/src/BlazingPizza.Server/Startup.cs +++ /dev/null @@ -1,70 +0,0 @@ -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; - -namespace BlazingPizza.Server -{ - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - public void ConfigureServices(IServiceCollection services) - { - services.AddControllersWithViews(); - services.AddRazorPages(); - - services.AddDbContext(options => - options.UseSqlite("Data Source=pizza.db")); - - services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) - .AddEntityFrameworkStores(); - - services.AddIdentityServer() - .AddApiAuthorization(); - - services.AddAuthentication() - .AddIdentityServerJwt(); - } - - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - app.UseWebAssemblyDebugging(); - } - else - { - 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.UseBlazorFrameworkFiles(); - app.UseStaticFiles(); - - app.UseRouting(); - - app.UseAuthentication(); - app.UseIdentityServer(); - app.UseAuthorization(); - - app.UseEndpoints(endpoints => - { - endpoints.MapRazorPages(); - endpoints.MapControllers(); - endpoints.MapFallbackToFile("index.html"); - }); - } - } -} diff --git a/src/BlazingPizza.Server/ToppingsController.cs b/src/BlazingPizza.Server/ToppingsController.cs index 6a677639..8b74e35a 100644 --- a/src/BlazingPizza.Server/ToppingsController.cs +++ b/src/BlazingPizza.Server/ToppingsController.cs @@ -1,26 +1,22 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -namespace BlazingPizza.Server +namespace BlazingPizza.Server; + +[Route("toppings")] +[ApiController] +public class ToppingsController : Controller { - [Route("toppings")] - [ApiController] - public class ToppingsController : Controller - { - private readonly PizzaStoreContext _db; + private readonly PizzaStoreContext _db; - public ToppingsController(PizzaStoreContext db) - { - _db = db; - } + public ToppingsController(PizzaStoreContext db) + { + _db = db; + } - [HttpGet] - public async Task>> GetToppings() - { - return await _db.Toppings.OrderBy(t => t.Name).ToListAsync(); - } + [HttpGet] + public async Task>> GetToppings() + { + return await _db.Toppings.OrderBy(t => t.Name).ToListAsync(); } } diff --git a/src/BlazingPizza.Shared/Address.cs b/src/BlazingPizza.Shared/Address.cs index d76bc52a..309438b7 100644 --- a/src/BlazingPizza.Shared/Address.cs +++ b/src/BlazingPizza.Shared/Address.cs @@ -1,27 +1,26 @@ using System.ComponentModel.DataAnnotations; -namespace BlazingPizza +namespace BlazingPizza; + +public class Address { - public class Address - { - public int Id { get; set; } + public int Id { get; set; } - [Required, MaxLength(100)] - public string Name { get; set; } + [Required, MaxLength(100)] + public string Name { get; set; } - [Required, MaxLength(100)] - public string Line1 { get; set; } + [Required, MaxLength(100)] + public string Line1 { get; set; } - [MaxLength(100)] - public string Line2 { get; set; } + [MaxLength(100)] + public string Line2 { get; set; } - [Required, MaxLength(50)] - public string City { get; set; } + [Required, MaxLength(50)] + public string City { get; set; } - [Required, MaxLength(20)] - public string Region { get; set; } + [Required, MaxLength(20)] + public string Region { get; set; } - [Required, MaxLength(20)] - public string PostalCode { get; set; } - } + [Required, MaxLength(20)] + public string PostalCode { get; set; } } diff --git a/src/BlazingPizza.Shared/BlazingPizza.Shared.csproj b/src/BlazingPizza.Shared/BlazingPizza.Shared.csproj index 911c57c5..0111427a 100644 --- a/src/BlazingPizza.Shared/BlazingPizza.Shared.csproj +++ b/src/BlazingPizza.Shared/BlazingPizza.Shared.csproj @@ -1,8 +1,9 @@  - net5.0 + net6.0 BlazingPizza + enable diff --git a/src/BlazingPizza.Shared/LatLong.cs b/src/BlazingPizza.Shared/LatLong.cs index 9b8c3811..8d81feda 100644 --- a/src/BlazingPizza.Shared/LatLong.cs +++ b/src/BlazingPizza.Shared/LatLong.cs @@ -1,27 +1,26 @@ -namespace BlazingPizza +namespace BlazingPizza; + +public class LatLong { - public class LatLong + public LatLong() { - public LatLong() - { - } + } - public LatLong(double latitude, double longitude) : this() - { - Latitude = latitude; - Longitude = longitude; - } + public LatLong(double latitude, double longitude) : this() + { + Latitude = latitude; + Longitude = longitude; + } - public double Latitude { get; set; } + public double Latitude { get; set; } - public double Longitude { get; set; } + public double Longitude { get; set; } - public static LatLong Interpolate(LatLong start, LatLong end, double proportion) - { - // The Earth is flat, right? So no need for spherical interpolation. - return new LatLong( - start.Latitude + (end.Latitude - start.Latitude) * proportion, - start.Longitude + (end.Longitude - start.Longitude) * proportion); - } + public static LatLong Interpolate(LatLong start, LatLong end, double proportion) + { + // The Earth is flat, right? So no need for spherical interpolation. + return new LatLong( + start.Latitude + (end.Latitude - start.Latitude) * proportion, + start.Longitude + (end.Longitude - start.Longitude) * proportion); } } diff --git a/src/BlazingPizza.Shared/NotificationSubscription.cs b/src/BlazingPizza.Shared/NotificationSubscription.cs index 04259c2f..5c99e3f4 100644 --- a/src/BlazingPizza.Shared/NotificationSubscription.cs +++ b/src/BlazingPizza.Shared/NotificationSubscription.cs @@ -1,17 +1,14 @@ -using System.ComponentModel.DataAnnotations; +namespace BlazingPizza; -namespace BlazingPizza +public class NotificationSubscription { - public class NotificationSubscription - { - public int NotificationSubscriptionId { get; set; } + public int NotificationSubscriptionId { get; set; } - public string UserId { get; set; } + public string UserId { get; set; } - public string Url { get; set; } + public string Url { get; set; } - public string P256dh { get; set; } + public string P256dh { get; set; } - public string Auth { get; set; } - } + public string Auth { get; set; } } diff --git a/src/BlazingPizza.Shared/Order.cs b/src/BlazingPizza.Shared/Order.cs index fb003bd6..0b134ead 100644 --- a/src/BlazingPizza.Shared/Order.cs +++ b/src/BlazingPizza.Shared/Order.cs @@ -1,25 +1,20 @@ -using System; -using System.Collections.Generic; -using System.Linq; +namespace BlazingPizza; -namespace BlazingPizza +public class Order { - public class Order - { - public int OrderId { get; set; } + public int OrderId { get; set; } - public string UserId { get; set; } + public string UserId { get; set; } - public DateTime CreatedTime { get; set; } + public DateTime CreatedTime { get; set; } - public Address DeliveryAddress { get; set; } = new Address(); + public Address DeliveryAddress { get; set; } = new Address(); - public LatLong DeliveryLocation { get; set; } + public LatLong DeliveryLocation { get; set; } - public List Pizzas { get; set; } = new List(); + public List Pizzas { get; set; } = new List(); - public decimal GetTotalPrice() => Pizzas.Sum(p => p.GetTotalPrice()); + public decimal GetTotalPrice() => Pizzas.Sum(p => p.GetTotalPrice()); - public string GetFormattedTotalPrice() => GetTotalPrice().ToString("0.00"); - } + public string GetFormattedTotalPrice() => GetTotalPrice().ToString("0.00"); } diff --git a/src/BlazingPizza.Shared/OrderWithStatus.cs b/src/BlazingPizza.Shared/OrderWithStatus.cs index 021de78c..05507467 100644 --- a/src/BlazingPizza.Shared/OrderWithStatus.cs +++ b/src/BlazingPizza.Shared/OrderWithStatus.cs @@ -1,79 +1,76 @@ using BlazingPizza.ComponentsLibrary.Map; -using System; -using System.Collections.Generic; -namespace BlazingPizza +namespace BlazingPizza; + +public class OrderWithStatus { - public class OrderWithStatus - { - public readonly static TimeSpan PreparationDuration = TimeSpan.FromSeconds(10); - public readonly static TimeSpan DeliveryDuration = TimeSpan.FromMinutes(1); // Unrealistic, but more interesting to watch + public readonly static TimeSpan PreparationDuration = TimeSpan.FromSeconds(10); + public readonly static TimeSpan DeliveryDuration = TimeSpan.FromMinutes(1); // Unrealistic, but more interesting to watch - public Order Order { get; set; } + public Order Order { get; set; } - public string StatusText { get; set; } + public string StatusText { get; set; } - public bool IsDelivered => StatusText == "Delivered"; + public bool IsDelivered => StatusText == "Delivered"; - public List MapMarkers { get; set; } + public List MapMarkers { get; set; } - public static OrderWithStatus FromOrder(Order order) - { - // To simulate a real backend process, we fake status updates based on the amount - // of time since the order was placed - string statusText; - List mapMarkers; - var dispatchTime = order.CreatedTime.Add(PreparationDuration); + public static OrderWithStatus FromOrder(Order order) + { + // To simulate a real backend process, we fake status updates based on the amount + // of time since the order was placed + string statusText; + List mapMarkers; + var dispatchTime = order.CreatedTime.Add(PreparationDuration); - if (DateTime.Now < dispatchTime) - { - statusText = "Preparing"; - mapMarkers = new List + if (DateTime.Now < dispatchTime) + { + statusText = "Preparing"; + mapMarkers = new List { ToMapMarker("You", order.DeliveryLocation, showPopup: true) }; - } - else if (DateTime.Now < dispatchTime + DeliveryDuration) - { - statusText = "Out for delivery"; + } + else if (DateTime.Now < dispatchTime + DeliveryDuration) + { + statusText = "Out for delivery"; - var startPosition = ComputeStartPosition(order); - var proportionOfDeliveryCompleted = Math.Min(1, (DateTime.Now - dispatchTime).TotalMilliseconds / DeliveryDuration.TotalMilliseconds); - var driverPosition = LatLong.Interpolate(startPosition, order.DeliveryLocation, proportionOfDeliveryCompleted); - mapMarkers = new List + var startPosition = ComputeStartPosition(order); + var proportionOfDeliveryCompleted = Math.Min(1, (DateTime.Now - dispatchTime).TotalMilliseconds / DeliveryDuration.TotalMilliseconds); + var driverPosition = LatLong.Interpolate(startPosition, order.DeliveryLocation, proportionOfDeliveryCompleted); + mapMarkers = new List { ToMapMarker("You", order.DeliveryLocation), ToMapMarker("Driver", driverPosition, showPopup: true), }; - } - else - { - statusText = "Delivered"; - mapMarkers = new List + } + else + { + statusText = "Delivered"; + mapMarkers = new List { ToMapMarker("Delivery location", order.DeliveryLocation, showPopup: true), }; - } - - return new OrderWithStatus - { - Order = order, - StatusText = statusText, - MapMarkers = mapMarkers, - }; } - private static LatLong ComputeStartPosition(Order order) + return new OrderWithStatus { - // Random but deterministic based on order ID - var rng = new Random(order.OrderId); - var distance = 0.01 + rng.NextDouble() * 0.02; - var angle = rng.NextDouble() * Math.PI * 2; - var offset = (distance * Math.Cos(angle), distance * Math.Sin(angle)); - return new LatLong(order.DeliveryLocation.Latitude + offset.Item1, order.DeliveryLocation.Longitude + offset.Item2); - } + Order = order, + StatusText = statusText, + MapMarkers = mapMarkers, + }; + } - static Marker ToMapMarker(string description, LatLong coords, bool showPopup = false) - => new Marker { Description = description, X = coords.Longitude, Y = coords.Latitude, ShowPopup = showPopup }; + private static LatLong ComputeStartPosition(Order order) + { + // Random but deterministic based on order ID + var rng = new Random(order.OrderId); + var distance = 0.01 + rng.NextDouble() * 0.02; + var angle = rng.NextDouble() * Math.PI * 2; + var offset = (distance * Math.Cos(angle), distance * Math.Sin(angle)); + return new LatLong(order.DeliveryLocation.Latitude + offset.Item1, order.DeliveryLocation.Longitude + offset.Item2); } + + static Marker ToMapMarker(string description, LatLong coords, bool showPopup = false) + => new Marker { Description = description, X = coords.Longitude, Y = coords.Latitude, ShowPopup = showPopup }; } diff --git a/src/BlazingPizza.Shared/Pizza.cs b/src/BlazingPizza.Shared/Pizza.cs index ec1108a9..d5a2e7fe 100644 --- a/src/BlazingPizza.Shared/Pizza.cs +++ b/src/BlazingPizza.Shared/Pizza.cs @@ -1,42 +1,38 @@ -using System.Collections.Generic; -using System.Linq; +namespace BlazingPizza; -namespace BlazingPizza +/// +/// Represents a customized pizza as part of an order +/// +public class Pizza { - /// - /// Represents a customized pizza as part of an order - /// - public class Pizza - { - public const int DefaultSize = 12; - public const int MinimumSize = 9; - public const int MaximumSize = 17; + public const int DefaultSize = 12; + public const int MinimumSize = 9; + public const int MaximumSize = 17; - public int Id { get; set; } + public int Id { get; set; } - public int OrderId { get; set; } + public int OrderId { get; set; } - public PizzaSpecial Special { get; set; } + public PizzaSpecial Special { get; set; } - public int SpecialId { get; set; } + public int SpecialId { get; set; } - public int Size { get; set; } + public int Size { get; set; } - public List Toppings { get; set; } + public List Toppings { get; set; } - public decimal GetBasePrice() - { - return ((decimal)Size / (decimal)DefaultSize) * Special.BasePrice; - } + public decimal GetBasePrice() + { + return ((decimal)Size / (decimal)DefaultSize) * Special.BasePrice; + } - public decimal GetTotalPrice() - { - return GetBasePrice() + Toppings.Sum(t => t.Topping.Price); - } + public decimal GetTotalPrice() + { + return GetBasePrice() + Toppings.Sum(t => t.Topping.Price); + } - public string GetFormattedTotalPrice() - { - return GetTotalPrice().ToString("0.00"); - } + public string GetFormattedTotalPrice() + { + return GetTotalPrice().ToString("0.00"); } } diff --git a/src/BlazingPizza.Shared/PizzaSpecial.cs b/src/BlazingPizza.Shared/PizzaSpecial.cs index 2f2b3383..21c19dbe 100644 --- a/src/BlazingPizza.Shared/PizzaSpecial.cs +++ b/src/BlazingPizza.Shared/PizzaSpecial.cs @@ -1,20 +1,19 @@ -namespace BlazingPizza +namespace BlazingPizza; + +/// +/// Represents a pre-configured template for a pizza a user can order +/// +public class PizzaSpecial { - /// - /// Represents a pre-configured template for a pizza a user can order - /// - public class PizzaSpecial - { - public int Id { get; set; } + public int Id { get; set; } - public string Name { get; set; } + public string Name { get; set; } - public decimal BasePrice { get; set; } + public decimal BasePrice { get; set; } - public string Description { get; set; } + public string Description { get; set; } - public string ImageUrl { get; set; } + public string ImageUrl { get; set; } - public string GetFormattedBasePrice() => BasePrice.ToString("0.00"); - } + public string GetFormattedBasePrice() => BasePrice.ToString("0.00"); } diff --git a/src/BlazingPizza.Shared/PizzaTopping.cs b/src/BlazingPizza.Shared/PizzaTopping.cs index f5a6c1ac..6fd20271 100644 --- a/src/BlazingPizza.Shared/PizzaTopping.cs +++ b/src/BlazingPizza.Shared/PizzaTopping.cs @@ -1,11 +1,10 @@ -namespace BlazingPizza +namespace BlazingPizza; + +public class PizzaTopping { - public class PizzaTopping - { - public Topping Topping { get; set; } + public Topping Topping { get; set; } + + public int ToppingId { get; set; } - public int ToppingId { get; set; } - - public int PizzaId { get; set; } - } + public int PizzaId { get; set; } } diff --git a/src/BlazingPizza.Shared/Topping.cs b/src/BlazingPizza.Shared/Topping.cs index 61bdeb92..3ac78a09 100644 --- a/src/BlazingPizza.Shared/Topping.cs +++ b/src/BlazingPizza.Shared/Topping.cs @@ -1,13 +1,12 @@ -namespace BlazingPizza +namespace BlazingPizza; + +public class Topping { - public class Topping - { - public int Id { get; set; } + public int Id { get; set; } - public string Name { get; set; } + public string Name { get; set; } - public decimal Price { get; set; } + public decimal Price { get; set; } - public string GetFormattedPrice() => Price.ToString("0.00"); - } + public string GetFormattedPrice() => Price.ToString("0.00"); } diff --git a/src/BlazingPizza.Shared/UserInfo.cs b/src/BlazingPizza.Shared/UserInfo.cs index 4996ef80..8dcf4773 100644 --- a/src/BlazingPizza.Shared/UserInfo.cs +++ b/src/BlazingPizza.Shared/UserInfo.cs @@ -1,9 +1,8 @@ -namespace BlazingPizza +namespace BlazingPizza; + +public class UserInfo { - public class UserInfo - { - public bool IsAuthenticated { get; set; } + public bool IsAuthenticated { get; set; } - public string Name { get; set; } - } + public string Name { get; set; } }