From 0d0dab12636b8c8e2447baf483e8311127984ed2 Mon Sep 17 00:00:00 2001
From: emkartal1
Date: Mon, 5 Dec 2022 15:07:59 +0100
Subject: [PATCH] =?UTF-8?q?Ajout=20des=20List,=20Des=20fonctionnalit=C3=A9?=
=?UTF-8?q?s=20Ajouter,=20Suprimer,=20Editer...=20Pas=20de=20connexion=20?=
=?UTF-8?q?=C3=A0=20l'API=20pour=20l'instant?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/CraftSharp/App.razor | 26 +-
src/CraftSharp/CraftSharp.csproj | 4 +
src/CraftSharp/Factories/ItemFactory.cs | 6 +-
.../Modals/DeleteConfirmation.razor | 10 +
.../Modals/DeleteConfirmation.razor.cs | 38 +
src/CraftSharp/Models/Item.cs | 2 +-
src/CraftSharp/Models/ItemModel.cs | 4 +-
src/CraftSharp/Pages/Add.razor | 69 ++
src/CraftSharp/Pages/Add.razor.cs | 89 +++
src/CraftSharp/Pages/Crafting.razor | 5 +
src/CraftSharp/Pages/Crafting.razor.cs | 32 +
src/CraftSharp/Pages/Edit.razor | 88 +++
src/CraftSharp/Pages/Edit.razor.cs | 105 +++
src/CraftSharp/Pages/List.razor | 52 +-
src/CraftSharp/Pages/List.razor.cs | 56 +-
src/CraftSharp/Pages/_Layout.cshtml | 3 +
src/CraftSharp/Program.cs | 16 +-
src/CraftSharp/Services/DataLocalService.cs | 147 ++++
src/CraftSharp/Services/IDataService.cs | 3 +-
src/CraftSharp/Shared/HeaderLayout.razor | 5 +
src/CraftSharp/_Imports.razor | 3 +
src/CraftSharp/wwwroot/Images/default.png | Bin 0 -> 2267 bytes
src/CraftSharp/wwwroot/Images/sq.png | Bin 0 -> 8451 bytes
src/CraftSharp/wwwroot/Images/weegee.png | Bin 0 -> 8451 bytes
src/CraftSharp/wwwroot/fake-data.json | 690 ++++++------------
25 files changed, 959 insertions(+), 494 deletions(-)
create mode 100644 src/CraftSharp/Modals/DeleteConfirmation.razor
create mode 100644 src/CraftSharp/Modals/DeleteConfirmation.razor.cs
create mode 100644 src/CraftSharp/Pages/Add.razor
create mode 100644 src/CraftSharp/Pages/Add.razor.cs
create mode 100644 src/CraftSharp/Pages/Crafting.razor
create mode 100644 src/CraftSharp/Pages/Crafting.razor.cs
create mode 100644 src/CraftSharp/Pages/Edit.razor
create mode 100644 src/CraftSharp/Pages/Edit.razor.cs
create mode 100644 src/CraftSharp/Services/DataLocalService.cs
create mode 100644 src/CraftSharp/wwwroot/Images/default.png
create mode 100644 src/CraftSharp/wwwroot/Images/sq.png
create mode 100644 src/CraftSharp/wwwroot/Images/weegee.png
diff --git a/src/CraftSharp/App.razor b/src/CraftSharp/App.razor
index 0643159..64264c7 100644
--- a/src/CraftSharp/App.razor
+++ b/src/CraftSharp/App.razor
@@ -1,12 +1,14 @@
-
-
-
-
-
-
- Not found
-
- Sorry, there's nothing at this address.
-
-
-
+
+
+
+
+
+
+
+ Not found
+
+ Sorry, there's nothing at this address.
+
+
+
+
\ No newline at end of file
diff --git a/src/CraftSharp/CraftSharp.csproj b/src/CraftSharp/CraftSharp.csproj
index 8055e4b..85da056 100644
--- a/src/CraftSharp/CraftSharp.csproj
+++ b/src/CraftSharp/CraftSharp.csproj
@@ -25,7 +25,11 @@
+
+
+
+
diff --git a/src/CraftSharp/Factories/ItemFactory.cs b/src/CraftSharp/Factories/ItemFactory.cs
index e0e91fd..a305db3 100644
--- a/src/CraftSharp/Factories/ItemFactory.cs
+++ b/src/CraftSharp/Factories/ItemFactory.cs
@@ -17,7 +17,7 @@ namespace CraftSharp.Factories
StackSize = item.StackSize,
ImageContent = imageContent,
ImageBase64 = string.IsNullOrWhiteSpace(item.ImageBase64) ? Convert.ToBase64String(imageContent) : item.ImageBase64,
- Rarity = item.Rarity
+ //Rarity = item.Rarity
};
}
@@ -34,7 +34,7 @@ namespace CraftSharp.Factories
StackSize = model.StackSize,
CreatedDate = DateTime.Now,
ImageBase64 = Convert.ToBase64String(model.ImageContent),
- Rarity = model.Rarity
+ //Rarity = model.Rarity
};
}
@@ -48,7 +48,7 @@ namespace CraftSharp.Factories
item.StackSize = model.StackSize;
item.UpdatedDate = DateTime.Now;
item.ImageBase64 = Convert.ToBase64String(model.ImageContent);
- item.Rarity = model.Rarity;
+ //item.Rarity = model.Rarity;
}
}
diff --git a/src/CraftSharp/Modals/DeleteConfirmation.razor b/src/CraftSharp/Modals/DeleteConfirmation.razor
new file mode 100644
index 0000000..b565665
--- /dev/null
+++ b/src/CraftSharp/Modals/DeleteConfirmation.razor
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/src/CraftSharp/Modals/DeleteConfirmation.razor.cs b/src/CraftSharp/Modals/DeleteConfirmation.razor.cs
new file mode 100644
index 0000000..7775be9
--- /dev/null
+++ b/src/CraftSharp/Modals/DeleteConfirmation.razor.cs
@@ -0,0 +1,38 @@
+using Blazored.Modal;
+using Blazored.Modal.Services;
+using CraftSharp.Models;
+using CraftSharp.Services;
+using Microsoft.AspNetCore.Components;
+
+namespace CraftSharp.Modals
+{
+ public partial class DeleteConfirmation
+ {
+ [CascadingParameter]
+ public BlazoredModalInstance ModalInstance { get; set; }
+
+ [Inject]
+ public IDataService DataService { get; set; }
+
+ [Parameter]
+ public int Id { get; set; }
+
+ private Item item = new Item();
+
+ protected override async Task OnInitializedAsync()
+ {
+ // Get the item
+ item = await DataService.GetById(Id);
+ }
+
+ void ConfirmDelete()
+ {
+ ModalInstance.CloseAsync(ModalResult.Ok(true));
+ }
+
+ void Cancel()
+ {
+ ModalInstance.CancelAsync();
+ }
+ }
+}
diff --git a/src/CraftSharp/Models/Item.cs b/src/CraftSharp/Models/Item.cs
index eaf12d8..48f3be7 100644
--- a/src/CraftSharp/Models/Item.cs
+++ b/src/CraftSharp/Models/Item.cs
@@ -13,6 +13,6 @@
public DateTime? UpdatedDate { get; set; }
public string ImageBase64 { get; set; }
- public Rarities Rarity { get; set; }
+ //public Rarities Rarity { get; set; }
}
}
diff --git a/src/CraftSharp/Models/ItemModel.cs b/src/CraftSharp/Models/ItemModel.cs
index a778e4a..88f7b6a 100644
--- a/src/CraftSharp/Models/ItemModel.cs
+++ b/src/CraftSharp/Models/ItemModel.cs
@@ -36,7 +36,7 @@ namespace CraftSharp.Models
public string ImageBase64 { get; set; }
- [Required]
- public Rarities Rarity { get; set; }
+ /*[Required]
+ public Rarities Rarity { get; set; }*/
}
}
diff --git a/src/CraftSharp/Pages/Add.razor b/src/CraftSharp/Pages/Add.razor
new file mode 100644
index 0000000..0ed932c
--- /dev/null
+++ b/src/CraftSharp/Pages/Add.razor
@@ -0,0 +1,69 @@
+@page "/add"
+
+Add
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Enchant categories:
+
+ @foreach (var item in enchantCategories)
+ {
+
+ }
+
+
+
+ Repair with:
+
+ @foreach (var item in repairWith)
+ {
+
+ }
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/CraftSharp/Pages/Add.razor.cs b/src/CraftSharp/Pages/Add.razor.cs
new file mode 100644
index 0000000..28d5d8e
--- /dev/null
+++ b/src/CraftSharp/Pages/Add.razor.cs
@@ -0,0 +1,89 @@
+using Blazored.LocalStorage;
+using CraftSharp.Models;
+using CraftSharp.Services;
+using Microsoft.AspNetCore.Components;
+using Microsoft.AspNetCore.Components.Forms;
+
+namespace CraftSharp.Pages
+{
+ public partial class Add
+ {
+ ///
+ /// The default enchant categories.
+ ///
+ private List enchantCategories = new List() { "armor", "armor_head", "armor_chest", "weapon", "digger", "breakable", "vanishable" };
+
+ ///
+ /// The current item model
+ ///
+ private ItemModel itemModel = new()
+ {
+ EnchantCategories = new List(),
+ RepairWith = new List()
+ };
+
+ ///
+ /// The default repair with.
+ ///
+ private List repairWith = new List() { "oak_planks", "spruce_planks", "birch_planks", "jungle_planks", "acacia_planks", "dark_oak_planks", "crimson_planks", "warped_planks" };
+
+ [Inject]
+ public IDataService DataService { get; set; }
+
+ [Inject]
+ public NavigationManager NavigationManager { get; set; }
+
+ private async void HandleValidSubmit()
+ {
+ await DataService.Add(itemModel);
+
+ NavigationManager.NavigateTo("list");
+ }
+
+ private async Task LoadImage(InputFileChangeEventArgs e)
+ {
+ // Set the content of the image to the model
+ using (var memoryStream = new MemoryStream())
+ {
+ await e.File.OpenReadStream().CopyToAsync(memoryStream);
+ itemModel.ImageContent = memoryStream.ToArray();
+ }
+ }
+
+ private void OnEnchantCategoriesChange(string item, object checkedValue)
+ {
+ if ((bool)checkedValue)
+ {
+ if (!itemModel.EnchantCategories.Contains(item))
+ {
+ itemModel.EnchantCategories.Add(item);
+ }
+
+ return;
+ }
+
+ if (itemModel.EnchantCategories.Contains(item))
+ {
+ itemModel.EnchantCategories.Remove(item);
+ }
+ }
+
+ private void OnRepairWithChange(string item, object checkedValue)
+ {
+ if ((bool)checkedValue)
+ {
+ if (!itemModel.RepairWith.Contains(item))
+ {
+ itemModel.RepairWith.Add(item);
+ }
+
+ return;
+ }
+
+ if (itemModel.RepairWith.Contains(item))
+ {
+ itemModel.RepairWith.Remove(item);
+ }
+ }
+ }
+}
diff --git a/src/CraftSharp/Pages/Crafting.razor b/src/CraftSharp/Pages/Crafting.razor
new file mode 100644
index 0000000..95529a1
--- /dev/null
+++ b/src/CraftSharp/Pages/Crafting.razor
@@ -0,0 +1,5 @@
+@page "/Crafting"
+
+
+
+
\ No newline at end of file
diff --git a/src/CraftSharp/Pages/Crafting.razor.cs b/src/CraftSharp/Pages/Crafting.razor.cs
new file mode 100644
index 0000000..0ce2f97
--- /dev/null
+++ b/src/CraftSharp/Pages/Crafting.razor.cs
@@ -0,0 +1,32 @@
+using CraftSharp.Components;
+using CraftSharp.Models;
+using CraftSharp.Services;
+using Microsoft.AspNetCore.Components;
+
+namespace CraftSharp.Pages
+{
+ public partial class Crafting
+ {
+ [Inject]
+ public IDataService DataService { get; set; }
+
+ public List- Items { get; set; } = new List
- ();
+
+ private List Recipes { get; set; } = new List();
+
+ protected override async Task OnAfterRenderAsync(bool firstRender)
+ {
+ base.OnAfterRenderAsync(firstRender);
+
+ if (!firstRender)
+ {
+ return;
+ }
+
+ Items = await DataService.List(0, await DataService.Count());
+ Recipes = await DataService.GetRecipes();
+
+ StateHasChanged();
+ }
+ }
+}
diff --git a/src/CraftSharp/Pages/Edit.razor b/src/CraftSharp/Pages/Edit.razor
new file mode 100644
index 0000000..029b141
--- /dev/null
+++ b/src/CraftSharp/Pages/Edit.razor
@@ -0,0 +1,88 @@
+@page "/edit/{Id:int}"
+
+
Edit
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Enchant categories:
+
+ @foreach (var item in enchantCategories)
+ {
+
+ }
+
+
+
+ Repair with:
+
+ @foreach (var item in repairWith)
+ {
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/CraftSharp/Pages/Edit.razor.cs b/src/CraftSharp/Pages/Edit.razor.cs
new file mode 100644
index 0000000..8ce6c2e
--- /dev/null
+++ b/src/CraftSharp/Pages/Edit.razor.cs
@@ -0,0 +1,105 @@
+using CraftSharp.Factories;
+using CraftSharp.Models;
+using CraftSharp.Services;
+using Microsoft.AspNetCore.Components;
+using Microsoft.AspNetCore.Components.Forms;
+
+namespace CraftSharp.Pages
+{
+ public partial class Edit
+ {
+ [Parameter]
+ public int Id { get; set; }
+
+ ///
+ /// The default enchant categories.
+ ///
+ private List enchantCategories = new List() { "armor", "armor_head", "armor_chest", "weapon", "digger", "breakable", "vanishable" };
+
+ ///
+ /// The current item model
+ ///
+ private ItemModel itemModel = new()
+ {
+ EnchantCategories = new List(),
+ RepairWith = new List()
+ };
+
+ ///
+ /// The default repair with.
+ ///
+ private List repairWith = new List() { "oak_planks", "spruce_planks", "birch_planks", "jungle_planks", "acacia_planks", "dark_oak_planks", "crimson_planks", "warped_planks" };
+
+ [Inject]
+ public IDataService DataService { get; set; }
+
+ [Inject]
+ public NavigationManager NavigationManager { get; set; }
+
+ [Inject]
+ public IWebHostEnvironment WebHostEnvironment { get; set; }
+
+ protected override async Task OnInitializedAsync()
+ {
+ var item = await DataService.GetById(Id);
+
+ var fileContent = await File.ReadAllBytesAsync($"{WebHostEnvironment.WebRootPath}/images/default.png");
+
+ // Set the model with the item
+ itemModel = ItemFactory.ToModel(item, fileContent);
+ }
+
+ private async void HandleValidSubmit()
+ {
+ await DataService.Update(Id, itemModel);
+
+ NavigationManager.NavigateTo("list");
+ }
+
+ private async Task LoadImage(InputFileChangeEventArgs e)
+ {
+ // Set the content of the image to the model
+ using (var memoryStream = new MemoryStream())
+ {
+ await e.File.OpenReadStream().CopyToAsync(memoryStream);
+ itemModel.ImageContent = memoryStream.ToArray();
+ }
+ }
+
+ private void OnEnchantCategoriesChange(string item, object checkedValue)
+ {
+ if ((bool)checkedValue)
+ {
+ if (!itemModel.EnchantCategories.Contains(item))
+ {
+ itemModel.EnchantCategories.Add(item);
+ }
+
+ return;
+ }
+
+ if (itemModel.EnchantCategories.Contains(item))
+ {
+ itemModel.EnchantCategories.Remove(item);
+ }
+ }
+
+ private void OnRepairWithChange(string item, object checkedValue)
+ {
+ if ((bool)checkedValue)
+ {
+ if (!itemModel.RepairWith.Contains(item))
+ {
+ itemModel.RepairWith.Add(item);
+ }
+
+ return;
+ }
+
+ if (itemModel.RepairWith.Contains(item))
+ {
+ itemModel.RepairWith.Remove(item);
+ }
+ }
+ }
+}
diff --git a/src/CraftSharp/Pages/List.razor b/src/CraftSharp/Pages/List.razor
index a2a357b..72bc9e9 100644
--- a/src/CraftSharp/Pages/List.razor
+++ b/src/CraftSharp/Pages/List.razor
@@ -1,8 +1,52 @@
@page "/list"
-@using Models
+@using CraftSharp.Models
-@Localizer["Title"]
+List
-@code {
+
+
+ Ajouter
+
+
-}
+
+
+
+
+ @if (!string.IsNullOrWhiteSpace(context.ImageBase64))
+ {
+
+ }
+ else
+ {
+
+ }
+
+
+
+
+
+
+
+ @(string.Join(", ", ((Item)context).EnchantCategories))
+
+
+
+
+ @(string.Join(", ", ((Item)context).RepairWith))
+
+
+
+
+
+ Editer
+
+
+
+
\ No newline at end of file
diff --git a/src/CraftSharp/Pages/List.razor.cs b/src/CraftSharp/Pages/List.razor.cs
index 5bb544e..de707ae 100644
--- a/src/CraftSharp/Pages/List.razor.cs
+++ b/src/CraftSharp/Pages/List.razor.cs
@@ -1,12 +1,64 @@
-using Microsoft.AspNetCore.Components;
+using Blazored.LocalStorage;
+using Blazored.Modal;
+using Blazored.Modal.Services;
+using Blazorise.DataGrid;
+using CraftSharp.Modals;
+using CraftSharp.Models;
+using CraftSharp.Services;
+using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;
namespace CraftSharp.Pages
{
public partial class List
{
+ private List- items;
+
+ private int totalItem;
+
+ [Inject]
+ public NavigationManager NavigationManager { get; set; }
+
+ [CascadingParameter]
+ public IModalService Modal { get; set; }
[Inject]
- public IStringLocalizer
Localizer { get; set; }
+ public IDataService DataService { get; set; }
+
+ [Inject]
+ public IWebHostEnvironment WebHostEnvironment { get; set; }
+
+ private async Task OnReadData(DataGridReadDataEventArgs- e)
+ {
+ if (e.CancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ if (!e.CancellationToken.IsCancellationRequested)
+ {
+ items = await DataService.List(e.Page, e.PageSize);
+ totalItem = await DataService.Count();
+ }
+ }
+ private async void OnDelete(int id)
+ {
+ var parameters = new ModalParameters();
+ parameters.Add(nameof(Item.Id), id);
+
+ var modal = Modal.Show("Delete Confirmation", parameters);
+ var result = await modal.Result;
+
+ if (result.Cancelled)
+ {
+ return;
+ }
+
+ await DataService.Delete(id);
+
+ // Reload the page
+ NavigationManager.NavigateTo("list", true);
+ }
}
}
+
diff --git a/src/CraftSharp/Pages/_Layout.cshtml b/src/CraftSharp/Pages/_Layout.cshtml
index 50f7cc9..b8ac950 100644
--- a/src/CraftSharp/Pages/_Layout.cshtml
+++ b/src/CraftSharp/Pages/_Layout.cshtml
@@ -28,7 +28,10 @@
+
+
+
diff --git a/src/CraftSharp/Program.cs b/src/CraftSharp/Program.cs
index 5ced326..c9f4343 100644
--- a/src/CraftSharp/Program.cs
+++ b/src/CraftSharp/Program.cs
@@ -1,3 +1,8 @@
+using Blazored.LocalStorage;
+using Blazorise;
+using Blazored.Modal;
+using Blazorise.Bootstrap;
+using Blazorise.Icons.FontAwesome;
using CraftSharp.Data;
using CraftSharp.Services;
using Microsoft.AspNetCore.Components;
@@ -21,7 +26,16 @@ builder.Services.AddLocalization(opts => { opts.ResourcesPath = "Resources"; });
builder.Services.AddHttpClient();
-builder.Services.AddScoped();
+builder.Services.AddBlazoredModal();
+
+builder.Services
+ .AddBlazorise()
+ .AddBootstrapProviders()
+ .AddFontAwesomeIcons();
+
+builder.Services.AddBlazoredLocalStorage();
+
+builder.Services.AddScoped();
// Configure the localtization
builder.Services.Configure(options =>
diff --git a/src/CraftSharp/Services/DataLocalService.cs b/src/CraftSharp/Services/DataLocalService.cs
new file mode 100644
index 0000000..f248643
--- /dev/null
+++ b/src/CraftSharp/Services/DataLocalService.cs
@@ -0,0 +1,147 @@
+using Blazored.LocalStorage;
+using CraftSharp.Components;
+using CraftSharp.Factories;
+using CraftSharp.Models;
+using Microsoft.AspNetCore.Components;
+
+namespace CraftSharp.Services
+{
+ public class DataLocalService : IDataService
+ {
+ private readonly HttpClient _http;
+ private readonly ILocalStorageService _localStorage;
+ private readonly NavigationManager _navigationManager;
+ private readonly IWebHostEnvironment _webHostEnvironment;
+
+ public DataLocalService(
+ ILocalStorageService localStorage,
+ HttpClient http,
+ IWebHostEnvironment webHostEnvironment,
+ NavigationManager navigationManager)
+ {
+ _localStorage = localStorage;
+ _http = http;
+ _webHostEnvironment = webHostEnvironment;
+ _navigationManager = navigationManager;
+ }
+
+ public async Task Add(ItemModel model)
+ {
+ // Get the current data
+ var currentData = await _localStorage.GetItemAsync
>("data");
+
+ // Simulate the Id
+ model.Id = currentData.Max(s => s.Id) + 1;
+
+ // Add the item to the current data
+ currentData.Add(ItemFactory.Create(model));
+
+ // Save the data
+ await _localStorage.SetItemAsync("data", currentData);
+ }
+
+ public async Task Count()
+ {
+ // 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-data.json");
+ await _localStorage.SetItemAsync("data", originalData);
+ }
+
+ return (await _localStorage.GetItemAsync
- ("data")).Length;
+ }
+
+ public async Task
> List(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-data.json");
+ await _localStorage.SetItemAsync("data", originalData);
+ }
+
+ return (await _localStorage.GetItemAsync
- ("data")).Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
+ }
+ public async Task
- GetById(int id)
+ {
+ // Get the current data
+ var currentData = await _localStorage.GetItemAsync
>("data");
+
+ // Get the item int the list
+ var item = currentData.FirstOrDefault(w => w.Id == id);
+
+ // Check if item exist
+ if (item == null)
+ {
+ throw new Exception($"Unable to found the item with ID: {id}");
+ }
+
+ return item;
+ }
+
+ public async Task Update(int id, ItemModel model)
+ {
+ // Get the current data
+ var currentData = await _localStorage.GetItemAsync>("data");
+
+ // Get the item int the list
+ var item = currentData.FirstOrDefault(w => w.Id == id);
+
+ // Check if item exist
+ if (item == null)
+ {
+ throw new Exception($"Unable to found the item with ID: {id}");
+ }
+
+ // Modify the content of the item
+ ItemFactory.Update(item, model);
+
+ // Save the data
+ await _localStorage.SetItemAsync("data", currentData);
+ }
+
+ public async Task Delete(int id)
+ {
+ // Get the current data
+ var currentData = await _localStorage.GetItemAsync>("data");
+
+ // Get the item int the list
+ var item = currentData.FirstOrDefault(w => w.Id == id);
+
+ // Delete item in
+ currentData.Remove(item);
+
+ // Save the data
+ await _localStorage.SetItemAsync("data", currentData);
+ }
+
+ public Task> GetRecipes()
+ {
+ var items = new List
+ {
+ new CraftingRecipe
+ {
+ Give = new Item { DisplayName = "Diamond", Name = "diamond" },
+ Have = new List>
+ {
+ new List { "dirt", "dirt", "dirt" },
+ new List { "dirt", null, "dirt" },
+ new List { "dirt", "dirt", "dirt" }
+ }
+ }
+ };
+
+ return Task.FromResult(items);
+ }
+
+ }
+}
diff --git a/src/CraftSharp/Services/IDataService.cs b/src/CraftSharp/Services/IDataService.cs
index c5a515c..2dd688d 100644
--- a/src/CraftSharp/Services/IDataService.cs
+++ b/src/CraftSharp/Services/IDataService.cs
@@ -14,8 +14,9 @@ namespace CraftSharp.Services
Task Update(int id, ItemModel model);
Task Delete(int id);
-
Task> GetRecipes();
+
+ //Task> GetRecipes();
}
}
diff --git a/src/CraftSharp/Shared/HeaderLayout.razor b/src/CraftSharp/Shared/HeaderLayout.razor
index 4b6b97e..5c9ba21 100644
--- a/src/CraftSharp/Shared/HeaderLayout.razor
+++ b/src/CraftSharp/Shared/HeaderLayout.razor
@@ -30,6 +30,11 @@
Inventaire
+
+
+ Table de craft
+
+
diff --git a/src/CraftSharp/_Imports.razor b/src/CraftSharp/_Imports.razor
index 06955e4..b191629 100644
--- a/src/CraftSharp/_Imports.razor
+++ b/src/CraftSharp/_Imports.razor
@@ -8,3 +8,6 @@
@using Microsoft.JSInterop
@using CraftSharp
@using CraftSharp.Shared
+@using Blazorise.DataGrid
+@using Blazored.Modal
+@using Blazored.Modal.Services
\ No newline at end of file
diff --git a/src/CraftSharp/wwwroot/Images/default.png b/src/CraftSharp/wwwroot/Images/default.png
new file mode 100644
index 0000000000000000000000000000000000000000..a7446c9e8a8c755f1e21faf389634136d44fed6d
GIT binary patch
literal 2267
zcmeHIX
BIq!$_ocGH~zGZI(lvb1m006)n
z*5;1;HEW*%QWE<)?4{2);XtUPl_>z%dun#Sk$ecXg8~56=`uSWhX4Qxz%5&6i`?AY
zyu7@(Z{OzU=NA+d6c-nll$4;+=+e^Cva+)B^74v`3JeB=#bPTfD{(knRaF%pkFTz-
zCJ+dpKYy;Rt*xu8BNB=A_4N%64ULVBBoe8mrKPpCwXLnKy}iA&v$MOqyQin8x3{;i
zudlzqe_&vMLZJ)}4pOPqp`jrfjYg-_hlht53FMd2nHe6BH#<8!H#f)U^XKR17Zw&47Z;b7mX?>7S5{U80>SF)
z>e|}c`uh6D#>VF6rcfx{+S(F{MBCfjJ3BjKv3PfPcW-ZR-2fMBIvBA&SM#k#iJoyiib{34ADdDcA_31T)KpX{irS?~{BklHj+M+J%
zdw&s15$x2E%ww_b0H
zGN`Wrd|F^q*B=xc1K~Lt??CkcoFt51b6of2;ey0^_r$9zTQI|#vY7M?ow*q>9SF8-
z@0iVrUJnQmYRvoR7rLH3!`KV^4KZPJv+ZSUf{CD-c{CJf7_T?DikxnFe$i3IWg0g2
z8v2|y1wY;cR@ycOa~`B6D4Xd0Y?F=Zy2WL(Sz}{QZDAy5>($Mi!c@bBwP~2}xXFM4
zuZi236Fe2m@7jC35T~iKy6(nCi6p^xq+%VK6rWTqDTU9^HVZc7N>f=YvH1%#>G~R%
ztWwS$S4Cj$c|}Mt5&b?1PH1XsJ*=P*c;8XHl`h;qD`)csmh^*;Ziip9o=jM3227F8
zGZ>AGkd9ka_Ac5MHM|7lJ(R+fRS_ES7v)@X=iSMWqkq4Nk|x#Rgm$f_t*}zQ!jA|K
zRz)QkD}}qV_E;EYEdSU3?oVs4d{vw@j`_P7cgT_%2??YQ!jK#rBos#}?S6pO{GJzO
zSO%*hRbUDLG8fcv#_##pk;k6BOB-r6^)?$g;r~avGaYk)R-Th4hjZ1|vu#)R@`K6r
z!L*z-e50v`Ks?iP*$*8`EH=wk%z6~8w~BZ<)M;hu8QxwA;?&Fi)&+0Vy{C;EyQ>^&
ziS+-4nd#d=aM{pQ2suv|PKaoN*Fq>#LKsyUq)t4amGHVQh8@jG)`|u;8%Whfh_5J<
zTN(*rSx-(aM+k(N5a9hTjs1}Zsax&EyR-zOwm;8l$&nN7QZ{};vtz%D6v=9-)H!P?
z{bY_NSum|GVuI^xUE?OoLe*g*)SZ#ttQeoK#=uV{@mFJT2ZPmNE{%gy_uU3)(0l9x
zx73I5aUQ83j};0gQ0ZxhqEjxs510W4{evv(Gw7`OBsfwDI*IqD5T{{Tv}C~r`M9YN
zah2EQ*j>4xg4@A5?ZY_GR
zmBeb<>8q*!FOJv@Tn9(^si4T-^I<>vLI(56kI}gtf%j20pN=VJDtS<=V}+tg$0Kbl
z!!;H?``-8vO}uA81l5)Nwwb>B1i#R
zUwuubIGlO9-DiKM2qM^#_tA4`D1xj!Dx_MzL$48HXY3cwwR8R_eDtd0wig>
literal 0
HcmV?d00001
diff --git a/src/CraftSharp/wwwroot/Images/sq.png b/src/CraftSharp/wwwroot/Images/sq.png
new file mode 100644
index 0000000000000000000000000000000000000000..d8bf2cef5d54faee6af2df719ac533e8ebdbf38c
GIT binary patch
literal 8451
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