Feat : Page & Start of API integration
continuous-integration/drone/push Build is passing Details

pull/37/head
Jade VAN BRABANDT 1 year ago
parent 3a0127df48
commit 150cca45ec

@ -1,25 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34330.188
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blazor", "Blazor\Blazor.csproj", "{F9B19564-ED8F-49F7-97D7-2132F92DE3C2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F9B19564-ED8F-49F7-97D7-2132F92DE3C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F9B19564-ED8F-49F7-97D7-2132F92DE3C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F9B19564-ED8F-49F7-97D7-2132F92DE3C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F9B19564-ED8F-49F7-97D7-2132F92DE3C2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {75BB0A32-C002-4B33-88B3-421A9369D9CB}
EndGlobalSection
EndGlobal

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34330.188
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blazor", "Blazor\Blazor.csproj", "{F9B19564-ED8F-49F7-97D7-2132F92DE3C2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F9B19564-ED8F-49F7-97D7-2132F92DE3C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F9B19564-ED8F-49F7-97D7-2132F92DE3C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F9B19564-ED8F-49F7-97D7-2132F92DE3C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F9B19564-ED8F-49F7-97D7-2132F92DE3C2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {75BB0A32-C002-4B33-88B3-421A9369D9CB}
EndGlobalSection
EndGlobal

@ -6,4 +6,11 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Blazored.LocalStorage" Version="4.4.0" />
<PackageReference Include="Blazorise.Bootstrap" Version="1.4.0" />
<PackageReference Include="Blazorise.DataGrid" Version="1.4.0" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.4.0" />
</ItemGroup>
</Project>

@ -0,0 +1,28 @@
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
using Microsoft.AspNetCore.Identity;
using System.Security.Cryptography;
namespace Blazor.Models;
public class AdministratorsModel : PasswordHasher<string>
{
public int Id { get; private set; }
public string Username { get; private set; }
public string HashedPassword { get; set; }
private byte[] salt = RandomNumberGenerator.GetBytes(128 / 8); // for password hash
AdministratorsModel(int id, string username, string password)
{
this.Id = id;
this.Username = username;
//hash password
this.HashedPassword = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password!,
salt: salt,
prf: KeyDerivationPrf.HMACSHA256,
iterationCount: 100000,
numBytesRequested: 256 / 8)
);
}
}

@ -0,0 +1,16 @@
namespace Blazor.Models;
public class AnswerModel
{
public int Id { get; private set; }
public string Content { get; set; }
public int IdQuestion { get; private set; }
public AnswerModel(int id, string content, int idQuestion)
{
Id = id;
Content = content;
IdQuestion = idQuestion;
}
}

@ -0,0 +1,13 @@
namespace Blazor.Models;
public class ChaptersModel
{
public int Id { get; private set; }
public string Name { get; set; }
public ChaptersModel(int id, string name)
{
Id = id;
Name = name;
}
}

@ -0,0 +1,25 @@
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
using System.Security.Cryptography;
namespace Blazor.Models;
public class PlayerModel
{
public int Id { get; private set; }
public string Nickname { get; private set; }
public string HashedPassword { get; set; }
private byte[] salt = RandomNumberGenerator.GetBytes(128 / 8); // for password hash
public PlayerModel(int id, string nickname, string password)
{
Id = id;
Nickname = nickname;
//hash password
HashedPassword = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password!,
salt: salt,
prf: KeyDerivationPrf.HMACSHA256,
iterationCount: 100000,
numBytesRequested: 256 / 8)
);
}
}

@ -0,0 +1,24 @@
namespace Blazor.Models;
public class QuestionsModel
{
public int Id { get; private set; }
public string Content { get; set; }
public int IdChapter { get; private set; }
public int? IdAnswerGood { get; set; }
public int Difficulty { get; set; }
public int NbFails { get; private set; }
public QuestionsModel(int id, string content, int idChapter, int difficulty, int nbFails, int? idAnswerGood = null)
{
Id = id;
Content = content;
IdChapter = idChapter;
Difficulty = difficulty;
NbFails = nbFails;
IdAnswerGood = idAnswerGood;
}
public void addFails(int nb) { NbFails += nb; }
public void removeFails(int nb) { NbFails -= nb; }
}

@ -1,4 +1,4 @@
@page "/fetchdata"
@page "/admins"
@using Blazor.Data
@inject WeatherForecastService ForecastService

