Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
s8_ivanov_r
VPL-pizza-shop-blazor
Commits
551ae3e0
Commit
551ae3e0
authored
Jan 25, 2019
by
Ryan Nowak
Browse files
Add part 3 - order status
parent
4ae51c7e
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
183 additions
and
20 deletions
+183
-20
README.md
README.md
+10
-4
save-points/00-Starting-point/BlazingPizza.Server/OrdersController.cs
...00-Starting-point/BlazingPizza.Server/OrdersController.cs
+4
-4
save-points/01-Components-and-layout/BlazingPizza.Server/OrdersController.cs
...onents-and-layout/BlazingPizza.Server/OrdersController.cs
+4
-4
save-points/02-customize-a-pizza/BlazingPizza.Server/OrdersController.cs
...customize-a-pizza/BlazingPizza.Server/OrdersController.cs
+4
-4
save-points/03-show-order-status/BlazingPizza.Client/Pages/Index.cshtml
...-show-order-status/BlazingPizza.Client/Pages/Index.cshtml
+2
-0
save-points/03-show-order-status/BlazingPizza.Client/Pages/MyOrders.cshtml
...ow-order-status/BlazingPizza.Client/Pages/MyOrders.cshtml
+48
-0
save-points/03-show-order-status/BlazingPizza.Client/Pages/OrderDetails.cshtml
...rder-status/BlazingPizza.Client/Pages/OrderDetails.cshtml
+102
-0
save-points/03-show-order-status/BlazingPizza.Client/Shared/MainLayout.cshtml
...order-status/BlazingPizza.Client/Shared/MainLayout.cshtml
+5
-0
save-points/03-show-order-status/BlazingPizza.Server/OrdersController.cs
...show-order-status/BlazingPizza.Server/OrdersController.cs
+4
-4
No files found.
README.md
View file @
551ae3e0
...
...
@@ -34,13 +34,19 @@ Lunch
-
add a ConfiguredPizzaItem component
-
hook up the order button to do an HTTP POST and clear the order
-
(no way to see existing orders yet)
1.
DI
1.
Build the order status screen
-
Add a new page MyOrders with
`@page orders`
-
Add a new NavLink to the layout that links to this URL
-
At this point you can appreciate how this page will share layout because that's specified in imports
-
MyOrders should retrieve list of orders and show the past orders
-
Add a new page OrderDetails to show the status of an individual order
-
It should be possible to click from MyOrders->OrderDetails
-
The OrderDetails should poll for updates to the order fromthe backend
-
Go back to the index and make placing an order navigate you to the MyOrders page
1.
DI and the AppState pattern
-
Create a service for interacting with the backend, repository abstraction
-
Refactor HttpClient code to use service instead
-
Talk to DI scopes
1.
Build the order status screen
-
Confirmation screen
-
Cover
`@page`
1.
JS interop
-
Add order status
-
Real status (map location, time to delivery) via polling
...
...
save-points/00-Starting-point/BlazingPizza.Server/OrdersController.cs
View file @
551ae3e0
...
...
@@ -10,7 +10,7 @@ namespace BlazingPizza.Server
{
[
Route
(
"orders"
)]
[
ApiController
]
[
Authorize
]
//
[Authorize]
public
class
OrdersController
:
Controller
{
private
readonly
PizzaStoreContext
_db
;
...
...
@@ -24,7 +24,7 @@ namespace BlazingPizza.Server
public
async
Task
<
ActionResult
<
List
<
OrderWithStatus
>>>
GetOrders
()
{
var
orders
=
await
_db
.
Orders
.
Where
(
o
=>
o
.
UserId
==
GetUserId
())
//
.Where(o => o.UserId == GetUserId())
.
Include
(
o
=>
o
.
Pizzas
).
ThenInclude
(
p
=>
p
.
Special
)
.
Include
(
o
=>
o
.
Pizzas
).
ThenInclude
(
p
=>
p
.
Toppings
).
ThenInclude
(
t
=>
t
.
Topping
)
.
OrderByDescending
(
o
=>
o
.
CreatedTime
)
...
...
@@ -38,7 +38,7 @@ namespace BlazingPizza.Server
{
var
order
=
await
_db
.
Orders
.
Where
(
o
=>
o
.
OrderId
==
orderId
)
.
Where
(
o
=>
o
.
UserId
==
GetUserId
())
//
.Where(o => o.UserId == GetUserId())
.
Include
(
o
=>
o
.
Pizzas
).
ThenInclude
(
p
=>
p
.
Special
)
.
Include
(
o
=>
o
.
Pizzas
).
ThenInclude
(
p
=>
p
.
Toppings
).
ThenInclude
(
t
=>
t
.
Topping
)
.
SingleOrDefaultAsync
();
...
...
@@ -56,7 +56,7 @@ namespace BlazingPizza.Server
{
order
.
CreatedTime
=
DateTime
.
Now
;
order
.
DeliveryLocation
=
new
LatLong
(
51.5001
,
-
0.1239
);
order
.
UserId
=
GetUserId
();
//
order.UserId = GetUserId();
_db
.
Orders
.
Attach
(
order
);
await
_db
.
SaveChangesAsync
();
...
...
save-points/01-Components-and-layout/BlazingPizza.Server/OrdersController.cs
View file @
551ae3e0
...
...
@@ -10,7 +10,7 @@ namespace BlazingPizza.Server
{
[
Route
(
"orders"
)]
[
ApiController
]
[
Authorize
]
//
[Authorize]
public
class
OrdersController
:
Controller
{
private
readonly
PizzaStoreContext
_db
;
...
...
@@ -24,7 +24,7 @@ namespace BlazingPizza.Server
public
async
Task
<
ActionResult
<
List
<
OrderWithStatus
>>>
GetOrders
()
{
var
orders
=
await
_db
.
Orders
.
Where
(
o
=>
o
.
UserId
==
GetUserId
())
//
.Where(o => o.UserId == GetUserId())
.
Include
(
o
=>
o
.
Pizzas
).
ThenInclude
(
p
=>
p
.
Special
)
.
Include
(
o
=>
o
.
Pizzas
).
ThenInclude
(
p
=>
p
.
Toppings
).
ThenInclude
(
t
=>
t
.
Topping
)
.
OrderByDescending
(
o
=>
o
.
CreatedTime
)
...
...
@@ -38,7 +38,7 @@ namespace BlazingPizza.Server
{
var
order
=
await
_db
.
Orders
.
Where
(
o
=>
o
.
OrderId
==
orderId
)
.
Where
(
o
=>
o
.
UserId
==
GetUserId
())
//
.Where(o => o.UserId == GetUserId())
.
Include
(
o
=>
o
.
Pizzas
).
ThenInclude
(
p
=>
p
.
Special
)
.
Include
(
o
=>
o
.
Pizzas
).
ThenInclude
(
p
=>
p
.
Toppings
).
ThenInclude
(
t
=>
t
.
Topping
)
.
SingleOrDefaultAsync
();
...
...
@@ -56,7 +56,7 @@ namespace BlazingPizza.Server
{
order
.
CreatedTime
=
DateTime
.
Now
;
order
.
DeliveryLocation
=
new
LatLong
(
51.5001
,
-
0.1239
);
order
.
UserId
=
GetUserId
();
//
order.UserId = GetUserId();
_db
.
Orders
.
Attach
(
order
);
await
_db
.
SaveChangesAsync
();
...
...
save-points/02-customize-a-pizza/BlazingPizza.Server/OrdersController.cs
View file @
551ae3e0
...
...
@@ -10,7 +10,7 @@ namespace BlazingPizza.Server
{
[
Route
(
"orders"
)]
[
ApiController
]
[
Authorize
]
//
[Authorize]
public
class
OrdersController
:
Controller
{
private
readonly
PizzaStoreContext
_db
;
...
...
@@ -24,7 +24,7 @@ namespace BlazingPizza.Server
public
async
Task
<
ActionResult
<
List
<
OrderWithStatus
>>>
GetOrders
()
{
var
orders
=
await
_db
.
Orders
.
Where
(
o
=>
o
.
UserId
==
GetUserId
())
//
.Where(o => o.UserId == GetUserId())
.
Include
(
o
=>
o
.
Pizzas
).
ThenInclude
(
p
=>
p
.
Special
)
.
Include
(
o
=>
o
.
Pizzas
).
ThenInclude
(
p
=>
p
.
Toppings
).
ThenInclude
(
t
=>
t
.
Topping
)
.
OrderByDescending
(
o
=>
o
.
CreatedTime
)
...
...
@@ -38,7 +38,7 @@ namespace BlazingPizza.Server
{
var
order
=
await
_db
.
Orders
.
Where
(
o
=>
o
.
OrderId
==
orderId
)
.
Where
(
o
=>
o
.
UserId
==
GetUserId
())
//
.Where(o => o.UserId == GetUserId())
.
Include
(
o
=>
o
.
Pizzas
).
ThenInclude
(
p
=>
p
.
Special
)
.
Include
(
o
=>
o
.
Pizzas
).
ThenInclude
(
p
=>
p
.
Toppings
).
ThenInclude
(
t
=>
t
.
Topping
)
.
SingleOrDefaultAsync
();
...
...
@@ -56,7 +56,7 @@ namespace BlazingPizza.Server
{
order
.
CreatedTime
=
DateTime
.
Now
;
order
.
DeliveryLocation
=
new
LatLong
(
51.5001
,
-
0.1239
);
order
.
UserId
=
GetUserId
();
//
order.UserId = GetUserId();
_db
.
Orders
.
Attach
(
order
);
await
_db
.
SaveChangesAsync
();
...
...
save-points/03-show-order-status/BlazingPizza.Client/Pages/Index.cshtml
View file @
551ae3e0
@page "/"
@inject HttpClient HttpClient
@inject IUriHelper UriHelper
<div
class=
"main"
>
<ul
class=
"pizza-cards"
>
...
...
@@ -104,5 +105,6 @@
{
await HttpClient.PostJsonAsync("/orders", order);
order = new Order();
UriHelper.NavigateTo("myorders");
}
}
save-points/03-show-order-status/BlazingPizza.Client/Pages/MyOrders.cshtml
0 → 100644
View file @
551ae3e0
@page "/myorders"
@inject HttpClient HttpClient
<div
class=
"main"
>
@if (ordersWithStatus == null)
{
<text>
Loading...
</text>
}
else if (ordersWithStatus.Count == 0)
{
<h2>
No orders placed
</h2>
<a
class=
"btn btn-success"
href=
""
>
Order some pizza
</a>
}
else
{
<div
class=
"list-group orders-list"
>
@foreach (var item in ordersWithStatus)
{
<div
class=
"list-group-item"
>
<div
class=
"col"
>
<h5>
@item.Order.CreatedTime.ToLongDateString()
</h5>
Items:
<strong>
@item.Order.Pizzas.Count()
</strong>
;
Total price:
<strong>
£@item.Order.GetFormattedTotalPrice()
</strong>
</div>
<div
class=
"col"
>
Status:
<strong>
@item.StatusText
</strong>
</div>
<div
class=
"col flex-grow-0"
>
<a
href=
"myorders/@item.Order.OrderId"
class=
"btn btn-success"
>
Track
>
</a>
</div>
</div>
}
</div>
}
</div>
@functions {
List
<OrderWithStatus>
ordersWithStatus;
protected override async Task OnParametersSetAsync()
{
ordersWithStatus = await HttpClient.GetJsonAsync
<List
<
OrderWithStatus
>
>("/orders");
}
}
save-points/03-show-order-status/BlazingPizza.Client/Pages/OrderDetails.cshtml
0 → 100644
View file @
551ae3e0
@page "/myorders/{orderId:int}"
@using System.Threading
@inject HttpClient HttpClient
@implements IDisposable
<div
class=
"main"
>
@if (invalidOrder)
{
<h2>
Nope
</h2>
<p>
Sorry, this order could not be loaded.
</p>
}
else if (orderWithStatus == null)
{
<text>
Loading...
</text>
}
else
{
<div
class=
"track-order"
>
<div
class=
"track-order-title"
>
<h2>
Order placed @orderWithStatus.Order.CreatedTime.ToLongDateString()
</h2>
<p
class=
"ml-auto mb-0"
>
Status:
<strong>
@orderWithStatus.StatusText
</strong>
</p>
</div>
<div
class=
"track-order-body"
>
<div
class=
"track-order-details"
>
@foreach (var pizza in orderWithStatus.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:
£@orderWithStatus.Order.GetFormattedTotalPrice()
</strong>
</p>
</div>
</div>
</div>
}
</div>
@functions {
[Parameter] int OrderId { get; set; }
OrderWithStatus orderWithStatus;
bool invalidOrder;
CancellationTokenSource pollingCancellationToken;
protected override void OnParametersSet()
{
// If we were already polling for a different order, stop doing so
pollingCancellationToken?.Cancel();
// Start a new poll loop
PollForUpdates();
}
void IDisposable.Dispose()
{
pollingCancellationToken?.Cancel();
}
private async void PollForUpdates()
{
pollingCancellationToken = new CancellationTokenSource();
while (!pollingCancellationToken.IsCancellationRequested)
{
try
{
invalidOrder = false;
orderWithStatus = await HttpClient.GetJsonAsync
<OrderWithStatus>
($"/orders/{OrderId}");
}
catch (Exception ex)
{
invalidOrder = true;
pollingCancellationToken.Cancel();
Console.Error.WriteLine(ex);
}
StateHasChanged();
await Task.Delay(4000);
}
}
}
save-points/03-show-order-status/BlazingPizza.Client/Shared/MainLayout.cshtml
View file @
551ae3e0
...
...
@@ -7,6 +7,11 @@
<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"
>
...
...
save-points/03-show-order-status/BlazingPizza.Server/OrdersController.cs
View file @
551ae3e0
...
...
@@ -10,7 +10,7 @@ namespace BlazingPizza.Server
{
[
Route
(
"orders"
)]
[
ApiController
]
[
Authorize
]
//
[Authorize]
public
class
OrdersController
:
Controller
{
private
readonly
PizzaStoreContext
_db
;
...
...
@@ -24,7 +24,7 @@ namespace BlazingPizza.Server
public
async
Task
<
ActionResult
<
List
<
OrderWithStatus
>>>
GetOrders
()
{
var
orders
=
await
_db
.
Orders
.
Where
(
o
=>
o
.
UserId
==
GetUserId
())
//
.Where(o => o.UserId == GetUserId())
.
Include
(
o
=>
o
.
Pizzas
).
ThenInclude
(
p
=>
p
.
Special
)
.
Include
(
o
=>
o
.
Pizzas
).
ThenInclude
(
p
=>
p
.
Toppings
).
ThenInclude
(
t
=>
t
.
Topping
)
.
OrderByDescending
(
o
=>
o
.
CreatedTime
)
...
...
@@ -38,7 +38,7 @@ namespace BlazingPizza.Server
{
var
order
=
await
_db
.
Orders
.
Where
(
o
=>
o
.
OrderId
==
orderId
)
.
Where
(
o
=>
o
.
UserId
==
GetUserId
())
//
.Where(o => o.UserId == GetUserId())
.
Include
(
o
=>
o
.
Pizzas
).
ThenInclude
(
p
=>
p
.
Special
)
.
Include
(
o
=>
o
.
Pizzas
).
ThenInclude
(
p
=>
p
.
Toppings
).
ThenInclude
(
t
=>
t
.
Topping
)
.
SingleOrDefaultAsync
();
...
...
@@ -56,7 +56,7 @@ namespace BlazingPizza.Server
{
order
.
CreatedTime
=
DateTime
.
Now
;
order
.
DeliveryLocation
=
new
LatLong
(
51.5001
,
-
0.1239
);
order
.
UserId
=
GetUserId
();
//
order.UserId = GetUserId();
_db
.
Orders
.
Attach
(
order
);
await
_db
.
SaveChangesAsync
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment