Add a benchmark app
This commit is contained in:
parent
6594d8bb7c
commit
07df9cfcf5
|
|
@ -0,0 +1,6 @@
|
||||||
|
<Router AppAssembly="typeof(Program).Assembly">
|
||||||
|
<NotFound>Page not found</NotFound>
|
||||||
|
<Found Context="routeData">
|
||||||
|
<RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)"></RouteView>
|
||||||
|
</Found>
|
||||||
|
</Router>
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||||
|
<TargetFramework Condition="'$(BenchmarksTargetFramework)' != ''">$(BenchmarksTargetFramework)</TargetFramework>
|
||||||
|
<IsTestAssetProject>true</IsTestAssetProject>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<!-- These references are used when building on the Benchmarks Server. -->
|
||||||
|
<ItemGroup Condition="'$(BenchmarksTargetFramework)' != ''">
|
||||||
|
|
||||||
|
<FrameworkReference Update="Microsoft.AspNetCore.App" RuntimeFrameworkVersion="$(MicrosoftAspNetCoreAppPackageVersion)" />
|
||||||
|
<FrameworkReference Update="Microsoft.NETCore.App" RuntimeFrameworkVersion="$(MicrosoftNETCoreAppPackageVersion)" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
using Microsoft.JSInterop;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BlazingPizza.Server
|
||||||
|
{
|
||||||
|
public static class JSRuntimeExtensions
|
||||||
|
{
|
||||||
|
public static ValueTask<bool> Confirm(this IJSRuntime jsRuntime, string message)
|
||||||
|
{
|
||||||
|
return jsRuntime.InvokeAsync<bool>("confirm", message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace BlazingPizza
|
||||||
|
{
|
||||||
|
public class Address
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
[Required, MaxLength(100)]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
[Required, MaxLength(100)]
|
||||||
|
public string Line1 { get; set; }
|
||||||
|
|
||||||
|
[MaxLength(100)]
|
||||||
|
public string Line2 { get; set; }
|
||||||
|
|
||||||
|
[Required, MaxLength(50)]
|
||||||
|
public string City { get; set; }
|
||||||
|
|
||||||
|
[Required, MaxLength(20)]
|
||||||
|
public string Region { get; set; }
|
||||||
|
|
||||||
|
[Required, MaxLength(20)]
|
||||||
|
public string PostalCode { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
namespace BlazingPizza
|
||||||
|
{
|
||||||
|
public class LatLong
|
||||||
|
{
|
||||||
|
public LatLong()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public LatLong(double latitude, double longitude) : this()
|
||||||
|
{
|
||||||
|
Latitude = latitude;
|
||||||
|
Longitude = longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double Latitude { 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace BlazingPizza
|
||||||
|
{
|
||||||
|
public class Order
|
||||||
|
{
|
||||||
|
public int OrderId { get; set; }
|
||||||
|
|
||||||
|
public string UserId { get; set; }
|
||||||
|
|
||||||
|
public DateTime CreatedTime { get; set; }
|
||||||
|
|
||||||
|
public Address DeliveryAddress { get; set; } = new Address();
|
||||||
|
|
||||||
|
public LatLong DeliveryLocation { get; set; }
|
||||||
|
|
||||||
|
public List<Pizza> Pizzas { get; set; } = new List<Pizza>();
|
||||||
|
|
||||||
|
public decimal GetTotalPrice() => Pizzas.Sum(p => p.GetTotalPrice());
|
||||||
|
|
||||||
|
public string GetFormattedTotalPrice() => GetTotalPrice().ToString("0.00");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace BlazingPizza
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a customized pizza as part of an order
|
||||||
|
/// </summary>
|
||||||
|
public class Pizza
|
||||||
|
{
|
||||||
|
public const int DefaultSize = 12;
|
||||||
|
public const int MinimumSize = 9;
|
||||||
|
public const int MaximumSize = 17;
|
||||||
|
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public int OrderId { get; set; }
|
||||||
|
|
||||||
|
public PizzaSpecial Special { get; set; }
|
||||||
|
|
||||||
|
public int SpecialId { get; set; }
|
||||||
|
|
||||||
|
public int Size { get; set; }
|
||||||
|
|
||||||
|
public List<PizzaTopping> Toppings { get; set; }
|
||||||
|
|
||||||
|
public decimal GetBasePrice()
|
||||||
|
{
|
||||||
|
return ((decimal)Size / (decimal)DefaultSize) * Special.BasePrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public decimal GetTotalPrice()
|
||||||
|
{
|
||||||
|
return GetBasePrice() + Toppings.Sum(t => t.Topping.Price);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetFormattedTotalPrice()
|
||||||
|
{
|
||||||
|
return GetTotalPrice().ToString("0.00");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
namespace BlazingPizza
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a pre-configured template for a pizza a user can order
|
||||||
|
/// </summary>
|
||||||
|
public class PizzaSpecial
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public int BasePrice { get; set; }
|
||||||
|
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
public string ImageUrl { get; set; }
|
||||||
|
|
||||||
|
public string GetFormattedBasePrice() => BasePrice.ToString("0.00");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
namespace BlazingPizza
|
||||||
|
{
|
||||||
|
public class PizzaTopping
|
||||||
|
{
|
||||||
|
public Topping Topping { get; set; }
|
||||||
|
|
||||||
|
public int ToppingId { get; set; }
|
||||||
|
|
||||||
|
public int PizzaId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
namespace BlazingPizza
|
||||||
|
{
|
||||||
|
public class Topping
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public decimal Price { get; set; }
|
||||||
|
|
||||||
|
public string GetFormattedPrice() => Price.ToString("0.00");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace BlazingPizza
|
||||||
|
{
|
||||||
|
public class UserInfo
|
||||||
|
{
|
||||||
|
public bool IsAuthenticated { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace BlazingPizza.Server
|
||||||
|
{
|
||||||
|
public class OrderState
|
||||||
|
{
|
||||||
|
private readonly ILogger<OrderState> logger;
|
||||||
|
|
||||||
|
public OrderState(ILogger<OrderState> logger)
|
||||||
|
{
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ShowingConfigureDialog { get; private set; }
|
||||||
|
|
||||||
|
public Pizza ConfiguringPizza { get; private set; }
|
||||||
|
|
||||||
|
public Order Order { get; private set; } = new Order();
|
||||||
|
|
||||||
|
public void ShowConfigurePizzaDialog(PizzaSpecial special)
|
||||||
|
{
|
||||||
|
logger.LogInformation($"Configuring pizza {special.Id}");
|
||||||
|
|
||||||
|
ConfiguringPizza = new Pizza()
|
||||||
|
{
|
||||||
|
Special = special,
|
||||||
|
SpecialId = special.Id,
|
||||||
|
Size = Pizza.DefaultSize,
|
||||||
|
Toppings = new List<PizzaTopping>(),
|
||||||
|
};
|
||||||
|
|
||||||
|
ShowingConfigureDialog = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CancelConfigurePizzaDialog()
|
||||||
|
{
|
||||||
|
ConfiguringPizza = null;
|
||||||
|
|
||||||
|
ShowingConfigureDialog = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ConfirmConfigurePizzaDialog()
|
||||||
|
{
|
||||||
|
logger.LogInformation($"Adding pizza {ConfiguringPizza.SpecialId}");
|
||||||
|
|
||||||
|
Order.Pizzas.Add(ConfiguringPizza);
|
||||||
|
ConfiguringPizza = null;
|
||||||
|
|
||||||
|
ShowingConfigureDialog = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveConfiguredPizza(Pizza pizza)
|
||||||
|
{
|
||||||
|
Order.Pizzas.Remove(pizza);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetOrder()
|
||||||
|
{
|
||||||
|
Order = new Order();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReplaceOrder(Order order)
|
||||||
|
{
|
||||||
|
Order = order;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
@page "/checkout"
|
||||||
|
@inject OrderState OrderState
|
||||||
|
|
||||||
|
<div class="main">
|
||||||
|
<EditForm Model="@OrderState.Order.DeliveryAddress">
|
||||||
|
<div class="checkout-cols">
|
||||||
|
<div class="checkout-order-details">
|
||||||
|
<h4>Review order</h4>
|
||||||
|
<OrderReview Order="@OrderState.Order" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="checkout-delivery-address">
|
||||||
|
<h4>Deliver to...</h4>
|
||||||
|
<AddressEditor Address="@OrderState.Order.DeliveryAddress" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="checkout-button btn btn-warning">
|
||||||
|
Place order
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<DataAnnotationsValidator />
|
||||||
|
</EditForm>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@functions {
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
// Try to recover any temporary saved order
|
||||||
|
OrderState.ReplaceOrder(new Order
|
||||||
|
{
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
@page "/"
|
||||||
|
@inject OrderState OrderState
|
||||||
|
@inject IJSRuntime JS
|
||||||
|
@inject SpecialsService Specials
|
||||||
|
|
||||||
|
<div class="main">
|
||||||
|
<ul class="pizza-cards">
|
||||||
|
@if (specials != null)
|
||||||
|
{
|
||||||
|
@foreach (var special in specials)
|
||||||
|
{
|
||||||
|
var id = $"pizza{special.Id}";
|
||||||
|
<li id="@id" @onclick="@(() => OrderState.ShowConfigurePizzaDialog(special))">
|
||||||
|
<div class="pizza-info">
|
||||||
|
<span class="title">@special.Name</span>
|
||||||
|
@special.Description
|
||||||
|
<span class="price">@special.GetFormattedBasePrice()</span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sidebar" id="pizzaOrders" pizzaCount="@Order.Pizzas.Count">
|
||||||
|
@if (Order.Pizzas.Any())
|
||||||
|
{
|
||||||
|
<div class="order-contents">
|
||||||
|
<h2>Your order</h2>
|
||||||
|
|
||||||
|
@foreach (var configuredPizza in Order.Pizzas)
|
||||||
|
{
|
||||||
|
<ConfiguredPizzaItem Pizza="configuredPizza" OnRemoved="@(() => RemovePizza(configuredPizza))" />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="empty-cart">Choose a pizza<br>to get started</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="order-total @(Order.Pizzas.Any() ? "" : "hidden")">
|
||||||
|
Total:
|
||||||
|
<span class="total-price">@Order.GetFormattedTotalPrice()</span>
|
||||||
|
<a href="checkout" class="btn btn-warning" disabled="@(Order.Pizzas.Count == 0)">
|
||||||
|
Order >
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<TemplatedDialog Show="OrderState.ShowingConfigureDialog">
|
||||||
|
<ConfigurePizzaDialog
|
||||||
|
Pizza="OrderState.ConfiguringPizza"
|
||||||
|
OnCancel="OrderState.CancelConfigurePizzaDialog"
|
||||||
|
OnConfirm="OrderState.ConfirmConfigurePizzaDialog" />
|
||||||
|
</TemplatedDialog>
|
||||||
|
|
||||||
|
@functions {
|
||||||
|
IList<PizzaSpecial> specials;
|
||||||
|
Order Order => OrderState.Order;
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
specials = Specials.GetSpecials();
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task RemovePizza(Pizza configuredPizza)
|
||||||
|
{
|
||||||
|
if (await JS.Confirm($"Remove {configuredPizza.Special.Name} pizza from the order?"))
|
||||||
|
{
|
||||||
|
OrderState.RemoveConfiguredPizza(configuredPizza);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
@page "/"
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>BlazorServerSIde</title>
|
||||||
|
<base href="~/" />
|
||||||
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
|
||||||
|
asp-fallback-href="css/bootstrap/bootstrap.min.css"
|
||||||
|
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"/>
|
||||||
|
<link href="css/site.css" rel="stylesheet" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<app>@(await Html.RenderComponentAsync<BlazingPizza.Server.App>(RenderMode.ServerPrerendered))</app>
|
||||||
|
|
||||||
|
<script src="_framework/blazor.server.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
@layout MainLayout
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace BlazingPizza.Server
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
CreateHostBuilder(args).Build().Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||||
|
Host.CreateDefaultBuilder(args)
|
||||||
|
.ConfigureWebHostDefaults(webBuilder =>
|
||||||
|
{
|
||||||
|
webBuilder.UseStartup<Startup>();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
<div class="form-field">
|
||||||
|
<label>Name:</label>
|
||||||
|
<div>
|
||||||
|
<InputText @bind-Value="@Address.Name" />
|
||||||
|
<ValidationMessage For="@(() => Address.Name)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-field">
|
||||||
|
<label>Line 1:</label>
|
||||||
|
<div>
|
||||||
|
<InputText @bind-Value="@Address.Line1" id="Line1" />
|
||||||
|
<ValidationMessage For="@(() => Address.Line1)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-field">
|
||||||
|
<label>Line 2:</label>
|
||||||
|
<div>
|
||||||
|
<InputText @bind-Value="@Address.Line2" />
|
||||||
|
<ValidationMessage For="@(() => Address.Line2)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-field">
|
||||||
|
<label>City:</label>
|
||||||
|
<div>
|
||||||
|
<InputText @bind-Value="@Address.City" />
|
||||||
|
<ValidationMessage For="@(() => Address.City)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-field">
|
||||||
|
<label>Region:</label>
|
||||||
|
<div>
|
||||||
|
<InputText @bind-Value="@Address.Region" />
|
||||||
|
<ValidationMessage For="@(() => Address.Region)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-field">
|
||||||
|
<label>Postal code:</label>
|
||||||
|
<div>
|
||||||
|
<InputText @bind-Value="@Address.PostalCode" />
|
||||||
|
<ValidationMessage For="@(() => Address.PostalCode)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@functions {
|
||||||
|
[Parameter] public Address Address { get; set; }
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
@inject ToppingsService ToppingsService
|
||||||
|
|
||||||
|
<div class="dialog-title">
|
||||||
|
<h2>@Pizza.Special.Name</h2>
|
||||||
|
@Pizza.Special.Description
|
||||||
|
</div>
|
||||||
|
<form class="dialog-body">
|
||||||
|
<div>
|
||||||
|
<label>Size:</label>
|
||||||
|
<input type="range" min="@Pizza.MinimumSize" max="@Pizza.MaximumSize" step="1" @bind-value="@Pizza.Size" @bind-value:event="oninput" />
|
||||||
|
<span class="size-label">
|
||||||
|
@(Pizza.Size)" (£@(Pizza.GetFormattedTotalPrice()))
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>Extra Toppings:</label>
|
||||||
|
@if (toppings == null)
|
||||||
|
{
|
||||||
|
<select class="custom-select" disabled>
|
||||||
|
<option>(loading...)</option>
|
||||||
|
</select>
|
||||||
|
}
|
||||||
|
else if (Pizza.Toppings.Count >= 6)
|
||||||
|
{
|
||||||
|
<div>(maximum reached)</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<select id="custom-select" class="custom-select" @onchange="@ToppingSelected">
|
||||||
|
<option value="-1" disabled selected>(select)</option>
|
||||||
|
@for (var i = 0; i < toppings.Count; i++)
|
||||||
|
{
|
||||||
|
<option value="@i">@toppings[i].Name - (£@(toppings[i].GetFormattedPrice()))</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="toppings">
|
||||||
|
@foreach (var topping in Pizza.Toppings)
|
||||||
|
{
|
||||||
|
<div class="topping">
|
||||||
|
@topping.Topping.Name
|
||||||
|
<span class="topping-price">@topping.Topping.GetFormattedPrice()</span>
|
||||||
|
<button type="button" class="delete-topping" @onclick="@(() => RemoveTopping(topping.Topping))">x</button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="dialog-buttons">
|
||||||
|
<button class="btn btn-secondary mr-auto" @onclick="@OnCancel" id="cancel">Cancel</button>
|
||||||
|
<span class="mr-center">
|
||||||
|
Price: <span class="price">@(Pizza.GetFormattedTotalPrice())</span>
|
||||||
|
</span>
|
||||||
|
<button class="btn btn-success ml-auto" @onclick="@OnConfirm" id="confirm">Order ></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@functions {
|
||||||
|
IList<Topping> toppings;
|
||||||
|
|
||||||
|
[Parameter] public Pizza Pizza { get; set; }
|
||||||
|
[Parameter] public EventCallback OnCancel { get; set; }
|
||||||
|
[Parameter] public EventCallback OnConfirm { get; set; }
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
toppings = ToppingsService.GetToppings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToppingSelected(ChangeEventArgs e)
|
||||||
|
{
|
||||||
|
if (int.TryParse((string)e.Value, out var index) && index >= 0)
|
||||||
|
{
|
||||||
|
AddTopping(toppings[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddTopping(Topping topping)
|
||||||
|
{
|
||||||
|
if (Pizza.Toppings.Find(pt => pt.Topping == topping) == null)
|
||||||
|
{
|
||||||
|
Pizza.Toppings.Add(new PizzaTopping() { Topping = topping });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveTopping(Topping topping)
|
||||||
|
{
|
||||||
|
Pizza.Toppings.RemoveAll(pt => pt.Topping == topping);
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<div class="cart-item">
|
||||||
|
<a @onclick="@OnRemoved" class="delete-item">x</a>
|
||||||
|
<div class="title">@(Pizza.Size)" @Pizza.Special.Name</div>
|
||||||
|
<ul>
|
||||||
|
@foreach (var topping in Pizza.Toppings)
|
||||||
|
{
|
||||||
|
<li>+ @topping.Topping.Name</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
<div class="item-price">
|
||||||
|
@Pizza.GetFormattedTotalPrice()
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@functions {
|
||||||
|
[Parameter] public Pizza Pizza { get; set; }
|
||||||
|
[Parameter] public EventCallback OnRemoved { get; set; }
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
@inherits LayoutComponentBase
|
||||||
|
|
||||||
|
<div class="top-bar">
|
||||||
|
<img class="logo" src="img/logo.svg" />
|
||||||
|
|
||||||
|
<NavLink href="" class="nav-tab" Match="NavLinkMatch.All">
|
||||||
|
<img src="img/pizza-slice.svg" />
|
||||||
|
<div>Get Pizza</div>
|
||||||
|
</NavLink>
|
||||||
|
|
||||||
|
<NavLink href="myorders" class="nav-tab">
|
||||||
|
<img src="img/bike.svg" />
|
||||||
|
<div>My Orders</div>
|
||||||
|
</NavLink>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
@Body
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
@foreach (var pizza in Order.Pizzas)
|
||||||
|
{
|
||||||
|
<p>
|
||||||
|
<strong>
|
||||||
|
@(pizza.Size)"
|
||||||
|
@pizza.Special.Name
|
||||||
|
(£@pizza.GetFormattedTotalPrice())
|
||||||
|
</strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
@foreach (var topping in pizza.Toppings)
|
||||||
|
{
|
||||||
|
<li>+ @topping.Topping.Name</li>
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>
|
||||||
|
Total price:
|
||||||
|
£@Order.GetFormattedTotalPrice()
|
||||||
|
</strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
@functions {
|
||||||
|
[Parameter] public Order Order { get; set; }
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
@if (Show)
|
||||||
|
{
|
||||||
|
<div class="dialog-container">
|
||||||
|
<div class="dialog">
|
||||||
|
@ChildContent
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
@functions {
|
||||||
|
[Parameter] public RenderFragment ChildContent { get; set; }
|
||||||
|
[Parameter] public bool Show { get; set; }
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
@typeparam TItem
|
||||||
|
|
||||||
|
@if (items == null)
|
||||||
|
{
|
||||||
|
@LoadingContent
|
||||||
|
}
|
||||||
|
else if (items.Count == 0)
|
||||||
|
{
|
||||||
|
@EmptyContent
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="list-group @ListGroupClass">
|
||||||
|
@foreach (var item in items)
|
||||||
|
{
|
||||||
|
<div class="list-group-item">
|
||||||
|
@ItemContent(item)
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
@functions {
|
||||||
|
List<TItem> items;
|
||||||
|
|
||||||
|
[Parameter] public Func<Task<List<TItem>>> Loader { get; set; }
|
||||||
|
[Parameter] public RenderFragment LoadingContent { get; set; }
|
||||||
|
[Parameter] public RenderFragment EmptyContent { get; set; }
|
||||||
|
[Parameter] public RenderFragment<TItem> ItemContent { get; set; }
|
||||||
|
[Parameter] public string ListGroupClass { get; set; }
|
||||||
|
|
||||||
|
protected override async Task OnParametersSetAsync()
|
||||||
|
{
|
||||||
|
items = await Loader();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace BlazingPizza.Server
|
||||||
|
{
|
||||||
|
public class SpecialsService
|
||||||
|
{
|
||||||
|
public IList<PizzaSpecial> GetSpecials()
|
||||||
|
{
|
||||||
|
return new PizzaSpecial[]
|
||||||
|
{
|
||||||
|
new PizzaSpecial()
|
||||||
|
{
|
||||||
|
Name = "Basic Cheese Pizza",
|
||||||
|
Description = "It's cheesy and delicious. Why wouldn't you want one?",
|
||||||
|
BasePrice = 9,
|
||||||
|
ImageUrl = "img/pizzas/cheese.jpg",
|
||||||
|
},
|
||||||
|
new PizzaSpecial()
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Name = "The Baconatorizor",
|
||||||
|
Description = "It has EVERY kind of bacon",
|
||||||
|
BasePrice = 12,
|
||||||
|
ImageUrl = "img/pizzas/bacon.jpg",
|
||||||
|
},
|
||||||
|
new PizzaSpecial()
|
||||||
|
{
|
||||||
|
Id = 3,
|
||||||
|
Name = "Classic pepperoni",
|
||||||
|
Description = "It's the pizza you grew up with, but Blazing hot!",
|
||||||
|
BasePrice = 10,
|
||||||
|
ImageUrl = "img/pizzas/pepperoni.jpg",
|
||||||
|
},
|
||||||
|
new PizzaSpecial()
|
||||||
|
{
|
||||||
|
Id = 4,
|
||||||
|
Name = "Buffalo chicken",
|
||||||
|
Description = "Spicy chicken, hot sauce and bleu cheese, guaranteed to warm you up",
|
||||||
|
BasePrice = 12,
|
||||||
|
ImageUrl = "img/pizzas/meaty.jpg",
|
||||||
|
},
|
||||||
|
new PizzaSpecial()
|
||||||
|
{
|
||||||
|
Id = 5,
|
||||||
|
Name = "Mushroom Lovers",
|
||||||
|
Description = "It has mushrooms. Isn't that obvious?",
|
||||||
|
BasePrice = 11,
|
||||||
|
ImageUrl = "img/pizzas/mushroom.jpg",
|
||||||
|
},
|
||||||
|
new PizzaSpecial()
|
||||||
|
{
|
||||||
|
Id = 6,
|
||||||
|
Name = "The Brit",
|
||||||
|
Description = "When in London...",
|
||||||
|
BasePrice = 10,
|
||||||
|
ImageUrl = "img/pizzas/brit.jpg",
|
||||||
|
},
|
||||||
|
new PizzaSpecial()
|
||||||
|
{
|
||||||
|
Id = 7,
|
||||||
|
Name = "Veggie Delight",
|
||||||
|
Description = "It's like salad, but on a pizza",
|
||||||
|
BasePrice = 11,
|
||||||
|
ImageUrl = "img/pizzas/salad.jpg",
|
||||||
|
},
|
||||||
|
new PizzaSpecial()
|
||||||
|
{
|
||||||
|
Id = 8,
|
||||||
|
Name = "Margherita",
|
||||||
|
Description = "Traditional Italian pizza with tomatoes and basil",
|
||||||
|
BasePrice = 9,
|
||||||
|
ImageUrl = "img/pizzas/margherita.jpg",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.ResponseCompression;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Mime;
|
||||||
|
|
||||||
|
namespace BlazingPizza.Server
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public Startup(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
Configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IConfiguration Configuration { get; }
|
||||||
|
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddMvc();
|
||||||
|
|
||||||
|
services.AddServerSideBlazor(options => options.DetailedErrors = true);
|
||||||
|
|
||||||
|
services.AddScoped<OrderState>();
|
||||||
|
services.AddScoped<SpecialsService>();
|
||||||
|
services.AddScoped<ToppingsService>();
|
||||||
|
|
||||||
|
services.AddResponseCompression(options =>
|
||||||
|
{
|
||||||
|
options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
|
||||||
|
new[] { MediaTypeNames.Application.Octet });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||||
|
{
|
||||||
|
app.UseResponseCompression();
|
||||||
|
|
||||||
|
if (env.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseDeveloperExceptionPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseStaticFiles();
|
||||||
|
|
||||||
|
app.UseRouting();
|
||||||
|
|
||||||
|
app.UseEndpoints(endpoints =>
|
||||||
|
{
|
||||||
|
endpoints.MapBlazorHub();
|
||||||
|
endpoints.MapFallbackToPage("/_Host");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,124 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace BlazingPizza.Server
|
||||||
|
{
|
||||||
|
public class ToppingsService
|
||||||
|
{
|
||||||
|
public IList<Topping> GetToppings()
|
||||||
|
{
|
||||||
|
return new Topping[]
|
||||||
|
{
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Extra cheese",
|
||||||
|
Price = 2.50m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "American bacon",
|
||||||
|
Price = 2.99m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "British bacon",
|
||||||
|
Price = 2.99m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Canadian bacon",
|
||||||
|
Price = 2.99m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Tea and crumpets",
|
||||||
|
Price = 5.00m
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Fresh-baked scones",
|
||||||
|
Price = 4.50m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Bell peppers",
|
||||||
|
Price = 1.00m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Onions",
|
||||||
|
Price = 1.00m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Mushrooms",
|
||||||
|
Price = 1.00m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Pepperoni",
|
||||||
|
Price = 1.00m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Duck sausage",
|
||||||
|
Price = 3.20m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Venison meatballs",
|
||||||
|
Price = 2.50m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Served on a silver platter",
|
||||||
|
Price = 250.99m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Lobster on top",
|
||||||
|
Price = 64.50m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Sturgeon caviar",
|
||||||
|
Price = 101.75m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Artichoke hearts",
|
||||||
|
Price = 3.40m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Fresh tomatos",
|
||||||
|
Price = 1.50m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Basil",
|
||||||
|
Price = 1.50m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Steak (medium-rare)",
|
||||||
|
Price = 8.50m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Blazing hot peppers",
|
||||||
|
Price = 4.20m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Buffalo chicken",
|
||||||
|
Price = 5.00m,
|
||||||
|
},
|
||||||
|
new Topping()
|
||||||
|
{
|
||||||
|
Name = "Blue cheese",
|
||||||
|
Price = 2.50m,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
@using System.Net.Http
|
||||||
|
@using Microsoft.AspNetCore.Authorization
|
||||||
|
@using Microsoft.AspNetCore.Components.Forms
|
||||||
|
@using Microsoft.AspNetCore.Components.Routing
|
||||||
|
@using Microsoft.AspNetCore.Components.Web
|
||||||
|
@using Microsoft.JSInterop
|
||||||
|
@using BlazingPizza.Server
|
||||||
|
@using BlazingPizza.Server.Shared
|
||||||
|
@using System.Security.Claims
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Debug",
|
||||||
|
"System": "Information",
|
||||||
|
"Microsoft": "Information"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/Components/benchmarkapps/BlazingPizza.Server/wwwroot/css/bootstrap/bootstrap.min.css
vendored
Normal file
7
src/Components/benchmarkapps/BlazingPizza.Server/wwwroot/css/bootstrap/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,40 @@
|
||||||
|
/* quicksand-300 - latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Quicksand';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
src: local('Quicksand Light'), local('Quicksand-Light'),
|
||||||
|
url('quicksand-v8-latin-300.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
|
||||||
|
url('quicksand-v8-latin-300.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* quicksand-regular - latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Quicksand';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: local('Quicksand Regular'), local('Quicksand-Regular'),
|
||||||
|
url('quicksand-v8-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
|
||||||
|
url('quicksand-v8-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* quicksand-500 - latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Quicksand';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: local('Quicksand Medium'), local('Quicksand-Medium'),
|
||||||
|
url('quicksand-v8-latin-500.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
|
||||||
|
url('quicksand-v8-latin-500.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* quicksand-700 - latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Quicksand';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: local('Quicksand Bold'), local('Quicksand-Bold'),
|
||||||
|
url('quicksand-v8-latin-700.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
|
||||||
|
url('quicksand-v8-latin-700.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,736 @@
|
||||||
|
@import url('font/quicksand.css');
|
||||||
|
|
||||||
|
body, html {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding-top: 5rem;
|
||||||
|
flex-direction: column;
|
||||||
|
font-family: 'quicksand';
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group.row > .col-form-label {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-bar {
|
||||||
|
height: 5rem;
|
||||||
|
background-color: rgb(192,0,0);
|
||||||
|
background-image: linear-gradient(rgba(0,0,0,0.3) 0%, rgba(0,0,0,0) 70%);
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
color: white;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
|
||||||
|
padding: 0 3rem;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1030;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
margin-right: 3rem;
|
||||||
|
width: 9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
flex-grow: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
background: linear-gradient(rgba(0,0,0,0) 40%, rgba(0,0,0,0.4) 80%);
|
||||||
|
padding: 1.5rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tab {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0.3rem 1.8rem;
|
||||||
|
display: inline-block;
|
||||||
|
background-color: rgba(0,0,0,0.1);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: white;
|
||||||
|
position: relative;
|
||||||
|
text-transform: uppercase;
|
||||||
|
transition: 0.2s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tab:hover {
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: rgba(255,255,255,0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tab.active {
|
||||||
|
background-color: rgba(255,255,255,0.2);
|
||||||
|
color: #fff2cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tab img {
|
||||||
|
height: 2rem;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tab.active img {
|
||||||
|
filter: brightness(0) saturate(100%) invert(93%) sepia(18%) saturate(797%) hue-rotate(316deg) brightness(109%) contrast(101%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tab.active:after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
bottom: -1rem;
|
||||||
|
z-index: 1;
|
||||||
|
width: 0px;
|
||||||
|
height: 0px;
|
||||||
|
border-left: 0.6rem solid transparent;
|
||||||
|
border-right: 0.6rem solid transparent;
|
||||||
|
border-top: 1rem solid rgb(205,51,51);
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info {
|
||||||
|
margin-left: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info img {
|
||||||
|
margin-right: 0.7rem;
|
||||||
|
width: 2.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info .username {
|
||||||
|
display: block;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 0.7rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info a {
|
||||||
|
color: #fff2cc;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pizza-cards {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, 20rem);
|
||||||
|
grid-gap: 2rem;
|
||||||
|
justify-content: center;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pizza-cards > li {
|
||||||
|
height: 10rem;
|
||||||
|
position: relative;
|
||||||
|
background-size: cover;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
list-style-type: none;
|
||||||
|
box-shadow: 0 3px 4px rgba(0,0,0,0.4);
|
||||||
|
transition: 0.1s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pizza-cards > li:hover {
|
||||||
|
transform: scale(1.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pizza-info {
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
position: absolute;
|
||||||
|
background: linear-gradient(rgba(0,0,0,0.7) 30%, rgba(0,0,0,0) 80%);
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
color: #fff2cc;
|
||||||
|
cursor: pointer;
|
||||||
|
text-shadow: 0 2px 2px rgba(0,0,0,0.5);
|
||||||
|
line-height: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pizza-info .title {
|
||||||
|
color: white;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
display: block;
|
||||||
|
margin: 0.2rem 0 0.4rem 0;
|
||||||
|
font-family: 'Bahnschrift', Arial, Helvetica, sans-serif;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pizza-info .price {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0.5rem;
|
||||||
|
right: 1rem;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 700;
|
||||||
|
padding: 0rem 0.7rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #08af08;
|
||||||
|
color: white;
|
||||||
|
line-height: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price::before {
|
||||||
|
content: '£';
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin-right: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
background-color: #2b2b2b;
|
||||||
|
width: 20rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-contents {
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 2rem 1.5rem 1.5rem 1.5rem;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-contents h2 {
|
||||||
|
color: #fff2cc;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
font-weight: 300;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-family: 'Bahnschrift', Arial, Helvetica, sans-serif;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-total {
|
||||||
|
background-color: rgb(191, 52, 52);
|
||||||
|
height: 4rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
color: white;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
transition: all 600ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||||||
|
padding: 0 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-total.hidden {
|
||||||
|
transform: translate3d(0, 4rem, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-total .total-price {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-total .total-price::before {
|
||||||
|
content: '£';
|
||||||
|
font-weight: 300;
|
||||||
|
margin: 0 0.1rem 0 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-total .btn {
|
||||||
|
margin-left: auto;
|
||||||
|
font-weight: 700;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 0.4rem 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkout-button {
|
||||||
|
margin: auto;
|
||||||
|
display: block;
|
||||||
|
font-weight: 700;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 0.4rem 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cart-item {
|
||||||
|
background-color: #333333;
|
||||||
|
padding: 0.8rem 1.2rem;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-weight: 100;
|
||||||
|
margin-top: 1rem;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cart-item .title {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cart-item ul {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0.4rem 0.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cart-item li {
|
||||||
|
list-style-type: none;
|
||||||
|
margin-left: 0rem;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-cart {
|
||||||
|
text-align: center;
|
||||||
|
margin: auto;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 100;
|
||||||
|
color: #676767;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-price {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-price::before {
|
||||||
|
content: '£';
|
||||||
|
font-weight: 100;
|
||||||
|
margin-right: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-item {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
content: 'X';
|
||||||
|
cursor: pointer;
|
||||||
|
color: #fff2cc;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-item:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #fff2cc;
|
||||||
|
background-color: rgba(255,255,255,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.configured-pizza-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: rgba(0,0,0,0.5);
|
||||||
|
z-index: 2000;
|
||||||
|
display: flex;
|
||||||
|
animation: dialog-container-entry 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dialog-container-entry {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog {
|
||||||
|
background-color: white;
|
||||||
|
box-shadow: 0 0 12px rgba(0,0,0,0.6);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
z-index: 2000;
|
||||||
|
align-self: center;
|
||||||
|
margin: auto;
|
||||||
|
width: 700px;
|
||||||
|
max-height: calc(100% - 3rem);
|
||||||
|
animation: dialog-entry 0.4s;
|
||||||
|
animation-timing-function: cubic-bezier(0.075, 0.820, 0.165, 1.000);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dialog-entry {
|
||||||
|
0% {
|
||||||
|
transform: translateY(30px) scale(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateX(0px) scale(1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-title {
|
||||||
|
background-color: #444;
|
||||||
|
color: #fff2cc;
|
||||||
|
padding: 1.3rem 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-title h2 {
|
||||||
|
color: white;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
margin: 0;
|
||||||
|
font-family: 'Bahnschrift', Arial, Helvetica, sans-serif;
|
||||||
|
text-transform: uppercase;
|
||||||
|
line-height: 1.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-body {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 0.5rem 3rem 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-buttons {
|
||||||
|
height: 4rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #eee;
|
||||||
|
padding: 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-body > div {
|
||||||
|
display: flex;
|
||||||
|
margin-top: 1rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-body label {
|
||||||
|
text-align: right;
|
||||||
|
width: 200px;
|
||||||
|
margin: 0 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-body input, .dialog-body select {
|
||||||
|
flex-grow: 1;
|
||||||
|
width: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-body .size-label {
|
||||||
|
min-width: 110px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog .toppings {
|
||||||
|
text-align: center;
|
||||||
|
display: block;
|
||||||
|
padding-left: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog .topping {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: #a04343;
|
||||||
|
color: white;
|
||||||
|
padding: 0.2rem 1rem;
|
||||||
|
border-radius: 2rem;
|
||||||
|
margin: 0.4rem 0.3rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog .topping-price {
|
||||||
|
font-weight: 100;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog .topping-price::before {
|
||||||
|
content: '£';
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-topping {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
padding: 0.2rem 0.2rem 0.3rem 0.2rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-topping:hover {
|
||||||
|
color: yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-message {
|
||||||
|
padding: 0.5rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog .price {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.orders-list .list-group-item {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.orders-list .col {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.orders-list h5 {
|
||||||
|
color: #c03939;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
font-weight: 300;
|
||||||
|
margin: 0.2rem 0 0 0;
|
||||||
|
font-family: 'Bahnschrift', Arial, Helvetica, sans-serif;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.track-order {
|
||||||
|
background-color: white;
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.4);
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.track-order > div {
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.track-order-title {
|
||||||
|
background-color: #eee;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1rem 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.track-order-title h2 {
|
||||||
|
color: #c03939;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
font-weight: 300;
|
||||||
|
margin: 0rem;
|
||||||
|
font-family: 'Bahnschrift', Arial, Helvetica, sans-serif;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.track-order-body {
|
||||||
|
flex-grow: 1;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.track-order-details {
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 1.5rem 3rem;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.track-order-map {
|
||||||
|
width: 350px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.sign-in {
|
||||||
|
background: none;
|
||||||
|
border: 1.5px solid white;
|
||||||
|
border-radius: 0.7em;
|
||||||
|
color: white;
|
||||||
|
text-transform: uppercase;
|
||||||
|
padding: 0.2rem 0.8rem 0.1rem 0.8rem;
|
||||||
|
font-family: 'Bahnschrift', Arial, Helvetica, sans-serif;
|
||||||
|
font-weight: 100;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: 0.2s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.sign-in:hover {
|
||||||
|
background-color: rgba(255,255,255,0.3);
|
||||||
|
color: #fff2cc;
|
||||||
|
border-color: #fff2cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info a.sign-out {
|
||||||
|
color: #fff2cc;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info a.sign-out:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range] {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin: 7.1px 0;
|
||||||
|
height: 21px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-webkit-slider-runnable-track {
|
||||||
|
width: 100%;
|
||||||
|
height: 5.8px;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0px 0px 1px #000000, 0px 0px 0px #0d0d0d;
|
||||||
|
background: #dcdcdc;
|
||||||
|
border-radius: 1.3px;
|
||||||
|
border: 0px solid #010101;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-webkit-slider-thumb {
|
||||||
|
box-shadow: 0.9px 0.9px 1px rgba(0, 0, 49, 0.43), 0px 0px 0.9px rgba(0, 0, 75, 0.43);
|
||||||
|
border: 0px solid #00001e;
|
||||||
|
height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #d45352;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin-top: -7.1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]:focus::-webkit-slider-runnable-track {
|
||||||
|
background: #e1e1e1;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-moz-range-track {
|
||||||
|
width: 100%;
|
||||||
|
height: 5.8px;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0px 0px 1px #000000, 0px 0px 0px #0d0d0d;
|
||||||
|
background: #dcdcdc;
|
||||||
|
border-radius: 1.3px;
|
||||||
|
border: 0px solid #010101;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-moz-range-thumb {
|
||||||
|
box-shadow: 0.9px 0.9px 1px rgba(0, 0, 49, 0.43), 0px 0px 0.9px rgba(0, 0, 75, 0.43);
|
||||||
|
border: 0px solid #00001e;
|
||||||
|
height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #d45352;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-ms-track {
|
||||||
|
width: 100%;
|
||||||
|
height: 5.8px;
|
||||||
|
cursor: pointer;
|
||||||
|
background: transparent;
|
||||||
|
border-color: transparent;
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-ms-fill-lower {
|
||||||
|
background: #d7d7d7;
|
||||||
|
border: 0px solid #010101;
|
||||||
|
border-radius: 2.6px;
|
||||||
|
box-shadow: 0px 0px 1px #000000, 0px 0px 0px #0d0d0d;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-ms-fill-upper {
|
||||||
|
background: #dcdcdc;
|
||||||
|
border: 0px solid #010101;
|
||||||
|
border-radius: 2.6px;
|
||||||
|
box-shadow: 0px 0px 1px #000000, 0px 0px 0px #0d0d0d;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-ms-thumb {
|
||||||
|
box-shadow: 0.9px 0.9px 1px rgba(0, 0, 49, 0.43), 0px 0px 0.9px rgba(0, 0, 75, 0.43);
|
||||||
|
border: 0px solid #00001e;
|
||||||
|
height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #d45352;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkout-cols {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.checkout-cols h4 {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkout-cols > div {
|
||||||
|
flex: 1;
|
||||||
|
margin: 1rem;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
background: rgba(255,255,255,0.3);
|
||||||
|
padding: 1.25rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkout-cols > div:first-child {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkout-cols > div:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-bar {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(50% - 3px);
|
||||||
|
left: calc(50% - 250px);
|
||||||
|
width: 500px;
|
||||||
|
height: 6px;
|
||||||
|
background-color: white;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 1px 3px rgba(0,0,0,0.2)
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-bar::after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: 200px;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #dc105a;
|
||||||
|
animation: progressbar-slide 1s infinite;
|
||||||
|
animation-timing-function: ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-field {
|
||||||
|
display: flex;
|
||||||
|
margin: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-field > label {
|
||||||
|
width: 8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-field > div {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-field input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.valid.modified:not([type=checkbox]) {
|
||||||
|
outline: 1px solid #26b050;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invalid {
|
||||||
|
outline: 1px solid red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.validation-message {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes progressbar-slide {
|
||||||
|
0% {
|
||||||
|
transform: translateX(-200px);
|
||||||
|
}
|
||||||
|
|
||||||
|
70% {
|
||||||
|
transform: translateX(500px);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateX(500px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="14.566216mm"
|
||||||
|
height="12.915195mm"
|
||||||
|
viewBox="0 0 14.566216 12.915195"
|
||||||
|
version="1.1"
|
||||||
|
id="svg6773"
|
||||||
|
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||||
|
sodipodi:docname="bike.svg">
|
||||||
|
<defs
|
||||||
|
id="defs6767" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="0.35"
|
||||||
|
inkscape:cx="-495.3304"
|
||||||
|
inkscape:cy="-464.16476"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="3018"
|
||||||
|
inkscape:window-height="1744"
|
||||||
|
inkscape:window-x="665"
|
||||||
|
inkscape:window-y="3070"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata6770">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-14.639502,-13.107878)">
|
||||||
|
<path
|
||||||
|
d="m 24.422045,14.741241 c 0,0.80786 -0.65263,1.4605 -1.4605,1.4605 -0.80786,0 -1.46402,-0.65264 -1.46402,-1.4605 0,-0.80786 0.65616,-1.46403 1.46402,-1.46403 0.80787,0 1.4605,0.65617 1.4605,1.46403 z"
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.33866665;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path4889"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 19.426715,23.546573 c 0,1.273528 -1.03364,2.307167 -2.30717,2.307167 -1.27352,0 -2.30716,-1.033639 -2.30716,-2.307167 0,-1.273528 1.03364,-2.307166 2.30716,-2.307166 1.27353,0 2.30717,1.033638 2.30717,2.307166 z"
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.33866665;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path4891"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 29.036385,23.546573 c 0,1.273528 -1.03364,2.307167 -2.30717,2.307167 -1.27353,0 -2.30717,-1.033639 -2.30717,-2.307167 0,-1.273528 1.03364,-2.307166 2.30717,-2.307166 1.27353,0 2.30717,1.033638 2.30717,2.307166 z"
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.33866665;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path4893"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 22.587605,19.711881 -1.04422,-0.10231 0.98072,-1.70039 2.23661,1.21709 c -0.0212,0.0212 -0.0212,0.0423 -0.0423,0.0635 l -1.7533,0.98425 v -0.0423 c 0,-0.20814 -0.16934,-0.39864 -0.37748,-0.4198 z m 4.13808,0.88194 c 0.39864,0 0.77611,0.0847 1.10772,0.22931 0.21167,-0.37747 0.35631,-0.81845 0.35631,-1.27706 0,-1.38289 -1.12889,-2.5153 -2.50825,-2.5153 -0.2928,0 -0.56444,0.0635 -0.83608,0.14816 0.10583,0.20814 0.1658,0.43745 0.18697,0.69145 l -2.82222,-1.55222 c -0.0423,-0.0212 -0.0811,-0.0423 -0.12347,-0.0423 -0.48331,-0.18697 -1.02659,-0.0212 -1.29823,0.44097 l -1.46402,2.51531 c -0.0176,0.0423 -0.0388,0.10231 -0.06,0.14464 l -4.45558,-0.45861 v 0.83608 l 3.13619,0.96308 c 1.21356,0.35631 2.09198,1.488727 2.09198,2.808115 0,0.296334 -0.0423,0.567973 -0.127,0.839612 h 4.01461 c -0.0811,-0.271639 -0.12347,-0.543278 -0.12347,-0.839612 0,-1.612194 1.31586,-2.931585 2.92452,-2.931585 z"
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:0.33866665;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path4895"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.1 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 43 KiB |
|
|
@ -0,0 +1,106 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="12.864264mm"
|
||||||
|
height="12.890507mm"
|
||||||
|
viewBox="0 0 12.864264 12.890507"
|
||||||
|
version="1.1"
|
||||||
|
id="svg7666"
|
||||||
|
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||||
|
sodipodi:docname="pizza-slice.svg">
|
||||||
|
<defs
|
||||||
|
id="defs7660">
|
||||||
|
<clipPath
|
||||||
|
clipPathUnits="userSpaceOnUse"
|
||||||
|
id="clipPath4885">
|
||||||
|
<path
|
||||||
|
d="M -3.9725e-5,540 H 960 V 1.2207e-4 L -4.3448e-5,6.1035e-5"
|
||||||
|
id="path4883"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="clip-rule:evenodd" />
|
||||||
|
</clipPath>
|
||||||
|
<clipPath
|
||||||
|
clipPathUnits="userSpaceOnUse"
|
||||||
|
id="clipPath4875">
|
||||||
|
<path
|
||||||
|
d="M -1.9395e-5,540 H 960 V 1.2207e-4 L -2.3118e-5,6.1035e-5"
|
||||||
|
id="path4873"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
style="clip-rule:evenodd" />
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="0.35"
|
||||||
|
inkscape:cx="-538.54671"
|
||||||
|
inkscape:cy="-372.78284"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="3018"
|
||||||
|
inkscape:window-height="1744"
|
||||||
|
inkscape:window-x="665"
|
||||||
|
inkscape:window-y="3070"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7663">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-26.073816,-37.310701)">
|
||||||
|
<g
|
||||||
|
id="g4869"
|
||||||
|
transform="matrix(0.35277777,0,0,-0.35277777,-82.464891,223.70045)"
|
||||||
|
style="stroke:#ffffff;stroke-opacity:1">
|
||||||
|
<g
|
||||||
|
id="g4871"
|
||||||
|
clip-path="url(#clipPath4875)"
|
||||||
|
style="stroke:#ffffff;stroke-opacity:1">
|
||||||
|
<path
|
||||||
|
d="m 331.92,516.06 c 0,0 -0.03,0.03 0,0 -0.03,0.03 -0.03,0.03 -0.03,0.03 -3.14,3.13 -6.77,5.57 -10.84,7.23 0,0 0,0 0,0 l -12.47,-30.6 30.61,12.47 c 0,0 0,0 0,0 -1.7,4.1 -4.13,7.73 -7.27,10.87 z m -10.3,-1.7 c -1.13,1.13 -1.13,2.93 -0.03,4.03 1.1,1.1 2.9,1.1 4.03,-0.03 1.13,-1.14 1.13,-2.94 0.03,-4.04 -1.1,-1.1 -2.9,-1.1 -4.03,0.04 z m -8.27,-14.94 2.3,5.63 c 0.5,-0.16 0.97,-0.36 1.37,-0.76 1.2,-1.2 1.2,-3.14 0,-4.34 -1,-1 -2.5,-1.16 -3.67,-0.53 z m 12.14,5.07 c -1.14,1.13 -1.14,2.93 -0.04,4.03 1.1,1.1 2.9,1.1 4.04,-0.03 1.13,-1.14 1.13,-2.94 0.03,-4.04 -1.1,-1.1 -2.9,-1.1 -4.03,0.04 z"
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path4877"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g4879"
|
||||||
|
transform="matrix(0.35277777,0,0,-0.35277777,-82.464891,223.70045)"
|
||||||
|
style="stroke:#ffffff;stroke-opacity:1">
|
||||||
|
<g
|
||||||
|
id="g4881"
|
||||||
|
clip-path="url(#clipPath4885)"
|
||||||
|
style="stroke:#ffffff;stroke-opacity:1">
|
||||||
|
<path
|
||||||
|
d="m 343.52,506.99 c -1.93,4.67 -4.73,8.87 -8.3,12.43 -3.6,3.6 -7.77,6.37 -12.37,8.31 -0.73,0.33 -1.56,-0.04 -1.83,-0.77 -0.27,-0.73 0.07,-1.53 0.8,-1.87 4.23,-1.76 8.07,-4.33 11.4,-7.67 3.34,-3.33 5.9,-7.16 7.7,-11.5 0.07,-0.2 0.2,-0.33 0.34,-0.47 0.4,-0.4 1,-0.53 1.53,-0.33 0.7,0.3 1.03,1.17 0.73,1.87 z"
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path4887"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.1 KiB |
|
|
@ -0,0 +1,72 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="15.113004mm"
|
||||||
|
height="15.113004mm"
|
||||||
|
viewBox="0 0 15.113004 15.113004"
|
||||||
|
version="1.1"
|
||||||
|
id="svg7709"
|
||||||
|
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||||
|
sodipodi:docname="user.svg">
|
||||||
|
<defs
|
||||||
|
id="defs7703" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="0.35"
|
||||||
|
inkscape:cx="-578.58286"
|
||||||
|
inkscape:cy="28.560012"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="3018"
|
||||||
|
inkscape:window-height="1744"
|
||||||
|
inkscape:window-x="665"
|
||||||
|
inkscape:window-y="3070"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7706">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-98.276833,-141.27683)">
|
||||||
|
<path
|
||||||
|
d="m 98.806,148.83333 c 0,-3.88055 3.14678,-7.02733 7.02733,-7.02733 3.88056,0 7.02734,3.14678 7.02734,7.02733 0,3.88056 -3.14678,7.02734 -7.02734,7.02734 -3.88055,0 -7.02733,-3.14678 -7.02733,-7.02734 z"
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:1.05833328;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path4913"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 108.23222,147.28111 c 0,1.2947 -1.04775,2.34245 -2.34244,2.34245 -1.29117,0 -2.33892,-1.04775 -2.33892,-2.34245 0,-1.29117 1.04775,-2.33892 2.33892,-2.33892 1.29469,0 2.34244,1.04775 2.34244,2.33892 z"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.35277775"
|
||||||
|
id="path4915"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
d="m 110.51117,153.92392 0.0847,-1.66864 c 0,-0.35278 -0.17639,-0.70203 -0.46919,-0.93839 -0.64206,-0.52564 -1.4605,-0.87842 -2.27895,-1.11125 -0.58561,-0.17639 -1.22766,-0.29281 -1.92969,-0.29281 -0.64206,0 -1.28764,0.11642 -1.92969,0.29281 -0.81845,0.23283 -1.63689,0.64558 -2.27895,1.11125 -0.2928,0.23636 -0.46919,0.58561 -0.46919,0.93839 v 1.73214 c 1.46755,0.40569 0.98777,1.64747 4.70605,1.54869 4.36034,-0.25753 2.94217,-1.18533 4.56495,-1.61219 z"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.35277775"
|
||||||
|
id="path4917"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.1 KiB |
|
|
@ -0,0 +1,2 @@
|
||||||
|
<Project>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
<!-- This file prevents any other Directory.Build.targets from a parent folder to be loaded -->
|
||||||
|
<Project>
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
|
<clear />
|
||||||
|
<add key="dotnet-core" value="https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json" />
|
||||||
|
<add key="extensions" value="https://dotnetfeed.blob.core.windows.net/aspnet-extensions/index.json" />
|
||||||
|
<add key="entityframeworkcore" value="https://dotnetfeed.blob.core.windows.net/aspnet-entityframeworkcore/index.json" />
|
||||||
|
<add key="aspnetcore-tooling" value="https://dotnetfeed.blob.core.windows.net/aspnet-aspnetcore-tooling/index.json" />
|
||||||
|
<add key="aspnetcore" value="https://dotnetfeed.blob.core.windows.net/aspnet-aspnetcore/index.json" />
|
||||||
|
<add key="NuGet.org" value="https://api.nuget.org/v3/index.json" />
|
||||||
|
</packageSources>
|
||||||
|
</configuration>
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
## Blazor benchamrks
|
||||||
|
|
||||||
|
These projects assist in Benchmarking Components.
|
||||||
|
See https://github.com/aspnet/Benchmarks#benchmarks for usage guidance on using the Benchmarking tool with your application
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue