From a1b99f9cb787c614f2812628aef34ebca880ad3f Mon Sep 17 00:00:00 2001 From: "maxence.guitard" Date: Mon, 18 Dec 2023 09:19:29 +0100 Subject: [PATCH 1/3] feat : page questions --- .../{ => Admins}/EditAdministrator.razor | 0 .../{ => Admins}/EditAdministrator.razor.cs | 2 +- Blazor/Blazor/Pages/Questions/Questions.razor | 68 +++---- .../Blazor/Pages/Questions/Questions.razor.cs | 174 +++++++++++++++++- Blazor/Blazor/Services/DataLocalService.cs | 102 +++++++++- Blazor/Blazor/Services/IDataService.cs | 9 + 6 files changed, 304 insertions(+), 51 deletions(-) rename Blazor/Blazor/Pages/{ => Admins}/EditAdministrator.razor (100%) rename Blazor/Blazor/Pages/{ => Admins}/EditAdministrator.razor.cs (97%) diff --git a/Blazor/Blazor/Pages/EditAdministrator.razor b/Blazor/Blazor/Pages/Admins/EditAdministrator.razor similarity index 100% rename from Blazor/Blazor/Pages/EditAdministrator.razor rename to Blazor/Blazor/Pages/Admins/EditAdministrator.razor diff --git a/Blazor/Blazor/Pages/EditAdministrator.razor.cs b/Blazor/Blazor/Pages/Admins/EditAdministrator.razor.cs similarity index 97% rename from Blazor/Blazor/Pages/EditAdministrator.razor.cs rename to Blazor/Blazor/Pages/Admins/EditAdministrator.razor.cs index 7d0d876..f41a5e9 100644 --- a/Blazor/Blazor/Pages/EditAdministrator.razor.cs +++ b/Blazor/Blazor/Pages/Admins/EditAdministrator.razor.cs @@ -2,7 +2,7 @@ using Blazor.Services; using Microsoft.AspNetCore.Components; -namespace Blazor.Pages +namespace Blazor.Pages.Admins { public partial class EditAdministrator { diff --git a/Blazor/Blazor/Pages/Questions/Questions.razor b/Blazor/Blazor/Pages/Questions/Questions.razor index a123a0c..eb87f83 100644 --- a/Blazor/Blazor/Pages/Questions/Questions.razor +++ b/Blazor/Blazor/Pages/Questions/Questions.razor @@ -1,47 +1,29 @@ @page "/questions" -@using Blazor.Data -@inject WeatherForecastService ForecastService +@using Blazor.ViewClasses; +@using Blazorise.DataGrid +@using Blazored.Modal; +

Chapters

-Weather forecast +
+ + Ajouter + +
-

Weather forecast

+ + + -

This component demonstrates fetching data from a service.

- -@if (forecasts == null) -{ -

Loading...

-} -else -{ - - - - - - - - - - - @foreach (var forecast in forecasts) - { - - - - - - - } - -
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
-} - -@code { - private WeatherForecast[]? forecasts; - - protected override async Task OnInitializedAsync() - { - forecasts = await ForecastService.GetForecastAsync(DateOnly.FromDateTime(DateTime.Now)); - } -} + + + Editer + + + +
\ No newline at end of file diff --git a/Blazor/Blazor/Pages/Questions/Questions.razor.cs b/Blazor/Blazor/Pages/Questions/Questions.razor.cs index 86bf53b..0c0138f 100644 --- a/Blazor/Blazor/Pages/Questions/Questions.razor.cs +++ b/Blazor/Blazor/Pages/Questions/Questions.razor.cs @@ -1,6 +1,178 @@ -namespace Blazor.Pages.Questions; +using Blazored.LocalStorage; +using Blazor.Services; +using Blazored.Modal.Services; +using Blazor.ViewClasses; +using System.Text; +using Microsoft.JSInterop; +using Microsoft.AspNetCore.Components; +using Blazorise.DataGrid; +using ChoETL; +using Microsoft.AspNetCore.Components.Forms; +using Blazor.Modals; +using Blazored.Modal; + +namespace Blazor.Pages.Questions; public partial class Questions { + public List questions; + + private int totalQuestion; + + [Inject] + public NavigationManager NavigationManager { get; set; } + + [CascadingParameter] + public IModalService Modal { get; set; } + + [Inject] + public IDataService DataService { get; set; } + public IWebHostEnvironment WebHostEnvironment { get; set; } + + [Inject] + public HttpClient Http { get; set; } + + [Inject] + public ILocalStorageService LocalStorage { get; set; } + + [Inject] + public IJSRuntime IJSRuntime { get; set; } + + private async void OnDelete(int id) + { + var parameters = new ModalParameters(); + parameters.Add(nameof(Question.Id), id); + + var modal = Modal.Show("Delete Confirmation", parameters); + var result = modal.Result; + + if (result.IsCanceled) + { + return; + } + + await DataService.Delete(id); + + // Reload the page + NavigationManager.NavigateTo("questions", true); + } + + + 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("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($"https://trusting-panini.87-106-126-109.plesk.page/api/chapters").Result; + await LocalStorage.SetItemAsync("data", originalData); + } + } + + private async Task OnReadData(DataGridReadDataEventArgs e) + { + if (e.CancellationToken.IsCancellationRequested) + { + return; + } + + // When you use a real API, we use this follow code + //var response = await Http.GetFromJsonAsync( $"https://trusting-panini.87-106-126-109.plesk.page/api/chapters?page={e.Page}&pageSize={e.PageSize}" ); + var response = Http.GetFromJsonAsync($"https://trusting-panini.87-106-126-109.plesk.page/api/chapters").Result; + + if (!e.CancellationToken.IsCancellationRequested) + { + totalQuestion = (await LocalStorage.GetItemAsync>("data")).Count; + questions = new List(response); // an actual data for the current page + } + } + + private async void Export() + { + StringBuilder sb = new StringBuilder(); + HttpResponseMessage response = await Http.GetAsync("https://trusting-panini.87-106-126-109.plesk.page/api/chapters"); + var json = await response.Content.ReadAsStringAsync(); + using (var jsonFile = ChoJSONReader.LoadText(json)) + { + using (var csvFile = new ChoCSVWriter(sb).WithFirstLineHeader()) + { + csvFile.Write(jsonFile); + } + } + + var sentFile = new MemoryStream(Encoding.UTF32.GetBytes(sb.ToString())); + + using (var streamRef = new DotNetStreamReference(stream: sentFile)) + { + await IJSRuntime.InvokeVoidAsync("downloadFileFromStream", "data.csv", streamRef); + } + } + private async Task SingleUpload(InputFileChangeEventArgs e) + { + using (MemoryStream ms = new MemoryStream()) + { + await e.File.OpenReadStream().CopyToAsync(ms); + var bytes = ms.ToArray(); + string s = Encoding.UTF8.GetString(bytes); + + char[] invalidChars = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '\r', '\n', ',', ' ' }; + + List filteredStrings = new List(); + StringBuilder filteredString = new StringBuilder(); + + foreach (var c in s) + { + if (!invalidChars.Contains(c)) + { + filteredString.Append(c); + } + else + { + if (filteredString.Length > 0) + { + filteredStrings.Add(filteredString.ToString()); + filteredString.Clear(); + } + } + } + + if (filteredString.Length > 0) + { + filteredStrings.Add(filteredString.ToString()); + } + foreach (var filteredStr in filteredStrings) + { + var formData = new List>(); + formData.Add(new KeyValuePair("name", filteredStr)); + + + var formContent = new FormUrlEncodedContent(formData); + + string apiUri = "https://trusting-panini.87-106-126-109.plesk.page/api/add/chapters"; + + using (var httpClient = new HttpClient()) + { + var response = await httpClient.PostAsync(apiUri, formContent); + + if (response.IsSuccessStatusCode) + { + var responseBody = await response.Content.ReadAsStringAsync(); + } + else + { + var errorResponse = await response.Content.ReadAsStringAsync(); + } + } + } + } + } } diff --git a/Blazor/Blazor/Services/DataLocalService.cs b/Blazor/Blazor/Services/DataLocalService.cs index 8d7e2e2..cfb8df2 100644 --- a/Blazor/Blazor/Services/DataLocalService.cs +++ b/Blazor/Blazor/Services/DataLocalService.cs @@ -98,8 +98,6 @@ namespace Blazor.Services await _localStorage.SetItemAsync("data", currentData); } - - public async Task Count() { // Load data from the local storage @@ -137,10 +135,10 @@ namespace Blazor.Services // Get the current data var currentData = await _localStorage.GetItemAsync>("data"); - // Get the chapter int the list + // Get the admin int the list var admin = currentData.FirstOrDefault(w => w.Id == id); - // Check if chapter exist + // Check if admin exist if (admin == null) { throw new Exception($"Unable to found the item with ID: {id}"); @@ -171,7 +169,6 @@ namespace Blazor.Services await _localStorage.SetItemAsync("data", currentData); } - public async Task Add(AdministratorsModel model) { // Get the current data @@ -180,7 +177,7 @@ namespace Blazor.Services // Simulate the Id model.Id = currentData.Max(s => s.Id) + 1; - // Add the chapter to the current data + // Add the admin to the current data currentData.Add(new Administrator { Id = model.Id, @@ -224,5 +221,98 @@ namespace Blazor.Services return (await _localStorage.GetItemAsync("data")).Skip((currentPage - 1) * pageSize).Take(pageSize).ToList(); } + + + public async Task GetQuestionById(int id) + { + // Get the current data + var currentData = await _localStorage.GetItemAsync>("data"); + + // Get the question int the list + var question = currentData.FirstOrDefault(w => w.Id == id); + + // Check if question exist + if (question == null) + { + throw new Exception($"Unable to found the item with ID: {id}"); + } + + return question; + } + + //public async Task Update(int id, QuestionsModel model) + //{ + // // Get the current data + // var currentData = await _localStorage.GetItemAsync>("data"); + + // // Get the admin int the list + // var question = currentData.FirstOrDefault(w => w.Id == id); + + // // Check if admin exist + // if (question == null) + // { + // throw new Exception($"Unable to found the item with ID: {id}"); + // } + + // // Modify the content of the adminnistrator + // question.Username = model.Username; + // question.hashedPassword = model.hashedPassword; + + // // Save the data + // await _localStorage.SetItemAsync("data", currentData); + //} + + //public async Task Add(QuestionsModel model) + //{ + // // Get the current data + // var currentData = await _localStorage.GetItemAsync>("data"); + + // // Simulate the Id + // model.Id = currentData.Max(s => s.Id) + 1; + + // // Add the admin to the current data + // currentData.Add(new Question + // { + // Id = model.Id, + // Username = model.Username, + // hashedPassword = model.hashedPassword + // }); + + + // // Save the data + // await _localStorage.SetItemAsync("data", currentData); + //} + + public async Task CountQuestion() + { + // Load data from the local storage + var currentData = await _localStorage.GetItemAsync("data"); + + // Check if data exist in the local storage + if (currentData == null) + { + // this code add in the local storage the fake data + var originalData = await _http.GetFromJsonAsync($"{_navigationManager.BaseUri}fake-question.json"); + await _localStorage.SetItemAsync("data", originalData); + } + + return (await _localStorage.GetItemAsync("data")).Length; + } + + public async Task> ListQuestion(int currentPage, int pageSize) + { + // Load data from the local storage + var currentData = await _localStorage.GetItemAsync("data"); + + // Check if data exist in the local storage + if (currentData == null) + { + // this code add in the local storage the fake data + var originalData = await _http.GetFromJsonAsync($"{_navigationManager.BaseUri}fake-question.json"); + await _localStorage.SetItemAsync("data", originalData); + } + + return (await _localStorage.GetItemAsync("data")).Skip((currentPage - 1) * pageSize).Take(pageSize).ToList(); + } } } diff --git a/Blazor/Blazor/Services/IDataService.cs b/Blazor/Blazor/Services/IDataService.cs index 8093eff..e965c2b 100644 --- a/Blazor/Blazor/Services/IDataService.cs +++ b/Blazor/Blazor/Services/IDataService.cs @@ -24,6 +24,15 @@ namespace Blazor.Services Task CountAdmin(); Task> ListAdmin(int currentPage, int pageSize); + //Task Add(QuestionsModel model); + + //Task Update(int id, QuestionsModel model); + + Task GetQuestionById(int id); + + Task CountQuestion(); + Task> ListQuestion(int currentPage, int pageSize); + Task Delete(int id); } From 6ac3ecabedea8013bf2f515bb5c8422375309070 Mon Sep 17 00:00:00 2001 From: "maxence.guitard" Date: Mon, 18 Dec 2023 09:31:03 +0100 Subject: [PATCH 2/3] fix : affichage questions --- .../Pages/Admins/Administrators.razor.cs | 74 +++++++++---------- .../Blazor/Pages/Questions/Questions.razor.cs | 7 +- 2 files changed, 41 insertions(+), 40 deletions(-) diff --git a/Blazor/Blazor/Pages/Admins/Administrators.razor.cs b/Blazor/Blazor/Pages/Admins/Administrators.razor.cs index 4ab4c1f..a55bc97 100644 --- a/Blazor/Blazor/Pages/Admins/Administrators.razor.cs +++ b/Blazor/Blazor/Pages/Admins/Administrators.razor.cs @@ -1,21 +1,21 @@ -using Microsoft.AspNetCore.Components; -using Blazorise.DataGrid; -using Blazor.ViewClasses; +using Microsoft.AspNetCore.Components; +using Blazorise.DataGrid; +using Blazor.ViewClasses; using Blazor.Modals; using Blazor.Models; using Blazored.LocalStorage; using Blazored.Modal.Services; using Blazor.Modals; using Blazor.Services; -using Blazored.Modal; -using Blazored.Modal; - -namespace Blazor.Pages.Admins; - -public partial class Administrators -{ - public List administrators; - +using Blazored.Modal; +using Blazored.Modal; + +namespace Blazor.Pages.Admins; + +public partial class Administrators +{ + public List administrators; + private int totalItem; [CascadingParameter] public IModalService Modal { get; set; } @@ -28,29 +28,29 @@ public partial class Administrators [Inject] public ILocalStorageService LocalStorage { get; set; } - - [Inject] - public HttpClient Http { get; set; } - - [Inject] - public NavigationManager NavigationManager { get; set; } - - private async Task OnReadData(DataGridReadDataEventArgs e) - { - if (e.CancellationToken.IsCancellationRequested) - { - return; - } - - // When you use a real API, we use this follow code - //var response = await Http.GetJsonAsync( $"http://my-api/api/data?page={e.Page}&pageSize={e.PageSize}" ); - var response = (await Http.GetFromJsonAsync($"{NavigationManager.BaseUri}fake-administrator.json")).Skip((e.Page - 1) * e.PageSize).Take(e.PageSize).ToList(); - - if (!e.CancellationToken.IsCancellationRequested) - { - totalItem = (await Http.GetFromJsonAsync>($"{NavigationManager.BaseUri}fake-administrator.json")).Count; - administrators = new List(response); // an actual data for the current page - } + + [Inject] + public HttpClient Http { get; set; } + + [Inject] + public NavigationManager NavigationManager { get; set; } + + private async Task OnReadData(DataGridReadDataEventArgs e) + { + if (e.CancellationToken.IsCancellationRequested) + { + return; + } + + // When you use a real API, we use this follow code + //var response = await Http.GetJsonAsync( $"http://my-api/api/data?page={e.Page}&pageSize={e.PageSize}" ); + var response = (await Http.GetFromJsonAsync($"{NavigationManager.BaseUri}fake-administrator.json")).Skip((e.Page - 1) * e.PageSize).Take(e.PageSize).ToList(); + + if (!e.CancellationToken.IsCancellationRequested) + { + totalItem = (await Http.GetFromJsonAsync>($"{NavigationManager.BaseUri}fake-administrator.json")).Count; + administrators = new List(response); // an actual data for the current page + } } protected override async Task OnAfterRenderAsync(bool firstRender) @@ -89,5 +89,5 @@ public partial class Administrators // Reload the page NavigationManager.NavigateTo("administrators", true); - } -} + } +} diff --git a/Blazor/Blazor/Pages/Questions/Questions.razor.cs b/Blazor/Blazor/Pages/Questions/Questions.razor.cs index 0c0138f..e245f8f 100644 --- a/Blazor/Blazor/Pages/Questions/Questions.razor.cs +++ b/Blazor/Blazor/Pages/Questions/Questions.razor.cs @@ -10,6 +10,7 @@ using ChoETL; using Microsoft.AspNetCore.Components.Forms; using Blazor.Modals; using Blazored.Modal; +using Blazor.Pages.Admins; namespace Blazor.Pages.Questions; @@ -85,12 +86,12 @@ public partial class Questions } // When you use a real API, we use this follow code - //var response = await Http.GetFromJsonAsync( $"https://trusting-panini.87-106-126-109.plesk.page/api/chapters?page={e.Page}&pageSize={e.PageSize}" ); - var response = Http.GetFromJsonAsync($"https://trusting-panini.87-106-126-109.plesk.page/api/chapters").Result; + //var response = await Http.GetJsonAsync( $"http://my-api/api/data?page={e.Page}&pageSize={e.PageSize}" ); + var response = (await Http.GetFromJsonAsync($"{NavigationManager.BaseUri}fake-question.json")).Skip((e.Page - 1) * e.PageSize).Take(e.PageSize).ToList(); if (!e.CancellationToken.IsCancellationRequested) { - totalQuestion = (await LocalStorage.GetItemAsync>("data")).Count; + totalQuestion = (await Http.GetFromJsonAsync>($"{NavigationManager.BaseUri}fake-question.json")).Count; questions = new List(response); // an actual data for the current page } } From a45bbfb2a3990303156228036a55916fd614bf8e Mon Sep 17 00:00:00 2001 From: "maxence.guitard" Date: Mon, 18 Dec 2023 09:38:56 +0100 Subject: [PATCH 3/3] fix : affichage chapter --- .../Blazor/Pages/Chapters/Chapters.razor.cs | 3 +- Blazor/Blazor/wwwroot/fake-data.json | 98 ------------------- 2 files changed, 2 insertions(+), 99 deletions(-) delete mode 100644 Blazor/Blazor/wwwroot/fake-data.json diff --git a/Blazor/Blazor/Pages/Chapters/Chapters.razor.cs b/Blazor/Blazor/Pages/Chapters/Chapters.razor.cs index 28a8e0e..350a0e1 100644 --- a/Blazor/Blazor/Pages/Chapters/Chapters.razor.cs +++ b/Blazor/Blazor/Pages/Chapters/Chapters.razor.cs @@ -89,8 +89,9 @@ public partial class Chapters if (!e.CancellationToken.IsCancellationRequested) { - totalChapter = (await LocalStorage.GetItemAsync>("data")).Count; chapters = new List(response); // an actual data for the current page + totalChapter = chapters.Count; + } } diff --git a/Blazor/Blazor/wwwroot/fake-data.json b/Blazor/Blazor/wwwroot/fake-data.json deleted file mode 100644 index fa487ca..0000000 --- a/Blazor/Blazor/wwwroot/fake-data.json +++ /dev/null @@ -1,98 +0,0 @@ -[ - { - "id": 1, - "name": "Zilla" - }, - { - "id": 2, - "name": "Silodyne" - }, - { - "id": 3, - "name": "Zolarity" - }, - { - "id": 4, - "name": "Straloy" - }, - { - "id": 5, - "name": "Extro" - }, - { - "id": 6, - "name": "Prosely" - }, - { - "id": 7, - "name": "Orbalix" - }, - { - "id": 8, - "name": "Hatology" - }, - { - "id": 9, - "name": "Exodoc" - }, - { - "id": 10, - "name": "Cinaster" - }, - { - "id": 11, - "name": "Toyletry" - }, - { - "id": 12, - "name": "Combogene" - }, - { - "id": 13, - "name": "Olympix" - }, - { - "id": 14, - "name": "Emoltra" - }, - { - "id": 15, - "name": "Macronaut" - }, - { - "id": 16, - "name": "Genekom" - }, - { - "id": 17, - "name": "Zaya" - }, - { - "id": 18, - "name": "Elentrix" - }, - { - "id": 19, - "name": "Comvex" - }, - { - "id": 20, - "name": "Exozent" - }, - { - "id": 21, - "name": "Fuelworks" - }, - { - "id": 22, - "name": "Splinx" - }, - { - "id": 23, - "name": "Greeker" - }, - { - "id": 24, - "name": "Martgo" - } -] \ No newline at end of file