parent
d4421d6d7e
commit
5de6a1565f
@ -1,12 +1,14 @@
|
||||
<Router AppAssembly="@typeof(App).Assembly">
|
||||
<Found Context="routeData">
|
||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
||||
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
|
||||
</Found>
|
||||
<NotFound>
|
||||
<PageTitle>Not found</PageTitle>
|
||||
<LayoutView Layout="@typeof(MainLayout)">
|
||||
<p role="alert">Sorry, there's nothing at this address.</p>
|
||||
</LayoutView>
|
||||
</NotFound>
|
||||
</Router>
|
||||
<CascadingBlazoredModal>
|
||||
<Router AppAssembly="@typeof(App).Assembly">
|
||||
<Found Context="routeData">
|
||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
||||
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
|
||||
</Found>
|
||||
<NotFound>
|
||||
<PageTitle>Not found</PageTitle>
|
||||
<LayoutView Layout="@typeof(MainLayout)">
|
||||
<p role="alert">Sorry, there's nothing at this address.</p>
|
||||
</LayoutView>
|
||||
</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