parent
d4421d6d7e
commit
5de6a1565f
@ -1,12 +1,14 @@
|
|||||||
<Router AppAssembly="@typeof(App).Assembly">
|
<CascadingBlazoredModal>
|
||||||
<Found Context="routeData">
|
<Router AppAssembly="@typeof(App).Assembly">
|
||||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
<Found Context="routeData">
|
||||||
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
|
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
||||||
</Found>
|
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
|
||||||
<NotFound>
|
</Found>
|
||||||
<PageTitle>Not found</PageTitle>
|
<NotFound>
|
||||||
<LayoutView Layout="@typeof(MainLayout)">
|
<PageTitle>Not found</PageTitle>
|
||||||
<p role="alert">Sorry, there's nothing at this address.</p>
|
<LayoutView Layout="@typeof(MainLayout)">
|
||||||
</LayoutView>
|
<p role="alert">Sorry, there's nothing at this address.</p>
|
||||||
</NotFound>
|
</LayoutView>
|
||||||
</Router>
|
</NotFound>
|
||||||
|
</Router>
|
||||||
|
</CascadingBlazoredModal>
|
@ -0,0 +1,47 @@
|
|||||||
|
using BlazorProject.Models;
|
||||||
|
|
||||||
|
namespace BlazorProject.Factories;
|
||||||
|
|
||||||
|
public static class ItemFactory
|
||||||
|
{
|
||||||
|
public static ItemModel ToModel(Item item, byte[] imageContent)
|
||||||
|
{
|
||||||
|
return new ItemModel
|
||||||
|
{
|
||||||
|
Id = item.Id,
|
||||||
|
DisplayName = item.DisplayName,
|
||||||
|
Name = item.Name,
|
||||||
|
RepairWith = item.RepairWith,
|
||||||
|
EnchantCategories = item.EnchantCategories,
|
||||||
|
MaxDurability = item.MaxDurability,
|
||||||
|
StackSize = item.StackSize,
|
||||||
|
ImageContent = imageContent
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Item Create(ItemModel model)
|
||||||
|
{
|
||||||
|
return new Item
|
||||||
|
{
|
||||||
|
Id = model.Id,
|
||||||
|
DisplayName = model.DisplayName,
|
||||||
|
Name = model.Name,
|
||||||
|
RepairWith = model.RepairWith,
|
||||||
|
EnchantCategories = model.EnchantCategories,
|
||||||
|
MaxDurability = model.MaxDurability,
|
||||||
|
StackSize = model.StackSize,
|
||||||
|
CreatedDate = DateTime.Now
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Update(Item item, ItemModel model)
|
||||||
|
{
|
||||||
|
item.DisplayName = model.DisplayName;
|
||||||
|
item.Name = model.Name;
|
||||||
|
item.RepairWith = model.RepairWith;
|
||||||
|
item.EnchantCategories = model.EnchantCategories;
|
||||||
|
item.MaxDurability = model.MaxDurability;
|
||||||
|
item.StackSize = model.StackSize;
|
||||||
|
item.UpdatedDate = DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
<div class="simple-form">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Are you sure you want to delete @item.DisplayName ?
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<button @onclick="ConfirmDelete" class="btn btn-primary">Delete</button>
|
||||||
|
|
||||||
|
<button @onclick="Cancel" class="btn btn-secondary">Cancel</button>
|
||||||
|
</div>
|
@ -0,0 +1,37 @@
|
|||||||
|
using Blazored.Modal;
|
||||||
|
using Blazored.Modal.Services;
|
||||||
|
using BlazorProject.Models;
|
||||||
|
using BlazorProject.Services;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace BlazorProject.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();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
@page "/edit/{Id:int}"
|
||||||
|
|
||||||
|
<h3>Edit</h3>
|
||||||
|
|
||||||
|
<EditForm Model="@itemModel" OnValidSubmit="@HandleValidSubmit">
|
||||||
|
<DataAnnotationsValidator />
|
||||||
|
<ValidationSummary />
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<label for="display-name">
|
||||||
|
Display name:
|
||||||
|
<InputText id="display-name" @bind-Value="itemModel.DisplayName" />
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="name">
|
||||||
|
Name:
|
||||||
|
<InputText id="name" @bind-Value="itemModel.Name" />
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="stack-size">
|
||||||
|
Stack size:
|
||||||
|
<InputNumber id="stack-size" @bind-Value="itemModel.StackSize" />
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="max-durability">
|
||||||
|
Max durability:
|
||||||
|
<InputNumber id="max-durability" @bind-Value="itemModel.MaxDurability" />
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Enchant categories:
|
||||||
|
<div>
|
||||||
|
@foreach (var item in enchantCategories)
|
||||||
|
{
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" @onchange="@(e => OnEnchantCategoriesChange(item, e.Value))" checked="@(itemModel.EnchantCategories.Contains(item) ? "checked" : null)" />@item
|
||||||
|
</label>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Repair with:
|
||||||
|
<div>
|
||||||
|
@foreach (var item in repairWith)
|
||||||
|
{
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" @onchange="@(e => OnRepairWithChange(item, e.Value))" checked="@(itemModel.RepairWith.Contains(item) ? "checked" : null)" />@item
|
||||||
|
</label>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label>
|
||||||
|
Current Item image:
|
||||||
|
@if (File.Exists($"{WebHostEnvironment.BaseAddress}/images/{itemModel.Name}.png"))
|
||||||
|
{
|
||||||
|
<img src="images/@(itemModel.Name).png" class="img-thumbnail" title="@itemModel.DisplayName" alt="@itemModel.DisplayName" style="max-width: 150px"/>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<img src="images/default.png" class="img-thumbnail" title="@itemModel.DisplayName" alt="@itemModel.DisplayName" style="max-width: 150px"/>
|
||||||
|
}
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label>
|
||||||
|
Item image:
|
||||||
|
<InputFile OnChange="@LoadImage" accept=".png" />
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label>
|
||||||
|
Accept Condition:
|
||||||
|
<InputCheckbox @bind-Value="itemModel.AcceptCondition" />
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<button type="submit">Submit</button>
|
||||||
|
</EditForm>
|
@ -0,0 +1,109 @@
|
|||||||
|
using BlazorProject.Factories;
|
||||||
|
using BlazorProject.Models;
|
||||||
|
using BlazorProject.Services;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Microsoft.AspNetCore.Components.Forms;
|
||||||
|
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||||
|
|
||||||
|
namespace BlazorProject.Pages;
|
||||||
|
|
||||||
|
public partial class Edit
|
||||||
|
{
|
||||||
|
[Parameter]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The default enchant categories.
|
||||||
|
/// </summary>
|
||||||
|
private List<string> enchantCategories = new List<string>() { "armor", "armor_head", "armor_chest", "weapon", "digger", "breakable", "vanishable" };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current item model
|
||||||
|
/// </summary>
|
||||||
|
private ItemModel itemModel = new()
|
||||||
|
{
|
||||||
|
EnchantCategories = new List<string>(),
|
||||||
|
RepairWith = new List<string>()
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The default repair with.
|
||||||
|
/// </summary>
|
||||||
|
private List<string> repairWith = new List<string>() { "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 IWebAssemblyHostEnvironment WebHostEnvironment { get; set; }
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
var item = await DataService.GetById(Id);
|
||||||
|
|
||||||
|
var fileContent = await File.ReadAllBytesAsync($"{WebHostEnvironment.BaseAddress}/images/default.png");
|
||||||
|
|
||||||
|
if (File.Exists($"{WebHostEnvironment.BaseAddress}/images/{itemModel.Name}.png"))
|
||||||
|
{
|
||||||
|
fileContent = await File.ReadAllBytesAsync($"{WebHostEnvironment.BaseAddress}/images/{item.Name}.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,178 @@
|
|||||||
|
using System.Net.Http.Json;
|
||||||
|
using Blazored.LocalStorage;
|
||||||
|
using BlazorProject.Factories;
|
||||||
|
using BlazorProject.Models;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||||
|
|
||||||
|
namespace BlazorProject.Services;
|
||||||
|
|
||||||
|
public class DataLocalService : IDataService
|
||||||
|
{
|
||||||
|
private readonly HttpClient _http;
|
||||||
|
private readonly ILocalStorageService _localStorage;
|
||||||
|
private readonly NavigationManager _navigationManager;
|
||||||
|
private readonly IWebAssemblyHostEnvironment _webHostEnvironment;
|
||||||
|
|
||||||
|
public DataLocalService(
|
||||||
|
ILocalStorageService localStorage,
|
||||||
|
HttpClient http,
|
||||||
|
IWebAssemblyHostEnvironment 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<List<Item>>("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 image
|
||||||
|
var imagePathInfo = new DirectoryInfo($"{_webHostEnvironment.BaseAddress}/images");
|
||||||
|
|
||||||
|
// Check if the folder "images" exist
|
||||||
|
if (!imagePathInfo.Exists)
|
||||||
|
{
|
||||||
|
imagePathInfo.Create();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the image name
|
||||||
|
var fileName = new FileInfo($"{imagePathInfo}/{model.Name}.png");
|
||||||
|
|
||||||
|
// Write the file content
|
||||||
|
await File.WriteAllBytesAsync(fileName.FullName, model.ImageContent);
|
||||||
|
|
||||||
|
// Save the data
|
||||||
|
await _localStorage.SetItemAsync("data", currentData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> Count()
|
||||||
|
{
|
||||||
|
// Load data from the local storage
|
||||||
|
var currentData = await _localStorage.GetItemAsync<Item[]>("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<Item[]>($"{_navigationManager.BaseUri}fake-data.json");
|
||||||
|
await _localStorage.SetItemAsync("data", originalData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (await _localStorage.GetItemAsync<Item[]>("data")).Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<Item>> List(int currentPage, int pageSize)
|
||||||
|
{
|
||||||
|
// Load data from the local storage
|
||||||
|
var currentData = await _localStorage.GetItemAsync<Item[]>("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<Item[]>($"{_navigationManager.BaseUri}fake-data.json");
|
||||||
|
await _localStorage.SetItemAsync("data", originalData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (await _localStorage.GetItemAsync<Item[]>("data")).Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Item> GetById(int id)
|
||||||
|
{
|
||||||
|
// Get the current data
|
||||||
|
var currentData = await _localStorage.GetItemAsync<List<Item>>("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<List<Item>>("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}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the image
|
||||||
|
var imagePathInfo = new DirectoryInfo($"{_webHostEnvironment.BaseAddress}/images");
|
||||||
|
|
||||||
|
// Check if the folder "images" exist
|
||||||
|
if (!imagePathInfo.Exists)
|
||||||
|
{
|
||||||
|
imagePathInfo.Create();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the previous image
|
||||||
|
if (item.Name != model.Name)
|
||||||
|
{
|
||||||
|
var oldFileName = new FileInfo($"{imagePathInfo}/{item.Name}.png");
|
||||||
|
|
||||||
|
if (oldFileName.Exists)
|
||||||
|
{
|
||||||
|
File.Delete(oldFileName.FullName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the image name
|
||||||
|
var fileName = new FileInfo($"{imagePathInfo}/{model.Name}.png");
|
||||||
|
|
||||||
|
// Write the file content
|
||||||
|
await File.WriteAllBytesAsync(fileName.FullName, model.ImageContent);
|
||||||
|
|
||||||
|
// 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<List<Item>>("data");
|
||||||
|
|
||||||
|
// Get the item int the list
|
||||||
|
var item = currentData.FirstOrDefault(w => w.Id == id);
|
||||||
|
|
||||||
|
// Delete item in
|
||||||
|
currentData.Remove(item);
|
||||||
|
|
||||||
|
// Delete the image
|
||||||
|
var imagePathInfo = new DirectoryInfo($"{_webHostEnvironment.BaseAddress}/images");
|
||||||
|
var fileName = new FileInfo($"{imagePathInfo}/{item.Name}.png");
|
||||||
|
|
||||||
|
if (fileName.Exists)
|
||||||
|
{
|
||||||
|
File.Delete(fileName.FullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the data
|
||||||
|
await _localStorage.SetItemAsync("data", currentData);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
using BlazorProject.Models;
|
||||||
|
|
||||||
|
namespace BlazorProject.Services;
|
||||||
|
|
||||||
|
public interface IDataService
|
||||||
|
{
|
||||||
|
Task Add(ItemModel model);
|
||||||
|
|
||||||
|
Task<int> Count();
|
||||||
|
|
||||||
|
Task<List<Item>> List(int currentPage, int pageSize);
|
||||||
|
|
||||||
|
Task<Item> GetById(int id);
|
||||||
|
|
||||||
|
Task Update(int id, ItemModel model);
|
||||||
|
|
||||||
|
Task Delete(int id);
|
||||||
|
}
|
After Width: | Height: | Size: 199 KiB |
Before Width: | Height: | Size: 220 KiB After Width: | Height: | Size: 220 KiB |
Loading…
Reference in new issue