Skip to content

Commit

Permalink
l09 preparation
Browse files Browse the repository at this point in the history
  • Loading branch information
Hijtec committed Nov 20, 2024
1 parent bec55c1 commit d106241
Show file tree
Hide file tree
Showing 20 changed files with 505 additions and 0 deletions.
1 change: 1 addition & 0 deletions ToDoList/src/ToDoList.Domain/Models/ToDoItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ public class ToDoItem
[StringLength(250)]
public string Description { get; set; }

Check warning on line 12 in ToDoList/src/ToDoList.Domain/Models/ToDoItem.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Description' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
public bool IsCompleted { get; set; }
public string? Category { get; set; }
}
10 changes: 10 additions & 0 deletions ToDoList/src/ToDoList.Frontend/Clients/IToDoItemsClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace ToDoList.Frontend.Clients;
using ToDoList.Frontend.Views;

public interface IToDoItemsClient
{
public Task<ToDoItemView?> ReadItemByIdAsync(int itemId);
public Task<List<ToDoItemView>> ReadItemsAsync();
public Task DeleteItemAsync(ToDoItemView itemView);
public Task UpdateItemAsync(ToDoItemView itemView);
}
128 changes: 128 additions & 0 deletions ToDoList/src/ToDoList.Frontend/Clients/ToDoItemsClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
namespace ToDoList.Frontend.Clients;

using System.Collections.Generic;
using System.Threading.Tasks;
using ToDoList.Domain.DTOs;
using ToDoList.Frontend.Views;

public class ToDoItemsClient(HttpClient httpClient) : IToDoItemsClient //primary constructor
{
public async Task CreateItemAsync(ToDoItemView itemView)
{
var itemRequest = new ToDoItemCreateRequestDto(itemView.Name, itemView.Description, itemView.IsCompleted, itemView.Category);
try
{
var response = await httpClient.PostAsJsonAsync($"api/ToDoItems", itemRequest);
if (response.StatusCode == System.Net.HttpStatusCode.Created)
{
Console.WriteLine($"POST request successful: Created a ToDoItem.");
return;
}
else
{
Console.WriteLine($"POST request failed with status code: {response.StatusCode}");
}
}
catch (Exception e)
{
Console.WriteLine($"Exception occured: {e.Message}");
}
}

public async Task DeleteItemAsync(ToDoItemView itemView)
{
try
{
var response = await httpClient.DeleteAsync($"api/ToDoItems/{itemView.ToDoItemId}");
if (response.StatusCode == System.Net.HttpStatusCode.NoContent)
{
Console.WriteLine($"DELETE request successful: Deleted ToDoItem with id {itemView.ToDoItemId}.");
return;
}
else
{
Console.WriteLine($"DELETE request failed with status code: {response.StatusCode}");
}
}
catch (Exception e)
{
Console.WriteLine($"Exception occured: {e.Message}");
}
}

public async Task<ToDoItemView?> ReadItemByIdAsync(int itemId)
{
try
{
var response = await httpClient.GetFromJsonAsync<ToDoItemGetResponseDto>($"api/TodoItems/{itemId}");
if (response is null)
{
Console.WriteLine($"GET request failed: Item with {itemId} id not found.");
throw new ArgumentException($"Given id {itemId} does not exist.");
}

return new()
{
ToDoItemId = response.Id,
Name = response.Name,
Description = response.Description,
IsCompleted = response.IsCompleted,
Category = response.Category
};
}
catch (Exception e)
{
Console.WriteLine($"Exception occured: {e.Message}");
return null;
}
}

public async Task<List<ToDoItemView>> ReadItemsAsync()
{
var toDoItemViews = new List<ToDoItemView>();
try
{
var response = await httpClient.GetFromJsonAsync<List<ToDoItemGetResponseDto>>("api/ToDoItems");
if (response is null)
{
Console.WriteLine($"GET request failed: No items to read.");
return toDoItemViews;
}
toDoItemViews = response.Select(i => new ToDoItemView
{
ToDoItemId = i.Id,
Name = i.Name,
Description = i.Description,
IsCompleted = i.IsCompleted,
Category = i.Category
}).ToList();
}
catch (Exception e)
{
Console.WriteLine($"Exception occured: {e.Message}");
}

return toDoItemViews;
}
public async Task UpdateItemAsync(ToDoItemView itemView)
{
try
{
var itemRequest = new ToDoItemUpdateRequestDto(itemView.Name, itemView.Description, itemView.IsCompleted, itemView.Category);
var response = await httpClient.PutAsJsonAsync($"api/ToDoItems/{itemView.ToDoItemId}", itemRequest);
if (response.StatusCode == System.Net.HttpStatusCode.NoContent)
{
Console.WriteLine($"PUT request successful: Updated ToDoItem with id {itemView.ToDoItemId}.");
return;
}
else
{
Console.WriteLine($"PUT request failed: {response.StatusCode}");
}
}
catch (Exception e)
{
Console.WriteLine($"Exception occured: {e.Message}");
}
}
}
23 changes: 23 additions & 0 deletions ToDoList/src/ToDoList.Frontend/Components/App.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="ToDoList.Frontend.styles.css" />
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<HeadOutlet />
</head>