@ -0,0 +1,61 @@
using Blazor.Models;
using Blazored.LocalStorage;
using Blazorise.DataGrid;
using Microsoft.AspNetCore.Components;
namespace Blazor.Pages;
public partial class Admins
{
private List<AdministratorsModel> items;
private int totalItem;
[Inject]
public IWebHostEnvironment WebHostEnvironment { get; set; }
[Inject]
public HttpClient Http { get; set; }
[Inject]
public ILocalStorageService LocalStorage { get; set; }
[Inject]
public NavigationManager NavigationManager { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
// Do not treat this action if is not the first render
if (!firstRender)
{
return;
}
var currentData = await LocalStorage.GetItemAsync<AdministratorsModel[]>("data");
// Check if data exist in the local storage
if (currentData == null)
{
// this code add in the local storage the fake data (we load the data sync for initialize the data before load the OnReadData method)
var originalData = Http.GetFromJsonAsync<AdministratorsModel[]>($"trusting-panini.87-106-126-109.plesk.page/api/chapters").Result;
await LocalStorage.SetItemAsync("data", originalData);
}
}
private async Task OnReadData(DataGridReadDataEventArgs<AdministratorsModel> e)
{
if (e.CancellationToken.IsCancellationRequested)
{
return;
}
// When you use a real API, we use this follow code
//var response = await Http.GetJsonAsync<Data[]>( $"http://my-api/api/data?page={e.Page}&pageSize={e.PageSize}" );
var response = (await LocalStorage.GetItemAsync<AdministratorsModel[]>("data")).Skip((e.Page - 1) * e.PageSize).Take(e.PageSize).ToList();
if (!e.CancellationToken.IsCancellationRequested)
{
totalItem = (await LocalStorage.GetItemAsync<List<AdministratorsModel>>("data")).Count;
items = new List<AdministratorsModel>(response); // an actual data for the current page
}
}
}

@ -0,0 +1,13 @@
@page "/chapters"
@using Blazor.Models
<h3>Liste</h3>
<DataGrid TItem="Item"
Data="@items"
ReadData="@OnReadData"
TotalItems="@totalItem"
PageSize="10"
ShowPager
Responsive>
<DataGridColumn TItem="Item" Field="@nameof(ChaptersModel.Id)" Caption="#" />
<DataGridColumn TItem="Item" Field="@nameof(ChaptersModel.Name)" Caption="Display name" />
</DataGrid>

@ -0,0 +1,61 @@
using Blazor.Models;
using Blazored.LocalStorage;
using Blazorise.DataGrid;
using Microsoft.AspNetCore.Components;
namespace Blazor.Pages;
public partial class Chapters
{
private List<ChaptersModel> items;
private int totalItem;
[Inject]
public IWebHostEnvironment WebHostEnvironment { get; set; }
[Inject]
public HttpClient Http { get; set; }
[Inject]
public ILocalStorageService LocalStorage { get; set; }
[Inject]
public NavigationManager NavigationManager { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
// Do not treat this action if is not the first render
if (!firstRender)
{
return;
}
var currentData = await LocalStorage.GetItemAsync<ChaptersModel[]>("data");
// Check if data exist in the local storage
if (currentData == null)
{
// this code add in the local storage the fake data (we load the data sync for initialize the data before load the OnReadData method)
var originalData = Http.GetFromJsonAsync<ChaptersModel[]>($"https://trusting-panini.87-106-126-109.plesk.page/api/chapters").Result;
await LocalStorage.SetItemAsync("data", originalData);
}
}
private async Task OnReadData(DataGridReadDataEventArgs<ChaptersModel> e)
{
if (e.CancellationToken.IsCancellationRequested)
{
return;
}
// When you use a real API, we use this follow code
//var response = await Http.GetJsonAsync<Data[]>( $"http://my-api/api/data?page={e.Page}&pageSize={e.PageSize}" );
var response = (await LocalStorage.GetItemAsync<ChaptersModel[]>("data")).Skip((e.Page - 1) * e.PageSize).Take(e.PageSize).ToList();
if (!e.CancellationToken.IsCancellationRequested)
{
totalItem = (await LocalStorage.GetItemAsync<List<AdministratorsModel>>("data")).Count;
items = new List<ChaptersModel>(response); // an actual data for the current page
}
}
}

@ -0,0 +1,6 @@
namespace Blazor.Pages;
public partial class Index
{
}

@ -0,0 +1,47 @@
@page "/questions"
@using Blazor.Data
@inject WeatherForecastService ForecastService
<PageTitle>Weather forecast</PageTitle>
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from a service.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private WeatherForecast[]? forecasts;
protected override async Task OnInitializedAsync()
{
forecasts = await ForecastService.GetForecastAsync(DateOnly.FromDateTime(DateTime.Now));
}
}

@ -0,0 +1,6 @@
namespace Blazor.Pages;
public partial class Questions
{
}

@ -1,4 +1,8 @@
using Blazor.Data;
using Blazored.LocalStorage;
using Blazorise;
using Blazorise.Bootstrap;
using Blazorise.Icons.FontAwesome;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
@ -8,6 +12,13 @@ var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();
builder.Services.AddHttpClient();
builder.Services
.AddBlazorise()
.AddBootstrapProviders()
.AddFontAwesomeIcons();
builder.Services.AddBlazoredLocalStorage();
var app = builder.Build();

@ -15,13 +15,18 @@
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="oi oi-plus" aria-hidden="true"></span> Counter
<NavLink class="nav-link" href="chapters">
<span class="oi oi-list-rich" aria-hidden="true"></span> Chapters
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="fetchdata">
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
<NavLink class="nav-link" href="questions">
<span class="oi oi-list-rich" aria-hidden="true"></span> Questions
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="admins">
<span class="oi oi-list-rich" aria-hidden="true"></span> Administrators
</NavLink>
</div>
</nav>

Loading…
Cancel
Save