ConfigurePizzaDialog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
@inject HttpClient HttpClient
<div class="dialog-container">
<div class="dialog">
<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="Pizza.Size" @bind: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 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">Cancel</button>
<span class="mr-center">
Price: <span class="price">@(Pizza.GetFormattedTotalPrice())</span>
</span>
<button class="btn btn-success ml-auto" @onclick="@OnConfirm">Order ></button>
</div>
</div>
</div>
@code {
List<Topping> toppings;
[Parameter] public Pizza Pizza { get; set; }
[Parameter] public EventCallback OnCancel { get; set; }
[Parameter] public EventCallback OnConfirm { get; set; }
protected async override Task OnInitializedAsync()
{
toppings = await HttpClient.GetJsonAsync<List<Topping>>("toppings");
}
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);
}
}
Index.razor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
@page "/"
@inject HttpClient HttpClient
@inject OrderState OrderState
@inject NavigationManager NavigationManager
<div class="main">
<ul class="pizza-cards">
@if (specials != null)
{
@foreach (var special in specials)
{
<li @onclick="@(() => OrderState.ShowConfigurePizzaDialog(special))" style="background-image: url('@special.ImageUrl')">
<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">
@if (Order.Pizzas.Any())
{
<div class="order-contents">
<h2>Your order</h2>
@foreach (var configuredPizza in Order.Pizzas)
{
<ConfiguredPizzaItem Pizza="configuredPizza" OnRemoved="@(() => OrderState.RemoveConfiguredPizza(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>
@if (OrderState.ShowingConfigureDialog)
{
<ConfigurePizzaDialog
Pizza="@OrderState.ConfiguringPizza"
OnConfirm="@OrderState.ConfirmConfigurePizzaDialog"
OnCancel="@OrderState.CancelConfigurePizzaDialog" />
}
@code {
List<PizzaSpecial> specials;
Order Order => OrderState.Order;
protected async override Task OnInitializedAsync()
{
specials = await HttpClient.GetJsonAsync<List<PizzaSpecial>>("specials");
}
}
OrderState
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using System.Collections.Generic;
namespace BlazingPizza.Client
{
public class OrderState
{
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)
{
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()
{
Order.Pizzas.Add(ConfiguringPizza);
ConfiguringPizza = null;
ShowingConfigureDialog = false;
}
public void RemoveConfiguredPizza(Pizza pizza)
{
Order.Pizzas.Remove(pizza);
}
public void ResetOrder()
{
Order = new Order();
}
}
}