<body>
<Routes />
<script src="_framework/blazor.web.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
crossorigin="anonymous"></script>
</body>

</html>
47 changes: 47 additions & 0 deletions ToDoList/src/ToDoList.Frontend/Components/Dashboard.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
@using ToDoList.Frontend.Views
@using ToDoList.Frontend.Clients

@inject IToDoItemsClient ToDoItemClient
@rendermode InteractiveServer

<div>
<table class="table table-hover">
<thead>
<th><button class="btn" @onclick="OrderById">Id</button></th>
<th><button class="btn" @onclick="OrderByName">Name</button></th>
<th>Description</th>
<th>IsCompleted</th>
</thead>
@if (toDoItemViews is not null)
{
@foreach (var item in toDoItemViews)
{
<tr>
<td>@item.ToDoItemId</td>
<td>@item.Name</td>
<td>@item.Description</td>
<td>@item.IsCompleted</td>
</tr>
}
}
</table>
</div>

@code
{
private List<ToDoItemView>? toDoItemViews;
protected override async Task OnInitializedAsync()
{
toDoItemViews = await ToDoItemClient.ReadItemsAsync();
}

public void OrderByName()
{
toDoItemViews = toDoItemViews?.OrderBy(x => x.Name).ToList();
}

public void OrderById()
{
toDoItemViews = toDoItemViews?.OrderBy(x => x.ToDoItemId).ToList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@inherits LayoutComponentBase

<div class="container">
@Body
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#blazor-error-ui {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}

#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}
36 changes: 36 additions & 0 deletions ToDoList/src/ToDoList.Frontend/Components/Pages/Error.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@page "/Error"
@using System.Diagnostics

<PageTitle>Error</PageTitle>

<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>

@if (ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@RequestId</code>
</p>
}

<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>

@code{
[CascadingParameter]
private HttpContext? HttpContext { get; set; }

private string? RequestId { get; set; }
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);

protected override void OnInitialized() =>
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
}
2 changes: 2 additions & 0 deletions ToDoList/src/ToDoList.Frontend/Components/Pages/Home.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@page "/"
<Dashboard />
6 changes: 6 additions & 0 deletions ToDoList/src/ToDoList.Frontend/Components/Routes.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>
10 changes: 10 additions & 0 deletions ToDoList/src/ToDoList.Frontend/Components/_Imports.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using ToDoList.Frontend
@using ToDoList.Frontend.Components
31 changes: 31 additions & 0 deletions ToDoList/src/ToDoList.Frontend/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using ToDoList.Frontend.Clients;
using ToDoList.Frontend.Components;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.Configuration["ToDoItemsApiAddress"]!) });
builder.Services.AddScoped<IToDoItemsClient, ToDoItemsClient>();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}

// app.UseHttpsRedirection();

app.UseStaticFiles();
app.UseAntiforgery();

app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();

app.Run();
38 changes: 38 additions & 0 deletions ToDoList/src/ToDoList.Frontend/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:20228",
"sslPort": 44348
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5001",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:7001;http://localhost:5001",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": false,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
13 changes: 13 additions & 0 deletions ToDoList/src/ToDoList.Frontend/ToDoList.Frontend.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\ToDoList.Domain\ToDoList.Domain.csproj" />
</ItemGroup>

</Project>
10 changes: 10 additions & 0 deletions ToDoList/src/ToDoList.Frontend/Views/ToDoItemView.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace ToDoList.Frontend.Views;

public class ToDoItemView
{
public required int ToDoItemId { get; set; }
public required string Name { get; set; }
public required string Description { get; set; }
public required bool IsCompleted { get; set; }
public string? Category { get; set; }
}
Loading

0 comments on commit d106241

Please sign in to comment.