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/Chapters/Chapters.razor.cs b/Blazor/Blazor/Pages/Chapters/Chapters.razor.cs index ca73382..6b1f01c 100644 --- a/Blazor/Blazor/Pages/Chapters/Chapters.razor.cs +++ b/Blazor/Blazor/Pages/Chapters/Chapters.razor.cs @@ -90,8 +90,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/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..e245f8f 100644 --- a/Blazor/Blazor/Pages/Questions/Questions.razor.cs +++ b/Blazor/Blazor/Pages/Questions/Questions.razor.cs @@ -1,6 +1,179 @@ -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; +using Blazor.Pages.Admins; + +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.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 Http.GetFromJsonAsync>($"{NavigationManager.BaseUri}fake-question.json")).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 9a70775..7db40b3 100644 --- a/Blazor/Blazor/Services/DataLocalService.cs +++ b/Blazor/Blazor/Services/DataLocalService.cs @@ -100,8 +100,6 @@ namespace Blazor.Services await _localStorage.SetItemAsync("data", currentData); } - - public async Task Count() { // Load data from the local storage @@ -139,10 +137,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}"); @@ -173,7 +171,6 @@ namespace Blazor.Services await _localStorage.SetItemAsync("data", currentData); } - public async Task Add(AdministratorsModel model) { // Get the current data @@ -182,7 +179,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, @@ -226,5 +223,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); } 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